From 23674dcf074dbec739ec26783af95542f3354e54 Mon Sep 17 00:00:00 2001 From: ansible Date: Tue, 10 Mar 2026 22:45:37 +0800 Subject: [PATCH] Update k8s manifests --- k8s/apps/pkg-repo/ci-rbac.yaml | 41 +++++++ k8s/apps/pkg-repo/deployment.yaml | 100 +++++++++++++++++- k8s/apps/pkg-repo/kustomization.yaml | 1 + k8s/infrastructure/sops/kustomization.yaml | 1 + .../sops/repo-gpg-key-secret.yaml | 27 +++++ 5 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 k8s/apps/pkg-repo/ci-rbac.yaml create mode 100644 k8s/infrastructure/sops/repo-gpg-key-secret.yaml diff --git a/k8s/apps/pkg-repo/ci-rbac.yaml b/k8s/apps/pkg-repo/ci-rbac.yaml new file mode 100644 index 0000000..3ab2e63 --- /dev/null +++ b/k8s/apps/pkg-repo/ci-rbac.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: pkg-repo-ci + namespace: pkg-repo +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: pkg-repo-publisher + namespace: pkg-repo +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: pkg-repo-ci-publisher + namespace: pkg-repo +subjects: + - kind: ServiceAccount + name: pkg-repo-ci + namespace: pkg-repo +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: pkg-repo-publisher +--- +apiVersion: v1 +kind: Secret +metadata: + name: pkg-repo-ci-token + namespace: pkg-repo + annotations: + kubernetes.io/service-account.name: pkg-repo-ci +type: kubernetes.io/service-account-token diff --git a/k8s/apps/pkg-repo/deployment.yaml b/k8s/apps/pkg-repo/deployment.yaml index 6ab1483..b1848df 100644 --- a/k8s/apps/pkg-repo/deployment.yaml +++ b/k8s/apps/pkg-repo/deployment.yaml @@ -1,4 +1,76 @@ --- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pkg-repo-pvc + namespace: pkg-repo +spec: + storageClassName: longhorn + accessModes: [ReadWriteOnce] + resources: + requests: + storage: 10Gi +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: reprepro-config + namespace: pkg-repo +data: + distributions: | + Codename: trixie + Suite: stable + Components: main + Architectures: amd64 arm64 + SignWith: yes + options: | + basedir /repo/debian + init.sh: | + #!/bin/bash + set -e + + # Install reprepro (one-time, cached in PVC) + if ! command -v reprepro &>/dev/null; then + apt-get update && apt-get install -y --no-install-recommends reprepro gpg + rm -rf /var/lib/apt/lists/* + fi + + # Import GPG key + gpg --batch --import /gpg/private.key 2>/dev/null || true + + # Export public key for clients + gpg --armor --export > /repo/pubkey.gpg + + # Init reprepro if not done + if [ ! -f /repo/debian/db/version ]; then + echo "Initializing reprepro..." + mkdir -p /repo/debian/conf + cp /config/distributions /repo/debian/conf/ + cp /config/options /repo/debian/conf/ + cd /repo/debian && reprepro export + fi + + # Always ensure conf is up-to-date + mkdir -p /repo/debian/conf + cp /config/distributions /repo/debian/conf/ + cp /config/options /repo/debian/conf/ + + # Index page + cat > /repo/index.html <<'HTML' + + n0ball repo + +

n0ball Package Repository

+ + + HTML + + echo "Repo initialized. Waiting for commands..." + sleep infinity +--- apiVersion: apps/v1 kind: Deployment metadata: @@ -23,11 +95,33 @@ spec: - name: repo-data mountPath: /usr/share/nginx/html readOnly: true + - name: reprepro + image: debian:trixie + command: ["bash", "/config/init.sh"] + volumeMounts: + - name: repo-data + mountPath: /repo + - name: gpg-key + mountPath: /gpg + readOnly: true + - name: config + mountPath: /config + readOnly: true + - name: incoming + mountPath: /incoming volumes: - name: repo-data - nfs: - server: 192.168.50.50 - path: /mnt/NFS/pve-nfs/pkg-repo + persistentVolumeClaim: + claimName: pkg-repo-pvc + - name: gpg-key + secret: + secretName: repo-gpg-key + - name: config + configMap: + name: reprepro-config + defaultMode: 0755 + - name: incoming + emptyDir: {} --- apiVersion: v1 kind: Service diff --git a/k8s/apps/pkg-repo/kustomization.yaml b/k8s/apps/pkg-repo/kustomization.yaml index 34a36c7..cb387ef 100644 --- a/k8s/apps/pkg-repo/kustomization.yaml +++ b/k8s/apps/pkg-repo/kustomization.yaml @@ -4,3 +4,4 @@ resources: - namespace.yaml - deployment.yaml - ingress.yaml + - ci-rbac.yaml diff --git a/k8s/infrastructure/sops/kustomization.yaml b/k8s/infrastructure/sops/kustomization.yaml index 9e3b4b7..f3922cd 100644 --- a/k8s/infrastructure/sops/kustomization.yaml +++ b/k8s/infrastructure/sops/kustomization.yaml @@ -11,3 +11,4 @@ resources: - smtp-secret.yaml - grafana-smtp-secret.yaml - vaultwarden-smtp-secret.yaml + - repo-gpg-key-secret.yaml diff --git a/k8s/infrastructure/sops/repo-gpg-key-secret.yaml b/k8s/infrastructure/sops/repo-gpg-key-secret.yaml new file mode 100644 index 0000000..912a6c3 --- /dev/null +++ b/k8s/infrastructure/sops/repo-gpg-key-secret.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: Secret +metadata: + name: repo-gpg-key + namespace: pkg-repo +stringData: + private.key: ENC[AES256_GCM,data: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,iv:cMtSMutwl2xFah4N9ETjQM/mksUzy28xQDDs0pvvihQ=,tag:babUz1bdcTxYFblzxb7eMg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1y5rw08wm2s2hemapzf43c0l4xass7fhc55qh3n4cxtuxzrj8q3cqtydy7m + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvV0JQQjFkQW01L1AvSWI4 + c3FYVkRWLzc1T1FVVE1zUEMrVE9sOENwQlZvCjViL2pYRnRrQWlla1dHOFNOUHpt + R24xbGdGWlc0NXhpSGRlb3V5b2x0NGsKLS0tIGd2VG9adG8vV1ROQ3FPM3MrV3Y2 + dUpjVWU2d0NuRkVVeXVmeGhWcHBvck0Kqp0OCx6NJOYobX1VQaedca89n8HbEYHl + GexaSWuuc8qPS9r9Wo9q4gcOGYd2UAIOxZCpY0nlBSvrA/HzMbN6lw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-10T14:42:17Z" + mac: ENC[AES256_GCM,data:wlxIC7SureKW2yVWFonx7BhN9Ff2j+WC1xH6QjpCd4ZR7qgzrI9SxiTVzNwsyssAkmTM8ntaEYl4Uh70GmkIUWnRzk870M+TspYeGcbP23Kg7evWpGDenf+WFDh8SI1DdI0nPObefW6WbNhWhqh+8ZeBp/KWwSIaz8NuV8fL9Wg=,iv:mecMWQHjBP6Gw31umjrzlVCgF8h15kMAv6gC5zrqhCE=,tag:Wa5/7L9gHWMDnL2O/dylUA==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.4