diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-28 12:22:00 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-28 12:22:00 +0200 |
| commit | fe718ba200e0b64efad6478f56fc56103f45a574 (patch) | |
| tree | 514281dc1238eef1673d494361bd729ae50c97f3 | |
| parent | 9c01cbe09da8d5519ad225760828c4c197845b8d (diff) | |
pkgrepo: add FreeBSD/OpenBSD package repository service
Serve custom-built FreeBSD and OpenBSD packages via nginx in the k3s
cluster. Includes helm chart, ArgoCD app, test artifact build script,
and DNS entry via frontends Rexfile.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| -rw-r--r-- | f3s/argocd-apps/infra/pkgrepo.yaml | 28 | ||||
| -rw-r--r-- | f3s/pkgrepo/helm-chart/Chart.yaml | 5 | ||||
| -rw-r--r-- | f3s/pkgrepo/helm-chart/templates/configmap-nginx.yaml | 36 | ||||
| -rw-r--r-- | f3s/pkgrepo/helm-chart/templates/deployment.yaml | 53 | ||||
| -rw-r--r-- | f3s/pkgrepo/helm-chart/templates/ingress.yaml | 20 | ||||
| -rw-r--r-- | f3s/pkgrepo/helm-chart/templates/persistent-volume.yaml | 28 | ||||
| -rw-r--r-- | f3s/pkgrepo/helm-chart/templates/service.yaml | 13 | ||||
| -rwxr-xr-x | f3s/pkgrepo/test-artifacts/build-test-packages.sh | 105 | ||||
| -rw-r--r-- | frontends/Rexfile | 2 |
9 files changed, 289 insertions, 1 deletions
diff --git a/f3s/argocd-apps/infra/pkgrepo.yaml b/f3s/argocd-apps/infra/pkgrepo.yaml new file mode 100644 index 0000000..12bdb9c --- /dev/null +++ b/f3s/argocd-apps/infra/pkgrepo.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: pkgrepo + namespace: cicd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: http://git-server.cicd.svc.cluster.local/conf.git + targetRevision: master + path: f3s/pkgrepo/helm-chart + destination: + server: https://kubernetes.default.svc + namespace: infra + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=false + retry: + limit: 3 + backoff: + duration: 5s + factor: 2 + maxDuration: 1m diff --git a/f3s/pkgrepo/helm-chart/Chart.yaml b/f3s/pkgrepo/helm-chart/Chart.yaml new file mode 100644 index 0000000..7507f7b --- /dev/null +++ b/f3s/pkgrepo/helm-chart/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: pkgrepo +description: A Helm chart for serving FreeBSD and OpenBSD package repositories. +version: 0.1.0 +appVersion: "1.0" diff --git a/f3s/pkgrepo/helm-chart/templates/configmap-nginx.yaml b/f3s/pkgrepo/helm-chart/templates/configmap-nginx.yaml new file mode 100644 index 0000000..61325ce --- /dev/null +++ b/f3s/pkgrepo/helm-chart/templates/configmap-nginx.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: pkgrepo-nginx-config + namespace: infra +data: + nginx.conf: | + worker_processes 1; + events { + worker_connections 256; + } + http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + server { + listen 8080; + root /usr/share/nginx/html; + + # FreeBSD pkg repository + location /freebsd/ { + autoindex on; + } + + # OpenBSD pkg_add repository + location /openbsd/ { + autoindex on; + } + + location / { + return 404; + } + } + } diff --git a/f3s/pkgrepo/helm-chart/templates/deployment.yaml b/f3s/pkgrepo/helm-chart/templates/deployment.yaml new file mode 100644 index 0000000..24d157c --- /dev/null +++ b/f3s/pkgrepo/helm-chart/templates/deployment.yaml @@ -0,0 +1,53 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: pkgrepo + namespace: infra + labels: + app: pkgrepo +spec: + replicas: 1 + selector: + matchLabels: + app: pkgrepo + template: + metadata: + labels: + app: pkgrepo + spec: + containers: + - name: nginx + image: nginx:1.27-alpine + ports: + - containerPort: 8080 + # Liveness probe: restart if nginx stops responding + livenessProbe: + httpGet: + path: / + port: 8080 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + # Readiness probe: remove from service if not ready + readinessProbe: + httpGet: + path: / + port: 8080 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 2 + volumeMounts: + - name: pkgrepo-storage + mountPath: /usr/share/nginx/html + readOnly: true + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + readOnly: true + volumes: + - name: pkgrepo-storage + persistentVolumeClaim: + claimName: pkgrepo-pvc + - name: nginx-config + configMap: + name: pkgrepo-nginx-config diff --git a/f3s/pkgrepo/helm-chart/templates/ingress.yaml b/f3s/pkgrepo/helm-chart/templates/ingress.yaml new file mode 100644 index 0000000..dc47972 --- /dev/null +++ b/f3s/pkgrepo/helm-chart/templates/ingress.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: pkgrepo-ingress + namespace: infra + annotations: + spec.ingressClassName: traefik + traefik.ingress.kubernetes.io/router.entrypoints: web +spec: + rules: + - host: pkgrepo.f3s.buetow.org + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: pkgrepo-service + port: + number: 80 diff --git a/f3s/pkgrepo/helm-chart/templates/persistent-volume.yaml b/f3s/pkgrepo/helm-chart/templates/persistent-volume.yaml new file mode 100644 index 0000000..2b6fb0b --- /dev/null +++ b/f3s/pkgrepo/helm-chart/templates/persistent-volume.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pkgrepo-pv +spec: + capacity: + storage: 20Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + hostPath: + path: /data/nfs/k3svolumes/pkgrepo + type: Directory +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pkgrepo-pvc + namespace: infra +spec: + storageClassName: "" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi + volumeName: pkgrepo-pv diff --git a/f3s/pkgrepo/helm-chart/templates/service.yaml b/f3s/pkgrepo/helm-chart/templates/service.yaml new file mode 100644 index 0000000..10ab51c --- /dev/null +++ b/f3s/pkgrepo/helm-chart/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: pkgrepo-service + namespace: infra +spec: + selector: + app: pkgrepo + ports: + - protocol: TCP + port: 80 + targetPort: 8080 + type: ClusterIP diff --git a/f3s/pkgrepo/test-artifacts/build-test-packages.sh b/f3s/pkgrepo/test-artifacts/build-test-packages.sh new file mode 100755 index 0000000..2ec8626 --- /dev/null +++ b/f3s/pkgrepo/test-artifacts/build-test-packages.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# Build a minimal hello-test package for FreeBSD or OpenBSD. +# Run on the target OS: ./build-test-packages.sh freebsd|openbsd +# The output directory will contain the package ready to copy to the repo PV. + +set -e + +usage() { + echo "Usage: $0 freebsd|openbsd" + exit 1 +} + +build_freebsd() { + WORKDIR=$(mktemp -d) + OUTDIR="$PWD/freebsd-output" + mkdir -p "$OUTDIR" + + # Create the hello-test script + mkdir -p "$WORKDIR/usr/local/bin" + cat > "$WORKDIR/usr/local/bin/hello-test" <<'SCRIPT' +#!/bin/sh +echo "Hello from the custom FreeBSD package repo!" +SCRIPT + chmod 755 "$WORKDIR/usr/local/bin/hello-test" + + # Create the package manifest + cat > "$WORKDIR/+MANIFEST" <<'MANIFEST' +name: hello-test +version: "1.0" +origin: local/hello-test +comment: "Test package for the custom FreeBSD package repository" +desc: "A minimal hello-world package to verify the custom pkg repo works." +maintainer: "paul@buetow.org" +www: "https://buetow.org" +prefix: /usr/local +MANIFEST + + # Create the packing list + cat > "$WORKDIR/+COMPACT_MANIFEST" <<'MANIFEST' +name: hello-test +version: "1.0" +origin: local/hello-test +comment: "Test package for the custom FreeBSD package repository" +desc: "A minimal hello-world package to verify the custom pkg repo works." +maintainer: "paul@buetow.org" +www: "https://buetow.org" +prefix: /usr/local +MANIFEST + + # Build the package + mkdir -p "$OUTDIR/All" + pkg create -M "$WORKDIR/+MANIFEST" -r "$WORKDIR" -o "$OUTDIR/All" + + # Generate the unsigned repo metadata + pkg repo "$OUTDIR" + + rm -rf "$WORKDIR" + + echo "" + echo "FreeBSD package built in: $OUTDIR" + echo "Copy contents to the PV:" + echo " scp -r $OUTDIR/* <nfs-host>:/data/nfs/k3svolumes/pkgrepo/freebsd/FreeBSD:15:amd64/latest/" +} + +build_openbsd() { + WORKDIR=$(mktemp -d) + OUTDIR="$PWD/openbsd-output" + mkdir -p "$OUTDIR" + + # Create the hello-test script + mkdir -p "$WORKDIR/usr/local/bin" + cat > "$WORKDIR/usr/local/bin/hello-test" <<'SCRIPT' +#!/bin/sh +echo "Hello from the custom OpenBSD package repo!" +SCRIPT + chmod 755 "$WORKDIR/usr/local/bin/hello-test" + + # Create the packing list + cat > "$WORKDIR/packing-list" <<'PLIST' +@name hello-test-1.0 +@comment Test package for the custom OpenBSD package repository +@bin usr/local/bin/hello-test +PLIST + + # Build the package + cd "$WORKDIR" + pkg_create -d "A minimal hello-world package to verify the custom pkg repo works." \ + -f "$WORKDIR/packing-list" \ + -B "$WORKDIR" \ + -p / \ + "$OUTDIR/hello-test-1.0.tgz" + + rm -rf "$WORKDIR" + + echo "" + echo "OpenBSD package built in: $OUTDIR" + echo "Copy contents to the PV:" + echo " scp $OUTDIR/hello-test-1.0.tgz <nfs-host>:/data/nfs/k3svolumes/pkgrepo/openbsd/7.7/packages/amd64/" +} + +case "$1" in + freebsd) build_freebsd ;; + openbsd) build_openbsd ;; + *) usage ;; +esac diff --git a/frontends/Rexfile b/frontends/Rexfile index 8431535..4b57dfa 100644 --- a/frontends/Rexfile +++ b/frontends/Rexfile @@ -85,7 +85,7 @@ our $secrets = sub { read_file './secrets/' . shift }; # k3s cluster running on FreeBSD in my LAN our @f3s_hosts = - qw/f3s.buetow.org pihole.f3s.buetow.org jellyfin.f3s.buetow.org navidrome.f3s.buetow.org git.f3s.buetow.org cgit.f3s.buetow.org immich.f3s.buetow.org argocd.f3s.buetow.org keybr.f3s.buetow.org anki.f3s.buetow.org bag.f3s.buetow.org flux.f3s.buetow.org audiobookshelf.f3s.buetow.org grafana.f3s.buetow.org radicale.f3s.buetow.org syncthing.f3s.buetow.org koreader.f3s.buetow.org filebrowser.f3s.buetow.org webdav.f3s.buetow.org ipv6test.f3s.buetow.org ipv4.ipv6test.f3s.buetow.org ipv6.ipv6test.f3s.buetow.org/; + qw/f3s.buetow.org pihole.f3s.buetow.org jellyfin.f3s.buetow.org navidrome.f3s.buetow.org git.f3s.buetow.org cgit.f3s.buetow.org immich.f3s.buetow.org argocd.f3s.buetow.org keybr.f3s.buetow.org anki.f3s.buetow.org bag.f3s.buetow.org flux.f3s.buetow.org audiobookshelf.f3s.buetow.org grafana.f3s.buetow.org radicale.f3s.buetow.org syncthing.f3s.buetow.org koreader.f3s.buetow.org filebrowser.f3s.buetow.org webdav.f3s.buetow.org pkgrepo.f3s.buetow.org ipv6test.f3s.buetow.org ipv4.ipv6test.f3s.buetow.org ipv6.ipv6test.f3s.buetow.org/; # optionally, only enable manually for temp time, as no password protection yet # push @f3s_hosts, 'registry.f3s.buetow.org'; |
