From f23863a128dcb6fc0d352d117033a7c81bdad24e Mon Sep 17 00:00:00 2001 From: Alper Gundogdu Date: Tue, 13 Oct 2026 16:11:45 +0100 Subject: [PATCH 1/2] chore(sponsord): pin decdn/sponsord v0.0.4 Moves sponsord_version and sponsord_onramp_version to 0.0.4 and the Compose example's sponsord and sponsord-onramp image digests to that release's sponsord-image-digest.txt and sponsord-onramp-image-digest.txt. KEYS and the daemon and onramp config env vars are unchanged since v0.0.3. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 4 ++-- ansible/README.md | 2 +- ansible/galaxy/publisher/CHANGELOG.md | 4 ++-- ansible/galaxy/publisher/README.md | 4 ++-- ansible/inventory/group_vars/sponsord_hosts.yml | 4 ++-- ansible/inventory/group_vars/sponsord_onramp_hosts.yml | 4 ++-- ansible/roles/sponsord/README.md | 6 +++--- ansible/roles/sponsord/defaults/main.yml | 2 +- ansible/roles/sponsord/tasks/main.yml | 2 +- ansible/roles/sponsord_onramp/README.md | 4 ++-- ansible/roles/sponsord_onramp/defaults/main.yml | 2 +- ansible/roles/sponsord_onramp/tasks/main.yml | 2 +- cloud-init/README.md | 2 +- compose/.env.example | 6 +++--- compose/README.md | 2 +- 15 files changed, 25 insertions(+), 25 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 187417a..b9a1659 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -142,7 +142,7 @@ lint-alloy` validates and runs it. **Pinned upstream releases.** One decdn/decdn release (`decdn_node_version`, today `0.0.4`) and one decdn/sponsord release (`sponsord_version` = `sponsord_onramp_version`, -today `0.0.3`; decdn/sponsord tags its whole workspace `vX.Y.Z`, there are no per-crate +today `0.0.4`; decdn/sponsord tags its whole workspace `vX.Y.Z`, there are no per-crate tags) are pinned across every path: the role defaults, the onramp's installer pin (`sponsord_onramp_decdn_release` + `_decdn_sums_sha256`, copied into `compose/sponsord-onramp.env.example`), `compose/.env.example`'s image digests, the @@ -292,7 +292,7 @@ the pinned `iroh-relay` (re-capture it when bumping `iroh_relay_version`). imported by `publisher.yml`) targets its own `sponsord_hosts` group, standalone or co-located with a node. - **Install:** a GPG-verified `v*` decdn/sponsord release by default - (`sponsord_version`, `0.0.3`), a host-side `source` build, or a manual binary. + (`sponsord_version`, `0.0.4`), a host-side `source` build, or a manual binary. The `--version` backstop checks the version in `release` mode only (the version has a default, so other modes would fail against it), as in the other two roles. - **Unit:** `DynamicUser`; the API token (generated on the host, never replaced), diff --git a/ansible/README.md b/ansible/README.md index f5368f5..ca152dc 100644 --- a/ansible/README.md +++ b/ansible/README.md @@ -174,7 +174,7 @@ ignored on the first converge. - **`release`** (the default) downloads the `v` tarballs from `decdn_node_release_base` and verifies them against the GPG-signed `SHA256SUMS`. `decdn_node_version` defaults to the decdn/decdn release this repo pins - (`0.0.4`); the sponsord roles pin decdn/sponsord `0.0.3` the same way. + (`0.0.4`); the sponsord roles pin decdn/sponsord `0.0.4` the same way. - **`source`** clones `decdn_node_source_repo` (default `decdn/decdn` on GitHub) at `decdn_node_source_ref` (any tag, branch or SHA) **on the node** and builds it there as an unprivileged `decdn-build` user, in a fresh environment per commit, with a diff --git a/ansible/galaxy/publisher/CHANGELOG.md b/ansible/galaxy/publisher/CHANGELOG.md index 3a82d5e..06ff975 100644 --- a/ansible/galaxy/publisher/CHANGELOG.md +++ b/ansible/galaxy/publisher/CHANGELOG.md @@ -128,7 +128,7 @@ role describe a change shared with that collection. host (the token gate and `/healthz` fail without the daemon) and reads the daemon's own `/etc/sponsord/api-token`. - Install: the `v` decdn/sponsord release (`release`, the default; - `sponsord_onramp_version` is pinned to `0.0.3`, the same release as sponsord's) + `sponsord_onramp_version` is pinned to `0.0.4`, the same release as sponsord's) verified against its GPG-signed `SHA256SUMS` with the keys vendored in the `sponsord` role, a host-side `source` build, or a local binary (`manual`; `sponsord_onramp_release_target_dir` follows `sponsord_release_target_dir`). @@ -161,7 +161,7 @@ role describe a change shared with that collection. - `sponsord` role: deploys the deCDN onboarding sponsor (decdn/sponsord) on its own host or beside a node. It installs the `v` decdn/sponsord release - (`release`, the default; `sponsord_version` is pinned to `0.0.3`; decdn/sponsord + (`release`, the default; `sponsord_version` is pinned to `0.0.4`; decdn/sponsord tags its whole workspace once, so a mirror in `sponsord_release_base` serves `v/sponsord--.tar.gz`) verified against its GPG-signed `SHA256SUMS`, a host-side `source` build, or a local binary (`manual`). The unit uses `DynamicUser`, and the diff --git a/ansible/galaxy/publisher/README.md b/ansible/galaxy/publisher/README.md index 24424af..a943de4 100644 --- a/ansible/galaxy/publisher/README.md +++ b/ansible/galaxy/publisher/README.md @@ -11,8 +11,8 @@ repository — four roles and nothing else: | Role | Purpose | |------|---------| -| `decdn.publisher.sponsord` | The `sponsord` onboarding sponsor (treasury signer + PaymentPool keeper), standalone or beside a node — local binary, a host-side source build or a GPG-verified decdn/sponsord `v*` release (pinned to 0.0.3), `DynamicUser` unit with the API token and treasury wallet as systemd credentials, loopback-only API, `/healthz` deploy gate. `sponsord_network` sets the chain and PaymentPool from upstream's manifest. Restarts refuse while a pool top-up is held; `tasks_from: backup` / `decommission` for day 2. | -| `decdn.publisher.sponsord_onramp` | `sponsord-onramp`, sponsord's public side (Turnstile gate, installers, capability API), on the daemon's host — local binary, a host-side source build or a GPG-verified decdn/sponsord `v*` release (pinned to 0.0.3), `DynamicUser` unit with the daemon token and Turnstile secret as systemd credentials, loopback listener behind Caddy (distro package, ACME TLS, admin API off; or your own proxy), `/healthz` deploy gate; `tasks_from: decommission`. | +| `decdn.publisher.sponsord` | The `sponsord` onboarding sponsor (treasury signer + PaymentPool keeper), standalone or beside a node — local binary, a host-side source build or a GPG-verified decdn/sponsord `v*` release (pinned to 0.0.4), `DynamicUser` unit with the API token and treasury wallet as systemd credentials, loopback-only API, `/healthz` deploy gate. `sponsord_network` sets the chain and PaymentPool from upstream's manifest. Restarts refuse while a pool top-up is held; `tasks_from: backup` / `decommission` for day 2. | +| `decdn.publisher.sponsord_onramp` | `sponsord-onramp`, sponsord's public side (Turnstile gate, installers, capability API), on the daemon's host — local binary, a host-side source build or a GPG-verified decdn/sponsord `v*` release (pinned to 0.0.4), `DynamicUser` unit with the daemon token and Turnstile secret as systemd credentials, loopback listener behind Caddy (distro package, ACME TLS, admin API off; or your own proxy), `/healthz` deploy gate; `tasks_from: decommission`. | | `decdn.publisher.iroh_relay` | A self-hosted [iroh relay](https://github.com/n0-computer/iroh) (`iroh-relay`) for deCDN peers that cannot hole-punch — sha256-pinned upstream release (or a local binary), its own Let's Encrypt TLS, QUIC address discovery, `DynamicUser` unit holding only `CAP_NET_BIND_SERVICE`, loopback metrics, a deploy gate on every listener, a refusal of ports another process holds; access limited to an allowlist of endpoint IDs by default (`iroh_relay_access`; `tasks_from: node-ids` reads nodes' IDs); `tasks_from: decommission`. Point nodes at it with `decdn_relay_urls`. | | `decdn.publisher.iroh_dns_server` | A self-hosted [iroh DNS server](https://github.com/n0-computer/iroh) (`iroh-dns-server`): the pkarr relay deCDN nodes publish their address records to and the DNS server peers resolve them through, in place of n0's `dns.iroh.link` — sha256-pinned upstream release (or a local binary), its own Let's Encrypt TLS, DNS on one bind address (clear of systemd-resolved's stub), `DynamicUser` unit holding only `CAP_NET_BIND_SERVICE`, loopback metrics, a deploy gate on every listener, `/healthz`'s version and an SOA answer over udp and tcp, a refusal of ports another process holds; `tasks_from: decommission`. Point nodes at it with `decdn_discovery_pkarr_url` and `decdn_discovery_dns_origin`. | diff --git a/ansible/inventory/group_vars/sponsord_hosts.yml b/ansible/inventory/group_vars/sponsord_hosts.yml index 6b23bf3..6680a40 100644 --- a/ansible/inventory/group_vars/sponsord_hosts.yml +++ b/ansible/inventory/group_vars/sponsord_hosts.yml @@ -14,11 +14,11 @@ # The default method, "release", installs the decdn/sponsord release the role pins # (tag v); set it only to hold the host on another one, together # with sponsord_onramp_version: -# sponsord_version: "0.0.3" +# sponsord_version: "0.0.4" # Or build on the host from a git ref (tag, branch or SHA; sponsord_version is not # checked in this mode): # sponsord_install_method: source -# sponsord_source_ref: v0.0.3 +# sponsord_source_ref: v0.0.4 # Or copy a control-machine build: a decdn/sponsord checkout's target dir # (`cargo build --release -p sponsord`; the role checks the ELF matches the host). # sponsord_install_method: manual diff --git a/ansible/inventory/group_vars/sponsord_onramp_hosts.yml b/ansible/inventory/group_vars/sponsord_onramp_hosts.yml index ed88bc8..21a22f8 100644 --- a/ansible/inventory/group_vars/sponsord_onramp_hosts.yml +++ b/ansible/inventory/group_vars/sponsord_onramp_hosts.yml @@ -12,10 +12,10 @@ # --- Binary ------------------------------------------------------------------------ # The same three methods as sponsord. "release" (default) installs the same release # as the sponsord role; set both versions together to hold the host on another: -# sponsord_onramp_version: "0.0.3" +# sponsord_onramp_version: "0.0.4" # Or build on the host (its own checkout, so it may pin a different ref): # sponsord_onramp_install_method: source -# sponsord_onramp_source_ref: v0.0.3 +# sponsord_onramp_source_ref: v0.0.4 # Or manual, which follows sponsord_release_target_dir (`cargo build --release` in # a decdn/sponsord checkout builds both binaries): # sponsord_onramp_install_method: manual diff --git a/ansible/roles/sponsord/README.md b/ansible/roles/sponsord/README.md index 4c8f329..c815215 100644 --- a/ansible/roles/sponsord/README.md +++ b/ansible/roles/sponsord/README.md @@ -20,7 +20,7 @@ gate, installers, behind a TLS reverse proxy), is the - **Installs the binary.** - `release` (the default) downloads `sponsord--.tar.gz` from the - `v` release of `decdn/sponsord` (`sponsord_version`, default `0.0.3`; + `v` release of `decdn/sponsord` (`sponsord_version`, default `0.0.4`; one tag releases the whole workspace) and verifies it against the GPG-signed `SHA256SUMS`, using `files/sponsord-release-KEYS.asc`, a copy of upstream's `KEYS`. `sponsord_release_base` points it at a mirror. @@ -32,7 +32,7 @@ gate, installers, behind a TLS reverse proxy), is the build environment for every new commit, a `@` stamp so an unchanged commit is not rebuilt, and a root-side install that refuses symlinks. `sponsord_version` is not checked in this mode; set the ref to a - release tag (`v0.0.3`) to build exactly that release. The build user, its home and the toolchain are + release tag (`v0.0.4`) to build exactly that release. The build user, its home and the toolchain are shared with the other roles on the host. cargo also fetches upstream's `decdn/decdn` git dependencies, pinned by `Cargo.lock`. - `manual` copies a binary built on the control machine, from a `decdn/sponsord` @@ -127,7 +127,7 @@ See [`defaults/main.yml`](defaults/main.yml) for the full list with comments. | `sponsord_source_repo` / `sponsord_source_ref` | `decdn/sponsord` on GitHub / `""` | `source` only. The ref is required: a tag, branch or SHA. | | `sponsord_source_build_jobs` | `""` | `source` only: `CARGO_BUILD_JOBS` (`""` = one per CPU). | | `sponsord_manual_bin_src` / `sponsord_release_target_dir` | `""` | `manual` only. Set one. | -| `sponsord_version` | `0.0.3` | `release` mode: the `decdn/sponsord` release (tag `v0.0.3`). Equal to `sponsord_onramp_version`. | +| `sponsord_version` | `0.0.4` | `release` mode: the `decdn/sponsord` release (tag `v0.0.4`). Equal to `sponsord_onramp_version`. | | `sponsord_network` | `""` | Network profile: `arbitrum-sepolia` supplies chain id and PaymentPool. | | `sponsord_chain_id`, `sponsord_payment_pool_address` | from profile | Explicit values win over the profile. | | `sponsord_pool_id` | `""` | **Required.** 0x + 64 hex. `""` only on the wallet-creation run. | diff --git a/ansible/roles/sponsord/defaults/main.yml b/ansible/roles/sponsord/defaults/main.yml index 7c38ca8..036d9b6 100644 --- a/ansible/roles/sponsord/defaults/main.yml +++ b/ansible/roles/sponsord/defaults/main.yml @@ -52,7 +52,7 @@ decdn_rustup_sha256: # The decdn/sponsord release (tag v) this repo pins. Keep it equal to # sponsord_onramp_version: both come from one workspace release (README.md, # "Bumping the sponsord release"; make test-scripts checks the defaults agree). -sponsord_version: "0.0.3" # asserted non-empty in "release" mode +sponsord_version: "0.0.4" # asserted non-empty in "release" mode # Release target triple, derived from the host's gathered architecture (see # vars/main/arch.yml). Set it explicitly only for a play with gather_facts: false. sponsord_target: "{{ _sponsord_arch_targets.get(ansible_facts.get('architecture', ''), '') }}" diff --git a/ansible/roles/sponsord/tasks/main.yml b/ansible/roles/sponsord/tasks/main.yml index 8fc2917..63ca462 100644 --- a/ansible/roles/sponsord/tasks/main.yml +++ b/ansible/roles/sponsord/tasks/main.yml @@ -23,7 +23,7 @@ - sponsord_version | length > 0 fail_msg: >- sponsord_install_method "release" (the default) requires sponsord_version (e.g. - "0.0.3") naming a v release of decdn/sponsord (or of the mirror in + "0.0.4") naming a v release of decdn/sponsord (or of the mirror in sponsord_release_base). To run something unreleased, set sponsord_install_method "source" with a sponsord_source_ref to build on the host, or use "manual" to copy a binary built on the control machine. diff --git a/ansible/roles/sponsord_onramp/README.md b/ansible/roles/sponsord_onramp/README.md index e3020b3..ca46d67 100644 --- a/ansible/roles/sponsord_onramp/README.md +++ b/ansible/roles/sponsord_onramp/README.md @@ -23,7 +23,7 @@ is unreachable. - **Installs the binary**, exactly as the `sponsord` role does: - `release` (the default) downloads `sponsord-onramp--.tar.gz` from the `v` release of `decdn/sponsord` (`sponsord_onramp_version`, - default `0.0.3`, the same release as the daemon's) and verifies it against the + default `0.0.4`, the same release as the daemon's) and verifies it against the GPG-signed `SHA256SUMS`, with the KEYS file vendored in the `sponsord` role. `sponsord_onramp_release_base` points it at a mirror. - `source` builds `sponsord_onramp_source_ref` of `sponsord_onramp_source_repo` @@ -118,7 +118,7 @@ See [`defaults/main.yml`](defaults/main.yml) for the full list with comments. | `sponsord_onramp_source_repo` / `_source_ref` | `decdn/sponsord` on GitHub / `""` | `source` only. The ref is required: a tag, branch or SHA. | | `sponsord_onramp_source_build_jobs` | `""` | `source` only: `CARGO_BUILD_JOBS` (`""` = one per CPU). | | `sponsord_onramp_manual_bin_src` / `_release_target_dir` | `""` / `sponsord_release_target_dir` | `manual` only. | -| `sponsord_onramp_version` | `0.0.3` | `release` mode: the `decdn/sponsord` release (tag `v0.0.3`). Keep it equal to `sponsord_version`: overriding one does not move the other. | +| `sponsord_onramp_version` | `0.0.4` | `release` mode: the `decdn/sponsord` release (tag `v0.0.4`). Keep it equal to `sponsord_version`: overriding one does not move the other. | | `sponsord_onramp_network` | `sponsord_network` | Supplies CapacityBond and SlashJudge. Must match the daemon's network. | | `sponsord_onramp_capacity_bond_address`, `_slash_judge_address` | from profile | Explicit values win. SlashJudge may be `""`. | | `sponsord_onramp_rpc_url` | `""` | **Required. Public**: served to every user. No credentials, query or API key. | diff --git a/ansible/roles/sponsord_onramp/defaults/main.yml b/ansible/roles/sponsord_onramp/defaults/main.yml index 5b31995..6ea2caa 100644 --- a/ansible/roles/sponsord_onramp/defaults/main.yml +++ b/ansible/roles/sponsord_onramp/defaults/main.yml @@ -50,7 +50,7 @@ decdn_rustup_sha256: # --- Release to install ("release" mode) ---------------------------------------- # The decdn/sponsord release (tag v) this repo pins, the # same one as the sponsord role's sponsord_version. -sponsord_onramp_version: "0.0.3" # asserted non-empty in "release" mode +sponsord_onramp_version: "0.0.4" # asserted non-empty in "release" mode # Derived from the host's gathered architecture (vars/main/arch.yml). sponsord_onramp_target: "{{ _sponsord_onramp_arch_targets.get(ansible_facts.get('architecture', ''), '') }}" sponsord_onramp_release_base: "https://github.com/decdn/sponsord/releases/download" diff --git a/ansible/roles/sponsord_onramp/tasks/main.yml b/ansible/roles/sponsord_onramp/tasks/main.yml index bed6388..49d9cbc 100644 --- a/ansible/roles/sponsord_onramp/tasks/main.yml +++ b/ansible/roles/sponsord_onramp/tasks/main.yml @@ -26,7 +26,7 @@ - sponsord_onramp_version | length > 0 fail_msg: >- sponsord_onramp_install_method "release" (the default) requires - sponsord_onramp_version (e.g. "0.0.3") naming a v release of + sponsord_onramp_version (e.g. "0.0.4") naming a v release of decdn/sponsord (or of the mirror in sponsord_onramp_release_base). To run something unreleased, set sponsord_onramp_install_method "source" with a sponsord_onramp_source_ref to build on the host, or use "manual" to copy a diff --git a/cloud-init/README.md b/cloud-init/README.md index 0944c0f..fe3c9bf 100644 --- a/cloud-init/README.md +++ b/cloud-init/README.md @@ -39,7 +39,7 @@ for the secrets of every group the host is in. > and the Ansible path's `source` mode builds whatever its git ref points at (and > takes many minutes on first boot), so the lint refuses both. The release is the > one the roles pin at `DEVOPS_REF` (decdn/decdn `v0.0.4` today, decdn/sponsord -> `v0.0.3` for the sponsor); set `decdn_node_version` in the user-data to pin +> `v0.0.4` for the sponsor); set `decdn_node_version` in the user-data to pin > another. `decdn_node_release_base` points the download at a mirror that serves > `v/{decdn-node,decdn}--.tar.gz`, `SHA256SUMS` and > `SHA256SUMS.asc`; the signature is still checked against deCDN's release keys. diff --git a/compose/.env.example b/compose/.env.example index 75659fe..8da70be 100644 --- a/compose/.env.example +++ b/compose/.env.example @@ -41,10 +41,10 @@ DECDN_GID=999 DECDN_ENV_FILE=/etc/decdn/decdn.env # --- sponsord and onramp ---------------------------------------------------------- -# decdn/sponsord v0.0.3, one release for both images -SPONSORD_IMAGE_DIGEST=sha256:98f8a9b476569f01b778938e852c28293193d93daef0661f668436597a9e5637 +# decdn/sponsord v0.0.4, one release for both images +SPONSORD_IMAGE_DIGEST=sha256:120982625257b28cf785c776cb2cc7a6c6cd8e2e5958b274f1a43d27ab857eea # SPONSORD_IMAGE_REPO=ghcr.io/decdn/sponsord -SPONSORD_ONRAMP_IMAGE_DIGEST=sha256:799b727b1b08eb8c90977e505a12ecd9ef37269d2cd1cff6c4fe59aeef615c07 +SPONSORD_ONRAMP_IMAGE_DIGEST=sha256:76362c0de04d3febf43b39ee1d00bd29d45a1b4338fc3f8fb0427d52d5b13805 # SPONSORD_ONRAMP_IMAGE_REPO=ghcr.io/decdn/sponsord-onramp # uid/gid of the host's dedicated `sponsord` system account, which owns the diff --git a/compose/README.md b/compose/README.md index 282067c..0999723 100644 --- a/compose/README.md +++ b/compose/README.md @@ -69,7 +69,7 @@ from: the wrapper always names the project (`decdn`) and refuses to run while th shell sets a `COMPOSE_*` variable or one `compose.yaml` reads, which Compose would otherwise take over `.env`, so its checks see what Compose runs. `init` starts it from `.env.example`, which carries the digests of the releases the Ansible -roles pin (decdn/decdn v0.0.4, decdn/sponsord v0.0.3), each copied from that +roles pin (decdn/decdn v0.0.4, decdn/sponsord v0.0.4), each copied from that release's signed digest file; [Operate](#operate) says how to take a newer one. ## The node From f39fe55710f6b56b245a971c67691c408ec67b96 Mon Sep 17 00:00:00 2001 From: Alper Gundogdu Date: Tue, 13 Oct 2026 16:18:13 +0100 Subject: [PATCH 2/2] chore(sponsord): leave the released publisher changelog section alone publisher-collection-v0.1.0 turned [Unreleased] into the generated [0.1.0] section, which records the 0.0.3 pin it shipped with. Co-Authored-By: Claude Opus 5.5 --- ansible/galaxy/publisher/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ansible/galaxy/publisher/CHANGELOG.md b/ansible/galaxy/publisher/CHANGELOG.md index b88b1ed..682ec3d 100644 --- a/ansible/galaxy/publisher/CHANGELOG.md +++ b/ansible/galaxy/publisher/CHANGELOG.md @@ -128,7 +128,7 @@ role describe a change shared with that collection. host (the token gate and `/healthz` fail without the daemon) and reads the daemon's own `/etc/sponsord/api-token`. - Install: the `v` decdn/sponsord release (`release`, the default; - `sponsord_onramp_version` is pinned to `0.0.4`, the same release as sponsord's) + `sponsord_onramp_version` is pinned to `0.0.3`, the same release as sponsord's) verified against its GPG-signed `SHA256SUMS` with the keys vendored in the `sponsord` role, a host-side `source` build, or a local binary (`manual`; `sponsord_onramp_release_target_dir` follows `sponsord_release_target_dir`). @@ -161,7 +161,7 @@ role describe a change shared with that collection. - `sponsord` role: deploys the deCDN onboarding sponsor (decdn/sponsord) on its own host or beside a node. It installs the `v` decdn/sponsord release - (`release`, the default; `sponsord_version` is pinned to `0.0.4`; decdn/sponsord + (`release`, the default; `sponsord_version` is pinned to `0.0.3`; decdn/sponsord tags its whole workspace once, so a mirror in `sponsord_release_base` serves `v/sponsord--.tar.gz`) verified against its GPG-signed `SHA256SUMS`, a host-side `source` build, or a local binary (`manual`). The unit uses `DynamicUser`, and the