apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/auto: "true"
    secret.reloader.stakater.com/reload: "vault-ca-cert"
  labels:
    app.kubernetes.io/component: puppetserver-compilers
    app.kubernetes.io/instance: puppetserver
    app.kubernetes.io/name: puppetserver
    app.kubernetes.io/version: 8.8.0
  name: puppetserver-compiler
  namespace: puppet
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: puppetserver-compilers
      app.kubernetes.io/name: puppetserver
  template:
    metadata:
      labels:
        app.kubernetes.io/component: puppetserver-compilers
        app.kubernetes.io/instance: puppetserver
        app.kubernetes.io/name: puppetserver
        app.kubernetes.io/version: 8.8.0
    spec:
      hostname: puppetserver-compiler
      imagePullSecrets: null
      containers:
      - name: puppetserver
        image: ghcr.io/openvoxproject/openvoxserver:8.8.0-main
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            cpu: 2
            memory: 3072Mi
          requests:
            cpu: 200m
            memory: 1024Mi
        ports:
        - containerPort: 8140
          name: puppetserver
        envFrom:
        - configMapRef:
            name: puppetserver-compiler-config
        env:
        - name: OPENVOXSERVER_HOSTNAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        livenessProbe:
          failureThreshold: 3
          periodSeconds: 30
          successThreshold: 1
          tcpSocket:
            port: 8140
          timeoutSeconds: 10
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /status/v1/simple
            port: 8140
            scheme: HTTPS
          periodSeconds: 60
          successThreshold: 1
          timeoutSeconds: 20
        securityContext:
          allowPrivilegeEscalation: false
          # Root entrypoint chowns baked-in dirs (CHOWN) then drops the JVM to
          # the puppet user via `runuser` (needs SETUID/SETGID). Cannot run
          # non-root: the image entrypoint requires a root start.
          capabilities:
            add:
            - CHOWN
            - DAC_OVERRIDE
            - FOWNER
            - SETGID
            - SETUID
            drop:
            - all
        startupProbe:
          failureThreshold: 30
          periodSeconds: 15
          tcpSocket:
            port: 8140
        volumeMounts:
        - mountPath: /etc/puppetlabs/code/
          name: puppet-code-volume
        - mountPath: /etc/puppetlabs/puppet/
          name: puppet-puppet-volume
        - mountPath: /var/lib/puppet/keys/
          name: eyaml-keys
          readOnly: true
        - mountPath: /opt/bin/
          name: puppet-shared-bins
        - mountPath: /opt/vault-ca-cert.crt
          name: vault-ca-cert
          subPath: ca.crt
        - mountPath: /docker-custom-entrypoint.d/post-startup/additional-ruby-gems.sh
          name: additional-ruby-gems
          subPath: additional-ruby-gems.sh
      initContainers:
      - name: copy-configmaps
        image: busybox:1.35
        command:
        - sh
        - -c
        args:
        - |
          echo "Copying configmap files to shared volume..."
          mkdir -p /etc/puppetlabs/puppet
          cp /configmaps/puppet.conf /etc/puppetlabs/puppet/puppet.conf
          cp /configmaps/puppetdb.conf /etc/puppetlabs/puppet/puppetdb.conf
          cp /configmaps/autosign.conf /etc/puppetlabs/puppet/autosign.conf
          echo "Configmap files copied successfully"
        volumeMounts:
        - mountPath: /etc/puppetlabs/puppet/
          name: puppet-puppet-volume
        - mountPath: /configmaps/puppet.conf
          name: compiler-puppet-conf
          subPath: puppet.conf
        - mountPath: /configmaps/puppetdb.conf
          name: compiler-puppetdb-conf
          subPath: puppetdb.conf
        - mountPath: /configmaps/autosign.conf
          name: compiler-autosign-conf
          subPath: autosign.conf

      - name: perms-and-dirs
        image: ghcr.io/openvoxproject/openvoxserver:8.8.0-main
        imagePullPolicy: IfNotPresent
        command:
        - sh
        - -c
        args:
        - |
          mkdir -p /etc/puppetlabs/puppet/eyaml/keys
          mkdir -p /etc/puppetlabs/code/environments
          mkdir -p /etc/puppetlabs/puppet/manifests
          chown -R puppet:puppet /etc/puppetlabs
          chown puppet:puppet /etc/puppetlabs/puppet/r10k.yaml
          mkdir -p /opt/puppetlabs/server/data/puppetserver/dropsonde/bin/
          touch /opt/puppetlabs/server/data/puppetserver/dropsonde/bin/dropsonde
          chown puppet:puppet -R /opt/puppetlabs/server/data/puppetserver/
        env:
        - name: PUPPETSERVER_JAVA_ARGS
          value: -Xms1024m -Xmx3072m -Dcom.sun.management.jmxremote.port=31000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
        resources:
          limits:
            cpu: 300m
            memory: 256Mi
          requests:
            cpu: 200m
            memory: 128Mi
        securityContext:
          runAsUser: 0
          runAsNonRoot: false
          allowPrivilegeEscalation: false
          # Runs as root to chown the mounted PVC dirs to puppet:puppet before
          # the main container starts (CHOWN); does not drop privileges itself.
          capabilities:
            add:
            - CHOWN
            - DAC_OVERRIDE
            - FOWNER
            drop:
            - all
        volumeMounts:
        - mountPath: /etc/puppetlabs/code/
          name: puppet-code-volume
        - mountPath: /etc/puppetlabs/puppet/
          name: puppet-puppet-volume

      - name: setup-shared-bins
        image: git.unkin.net/unkin/almalinux9-base:20260606
        command:
        - sh
        - -c
        args:
        - |
          set -e
          echo "Setting up shared binaries..."
          mkdir -p /opt/bin

          # Install the encapic ENC client (stdlib-only Go binary) to the shared
          # bin volume. It replaces the uv/python ENC script, whose
          # first-invocation dependency resolution failed on fresh compiler pods.
          ENCAPIC_VERSION=v0.1.0
          BASE=https://git.unkin.net/unkin/encapic/releases/download/$ENCAPIC_VERSION
          cd /tmp
          curl -fsSL -o encapic "$BASE/encapic_linux_amd64"
          curl -fsSL -o encapic.sha256 "$BASE/encapic_linux_amd64.sha256"
          # The published checksum names the release asset; verify against the
          # file we downloaded regardless of the recorded filename.
          EXPECTED=$(awk '{print $1}' encapic.sha256)
          echo "$EXPECTED  encapic" | sha256sum -c -
          install -m 0755 encapic /opt/bin/encapic

          echo "Shared binaries setup completed"
        volumeMounts:
        - mountPath: /opt/bin/
          name: puppet-shared-bins
      securityContext:
        fsGroup: 999
        seccompProfile:
          type: RuntimeDefault
      volumes:
      - name: puppet-code-volume
        persistentVolumeClaim:
          claimName: puppetserver-code-shared
      - name: puppet-puppet-volume
        persistentVolumeClaim:
          claimName: puppetserver-compiler-config-shared
      - name: eyaml-keys
        secret:
          secretName: eyaml-keys
          defaultMode: 0600
      - name: compiler-puppet-conf
        configMap:
          name: compiler-puppet.conf
      - name: compiler-puppetdb-conf
        configMap:
          name: compiler-puppetdb.conf
      - name: compiler-autosign-conf
        configMap:
          name: compiler-autosign.conf
      - name: puppet-shared-bins
        persistentVolumeClaim:
          claimName: puppet-shared-bins
      - name: vault-ca-cert
        secret:
          secretName: vault-ca-cert
      - name: additional-ruby-gems
        configMap:
          name: additional-ruby-gems
          defaultMode: 0755
  strategy:
    type: RollingUpdate
