SELFUPGRADE reference

SELFUPGRADE is BOA's cron-driven upgrade scheduler. You set _AUTO_UP_* variables in /root/.barracuda.cnf; autoupboa reads them, refreshes the meta-installers, and (re)writes the upgrade cron lines into /etc/crontab. Two flavours run from the same configuration:

  • Weekly system-onlybarracuda up-<tier> system every week on a chosen weekday, through the autoupboa weekly-system wrapper.
  • One-time full upgrade — full barracuda up-<tier> plus octopus up-<tier> all force on a chosen month/day.

Pair this with SKYNET (the tag-driven auto-update, left on by default) for a hands-off production host: SKYNET handles security urgency between windows; SELFUPGRADE handles the predictable cadence.

Enabling: the three primary variables

In /root/.barracuda.cnf:

# All three must be set, or no auto-upgrade cron is written.
_AUTO_UP_WEEKLY=    # Day of week (1-7) for the weekly system upgrade
_AUTO_UP_MONTH=     # Month (1-12) for the one-time full upgrade
_AUTO_UP_DAY=       # Day (1-31) for the one-time full upgrade

# Optional — defaults shown in "Default timing" below.
_AUTO_VER=          # BOA tier passed to up-: lts | pro | dev (default: this host's tier)
_AUTO_PHP=          # PHP scope token: php-min | php-max | php-all

# Optional schedule tuning (fall back to BOA defaults if unset).
_AUTO_UP_HOUR=      # Hour (0-23) for the barracuda pass
_AUTO_UP_MINUTE=    # Minute (0-59) for the barracuda pass
_AUTO_OCT_UP_HOUR=  # Hour (0-23) for the octopus pass
_AUTO_OCT_UP_MINUTE=# Minute (0-59) for the octopus pass

Validate the ranges yourself. Out-of-range values are interpolated verbatim into the cron expression (_AUTO_UP_WEEKLY=8 writes a day-of-week field of 8). BOA does not reject them; an invalid field produces a cron line that never fires — or, worse, breaks subsequent scheduled jobs.

_AUTO_VER — the tier token

_AUTO_VER is interpolated literally into the command autoupboa emits (up-${_AUTO_VER} …), so it must be a tier barracuda/octopus accept: lts, pro or dev. There is no head value — up-head is rejected by both meta-installers. When _AUTO_VER is unset, autoupboa falls back to this host's own tier (${_tRee}), so on an LTS host the default is lts; set it explicitly only to override.

_AUTO_VER=pro      # or: dev  (dev follows the development tip — not for production)

_AUTO_PHP — the PHP scope

_AUTO_PHP accepts three values, each passed straight through as the PHP token of the upgrade command:

_AUTO_PHP=php-min   # recommended set: PHP 8.5, 8.4, 8.3 (8.4 default)
# _AUTO_PHP=php-all # same recommended set (synonym of php-min in this path)
# _AUTO_PHP=php-max # every supported PHP version

