Phase 4 §7.1: bundle uBlock Origin in profile template#748
Merged
Conversation
Bundles uBlock Origin's signed XPI in Dockerfile.browser
(/opt/openlegion/extensions/uBlock0.xpi, version pinned via
UBLOCK_VERSION arg). Profile schema bumps to v3 with a migration
that copies the bundled XPI into each profile's extensions/{addon-id}.xpi
where Firefox auto-discovers it on launch.
Stealth prefs gain three Firefox prefs that cooperate with the
profile-bundled extension: extensions.autoDisableScopes=0,
extensions.startupScanScopes=15, and xpinstall.signatures.required=False.
Operator escape hatch via BROWSER_ENABLE_ADBLOCK=false skips the
install at migration time and at every-launch sync time. The flag
default stays "true" per §2.1 — uBlock Origin's default filter lists
(EasyList + EasyPrivacy) ship enabled.
Migration is idempotent: size+mtime guard skips recopy on unchanged
XPI, refreshes when the operator rebuilds the image with a newer
version. The launch-time sync_adblock_extension() helper runs every
browser start so flag toggles after a profile is at v3 take effect
without needing another schema bump.
Per-host opt-out is deferred to a follow-up — the ambiguity in §7.1
between "operator endpoint" and per-page disable means it deserves
its own design pass once we have a concrete site-detection report
(e.g. Forbes-style adblock-walled sites in production).
sync_adblock_extension now acquires the same per-profile flock that
migrate_profile uses, so two browser-service processes (e.g. a
provisioner update path racing an agent restart) can't both write to
{profile}/extensions/ at once. Non-blocking — if the peer holds the
lock, we skip and report present-or-not based on a stat. Idempotency
of _v3_install_ublock means the eventual disk state is correct
regardless of who wins the race.
…tests
- XPI download moved BEFORE pyproject.toml COPY so Python-dependency
bumps no longer invalidate the 3MB XPI download cache.
- URL fallback to .firefox.xpi (unsigned) when .firefox.signed.xpi
404s. Lets developers pin to a uBO beta release that hasn't been
AMO-signed yet without hand-editing the URL — Camoufox's patched
Firefox accepts unsigned XPIs anyway because
xpinstall.signatures.required=False.
- Two new tests for sync_adblock_extension flock contention:
(a) peer holds lock + existing XPI present → returns True without
re-installing
(b) peer holds lock + no XPI yet → returns False (peer hasn't
finished install)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
§7.1 of the browser-automation roadmap — bundles uBlock Origin's signed XPI in the browser image and installs it into every agent profile via the profile-schema framework.
Dockerfile.browserdownloadsuBlock0_${UBLOCK_VERSION}.firefox.signed.xpifrom the official GitHub releases (pinned viaUBLOCK_VERSIONbuild arg, defaults to 1.62.0). Stored read-only at/opt/openlegion/extensions/uBlock0.xpi._v3_install_ublock) drops the XPI into{profile}/extensions/{addon-id}.xpiwhere Firefox auto-discovers it on launch. Idempotent — size+mtime guard skips recopy on unchanged XPI; refreshes when the image rebuilds with a newer version._stealth_prefs():extensions.autoDisableScopes=0,extensions.startupScanScopes=15,xpinstall.signatures.required=False. Without these Firefox sees the file but installs disabled.BROWSER_ENABLE_ADBLOCK=falseskips install at migration time and at every-launch sync time. Default staystrueper §2.1.sync_adblock_extension()runs at everyBrowserManager.get_or_startso flag toggles after a profile is at v3 (or image rebuilds with a newer XPI) take effect without another schema bump.Risk and rollout
Dockerfile.browserhasn't been rebuilt log INFO and continue, letting the next launch on a properly-built image fix the install viasync_adblock_extension.Test plan
{profile}/extensions/{addon-id}.xpiwith mode 0644.BROWSER_ENABLE_ADBLOCK=false→ install skipped.v0 → v3runs v2 (font cache wipe) then v3 (XPI install) in order.sync_adblock_extensionreturnsTruewhen installed,Falseon flag-disabled / source-missing / failure.test_profile_schema.py; 308/308 acrosstest_browser_service.py+test_stealth.py(no regressions).