From 5b8d663c2b9aa20dff05c1f3f885e72fc9dad8b2 Mon Sep 17 00:00:00 2001 From: dubo-dubon-duponey Date: Thu, 14 Mar 2024 21:18:49 -0700 Subject: [PATCH] Spring cleanup --- .github/workflows/CI.yml | 6 +- DEVELOP.md | 8 +- Dockerfile | 6 +- README.md | 19 +-- context/runtime/boot/entrypoint.sh | 4 +- context/runtime/boot/mdns.sh | 111 ++++++++++++++++++ context/runtime/config/snips/monitor.conf | 2 +- .../buildkit/buildctl/buildctl.cue | 2 +- cue.mod/pkg/duponey.cloud/scullery/icing.cue | 2 +- hack/build.sh | 6 +- hack/{ => helpers}/cue_tool.cue | 0 hack/helpers/install-tools.sh | 8 +- hack/helpers/start-buildkit.sh | 13 +- hack/lint.sh | 7 +- hack/recipe.cue | 6 +- hack/test.sh | 6 +- 16 files changed, 157 insertions(+), 49 deletions(-) create mode 100755 context/runtime/boot/mdns.sh rename hack/{ => helpers}/cue_tool.cue (100%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 31f466c..c069344 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,12 +10,12 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: - name: Checks-out repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: true - name: Enable cache - uses: actions/cache@v2.1.1 + uses: actions/cache@v4 with: path: $GITHUB_WORKSPACE/cache key: cache @@ -50,7 +50,7 @@ jobs: - name: test run: | # Set the path and install the tools - export PATH="$GITHUB_WORKSPACE/cache/bin:$PATH" + export PATH="$HOME/bin:$PATH" ./hack/helpers/install-tools.sh # Start buildkit bkaddr="$(./hack/helpers/start-buildkit.sh 2>/dev/null)" diff --git a/DEVELOP.md b/DEVELOP.md index 73dfe5a..46931a8 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -10,18 +10,18 @@ ### The what -This image is built using: `docker.io/dubodubonduponey/base:builder-bullseye-2022-12-01` +This image is built using: `docker.io/dubodubonduponey/base:builder-bookworm-2024-02-20` -The runtime part is based on: `docker.io/dubodubonduponey/base:runtime-bullseye-2022-12-01` +The runtime part is based on: `docker.io/dubodubonduponey/base:runtime-bookworm-2024-02-20` -Both these images are built upon: `docker.io/dubodubonduponey/debian:bullseye-2022-12-01` +Both these images are built upon: `docker.io/dubodubonduponey/debian:bookworm-2024-02-20` You can find out more here: * https://github.com/dubo-dubon-duponey/docker-debian for the debootstrapped Debian base * https://github.com/dubo-dubon-duponey/docker-base for the builder and runtime images -These images provide very little - they are (mostly) barebone bullseye with some ONBUILD +These images provide very little - they are (mostly) barebone bookworm with some ONBUILD Docker syntactic sugar (metadata, user creation, entrypoint). Let me repeat: you have very little reason to go and add anything up there. diff --git a/Dockerfile b/Dockerfile index aa5d54f..e247281 100644 --- a/Dockerfile +++ b/Dockerfile @@ -202,7 +202,9 @@ ENV DNS_PORT=53 # ENV DNS_OVER_GRPC_PORT=553 ENV DNS_STUFF_MDNS=false -ENV METRICS_LISTEN=:9253 +# XXX cannot be disabled through this variable +ENV MOD_METRICS_ENABLED=true +ENV MOD_METRICS_BIND=:4242 # NOTE: this will not be updated at runtime and will always EXPOSE default values # Either way, EXPOSE does not do anything, except function as a documentation helper @@ -210,7 +212,7 @@ EXPOSE $DNS_PORT/udp EXPOSE $DNS_OVER_TLS_PORT/tcp EXPOSE $DNS_OVER_TLS_LEGO_PORT/tcp #EXPOSE $DNS_OVER_GRPC_PORT/tcp -EXPOSE $METRICS_LISTEN/tcp +EXPOSE $MOD_METRICS_BIND/tcp # Lego just needs /certs to work VOLUME /certs diff --git a/README.md b/README.md index 67a431a..7963ead 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This is based on [CoreDNS](https://coredns.io/), and [Let's Encrypt](https://let This is useful in the following scenarios: 1. you want to run a *local* DNS server on your LAN (or your laptop) that will forward requests with encryption to an upstream resolver - ( like Cloudflare, Quad9, Google, or any other DoT public resolver) + (like Cloudflare, Quad9, Google, or any other DoT public resolver) 1. you want to run your own DNS over TLS (recursive) service 1. other stuff @@ -19,21 +19,14 @@ Before running this publicly on the internet, you should think twice though, and * [x] linux/amd64 * [x] linux/arm64 -* multi-architecture (not publishing anymore) - * [x] linux/386 - * [x] linux/arm/v7 - * [x] linux/arm/v6 - * [x] linux/ppc64le - * [x] linux/s390x -* * hardened: * [x] image runs read-only - * [x] image runs with no capabilities but NET_BIND_SERVICE, which you could remove if you use unprivileged ports + * [x] image runs with no capabilities (you need NET_BIND_SERVICE if you want to use privileged ports obviously) * [x] process runs as a non-root user, disabled login, no shell * lightweight - * [x] based on our slim [Debian Bullseye](https://github.com/dubo-dubon-duponey/docker-debian) + * [x] based on our slim [Debian Bookworm](https://github.com/dubo-dubon-duponey/docker-debian) * [x] simple entrypoint script - * [x] multi-stage build with no installed dependencies for the runtime image + * [x] multi-stage build with zero packages installed in the runtime image * observable * [x] healthcheck * [x] log to stdout @@ -175,7 +168,7 @@ You can also tweak the following: * DNS_OVER_GRPC_PORT (default to 553) --> * DNS_STUFF_MDNS: convenient little trick to respond for certain mDNS queries over traditional DNS - * METRICS_LISTEN for Prometheus (default to :9253) + * MOD_METRICS_BIND for Prometheus (default to :4242) Of course using any privileged port for these requires CAP_NET_BIND_SERVICE. @@ -183,7 +176,7 @@ Finally, any additional arguments provided when running the image will get fed t ### Prometheus -The default configuration files expose a Prometheus metrics endpoint on port 9253. +The default configuration files expose a Prometheus metrics endpoint on port 4242. ## Moar? diff --git a/context/runtime/boot/entrypoint.sh b/context/runtime/boot/entrypoint.sh index 44a661e..5204fc0 100755 --- a/context/runtime/boot/entrypoint.sh +++ b/context/runtime/boot/entrypoint.sh @@ -4,7 +4,7 @@ set -o errexit -o errtrace -o functrace -o nounset -o pipefail root="$(cd "$(dirname "${BASH_SOURCE[0]:-$PWD}")" 2>/dev/null 1>&2 && pwd)" readonly root # shellcheck source=/dev/null -source "$root/helpers.sh" +. "$root/helpers.sh" helpers::dir::writable /certs @@ -30,7 +30,7 @@ DNS_PORT="${DNS_PORT:-}" DNS_STUFF_MDNS="${DNS_STUFF_MDNS:-}" # Metrics settings -METRICS_LISTEN="${METRICS_LISTEN:-}" +MOD_METRICS_BIND="${MOD_METRICS_BIND:-}" certs::renew(){ local domain="$1" diff --git a/context/runtime/boot/mdns.sh b/context/runtime/boot/mdns.sh new file mode 100755 index 0000000..e8d739e --- /dev/null +++ b/context/runtime/boot/mdns.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +set -o errexit -o errtrace -o functrace -o nounset -o pipefail + +readonly _default_mod_mdns_configuration_path="$XDG_CONFIG_DIRS/goello/main.json" +_internal_mod_mdns_records=() + +mdns::records::add(){ + local type="$1" + local host="$2" + local name="${3:-$host}" + local port="${4:-9}" + local text="${5:-[\"\"]}" # XXX Goello bug - if [] the announce is not visible + _internal_mod_mdns_records+=("$(printf '{"Type": "%s", "Host": "%s", "Name": "%s", "Port": %s, "Text": %s}' "$type" "$host" "$name" "$port" "$text")") +} + +mdns::records::load(){ + local file="$1" + local records="" + while read line -r; do + records+="$line" + done < "$file" + records="${records%]*}" + records="${records#*[}" + _internal_mod_mdns_records+=("$records") +} + +mdns::records::resolve(){ + local name="$1" + local type="$2" + local server + local port + server="$(goello-client -t "$type" -n "$name")" + port="$(printf "%s" "$server" | jq -rc .Port)" + server="$(printf "%s" "$server" | jq -rc .IPs[])" + printf "%s %s" "$server" "$port" +} + +mdns::start::broadcaster(){ + [ ! -e "$_default_mod_mdns_configuration_path" ] || mdns::records::load "$_default_mod_mdns_configuration_path" + local IFS="," + goello-server-ng -json "[${_internal_mod_mdns_records[*]}]" & +} + +mdns::start::avahi(){ + # Current issues with Avahi: + # - no way to change /run/avahi-daemon to another location - symlink works though + # - daemonization writing to syslog is a problem + # - avahi insists that /run/avahi-daemon must belong to avahi:avahi + # which is absolutely ridiculous - https://github.com/lathiat/avahi/blob/778fadb71cb923eee74f3f1967db88b8c2586830/avahi-daemon/main.c#L1434 + # Some variant of it: https://github.com/lathiat/avahi/issues/349 + # - project is half-dead: https://github.com/lathiat/avahi/issues/388 + + local args=() + # local avahisocket="$XDG_STATE_HOME/avahi-daemon/socket" + # XXX giving up on trying to be fancy with avahi + local avahisocket="/run/avahi-daemon/socket" + + # Make sure we can write it + helpers::dir::writable "$(dirname "$avahisocket")" true + + # Cleanup leftovers on container restart + rm -f "$(dirname "$avahisocket")/pid" + + [ "$(printf "%s" "$LOG_LEVEL" | tr '[:upper:]' '[:lower:]')" != "debug" ] || args+=(--debug) + + # -D/--daemonize implies -s/--syslog that we do not want, so, just background it + avahi-daemon -f /config/avahi/main.conf --no-drop-root --no-chroot "${args[@]}" & + + local tries=1 + # Wait until the socket is there + until [ -e "$avahisocket" ]; do + sleep 1s + tries=$(( tries + 1)) + [ $tries -lt 10 ] || { + printf >&2 "Failed starting avahi in a reasonable time. Something is quite wrong\n" + return 1 + } + done +} + +mdns::start::dbus(){ + # https://linux.die.net/man/1/dbus-daemon-1 + # https://man7.org/linux/man-pages/man3/sd_bus_default.3.html + # https://specifications.freedesktop.org/basedir-spec/latest/ar01s03.html + + # $XDG_STATE_HOME=/tmp/state + # Configuration file also has that ^ hardcoded, so, cannot use the variable... + + local dbussocket=/tmp/state/dbus/system_bus_socket + + # Ensure directory exists + helpers::dir::writable "$(dirname "$dbussocket")" create + + # Point it there for other systems + export DBUS_SYSTEM_BUS_ADDRESS=unix:path="$dbussocket" + export DBUS_SESSION_BUS_ADDRESS=unix:path="$dbussocket" + + # Start it, without a PID file + dbus-daemon --nopidfile --config-file /config/dbus/main.conf + + local tries=1 + # Wait until the socket is there + until [ -e "$dbussocket" ]; do + sleep 1s + tries=$(( tries + 1)) + [ $tries -lt 10 ] || { + printf >&2 "Failed starting dbus in a reasonable time. Something is quite wrong\n" + return 1 + } + done +} diff --git a/context/runtime/config/snips/monitor.conf b/context/runtime/config/snips/monitor.conf index 672b1f9..cb7ccd3 100644 --- a/context/runtime/config/snips/monitor.conf +++ b/context/runtime/config/snips/monitor.conf @@ -3,7 +3,7 @@ health localhost:8091 # https://coredns.io/plugins/pprof/ pprof localhost:6053 # https://coredns.io/plugins/metrics/ -prometheus {$METRICS_LISTEN} +prometheus {$MOD_METRICS_BIND} # https://coredns.io/plugins/log/ log # {combined} diff --git a/cue.mod/pkg/duponey.cloud/buildkit/buildctl/buildctl.cue b/cue.mod/pkg/duponey.cloud/buildkit/buildctl/buildctl.cue index 7a74ef0..e91385a 100644 --- a/cue.mod/pkg/duponey.cloud/buildkit/buildctl/buildctl.cue +++ b/cue.mod/pkg/duponey.cloud/buildkit/buildctl/buildctl.cue @@ -72,7 +72,7 @@ import ( ["--local", "dockerfile=\(dockerfile)"] + ["--frontend", frontend] + - ["--trace", "buildctl.trace.json"] + + ["--trace", "cache/buildctl.trace.json"] + ["--opt", "filename=\(filename)"] + ["--local", "context=\(context)"] + diff --git a/cue.mod/pkg/duponey.cloud/scullery/icing.cue b/cue.mod/pkg/duponey.cloud/scullery/icing.cue index 6fbfcb2..fe17b30 100644 --- a/cue.mod/pkg/duponey.cloud/scullery/icing.cue +++ b/cue.mod/pkg/duponey.cloud/scullery/icing.cue @@ -64,7 +64,7 @@ import ( #Icing: { // XXX make this type more specific buildkit?: { - address?: string | * "docker-container://buildkitd" + address?: string | * "docker-container://dbdbdp-buildkit" name?: string ca?: types.#Path cert?: types.#Path diff --git a/hack/build.sh b/hack/build.sh index 26f7246..0133f44 100755 --- a/hack/build.sh +++ b/hack/build.sh @@ -6,7 +6,9 @@ root="$(cd "$(dirname "${BASH_SOURCE[0]:-$PWD}")" 2>/dev/null 1>&2 && pwd)/../" readonly root # shellcheck source=/dev/null -BIN_LOCATION="${BIN_LOCATION:-$root/cache/bin}" source "$root/hack/helpers/install-tools.sh" +BIN_LOCATION="${BIN_LOCATION:-$root/cache/bin}" . "$root/hack/helpers/install-tools.sh" + +rm -f "$root/cache/buildctl.trace.json" # Build the cue invocation params=(cue) @@ -22,7 +24,7 @@ case "${1:-}" in *) cd "$root" target=image - files=("$root/hack/recipe.cue" "$root/hack/cue_tool.cue") + files=("$root/hack/recipe.cue" "$root/hack/helpers/cue_tool.cue") isparam= for i in "$@"; do if [ "${i:0:2}" == "--" ]; then diff --git a/hack/cue_tool.cue b/hack/helpers/cue_tool.cue similarity index 100% rename from hack/cue_tool.cue rename to hack/helpers/cue_tool.cue diff --git a/hack/helpers/install-tools.sh b/hack/helpers/install-tools.sh index 8be862c..0166b3a 100755 --- a/hack/helpers/install-tools.sh +++ b/hack/helpers/install-tools.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash set -o errexit -o errtrace -o functrace -o nounset -o pipefail -export SUITE=bullseye -export DATE=2021-08-01 +export SUITE=bookworm +export DATE=2024-02-20 export BIN_LOCATION="${BIN_LOCATION:-$HOME/bin}" export PATH="$BIN_LOCATION:$PATH" readonly IMAGE_TOOLS="${IMAGE_TOOLS:-dubodubonduponey/tools:$(uname -s | grep -q Darwin && printf "macos" || printf "linux-dev")-$SUITE-$DATE}" -export SHELLCHECK_VERSION=0.7.2 -export HADOLINT_VERSION=2.7.0 +export SHELLCHECK_VERSION=0.10.0 +export HADOLINT_VERSION=2.12.0 setup::tools(){ local location="$1" diff --git a/hack/helpers/start-buildkit.sh b/hack/helpers/start-buildkit.sh index 80702fa..b1b98b3 100755 --- a/hack/helpers/start-buildkit.sh +++ b/hack/helpers/start-buildkit.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash set -o errexit -o errtrace -o functrace -o nounset -o pipefail -export SUITE=bullseye -export DATE=2021-08-01 - -readonly IMAGE_BLDKT="${IMAGE_BLDKT:-docker.io/dubodubonduponey/buildkit:$SUITE-$DATE}" +export TAG=latest +readonly IMAGE_BLDKT="${IMAGE_BLDKT:-docker.io/dubodubonduponey/buildkit:$TAG}" setup::buildkit() { [ "$(docker container inspect -f '{{.State.Running}}' dbdbdp-buildkit 2>/dev/null)" == "true" ] || { @@ -12,14 +10,15 @@ setup::buildkit() { -p 4242:4242 \ --network host \ --name dbdbdp-buildkit \ - --env MDNS_ENABLED=true \ - --env MDNS_HOST=buildkit-machina \ - --env MDNS_NAME="Dubo Buildkit on la machina" \ + --env MOD_MDNS_ENABLED=true \ + --env MOD_MDNS_HOST=buildkit-machina \ + --env MOD_MDNS_NAME="Dubo Buildkit on la machina" \ --entrypoint buildkitd \ --user root \ --privileged \ "$IMAGE_BLDKT" docker exec --env QEMU_BINARY_PATH=/boot/bin/ dbdbdp-buildkit binfmt --install all + docker exec dbdbdp-buildkit mkdir /tmp/runtime } } diff --git a/hack/lint.sh b/hack/lint.sh index e39dd2d..127b850 100755 --- a/hack/lint.sh +++ b/hack/lint.sh @@ -1,12 +1,11 @@ #!/usr/bin/env bash set -o errexit -o errtrace -o functrace -o nounset -o pipefail -# shellcheck source=/dev/null root="$(cd "$(dirname "${BASH_SOURCE[0]:-$PWD}")" 2>/dev/null 1>&2 && pwd)/../" readonly root # shellcheck source=/dev/null -BIN_LOCATION="${BIN_LOCATION:-$root/cache/bin}" source "$root/hack/helpers/install-tools.sh" +BIN_LOCATION="${BIN_LOCATION:-$root/cache/bin}" . "$root/hack/helpers/install-tools.sh" # Ignore some hadolint warnings that do not make much sense # DL3006 is about "dO nOT UsE --platform", which is really ludicrous @@ -24,4 +23,6 @@ if ! hadolint "${hadolint_ignore[@]}" "$root"/*Dockerfile*; then exit 1 fi -find "$root" -iname "*.sh" -not -path "*debuerreotype*" -not -path "*cache*" -exec shellcheck {} \; +while read -r line; do + shellcheck "$line" +done < <(find "$root" -iname "*.sh" -not -path "*debuerreotype*" -not -path "*cache*" -not -path "*xxx*" 2>/dev/null || true) diff --git a/hack/recipe.cue b/hack/recipe.cue index 6b728d3..6671e08 100644 --- a/hack/recipe.cue +++ b/hack/recipe.cue @@ -19,7 +19,7 @@ cakes: { platforms: types.#Platforms | * [ types.#Platforms.#AMD64, types.#Platforms.#ARM64, - types.#Platforms.#V7, + // types.#Platforms.#V7, // types.#Platforms.#I386, // types.#Platforms.#V6, // types.#Platforms.#S390X, @@ -43,8 +43,8 @@ cakes: { } injectors: { - suite: * "bullseye" | =~ "^(?:bullseye|bookworm|trixie|sid)$" @tag(suite, type=string) - date: * "2022-12-01" | =~ "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" @tag(date, type=string) + suite: * "bookworm" | =~ "^(?:bullseye|bookworm|trixie|sid)$" @tag(suite, type=string) + date: * "2024-02-20" | =~ "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" @tag(date, type=string) platforms: string @tag(platforms, type=string) registry: * "registry.local" | string @tag(registry, type=string) } diff --git a/hack/test.sh b/hack/test.sh index ac1a5a1..14be565 100755 --- a/hack/test.sh +++ b/hack/test.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -o errexit -o errtrace -o functrace -o nounset -o pipefail -# shellcheck source=/dev/null root="$(cd "$(dirname "${BASH_SOURCE[0]:-$PWD}")" 2>/dev/null 1>&2 && pwd)/../" +readonly root # Simple no-thrill build tester # XXX Currently reduced to a single architecture to avoid using all disk space until we figure out our space efficiency problem (likely the fat builder image getting duplicated over and over) @@ -10,8 +10,8 @@ root="$(cd "$(dirname "${BASH_SOURCE[0]:-$PWD}")" 2>/dev/null 1>&2 && pwd)/../" if ! "$root/hack/build.sh" \ --inject registry="docker.io/dubodubonduponey" \ --inject progress=plain \ - --inject date=2022-12-01 \ - --inject suite=bullseye \ + --inject date=2024-02-20 \ + --inject suite=bookworm \ --inject platforms=linux/arm64 \ "image" "$@"; then printf >&2 "Failed building\n"