php-min and php-all resolve to the same recommended set; php-max is the only value that rebuilds every supported version. Left empty, the upgrade runs with no explicit PHP token (BOA's own default scope). Setting php-min/php-all re-installs the recommended versions on each scheduled window — handy if you prune aggressively and want the standard set rebuilt automatically.

Common schedule patterns

Weekly system-only (typical production)

System upgrade every Wednesday shortly after midnight, no Octopus touch:

_AUTO_UP_WEEKLY=3
_AUTO_UP_MONTH=2     # placeholder — required to enable, no full run lands on it unless the day matches
_AUTO_UP_DAY=29      # placeholder
_AUTO_VER=lts

The weekly line runs only barracuda up-<tier> system — fast, narrow, no Octopus instances touched.

One-time full upgrade

Full barracuda up-<tier> + octopus up-<tier> all force on a specific date:

_AUTO_UP_WEEKLY=    # empty — no weekly line
_AUTO_UP_MONTH=10   # October
_AUTO_UP_DAY=15     # 15th
_AUTO_VER=lts

Default timing

When the three primary variables are set and the optional time variables are empty, BOA applies:

  • Weekly system upgrades start at 00:15 on the chosen weekday.
  • Full one-time upgrades start at 00:15 for system + Master and 01:15 for Octopus instances.

BOA-hosted boxes (_hostedSys=YES) carry their own hardcoded internal schedule — 03:10 / 04:10 — set automatically and not relevant to ordinary operator hosts. Override per-host with _AUTO_UP_HOUR / _AUTO_UP_MINUTE / _AUTO_OCT_UP_HOUR / _AUTO_OCT_UP_MINUTE; staggering windows across many hosts avoids them all hitting the mirror at once.

The cron lines autoupboa writes

autoupboa emits up to three lines into /etc/crontab, and the weekly line is deliberately not the same shape as the full lines:

  • Weekly system line — through the wrapper: bash /opt/local/bin/autoupboa weekly-system up-<tier> system [php-*] noscreen. The weekly-system wrapper performs the ICU 7.4 intl self-heal (below) and only ever calls barracuda as a leaf process — it never re-enters itself.
  • One-time full lines — direct to the meta-installers: bash /opt/local/bin/barracuda up-<tier> log [php-*] noscreen and bash /opt/local/bin/octopus up-<tier> all force log noscreen.

The noscreen token marks these as silent, non-interactive scheduled runs (no screen session). Note the directionality: autoupboa invokes barracuda and octopus, never the reverse — barracuda is always a leaf call, so there is no self-recursion loop.

ICU 7.4 intl auto-heal on the weekly run

Where auto-updates are enabled, the weekly-system wrapper guards a specific regression: a system ICU bump to 76 can rebuild PHP 7.4 without intl. On each weekly run the wrapper checks php -m for PHP 7.4 and, only if intl is missing, transparently:

  1. pins ICU to 73-1 (writes _ICU_FORCE_VRN="73-1" to /root/.barracuda.cnf),
  2. rebuilds 7.4 with intl against ICU 73,
  3. unpins so the 8.x versions return to OS-default ICU 76 while 7.4 keeps its ICU-73 intl.

It is self-limiting — once 7.4 carries intl, detection is false and the plain weekly upgrade runs. A resume marker (/var/log/boa/.php74_intl_bootstrap.active) makes it interrupt-safe: a leftover marker means a prior run pinned but did not unpin, so the next run clears the pin before deciding. On hosts without auto-updates the ICU pin is the operator's responsibility; the _ICU_FORCE_VRN variable is catalogued in barracuda.cnf reference.

Unattended reboot after a kernel upgrade

A scheduled OS pass can leave a new kernel pending. By default an ordinary (non-hosted) box does not reboot itself — it prints a notice on the final upgrade stage and leaves the reboot to you:

NOTE: Your OS kernel has been upgraded
NOTE: Please reboot this server to activate the new kernel
NOTE: Use 'boa reboot' command for optimized reboot

To opt into unattended reboots, create the marker:

touch /root/.allow.auto.reboot.cnf

On every autoupboa pass, when the host is BOA-hosted (_hostedSys=YES) or this marker exists, autoupboa runs _if_new_kernel_reboot. It treats a kernel as pending when either signal fires:

  • /run/reboot-required.pkgs lists a linux package, or
  • boa info reports a Next (pending) kernel line — printed only when the running and next kernel differ.

If a kernel is pending it triggers BOA's accelerated reboot in the background (nohup /opt/local/bin/boa reboot) and exits. The check is skipped during a protected run — when _is_protected_run detects a concurrent autoinit/automini/barracuda/boa/octopus process or one of the octopus_install_run.pid / boa_run.pid / boa_wait.pid run-locks — so it never reboots mid-upgrade.

Behaviour-changing. An opted-in box reboots itself unattended after a kernel bump. The marker stays in /root (it is not relocated to /etc/boa).

Logs and notifications

Auto-upgrade output lands in:

  • /var/backups/reports/up/barracuda/* — per-run barracuda log
  • /var/backups/reports/up/octopus/* — per-run octopus log
  • /var/log/boa/ — BOA operational log (includes auto-upgrade events)

Both the system and Octopus reports are emailed to _MY_EMAIL from /root/.barracuda.cnf (default notify@omega8.cc; forced to <tool>@omega8.cc on a BOA-hosted box). There is no _EMAIL_USER_ADM variable.

Disabling SELFUPGRADE

Blank any of the three primary variables:

_AUTO_UP_WEEKLY=
_AUTO_UP_MONTH=
_AUTO_UP_DAY=

Auto-upgrade stops on the next BOA cron pickup (within an hour). This does not disable SKYNET — that is a separate tag-driven mechanism with its own supported switch, _SKYNET_MODE=OFF in /root/.barracuda.cnf — and even that switch keeps the critical tools updating, as the next section explains.

How the fleet updates its own tools

SELFUPGRADE schedules the meta-installers; the tools themselves — barracuda, octopus, boa, autoupboa and the rest of /opt/local/bin — are kept current by the BOA.sh.txt agent, the same script that the bootstrap one-liner (wget -qO- https://files.boa.io/BOA.sh.txt | bash) executes and the SKYNET cron re-fetches. Two updater tiers live inside it:

  • _update_boa_tools — runs on every path and tier. On the normal bootstrap path it runs from _boa_setup. With _SKYNET_MODE=OFF in /root/.barracuda.cnf it still runs: an interactive (SSH TTY) run prints STATUS: BOA Skynet Agent is Inactive! and NOTE: Critically important BOA tools will be still updated, refreshes the key tools (via _if_update_boa_key_tools_only, which calls _update_boa_tools), and exits before anything else; a non-interactive (cron) run does the same refresh silently and exits. This is why the section above says blanking the _AUTO_* variables does not disable SKYNET — and why even SKYNET's own off-switch does not stop core-tool updates. _SKYNET_MODE is catalogued in the barracuda.cnf reference.
  • _update_agents — Skynet-active boxes only. Refreshes the cron agents, the monitor/night scripts, and the same core tools, but runs only when SKYNET is active on an installed box.

Per-file versioned fetches

Since BOA-5.10.3 both tiers fetch every tool per-file through a shared helper, _fetch_versioned. A file counts as current only when its stamp /var/log/boa/<name>.ctrl.<serial>.<tree>.<xSrl>.pid exists and the file on disk is non-empty (and its managed symlink is intact, where one is used). Around every fetch:

  • a --guard pgrep check refuses to overwrite a currently-running tool (The <name> is running!);
  • the old copy is moved to <file>.old before the download and restored if the fetch comes back empty;
  • the stamp is written only after a successful, non-empty fetch.

The design intent: a lagging mirror or a transient failure leaves no stamp, so the fetch is retried on the next run, and a zero-byte download can never destroy a working tool. (The pre-5.10.3 bulk loop tested -e rather than -s and stamped a one-shot marker even on failure, so a partial fetch was never retried until the next release.)

The privileged root helpers in /usr/local/binfix-drupal-platform-permissions.sh, fix-drupal-site-permissions.sh, fix-drupal-platform-ownership.sh, fix-drupal-site-ownership.sh, lock-local-drush-permissions.sh, fix-drupal-site-symlinks.sh — are fetched the same per-file way.

Serial conventions (read-only plumbing)

None of these are barracuda.cnf variables — they ship inside the agent and are never set by the operator:

  • Per-tool fNN serials count DOWN from f99. A forced refresh of a tool is a decrement (f99f98), never an increment.
  • _bTs (format 5103vNN, counting UP within a release) gates the whole _update_boa_tools pass once per value, via /var/log/boa/updateBOAtools.<_bTs>.ctrl.<tree>.<xSrl>.pid — so any behaviour change to that function ships together with a _bTs bump.
  • _xSrl / _rLsn identify the release train the stamps belong to.

One core-tool list, two owners — by design

The core-tool list is intentionally duplicated between _update_boa_tools and _update_agents. _update_boa_tools must fetch the core tools independently because it runs before BOA is even installed and is the only updater left under _SKYNET_MODE=OFF. A tool present in both lists shares one stamp name, so by design its serial must be bumped in both functions together — a divergent serial would make each run wipe the other's stamp and refetch every cycle. The two functions are not a deduplication candidate.

Related