Compare commits
3 commits
b9e9c3f084
...
cc56ba2939
| Author | SHA1 | Date | |
|---|---|---|---|
| cc56ba2939 | |||
|
|
f6cff262f0 | ||
|
|
43254ccd3f |
3 changed files with 78 additions and 8 deletions
63
.woodpecker/pve-nfs-exports-sync.yml
Normal file
63
.woodpecker/pve-nfs-exports-sync.yml
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Sync infra/scripts/pve-nfs-exports → PVE host /etc/exports on change.
|
||||
#
|
||||
# Wave 6b of the state-drift consolidation plan: move the "scp + exportfs -ra"
|
||||
# deploy step out of runbook-human-hands and into CI so the Proxmox NFS export
|
||||
# table tracks git.
|
||||
#
|
||||
# Trigger: push to master that touches `scripts/pve-nfs-exports`. The file
|
||||
# header documents the deploy invocation; this pipeline codifies it.
|
||||
#
|
||||
# Credentials:
|
||||
# - pve_ssh_key: Woodpecker repo-secret (ed25519 keypair provisioned
|
||||
# 2026-04-18 as `woodpecker-pve-nfs-exports-sync`). Public key lives in
|
||||
# /root/.ssh/authorized_keys on the PVE host. Private key mirrored in
|
||||
# Vault `secret/woodpecker/pve_ssh_key` for recovery.
|
||||
|
||||
when:
|
||||
- event: push
|
||||
branch: master
|
||||
path: scripts/pve-nfs-exports
|
||||
- event: manual
|
||||
|
||||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git
|
||||
settings:
|
||||
depth: 1
|
||||
attempts: 3
|
||||
|
||||
steps:
|
||||
- name: deploy
|
||||
image: alpine:3.20
|
||||
environment:
|
||||
PVE_SSH_KEY:
|
||||
from_secret: pve_ssh_key
|
||||
SLACK_WEBHOOK:
|
||||
from_secret: slack_webhook
|
||||
commands:
|
||||
- apk add --no-cache openssh-client curl
|
||||
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||||
- printf '%s\n' "$PVE_SSH_KEY" > ~/.ssh/id_ed25519
|
||||
- chmod 600 ~/.ssh/id_ed25519
|
||||
# Pin host key — CI's ~/.ssh/known_hosts is ephemeral, so accept-new on first pull.
|
||||
- ssh-keyscan -t ed25519 192.168.1.127 >> ~/.ssh/known_hosts 2>/dev/null
|
||||
# Diff what we'd ship, so pipeline logs show the intended change.
|
||||
- echo '---diff---' && ssh -o BatchMode=yes root@192.168.1.127 "cat /etc/exports" > /tmp/remote.exports || true
|
||||
- diff -u /tmp/remote.exports scripts/pve-nfs-exports || true
|
||||
- echo '---applying---'
|
||||
- scp -o BatchMode=yes scripts/pve-nfs-exports root@192.168.1.127:/etc/exports
|
||||
- ssh -o BatchMode=yes root@192.168.1.127 "exportfs -ra && exportfs -s | head -5"
|
||||
- echo '---done---'
|
||||
|
||||
- name: slack
|
||||
image: curlimages/curl:8.11.0
|
||||
environment:
|
||||
SLACK_WEBHOOK:
|
||||
from_secret: slack_webhook
|
||||
commands:
|
||||
- |
|
||||
curl -s -X POST -H 'Content-type: application/json' \
|
||||
--data "{\"channel\":\"general\",\"text\":\"PVE /etc/exports sync: ${CI_PIPELINE_STATUS}\"}" \
|
||||
"$SLACK_WEBHOOK" || true
|
||||
when:
|
||||
status: [success, failure]
|
||||
|
|
@ -669,7 +669,9 @@ resource "kubernetes_cron_job_v1" "fidelity" {
|
|||
spec {
|
||||
restart_policy = "OnFailure"
|
||||
# Materialise the JSON storage_state from the projected Secret
|
||||
# onto the PVC where Playwright expects to read it.
|
||||
# onto the PVC where Playwright expects to read it. Init container
|
||||
# runs as root; the main broker-sync container runs as uid 10001,
|
||||
# so we chown+chmod 600 to grant read access to the broker user.
|
||||
init_container {
|
||||
name = "stage-storage-state"
|
||||
image = "busybox:1.36"
|
||||
|
|
@ -677,6 +679,7 @@ resource "kubernetes_cron_job_v1" "fidelity" {
|
|||
set -eu
|
||||
mkdir -p /data
|
||||
cp /secrets/fidelity_storage_state /data/fidelity_storage_state.json
|
||||
chown 10001:10001 /data/fidelity_storage_state.json
|
||||
chmod 600 /data/fidelity_storage_state.json
|
||||
EOT
|
||||
]
|
||||
|
|
|
|||
|
|
@ -312,14 +312,18 @@ resource "kubernetes_config_map" "grafana_payslips_datasource" {
|
|||
"payslips-datasource.yaml" = yamlencode({
|
||||
apiVersion = 1
|
||||
datasources = [{
|
||||
name = "Payslips"
|
||||
type = "postgres"
|
||||
access = "proxy"
|
||||
url = "${var.postgresql_host}:5432"
|
||||
database = "payslip_ingest"
|
||||
user = "payslip_ingest"
|
||||
uid = "payslips-pg"
|
||||
name = "Payslips"
|
||||
type = "postgres"
|
||||
access = "proxy"
|
||||
url = "${var.postgresql_host}:5432"
|
||||
user = "payslip_ingest"
|
||||
uid = "payslips-pg"
|
||||
# Grafana 11.2+ Postgres plugin reads the DB name from jsonData.database;
|
||||
# the top-level `database` field is silently ignored by the frontend and
|
||||
# triggers "you do not have default database" on every panel.
|
||||
# See github.com/grafana/grafana#112418.
|
||||
jsonData = {
|
||||
database = "payslip_ingest"
|
||||
sslmode = "disable"
|
||||
postgresVersion = 1600
|
||||
timescaledb = false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue