#!/bin/sh # Builds Jarl's two Debian packages: # # dist/jarl-cli__.deb the CLI, to install anywhere: # /usr/bin/jarl, its bash completion, and /usr/share/doc/jarl-cli/ # (README, CHANGELOG, the CLI, ACME and permissions docs, contrib/ with # the acme.sh and lego hooks). No scripts: installing it changes nothing # else on the machine. # dist/jarl__.deb the server, which depends on # jarl-cli of the same version: # /usr/bin/jarld and its bash completion # /usr/lib/systemd/system/{jarl.service,jarl-backup.service,jarl-backup.timer} # /usr/lib/sysusers.d/jarl.conf, /usr/lib/tmpfiles.d/jarl.conf # /usr/share/doc/jarl/ (README, CHANGELOG, docs) # Its scripts (deploy/debian) create the jarl user and directories and # /etc/jarl/jarl.yaml on the first install, turn on the daily backup # timer, restart a running jarld on upgrades, and stop both on removal. # No file in /etc belongs to the package, so an upgrade never asks # about configuration files. # # Until 0.1.0 one package, jarl, held both; jarl-cli takes /usr/bin/jarl # over from it (Replaces: jarl). # # Run through 'make deb' (which sets the variables below); needs only # dpkg-deb, no root and no debhelper. # # Variables: DEB_ARCH (Debian architecture, e.g. amd64, arm64, armhf), # DEB_VERSION, VERSION, LDFLAGS, GOFLAGS, and DEB_MAINTAINER (default: your # git name and email). set -eu : "${DEB_ARCH:?}" "${DEB_VERSION:?}" "${VERSION:?}" "${LDFLAGS:?}" GOFLAGS=${GOFLAGS:-} # Debian architecture -> Go architecture. goarm= case "$DEB_ARCH" in amd64) goarch=amd64 ;; arm64) goarch=arm64 ;; armhf) goarch=arm goarm=7 ;; i386) goarch=386 ;; ppc64el) goarch=ppc64le ;; riscv64) goarch=riscv64 ;; s390x) goarch=s390x ;; *) echo "mkdeb: unsupported architecture $DEB_ARCH" >&2; exit 1 ;; esac if [ -z "${DEB_MAINTAINER:-}" ]; then name=$(git config user.name 2>/dev/null || true) email=$(git config user.email 2>/dev/null || true) DEB_MAINTAINER="${name:-Jarl packager} <${email:-root@localhost}>" fi work=dist/deb/${DEB_VERSION}_${DEB_ARCH} stage=$work/stage rm -rf "$work" # Older packages of this architecture (every development build has its # own version), so 'apt install ./dist/jarl_*_amd64.deb' finds just one. rm -f dist/jarl_*_"$DEB_ARCH".deb dist/jarl-cli_*_"$DEB_ARCH".deb mkdir -p "$stage" # Binaries for the package's architecture (bin/ holds the host's, which # also generated the completion scripts). echo "mkdeb: building for linux/$goarch" # go reads GOFLAGS (-trimpath) from the environment. export GOFLAGS GOOS=linux GOARCH=$goarch GOARM=$goarm CGO_ENABLED=0 go build -ldflags "$LDFLAGS" -o "$work/bin/jarld" ./cmd/jarld GOOS=linux GOARCH=$goarch GOARM=$goarm CGO_ENABLED=0 go build -ldflags "$LDFLAGS" -o "$work/bin/jarl" ./cmd/jarl # Everything 'make install' would install, then split in two. make --no-print-directory install-files DESTDIR="$stage" PREFIX=/usr \ UNITDIR=/usr/lib/systemd/system JARLD_BIN="$work/bin/jarld" JARL_BIN="$work/bin/jarl" >/dev/null cli=$work/jarl-cli srv=$work/jarl mkdir -p "$cli/DEBIAN" "$cli/usr/bin" "$cli/usr/share/bash-completion/completions" "$cli/usr/share/doc/jarl-cli/docs" mv "$stage/usr/bin/jarl" "$cli/usr/bin/" mv "$stage/usr/share/bash-completion/completions/jarl" "$cli/usr/share/bash-completion/completions/" mv "$stage/usr/share/doc/jarl/contrib" "$cli/usr/share/doc/jarl-cli/" cp "$stage/usr/share/doc/jarl/README.md" "$stage/usr/share/doc/jarl/CHANGELOG.md" "$cli/usr/share/doc/jarl-cli/" for d in cli acme permissions; do cp "$stage/usr/share/doc/jarl/docs/$d.md" "$cli/usr/share/doc/jarl-cli/docs/" done mv "$stage" "$srv" mkdir -p "$srv/DEBIAN" for f in postinst prerm postrm; do install -m 0755 "deploy/debian/$f" "$srv/DEBIAN/$f" done # Debian's machine-readable copyright file, from LICENSE. indent() { sed -e 's/^$/./' -e 's/^/ /' "$1"; } copyright() { echo "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/" echo "Upstream-Name: jarl" echo echo "Files: *" echo "Copyright: $(sed -n 's/^Copyright (c) //p' LICENSE)" echo "License: Expat" indent LICENSE } # build PACKAGE ROOT: writes the control file and md5sums and builds the .deb. build() { pkg=$1 root=$2 out=dist/${1}_${DEB_VERSION}_${DEB_ARCH}.deb copyright > "$root/usr/share/doc/$pkg/copyright" rm -f "$root/usr/share/doc/$pkg/LICENSE" # Directories 0755 and no group/other write, whatever the build's umask. find "$root" -type d -exec chmod 0755 {} + chmod -R go-w "$root" size=$(du -sk --exclude=DEBIAN "$root" | cut -f1) sed -e "s/@VERSION@/$DEB_VERSION/g" -e "s/@ARCH@/$DEB_ARCH/" -e "s/@SIZE@/$size/" \ -e "s|@MAINTAINER@|$DEB_MAINTAINER|" "deploy/debian/control-$pkg.in" > "$root/DEBIAN/control" (cd "$root" && find . -path ./DEBIAN -prune -o -type f -print | sed 's|^\./||' | sort | xargs md5sum) > "$root/DEBIAN/md5sums" chmod 0644 "$root/DEBIAN/control" "$root/DEBIAN/md5sums" # Files belong to root in the package, whoever builds it. dpkg-deb --root-owner-group -Zxz --build "$root" "$out" >/dev/null echo "mkdeb: wrote $out" dpkg-deb --info "$out" | sed -n 's/^ \(Package\|Version\|Architecture\|Installed-Size\|Depends\):/ \1:/p' } build jarl-cli "$cli" build jarl "$srv" rm -rf dist/deb