Split the packages, publish releases from Gitea Actions, release 0.1.0
release / release (push) Successful in 7m7s
release / release (push) Successful in 7m7s
make deb now builds two packages: jarl-cli (the CLI, its completion and the ACME hooks, no scripts) and jarl (the server), which depends on jarl-cli of the same version. Pushing a v* tag runs .gitea/workflows/release.yml: it tests, builds the tarballs, the CLI for Linux, macOS and Windows (make cli-dist) and the .debs for amd64 and arm64, then scripts/gitea-release.sh creates the Gitea release and uploads the .debs to the Debian package registry, so servers install and upgrade with apt. The stats package's inode lookup is split by OS so the CLI builds for Windows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
293e6ddd33
commit
4d00be53c3
16 files changed
+441
-75
No files matched your search
@@ -0,0 +1,61 @@
|
|||||||
|
# Builds and publishes a release when a version tag (v0.2.0, v1.0.0-rc.1)
|
||||||
|
# is pushed:
|
||||||
|
# * a Gitea release with the CHANGELOG notes, the linux tarballs, the CLI
|
||||||
|
# for Linux, macOS and Windows, the .debs and SHA256SUMS;
|
||||||
|
# * the .debs (amd64, arm64) in the owner's Debian package registry.
|
||||||
|
#
|
||||||
|
# Needs a repository secret RELEASE_TOKEN: an access token of a user who
|
||||||
|
# can write to the repository, with the write:repository and write:package
|
||||||
|
# scopes. docs/development.md ("Releasing") has the steps.
|
||||||
|
name: release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: ["v*"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
|
||||||
|
- name: Check the tag against VERSION and CHANGELOG.md
|
||||||
|
run: |
|
||||||
|
version=$(cat VERSION)
|
||||||
|
if [ "$GITHUB_REF_NAME" != "v$version" ]; then
|
||||||
|
echo "::error::tag $GITHUB_REF_NAME does not match VERSION ($version)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! grep -q "^## \[$version\]" CHANGELOG.md; then
|
||||||
|
echo "::error::CHANGELOG.md has no '## [$version]' section"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Tools
|
||||||
|
run: |
|
||||||
|
missing=
|
||||||
|
for t in jq dpkg-deb curl; do command -v $t >/dev/null || missing="$missing $t"; done
|
||||||
|
if [ -n "$missing" ]; then
|
||||||
|
sudo=; [ "$(id -u)" = 0 ] || sudo=sudo
|
||||||
|
$sudo apt-get update -qq && $sudo apt-get install -y -qq jq dpkg curl
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: make test
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
export DEB_MAINTAINER="$(git log -1 --format='%an <%ae>')"
|
||||||
|
make dist
|
||||||
|
make cli-dist
|
||||||
|
make deb DEB_ARCH=amd64
|
||||||
|
make deb DEB_ARCH=arm64
|
||||||
|
|
||||||
|
- name: Publish
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
|
run: scripts/gitea-release.sh
|
||||||
+20
-7
@@ -6,7 +6,9 @@ All notable changes to Jarl are documented here. The format follows
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
The first version, to be released as 0.1.0.
|
## [0.1.0] - 2026-10-09
|
||||||
|
|
||||||
|
The first version.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
@@ -68,12 +70,23 @@ The first version, to be released as 0.1.0.
|
|||||||
`socket`. The systemd unit creates `/run/jarl` (0750).
|
`socket`. The systemd unit creates `/run/jarl` (0750).
|
||||||
- Jarl is released under the MIT License (`LICENSE`), which is installed
|
- Jarl is released under the MIT License (`LICENSE`), which is installed
|
||||||
with the docs and is the Debian package's `copyright` file.
|
with the docs and is the Debian package's `copyright` file.
|
||||||
- A Debian package: `make deb` builds `dist/jarl_<version>_<arch>.deb` with
|
- Debian packages: `make deb` builds, with only `dpkg-deb` (no root) and
|
||||||
only `dpkg-deb` (no root), for the host or any other architecture
|
for the host or any other architecture (`DEB_ARCH=arm64`), `jarl` (the
|
||||||
(`DEB_ARCH=arm64`). Installing it creates the `jarl` user and directories
|
server: jarld, its units and docs) and `jarl-cli` (the `jarl` CLI, its
|
||||||
and an example `/etc/jarl/jarl.yaml`; upgrades restart a running jarld and
|
completion and the ACME hooks), which `jarl` depends on. `jarl-cli` has no
|
||||||
never touch `/etc/jarl/jarl.yaml`; removing it stops jarld, and even a
|
scripts, so it can go on any machine you manage Jarl from. Installing
|
||||||
purge keeps Jarl's database and the files named uses.
|
`jarl` creates the `jarl` user and directories and an example
|
||||||
|
`/etc/jarl/jarl.yaml`; upgrades restart a running jarld and never touch
|
||||||
|
`/etc/jarl/jarl.yaml`; removing it stops jarld, and even a purge keeps
|
||||||
|
Jarl's database and the files named uses.
|
||||||
|
- Releases from Gitea Actions: pushing a `v<version>` tag runs
|
||||||
|
`.gitea/workflows/release.yml`, which tests, builds and publishes a Gitea
|
||||||
|
release (the CHANGELOG section as notes; the tarballs, the CLI for Linux,
|
||||||
|
macOS and Windows, the `.deb`s and `SHA256SUMS`), and uploads the `.deb`s
|
||||||
|
for amd64 and arm64 to the Gitea Debian registry, so servers install and
|
||||||
|
upgrade Jarl with apt. `make cli-dist` builds the standalone CLI files;
|
||||||
|
`scripts/gitea-release.sh` publishes. docs/development.md has the setup
|
||||||
|
(a runner and a `RELEASE_TOKEN` secret), docs/install.md the apt source.
|
||||||
- Bash completion for `jarl` and `jarld`, installed by `make install` and
|
- Bash completion for `jarl` and `jarld`, installed by `make install` and
|
||||||
the Debian package. Besides commands and flags, it completes server and
|
the Debian package. Besides commands and flags, it completes server and
|
||||||
group names from the CLI configuration, zone, view, ACL, TSIG key and
|
group names from the CLI configuration, zone, view, ACL, TSIG key and
|
||||||
|
|||||||
@@ -6,9 +6,12 @@
|
|||||||
# make e2e end-to-end test against a real named (scripts/e2e.sh)
|
# make e2e end-to-end test against a real named (scripts/e2e.sh)
|
||||||
# sudo make install install binaries, bash completion, systemd units,
|
# sudo make install install binaries, bash completion, systemd units,
|
||||||
# sysusers/tmpfiles files and an example /etc/jarl/jarl.yaml
|
# sysusers/tmpfiles files and an example /etc/jarl/jarl.yaml
|
||||||
# make deb a Debian package in dist/ (DEB_ARCH=arm64 for another
|
# make deb Debian packages in dist/ (DEB_ARCH=arm64 for another
|
||||||
# architecture); install it with 'sudo apt install ./dist/jarl_*.deb'
|
# architecture): jarl (the server) and jarl-cli (the CLI,
|
||||||
|
# which jarl depends on); 'sudo apt install ./dist/jarl*_amd64.deb'
|
||||||
# make dist static binaries for linux/amd64 and linux/arm64 in dist/
|
# make dist static binaries for linux/amd64 and linux/arm64 in dist/
|
||||||
|
# make cli-dist the CLI alone for Linux, macOS and Windows in dist/
|
||||||
|
# (jarl-cli-<version>-<os>-<arch>[.exe])
|
||||||
|
|
||||||
VERSION ?= $(shell cat VERSION 2>/dev/null || echo 0.0.0-dev)
|
VERSION ?= $(shell cat VERSION 2>/dev/null || echo 0.0.0-dev)
|
||||||
LDFLAGS := -s -w -X jarl/internal/version.Version=$(VERSION)
|
LDFLAGS := -s -w -X jarl/internal/version.Version=$(VERSION)
|
||||||
@@ -34,7 +37,7 @@ JARL_BIN ?= bin/jarl
|
|||||||
DEB_ARCH ?= $(shell dpkg --print-architecture 2>/dev/null || go env GOARCH)
|
DEB_ARCH ?= $(shell dpkg --print-architecture 2>/dev/null || go env GOARCH)
|
||||||
DEB_VERSION ?= $(subst -,~,$(VERSION))
|
DEB_VERSION ?= $(subst -,~,$(VERSION))
|
||||||
|
|
||||||
.PHONY: all build completion test vet e2e install install-files uninstall deb dist clean
|
.PHONY: all build completion test vet e2e install install-files uninstall deb dist cli-dist clean
|
||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
@@ -114,5 +117,15 @@ dist: build
|
|||||||
tar -C dist -czf dist/jarl-$(VERSION)-linux-$$arch.tar.gz jarl-$(VERSION)-linux-$$arch || exit 1; \
|
tar -C dist -czf dist/jarl-$(VERSION)-linux-$$arch.tar.gz jarl-$(VERSION)-linux-$$arch || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# The platforms cli-dist builds the CLI for.
|
||||||
|
CLI_PLATFORMS ?= linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64
|
||||||
|
|
||||||
|
cli-dist:
|
||||||
|
@mkdir -p dist
|
||||||
|
for p in $(CLI_PLATFORMS); do \
|
||||||
|
os=$${p%/*} arch=$${p#*/} ext=; [ $$os = windows ] && ext=.exe; \
|
||||||
|
GOOS=$$os GOARCH=$$arch go build $(GOFLAGS) -ldflags '$(LDFLAGS)' -o dist/jarl-cli-$(VERSION)-$$os-$$arch$$ext ./cmd/jarl || exit 1; \
|
||||||
|
done
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf bin dist
|
rm -rf bin dist
|
||||||
@@ -67,8 +67,9 @@ error: www.adbraun.lol has a CNAME, so it can't have any other records (found A)
|
|||||||
fallback.
|
fallback.
|
||||||
* One static Go binary for the daemon (web UI embedded, SQLite built in) and
|
* One static Go binary for the daemon (web UI embedded, SQLite built in) and
|
||||||
one for the CLI, run by a sandboxed systemd service as an unprivileged
|
one for the CLI, run by a sandboxed systemd service as an unprivileged
|
||||||
user. `make deb` builds a Debian package, and both come with bash
|
user. Releases come as Debian packages in an apt repository (server and
|
||||||
completion.
|
CLI separately) and as standalone CLI downloads for Linux, macOS and
|
||||||
|
Windows; both binaries have bash completion.
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
@@ -76,7 +77,8 @@ On a Debian/Ubuntu BIND 9.20 server ([install.md](docs/install.md) has the
|
|||||||
details):
|
details):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make deb && sudo apt install ./dist/jarl_*.deb # or: make && sudo make install, see install.md
|
sudo apt install jarl # from the Gitea package registry (install.md shows adding it)
|
||||||
|
# or build it: make deb && sudo apt install ./dist/jarl*_amd64.deb, or make && sudo make install
|
||||||
sudo -u jarl jarld init # database + first administrator
|
sudo -u jarl jarld init # database + first administrator
|
||||||
sudo -u jarl jarld import # read the current named.conf and zones
|
sudo -u jarl jarld import # read the current named.conf and zones
|
||||||
sudo jarld adopt # switch named over (keeps a backup, rolls back on failure)
|
sudo jarld adopt # switch named over (keeps a backup, rolls back on failure)
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
Package: jarl-cli
|
||||||
|
Version: @VERSION@
|
||||||
|
Architecture: @ARCH@
|
||||||
|
Maintainer: @MAINTAINER@
|
||||||
|
Installed-Size: @SIZE@
|
||||||
|
Replaces: jarl
|
||||||
|
Section: net
|
||||||
|
Priority: optional
|
||||||
|
Description: command line client for Jarl, the BIND 9 manager
|
||||||
|
jarl is the command line client for Jarl servers (jarld): zones,
|
||||||
|
records, views, ACLs, TSIG keys and options, changesets, users and
|
||||||
|
tokens, and query statistics, on one server or a group of them.
|
||||||
|
It talks to jarld's REST API with an API token, or, on the server
|
||||||
|
itself, to jarld's local socket.
|
||||||
|
.
|
||||||
|
Install this package alone to manage Jarl servers from another machine;
|
||||||
|
the jarl package (the server) depends on it. It also has the ACME DNS-01
|
||||||
|
hooks for acme.sh and lego in /usr/share/doc/jarl-cli/contrib.
|
||||||
@@ -3,7 +3,7 @@ Version: @VERSION@
|
|||||||
Architecture: @ARCH@
|
Architecture: @ARCH@
|
||||||
Maintainer: @MAINTAINER@
|
Maintainer: @MAINTAINER@
|
||||||
Installed-Size: @SIZE@
|
Installed-Size: @SIZE@
|
||||||
Depends: systemd
|
Depends: systemd, jarl-cli (= @VERSION@)
|
||||||
Recommends: bind9 (>= 1:9.20)
|
Recommends: bind9 (>= 1:9.20)
|
||||||
Section: net
|
Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
@@ -14,7 +14,8 @@ Description: web UI, REST API and CLI for managing a BIND 9 server
|
|||||||
loaded into named as one changeset that can be reverted. Users and API
|
loaded into named as one changeset that can be reverted. Users and API
|
||||||
tokens have fine-grained permissions, and every change is audited.
|
tokens have fine-grained permissions, and every change is audited.
|
||||||
.
|
.
|
||||||
The package installs jarld (the daemon, as the systemd service jarl) and
|
This package is the server: jarld (the daemon, as the systemd service
|
||||||
jarl (the CLI), with bash completion for both. jarld isn't started on a
|
jarl) with its daily backup timer. The jarl CLI comes from jarl-cli,
|
||||||
first install: see /usr/share/doc/jarl/docs/install.md to create the
|
which can also be installed on its own on other machines. jarld isn't
|
||||||
database and adopt the BIND configuration.
|
started on a first install: see /usr/share/doc/jarl/docs/install.md to
|
||||||
|
create the database and adopt the BIND configuration.
|
||||||
+2
-2
@@ -68,7 +68,7 @@ configuration, so `certbot renew` works unattended.
|
|||||||
Install the DNS API hook that comes with Jarl:
|
Install the DNS API hook that comes with Jarl:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cp contrib/acme.sh/dns_jarl.sh ~/.acme.sh/dnsapi/ # or from /usr/local/share/doc/jarl/contrib/
|
cp contrib/acme.sh/dns_jarl.sh ~/.acme.sh/dnsapi/ # or from /usr/share/doc/jarl-cli/contrib/ (jarl-cli package)
|
||||||
export JARL_SERVER=https://ns1.adbraun.lol:8053
|
export JARL_SERVER=https://ns1.adbraun.lol:8053
|
||||||
export JARL_TOKEN=$(cat /etc/jarl/certbot.token)
|
export JARL_TOKEN=$(cat /etc/jarl/certbot.token)
|
||||||
acme.sh --issue --dns dns_jarl -d adbraun.lol -d '*.adbraun.lol'
|
acme.sh --issue --dns dns_jarl -d adbraun.lol -d '*.adbraun.lol'
|
||||||
@@ -86,7 +86,7 @@ Jarl ships one, `contrib/lego/jarl-lego.sh`, which calls the `jarl` CLI
|
|||||||
(so jarl must be installed on the same host):
|
(so jarl must be installed on the same host):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo install -m 0755 contrib/lego/jarl-lego.sh /usr/local/bin/jarl-lego # or from /usr/local/share/doc/jarl/contrib/
|
sudo install -m 0755 contrib/lego/jarl-lego.sh /usr/local/bin/jarl-lego # or from /usr/share/doc/jarl-cli/contrib/ (jarl-cli package)
|
||||||
export EXEC_PATH=/usr/local/bin/jarl-lego
|
export EXEC_PATH=/usr/local/bin/jarl-lego
|
||||||
export JARL_SERVER=https://ns1.adbraun.lol:8053
|
export JARL_SERVER=https://ns1.adbraun.lol:8053
|
||||||
export JARL_TOKEN=@/etc/jarl/certbot.token
|
export JARL_TOKEN=@/etc/jarl/certbot.token
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ Besides commands and flags, Tab completes:
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
|
On the DNS server the CLI comes with Jarl. To use it from another machine,
|
||||||
|
install just the `jarl-cli` package there, or copy the static `jarl` binary
|
||||||
|
([install.md](install.md#just-the-cli-on-another-machine)).
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
jarl config set server https://ns1.adbraun.lol:8053
|
jarl config set server https://ns1.adbraun.lol:8053
|
||||||
jarl config set token # paste the token at the prompt
|
jarl config set token # paste the token at the prompt
|
||||||
|
|||||||
+38
-5
@@ -49,7 +49,7 @@ make # bin/jarld, bin/jarl (CGO_ENABLED=0, version from ./VERSION),
|
|||||||
# and bin/completion/{jarl,jarld} (bash completion)
|
# and bin/completion/{jarl,jarld} (bash completion)
|
||||||
make test # go vet, gofmt check, go test ./...
|
make test # go vet, gofmt check, go test ./...
|
||||||
make e2e # scripts/e2e.sh
|
make e2e # scripts/e2e.sh
|
||||||
make deb # dist/jarl_<version>_<arch>.deb (DEB_ARCH=arm64 etc. cross-builds)
|
make deb # dist/jarl_<version>_<arch>.deb (server) and jarl-cli_<version>_<arch>.deb (DEB_ARCH=arm64 etc. cross-builds)
|
||||||
```
|
```
|
||||||
|
|
||||||
### The Debian package
|
### The Debian package
|
||||||
@@ -70,7 +70,7 @@ To try the package without installing it on your machine:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker run --rm -it -v "$PWD/dist:/pkg:ro" debian:trixie \
|
docker run --rm -it -v "$PWD/dist:/pkg:ro" debian:trixie \
|
||||||
sh -c 'apt-get update && apt-get install -y /pkg/jarl_*_amd64.deb && bash'
|
sh -c 'apt-get update && apt-get install -y /pkg/jarl_*_amd64.deb /pkg/jarl-cli_*_amd64.deb && bash'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Shell completion
|
### Shell completion
|
||||||
@@ -154,7 +154,40 @@ files are embedded at build time, so rebuild jarld after changes.
|
|||||||
|
|
||||||
## Releasing
|
## Releasing
|
||||||
|
|
||||||
1. Move the "Unreleased" section of `CHANGELOG.md` under the new version
|
1. Move the "Unreleased" section of `CHANGELOG.md` under
|
||||||
and date.
|
`## [<version>] - <date>`.
|
||||||
2. Put the version in `VERSION`.
|
2. Put the version in `VERSION`.
|
||||||
3. `make test && JARL_BIND_ROOT=... make e2e && make dist`.
|
3. `make test && JARL_BIND_ROOT=... make e2e` (CI runs only `make test`;
|
||||||
|
it has no BIND).
|
||||||
|
4. Commit, tag and push: `git tag v<version> && git push origin main v<version>`.
|
||||||
|
|
||||||
|
The tag starts `.gitea/workflows/release.yml`, which checks that the tag
|
||||||
|
matches `VERSION` and that `CHANGELOG.md` has the section, runs `make
|
||||||
|
test`, builds everything (`make dist`, `make cli-dist`, `make deb` for
|
||||||
|
amd64 and arm64) and runs `scripts/gitea-release.sh`. That creates the
|
||||||
|
Gitea release (the CHANGELOG section as notes; the tarballs, the CLI for
|
||||||
|
Linux, macOS and Windows, the `.deb`s and `SHA256SUMS` attached) and
|
||||||
|
uploads the `.deb`s to the owner's Debian registry, distribution `stable`,
|
||||||
|
component `main` ([install.md](install.md#from-the-package-registry)). A
|
||||||
|
version with a hyphen (`1.0.0-rc.1`) becomes a pre-release; its packages
|
||||||
|
get version `1.0.0~rc.1`, which apt sorts before `1.0.0`.
|
||||||
|
|
||||||
|
Pushing the same tag again (`git tag -f`, `git push -f`) re-runs it, and
|
||||||
|
the script replaces the attachments and packages, so a failed release can
|
||||||
|
simply be retried.
|
||||||
|
|
||||||
|
Once, on Gitea:
|
||||||
|
|
||||||
|
* Actions on for the repository (Settings → Repository → Actions), and a
|
||||||
|
runner with the `ubuntu-latest` label: act_runner's default, which runs
|
||||||
|
jobs in `docker.gitea.com/runner-images:ubuntu-latest`. The job
|
||||||
|
downloads Go itself (`actions/setup-go`, from `go.mod`), so the runner
|
||||||
|
needs internet access, or a mirror of the actions and Go.
|
||||||
|
* A repository secret `RELEASE_TOKEN` (Settings → Actions → Secrets): an
|
||||||
|
access token (User settings → Applications) with the `write:repository`
|
||||||
|
and `write:package` scopes, from a user who can write to the repository.
|
||||||
|
The job's automatic token can't be relied on to publish packages.
|
||||||
|
|
||||||
|
`scripts/gitea-release.sh` also runs by hand after the same builds, with
|
||||||
|
`GITEA_URL`, `GITEA_REPO` (`owner/name`) and `GITEA_TOKEN` set; it needs
|
||||||
|
`curl`, `jq` and `dpkg-deb`.
|
||||||
+84
-12
@@ -12,6 +12,12 @@ to load Jarl's configuration the old one is put back automatically.
|
|||||||
|
|
||||||
## 1. Build
|
## 1. Build
|
||||||
|
|
||||||
|
Each release is already built: the Debian packages are in the Gitea
|
||||||
|
package registry ([below](#from-the-package-registry)), and the release
|
||||||
|
page (https://gitea.adbraun.lol/adam/jarl/releases) has the packages, the
|
||||||
|
linux tarballs, and the CLI for Linux, macOS and Windows. Build it yourself
|
||||||
|
for an unreleased version.
|
||||||
|
|
||||||
Jarl is two static binaries with no runtime dependencies (SQLite is
|
Jarl is two static binaries with no runtime dependencies (SQLite is
|
||||||
compiled in). Building needs Go 1.27 or newer, on any machine:
|
compiled in). Building needs Go 1.27 or newer, on any machine:
|
||||||
|
|
||||||
@@ -30,23 +36,62 @@ package (below) and copy that.
|
|||||||
There are two ways: a Debian package, which is easiest to upgrade and
|
There are two ways: a Debian package, which is easiest to upgrade and
|
||||||
remove, or `make install`.
|
remove, or `make install`.
|
||||||
|
|
||||||
### With the Debian package
|
### With the Debian packages
|
||||||
|
|
||||||
|
There are two packages:
|
||||||
|
|
||||||
|
| Package | Holds | Install it |
|
||||||
|
|---------|-------|-----------|
|
||||||
|
| `jarl` | the server: `jarld`, its systemd units, the docs | on the DNS server |
|
||||||
|
| `jarl-cli` | the `jarl` CLI, its bash completion, the ACME hooks | wherever you manage Jarl from; `jarl` depends on it |
|
||||||
|
|
||||||
|
#### From the package registry
|
||||||
|
|
||||||
|
Every release is published to Gitea's Debian registry (amd64 and arm64).
|
||||||
|
Add it to apt once, and apt then finds `jarl-cli` by itself and
|
||||||
|
`apt upgrade` brings new releases:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make deb # dist/jarl_0.1.0_amd64.deb
|
sudo install -d /etc/apt/keyrings
|
||||||
make deb DEB_ARCH=arm64 # for another architecture (also armhf, i386, ...)
|
sudo curl -fsSL https://gitea.adbraun.lol/api/packages/adam/debian/repository.key -o /etc/apt/keyrings/jarl.asc
|
||||||
sudo apt install ./dist/jarl_0.1.0_amd64.deb
|
echo "deb [signed-by=/etc/apt/keyrings/jarl.asc] https://gitea.adbraun.lol/api/packages/adam/debian stable main" \
|
||||||
|
| sudo tee /etc/apt/sources.list.d/jarl.list
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install jarl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The packages are as visible as the Gitea account that owns them, not the
|
||||||
|
repository: with a public account, apt needs no login even if the
|
||||||
|
repository is private. For a private or limited account, give apt a token
|
||||||
|
with the `read:package` scope in `/etc/apt/auth.conf.d/jarl.conf` (mode
|
||||||
|
0600):
|
||||||
|
|
||||||
|
```
|
||||||
|
machine gitea.adbraun.lol/api/packages/adam/debian
|
||||||
|
login adam
|
||||||
|
password <token>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### From files
|
||||||
|
|
||||||
|
Download the two `.deb` files from the release page, or build them:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make deb # dist/jarl_0.1.0_amd64.deb and dist/jarl-cli_0.1.0_amd64.deb
|
||||||
|
make deb DEB_ARCH=arm64 # for another architecture (also armhf, i386, ...)
|
||||||
|
sudo apt install ./dist/jarl_0.1.0_amd64.deb ./dist/jarl-cli_0.1.0_amd64.deb
|
||||||
|
```
|
||||||
|
|
||||||
|
Give apt both files: `jarl` needs `jarl-cli` of the same version.
|
||||||
`make deb` needs only `dpkg-deb` (no root, no debhelper) and cross-builds
|
`make deb` needs only `dpkg-deb` (no root, no debhelper) and cross-builds
|
||||||
for any architecture Go supports. apt also installs `bind9` (recommended)
|
for any architecture Go supports. apt also installs `bind9` (recommended)
|
||||||
if it's missing. Installing the package:
|
if it's missing. Installing the server package:
|
||||||
|
|
||||||
* puts the binaries in `/usr/bin`, bash completion in
|
* puts `jarld` in `/usr/bin`, its bash completion in
|
||||||
`/usr/share/bash-completion/completions`, the systemd units in
|
`/usr/share/bash-completion/completions`, the systemd units in
|
||||||
`/usr/lib/systemd/system` (`jarl.service`, and `jarl-backup.service`
|
`/usr/lib/systemd/system` (`jarl.service`, and `jarl-backup.service`
|
||||||
with its daily `jarl-backup.timer`), the sysusers and tmpfiles files
|
with its daily `jarl-backup.timer`), the sysusers and tmpfiles files
|
||||||
in `/usr/lib`, and the docs and contrib files in `/usr/share/doc/jarl`;
|
in `/usr/lib`, and the docs in `/usr/share/doc/jarl`;
|
||||||
* creates the `jarl` user (in group `bind`) and Jarl's directories, and
|
* creates the `jarl` user (in group `bind`) and Jarl's directories, and
|
||||||
writes `/etc/jarl/jarl.yaml` from the example on the first install. No
|
writes `/etc/jarl/jarl.yaml` from the example on the first install. No
|
||||||
file in `/etc` belongs to the package, so your configuration is never
|
file in `/etc` belongs to the package, so your configuration is never
|
||||||
@@ -58,17 +103,44 @@ if it's missing. Installing the package:
|
|||||||
* doesn't start jarld: continue with [3. Configure](#3-configure), then
|
* doesn't start jarld: continue with [3. Configure](#3-configure), then
|
||||||
`systemctl enable --now jarl` in step 8.
|
`systemctl enable --now jarl` in step 8.
|
||||||
|
|
||||||
**Upgrading**: build and install the newer package the same way. A running
|
`jarl-cli` installs `/usr/bin/jarl`, its completion, and
|
||||||
jarld is restarted, and upgrades its database as it starts.
|
`/usr/share/doc/jarl-cli` (the CLI, ACME and permissions docs, and the
|
||||||
|
acme.sh and lego hooks in `contrib/`).
|
||||||
|
|
||||||
|
**Upgrading**: `sudo apt update && sudo apt upgrade` with the registry, or
|
||||||
|
install the newer files the same way. A running
|
||||||
|
jarld is restarted, and upgrades its database as it starts. Up to 0.1.0
|
||||||
|
everything was one `jarl` package; installing the two new ones over it
|
||||||
|
moves `/usr/bin/jarl` to `jarl-cli` by itself.
|
||||||
|
|
||||||
**Removing** (`sudo apt remove jarl`) stops jarld and the backup timer and
|
**Removing** (`sudo apt remove jarl`) stops jarld and the backup timer and
|
||||||
removes the program, but named keeps running with the configuration Jarl
|
removes the server (the CLI stays until you remove `jarl-cli` too), but named keeps running with the configuration Jarl
|
||||||
last wrote. Even `apt purge jarl` keeps `/etc/jarl`, `/var/lib/jarl` (the
|
last wrote. Even `apt purge jarl` keeps `/etc/jarl`, `/var/lib/jarl` (the
|
||||||
database), `/var/backups/jarl` and the
|
database), `/var/backups/jarl` and the
|
||||||
files in `/etc/bind/jarl`, `/var/lib/bind/jarl` and `/var/cache/bind/jarl`,
|
files in `/etc/bind/jarl`, `/var/lib/bind/jarl` and `/var/cache/bind/jarl`,
|
||||||
since named.conf may still include them. Remove them by hand once named no
|
since named.conf may still include them. Remove them by hand once named no
|
||||||
longer uses them.
|
longer uses them.
|
||||||
|
|
||||||
|
### Just the CLI, on another machine
|
||||||
|
|
||||||
|
To manage Jarl servers from your laptop or another server, install only
|
||||||
|
`jarl-cli`. It needs nothing else and changes nothing on the machine (no
|
||||||
|
users, services or directories):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt install jarl-cli # with the registry above; or: sudo apt install ./jarl-cli_0.1.0_amd64.deb
|
||||||
|
jarl config set server https://ns1.adbraun.lol:8053
|
||||||
|
jarl config set token
|
||||||
|
```
|
||||||
|
|
||||||
|
Elsewhere, download the CLI from the release page:
|
||||||
|
`jarl-cli-<version>-<os>-<arch>` for Linux, macOS (`darwin`) and Windows
|
||||||
|
(`.exe`), with their checksums in `SHA256SUMS`. It is one static file; put
|
||||||
|
it in your PATH as `jarl` (on macOS, `xattr -d com.apple.quarantine jarl`
|
||||||
|
lets an unsigned download run). `make cli-dist` builds the same files, and
|
||||||
|
`make` builds it for this machine in `bin/`. [cli.md](cli.md)
|
||||||
|
explains the setup, and several servers in one configuration.
|
||||||
|
|
||||||
### With make install
|
### With make install
|
||||||
|
|
||||||
On the DNS server, as root:
|
On the DNS server, as root:
|
||||||
@@ -297,8 +369,8 @@ without dropping connections. More in [acme.md](acme.md).
|
|||||||
## Upgrading
|
## Upgrading
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make && sudo make install
|
sudo apt update && sudo apt upgrade # Debian packages from the registry
|
||||||
sudo systemctl restart jarl
|
make && sudo make install && sudo systemctl restart jarl # make install
|
||||||
```
|
```
|
||||||
|
|
||||||
Database migrations run automatically at startup. Before an upgrade, take
|
Database migrations run automatically at startup. Before an upgrade, take
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
| Restart / reload TLS | `systemctl restart jarl` / `systemctl reload jarl` |
|
| Restart / reload TLS | `systemctl restart jarl` / `systemctl reload jarl` |
|
||||||
| Work on the server itself | `sudo jarl ...`: root uses jarld's local socket and needs no token ([cli.md](cli.md#on-the-server-itself)) |
|
| Work on the server itself | `sudo jarl ...`: root uses jarld's local socket and needs no token ([cli.md](cli.md#on-the-server-itself)) |
|
||||||
| Renew or replace a token | `jarl token rotate NAME --grace 1h` (same grants, new secret; [permissions.md](permissions.md#rotating-a-token)). `jarl token list --all --expiring` shows those that expire within 14 days |
|
| Renew or replace a token | `jarl token rotate NAME --grace 1h` (same grants, new secret; [permissions.md](permissions.md#rotating-a-token)). `jarl token list --all --expiring` shows those that expire within 14 days |
|
||||||
| Upgrade Jarl | Debian package: build the new one and `sudo apt install ./dist/jarl_*.deb`; otherwise `make && sudo make install && sudo systemctl restart jarl`. jarld upgrades its database when it starts |
|
| Upgrade Jarl | Debian packages: build the new ones and `sudo apt install ./dist/jarl*_amd64.deb` (server and CLI); otherwise `make && sudo make install && sudo systemctl restart jarl`. jarld upgrades its database when it starts |
|
||||||
|
|
||||||
Restarting jarld doesn't affect DNS: named keeps serving the files it
|
Restarting jarld doesn't affect DNS: named keeps serving the files it
|
||||||
loaded. jarld is only needed to make changes.
|
loaded. jarld is only needed to make changes.
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
//go:build !unix
|
||||||
|
|
||||||
|
package stats
|
||||||
|
|
||||||
|
import "io/fs"
|
||||||
|
|
||||||
|
// inode is 0 where there are no inodes (the CLI uses this package on
|
||||||
|
// Windows for its types; only jarld tails logs).
|
||||||
|
func inode(fs.FileInfo) uint64 { return 0 }
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//go:build unix
|
||||||
|
|
||||||
|
package stats
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/fs"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func inode(fi fs.FileInfo) uint64 {
|
||||||
|
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
|
||||||
|
return st.Ino
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tailer follows a log file that named rotates (renaming it to FILE.0,
|
// Tailer follows a log file that named rotates (renaming it to FILE.0,
|
||||||
@@ -30,13 +29,6 @@ type Position struct {
|
|||||||
Offset int64 `json:"offset"`
|
Offset int64 `json:"offset"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func inode(fi fs.FileInfo) uint64 {
|
|
||||||
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
|
|
||||||
return st.Ino
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Position returns the current position (of complete lines).
|
// Position returns the current position (of complete lines).
|
||||||
func (t *Tailer) Position() Position {
|
func (t *Tailer) Position() Position {
|
||||||
return Position{Inode: t.ino, Offset: t.offset - int64(len(t.partial))}
|
return Position{Inode: t.ino, Offset: t.offset - int64(len(t.partial))}
|
||||||
|
|||||||
Executable
+103
@@ -0,0 +1,103 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Publishes a built release (make dist, make cli-dist, make deb for each
|
||||||
|
# architecture) to Gitea:
|
||||||
|
#
|
||||||
|
# * a release for tag v<VERSION> with the CHANGELOG section for VERSION as
|
||||||
|
# its notes, and every file in dist/ (tarballs, CLI binaries, .debs)
|
||||||
|
# plus a SHA256SUMS of them attached;
|
||||||
|
# * the .debs in the owner's Debian package registry, so servers can
|
||||||
|
# 'apt install jarl' and get updates with apt (docs/install.md).
|
||||||
|
#
|
||||||
|
# Run by .gitea/workflows/release.yml when a v* tag is pushed. Running it
|
||||||
|
# again for the same version replaces the attachments and packages.
|
||||||
|
#
|
||||||
|
# Variables:
|
||||||
|
# GITEA_URL e.g. https://gitea.example.com (in Actions:
|
||||||
|
# GITHUB_SERVER_URL)
|
||||||
|
# GITEA_REPO owner/name (in Actions: GITHUB_REPOSITORY)
|
||||||
|
# GITEA_TOKEN a token with write:repository and write:package
|
||||||
|
# VERSION default: the VERSION file
|
||||||
|
# DEB_DISTRIBUTION the apt distribution (default: stable)
|
||||||
|
# DEB_COMPONENT the apt component (default: main)
|
||||||
|
#
|
||||||
|
# Needs curl and jq.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
: "${GITEA_URL:=${GITHUB_SERVER_URL:-}}" "${GITEA_REPO:=${GITHUB_REPOSITORY:-}}"
|
||||||
|
: "${GITEA_URL:?set GITEA_URL}" "${GITEA_REPO:?set GITEA_REPO}" "${GITEA_TOKEN:?set GITEA_TOKEN}"
|
||||||
|
VERSION=${VERSION:-$(cat VERSION)}
|
||||||
|
DEB_DISTRIBUTION=${DEB_DISTRIBUTION:-stable}
|
||||||
|
DEB_COMPONENT=${DEB_COMPONENT:-main}
|
||||||
|
GITEA_URL=${GITEA_URL%/}
|
||||||
|
owner=${GITEA_REPO%%/*}
|
||||||
|
tag=v$VERSION
|
||||||
|
api=$GITEA_URL/api/v1/repos/$GITEA_REPO
|
||||||
|
|
||||||
|
# curl with the token; fails on HTTP errors except the codes in $ok.
|
||||||
|
call() {
|
||||||
|
ok=$1
|
||||||
|
shift
|
||||||
|
out=$(mktemp)
|
||||||
|
code=$(curl -sS -o "$out" -w '%{http_code}' -H "Authorization: token $GITEA_TOKEN" "$@")
|
||||||
|
case " 200 201 204 $ok " in
|
||||||
|
*" $code "*) cat "$out"; rm -f "$out"; return 0 ;;
|
||||||
|
esac
|
||||||
|
echo "gitea-release: HTTP $code from $*" >&2
|
||||||
|
cat "$out" >&2
|
||||||
|
echo >&2
|
||||||
|
rm -f "$out"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
files=$(find dist -maxdepth 1 -type f ! -name SHA256SUMS | sort)
|
||||||
|
[ -n "$files" ] || { echo "gitea-release: nothing in dist/" >&2; exit 1; }
|
||||||
|
for f in $files; do
|
||||||
|
case $f in *"$VERSION"*) ;; *) echo "gitea-release: $f is not version $VERSION" >&2; exit 1 ;; esac
|
||||||
|
done
|
||||||
|
# shellcheck disable=SC2046 # file names have no spaces
|
||||||
|
(cd dist && sha256sum $(printf '%s\n' "$files" | sed 's|^dist/||')) > dist/SHA256SUMS
|
||||||
|
files="$files dist/SHA256SUMS"
|
||||||
|
|
||||||
|
# The release notes: the CHANGELOG section for this version.
|
||||||
|
notes=$(awk -v v="$VERSION" '
|
||||||
|
/^## \[/ { if (on) exit; on = index($0, "## [" v "]") == 1; next }
|
||||||
|
on' CHANGELOG.md)
|
||||||
|
[ -n "$notes" ] || notes="See CHANGELOG.md."
|
||||||
|
prerelease=false
|
||||||
|
case $VERSION in *-*) prerelease=true ;; esac
|
||||||
|
|
||||||
|
# The release (created, or found when publishing again).
|
||||||
|
release=$(call 404 "$api/releases/tags/$tag")
|
||||||
|
id=$(printf '%s\n' "$release" | jq -r '.id // empty')
|
||||||
|
if [ -z "$id" ]; then
|
||||||
|
body=$(jq -n --arg tag "$tag" --arg notes "$notes" --argjson pre "$prerelease" \
|
||||||
|
'{tag_name: $tag, name: ("Jarl " + $tag), body: $notes, prerelease: $pre}')
|
||||||
|
release=$(call "" -X POST -H 'Content-Type: application/json' -d "$body" "$api/releases")
|
||||||
|
id=$(printf '%s\n' "$release" | jq -r .id)
|
||||||
|
echo "gitea-release: created release $tag"
|
||||||
|
fi
|
||||||
|
for f in $files; do
|
||||||
|
name=${f#dist/}
|
||||||
|
old=$(printf '%s\n' "$release" | jq -r --arg n "$name" '.assets[]? | select(.name == $n) | .id')
|
||||||
|
[ -z "$old" ] || call "" -X DELETE "$api/releases/$id/assets/$old" >/dev/null
|
||||||
|
call "" -X POST -F "attachment=@$f" "$api/releases/$id/assets?name=$name" >/dev/null
|
||||||
|
echo "gitea-release: attached $name"
|
||||||
|
done
|
||||||
|
|
||||||
|
# The Debian packages. Gitea refuses a package version it already has
|
||||||
|
# (409), so publishing again deletes it first.
|
||||||
|
pool=$GITEA_URL/api/packages/$owner/debian/pool/$DEB_DISTRIBUTION/$DEB_COMPONENT
|
||||||
|
for f in dist/*.deb; do
|
||||||
|
[ -e "$f" ] || continue
|
||||||
|
# shellcheck disable=SC2016,SC2046 # dpkg-deb's fields; split into "$@"
|
||||||
|
set -- $(dpkg-deb --showformat '${Package} ${Version} ${Architecture}' --show "$f")
|
||||||
|
if ! call 409 --upload-file "$f" "$pool/upload" >/dev/null; then
|
||||||
|
echo "gitea-release: upload of $f failed" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$code" = 409 ]; then
|
||||||
|
call "" -X DELETE "$pool/$1/$2/$3" >/dev/null
|
||||||
|
call "" --upload-file "$f" "$pool/upload" >/dev/null
|
||||||
|
fi
|
||||||
|
echo "gitea-release: uploaded $1 $2 $3 to $DEB_DISTRIBUTION/$DEB_COMPONENT"
|
||||||
|
done
|
||||||
+59
-29
@@ -1,18 +1,28 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Builds a Debian package of Jarl: dist/jarl_<version>_<arch>.deb.
|
# Builds Jarl's two Debian packages:
|
||||||
# Run through 'make deb' (which sets the variables below); needs only
|
|
||||||
# dpkg-deb, no root and no debhelper.
|
|
||||||
#
|
#
|
||||||
# The package installs, with Debian's paths:
|
# dist/jarl-cli_<version>_<arch>.deb the CLI, to install anywhere:
|
||||||
# /usr/bin/jarld, /usr/bin/jarl
|
# /usr/bin/jarl, its bash completion, and /usr/share/doc/jarl-cli/
|
||||||
# /usr/share/bash-completion/completions/{jarl,jarld}
|
# (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_<version>_<arch>.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/systemd/system/{jarl.service,jarl-backup.service,jarl-backup.timer}
|
||||||
# /usr/lib/sysusers.d/jarl.conf, /usr/lib/tmpfiles.d/jarl.conf
|
# /usr/lib/sysusers.d/jarl.conf, /usr/lib/tmpfiles.d/jarl.conf
|
||||||
# /usr/share/doc/jarl/ (README, CHANGELOG, docs, contrib)
|
# /usr/share/doc/jarl/ (README, CHANGELOG, docs)
|
||||||
# and its scripts (deploy/debian) create the jarl user and directories and
|
# 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,
|
# /etc/jarl/jarl.yaml on the first install, turn on the daily backup
|
||||||
# restart a running jarld on upgrades, and stop both on removal. No file in /etc belongs to the package,
|
# timer, restart a running jarld on upgrades, and stop both on removal.
|
||||||
# so an upgrade never asks about configuration files.
|
# 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),
|
# Variables: DEB_ARCH (Debian architecture, e.g. amd64, arm64, armhf),
|
||||||
# DEB_VERSION, VERSION, LDFLAGS, GOFLAGS, and DEB_MAINTAINER (default: your
|
# DEB_VERSION, VERSION, LDFLAGS, GOFLAGS, and DEB_MAINTAINER (default: your
|
||||||
@@ -41,26 +51,42 @@ if [ -z "${DEB_MAINTAINER:-}" ]; then
|
|||||||
DEB_MAINTAINER="${name:-Jarl packager} <${email:-root@localhost}>"
|
DEB_MAINTAINER="${name:-Jarl packager} <${email:-root@localhost}>"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
work=dist/deb/jarl_${DEB_VERSION}_${DEB_ARCH}
|
work=dist/deb/${DEB_VERSION}_${DEB_ARCH}
|
||||||
root=$work/root
|
stage=$work/stage
|
||||||
out=dist/jarl_${DEB_VERSION}_${DEB_ARCH}.deb
|
|
||||||
rm -rf "$work"
|
rm -rf "$work"
|
||||||
mkdir -p "$root/DEBIAN"
|
mkdir -p "$stage"
|
||||||
|
|
||||||
# Binaries for the package's architecture (bin/ holds the host's, which
|
# Binaries for the package's architecture (bin/ holds the host's, which
|
||||||
# also generated the completion scripts).
|
# also generated the completion scripts).
|
||||||
echo "mkdeb: building for linux/$goarch"
|
echo "mkdeb: building for linux/$goarch"
|
||||||
# go reads GOFLAGS (-trimpath) from the environment.
|
# go reads GOFLAGS (-trimpath) from the environment.
|
||||||
export GOFLAGS
|
export GOFLAGS
|
||||||
GOOS=linux GOARCH=$goarch GOARM=$goarm CGO_ENABLED=0 go build -ldflags "$LDFLAGS" -o "$work/jarld" ./cmd/jarld
|
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/jarl" ./cmd/jarl
|
GOOS=linux GOARCH=$goarch GOARM=$goarm CGO_ENABLED=0 go build -ldflags "$LDFLAGS" -o "$work/bin/jarl" ./cmd/jarl
|
||||||
|
|
||||||
make --no-print-directory install-files DESTDIR="$root" PREFIX=/usr \
|
# Everything 'make install' would install, then split in two.
|
||||||
UNITDIR=/usr/lib/systemd/system JARLD_BIN="$work/jarld" JARL_BIN="$work/jarl" >/dev/null
|
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.
|
# Debian's machine-readable copyright file, from LICENSE.
|
||||||
indent() { sed -e 's/^$/./' -e 's/^/ /' "$1"; }
|
indent() { sed -e 's/^$/./' -e 's/^/ /' "$1"; }
|
||||||
{
|
copyright() {
|
||||||
echo "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/"
|
echo "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/"
|
||||||
echo "Upstream-Name: jarl"
|
echo "Upstream-Name: jarl"
|
||||||
echo
|
echo
|
||||||
@@ -68,22 +94,26 @@ indent() { sed -e 's/^$/./' -e 's/^/ /' "$1"; }
|
|||||||
echo "Copyright: $(sed -n 's/^Copyright (c) //p' LICENSE)"
|
echo "Copyright: $(sed -n 's/^Copyright (c) //p' LICENSE)"
|
||||||
echo "License: Expat"
|
echo "License: Expat"
|
||||||
indent LICENSE
|
indent LICENSE
|
||||||
} > "$root/usr/share/doc/jarl/copyright"
|
}
|
||||||
|
|
||||||
for f in postinst prerm postrm; do
|
# build PACKAGE ROOT: writes the control file and md5sums and builds the .deb.
|
||||||
install -m 0755 "deploy/debian/$f" "$root/DEBIAN/$f"
|
build() {
|
||||||
done
|
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.
|
# Directories 0755 and no group/other write, whatever the build's umask.
|
||||||
find "$root" -type d -exec chmod 0755 {} +
|
find "$root" -type d -exec chmod 0755 {} +
|
||||||
chmod -R go-w "$root"
|
chmod -R go-w "$root"
|
||||||
size=$(du -sk --exclude=DEBIAN "$root" | cut -f1)
|
size=$(du -sk --exclude=DEBIAN "$root" | cut -f1)
|
||||||
sed -e "s/@VERSION@/$DEB_VERSION/" -e "s/@ARCH@/$DEB_ARCH/" -e "s/@SIZE@/$size/" \
|
sed -e "s/@VERSION@/$DEB_VERSION/g" -e "s/@ARCH@/$DEB_ARCH/" -e "s/@SIZE@/$size/" \
|
||||||
-e "s|@MAINTAINER@|$DEB_MAINTAINER|" deploy/debian/control.in > "$root/DEBIAN/control"
|
-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"
|
(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"
|
chmod 0644 "$root/DEBIAN/control" "$root/DEBIAN/md5sums"
|
||||||
|
|
||||||
# Files belong to root in the package, whoever builds it.
|
# Files belong to root in the package, whoever builds it.
|
||||||
dpkg-deb --root-owner-group -Zxz --build "$root" "$out" >/dev/null
|
dpkg-deb --root-owner-group -Zxz --build "$root" "$out" >/dev/null
|
||||||
rm -rf dist/deb
|
|
||||||
echo "mkdeb: wrote $out"
|
echo "mkdeb: wrote $out"
|
||||||
dpkg-deb --info "$out" | sed -n 's/^ \(Package\|Version\|Architecture\|Installed-Size\):/ \1:/p'
|
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
|
||||||
Reference in new issue
Block a user