Overview — the control-file system

BOA's host-level configuration is a mix of two surfaces: a small number of master .cnf files you edit directly (/root/.barracuda.cnf and the per-instance /root/.${USER}.octopus.cnf) and a large set of empty boolean marker files whose mere existence toggles behaviour. Below those sit the per-platform and per-site INI files a tenant can edit without root, covered on the INI files & precedence page.

Three marker categories

  1. Files you never edit — generated by BOA install/upgrade tooling. Touching them corrupts state. Credentials and cluster files live here: /root/.my.cnf (MySQL root password + auto-healing access), /root/.my.pass.txt (the same password in plain text), /root/.my.cluster_root.cnf, /root/.my.proxysql_adm.cnf, /root/.ssl.proxy.cnf.
  2. Master config files/root/.barracuda.cnf (host-wide) and one /root/.${USER}.octopus.cnf per Octopus instance. These you DO edit; they are the primary host configuration interface. See barracuda.cnf and octopus.cnf. Both are maintained append-if-absent by their writers: a fresh install writes the full variable set, and every subsequent upgrade pass appends any newly introduced variable with its default only when no line with that name exists — the append mechanism itself never overwrites an operator-set value. Consequence: new lines appearing in these files after an upgrade are expected self-healing (new features arrive as no-op default lines), and removing a line you never customised just gets the default re-appended on the next run — to change behaviour, edit the value rather than deleting the line. Recent examples: the post-5.10.3 barracuda.cnf additions (_NIGHT_PARALLEL, _CLEAR_BOOST, _LE_CLIENT_NOTIFY, _AUTOSYMLINK_NIGHTLY, the ghost-cleanup family) and octopus.cnf's _PLATFORMS_ONLY, persisted alongside _HM_ONLY (written at install, back-filled on upgrade). Two deliberate exceptions: (a) the *_FORCE_REINSTALL one-shots are never persisted and are scrubbed after use (see barracuda.cnf); (b) a small set of legacy values is force-normalised on every upgrade pass regardless of operator edits (e.g. _NGINX_SPDY=YES, _NGINX_FORWARD_SECRECY=YES, _SSH_FROM_SOURCES=YES, _STRICT_BIN_PERMISSIONS=YES, _MAGICK_FROM_SOURCES=NO) — so the self-heal rule is append-only for new variables, not a universal never-touch guarantee.
  3. Empty toggle files — each .<feature>.cnf is a boolean: file present = feature on, file missing = feature off. Content is irrelevant. touch to enable, rm to disable. Effect picks up on the next BOA cron pass or upgrade.

Automatic snapshots before every rewrite: /var/backups/dragon/config

The master config files are rewritten in place by BOA itself (the self-heal appends and force-normalise sweep above, one-shot scrubbing). Before its first on-the-fly edit each run, the writer snapshots what it may touch: BARRACUDA snapshots /root/.barracuda.cnf plus every /root/.*.octopus.cnf (the snapshot precedes the early php-idle branch, so it happens on that short-circuit path too), and OCTOPUS snapshots its instance cnf before _satellite_cnf. Both go through the shared _backup_to_dragon helper, which only ever copies — never alters the original — and no-ops on a missing/empty source.

All files snapshotted during one run share a single human-readable subdir, ${_vBs:-/var/backups}/dragon/config/YYYY-MM-DD_HH-MM-SS/ (chmod 0700), so a rollback set stays grouped. The earliest pristine copy per run is preserved and never overwritten later in the same run. Legacy flat *-pre-* snapshot files at the store's top level are swept once into config/archive/.

The store covers more than the two master files: /root/.my.cnf and /root/.my.pass.txt are snapshotted through the same helper by the SQL flows, and the four auto* OS-upgrade tools (autobeowulf, autochimaera, autodaedalus, autoexcalibur) inline the same subdir scheme before their post-reboot cnf edits.

