Skip to content

Latest commit

 

History

History
225 lines (186 loc) · 11.2 KB

File metadata and controls

225 lines (186 loc) · 11.2 KB

Building os-bind-rp

Build inputs

Build a release branch in the FreeBSD release declared by that branch's .resolver-plugins/upstream.json. The profile contains exactly these immutable inputs:

  • series and upstream_branch: the OPNsense stable series being built.
  • upstream_commit: the OPNsense plugins source commit.
  • tools_tag: the matching numeric opnsense/tools release tag.
  • freebsd_release: the value of OS?= in config/<series>/build.conf at that tools_tag.
  • core_commit: the exact OPNsense core Git commit used to configure the package repository. The build checks out and verifies this commit directly; it does not trust the bytes of a GitHub-generated archive.
  • core_archive_url and core_archive_sha256: legacy provenance fields kept in existing release profiles. They are not the build-time trust anchor.

Do not substitute a moving branch, a current tools checkout, or an unverified core commit for these values. .github/ci/metadata_profile.py rejects profiles that do not meet the required schema and provenance checks.

The BIND runtime package recipe is pinned separately in .resolver-plugins/bind920.json. That profile records the FreeBSD Ports repository, exact Ports commit, dns/bind920 Makefile and distinfo SHA-256 values, BIND DISTVERSION, and PORTREVISION. Resolver Plugins owns this pin for os-bind-rp; OPNsense's bundled BIND package remains the compatibility baseline, but this repository may carry a newer reviewed BIND 9.20 package when a security fix, critical bugfix, or maintainer-approved routine update warrants it.

Local build

The GitHub Actions workflow is the canonical build path. It keeps the CI scripts checked out from master, fetches the selected immutable release commit, then materializes only that commit's dns/bind source and .resolver-plugins/upstream.json and Mk build framework. This matters for legacy release branches, which intentionally do not carry the control-plane scripts. In particular, the release Mk files prevent a development-branch marker from adding an unintended -devel package suffix.

Package-affecting pushes to master automatically run production for the newest numeric release/bind-rp/<series> branch. Merging a package-affecting pull request into a release-source branch automatically runs production for that series, pinned to the merge commit. The workflow and publication helpers still come from the trusted master control plane. Closing a pull request without merging does not build a release. Manual dispatch remains available for an explicit series or development build.

Reproduce that split in a disposable worktree when building locally. Start from master, fetch the selected release branch, and overlay only its release inputs before entering the matching FreeBSD environment:

series=26.7
release_ref="refs/heads/release/bind-rp/$series"
git fetch --no-tags origin "$release_ref:refs/remotes/origin/build-source"
source_commit=$(git rev-parse refs/remotes/origin/build-source)
git checkout "$source_commit" -- .resolver-plugins/upstream.json Mk dns/bind
git cat-file -e "$source_commit:Mk/devel.mk" 2>/dev/null || rm -f Mk/devel.mk

The runner checks out the pinned OPNsense core commit and configures its package repository and fingerprints. Before compiling, it checks the self-contained pkg-<series> channel in resolver-plugins/repository for bind920-provenance.json. If the complete BIND profile, series, FreeBSD release, architecture, and target package-creator identity match, it downloads the two BIND packages through the signed package channel and installs them in the build VM. A first build or changed compatibility identity is a normal cache miss and uses the exact FreeBSD Ports recipe pinned in .resolver-plugins/bind920.json, verifies its hashes, and builds bind-tools followed by bind920 at the pinned BIND package version. Documentation is excluded because it is not needed at runtime; this keeps the source build from pulling in the large Sphinx documentation toolchain. The plugin build then installs that exact pair before packaging os-bind-rp, so the current channel and its rollback snapshot contain the BIND packages actually used by the build. The plugin manifest records dep_formula: "bind920 >= 9.20.26", not a locally built BIND revision, and the builder verifies the OPNsense version floor. It clears only dns/bind/work before packaging; do not invoke the inherited make clean target after materializing a release source, because that target resets dns/bind/src to the control-plane checkout.

The disposable FreeBSD 14.3 GitHub Actions image may need IGNORE_OSVERSION=yes to install current builder tools after the public FreeBSD catalogue advances. Current FreeBSD Ports also requires ALLOW_UNSUPPORTED_SYSTEM=yes for its end-of-life release; the BIND wrapper scopes that flag, along with BATCH=yes, to the two Ports package builds. None of these builder-only compatibility overrides alter the target ABI or the OPNsense packages used by os-bind-rp.

The wrapper explicitly installs the pinned recipe's ordinary build and linked library dependencies from the configured OPNsense repository, then invokes the two BIND builds with NO_DEPENDS=yes. It therefore compiles only the pinned BIND source instead of recursively rebuilding ordinary Ports dependencies, while retaining OPNsense-compatible linked libraries.

The runner installs python3 first when the clean FreeBSD environment does not provide it; Python is required to validate the immutable metadata before any OPNsense package repository configuration is used.

Target package manager and manifest compatibility

