Overview — the control-file system
BOA's host-level configuration is a mix of two surfaces:
- a small number of master
.cnffiles you edit directly (/root/.barracuda.cnfand the per-instance/root/.${USER}.octopus.cnf) - 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
- 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
-
Master config files —
/root/.barracuda.cnf(host-wide) and one/root/.${USER}.octopus.cnfper Octopus instance. These you DO edit; they are the primary host configuration interface. Seebarracuda.cnfandoctopus.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.cnfadditions (_NIGHT_PARALLEL,_CLEAR_BOOST,_LE_CLIENT_NOTIFY,_AUTOSYMLINK_NIGHTLY, the ghost-cleanup family) andoctopus.cnf's_PLATFORMS_ONLY, persisted alongside_HM_ONLY(written at install, back-filled on upgrade).Two deliberate exceptions:
- the
*_FORCE_REINSTALLone-shots are never persisted and are scrubbed after use (seebarracuda.cnf); - 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.
- the
-
Empty toggle files — each
.<feature>.cnfis a boolean: file present = feature on, file missing = feature off. Content is irrelevant.touchto enable,rmto disable. Effect picks up on the next BOA cron pass or upgrade.The installer debug markers live in this category and are worth knowing before you ever need them:
touch /root/.debug-boa-installer.cnfmakes the next install or upgrade run verbose (debug mode) instead of discarding most of its output. That one is safe; its sibling.debug-barracuda-installer.cnfalso skips Drush and Master Ægir updates as a side effect, so read the verbose-output FAQ entry before touching it. Note the off-switch quirk: a debug run persists_DEBUG_MODE=YESinto the master cnf files, so removing the marker alone does not restore quiet output — set_DEBUG_MODE=NOback by hand.
Automatic snapshots: /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.cnfplus every/root/.*.octopus.cnf(the snapshot precedes the earlyphp-idlebranch, so it happens on that short-circuit path too). - 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/boaonly — there is no/rootfallback. 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/roothas no effect for these names. - The
/rootcopies 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 |
| behaviour-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 |
This /root → /etc/boa relocation is a separate exercise from the ongoing
conversion of markers into /root/.barracuda.cnf variables, and the per-marker
rows in the control-file reference name
the variable wherever one now exists.
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 Ægir tasks (verify/migrate) running as aegir/oN — oN.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 Ægir 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),
.tg.cnf, .step.init.basic.cnf, and the
.run-to-<release>.cnf / .top-<release>.cnf OS-target markers.
/root/.tg.cnf is the host-tier state file in that set. On a hosted box the
_update_agents ladder in BOA.sh.txt writes it — its content is the instance
count the ladder measured — once the box carries more than 50 Octopus instances
or any account sits on a POWER, PHANTOM or CLUSTER plan, and removes it
again below that; BOA never creates it on a self-hosted server. Presence then
steers the tuning pass: the box is classified _VMFAMILY=TG rather than XEN,
a VS-family host derives its MySQL memory base from RAM/12 instead of RAM/24
(the base the InnoDB buffer pool and the MyISAM sort buffer scale from), a box
with at least 8 GB of usable RAM takes the bare-metal branch (a floor of 10 on
the derived max_connections, plus mysqlnd.mempool_default_size doubled from
64000 to 128000 in every /opt/phpNN/etc/phpNN.ini, 5.6 through 8.5), and
_PHP_FPM_WORKERS is rewritten to 100 in /root/.barracuda.cnf once, latched
by .fixed_fpm_workers.cnf. That rewrite is never undone when the marker goes
away — which is the practical reason not to hand-create or delete it.
Two neighbours of .tg.cnf look like tier state but are not: .high_load.cnf
and .big_db.cnf have no writer anywhere in BOA. They are operator markers,
and they are now inert — the barracuda pass no longer seds any long-query
TTL into the deployed database watchdog (/var/xdrago/monitor/check/mysql.sh).
The /root/.barracuda.cnf value is authoritative on every box that carries
the key with a value (which the create and append machinery ensures; a
hand-commented or blanked line is the one narrow escape), because the
watchdog sources that file before its built-in fallback can fire, so set
_SQL_MAX_TTL explicitly when you want a custom ceiling — see
barracuda.cnf. An existing marker file is harmless and
is never removed for you; the upgrade pass simply leaves a one-time advisory
note when it finds one. The retired retune is described on
Discontinued features. .proxy.cnf is
not state either: it is the proxy-node role marker an operator creates,
covered on the Architecture overview.
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 and
control-file indexes are in the
Reference appendix.