diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7a17a88..6ee5f1b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,12 @@ name: CI -on: [push, pull_request] +on: + push: + branches: + - '*' + tags: + - 'v*' + pull_request: + jobs: tests: runs-on: ubuntu-latest @@ -9,9 +16,9 @@ jobs: uses: actions/checkout@v2 - name: Install Nix - uses: cachix/install-nix-action@v20 + uses: cachix/install-nix-action@v22 with: - nix_path: nixpkgs=channel:nixos-23.05 + nix_path: nixpkgs=channel:nixos-23.11 - name: Cargo cache uses: actions/cache@v3 @@ -26,3 +33,50 @@ jobs: - name: Run tests run: nix-shell --command "make test" + + dist: + needs: tests + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + strategy: + matrix: + target: + - x86_64-unknown-linux-musl + - aarch64-unknown-linux-musl + - armv7-unknown-linux-musleabihf + steps: + - + name: Checkout + uses: actions/checkout@v2 + - + name: Install Nix + uses: cachix/install-nix-action@v22 + with: + nix_path: nixpkgs=channel:nixos-23.11 + - + name: Cargo cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-dist-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} + - + name: Build distributables + run: nix-shell --command "make dist-${{ matrix.target }}" + - + name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: eu-west-1 + - + name: Upload binaries to S3 + run: | + aws s3 sync dist s3://builds.loraserver.io/chirpstack-udp-forwarder + if: startsWith(github.ref, 'refs/tags/v') + diff --git a/Cargo.toml b/Cargo.toml index bc533f1..2d8d812 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,27 @@ prometheus-client = "0.22" lazy_static = "1.4" anyhow = "1.0" + +[package.metadata.deb] + assets = [ + [ + "target/release/chirpstack-udp-forwarder", + "usr/bin/", + "755", + ], + [ + "packaging/debian/chirpstack-udp-forwarder.toml", + "etc/chirpstack-udp-forwarder/", + "640", + ], + ] + conf-files = ["/etc/chirpstack-udp-forwarder/chirpstack-udp-forwarder.toml"] + maintainer-scripts = "packaging/debian/" + systemd-units = { enable = true } + +[profile.release] + strip = true + opt-level = "z" + lto = true + codegen-units = 1 + panic = "abort" diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 0000000..a56404e --- /dev/null +++ b/Cross.toml @@ -0,0 +1,8 @@ +[target.x86_64-unknown-linux-musl] +dockerfile="cross/Dockerfile.x86_64-unknown-linux-musl" + +[target.aarch64-unknown-linux-musl] +dockerfile="cross/Dockerfile.aarch64-unknown-linux-musl" + +[target.armv7-unknown-linux-musleabihf] +dockerfile="cross/Dockerfile.armv7-unknown-linux-musleabihf" diff --git a/Makefile b/Makefile index 3e7c9af..0eb6e5d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,66 @@ .PHONY: dist +# Compile the binaries for all targets +build: \ + build-aarch64-unknown-linux-musl \ + build-x86_64-unknown-linux-musl \ + build-armv7-unknown-linux-musleabihf + +build-x86_64-unknown-linux-musl: + cross build --target x86_64-unknown-linux-musl --release + +build-aarch64-unknown-linux-musl: + cross build --target aarch64-unknown-linux-musl --release + +build-armv7-unknown-linux-musleabihf: + cross build --target armv7-unknown-linux-musleabihf --release + +# Build distributable binaries for all targets. +dist: \ + dist-aarch64-unknown-linux-musl \ + dist-x86_64-unknown-linux-musl \ + dist-armv7-unknown-linux-musleabihf + +dist-x86_64-unknown-linux-musl: build-x86_64-unknown-linux-musl package-x86_64-unknown-linux-musl + +dist-aarch64-unknown-linux-musl: build-aarch64-unknown-linux-musl package-aarch64-unknown-linux-musl + +dist-armv7-unknown-linux-musleabihf: build-armv7-unknown-linux-musleabihf package-armv7-unknown-linux-musleabihf + +# Package the compiled binaries +package-x86_64-unknown-linux-musl: + $(eval PKG_VERSION := $(shell cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')) + mkdir -p dist + + # .tar.gz + tar -czvf dist/chirpstack-udp-forwarder_$(PKG_VERSION)_amd64.tar.gz -C target/x86_64-unknown-linux-musl/release chirpstack-udp-forwarder + + # .deb + cargo deb --target x86_64-unknown-linux-musl --no-build --no-strip + cp target/x86_64-unknown-linux-musl/debian/*.deb ./dist + +package-aarch64-unknown-linux-musl: + $(eval PKG_VERSION := $(shell cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')) + mkdir -p dist + + # .tar.gz + tar -czvf dist/chirpstack-udp-forwarder_$(PKG_VERSION)_arm64.tar.gz -C target/aarch64-unknown-linux-musl/release chirpstack-udp-forwarder + + # .deb + cargo deb --target aarch64-unknown-linux-musl --no-build --no-strip + cp target/aarch64-unknown-linux-musl/debian/*.deb ./dist + +package-armv7-unknown-linux-musleabihf: + $(eval PKG_VERSION := $(shell cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')) + mkdir -p dist + + # .tar.gz + tar -czvf dist/chirpstack-udp-forwarder_$(PKG_VERSION)_armv7hf.tar.gz -C target/armv7-unknown-linux-musleabihf/release chirpstack-udp-forwarder + + # .deb + cargo deb --target armv7-unknown-linux-musleabihf --no-build --no-strip + cp target/armv7-unknown-linux-musleabihf/debian/*.deb ./dist + # Update the version version: test -n "$(VERSION)" diff --git a/cross/Dockerfile.aarch64-unknown-linux-musl b/cross/Dockerfile.aarch64-unknown-linux-musl new file mode 100644 index 0000000..1d3915e --- /dev/null +++ b/cross/Dockerfile.aarch64-unknown-linux-musl @@ -0,0 +1,6 @@ +FROM ghcr.io/cross-rs/aarch64-unknown-linux-musl:latest + +RUN apt-get update && \ + apt-get --assume-yes install \ + protobuf-compiler \ + libprotobuf-dev diff --git a/cross/Dockerfile.armv7-unknown-linux-musleabihf b/cross/Dockerfile.armv7-unknown-linux-musleabihf new file mode 100644 index 0000000..1a6682e --- /dev/null +++ b/cross/Dockerfile.armv7-unknown-linux-musleabihf @@ -0,0 +1,6 @@ +FROM ghcr.io/cross-rs/armv7-unknown-linux-musleabihf:latest + +RUN apt-get update && \ + apt-get --assume-yes install \ + protobuf-compiler \ + libprotobuf-dev diff --git a/cross/Dockerfile.x86_64-unknown-linux-musl b/cross/Dockerfile.x86_64-unknown-linux-musl new file mode 100644 index 0000000..30ac69e --- /dev/null +++ b/cross/Dockerfile.x86_64-unknown-linux-musl @@ -0,0 +1,6 @@ +FROM ghcr.io/cross-rs/x86_64-unknown-linux-musl:latest + +RUN apt-get update && \ + apt-get --assume-yes install \ + protobuf-compiler \ + libprotobuf-dev diff --git a/packaging/debian/chirpstack-udp-forwarder.toml b/packaging/debian/chirpstack-udp-forwarder.toml new file mode 100644 index 0000000..ee426dd --- /dev/null +++ b/packaging/debian/chirpstack-udp-forwarder.toml @@ -0,0 +1,62 @@ +# UDP Forwarder configuration. +[udp_forwarder] + + # Log level. + # + # Valid options are: + # * TRACE + # * DEBUG + # * INFO + # * WARN + # * ERROR + # * OFF + log_level="INFO" + + # Log to syslog. + # + # When set to true, log messages are being written to syslog instead of stdout. + log_to_syslog=false + + # Prometheus metrics bind. + # + # E.g. '0.0.0.0:9800', leave blank to disable the metrics endpoint. + metrics_bind="" + + + # Servers to forward the data to using UDP. + # This section can be repeated. + [[udp_forwarder.servers]] + # Server (hostname:port). + server="localhost:1700" + + # Keepalive interval (seconds). + # + # In this interval, the ChirpStack UDP Forwarder will send keepalive + # frames to the server, which must be answered by an acknowledgement. + keepalive_interval_secs=10 + + # Max. allowed keepalive failures. + # + # After the max. number has been reached, the ChirpStack UDP Forwarder will + # 're-connect' to the server, meaning it will also re-resolve the DNS in case + # the server address is a hostname. + keepalive_max_failures=12 + + # Forward CRC OK. + forward_crc_ok=true + + # Forward CRC invalid. + forward_crc_invalid=false + + # Forward CRC missing. + forward_crc_missing=false + + +# Concentratord configuration. +[concentratord] + + # Event API URL. + event_url="ipc:///tmp/concentratord_event" + + # Command API URL. + command_url="ipc:///tmp/concentratord_command" diff --git a/packaging/debian/postinst b/packaging/debian/postinst new file mode 100644 index 0000000..304b7e6 --- /dev/null +++ b/packaging/debian/postinst @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +# Set config-file permissions +chown -R chirpstack:chirpstack /etc/chirpstack-udp-forwarder +chmod 750 /etc/chirpstack-udp-forwarder +chmod 640 /etc/chirpstack-udp-forwarder/*.toml + +#DEBHELPER# + diff --git a/packaging/debian/preinst b/packaging/debian/preinst new file mode 100644 index 0000000..0170694 --- /dev/null +++ b/packaging/debian/preinst @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +# Create the ChirpStack user +id chirpstack &>/dev/null +if [[ $? -ne 0 ]]; then + useradd --system -U -M chirpstack -s /bin/false -d /etc/chirpstack +fi + +#DEBHELPER# diff --git a/packaging/debian/service b/packaging/debian/service new file mode 100644 index 0000000..56a7693 --- /dev/null +++ b/packaging/debian/service @@ -0,0 +1,14 @@ +[Unit] +Description=ChirpStack UDP Forwarder +Documentation=https://www.chirpstack.io/ +Wants=network-online.target +After=network-online.target + +[Service] +User=chirpstack +Group=chirpstack +ExecStart=/usr/bin/chirpstack-udp-forwarder -c /etc/chirpstack-udp-forwarder/chirpstack-udp-forwarder.toml +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 6da8833..5e0120e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.77.1" +channel = "1.78.0" components = ["rustfmt", "clippy"] profile = "default" diff --git a/shell.nix b/shell.nix index 391f68d..07d22da 100644 --- a/shell.nix +++ b/shell.nix @@ -5,5 +5,7 @@ pkgs.mkShell { pkgs.cacert pkgs.rustup pkgs.protobuf + pkgs.cargo-cross + pkgs.cargo-deb ]; }