Skip to content

Powered by Grav

Overview — the control-file system

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)
  • 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:

    • the *_FORCE_REINSTALL one-shots are never persisted and are scrubbed after use (see barracuda.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.
  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.

    The installer debug markers live in this category and are worth knowing before you ever need them: touch /root/.debug-boa-installer.cnf makes 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.cnf also 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=YES into the master cnf files, so removing the marker alone does not restore quiet output — set _DEBUG_MODE=NO back 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.cnf plus every /root/.*.octopus.cnf (the snapshot precedes the early php-idle branch, 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/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
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/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 Æ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.

© 2026 BOA Documentation. All rights reserved.