diff --git a/services/jenkins/kustomization.yaml b/services/jenkins/kustomization.yaml index 5f3e0554..4e00efcb 100644 --- a/services/jenkins/kustomization.yaml +++ b/services/jenkins/kustomization.yaml @@ -18,6 +18,7 @@ resources: - deployment.yaml - service.yaml - ingress.yaml + - lesavka-userns-probe.yaml configMapGenerator: - name: jenkins-jcasc-revision diff --git a/services/jenkins/lesavka-userns-probe.yaml b/services/jenkins/lesavka-userns-probe.yaml new file mode 100644 index 00000000..03958421 --- /dev/null +++ b/services/jenkins/lesavka-userns-probe.yaml @@ -0,0 +1,56 @@ +# services/jenkins/lesavka-userns-probe.yaml +# Qualification only: never relax the compiler pod to bypass a failed gate. +apiVersion: batch/v1 +kind: Job +metadata: + name: lesavka-userns-probe-1 + namespace: jenkins +spec: + backoffLimit: 0 + activeDeadlineSeconds: 120 + template: + metadata: + labels: + atlas.bstein.dev/workload: lesavka-userns-probe + spec: + restartPolicy: Never + hostUsers: false + automountServiceAccountToken: false + enableServiceLinks: false + nodeSelector: + kubernetes.io/hostname: titan-22 + kubernetes.io/arch: amd64 + imagePullSecrets: + - name: harbor-bstein-robot + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + seccompProfile: + type: RuntimeDefault + containers: + - name: probe + image: registry.bstein.dev/bstein/lesavka-ci@sha256:7d3a2548ef0df8da053a2e2939675f5a3cf23e26517828e5fa9a3185911a8e75 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + resources: + requests: {cpu: 10m, memory: 32Mi} + limits: {cpu: 100m, memory: 64Mi, ephemeral-storage: 32Mi} + command: ["python3", "-I", "-c"] + args: + - | + import json, os + from pathlib import Path + maps = {name: [[int(v) for v in line.split()] for line in + Path('/proc/self/' + name).read_text().splitlines()] + for name in ('uid_map', 'gid_map')} + assert os.geteuid() == 1000 and os.getegid() == 1000 + for entries in maps.values(): + assert len(entries) == 1 + inside, outside, count = entries[0] + assert inside == 0 and outside >= 65536 and count >= 65536 + print(json.dumps({'pod_user_namespace': 'pass', 'maps': maps, + 'scope': 'outer mapping only; nested test namespaces unqualified'}))