Compare commits

...
Author SHA1 Message Date
Logan CusanoandClaude Opus 5.5 172f31d7c5 drb-update: trust INSTALL_DIR for git so a user-owned checkout can update
CI / lint (pull_request) Successful in 9s
CI / lint (push) Successful in 10s
CI / test-op25 (pull_request) Successful in 18s
CI / test-op25 (push) Successful in 19s
CI / test (pull_request) Successful in 50s
CI / test (push) Successful in 50s
radio-box (INSTALL_DIR=/home/pi/node-26, owned by pi) failed every update:
root's git refused the repo as 'dubious ownership', so origin read as ''
and the origin check refused. Scope safe.directory to INSTALL_DIR via
GIT_CONFIG_* env (command-line scope) for the updater process only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 19:55:30 -04:00
logan 44e41b3dd8 Merge pull request 'CI: build node images for amd64 as well as arm64 (#28)' (#35) from fix/28-amd64-images into main
Publish public images / publish (edge-node, ./drb-edge-node, ./drb-edge-node/Dockerfile, edge-node) (push) Skipped
Publish public images / publish (op25-client, ./op25-container, ./op25-container/Dockerfile, op25-client) (push) Skipped
Publish public images / publish (icecast, ./icecast, ./icecast/Dockerfile, icecast) (push) Skipped
CI / lint (push) Successful in 9s
CI / test-op25 (push) Successful in 18s
CI / test (push) Successful in 1m5s
Release images / ensure (drb-edge-node, edge-node) (push) Successful in 3m23s
Release images / ensure (icecast, icecast) (push) Successful in 5m7s
Release images / ensure (op25-container, op25-client) (push) Successful in 14m22s
Release images / ensure (secondary-sdr-container, secondary-sdr) (push) Successful in 47m53s
Reviewed-on: #35
2026-10-04 18:55:04 -04:00
Logan CusanoandClaude Opus 5.5 f9d23ad267 CI: build node images for amd64 as well as arm64 (node-26#28)
CI / lint (push) Successful in 7s
CI / lint (pull_request) Successful in 9s
CI / test-op25 (push) Successful in 17s
CI / test-op25 (pull_request) Successful in 17s
CI / test (push) Successful in 49s
CI / test (pull_request) Successful in 50s
amd64 nodes (radio-box) got 'no matching manifest for linux/amd64' on
pull and had to build locally. Every image workflow now builds
linux/amd64,linux/arm64. Release images treats an existing src- tag as
present only if it carries both platforms, so the arm64-only src- tags
pushed before this get rebuilt on the next v1 push.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 18:53:37 -04:00
logan 582bc407be Merge pull request 'install.sh: enrollment token never on the command line (#18)' (#30) from fix/18-install-token-argv into main
Build edge-node / build (push) Successful in 43s
Publish public images / publish (edge-node, ./drb-edge-node, ./drb-edge-node/Dockerfile, edge-node) (push) Skipped
Publish public images / publish (icecast, ./icecast, ./icecast/Dockerfile, icecast) (push) Skipped
Publish public images / publish (op25-client, ./op25-container, ./op25-container/Dockerfile, op25-client) (push) Skipped
CI / lint (push) Successful in 6s
CI / test-op25 (push) Successful in 18s
Release images / ensure (drb-edge-node, edge-node) (push) Successful in 28s
Release images / ensure (op25-container, op25-client) (push) Successful in 40s
CI / test (push) Successful in 53s
Release images / ensure (icecast, icecast) (push) Successful in 3m0s
Release images / ensure (secondary-sdr-container, secondary-sdr) (push) Canceled after 20m47s
Reviewed-on: #30
2026-10-04 18:28:19 -04:00
8 changed files with 23 additions and 13 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
with: with:
context: ./drb-edge-node context: ./drb-edge-node
file: ./drb-edge-node/Dockerfile file: ./drb-edge-node/Dockerfile
platforms: linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: | tags: |
git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.VERSION }} git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.VERSION }}
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
with: with:
context: ./icecast context: ./icecast
file: ./icecast/Dockerfile file: ./icecast/Dockerfile
platforms: linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: | tags: |
git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.VERSION }} git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.VERSION }}
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
with: with:
context: ./op25-container context: ./op25-container
file: ./op25-container/Dockerfile file: ./op25-container/Dockerfile
platforms: linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: | tags: |
git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.VERSION }} git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.VERSION }}
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
with: with:
context: ./secondary-sdr-container context: ./secondary-sdr-container
file: ./secondary-sdr-container/Dockerfile file: ./secondary-sdr-container/Dockerfile
platforms: linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: | tags: |
git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.VERSION }} git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.VERSION }}
+1 -1
View File
@@ -95,7 +95,7 @@ jobs:
with: with:
context: ${{ matrix.context }} context: ${{ matrix.context }}
file: ${{ matrix.file }} file: ${{ matrix.file }}
platforms: linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: | tags: |
${{ vars.PUBLIC_REGISTRY }}/${{ vars.PUBLIC_NAMESPACE }}/drb-${{ matrix.name }}:${{ steps.meta.outputs.VERSION }} ${{ vars.PUBLIC_REGISTRY }}/${{ vars.PUBLIC_NAMESPACE }}/drb-${{ matrix.name }}:${{ steps.meta.outputs.VERSION }}
+9 -5
View File
@@ -67,12 +67,16 @@ jobs:
TAG="src-$(git rev-parse HEAD:${{ matrix.context }})" TAG="src-$(git rev-parse HEAD:${{ matrix.context }})"
echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT
echo "TAG=$TAG" >> $GITHUB_OUTPUT echo "TAG=$TAG" >> $GITHUB_OUTPUT
if docker buildx imagetools inspect "$IMAGE:$TAG" >/dev/null 2>&1; then # Present only counts if BOTH platforms are in it: src- tags pushed
# before node-26#28 are arm64-only, and an amd64 node can't pull them.
RAW="$(docker buildx imagetools inspect --raw "$IMAGE:$TAG" 2>/dev/null | tr -d ' \n' || true)"
if printf '%s' "$RAW" | grep -q '"architecture":"amd64"' \
&& printf '%s' "$RAW" | grep -q '"architecture":"arm64"'; then
echo "EXISTS=true" >> $GITHUB_OUTPUT echo "EXISTS=true" >> $GITHUB_OUTPUT
echo "$IMAGE:$TAG already published — nothing to do" echo "$IMAGE:$TAG already published for amd64 + arm64 — nothing to do"
else else
echo "EXISTS=false" >> $GITHUB_OUTPUT echo "EXISTS=false" >> $GITHUB_OUTPUT
echo "$IMAGE:$TAG missing — building it" echo "$IMAGE:$TAG missing or not multi-arch — building it"
fi fi
- if: steps.meta.outputs.EXISTS != 'true' - if: steps.meta.outputs.EXISTS != 'true'
@@ -80,8 +84,8 @@ jobs:
with: with:
context: ./${{ matrix.context }} context: ./${{ matrix.context }}
file: ./${{ matrix.context }}/Dockerfile file: ./${{ matrix.context }}/Dockerfile
# arm64 only, same as the build-*.yml workflows (node-26#28). # amd64 + arm64, same as the build-*.yml workflows (node-26#28).
platforms: linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: ${{ steps.meta.outputs.IMAGE }}:${{ steps.meta.outputs.TAG }} tags: ${{ steps.meta.outputs.IMAGE }}:${{ steps.meta.outputs.TAG }}
cache-from: type=registry,ref=${{ steps.meta.outputs.IMAGE }}:buildcache cache-from: type=registry,ref=${{ steps.meta.outputs.IMAGE }}:buildcache
+3 -3
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# DRB edge node — one-shot bootstrap for a clean Raspberry Pi OS (arm64). # DRB edge node — one-shot bootstrap for a clean Raspberry Pi OS (arm64) or Debian (amd64).
# #
# curl -fsSL https://git.vpn.cusano.net/logan/node-26/raw/tag/v1/install.sh \ # curl -fsSL https://git.vpn.cusano.net/logan/node-26/raw/tag/v1/install.sh \
# | sudo bash -s -- --node-id node-003 \ # | sudo bash -s -- --node-id node-003 \
@@ -228,8 +228,8 @@ command -v apt-get >/dev/null || die "apt-get not found — this script targets
ARCH="$(dpkg --print-architecture)" ARCH="$(dpkg --print-architecture)"
case "$ARCH" in case "$ARCH" in
arm64|aarch64) ok "arch $ARCH" ;; arm64|aarch64|amd64|x86_64) ok "arch $ARCH" ;;
*) warn "arch is $ARCH — CI only builds linux/arm64 images. Prebuilt pull will fail; use --build." ;; *) warn "arch is $ARCH — CI only builds linux/amd64 + linux/arm64 images. Prebuilt pull will fail; use --build." ;;
esac esac
ok "running as root" ok "running as root"
+6
View File
@@ -51,6 +51,12 @@ main() {
flock -n 9 || { log "another update is already running"; return 0; } flock -n 9 || { log "another update is already running"; return 0; }
cd "$INSTALL_DIR" cd "$INSTALL_DIR"
# This runs as root, but a pre-install.sh checkout (e.g. /home/pi/node-26)
# is owned by the login user, and git >= 2.35.2 then refuses every command
# with "dubious ownership" — which surfaced as origin '' != REPO_URL. Trust
# exactly the configured INSTALL_DIR, for this process only (env config is
# command-line scope, which safe.directory honours; no global config change).
export GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=safe.directory GIT_CONFIG_VALUE_0="$INSTALL_DIR"
envget() { grep -E "^$1=" .env 2>/dev/null | head -1 | cut -d= -f2- | tr -d '"' || true; } envget() { grep -E "^$1=" .env 2>/dev/null | head -1 | cut -d= -f2- | tr -d '"' || true; }
local NODE_ID C2_URL local NODE_ID C2_URL
NODE_ID="$(envget NODE_ID)"; C2_URL="$(envget C2_URL)"; C2_URL="${C2_URL%/}" NODE_ID="$(envget NODE_ID)"; C2_URL="$(envget C2_URL)"; C2_URL="${C2_URL%/}"