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-only —
barracuda up-<tier> systemevery week on a chosen weekday, through theautoupboa weekly-systemwrapper. - One-time full upgrade — full
barracuda up-<tier>plusoctopus up-<tier> all forceon 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. SKYNET's hourly urgency is not paranoia — it was built in direct response to Drupageddon (SA-CORE-2014-005, October 2014), when unpatched Drupal sites were treated as compromised within about seven hours of disclosure; the design goal is that a critical core fix reaches every opted-in box within the hour. The fuller story is under Security history.
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=8writes a day-of-week field of8). 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_UP_HOUR=0 # set explicitly — the 00:15/01:15 defaults apply
_AUTO_UP_MINUTE=15 # only when _AUTO_UP_WEEKLY is also set
_AUTO_OCT_UP_HOUR=1
_AUTO_OCT_UP_MINUTE=15
_AUTO_VER=lts
Without explicit hour/minute values in this weekly-less shape the schedule
fields stay empty and autoupboa skips writing the lines entirely (an empty
field would shift the cron columns and produce a line cron rejects).
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. Theweekly-systemwrapper performs the ICU 7.4intlself-heal (below) and only ever callsbarracudaas 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-*] noscreenandbash /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:
- pins ICU to
73-1(writes_ICU_FORCE_VRN="73-1"to/root/.barracuda.cnf), - rebuilds 7.4 with
intlagainst ICU 73, - 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.
Mind the scope: the self-heal runs only where the weekly upgrade cron line
was actually written — auto-updates configured, and the box not flagged as
a development/scratch server via /root/.dev.server.cnf (the flag is
independent of which BOA branch the box tracks). A box outside that set never
runs the wrapper, so it falls to the manual procedure below.
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.
Manual pin on hosts without auto-updates
On hosts without auto-updates the ICU pin is the operator's responsibility:
run the same pin → rebuild → unpin → rebuild cycle by hand. Substitute your tier
verb (up-lts, up-pro or up-dev):
# 1. Pin ICU to 73 and rebuild: 7.4 gains intl on ICU 73 (8.x rebuild onto 73 too, temporarily)
echo '_ICU_FORCE_VRN="73-1"' >> /root/.barracuda.cnf
barracuda up-<tier> system
# 2. Unpin and rebuild: 8.x return to OS-default ICU 76; 7.4 keeps its ICU-73 intl
sed -i '/^_ICU_FORCE_VRN=/d' /root/.barracuda.cnf
barracuda up-<tier> system
Verify the end state — PHP 7.4 on ICU 73 with intl, PHP 8.x back on ICU 76:
readlink /usr/local/lib/icu/current # -> /usr/local/lib/icu/76.1 after the unpin
/opt/php74/bin/php -m | grep -i intl # -> intl
/opt/php74/bin/php -i | grep -i 'ICU version' # -> ICU version => 73.1
ldd /opt/php74/bin/php | grep -i icu # -> libicu*.so.73 all resolve (no "not found")
/opt/php83/bin/php -i | grep -i 'ICU version' # -> ICU version => 76.1
The _ICU_FORCE_VRN variable is catalogued in the
barracuda.cnf reference.
Both passes rebuild PHP: the pin pass rebuilds every active version onto ICU 73, and the unpin pass rebuilds the 8.x versions back onto ICU 76 — so 8.x are rebuilt twice. The pin pass always compiles from sources (a pinned ICU is a customised build shape, so the prebuilt PHP packages don't apply); the unpin pass can take the prebuilt-package path again. Either way it is a one-time transition cost, but real per-rebuild downtime.
Durability — the pin is transient, but 7.4's intl is not automatically
durable. PHP 7.4 keeps its ICU-73 intl only as long as it is not rebuilt
while unpinned: the build adds --enable-intl for 7.4 only when
_ICU_FORCE_VRN is set, so any forced 7.4 rebuild with the pin off — an OpenSSL
change, a php-min/php-max run, a version bump — silently drops intl again.
A 7.4 left untouched survives later ICU upgrades unharmed, but re-pin before
deliberately rebuilding 7.4.
Do not manually purge old ICU libraries. The transient pin is durable only because ICU runtime libraries are version-suffixed (
libicuuc.so.73,libicuuc.so.76, …) and coexist — installing ICU 76 never removes the ICU 73 libraries that 7.4'sintllinks against. Deleting theso.73set breaks 7.4intleven though nothing else on the box still references it.
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.pkgslists alinuxpackage, orboa inforeports aNext(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 — but only inside the silent
night maintenance window (04:00–04:59 server time). At any other hour the
pass just notes that the reboot is pending and waits for the window, so an
apt security run staging a kernel mid-day can never reboot a box mid-day.
The window is additionally skipped for the whole day when any active
/etc/crontab entry schedules a barracuda or octopus upgrade (directly
or via the autoupboa weekly-system wrapper) for today's date — the reboot
must never land near or inside an upgrade run, so the staged kernel waits
for the next free night instead. Date fields are parsed with crontab(5)
semantics (*, numbers, ranges, steps, lists, names; dom/dow combine as
OR when both are restricted), and an unparseable entry counts as scheduled —
fail-closed for a destructive action.
Before firing, the reboot is announced: an entry is appended to
/var/log/boa/kernel-reboot.log (timestamp, the kernel running until now,
the pending packages) and, when an admin email address is configured, the
same lines are sent as an email alert — so an overnight restart is never a
mystery. Hosted boxes always report to the platform address.
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).
Service teardown on every pass
autoupboa is not only the scheduler. Every plain pass also runs
_if_disable_not_used_services, a janitor that stands unwanted services down.
On a normally configured box that is roughly every five minutes: the */5
root cron entry runs /var/xdrago/clear.sh, which calls autoupboa whenever no
/run/boa_run.pid lock is held.
Two conditions gate the whole function:
_SKYNET_MODE=OFFin/root/.barracuda.cnfmakesautoupboaexit long before the janitor is reached, so every marker in this section becomes inert.- The
weekly-systemwrapper invocation returns first, so the janitor runs only on the plain, cron-driven pass — never on the weekly upgrade line.
None of the markers below is created or removed by BOA. They are operator files that survive upgrades and reboots until you delete them, and none of them is touched by the hosted normalisation block.
The deny family — Jetty 9, Solr 7, Solr 9
Three markers in /etc/boa/ each stand one search-stack service down:
| Marker | Deregisters | Init script moved to | Also killed |
|---|---|---|---|
.deny.jetty9.cnf |
jetty9 |
/var/backups/jetty9.initd |
jetty9, avahi-daemon |
.deny.solr7.cnf |
solr7 |
/var/backups/solr7.initd |
solr7, avahi-daemon |
.deny.solr9.cnf |
solr9 |
/var/backups/solr9.initd |
solr9, avahi-daemon |
Each arm is inner-guarded on its /etc/init.d/<service> still being present. When
it is, BOA runs update-rc.d -f <service> remove, moves the init script into
/var/backups, then pkill -9s the daemon and avahi-daemon with it. A marker
dropped on a box that never had the service is a no-op.
The teardown is not permanent, but nothing in the janitor undoes it. Clearing the switch — deleting the marker and leaving the variable at
NO— stops the arm firing, and that pass puts nothing back. What restores the service is the Solr installer, which is gated on/root/.deny.java.cnf/_DENY_JAVAalone and never on these three markers, so a laterbarracuda up-<tier>UPGRADE pass with_ALLOW_HEAVY_REBUILDS=YESre-lays the init script and runsupdate-rc.dagain: straight away for Jetty 9, whose arm rewrites/etc/init.d/jetty9whenever it is missing, and on the next version bump for Solr 7 and Solr 9, whose init scripts come back withinstall_solr_service.sh. The one thing that never returns on its own is the copy parked in/var/backups— it stays behind as a stale duplicate, so tidy it up yourself.
/root/.deny.java.cnf is the superset of all three: one arm tears down solr9,
solr7 and jetty9 together and adds pkill -9 -f java, and the same switch
also stops Barracuda installing or upgrading Solr at all. _DENY_JAVA=YES in
/root/.barracuda.cnf is the supported switch; the marker file stays honoured for
one release, and while it exists it wins, so switching back off means setting
_DENY_JAVA=NO and removing the file. It is documented with the
Solr installer internals.
ClamAV — the missing allow file is the active state
/root/.allow.clamav.cnf and /root/.deny.clamav.cnf are a pair, and their
polarity is the opposite of the deny family above. The teardown arm is
negated:
if { [ ! -e "/root/.allow.clamav.cnf" ] \
&& ! grep -qiE "^[[:space:]]*(export[[:space:]]+)?_ALLOW_CLAMAV=[\"' ]*YES" /root/.barracuda.cnf 2>/dev/null; } \
|| [ -e "/root/.deny.clamav.cnf" ] \
|| grep -qiE "^[[:space:]]*(export[[:space:]]+)?_DENY_CLAMAV=[\"' ]*YES" /root/.barracuda.cnf 2>/dev/null; then
The braces are load-bearing: they keep the allow-file test and its variable arm as one negated unit, so either form of the opt-in satisfies it, while either form of the deny still overrides.
So a box carrying neither form of the opt-in is torn down on every pass — that
is the default. BOA still installs clamav, clamav-base, clamav-daemon and
clamdscan on a fresh install and on every full upgrade pass, so the daemons are
present but parked: both init scripts are deregistered and moved into
/var/backups, clamd and freshclam are killed, and /run/clamav/* is cleared.
To keep ClamAV running, set _ALLOW_CLAMAV=YES in /root/.barracuda.cnf (the
/root/.allow.clamav.cnf marker stays honoured for one release);
_DENY_CLAMAV=YES or the deny marker overrides it wherever it appears. On its own
the deny changes nothing, because the absence of the allow already denies. The
marker file wins while it exists, so switching the opt-in back off means setting
_ALLOW_CLAMAV=NO and removing /root/.allow.clamav.cnf. Both keys belong in
the system cnf only — a same-named line in an Octopus cnf is unsupported.
Through this transition, keep the marker file alongside the variable. The two slow-cycle OS-upgrade drivers,
autochimaeraandautodaedalus, are refreshed only through the release-latched tool update, so they learn the variable when the next release serial reaches them. Until the release after this one, pair_ALLOW_CLAMAV=YESwithtouch /root/.allow.clamav.cnf: a major OS upgrade driven by a still-stale driver would tear ClamAV down on a variable-only box.
The same negated test is repeated in six places, so the pair is honoured well
beyond autoupboa. The four codename upgrade drivers — autobeowulf,
autochimaera, autodaedalus, autoexcalibur — deregister the two init scripts
under it while standing the box down for a major OS upgrade, though they do not
move the files aside. /etc/init.d/clean-boa-env does the same on its stop
path, and skips that whole block while a major-OS-upgrade reboot marker is still
pending.
There is exactly one positive reader. The system monitor's
_clamav_health_check_fix restarts clamav-daemon or clamav-freshclam when it
finds them down, but only when all of these hold: the allow is set in either form,
neither deny form is set, /data/u exists, and both init scripts are still in
/etc/init.d.
It also returns early whenever /run/max_load.pid or /run/critical_load.pid
exists, and the monitor as a whole exits on a box that is not fully installed. The
/data/u condition means the auto-restart never fires on a host without the
Octopus disk layout.
Neither file has a BOA writer. The one write that mentions the deny file — inside
the freeze branch below — is [ -e … ] && touch, which only refreshes the
timestamp of a file you already created. The upgrade pass that mirrors a marker
into its variable writes the cnf, never the marker.
Freezing a development-tree VM
/etc/boa/.ice.vm.cnf is the first and by far the most destructive arm of the
same function, and it is doubly gated: the marker must exist and the deployed
autoupboa must carry the dev delivery-tree stamp (_tRee=dev, set at the top
of the tool itself — /root/.barracuda.cnf never overrides it). On a pro or
lts box the branch never runs.
Where it does run, it re-runs on every pass and:
- truncates six scripts to a blank line —
/var/xdrago/move_sql.sh,proc_num_ctrl.pl,runner.sh,monitor/check/nginx.sh,monitor/check/mysql.shandmysql_backup.sh; - deletes the
aegircrontab (/var/spool/cron/crontabs/aegir); - kills
pure-ftpdandnewrelic-daemon; - stops nginx, MySQL, Valkey and Redis wherever their run files exist, and kills
every
php-fpmprocess when/run/php83-fpm.pidis there; - refreshes the timestamp of
/root/.deny.clamav.cnfand/root/.deny.java.cnfif you already created them — it never creates either. The refresh touches the marker files and nothing else: it never sets_DENY_CLAMAVor_DENY_JAVA, so a box that opted in by variable alone has nothing refreshed here.
One-way. Nothing reverses the freeze. Removing the marker stops further passes, but it restarts no daemon, restores neither the
aegircrontab nor the blanked scripts, and leaves whatever the ClamAV and Java arms did in place. Treat it as a deliberate, manually recoverable shutdown of a development VM, never as a pause switch.
Any arm that actually did something sets an internal flag, and the janitor finishes by dropping the kernel page cache — but only when RAM usage is already above 90%.
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 [email protected]; forced to <tool>@omega8.cc
on a BOA-hosted box). There is no _EMAIL_USER_ADM variable.
Requesting a full status report
/etc/boa/.run.example.report.cnf is a one-shot request for a complete status
report. On the pass that lands on the top of the hour, _send_boa_system_report
runs boa info report both, mails the output and deletes its temporary body file.
(The test is _TIME equal to 1200 or _MINUTE equal to 00; since 12:00
already has minute 00, the effective window is the top of every hour — one pass
in twelve.)
Two current limits matter before you rely on it:
- It only ever sends on a BOA-hosted box. The recipient and BCC addresses
(
[email protected], with[email protected]in BCC) are set inside the_hostedSys=YESbranch and nowhere else, and the send is skipped while either is empty. On an ordinary operator host the marker is inert — it produces no report and no error. - On a hosted box the marker is erased roughly every five minutes. The hosted normalisation block, later in the same run, removes it unconditionally, and the reader never removes it after a send. A request created at any other minute of the hour is therefore wiped before the send window arrives, and the report is silently dropped. Within a single top-of-the-hour pass the send happens first and the wipe second, so a marker that is already in place when the hour rolls over does get its one report.
Like the teardown markers above, the whole path is inert while
_SKYNET_MODE=OFF, because autoupboa exits before it.
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=OFFin/root/.barracuda.cnfit still runs: an interactive (SSH TTY) run printsSTATUS: BOA Skynet Agent is Inactive!andNOTE: 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_MODEis catalogued in the barracuda.cnf reference._update_agents— Skynet-active boxes only. Refreshes the cron agents, the monitor/night scripts, and a few bin tools scoped to installed Skynet-active boxes; the core tool set itself is fetched only by_update_boa_tools.
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
--guardpgrep check refuses to overwrite a currently-running tool (The <name> is running!); - the download lands in a private temp file and only replaces the live copy
via an atomic
mvafter it passes validation — curl reported success, the body is non-empty, it is not the mirror's HTML "Under Construction" stub, and (for sentinel-protected files such aswebsh) it carries the required token near its end; - the stamp is written only after a successful, validated fetch, and even a current stamp is re-checked against the mirror once it ages past the revalidation window (24 h default), so stale bytes self-heal.
The design intent: a lagging mirror or a transient failure leaves no stamp, so the fetch is retried on the next run, and a partial or wrong 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/bin are fetched the same per-file
way:
fix-drupal-platform-permissions.shfix-drupal-site-permissions.shfix-drupal-platform-ownership.shfix-drupal-site-ownership.shlock-local-drush-permissions.shfix-drupal-site-symlinks.sh
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
fNNserials count DOWN fromf99. A forced refresh of a tool is a decrement (f99→f98), never a value the tool already used. - The old
_bTsfunction latch is retired._update_boa_toolsused to run once per release behind aupdateBOAtools.<_bTs>.ctrl.…stamp; it now runs on every pass and every path, each tool line self-gating on its ownfNNstamp — so a bumped tool serial reaches every box (including_SKYNET_MODE=OFFboxes) on the next tick, with no release involved. _xSrl/_rLsnidentify the release train the stamps belong to.
One core-tool list, one owner
Each tool has exactly one fetch line. The core tool set lives only in
_update_boa_tools, which runs before BOA is even installed and is the only
updater left under _SKYNET_MODE=OFF, so every class of box gets it;
_update_agents fetches only the monitors, system scripts and the few extra
tools that exist solely on installed Skynet-active boxes. (Historically the
core list was duplicated into _update_agents to work around the
once-per-release latch; that duplication — and its bump-both-together serial
discipline — is gone.)
Related
- Manual BOA upgrade reference — the interactive
up-*commands SELFUPGRADE schedules. - Automated codename upgrades — OS-level chains (distinct from this software scheduler).
- barracuda.cnf reference — the
full
/root/.barracuda.cnfreference (_AUTO_*,_ICU_FORCE_VRN). - Reference appendix — consolidated
_VARtable.