pdbmux: ship as k8s container, drop per-VM systemd/RPM delivery
The estate direction is all-in-kubernetes, so pdbmux (a long-running daemon) should run as an in-cluster service rather than an RPM-installed systemd unit on each VM. The RPM is for workstation/VM CLI tools only; a daemon does not belong there. - Remove packaging/pdbmux.service and drop pdbmux (binary, systemd unit, completions) from the RPM/nfpm spec and build-rpm.sh. - Keep pdbmux in the Makefile build and the test suite. - Add Dockerfile.pdbmux building a static CGO_ENABLED=0 binary on distroless (mirrors encapi's image style). - Add .woodpecker/docker.yaml to build+push git.unkin.net/unkin/pdbmux:<tag> on v* tags via the docker-buildx plugin (droneci/DRONECI_PASSWORD creds, same as encapi), with k8s resources set. - Update README/AGENTS.md: deployment is k8s, config via PDBMUX_* env.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# Build and push the pdbmux container image on a v* tag. pdbmux is a k8s-only
|
||||
# daemon (deployed via argocd-apps), so it ships as an image rather than in the
|
||||
# RPM. Mirrors the estate convention (encapi's docker.yaml): the
|
||||
# woodpeckerci/plugin-docker-buildx plugin pushes to the Gitea registry using
|
||||
# the droneci / DRONECI_PASSWORD credentials.
|
||||
when:
|
||||
- event: tag
|
||||
ref: refs/tags/v*
|
||||
|
||||
steps:
|
||||
- name: docker-pdbmux
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
registry: git.unkin.net
|
||||
repo: git.unkin.net/unkin/pdbmux
|
||||
dockerfile: Dockerfile.pdbmux
|
||||
build_args:
|
||||
VERSION: ${CI_COMMIT_TAG}
|
||||
username: droneci
|
||||
password:
|
||||
from_secret: DRONECI_PASSWORD
|
||||
tags:
|
||||
- ${CI_COMMIT_TAG}
|
||||
- latest
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: default
|
||||
resources:
|
||||
requests:
|
||||
memory: 1Gi
|
||||
cpu: 1
|
||||
limits:
|
||||
memory: 2Gi
|
||||
cpu: 2
|
||||
@@ -33,10 +33,10 @@ internal/puppet/ # shared: config, puppetdb nodes query, board URLs
|
||||
go.mod # Go module (module name: node-lookup)
|
||||
go.sum # dependency checksums
|
||||
Makefile # build / test / lint / completions / rpm / version-bump targets
|
||||
packaging/nfpm.yaml # nfpm spec (envsubst-templated) for the RPM (all 4 binaries)
|
||||
packaging/pdbmux.service # systemd unit for the pdbmux daemon
|
||||
packaging/nfpm.yaml # nfpm spec (envsubst-templated) for the RPM (CLI tools only)
|
||||
Dockerfile.pdbmux # container image for the k8s-only pdbmux daemon
|
||||
scripts/build-rpm.sh # generates completions + packages the RPM with nfpm
|
||||
.woodpecker/ # CI: build, test, pre-commit (PR) + release (tag)
|
||||
.woodpecker/ # CI: build, test, pre-commit (PR) + release/docker (tag)
|
||||
dist/ # build output: binaries, completions, RPM (not committed)
|
||||
```
|
||||
|
||||
@@ -63,6 +63,13 @@ make rpm # build the binary + package it into dist/*.rpm via nfpm
|
||||
and bundles them alongside `/usr/bin/node-lookup`. On a `v*` tag the release
|
||||
pipeline builds the RPM and `PUT`s it to the artifactapi `rpm-internal` repo.
|
||||
|
||||
The RPM contains the workstation/VM CLI tools only (`node-lookup`, `pburl`,
|
||||
`pblastreport`). `pdbmux` is a k8s-only daemon and is deliberately excluded from
|
||||
the RPM — it is released as a container image
|
||||
(`git.unkin.net/unkin/pdbmux:<tag>`, built by `.woodpecker/docker.yaml` from
|
||||
`Dockerfile.pdbmux`) and deployed via `argocd-apps`. `make build` and
|
||||
`go test ./...` still cover pdbmux.
|
||||
|
||||
## Shell completions
|
||||
|
||||
Cobra provides a `completion` subcommand:
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# Container image for pdbmux, the merging PuppetDB proxy daemon. This repo ships
|
||||
# several CLI tools (node-lookup/pburl/pblastreport) as an RPM, but pdbmux is a
|
||||
# k8s-only service, so it gets its own Dockerfile (Dockerfile.pdbmux) and image.
|
||||
FROM golang:1.25-alpine AS builder
|
||||
|
||||
RUN apk add --no-cache git
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
|
||||
ARG VERSION=dev
|
||||
RUN CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=${VERSION}" -o pdbmux ./cmd/pdbmux
|
||||
|
||||
FROM gcr.io/distroless/static-debian12:nonroot
|
||||
|
||||
COPY --from=builder /build/pdbmux /usr/local/bin/pdbmux
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["pdbmux", "serve"]
|
||||
@@ -1,10 +1,15 @@
|
||||
# node-lookup tools
|
||||
|
||||
PuppetDB CLIs and one proxy daemon, shipped together in a single RPM:
|
||||
PuppetDB CLIs plus one proxy daemon.
|
||||
|
||||
The CLIs ship together in a single RPM for workstations/VMs:
|
||||
|
||||
- **`node-lookup`** — query and filter PuppetDB node facts.
|
||||
- **`pburl`** — print each host's Puppetboard node-page URL.
|
||||
- **`pblastreport`** — print each host's last Puppet report time + Puppetboard URL.
|
||||
|
||||
The proxy daemon is deployed to Kubernetes as a container image (not in the RPM):
|
||||
|
||||
- **`pdbmux`** — merging HTTP proxy over two PuppetDBs (see below).
|
||||
|
||||
See [AGENTS.md](AGENTS.md) for the CLI tools' flags, config, and internals. This
|
||||
@@ -71,11 +76,12 @@ unknown fields survive untouched.
|
||||
|
||||
Precedence (lowest → highest): **defaults < config file < env vars (`PDBMUX_*`) < flags**.
|
||||
|
||||
Config file: `$XDG_CONFIG_HOME/pdbmux/config.yaml` (as an RPM/systemd service:
|
||||
`/etc/pdbmux/config.yaml`).
|
||||
Config file: `$XDG_CONFIG_HOME/pdbmux/config.yaml`. In Kubernetes, configuration
|
||||
is supplied entirely via `PDBMUX_*` env vars (no config file), which is the
|
||||
supported deployment path — see [Deployment](#deployment).
|
||||
|
||||
```yaml
|
||||
# ~/.config/pdbmux/config.yaml (or /etc/pdbmux/config.yaml under systemd)
|
||||
# ~/.config/pdbmux/config.yaml (local dev; in k8s use PDBMUX_* env instead)
|
||||
listen: ":8080"
|
||||
backends:
|
||||
- name: old
|
||||
@@ -123,15 +129,30 @@ NODE_LOOKUP_URL=http://localhost:8080/pdb/query/v4/facts pblastreport somehost
|
||||
|
||||
### Deployment
|
||||
|
||||
The RPM installs `/usr/bin/pdbmux` plus a systemd unit at
|
||||
`/usr/lib/systemd/system/pdbmux.service` (reads `/etc/pdbmux/config.yaml`):
|
||||
`pdbmux` runs **in Kubernetes** as a container, in line with the all-in-k8s
|
||||
estate direction — it is not shipped as a per-VM RPM/systemd service. The image
|
||||
is built and pushed on every `v*` tag (`.woodpecker/docker.yaml`) to:
|
||||
|
||||
```bash
|
||||
systemctl enable --now pdbmux
|
||||
curl -s localhost:8080/healthz
|
||||
```
|
||||
git.unkin.net/unkin/pdbmux:<tag>
|
||||
```
|
||||
|
||||
Suited to run as an RPM-managed daemon on a VM alongside the existing Puppet
|
||||
infra during migration; the same static binary is container-ready for a future
|
||||
k8s deployment (single listener, `/healthz` liveness/readiness probe, config via
|
||||
`PDBMUX_*` env).
|
||||
It is a minimal static (`CGO_ENABLED=0`) binary on a distroless base
|
||||
(`Dockerfile.pdbmux`), configured entirely via `PDBMUX_*` env vars, with a
|
||||
single HTTP listener and `/healthz` for liveness/readiness probes.
|
||||
|
||||
The Deployment/Service/Gateway manifests live in the estate's `argocd-apps` repo
|
||||
under `apps/base/pdbmux/` (namespace `pdbmux`, 2 replicas), and it is exposed to
|
||||
VM/workstation `node-lookup` consumers over HTTPS at:
|
||||
|
||||
```
|
||||
https://pdbmux.k8s.syd1.au.unkin.net
|
||||
```
|
||||
|
||||
Locally you can still run the binary directly for development:
|
||||
|
||||
```bash
|
||||
PDBMUX_BACKENDS='old=http://puppetdbapi.service.consul:8080,new=http://puppetdb.puppet.svc.cluster.local:8080' \
|
||||
pdbmux serve
|
||||
curl -s localhost:8080/healthz
|
||||
```
|
||||
|
||||
+5
-23
@@ -42,18 +42,12 @@ contents:
|
||||
mode: 0755
|
||||
owner: root
|
||||
group: root
|
||||
- src: dist/pdbmux
|
||||
dst: /usr/bin/pdbmux
|
||||
file_info:
|
||||
mode: 0755
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
# systemd unit for the pdbmux proxy daemon (config: /etc/pdbmux/config.yaml).
|
||||
- src: packaging/pdbmux.service
|
||||
dst: /usr/lib/systemd/system/pdbmux.service
|
||||
file_info:
|
||||
mode: 0644
|
||||
# NOTE: pdbmux is intentionally NOT shipped in this RPM. It is a k8s-only
|
||||
# daemon (deployed via argocd-apps as a container image), not a workstation/VM
|
||||
# CLI tool, so it has no place in the CLI package. pdbmux is still built and
|
||||
# tested in this repo (see Makefile) and released as a container image
|
||||
# (.woodpecker/docker.yaml).
|
||||
|
||||
# Shell completions (generated by scripts/build-rpm.sh before packaging).
|
||||
- src: dist/completions/node-lookup.bash
|
||||
@@ -92,15 +86,3 @@ contents:
|
||||
dst: /usr/share/fish/vendor_completions.d/pblastreport.fish
|
||||
file_info:
|
||||
mode: 0644
|
||||
- src: dist/completions/pdbmux.bash
|
||||
dst: /usr/share/bash-completion/completions/pdbmux
|
||||
file_info:
|
||||
mode: 0644
|
||||
- src: dist/completions/_pdbmux
|
||||
dst: /usr/share/zsh/site-functions/_pdbmux
|
||||
file_info:
|
||||
mode: 0644
|
||||
- src: dist/completions/pdbmux.fish
|
||||
dst: /usr/share/fish/vendor_completions.d/pdbmux.fish
|
||||
file_info:
|
||||
mode: 0644
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
[Unit]
|
||||
Description=pdbmux - merging proxy over old + new PuppetDB during migration
|
||||
Documentation=https://git.unkin.net/unkin/node-lookup
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
# Configure via /etc/pdbmux/config.yaml or PDBMUX_* env in this file / a drop-in.
|
||||
# Example env overrides:
|
||||
# Environment=PDBMUX_LISTEN=:8080
|
||||
# Environment=PDBMUX_MERGE=freshness
|
||||
Environment=XDG_CONFIG_HOME=/etc
|
||||
ExecStart=/usr/bin/pdbmux serve
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
# Hardening: pdbmux only makes outbound HTTP(S) and listens on a socket.
|
||||
DynamicUser=yes
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectControlGroups=yes
|
||||
RestrictAddressFamilies=AF_INET AF_INET6
|
||||
RestrictNamespaces=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -12,7 +12,10 @@ cd "${ROOT_DIR}"
|
||||
VERSION="${1:-${CI_COMMIT_TAG:-0.0.0-dev}}"
|
||||
VERSION="${VERSION#v}" # strip a leading v
|
||||
BINARY="node-lookup"
|
||||
BINARIES=(node-lookup pburl pblastreport pdbmux)
|
||||
# RPM ships the workstation/VM CLI tools only. pdbmux is a k8s-only daemon and
|
||||
# is deliberately excluded from the RPM (it is released as a container image);
|
||||
# it is still built + tested in this repo via the Makefile.
|
||||
BINARIES=(node-lookup pburl pblastreport)
|
||||
DIST="dist"
|
||||
|
||||
for b in "${BINARIES[@]}"; do
|
||||
@@ -37,7 +40,7 @@ export PACKAGE_VERSION="${VERSION}"
|
||||
export PACKAGE_RELEASE="1"
|
||||
export PACKAGE_ARCH="amd64"
|
||||
export PACKAGE_PLATFORM="linux"
|
||||
export PACKAGE_DESCRIPTION="CLI tools for PuppetDB: node-lookup (fact lookup/filtering), pburl and pblastreport (Puppetboard URLs and last-report times), plus pdbmux (merging proxy over the old + new PuppetDB during migration)"
|
||||
export PACKAGE_DESCRIPTION="CLI tools for PuppetDB: node-lookup (fact lookup/filtering), pburl and pblastreport (Puppetboard URLs and last-report times)"
|
||||
export PACKAGE_MAINTAINER="Ben Vincent <ben@unkin.net>"
|
||||
export PACKAGE_HOMEPAGE="https://git.unkin.net/unkin/node-lookup"
|
||||
export PACKAGE_LICENSE="MIT"
|
||||
|
||||
Reference in New Issue
Block a user