From e1496baa18e99dd90808ea87f597758e248c4a3a Mon Sep 17 00:00:00 2001 From: Kenneth Bingham Date: Wed, 24 Jul 2024 16:11:17 -0400 Subject: [PATCH 1/5] use goreleaser config spec v2 --- .goreleaser-darwin.yml | 1 + .goreleaser-linux-arm64.yml | 1 + .goreleaser-linux-armhf.yml | 5 ++++- .goreleaser-linux.yml | 1 + .goreleaser-release.yml | 1 + .goreleaser-windows.yml | 1 + 6 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.goreleaser-darwin.yml b/.goreleaser-darwin.yml index a741d3cb..a4c14a6c 100644 --- a/.goreleaser-darwin.yml +++ b/.goreleaser-darwin.yml @@ -1,3 +1,4 @@ +version: 2 builds: - id: zrok-amd64 main: ./cmd/zrok diff --git a/.goreleaser-linux-arm64.yml b/.goreleaser-linux-arm64.yml index 27bd3474..d63b87fa 100644 --- a/.goreleaser-linux-arm64.yml +++ b/.goreleaser-linux-arm64.yml @@ -1,3 +1,4 @@ +version: 2 builds: - id: zrok-armv8 main: ./cmd/zrok diff --git a/.goreleaser-linux-armhf.yml b/.goreleaser-linux-armhf.yml index 829c85b8..b02e10d8 100644 --- a/.goreleaser-linux-armhf.yml +++ b/.goreleaser-linux-armhf.yml @@ -1,8 +1,11 @@ +version: 2 builds: - id: zrok-armv7 main: ./cmd/zrok binary: zrok - ldflags: "-s -w -X github.com/openziti/zrok/build.Version={{.Tag}} -X github.com/openziti/zrok/build.Hash={{.ShortCommit}}" + ldflags: + - '-extldflags "-static"' + - "-s -w -X github.com/openziti/zrok/build.Version={{.Tag}} -X github.com/openziti/zrok/build.Hash={{.ShortCommit}}" env: - CC=arm-linux-gnueabi-gcc - CGO_ENABLED=1 diff --git a/.goreleaser-linux.yml b/.goreleaser-linux.yml index 0e5ec9e8..aeaf8074 100644 --- a/.goreleaser-linux.yml +++ b/.goreleaser-linux.yml @@ -1,3 +1,4 @@ +version: 2 builds: - id: zrok-amd64 main: ./cmd/zrok diff --git a/.goreleaser-release.yml b/.goreleaser-release.yml index 9effbc27..ae817e34 100644 --- a/.goreleaser-release.yml +++ b/.goreleaser-release.yml @@ -1,3 +1,4 @@ +version: 2 builds: - skip: true release: diff --git a/.goreleaser-windows.yml b/.goreleaser-windows.yml index b14196bc..deeda04c 100644 --- a/.goreleaser-windows.yml +++ b/.goreleaser-windows.yml @@ -1,3 +1,4 @@ +version: 2 builds: - main: ./cmd/zrok binary: zrok From efbe3df4c5e7bcfef5462f8ca24cb7711b1ee17c Mon Sep 17 00:00:00 2001 From: Kenneth Bingham Date: Wed, 24 Jul 2024 15:17:18 -0400 Subject: [PATCH 2/5] use goreleaser in cross-build image to emulate CI more closely --- docker/images/cross-build/Dockerfile | 33 ++++++----- docker/images/cross-build/linux-build.sh | 72 +++++++----------------- 2 files changed, 37 insertions(+), 68 deletions(-) diff --git a/docker/images/cross-build/Dockerfile b/docker/images/cross-build/Dockerfile index 2f5f0670..2a30e63d 100644 --- a/docker/images/cross-build/Dockerfile +++ b/docker/images/cross-build/Dockerfile @@ -1,5 +1,8 @@ -# Stage 1: Install Node.js with nvm -FROM debian:bullseye-slim +FROM goreleaser/goreleaser AS goreleaser + +FROM golang:1.21 AS golang + +FROM debian:bookworm-slim # # this file mirrors the build params used in the GitHub Actions and enables # reproducible builds for downstream forks for Ziti contributors @@ -7,38 +10,38 @@ FROM debian:bullseye-slim ARG TARGETARCH ARG golang_version=1.21.3 -ARG go_distribution_file=go${golang_version}.linux-${TARGETARCH}.tar.gz ARG go_path=/usr/share/go ARG go_root=/usr/local/go -ARG go_cache=/usr/share/go_cache -ARG uid=1000 -ARG gid=1000 +ARG go_cache=/usr/share/go + RUN apt-get -y update \ && apt-get -y install \ - gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf gcc-aarch64-linux-gnu \ - wget build-essential + gcc-arm-linux-gnueabi \ + gcc-aarch64-linux-gnu \ + wget \ + git \ + build-essential -RUN wget -q https://go.dev/dl/${go_distribution_file} -RUN tar -xzf ${go_distribution_file} -C /usr/local/ RUN wget -qO- https://deb.nodesource.com/setup_18.x | bash \ && apt-get -y update \ && apt-get -y install \ nodejs -RUN mkdir ${go_path} ${go_cache} -RUN chown -R ${uid}:${gid} ${go_path} ${go_cache} -COPY ./linux-build.sh /usr/local/bin/ +COPY --from=golang /usr/local/go /usr/local/go +# RUN chmod -R go+rX ${go_path} ${go_cache} + +COPY --from=goreleaser /usr/bin/goreleaser /usr/local/bin/goreleaser + +COPY ./linux-build.sh /usr/local/bin/linux-build.sh -USER ${uid}:${gid} ENV TARGETARCH=${TARGETARCH} ENV GOPATH=${go_path} ENV GOROOT=${go_root} ENV GOCACHE=${go_cache} ENV PATH=${go_path}/bin:${go_root}/bin:$PATH -RUN go install github.com/mitchellh/gox@latest WORKDIR /mnt ENTRYPOINT ["linux-build.sh"] diff --git a/docker/images/cross-build/linux-build.sh b/docker/images/cross-build/linux-build.sh index 447106a8..f75c0eff 100755 --- a/docker/images/cross-build/linux-build.sh +++ b/docker/images/cross-build/linux-build.sh @@ -11,6 +11,19 @@ set -o nounset set -o pipefail set -o xtrace +resolveArch() { + case ${1} in + amd64) echo amd64 + ;; + arm|armv7*|arm/v7*|armhf*) echo armhf + ;; + arm64|armv8*|arm/v8*) echo arm64 + ;; + *) echo ${1} + ;; + esac +} + # if no architectures supplied then default list of three if (( ${#} )); then typeset -a JOBS=(${@}) @@ -18,22 +31,6 @@ else typeset -a JOBS=(amd64 arm arm64) fi -# specify the Go template used by Gox to save the artifacts -GOX_OUTPUT="dist/{{.Arch}}/{{.OS}}/{{.Dir}}" -# count the number of available CPUs for time-efficient parallelism -PROC_COUNT=$(nproc --all) -# compute the number of processors available for each job, rounded down to integer -PROCS_PER_JOB=$((PROC_COUNT / ${#JOBS[@]})) -# if multiple jobs and at least one processor for each job then background, else foreground with all available CPUs-1 (gox default) -if (( ${#JOBS[@]} > 1 && ${PROCS_PER_JOB} )); then - BACKGROUND="&" - # initialize an associative array in which to map background PIDs to the ARCH being built - typeset -A BUILDS -else - BACKGROUND="" # run normally in foreground - PROCS_PER_JOB=0 # invokes gox default to use all CPUs-1 -fi - ( HOME=/tmp/builder # Navigate to the "ui" directory and run npm commands @@ -44,42 +41,11 @@ fi npm run build ) -for ARCH in ${JOBS[@]}; do - GOX_CMD=" - gox \ - -cgo \ - -os=linux \ - -arch=${ARCH} \ - -output=${GOX_OUTPUT} \ - -parallel=${PROCS_PER_JOB} \ - ./cmd/zrok - " -case ${ARCH} in - amd64) eval ${GOX_CMD} ${BACKGROUND} - (( ${PROCS_PER_JOB} )) && BUILDS[${!}]=${ARCH} # if greater than zero procs per job then map background pid->arch - ;; - arm) eval CC=arm-linux-gnueabihf-gcc ${GOX_CMD} ${BACKGROUND} - (( ${PROCS_PER_JOB} )) && BUILDS[${!}]=${ARCH} - ;; - arm64) eval CC=aarch64-linux-gnu-gcc ${GOX_CMD} ${BACKGROUND} - (( ${PROCS_PER_JOB} )) && BUILDS[${!}]=${ARCH} - ;; - *) echo "ERROR: invalid architecture '${ARCH}', must be one of amd64, arm, arm64" >&2 - exit 1 - ;; - esac +for ARCH in "${JOBS[@]}"; do + goreleaser build \ + --clean \ + --snapshot \ + --output ./dist/ \ + --config "./.goreleaser-linux-$(resolveArch "${ARCH}").yml" done -# if not background in parallel then exit now with well earned success -[[ -z "${BACKGROUND:-}" ]] && exit 0 - -# Wait for builds in the background and exit with an error if any fail -EXIT=0 -while true; do - # "wait -p" requires BASH >=5.1 which is present in Ubuntu 20.10 and Debian Bullseye - wait -n -p JOB_PID; JOB_RESULT=$? - echo "Building for ${BUILDS[$JOB_PID]} finished with result ${JOB_RESULT}" - (( ${JOB_RESULT} )) && EXIT=1 -done - -exit ${EXIT} From b19e0994df21b1314cda4ebe8e1ed28c566e9273 Mon Sep 17 00:00:00 2001 From: Kenneth Bingham Date: Wed, 24 Jul 2024 16:21:02 -0400 Subject: [PATCH 3/5] announce fix in changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49849180..993f62fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ CHANGE: Enable `"declaration": true` in `tsconfig.json` for Node SDK. +FIX: Statically link arm 32bit build for broader compatibility. + ## v0.4.35 FEATURE: Added import for `github.com/greenpau/caddy-security` to include that Caddy plugin to enable authentication, authorization, and credentials extensions for the `caddy` backend (https://github.com/openziti/zrok/issues/506) From 477edd503c3420814d46fb5487a4bee81c4bbde1 Mon Sep 17 00:00:00 2001 From: Kenneth Bingham Date: Wed, 24 Jul 2024 16:41:13 -0400 Subject: [PATCH 4/5] rename goreleaser amd64 config to match other archs --- .github/workflows/release.yml | 4 ++-- .goreleaser-linux.yml => .goreleaser-linux-amd64.yml | 0 docker/images/cross-build/linux-build.sh | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) rename .goreleaser-linux.yml => .goreleaser-linux-amd64.yml (100%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba86e0b9..500ee20e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,7 +48,7 @@ jobs: with: distribution: goreleaser version: '~> v2' - args: release --skip=publish --config .goreleaser-linux.yml + args: release --skip=publish --config .goreleaser-linux-amd64.yml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -230,7 +230,7 @@ jobs: runs-on: macos-latest steps: - name: import distribution cert - uses: apple-actions/import-codesign-certs@v1 + uses: apple-actions/import-codesign-certs@v3 with: p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} diff --git a/.goreleaser-linux.yml b/.goreleaser-linux-amd64.yml similarity index 100% rename from .goreleaser-linux.yml rename to .goreleaser-linux-amd64.yml diff --git a/docker/images/cross-build/linux-build.sh b/docker/images/cross-build/linux-build.sh index f75c0eff..002c288d 100755 --- a/docker/images/cross-build/linux-build.sh +++ b/docker/images/cross-build/linux-build.sh @@ -13,13 +13,11 @@ set -o xtrace resolveArch() { case ${1} in - amd64) echo amd64 - ;; arm|armv7*|arm/v7*|armhf*) echo armhf ;; - arm64|armv8*|arm/v8*) echo arm64 + armv8*|arm/v8*) echo arm64 ;; - *) echo ${1} + *) echo "${1}" ;; esac } From a60c0bfab355d9798b5c218bb74392261f6e24ce Mon Sep 17 00:00:00 2001 From: Kenneth Bingham Date: Thu, 25 Jul 2024 13:27:31 -0400 Subject: [PATCH 5/5] switch 32bit release to armhf dynamically linked --- .github/workflows/release.yml | 2 +- .goreleaser-linux-armel.yml | 144 +++++++++++++++++++++++ .goreleaser-linux-armhf.yml | 10 +- docker/images/cross-build/Dockerfile | 1 + docker/images/cross-build/README.md | 30 +---- docker/images/cross-build/linux-build.sh | 13 +- docs/guides/install/linux.mdx | 20 ++-- 7 files changed, 173 insertions(+), 47 deletions(-) create mode 100644 .goreleaser-linux-armel.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 500ee20e..ebd59340 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -159,7 +159,7 @@ jobs: runs-on: ubuntu-20.04 steps: - run: sudo apt update - - run: sudo apt-get install gcc-arm-linux-gnueabi + - run: sudo apt-get install gcc-arm-linux-gnueabihf - uses: actions/checkout@v4 with: diff --git a/.goreleaser-linux-armel.yml b/.goreleaser-linux-armel.yml new file mode 100644 index 00000000..80bdbc26 --- /dev/null +++ b/.goreleaser-linux-armel.yml @@ -0,0 +1,144 @@ +# this is a DiY build config for the soft-float, armel platform (32bit ARMv7 devices lacking an FPU) see +# instructions to cross-build this binary in ./docker/images/cross-build/README.md or +# https://github.com/openziti/zrok/tree/main/docker/images/cross-build#readme +version: 2 +builds: +- id: zrok-armel + main: ./cmd/zrok + binary: zrok + ldflags: + - "-s -w -X github.com/openziti/zrok/build.Version={{.Tag}} -X github.com/openziti/zrok/build.Hash={{.ShortCommit}}" + env: + - CC=arm-linux-gnueabi-gcc + - CGO_ENABLED=1 + - CC_FOR_TARGET=gcc-arm-linux-gnueabi + goos: + - linux + goarch: + - arm + goarm: + - 7 + +nfpms: + - package_name: zrok + id: zrok-cli + vendor: NetFoundry + homepage: https://zrok.io/ + maintainer: support@zrok.io + description: |- + zrok is a next-generation sharing platform, designed to make sharing network and file resources simple and + secure. + license: Apache 2.0 + + # Build IDs for the builds you want to create NFPM packages for. + builds: + - zrok-armel + + # Formats to be generated. + formats: + - deb + - rpm + + # {{ .ConventionalFileName }} satisfies the RPM name convention. + file_name_template: "{{ .ConventionalFileName }}" + + # Umask to be used on files without explicit mode set. (overridable) + umask: 0o002 + + # Package version within this release version. + release: 1 + + # Section. + section: default + + # Priority. + priority: optional + + # GoReleaser will automatically add the binaries here + bindir: /opt/openziti/bin + + # Contents to add to the package. + contents: + - src: /opt/openziti/bin/zrok + dst: /usr/bin/zrok + type: "symlink" + + - package_name: zrok-share + id: zrok-share + vendor: NetFoundry + homepage: https://zrok.io/ + maintainer: support@zrok.io + description: |- + This package provides zrok-share.service. To enable, edit the "/opt/openziti/etc/zrok/zrok-share.env" file with the + desired target for sharing, and run "systemctl enable --now zrok-share.service". + license: Apache 2.0 + + # do not bundle the built binaries, only supporting files + meta: true + + # Formats to be generated. + formats: + - deb + - rpm + + # {{ .ConventionalFileName }} satisfies the RPM name convention. + file_name_template: "{{ .ConventionalFileName }}" + + # Umask to be used on files without explicit mode set. (overridable) + umask: 0o002 + + # Package version within this release version. + release: 1 + + # Section. + section: default + + # Priority. + priority: optional + + # GoReleaser will automatically add the binaries here + dependencies: + - zrok + + # this allows users to satisfy the requirement for jq another way, not with the package manager, e.g. + # apt install --no-recommends zrok-share + recommends: + - jq + + overrides: + # yum and dnf do not automatically install "weak deps" aka "recommends", so we need to add them as a dependency + rpm: + dependencies: + - zrok + - jq + + # Contents to add to the package. + contents: + - dst: /lib/systemd/system/ + src: ./nfpm/zrok-share.service + + - dst: /etc/systemd/system/zrok-share.service.d/override.conf + src: ./nfpm/zrok-share.service.override.conf + + - dst: /opt/openziti/etc/zrok + type: dir + file_info: + mode: 0755 + + - dst: /opt/openziti/bin/ + src: ./nfpm/zrok-share.bash + file_info: + mode: 0755 + + - dst: /opt/openziti/bin/ + src: ./nfpm/zrok-enable.bash + file_info: + mode: 0755 + + - dst: /opt/openziti/etc/zrok/ + src: ./nfpm/zrok-share.env + type: config|noreplace + + - dst: /opt/openziti/etc/zrok/ + src: ./etc/caddy/multiple_upstream.Caddyfile + type: config|noreplace diff --git a/.goreleaser-linux-armhf.yml b/.goreleaser-linux-armhf.yml index b02e10d8..c7275d81 100644 --- a/.goreleaser-linux-armhf.yml +++ b/.goreleaser-linux-armhf.yml @@ -1,15 +1,15 @@ +# this is the release build config for hard-float, arm/v7 platform (32bit ARM devices with a FPU) version: 2 builds: -- id: zrok-armv7 +- id: zrok-armhf main: ./cmd/zrok binary: zrok ldflags: - - '-extldflags "-static"' - "-s -w -X github.com/openziti/zrok/build.Version={{.Tag}} -X github.com/openziti/zrok/build.Hash={{.ShortCommit}}" env: - - CC=arm-linux-gnueabi-gcc + - CC=arm-linux-gnueabihf-gcc - CGO_ENABLED=1 - - CC_FOR_TARGET=gcc-arm-linux-gnueabi + - CC_FOR_TARGET=gcc-arm-linux-gnueabihf goos: - linux goarch: @@ -30,7 +30,7 @@ nfpms: # Build IDs for the builds you want to create NFPM packages for. builds: - - zrok-armv7 + - zrok-armhf # Formats to be generated. formats: diff --git a/docker/images/cross-build/Dockerfile b/docker/images/cross-build/Dockerfile index 2a30e63d..a8402f6f 100644 --- a/docker/images/cross-build/Dockerfile +++ b/docker/images/cross-build/Dockerfile @@ -17,6 +17,7 @@ ARG go_cache=/usr/share/go RUN apt-get -y update \ && apt-get -y install \ gcc-arm-linux-gnueabi \ + gcc-arm-linux-gnueabihf \ gcc-aarch64-linux-gnu \ wget \ git \ diff --git a/docker/images/cross-build/README.md b/docker/images/cross-build/README.md index 7aac5dc0..eb2db2f1 100644 --- a/docker/images/cross-build/README.md +++ b/docker/images/cross-build/README.md @@ -1,21 +1,15 @@ # Cross-build Container for Building the Linux Executables for this zrok Project -Running this container produces three executables for zrok, one for each platform architecture: amd64, arm, arm64. You may specify the target CPU architecture as a parameter to the `docker run` command. +Running this container produces one snapshot executable for zrok from the current checkout, even if dirty. Platform choices are: `amd64`, `arm64`, `arm` (the arm/v7 "armhf" ABI target), and `armel` (the arm/v7 "armel" ABI). You may specify the target architecture as a parameter to the `docker run` command. ## Build the Container Image You only need to build the container image once unless you change the Dockerfile or `./linux-build.sh`. ```bash -# build a container image named "zrok-builder" with the same version of Go that's declared in go.mod -docker buildx build \ - --tag=zrok-builder \ - --build-arg uid=$UID \ - --build-arg gid=$GID \ - --build-arg golang_version=$(grep -Po '^go\s+\K\d+\.\d+(\.\d+)?$' go.mod) \ - --load \ - ./docker/images/cross-build/ +# build a container image named "zrok-builder" +docker buildx build -t zrok-builder ./docker/images/cross-build --load; ``` ## Run the Container to Build Executables for the Desired Architectures @@ -24,23 +18,11 @@ Executing the following `docker run` command will: 1. Mount the top-level of this repo on the container's `/mnt` 2. Run `linux-build.sh ${@}` inside the container -3. Deposit built executables in `./dist/` +3. Deposit built executable in `./dist/` ```bash -# build for all three architectures: amd64 arm arm64 -docker run \ - --rm \ - --name=zrok-builder \ - --volume=$PWD:/mnt \ - zrok-builder - -# build only amd64 -docker run \ - --rm \ - --name=zrok-builder \ - --volume=$PWD:/mnt \ - zrok-builder \ - amd64 +# cross-build for arm64/aarch64 architecture on Linux +docker run --user "${UID}" --rm --volume=${HOME}/.cache/go-build:/usr/share/go --volume "${PWD}:/mnt" zrok-builder arm64 ``` You will find the built artifacts in `./dist/`. diff --git a/docker/images/cross-build/linux-build.sh b/docker/images/cross-build/linux-build.sh index 002c288d..04654f4a 100755 --- a/docker/images/cross-build/linux-build.sh +++ b/docker/images/cross-build/linux-build.sh @@ -1,10 +1,7 @@ #!/usr/bin/env bash # -# build the Linux artifacts for amd64, arm, arm64 +# build the Linux artifact for amd64, armhf, armel, or arm64 # -# runs one background job per desired architecture unless there are too few CPUs -# -# set -o errexit set -o nounset @@ -13,7 +10,7 @@ set -o xtrace resolveArch() { case ${1} in - arm|armv7*|arm/v7*|armhf*) echo armhf + arm|armv7*|arm/v7*) echo armhf ;; armv8*|arm/v8*) echo arm64 ;; @@ -22,11 +19,11 @@ resolveArch() { esac } -# if no architectures supplied then default list of three +# if no architectures supplied then default to amd64 if (( ${#} )); then typeset -a JOBS=(${@}) else - typeset -a JOBS=(amd64 arm arm64) + typeset -a JOBS=(amd64) fi ( @@ -43,7 +40,7 @@ for ARCH in "${JOBS[@]}"; do goreleaser build \ --clean \ --snapshot \ - --output ./dist/ \ + --output "./dist/" \ --config "./.goreleaser-linux-$(resolveArch "${ARCH}").yml" done diff --git a/docs/guides/install/linux.mdx b/docs/guides/install/linux.mdx index 2bdde103..f1cff6f2 100644 --- a/docs/guides/install/linux.mdx +++ b/docs/guides/install/linux.mdx @@ -64,11 +64,9 @@ Download the binary distribution for your Linux distribution's architecture or r
Script to install binary in `/usr/local/bin/zrok` -This script auto-selects the correct architecture, and may be helpful for Raspberry Pi users. +This script auto-selects the correct architecture and may be helpful for Raspberry Pi users. ```text -(set -euo pipefail; - cd $(mktemp -d); ZROK_VERSION=$( @@ -77,11 +75,15 @@ ZROK_VERSION=$( ); case $(uname -m) in - x86_64) GOXARCH=amd64 ;; - aarch64|arm64) GOXARCH=arm64 ;; - armv7|armhf|arm) GOXARCH=arm ;; - *) echo "ERROR: unknown arch '$(uname -m)'" >&2 - exit 1 ;; + x86_64) GOXARCH=amd64 + ;; + aarch64|arm64) GOXARCH=arm64 + ;; + arm*) GOXARCH=arm + ;; + *) echo "ERROR: unknown arch '$(uname -m)'" >&2 + exit 1 + ;; esac; curl -sSfL \ @@ -89,8 +91,8 @@ curl -sSfL \ | tar -xz -f -; sudo install -o root -g root ./zrok /usr/local/bin/; + zrok version; -) ```