cluster

Infrastructure files for Nordgedanken and Midnightthoughts.
git clone git://archive.git.mtrnord.blog/MTRNord/cluster.git
Log | Files | Refs | README

commit b320dfbe2bd2e754c21f6e55b57bf6015ffb1ecb
parent e88dba7dc57972ce7ea0527665a8b9855c9aabc5
Author: MTRNord <MTRNord@users.noreply.github.com>
Date:   Thu,  9 Apr 2026 22:56:18 +0200

try to set up jenkins

Signed-off-by: MTRNord <MTRNord@users.noreply.github.com>

Diffstat:
AJenkinsfile | 304+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mapps/talos_cluster/envoy-gateway/gateway_settings.yaml | 12++++++++++++
Aapps/talos_cluster/jenkins/helm-repository.yaml | 8++++++++
Aapps/talos_cluster/jenkins/jenkins-instance.yaml | 284+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aapps/talos_cluster/jenkins/kustomization.yaml | 11+++++++++++
Aapps/talos_cluster/jenkins/namespace.yaml | 4++++
Aapps/talos_cluster/jenkins/operator-release.yaml | 19+++++++++++++++++++
Mencrypt.sh | 4++--
8 files changed, 644 insertions(+), 2 deletions(-)

diff --git a/Jenkinsfile b/Jenkinsfile @@ -0,0 +1,304 @@ +pipeline { + agent any + + options { + timestamps() + timeout(time: 4, unit: 'HOURS') + buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '5')) + } + + parameters { + choice( + name: 'BUILD_IMAGE', + choices: ['matrix-backup', 'continuwuity', 'blog', 'bookwyrm', 'all'], + description: 'Which image(s) to build' + ) + } + + environment { + REGISTRY = 'registry.midnightthoughts.space' + REGISTRY_URL = 'https://registry.midnightthoughts.space' + DOCKER_CONFIG = '/var/run/secrets/docker.io' + COSIGN_KEY_PATH = '/var/run/secrets/cosign/key' + } + + stages { + stage('Prepare Build Environment') { + steps { + script { + echo "=== Preparing multi-arch build environment ===" + sh ''' + # Register QEMU handlers for multi-arch builds + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes || true + + # Verify QEMU is registered + ls -la /proc/sys/fs/binfmt_misc/ || echo "binfmt_misc not available" + + # Enable buildx for multi-arch support + docker buildx create --use --name multiarch-builder || docker buildx use multiarch-builder + docker buildx inspect --bootstrap + ''' + } + } + } + + stage('Clone Repository') { + steps { + checkout scm + } + } + + stage('Build Images') { + parallel { + stage('matrix-backup') { + when { + expression { params.BUILD_IMAGE == 'matrix-backup' || params.BUILD_IMAGE == 'all' } + } + steps { + script { + build_matrix_backup() + } + } + } + + stage('continuwuity') { + when { + expression { params.BUILD_IMAGE == 'continuwuity' || params.BUILD_IMAGE == 'all' } + } + steps { + script { + build_continuwuity() + } + } + } + + stage('blog') { + when { + expression { params.BUILD_IMAGE == 'blog' || params.BUILD_IMAGE == 'all' } + } + steps { + script { + build_blog() + } + } + } + + stage('bookwyrm') { + when { + expression { params.BUILD_IMAGE == 'bookwyrm' || params.BUILD_IMAGE == 'all' } + } + steps { + script { + build_bookwyrm() + } + } + } + } + } + } + + post { + always { + cleanWs() + } + success { + echo "✓ Build pipeline completed successfully!" + } + failure { + echo "✗ Build pipeline failed!" + } + } +} + +def build_matrix_backup() { + echo "=== Building matrix-backup ===" + docker.image('docker:latest').inside('--privileged') { + sh ''' + set -eu + + # Configure Docker login + mkdir -p ~/.docker + cp ${DOCKER_CONFIG}/config.json ~/.docker/config.json 2>/dev/null || true + + # Get image metadata + TAG_TS=$(date -u +%Y%m%d-%H%M%S) + TAG_SHA="sha-$(git rev-parse --short HEAD)" + IMAGE="${REGISTRY}/mtrnord/cluster/matrix-backup" + + echo "Building multi-arch image: ${IMAGE}" + echo "Tags: ${TAG_TS}, main, ${TAG_SHA}" + + # Build and push multi-arch image + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag "${IMAGE}:${TAG_TS}" \ + --tag "${IMAGE}:main" \ + --tag "${IMAGE}:${TAG_SHA}" \ + --push \ + -f apps/talos_cluster/image-builder/matrix-backup/Dockerfile \ + apps/talos_cluster/image-builder/matrix-backup/ + + # Sign all pushed digests with cosign + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:${TAG_TS}" + + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:main" + + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:${TAG_SHA}" + ''' + } +} + +def build_continuwuity() { + echo "=== Building continuwuity ===" + docker.image('docker:latest').inside('--privileged') { + sh ''' + set -eu + + # Configure Docker login + mkdir -p ~/.docker + cp ${DOCKER_CONFIG}/config.json ~/.docker/config.json 2>/dev/null || true + + # Get image metadata + TAG_SHA="sha-$(git rev-parse --short HEAD)" + IMAGE="${REGISTRY}/mtrnord/cluster/continuwuity" + + echo "Building multi-arch image: ${IMAGE}" + echo "Tags: main, ${TAG_SHA}" + + # Build and push multi-arch image + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag "${IMAGE}:main" \ + --tag "${IMAGE}:${TAG_SHA}" \ + --push \ + -f apps/talos_cluster/image-builder/continuwuity/Dockerfile \ + apps/talos_cluster/image-builder/continuwuity/ + + # Sign all pushed digests with cosign + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:main" + + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:${TAG_SHA}" + ''' + } +} + +def build_blog() { + echo "=== Building blog ===" + docker.image('docker:latest').inside('--privileged') { + sh ''' + set -eu + + # Configure Docker login + mkdir -p ~/.docker + cp ${DOCKER_CONFIG}/config.json ~/.docker/config.json 2>/dev/null || true + + # Get image metadata + TAG_TS=$(date -u +%Y%m%d-%H%M%S) + TAG_SHA="sha-$(git rev-parse --short HEAD)" + IMAGE="${REGISTRY}/mtrnord/blog" + + echo "Building multi-arch image: ${IMAGE}" + echo "Tags: ${TAG_TS}, latest, ${TAG_SHA}" + + # Build and push multi-arch image + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag "${IMAGE}:${TAG_TS}" \ + --tag "${IMAGE}:latest" \ + --tag "${IMAGE}:${TAG_SHA}" \ + --push \ + -f apps/talos_cluster/image-builder/blog/Dockerfile \ + apps/talos_cluster/image-builder/blog/ + + # Sign all pushed digests with cosign + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:${TAG_TS}" + + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:latest" + + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:${TAG_SHA}" + ''' + } +} + +def build_bookwyrm() { + echo "=== Building bookwyrm ===" + docker.image('docker:latest').inside('--privileged') { + sh ''' + set -eu + + # Configure Docker login + mkdir -p ~/.docker + cp ${DOCKER_CONFIG}/config.json ~/.docker/config.json 2>/dev/null || true + + # Get upstream version + VERSION=$(docker run --rm curlimages/curl:latest \ + curl -sf "https://api.github.com/repos/bookwyrm-social/bookwyrm/releases/latest" | \ + grep '"tag_name"' | head -1 | cut -d'"' -f4) + + if [ -z "$VERSION" ]; then + echo "ERROR: could not determine upstream version" + exit 1 + fi + + IMAGE="${REGISTRY}/mtrnord/cluster/bookwyrm" + + echo "Building multi-arch image: ${IMAGE}" + echo "Tags: ${VERSION}, latest" + + # Build and push multi-arch image + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --build-arg VERSION="${VERSION}" \ + --tag "${IMAGE}:${VERSION}" \ + --tag "${IMAGE}:latest" \ + --push \ + -f apps/talos_cluster/image-builder/bookwyrm/Dockerfile \ + apps/talos_cluster/image-builder/bookwyrm/ + + # Sign all pushed digests with cosign + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:${VERSION}" + + docker run --rm \ + -v ${COSIGN_KEY_PATH}:/cosign/key:ro \ + -v ~/.docker:/root/.docker:ro \ + gcr.io/projectsigstore/cosign:latest \ + sign --key /cosign/key "${IMAGE}:latest" + ''' + } +} diff --git a/apps/talos_cluster/envoy-gateway/gateway_settings.yaml b/apps/talos_cluster/envoy-gateway/gateway_settings.yaml @@ -833,6 +833,18 @@ spec: certificateRefs: - kind: Secret name: registry.midnightthoughts.space-tls + - name: https-jenkins-midnightthoughts + protocol: HTTPS + hostname: jenkins.midnightthoughts.space + port: 443 + allowedRoutes: + namespaces: + from: All + tls: + mode: Terminate + certificateRefs: + - kind: Secret + name: jenkins.midnightthoughts.space-tls - name: http protocol: HTTP port: 80 diff --git a/apps/talos_cluster/jenkins/helm-repository.yaml b/apps/talos_cluster/jenkins/helm-repository.yaml @@ -0,0 +1,8 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: jenkins-operator + namespace: jenkins +spec: + interval: 1h + url: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart diff --git a/apps/talos_cluster/jenkins/jenkins-instance.yaml b/apps/talos_cluster/jenkins/jenkins-instance.yaml @@ -0,0 +1,284 @@ +apiVersion: jenkins.io/v1alpha2 +kind: Jenkins +metadata: + name: jenkins + namespace: jenkins +spec: + # Enable security validation + validateSecurityWarnings: true + # Configuration as Code + configurationAsCode: + configurations: + - name: jenkins-casc + content: ENC[AES256_GCM,data:lmtOI2KiZWTwq4H6oBcu0syAe9K0Zc+VQ8NhIHXmStzyGtPrlfvDZCxp2nJ6v5FZIsr7kcue+mnbtYpCFeFv1amYmqs1HDPnh/eTePt6/NAP9onaTzHtzGlVwl6gNr/5kXYZJO0dxVELHqejGwREAOyCY2+Ld1eip1UEKii0WfJAYKk1diD927YN2OKDbSv/aCI3XeLEtV9TbUCZojoazZSbfrTNwhx8XFA5D5OgQVFKCHvhOxLjAY5F4G66km5FlMGksJFcEMhpWvtT+H124RfcB5gmJalXQmhLZMocZvcHcXyDX1Ox10T/WP07be7I2lQttDi8l6rHF3cssTzL5Opw1XuJkHG3gmXoVD76Tf261vFJLUDe8FfcfDxcW3wyZvSljCJsAZ39Lrbwj76sFA1YiA7mS8EPEbR9MNWY5N7al6pIB4jShupFf7TnmcgKrNxopOlZSP40qWXH4QrGgihwF01KBuyKGV9D/5P61V9AY7TBGpYK+jTGTYKm+fvgJ2PZC+tYwcHD+9VyG0agCBTBZNM/R1TqCu5QzOdj9SJHlOM4otbZxsE/zHMZYlQVzBTlu1uNJPYNsfxsqJRyfX8zBGZsJ1kTRonYacUhE2LGopqkVvs0lOa5WHkMIsxPjPFzViDcjp6+0DGdXqii7molz84vwB+gGoPLSXwnfGCHcjXDmsNiASD4wrbDXJ4n/Ug0ch/r7sa7SonX/UIHHga7pLOFnZJw6V4QwDAv9nZh3MC4CowZxIjgCcSCewXVvt5jvak9LygapZIgdT+qR9KcSS2iOJlPyBG9JBPQP94hU2M9KafmHE1e01qxyBqptosbh4PpkVlUjrFgDtXC6qJQw43HgAyXoII2GJCHd5M+/WuCuxdSTkzVLV0ZHcF0aSKQcFIbNnuFGcbDmFflX2mha/qeeKbGRM2ieOTn7EqfPLMHmouPYlE8QwkxmZYSy6FMOjMWrSg/Bgu3S/5DGPvFTcv1KeWwUScJ7dxiOH/ujQee5NJ/mrZ4Hyl5TMlqQU0i9K87pDte7s0JXy0Gkdl6t4uttFlRSrOFNHrKDvg32ePBqPKk1CVmhnZw9edjA2dBbdhIGGHalXOkkqVFcOYCjQgfJxD+9zH3vozGDdfs1n/BQQxcvB1CbBNWWEjWgP5VCer0PVG1qA7SjcF9YUL/Qbd5j7a/5/UjqDyZnEp7ztnUkuqUn5ySTiWut/VRbuf1diDOliyeTmOgOJ+sMcMFTIt28Def1sirHlVmDFMO,iv:D6oladjgKIpT/F7H542ciASjAkz9OhdZDxUb5RPXNVQ=,tag:JN/gUMq+qwhh0Q+PgTFc9A==,type:str] + # API settings - IMPORTANT: jenkins-operator user must have admin rights + jenkinsAPISettings: + authorizationStrategy: createUser + # Service configuration + service: + type: ClusterIP + port: 8080 + slaveService: + type: ClusterIP + port: 50000 + # Master/Controller pod specification + master: + # Use specific LTS version instead of latest (best practice) + image: jenkins/jenkins:2.541.3-lts + imagePullPolicy: IfNotPresent + # Security context - run as jenkins user (1000) + securityContext: + runAsUser: 1000 + fsGroup: 1000 + # Disable CSRF protection is not recommended - keep enabled (default) + disableCSRFProtection: false + # Annotations and labels + annotations: + description: Jenkins instance for multi-arch container builds + labels: + app: jenkins + version: lts + # Base plugins (required by operator) + basePlugins: + - name: kubernetes + version: 4423.vb_59f230b_ce53 + - name: workflow-job + version: 1573.v1465f6f78810 + - name: workflow-aggregator + version: 608.v67378e9d3db_1 + - name: git + version: 5.10.1 + - name: job-dsl + version: 3654.vdf58f53e2d15 + - name: configuration-as-code + version: 2065.v7a_20a_b_d84088 + - name: kubernetes-credentials-provider + version: 1.303.vdfcf47fb_b_fef + # Additional plugins for our use case + plugins: + - name: oic-auth + version: 4.668.v653c6b_c6cb_f5 + - name: matrix-auth + version: 3.2.9 + - name: pipeline-stage-view + version: "2.39" + - name: generic-webhook-trigger + version: 2.4.1 + - name: timestamper + version: "1.30" + - name: ansicolor + version: 536.v13fa_b_860c267 + - name: docker-workflow + version: 634.vedc7242b_eda_7 + # Container specification + containers: + - name: jenkins-master + image: jenkins/jenkins:2.440.1-lts + imagePullPolicy: IfNotPresent + # Security context for container + securityContext: + # Allow privileged for Docker socket access + privileged: true + allowPrivilegeEscalation: true + # Environment variables + env: + - name: JAVA_OPTS + value: -Djenkins.install.runSetupWizard=false -Djenkins.model.Jenkins.crumbIssuerProxyCompatibility=true -Dorg.jenkinsci.plugins.matrixauth.inheritance.InheritParentStrategy=true + # Liveness probe + livenessProbe: + failureThreshold: 12 + httpGet: + path: /login + port: 8080 + scheme: HTTP + initialDelaySeconds: 100 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + # Readiness probe + readinessProbe: + failureThreshold: 10 + httpGet: + path: /login + port: 8080 + scheme: HTTP + initialDelaySeconds: 80 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + # Resource management + resources: + limits: + cpu: 1500m + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi + # Port configuration + ports: + - containerPort: 8080 + name: http + protocol: TCP + - containerPort: 50000 + name: agent + protocol: TCP + # Volume mounts + volumeMounts: + - name: jenkins-home + mountPath: /var/jenkins_home + - name: registry-secret + mountPath: /var/run/secrets/docker.io + readOnly: true + - name: cosign-key + mountPath: /var/run/secrets/cosign + readOnly: true + - name: docker-sock + mountPath: /var/run/docker.sock + # Volumes + volumes: + - name: jenkins-home + persistentVolumeClaim: + claimName: jenkins-home + - name: registry-secret + secret: + secretName: ENC[AES256_GCM,data:7USvSu9F1aAzUvE5GsVwJJVhwAg=,iv:gjniozAMy7KJbN92QTUz/dF1GJxd4cCNMry0foTi/ig=,tag:b1j7RzItnt+Ck+gmnBBgIQ==,type:str] + defaultMode: ENC[AES256_GCM,data:XRRC,iv:OhIgPF2mFh3kvms/rH58YeL2pmYUeWCSO7PDuhZpUZE=,tag:M77Kj3TEHZ0/ZOClsCF2xA==,type:int] + - name: cosign-key + secret: + secretName: ENC[AES256_GCM,data:ikUpHd2Wf3Xrc6l6C6Q15cJF,iv:kyJMlr5Mt0zHnQF2zrxZOgtGrEcg9F1PW5mav2OCgTE=,tag:vVnYPpGRWVljMbfaKos8qA==,type:str] + defaultMode: ENC[AES256_GCM,data:d958,iv:yEtCjaXo2Ai0ARBYIT+zCNdlkgMgRI3WO5iy1VEMNn4=,tag:0t/3muHtG//KomxrpmTQyQ==,type:int] + - name: docker-sock + hostPath: + path: /var/run/docker.sock + type: Socket +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByOWRrKzUrSUxXUlhSdTlY + MkdYM0dOZ0JNaXU0cmp3MS9PcHR1LzJSN1dJCmhGYmw4TGVPNEpEWnlnQlV2Yjhh + Vi8yK21xZjBldXduWXhNZ3hNSFoyY1kKLS0tIGR5L1FWS2FxYkhHR3JWcXBFTjEr + dHkrRVI5c3FBeUxFL2ZyL09Sd2hIZ3cKsDbe8WLlZXSTWpKKY5dx21cEKOxFFtw+ + 3DUtEJqIOAYdgxoFv/+Z4E44VtzLuA0swPk3DzY+bPvax31vZMdYkg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-04-09T20:54:47Z" + mac: ENC[AES256_GCM,data:Q1tSbclL62fLqa+FB1H6eFGqclWSkdVYTiOvnj8nJrWQxd1OGv/VVmTK6CRHpQKDJhro0H163X/Rmw2pUrw0DC30DAjbq+DxRDpYTr8BEcDT/u7mb1xNC093fSPcdRMvnOK+Jbq7Inv9XwlMAoG3NlNqNEgnInYxG10AnW9O4J4=,iv:xtZpt0c4mbh0XdDyOjwkwGZWD9ESycr8GyHptLfTp0M=,tag:pQVI7DcO0RidAoIUDa7oZw==,type:str] + pgp: [] + encrypted_regex: ^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret|content)$ + version: 3.9.1 +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: jenkins-home + namespace: jenkins +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: longhorn-2replicas +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByOWRrKzUrSUxXUlhSdTlY + MkdYM0dOZ0JNaXU0cmp3MS9PcHR1LzJSN1dJCmhGYmw4TGVPNEpEWnlnQlV2Yjhh + Vi8yK21xZjBldXduWXhNZ3hNSFoyY1kKLS0tIGR5L1FWS2FxYkhHR3JWcXBFTjEr + dHkrRVI5c3FBeUxFL2ZyL09Sd2hIZ3cKsDbe8WLlZXSTWpKKY5dx21cEKOxFFtw+ + 3DUtEJqIOAYdgxoFv/+Z4E44VtzLuA0swPk3DzY+bPvax31vZMdYkg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-04-09T20:54:47Z" + mac: ENC[AES256_GCM,data:Q1tSbclL62fLqa+FB1H6eFGqclWSkdVYTiOvnj8nJrWQxd1OGv/VVmTK6CRHpQKDJhro0H163X/Rmw2pUrw0DC30DAjbq+DxRDpYTr8BEcDT/u7mb1xNC093fSPcdRMvnOK+Jbq7Inv9XwlMAoG3NlNqNEgnInYxG10AnW9O4J4=,iv:xtZpt0c4mbh0XdDyOjwkwGZWD9ESycr8GyHptLfTp0M=,tag:pQVI7DcO0RidAoIUDa7oZw==,type:str] + pgp: [] + encrypted_regex: ^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret|content)$ + version: 3.9.1 +--- +apiVersion: v1 +kind: Service +metadata: + name: jenkins + namespace: jenkins +spec: + type: ClusterIP + selector: + jenkins.io/instance: jenkins + ports: + - port: 8080 + targetPort: 8080 + name: http + protocol: TCP + - port: 50000 + targetPort: 50000 + name: agent + protocol: TCP +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByOWRrKzUrSUxXUlhSdTlY + MkdYM0dOZ0JNaXU0cmp3MS9PcHR1LzJSN1dJCmhGYmw4TGVPNEpEWnlnQlV2Yjhh + Vi8yK21xZjBldXduWXhNZ3hNSFoyY1kKLS0tIGR5L1FWS2FxYkhHR3JWcXBFTjEr + dHkrRVI5c3FBeUxFL2ZyL09Sd2hIZ3cKsDbe8WLlZXSTWpKKY5dx21cEKOxFFtw+ + 3DUtEJqIOAYdgxoFv/+Z4E44VtzLuA0swPk3DzY+bPvax31vZMdYkg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-04-09T20:54:47Z" + mac: ENC[AES256_GCM,data:Q1tSbclL62fLqa+FB1H6eFGqclWSkdVYTiOvnj8nJrWQxd1OGv/VVmTK6CRHpQKDJhro0H163X/Rmw2pUrw0DC30DAjbq+DxRDpYTr8BEcDT/u7mb1xNC093fSPcdRMvnOK+Jbq7Inv9XwlMAoG3NlNqNEgnInYxG10AnW9O4J4=,iv:xtZpt0c4mbh0XdDyOjwkwGZWD9ESycr8GyHptLfTp0M=,tag:pQVI7DcO0RidAoIUDa7oZw==,type:str] + pgp: [] + encrypted_regex: ^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret|content)$ + version: 3.9.1 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: jenkins + namespace: jenkins +spec: + parentRefs: + - name: envoy-gateway + namespace: envoy-gateway + hostnames: + - jenkins.midnightthoughts.space + rules: + - backendRefs: + - name: jenkins + port: 8080 + timeouts: + request: 600s + backendRequest: 0s +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByOWRrKzUrSUxXUlhSdTlY + MkdYM0dOZ0JNaXU0cmp3MS9PcHR1LzJSN1dJCmhGYmw4TGVPNEpEWnlnQlV2Yjhh + Vi8yK21xZjBldXduWXhNZ3hNSFoyY1kKLS0tIGR5L1FWS2FxYkhHR3JWcXBFTjEr + dHkrRVI5c3FBeUxFL2ZyL09Sd2hIZ3cKsDbe8WLlZXSTWpKKY5dx21cEKOxFFtw+ + 3DUtEJqIOAYdgxoFv/+Z4E44VtzLuA0swPk3DzY+bPvax31vZMdYkg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-04-09T20:54:47Z" + mac: ENC[AES256_GCM,data:Q1tSbclL62fLqa+FB1H6eFGqclWSkdVYTiOvnj8nJrWQxd1OGv/VVmTK6CRHpQKDJhro0H163X/Rmw2pUrw0DC30DAjbq+DxRDpYTr8BEcDT/u7mb1xNC093fSPcdRMvnOK+Jbq7Inv9XwlMAoG3NlNqNEgnInYxG10AnW9O4J4=,iv:xtZpt0c4mbh0XdDyOjwkwGZWD9ESycr8GyHptLfTp0M=,tag:pQVI7DcO0RidAoIUDa7oZw==,type:str] + pgp: [] + encrypted_regex: ^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret|content)$ + version: 3.9.1 diff --git a/apps/talos_cluster/jenkins/kustomization.yaml b/apps/talos_cluster/jenkins/kustomization.yaml @@ -0,0 +1,11 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +metadata: + name: jenkins + namespace: jenkins + +resources: + - namespace.yaml + - helm-repository.yaml + - operator-release.yaml + - jenkins-instance.yaml diff --git a/apps/talos_cluster/jenkins/namespace.yaml b/apps/talos_cluster/jenkins/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: jenkins diff --git a/apps/talos_cluster/jenkins/operator-release.yaml b/apps/talos_cluster/jenkins/operator-release.yaml @@ -0,0 +1,19 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: jenkins-operator + namespace: jenkins +spec: + interval: 1h + releaseName: jenkins-operator + chart: + spec: + chart: jenkins-operator + sourceRef: + kind: HelmRepository + name: jenkins-operator + namespace: jenkins + values: + # Disable default Jenkins instance - we'll create our own via CRD + jenkins: + enabled: false diff --git a/encrypt.sh b/encrypt.sh @@ -5,13 +5,13 @@ if [ -z "$1" ]; then # Encrypt apps/talos_cluster/externaldns/release.yaml as a whole sops --age=age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh \ --encrypt \ - --encrypted-regex '^(apiKey|appUserPassword|otelUserPassword|extraArgs|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials||pass|postgresPassword|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret)$' \ + --encrypted-regex '^(apiKey|appUserPassword|otelUserPassword|extraArgs|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials||pass|postgresPassword|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret|content)$' \ --in-place apps/talos_cluster/externaldns/release2.yaml else echo "Encrypting file: $1" sops --age=age1esjyg2qfy49awv0ptkzvpk425adczjr38m37w2mmcahzc4p8n54sll2nzh \ --encrypt \ - --encrypted-regex '^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret)$' \ + --encrypted-regex '^(apiKey|appUserPassword|otelUserPassword|harborAdminPassword|totpVaultKey|kimaiAppSecret|kimaiAdminPassword|GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|GITHUB_PRIVATE_KEY|woosh|root_password|rspamd_password|pgdb_password|matrix_access_token|pgdb_remote_url|hmac_secret_key|adminPassword|adminEmail|jenkinsAdminEmail|securityRealm|gerrit.config|routing_key|DATABASE_URL|SMTP_PASSWORD|SECRET_KEY_BASE|admin_password|extraCommands|key|clickhouseDatabaseURL|databaseURL|client_id|client_secret|secret_key_base|otp_secret|private_key|public_key|primaryKey|deterministicKey|keyDerivationSalt|token|clientId|secretKey|installationId|installationKey|uriOverride|adminToken.value|password.value|sql_password|erlangCookie|AUTHENTICATION_PASSWORD|ROOM_API_SECRET_KEY|adminPassword|configPassword|adminUser|configUser|MAIL_PASSWORD|APP_KEY|api_key|api_secret|keys|livekit_key|livekit_secret|secret_key|admin_pass|admin_email|mariadbPassword|mariadbRootPassword|privateKey|data|stringData|PASSWD|password|pass|postgresPassword|smtp_auth_password|addresses|smtp_auth_username|authorization_credentials|postgresqlPassword|redminePassword|smtpPassword|registration_shared_secret|shared_secret|secret|admin_token|integrationKey|integration_key|rootPassword|adminPassword|adminUser|adminEmail|emailPassword|secretKey|appId|clientSecret|webhookSecret|content)$' \ --in-place "$1" fi