Retention: dragon/config is a permanent archive — the one path excluded from the 7-day /var/backups/dragon/* purge in the nightly run; pruning is operator-only (the retention rule itself is owned by Backup retention). Net effect: every barracuda/octopus/auto-OS-upgrade run leaves a timestamped rollback copy of the control files it may rewrite.

Marker relocation: /root/etc/boa

A growing set of operator-toggle markers has moved from /root/.<name>.cnf to /etc/boa/.<name>.cnf. On the first upgrade after this change BOA runs a one-time, per-group migration that copies existing markers from /root into /etc/boa (cp -a in BOA.sh.txt — the /root originals are left in place for later cleanup, not moved). Each group is guarded once by an /etc/boa/.migrated.<group>.txt stamp, so removing an /etc/boa marker later is never undone by a re-copy from a stale /root original.

Two consequences, both load-bearing:

  • For the migrated names the live readers test /etc/boa only — there is no /root fallback. Any new toggle you create after the upgrade must go under /etc/boa (e.g. touch /etc/boa/.allow.sendmail.cnf); a marker dropped only in /root has no effect for these names.
  • The /root copies are now stale duplicates — harmless, but no longer the source of truth. Delete them at leisure.

The migrated groups (each migrated as a unit, with its own .migrated.*.txt stamp in BOA.sh.txt):

Group Markers moved to /etc/boa
svc-control .allow.nginx.restart · .allow.php.fpm.reload · .allow.redis.restart · .allow.valkey.restart · .allow.aegir.queue
deny-disable .deny.jetty9 · .deny.solr7 · .deny.solr9 · .disable_mysql_cleanup
behavior-toggles .allow.sendmail · .allow.du · .allow-codebasecheck · .dont.touch.permissions
pause-tasks .pause_tasks_maint
csf-firewall .full.csf.cleanup · .ignore.site24x7.firewall · .whitelist.dont.cleanup · .instant.csf.block
debug-goaccess .debug.monitor · .debug.monitor.log · .goaccess.all (plus value-bearing .debug.email.txt · .goaccess.use.github.txt)
misc-toggles .instant.busy.mysql.action · .mysqladmin.monitor · .sql.problematic.users · .ice.vm · .home.no.wildcard.chmod · .run.example.report (plus .silent-octopus-upgrade.cnf)
lshell-virt .look.like.jenkins · .send-extended-report
newrelic .enable.newrelic.sysmond

Dual-reader exception

.full.csf.cleanup, .whitelist.dont.cleanup, and .ignore.site24x7.firewall are read by two tools with different roots: the guest/instance-side guest-water.sh reads /etc/boa, but the proxy/host-side host-water.sh still reads /root. On a proxy host you therefore need these in both locations. A migrated host already satisfies this (the migration leaves the /root copy in place); a freshly created marker on a proxy host must be touched in /root as well as /etc/boa.

Markers that deliberately stay in /root

Security-gate, credential, and restricted-shell-escape files are not relocated and must stay in /root: .allow.any.virt.cnf, .allow.node.lshell.cnf, .allow.php.lshell.cnf, .allow.mc.cnf, .allow.auto.reboot.cnf, .my.cnf, .my.pass.txt. Also staying in /root: .pause_heavy_tasks_maint.cnf, .deny.java.cnf, .restrict_this_vm.cnf.

Per-site / per-account control files

Not every control file is a host-level /root or /etc/boa marker. A few live under /data/conf or the instance tree, mostly scoped to a single Octopus instance or a single site:

File Scope What it does
/data/disk/<oct>/static/control/ai/policy.txt Per-Octopus Per-site AI-crawler policy. AI training crawlers are BLOCK-by-default in BOA; this file declares per-site opt-ins and other per-class overrides, which ai_policy.sh reads to regenerate the Nginx AI maps.
/data/conf/<octopus-user>_civicrm.txt Per-account CiviCRM opt-in for the Drush extension filter. Since Drush 8.5.4 the filter is backend-identity-gated, so this matters only for backend Aegir tasks (verify/migrate) running as aegir/oNoN.ftp client CLI sessions load contributed Drush commands without it. Re-allowlists exactly civicrm.drush.inc, cv.drush.inc, civicrm_drush.drush.inc. PHP-served CiviCRM is unaffected either way.
/data/conf/<octopus-user>_elysia_cron.txt Per-account Backend opt-in letting Aegir backend tasks load elysia_cron.drush.inc, so backend-mode cron (hosting_cron_use_backend) keeps Elysia's scheduling granularity. Legacy path, not used on D8+. See Drush extension filter.
/data/conf/drush_extension_filter_disabled.txt Host-level Global kill switch: turns the *.drush.inc deny-filter off for every identity. Single-tenant servers only — it re-opens the #762138 escalation. See Drush extension filter.

The three Drush-filter files are presence-only: create them as root; content is irrelevant (the filter checks existence, nothing else).

Internal state markers BOA manages itself

A set of .cnf files exist in /root/ but are touched and removed by BOA itself as one-shot or phase markers. Recognise them; do not hand-edit — doing so risks corrupting upgrade state. Examples: .allow-php-multi-install-cleanup.cnf, .fixed.multi.php.cnf, .sorted.multi.php.cnf, .updated.multi.php.cnf, .fixed_fpm_workers.cnf, .found_correct_city.cnf, .found_correct_ipv4.cnf (value-bearing caches), .high_load.cnf, .big_db.cnf, .proxy.cnf, .step.init.basic.cnf, and the .run-to-<release>.cnf / .top-<release>.cnf OS-target markers.

The host-wide and per-instance _VAR settings these markers complement are documented on barracuda.cnf and octopus.cnf. For variable-level config below the host level, see INI files & precedence. Markers and variables dropped from the stack are listed in Discontinued features; the consolidated variable index is in the Reference appendix.