Branches, editions & licensing
BOA releases along three trees — lts, pro, dev. A tree is three things
at once, and the same short name is load-bearing in all three places:
- a public git branch
5.x-<tree>ingithub.com/omega8cc/boa; - a mirror payload tree
https://files.boa.io/versions/<tree>/that every installed box fetches from; - an identity stamp shipped inside the code itself:
export _tRee=<tree>+export _xSrl=<serial>(lib/settings/barracuda.sh.cnf:1319-1320).
Everything on this page hangs off that mapping. Get the tree wrong and you are not publishing to a branch — you are publishing to a fleet.
The public branch scheme
Nine active branches in omega8cc/boa, three per tree:
| Branch | Role |
|---|---|
5.x-dev |
Main development line. Everything lands here first. Default branch (origin/HEAD → 5.x-dev), default PR target. |
5.x-dev-base |
Slower cut of 5.x-dev: proven, non-breaking commits only. |
5.x-dev-edge |
Experimental staging for the dev line. |
5.x-pro |
Stable PRO release branch. Tag target. |
5.x-pro-base |
PRO testing; receives promotions from 5.x-dev-base. |
5.x-pro-edge |
Experimental staging for 5.x-pro-base. |
5.x-lts |
Stable LTS release branch. Tag target. |
5.x-lts-base |
LTS testing; receives promotions from 5.x-dev-base. |
5.x-lts-edge |
Experimental staging for 5.x-lts-base. |
Two consumption facts keep this scheme honest:
- Installer code only ever consumes the three tree tips. The branch a box
clones is computed as
_bRnh="5.x-${_tRee}"(aegir/tools/bin/barracuda:1967); the strings5.x-dev-base,5.x-*-edgeetc. appear nowhere inBARRACUDA.sh.txt,OCTOPUS.sh.txt,BOA.sh.txt,lib/oraegir/. The-baseand-edgebranches are maintainer staging only — breaking one inconveniences maintainers, breaking a tree tip reaches customers. - The Ægir forks track the same tree names, without the staging tiers.
Each fork carries
5.x-dev/5.x-pro/5.x-lts(no-base/-edge), and every clone resolves to5.x-<tree>— but by two different mechanisms. The core forks (hostmaster,hosting,eldir,hosting_civicrm,hosting_deploy,hosting_git,hosting_le, and the rest) are cloned with a literal5.x-${_tRee}branch (lib/functions/master.sh.inc:576-588), whereasprovisionis cloned at the sed-rewritten_BRANCH_PRNvariable (lib/functions/master.sh.inc:688,793) — the same value, a different path to it. All fork clones resolve against_gitHub="https://github.com/omega8cc"(BARRACUDA.sh.txt:183,OCTOPUS.sh.txt:184) — omega8cc is the upstream; pre-fork remotes are irrelevant.
Historical branches (5.x-head, 5.x-lite, 5.x-lts-oldstable, 4.x*,
master, feature/*) are relics kept for archaeology. Never target them.
How the tree name propagates through code
barracuda up-lts | up-pro | up-dev is the single entry point that binds a box
to a tree. _set_tree_vars (aegir/tools/bin/barracuda:1925-1970) exports:
export _tRee=lts|pro|dev # from the up-* verb
export _rLsn="BOA-5.10.3" # release version, hardcoded per release
export _rlsE="${_rLsn}-${_tRee}"
export _bRnh="5.x-${_tRee}" # git branch consumed in GIT download mode
export _rgUrl="https://files.boa.io/versions/${_tRee}/boa"
_proceed then fetches the next-stage installer and its settings from the
tree's mirror path — BARRACUDA.sh.txt and lib/settings/barracuda.sh.cnf
(barracuda:20-22,1834-1835) — and stamps the tree into the fetched settings
before executing:
_BRANCH_BOA/_BRANCH_PRNare sed-rewritten fromAUTOto5.x-${_tRee},_AEGIR_VERSIONto${_tRee},_X_VERSIONto${_rlsE}(barracuda:867-905).
A staged build tree of another tree is never reused: every published tar
bakes its tree name into the libs (export _tRee= in lib/functions/*.inc),
and _download_boa_code drops /opt/tmp/boa with a NOTE: naming both trees
when the staged name differs from the running one, before the marker probe
that cannot tell trees apart. Without it a switch at the same release number
(lts to pro when a licence arrives, dev to pro on a box that kept its tree)
ran the old tree's code while logging the new one. Same-tree reuse across
steps and bulk upgrades is unchanged.
In GIT download mode the BOA codebase is cloned as
git clone --branch ${_BRANCH_BOA} ${_BOA_REPO_GIT_URL}/boa.git
(lib/settings/barracuda.sh.cnf:1636).
octopus up-lts | up-pro | up-dev applies the same tree gate per satellite
instance — the up-* verb sets export _tRee=lts|pro|dev
(aegir/tools/bin/octopus:1129-1136). The daily runtime uses the same
mapping: _urlHmr="https://${_USE_MIR}/versions/${_tRee}/boa/aegir"
(aegir/tools/system/owl.sh:150).
Tree transitions are one-way. _barracuda_downgrade_protection
(barracuda:432-467) refuses up-lts once /var/log/barracuda_log.txt
records a -pro or -dev release: LTS → PRO/DEV is a ratchet, there is no
downgrade path. Octopus mirrors the refusal per instance in
_satellite_downgrade_protection (octopus:315-356).
Remember this when testing: a box flipped to dev to reproduce a bug cannot be
flipped back with an up-* verb. up-dev also
drops /root/.debug-boa-installer.cnf and /root/.debug-octopus-installer.cnf
(barracuda:1813-1816), so dev-tree boxes run the installers in debug mode by
design.
Release identity: version string and serial
Each release cut carries two identities:
- Version string —
_rLsn="BOA-5.10.3"hardcoded inaegir/tools/bin/barracuda:1965, suffixed per tree toBOA-5.10.3-lts/-pro/-dev(_rlsE). This is whatbarracuda_log.txt, the downgrade ratchet and the release-notice email compare against. - Release serial —
_xSrl, formNNNN<tree>TNNwhereNNNNsquashes the version (5103↔ 5.10.3) and theTNNsuffix increments across successive pushes within one version line. Each tree branch carries its own value:5103devT01on5.x-dev,5103ltsT01on5.x-lts,5103proT01on5.x-pro(lib/settings/barracuda.sh.cnf:1319-1320per branch; also exported ataegir/tools/bin/autoupboa:7). The serial namespaces control stamps and lock/PID files fleet-wide (e.g./var/log/boa/.etc_crontab_update_prod_ctrl_5103v01.${_tRee}.${_xSrl}.pid,autoupboa:1218-1233), so bumping it is what makes one-shot maintenance blocks re-run after a release.
The per-file fNN fetch serials in BOA.sh.txt (_fetch_versioned) are a
separate, finer-grained mechanism for shipping individual tool updates between
releases; they ride the same versions/<tree>/ mirror paths but are not part
of the release identity described here. See
The serial & fetch pipeline (SKYNET) for their
mechanics.
Tags — the release act. Never tag casually
Release-triggering tags — the ones that publish to the mirror and drive SKYNET
— are applied only to 5.x-pro and 5.x-lts. Two naming families, both
in active use:
- version tags:
BOA-5.9.1-lts,BOA-5.9.1-pro,BOA-5.9.3-pro,BOA-5.8.5-lts,BOA-5.8.5-pro, … - serial tags matching
_xSrl:5103ltsT01(on the5.x-ltstip),5103proT01(on the5.x-protip),5101ltsT01,5101proT01, …
Only the pro / lts version tags are the release act that triggers a
SKYNET publish. 5.x-dev is not the release trigger — dev boxes track the
branch tip continuously — but it is not untagged: dev serial tags matching
_xSrl (e.g. 500devT02, 570devT11) are cut on the 5.x-dev tip, and the
dev tree still publishes its own release pin.
owl.sh fetches
https://files.boa.io/versions/dev/boa/aegir/conf/version/barracuda-release.txt
for the dev tree exactly as for pro / lts — the mirror path is
versions/${_tRee}/… with no per-tree exception
(aegir/tools/system/owl.sh:150,349-390) — so dev-tree boxes also get the
"upgrade now" notice on mismatch.
A tag is not bookkeeping — it is the release act. The tagged state is what the
release process publishes to the tree's files.boa.io/versions/<tree>/ mirror
payload, and that mirror is polled by every installed box running the SKYNET
agent. The fleet-facing machinery, all shipped in the codebase:
- Daily version check. The daily runner fetches
${_urlHmr}/conf/version/barracuda-release.txtwhenever_SKYNET_MODEis unset orON, compares against/var/log/barracuda_log.txt, and emails the admin an "upgrade now" notice on mismatch (aegir/tools/system/owl.sh:349-390). - Daily tool refresh.
BOA.sh.txtrefetches individual tools from the tree's mirror path, gated byfNNserials; even with_SKYNET_MODE=OFFthe run still updates critically important tools before exiting (BOA.sh.txt:3592,4473-4494). - Weekly auto-upgrade. On boxes with auto-updates enabled,
_crontab_updatewritesautoupboa weekly-system up-<tree> system [php-*] noscreeninto/etc/crontab, plus monthly fullbarracuda up-<tree> logandoctopus up-<tree> all force loglines (aegir/tools/bin/autoupboa:921-976)._AUTO_VERdefaults to the box's own tree (autoupboa:1060), so every box upgrades within its tree, unattended.
Consequence: a bad tag-and-publish on 5.x-pro or 5.x-lts propagates to
every production box on that tree within its cron cadence — there is no
staged-rollout tier between the tag and the fleet. Test on the -base /
-edge branches and on dev-tree boxes first; treat the tag as the last
irreversible step.
Per-box opt-outs exist (_SKYNET_MODE=OFF in
/root/.barracuda.cnf; the /root/.turn.off.auto.update.cnf lock,
autoupboa:1180-1215) but you must assume the default: SKYNET on,
auto-updates live.
How a release flows: dev → base → pro/lts
The promotion path is maintainer process, not code — the code only defines the consumption points above. The intended flow:
- Land on
5.x-dev. All feature and fix work merges here first; dev-tree boxes pick it up continuously. - Graduate to
5.x-dev-base. Commits proven non-breaking on the dev tip are promoted;-baseis the slower, stabilising cut. - Promote to
5.x-pro-baseand5.x-lts-base. Both stable lines take their input from5.x-dev-base— never directly from5.x-dev. The LTS line is kept current alongside PRO: security updates and feature work cross into5.x-lts-baseas well. - Stage experiments on
-edge. Each line's-edgebranch holds experimental work for that line; nothing ships from-edgedirectly. - Cut the release. When a
-basebranch is release-ready it lands on the tree tip (5.x-pro/5.x-lts) together with the release bookkeeping: the_rLsnbump inbarracuda, the per-tree_tRee/_xSrlstamps inbarracuda.sh.cnf,CHANGELOG.txt, and a release announcement underreleases/(e.g.releases/BOA-5.10.3-PRO.md). - Tag and publish. The tip is tagged (
BOA-X.Y.Z-<tree>+ serial tag) and the tagged state is published toversions/<tree>/on the mirrors, wherebarracuda-release.txtflips the fleet's version check.
Editions and licensing
The legal text is DUALLICENSE.md at the repo root. Model: all BOA code is
Free/Libre open source; what is licensed is running the commercial trees.
The dev and pro branches are public (barracuda help states the terms
inline: up-lts "no license", up-pro / up-dev "requires license"), and
the installers enforce the licence with a hostname key check,
_verify_boa_keys, that runs on the pro and dev trees only — lts
never checks. Every entry point carries its own copy of the check:
BOA.sh.txt (the agent pass), the barracuda and octopus settings
includes (lib/settings/*.sh.cnf, so every up-pro / up-dev run and every
in-pro / in-dev install), and the PRO backup tools dcysetup and
multiback (the dormant duplicity bundle installer in the same tree carries
the same copy). The check hashes the box hostname (md5 of /etc/hostname),
fetches enc/2024/<hash> from the mirror and compares it with the local
<hostname>.<hash>; a mismatch ends the run with "Your system requires valid
license". Two hostname classes pass without a mirror-side key:
- hostnames of the Omega8.cc-managed fleet, on both licensed trees;
*.sslip.iohostnames (wildcard DNS that resolves to the IP embedded in the name, so a throwaway box needs no DNS setup), on the dev tree only — this is what lets the end-to-end test suites run againstdevon ephemeral boxes without a per-box key, whileprostays licensed on every hostname outside the fleet domains (since 2026-09-03;DUALLICENSE.mdnames this testing exception under the DEV branch).
Both passes skip the key comparison, not the fetch. When the mirror cannot be
reached at all, the two key-free classes log NOTE: the key server could not be reached; <host> is allowed on the <tree> tree by its hostname and continue
(a pass relaunched seconds after a reboot, with the resolver still down, used to
be refused here and park an upgrade chain); every other hostname still ends
the run ("it was not possible to verify your system status").
| Edition | Tree | Cost | Cadence |
|---|---|---|---|
| LTS | lts |
Free, no licence (previously named HEAD/STABLE) | Kept current alongside PRO — frequent security updates and new-feature work |
| PRO | pro |
Commercial licence | Stable feature releases, cut from tested dev work |
| DEV | dev |
Commercial licence (install and upgrades); *.sslip.io test hostnames are the licence's stated testing exception |
Continuous; latest features, not for unattended production |
Edition mechanics worth knowing when you maintain the code:
- LTS is kept current. The LTS line receives frequent security updates
and serious new-feature work alongside PRO (
DUALLICENSE.md); no feature-freeze is planned or expected. The editions are kept 1:1: the only PRO-only feature is the extended backup sub-system (ROADMAP.mdtracks it in its RELEASED IN BOA PRO only section), designed as something extra for those who decided to support BOA with a licence subscription. - PRO is positioned as an upgrade.
DUALLICENSE.mdoffers PRO as an upgrade from LTS or DEV (theup-*ratchet above matches: LTS → PRO is one-way), though the installer dispatch does accept a directboa in-prothat sets_tRee=pro(aegir/tools/bin/boa:3099, dispatch case atboa:3037). - PRO support tiers are support-only. Basic (GitHub issue queue),
Advanced (private helpdesk, best-effort, Site24x7 monitoring included) and
Hands-Off Experience (fully managed by Omega8.cc under SLA) all run the
same
5.x-procode — the tiers differ in support level, never in the code a box receives (DUALLICENSE.md). - OMM is a code variant, not a tier.
DUALLICENSE.mddescribes OMM as a private branch managed separately — components removed/added, simplified, modernised. Do not conflate it with the PRO Hands-Off support tier: one is a codebase, the other is a service level. OMM appears nowhere in the public branch scheme or the installer tree logic.
For maintainers the practical rule set is:
- feature work targets
5.x-dev; - LTS and PRO take the same work — the editions are kept 1:1, so whatever is promoted towards one stable tree is promoted towards the other;
- the moment a change is meant to reach
5.x-proor5.x-ltstips, the tag-and-publish consequences above apply.
Related
- Contributing to BOA — where PRs and
bug reports go;
5.x-devas the default target. - Code style — the conventions promoted code must already satisfy before it can graduate towards a tree tip.
- The serial & fetch pipeline (SKYNET) — how
_xSrland the per-filefNNserials drive the fleet fetch/refresh machinery.