Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Check the deployment files before a user's first boot

dbae2e01bcec3167e007123a211c8cdd5f356487 · Keenan Nemetz · 3d ago · parent b8e7a567

Check the deployment files before a user's first boot

The files a new instance is built from are the ones nobody runs before a
user does. A stray placeholder, a boot script with a syntax error, or a
compose file naming a path that is not there all fail minutes after someone
paid for a machine.

check-deploy.py parses every YAML under deploy/, renders the template with
the placeholder list render.sh uses (so the two cannot drift), checks the
rendered document has the files it promises, and runs `sh -n` on the boot
script and the container entrypoint. Terraform is formatted with
`terraform fmt -check`, from a version pinned by checksum for both
architectures a runner can be, beside nfpm and govulncheck.

The link checker also skips .terraform, which every operator will create in
place, and the ignore file keeps Terraform's working directory out of Git
while keeping its lock files in.

.vole/images/verify.yaml +12−4

@@ -1,7 +1,8 @@
1 1 # The image .vole/workflows/verify.yaml runs in. It carries everything the steps call: the Go toolchain
2 2 # (with gcc, so -race works), the SQLite development headers the driver links
3 # against, git and the ssh client and keygen the server tests spawn, and python3
4 # for the link check.
3 # against, git and the ssh client and keygen the server tests spawn, python3 for
4 # the link check, PyYAML for the deployment check, and Terraform for the
5 # configurations under deploy/terraform.
5 6 #
6 7 # The toolchain is the one go.mod pins (go 1.27.3), and the base image is pinned
7 8 # by digest so the scanner and the compiler that pass a push are the ones the
@@ -16,7 +17,10 @@
16 17 # --container-user.
17 18
18 19 # nfpm is not installed here: the packaging step fetches it at a pinned version, so
19 # that a local run and a pushed run execute the same command.
20 # that a local run and a pushed run execute the same command. Terraform is
21 # installed here rather than fetched by each step, because it is a single binary
22 # that the deployment check runs three times; its version and both architectures'
23 # checksums are below, so a pushed run and a local one format with the same tool.
20 24 version: 1
21 25 from: golang:1.27.3-bookworm@sha256:972b4110ba0f47539a975c31e52c64765e1ff19f2d74469ae4a595c6676e80a5
22 26 env:
@@ -29,5 +33,9 @@ env:
29 33 GOMODCACHE: "/cache/go-mod"
30 34 GOCACHE: "/cache/go-build"
31 35 run:
32 - apt-get update && apt-get install -y --no-install-recommends libsqlite3-dev git git-lfs openssh-client python3 ca-certificates && rm -rf /var/lib/apt/lists/*
36 - apt-get update && apt-get install -y --no-install-recommends libsqlite3-dev git git-lfs openssh-client python3 python3-yaml gettext-base ca-certificates curl unzip && rm -rf /var/lib/apt/lists/*
37 # Terraform, pinned by version and by checksum for each architecture a runner can
38 # be. It is used by `terraform fmt -check` in the deployment step; `terraform
39 # validate` is left to people, because it downloads three providers.
40 - set -eu; ver=1.17.1; case "$(dpkg --print-architecture)" in amd64) sum=4638628058e71a55212b1c563712eac03b902128f40740f3dc8174df12135061 ;; arm64) sum=988e950a1c23058093b0e66ab2d5fb53fc18345ecfbd5871acf51dbac9325edd ;; *) echo "no pinned Terraform for $(dpkg --print-architecture)" >&2; exit 1 ;; esac; curl -fsSLo /tmp/tf.zip "https://releases.hashicorp.com/terraform/$ver/terraform_${ver}_linux_$(dpkg --print-architecture).zip"; echo "$sum /tmp/tf.zip" | sha256sum -c -; unzip -q /tmp/tf.zip -d /usr/local/bin; rm -f /tmp/tf.zip; terraform version
33 41 - useradd --uid 1000 --create-home --shell /bin/sh ci