Install & staged-setup internals

How a BOA box builds and upgrades its Aegir layer. Two orchestrations, both driven from the staged scripts under aegir/scripts/ in the build tree: the four AegirSetup{A,B,C,M}.sh.txt phases assemble the Master (Barracuda-side) and Satellite (Octopus-side) Aegir instances, and AegirUpgrade.sh.txt re-runs the hostmaster lifecycle on every Barracuda upgrade. If you change anything in satellite.sh.inc, master.sh.inc, or the staged scripts themselves, this is the execution model your change lands in.

The delivery and execution chain

Every install or upgrade run passes through the same four steps:

  1. Wrapper fetch. The barracuda/octopus CLI wrappers (aegir/tools/bin/) resolve the tree from the verb (up-dev|up-pro|up-lts_tRee), then pull the main script and its settings file from the per-tree mirror path _rgUrl="https://files.boa.io/versions/${_tRee}/boa" into /var/backups: BARRACUDA.sh.txt + lib/settings/barracuda.sh.cnf (barracuda:1834-1835, _rgUrl at :1968), or the OCTOPUS.sh.txt pair (octopus:1154-1155). Mode flags are sed-edited into the staged copies, then the wrapper runs bash /var/backups/BARRACUDA.sh.txt — nothing is ever made executable.
  2. Build tree. The main script sources its /var/backups/*.sh.cnf snapshot first; that settings file defines _download_helpers_libs() (lib/settings/barracuda.sh.cnf:1613, octopus.sh.cnf:1090), which populates _bldPth="/opt/tmp/boa"_download_boa_code tarball fetch in BATCH/default _DL_MODE, or git clone --branch ${_BRANCH_BOA} ${_BOA_REPO_GIT_URL}/${_BOA_REPO_NAME}.git ${_bldPth} in GIT mode.
  3. Library sourcing. lib/functions/*.sh.inc are sourced from the build tree: BARRACUDA loads thirteen (helper dns system sql valkey redis nginx php solr master xtra firewall hotfix, BARRACUDA.sh.txt:275), OCTOPUS three (helper dns satellite, OCTOPUS.sh.txt:266). Functions do not survive the su boundary, so each staged script re-sources its own subset from the build tree on entry — _FL="helper satellite" for A, B, C (AegirSetup{A,B,C}.sh.txt:110), _FL="helper master" for M and Upgrade (AegirSetupM.sh.txt:73, AegirUpgrade.sh.txt:73): a child stage executes the build tree's copy of the engine, never the parent's in-memory one. The staged-setup engine proper lives in satellite.sh.inc (Octopus side) and master.sh.inc (Barracuda side) — deliberately parallel copies that are never co-loaded; a fix in one is mirrored by hand into the other.
  4. Staged execution. The main script drives the AegirSetup* phases with strict user separation (table below). The staged scripts run straight from the build tree via explicit bash invocation — the .sh.txt suffix is the text-mirror convention, not a rename-then-execute scheme.

The five staged scripts

Script Runs as Launched by Role
AegirSetupA.sh.txt (268L) root _satellite_make() satellite.sh.inc:4382, from OCTOPUS.sh.txt:342 Satellite driver: root-side prep, then su into B and C
AegirSetupB.sh.txt (221L) ${_USER} _satellite_run_child_b() satellite.sh.inc:3220 Drush install + Aegir instance build; hostmaster-install on INIT (satellite.sh.inc:5734)
AegirSetupC.sh.txt (1672L) ${_USER} _satellite_run_child_c() satellite.sh.inc:3414 Platform factory: builds every Drupal platform Octopus ships
AegirSetupM.sh.txt (167L) aegir _aegir_master_install_upgrade() master.sh.inc:1239/1245, from BARRACUDA.sh.txt:542 Master Aegir install: Drush + Provision backend, then hostmaster-install
AegirUpgrade.sh.txt (521L) aegir _aegir_master_upgrade() master.sh.inc:865 Hostmaster upgrade: fixed five-function sequence ending in hostmaster-migrate

A/M/Upgrade enforce their side of the user split with id -u guards that abort the run: A refuses non-root (AegirSetupA.sh.txt:188-197), B, C, M refuse root (AegirSetupB.sh.txt:186-190, AegirSetupC.sh.txt:201-206, AegirSetupM.sh.txt:113-118).

The contracts that bite

Three mechanics carry all the state between stages — get any of them wrong and the failure is silent or off-by-one-run, not a crash at your edit site:

  • Settings snapshot, not environment. Every stage is launched through su -s /bin/bash - <user>, which resets the environment. The only input channels are argv and the /var/backups settings snapshot each stage re-sources on entry: octopus.sh.cnf.${_USER} with fallback to octopus.sh.cnf (AegirSetupA.sh.txt:73-81), barracuda.sh.cnf for M and Upgrade (AegirSetupM.sh.txt:66-67). The parent appends its computed runtime state (_AEGIR_VERSION, _DL_MODE, _PHP_CLI_VERSION, _THIS_DB_HOST, _USE_MIR, …) to that file immediately before the su (master.sh.inc:830, :1199; _satellite_make() appends to the per-instance octopus.sh.cnf.${_USER} copy staged by the octopus wrapper — cp -af at octopus:539-544 — with fallback to the base file, satellite.sh.inc:4198-4207). A new variable a child stage needs must be added to the parent's append block, or the child sees the stale snapshot value.
  • Failure travels via marker files, not exit codes. Each stage's _panic_exit() and guards touch /opt/tmp/status-<Stage>-FAIL; the parent checks the marker after wait and cascades it upward: status-AegirSetupB-FAILstatus-AegirSetupA-FAIL (satellite.sh.inc:3222-3225), status-AegirSetupA-FAILstatus-Octopus-FAIL (:4386-4390), status-AegirSetupM-FAIL and status-AegirUpgrade-FAILstatus-Barracuda-FAIL (master.sh.inc:1255-1260, :869-872). An abort path that exits non-zero but forgets the touch is invisible to the orchestrator.
  • INIT vs UPGRADE is re-derived per stage from the filesystem, never passed down: A and B flip _STATUS=UPGRADE when ${_ROOT}/aegir.sh exists (AegirSetupA.sh.txt:176-182, AegirSetupB.sh.txt:177-178), C when a setupmail log marker exists (AegirSetupC.sh.txt:188-193), and AegirUpgrade hard-aborts unless ${_PREV_HM_ROOT}/sites/${_DOMAIN}/settings.php exists (AegirUpgrade.sh.txt:496-512).

Verbose tracing for all of this is gated on _DEBUG_MODE=YES, and it rides the same snapshot channel: when /root/.debug-boa-installer.cnf (or .debug-barracuda-installer.cnf) exists, the barracuda wrapper seds _DEBUG_MODE=YES into the staged cnf copy (barracuda:712-714; the octopus wrapper checks its own marker pair, octopus:554-555), so every stage inherits it. The dev tree auto-touches both markers (barracuda:1814-1815).

Pages in this topic

  • *[Staged setup engine (AegirSetup)](01.staged-setup)* — the four phases in depth: A's root-side `satelliteprocedure chain and child launching, B's twelve_satellite_childbbuild steps, C's shared-core selection (_HOT_SAUCE/_USE_CURRENT,/data/all/NNN) and thedeclare -A distrosplatform maps driving_d_dist_loop, M's Drush-backend-plus-hostmaster-install` sequence, plus the mirror/fetch convention and where staging state lives during a run.
  • Hostmaster upgrade orchestrator (AegirUpgrade) — the fixed _hostmaster_mv_up → _hostmaster_dr_up → _hostmaster_go_up → _hostmaster_dr_tt → _hostmaster_mi_up sequence (AegirUpgrade.sh.txt:500-504), the numbered ${_ROOT}/host_master/NNN roots with zombie detection and recovery (broken previous roots moved to backups/system/empty-hm-*, AegirUpgrade.sh.txt:401-484), the Provision-backend presence gate (/var/aegir/.drush/sys/provision/http, AegirUpgrade.sh.txt:489-495), and how barracuda up-* reaches it through _aegir_master_upgrade().

Adjacent developing topics

  • Release model & SKYNET pipeline — how a new BARRACUDA.sh.txt/OCTOPUS.sh.txt reaches the mirrors in the first place, and what a tag on 5.x-pro/5.x-lts triggers on deployed fleets.
  • Aegir backend APIs — what hostmaster-install and hostmaster-migrate dispatch into: the Provision backend and the Hosting module suite these stages assume.
  • Build & test — verifying changes to the staged engine: the disposable-VM full install/upgrade gate exercises exactly these phases.

Reference

  • Variables and Commands — the consolidated knob and CLI tables for the control variables named above.
  • Discontinued features — retired install-era subsystems that old logs and forum threads still reference.