.resolver-plugins/target-pkg.json pins the exact pkg archive and pkg-static executable hash for each OPNsense series. Build wrappers install and lock that target package manager before creating either BIND or plugin archives. This forced selection is builder-only; it is not an instruction to upgrade an OPNsense host package manager.

.resolver-plugins/target-pkg-content.json separately pins a canonical digest of the archive's extracted paths, types, modes, ownership, file flags, hardlink relationships, file bytes, and symlink targets. Each digest records the exact signed archive from which its reviewed baseline was calculated. If a production build fails because OPNsense repacked an otherwise identical archive, the workflow opens a review PR containing only the new outer archive hash. It never merges that PR automatically. Merging the PR rebuilds the affected release series. An identity or extracted-content change remains a hard failure and requires an intentional package-creator update.

The initial 26.7 content pin is an intentional baseline of the currently signed archive. The previously pinned archive was no longer available when this guard was introduced, so that baseline must be reviewed as a full package content trust decision; it is not cryptographic proof that the unavailable archive had identical contents. Subsequent automatic proposals compare against this fixed baseline and cannot update it.

BIND provenance records the immutable creator as package_creator; plugin build-metadata.txt records the flat pkg_creator and pkg_creator_sha256 fields. Reuse is a cache miss unless those values match the selected target exactly.

Before copying an artifact, each wrapper verifies that the target parser can read a non-null checksum for every packaged file. The equivalent manual gate is:

python3 .github/ci/package_checksums.py \
  --pkg-command /usr/local/sbin/pkg-static path/to/package.pkg

Treat a missing, (null), or malformed file checksum as an incompatible artifact even when the archive and repository signatures are valid.

For example, after preparing the selected release source:

RP_UPSTREAM_METADATA=.resolver-plugins/upstream.json \
SOURCE_COMMIT="$source_commit" \
.github/ci/build-os-bind-rp.sh "$series" "artifacts/$series"

If that command exits with status 3, build or reuse the Resolver fallback and invoke the plugin wrapper with RP_BIND920_FALLBACK=yes:

RP_UPSTREAM_METADATA=.resolver-plugins/upstream.json \
SOURCE_COMMIT="$source_commit" \
.github/ci/build-bind920.sh "$series" "artifacts/$series"
RP_BIND920_FALLBACK=yes RP_UPSTREAM_METADATA=.resolver-plugins/upstream.json \
SOURCE_COMMIT="$source_commit" \
.github/ci/build-os-bind-rp.sh "$series" "artifacts/$series"

The package and build-metadata.txt are written below the output directory. The metadata records the source commit, BIND package version, OPNsense package version, ABI, provenance values, and FreeBSD environment used for the build.

.github/ci/setup-opnsense-repository.sh <series> is normally called by the build runner. Use it directly only when diagnosing repository setup; it changes the FreeBSD VM's package repository configuration.

The Test BIND plugin pull-request workflow discovers every active release/bind-rp/<series> branch, materializes its dns/bind/src tree, and runs the canonical dns/bind/tests suite from the pull request. It also runs the CI helper tests for BIND profile changes, including generated .resolver-plugins/bind920.json candidate PRs. Do not add a static release matrix: a newly created release branch is included automatically.

The workflow also requires dns/bind/pkg-descr to change with publishable BIND runtime, package-hook, or package-metadata changes. Test-only changes and PLUGIN_REVISION-only rebuilds do not require a changelog entry.

BIND candidate updates

The Propose bind920 candidate workflow is manual-only. It inspects a FreeBSD Ports ref, defaults to main, and compares dns/bind920 with the current .resolver-plugins/bind920.json pin. If it finds a newer BIND 9.20 candidate, it updates the pin on a sync/bind920/<version>-<portrevision> branch and opens or updates a PR against master.

The workflow's assessment is deterministic. It classifies a candidate as:

  • security when maintainer-supplied notes or security text contain CVE, vulnerability, advisory, or related security signals.
  • risky when the Ports diff changes dependency or configuration inputs such as LIB_DEPENDS, RUN_DEPENDS, USES, OPTIONS_DEFAULT, or CONFIGURE_ARGS.
  • critical-bugfix when notes mention resolver-impacting issues such as crash, assertion, SERVFAIL, DNSSEC validation, DoT, TLS, cache corruption, or data loss.
  • routine when none of those signals are present.

The workflow may receive maintainer-supplied changelog/security notes through its changelog_text input. It does not fetch ISC or VuXML pages directly, because adding non-GitHub egress destinations requires explicit approval under the workspace security policy. The generated PR is evidence for review only; it does not publish packages.

Before approving a build change

Check that the metadata is valid before running a full VM build:

python3 .github/ci/metadata_profile.py \
  .resolver-plugins/upstream.json "$series" freebsd_release
sh -n .github/ci/build-bind920.sh .github/ci/build-os-bind-rp.sh \
  .github/ci/setup-opnsense-repository.sh
python3 -m py_compile .github/ci/*.py
pytest -q .github/ci/ci-tests
git diff --check

Inspect the resulting package and build-metadata.txt before treating a build artifact as suitable for later package-repository publication.