Skip to content

Commit 96cd1e5

Browse files
Authorclaude
authored andcommitted
feat(ISV-7115): add rh-direct-sign-image task
New task for signing images using the direct signing method, which will replace rh-sign-image that goes through Radas. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Ales Raszka <araszka@redhat.com>
1 parent 502b9fa commit 96cd1e5

6 files changed

Lines changed: 586 additions & 0 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# rh-direct-sign-image
2+
3+
Task to create internalrequests to directly sign snapshot components
4+
5+
## Parameters
6+
7+
| Name | Description | Optional | Default value |
8+
|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------------------------------------------------|
9+
| snapshotPath | Path to the JSON string of the mapped Snapshot spec in the data workspace | No | - |
10+
| dataPath | Path to the JSON string of the merged data to use in the data workspace | No | - |
11+
| requester | Name of the user that requested the signing, for auditing purposes | No | - |
12+
| requestTimeout | InternalRequest timeout | Yes | 1800 |
13+
| concurrentLimit | The maximum number of signing requests to run in parallel | Yes | 8 |
14+
| pipelineRunUid | The uid of the current pipelineRun. Used as a label value when creating internal requests | No | - |
15+
| pyxisServer | The server type to use. Options are 'production','production-internal,'stage-internal' and 'stage' | Yes | production |
16+
| pyxisSecret | The kubernetes secret to use to authenticate to Pyxis. It needs to contain two keys: key and cert | No | - |
17+
| batchLimit | size of batch attributes to send to internal-request. As internal request arguments are need to be strings, size here represent maximal string length of `references` and `manifest_digests` sent to internal request | Yes | 15000 |
18+
| signRegistryAccessPath | The relative path in the workspace to a text file that contains a list of repositories that needs registry.access.redhat.com image references to be signed (i.e. requires_terms=true), one repository string per line, e.g. "rhtas/cosign-rhel9" | No | - |
19+
| ociStorage | The OCI repository where the Trusted Artifacts are stored | Yes | empty |
20+
| ociArtifactExpiresAfter | Expiration date for the trusted artifacts created in the OCI repository. An empty string means the artifacts do not expire | Yes | 1d |
21+
| trustedArtifactsDebug | Flag to enable debug logging in trusted artifacts. Set to a non-empty string to enable | Yes | "" |
22+
| orasOptions | oras options to pass to Trusted Artifacts calls | Yes | "" |
23+
| sourceDataArtifact | Location of trusted artifacts to be used to populate data directory | Yes | "" |
24+
| dataDir | The location where data will be stored | Yes | /var/workdir/release |
25+
| taskGitUrl | The url to the git repo where the release-service-catalog tasks and stepactions to be used are stored | No | - |
26+
| taskGitRevision | The revision in the taskGitUrl repo to be used | No | - |
27+
| signingRepo | Git repository URL containing the signing tasks | Yes | https://gitlab.cee.redhat.com/signing/signing.git |
28+
| signingRevision | Git revision (branch, tag, or commit) in the signing repository | Yes | main |
29+
| signPipeline | Name of the internal pipeline to use for container signing | Yes | container-signing |
30+
| signPipelineServiceAccount | Service account to use for the signing pipeline | Yes | signing-pipeline-sa |
31+
| pipelineImage | The image to use for the signing pipeline | Yes | quay.io/konflux-ci/signing:latest |
32+
| caTrustConfigMapName | The name of the ConfigMap to read CA bundle data from | Yes | trusted-ca |
33+
| caTrustConfigMapKey | The name of the key in the ConfigMap that contains the CA bundle data | Yes | ca-bundle.crt |
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
---
2+
apiVersion: tekton.dev/v1
3+
kind: Task
4+
metadata:
5+
name: rh-direct-sign-image
6+
annotations:
7+
tekton.dev/pipelines.minVersion: "0.12.1"
8+
tekton.dev/tags: release
9+
spec:
10+
description: |-
11+
Task to create internalrequests to directly sign snapshot components
12+
params:
13+
- name: snapshotPath
14+
description: Path to the JSON string of the mapped Snapshot spec in the data workspace
15+
type: string
16+
- name: dataPath
17+
description: Path to the JSON string of the merged data to use in the data workspace
18+
type: string
19+
- name: requester
20+
type: string
21+
description: Name of the user that requested the signing, for auditing purposes
22+
- name: requestTimeout
23+
type: string
24+
default: "1800"
25+
description: InternalRequest timeout
26+
- name: concurrentLimit
27+
type: string
28+
description: The maximum number of signing requests to run in parallel
29+
default: 8
30+
- name: pipelineRunUid
31+
type: string
32+
description: >-
33+
The uid of the current pipelineRun. Used as a label value when creating internal requests
34+
- name: pyxisServer
35+
type: string
36+
description: >-
37+
The server type to use. Options are 'production','production-internal,'stage-internal' and 'stage'
38+
default: production
39+
- name: pyxisSecret
40+
type: string
41+
description: |
42+
The kubernetes secret to use to authenticate to Pyxis. It needs to contain two keys: key and cert
43+
- name: batchLimit
44+
type: string
45+
description: |
46+
size of batch attributes to send to internal-request. As internal request arguments are need to be
47+
strings, size here represent maximal string length of `references` and `manifest_digests` sent to
48+
internal request
49+
default: 15000
50+
- name: signRegistryAccessPath
51+
type: string
52+
description: |
53+
The relative path in the workspace to a text file that contains a list of repositories
54+
that needs registry.access.redhat.com image references to be signed (i.e.
55+
requires_terms=true), one repository string per line, e.g. "rhtas/cosign-rhel9"
56+
- name: ociStorage
57+
description: The OCI repository where the Trusted Artifacts are stored
58+
type: string
59+
default: "empty"
60+
- name: ociArtifactExpiresAfter
61+
description: Expiration date for the trusted artifacts created in the
62+
OCI repository. An empty string means the artifacts do not expire
63+
type: string
64+
default: "1d"
65+
- name: trustedArtifactsDebug
66+
description: >-
67+
Flag to enable debug logging in trusted artifacts. Set to a non-empty string to enable
68+
type: string
69+
default: ""
70+
- name: orasOptions
71+
description: oras options to pass to Trusted Artifacts calls
72+
type: string
73+
default: ""
74+
- name: sourceDataArtifact
75+
type: string
76+
description: Location of trusted artifacts to be used to populate data directory
77+
default: ""
78+
- name: dataDir
79+
description: The location where data will be stored
80+
type: string
81+
default: /var/workdir/release
82+
- name: taskGitUrl
83+
type: string
84+
description: >-
85+
The url to the git repo where the release-service-catalog tasks and stepactions to be used are stored
86+
- name: taskGitRevision
87+
type: string
88+
description: The revision in the taskGitUrl repo to be used
89+
- name: signingRepo
90+
type: string
91+
description: Git repository URL containing the signing tasks
92+
default: "https://gitlab.cee.redhat.com/signing/signing.git"
93+
- name: signingRevision
94+
type: string
95+
description: Git revision (branch, tag, or commit) in the signing repository
96+
default: "main"
97+
- name: signPipeline
98+
type: string
99+
description: Name of the internal pipeline to use for container signing
100+
default: "container-signing"
101+
- name: signPipelineServiceAccount
102+
type: string
103+
description: Service account to use for the signing pipeline
104+
default: "signing-pipeline-sa"
105+
- name: pipelineImage
106+
type: string
107+
description: The image to use for the signing pipeline
108+
default: quay.io/konflux-ci/signing:latest
109+
- name: caTrustConfigMapName
110+
type: string
111+
description: The name of the ConfigMap to read CA bundle data from
112+
default: trusted-ca
113+
- name: caTrustConfigMapKey
114+
type: string
115+
description: The name of the key in the ConfigMap that contains the CA bundle data
116+
default: ca-bundle.crt
117+
results:
118+
- description: Produced trusted data artifact
119+
name: sourceDataArtifact
120+
type: string
121+
volumes:
122+
- name: workdir
123+
emptyDir: {}
124+
- name: pyxis-secret-vol
125+
secret:
126+
secretName: $(params.pyxisSecret)
127+
defaultMode: 0444
128+
- name: trusted-ca
129+
configMap:
130+
name: $(params.caTrustConfigMapName)
131+
items:
132+
- key: $(params.caTrustConfigMapKey)
133+
path: ca-bundle.crt
134+
optional: true
135+
136+
stepTemplate:
137+
volumeMounts:
138+
- mountPath: /var/workdir
139+
name: workdir
140+
- name: trusted-ca
141+
mountPath: /mnt/trusted-ca
142+
readOnly: true
143+
securityContext:
144+
runAsUser: 1001
145+
env:
146+
- name: IMAGE_EXPIRES_AFTER
147+
value: $(params.ociArtifactExpiresAfter)
148+
- name: "ORAS_OPTIONS"
149+
value: "$(params.orasOptions)"
150+
- name: "DEBUG"
151+
value: "$(params.trustedArtifactsDebug)"
152+
steps:
153+
- name: use-trusted-artifact
154+
computeResources:
155+
limits:
156+
memory: 64Mi
157+
cpu: 100m
158+
requests:
159+
memory: 64Mi
160+
cpu: 30m
161+
ref:
162+
resolver: "git"
163+
params:
164+
- name: url
165+
value: $(params.taskGitUrl)
166+
- name: revision
167+
value: $(params.taskGitRevision)
168+
- name: pathInRepo
169+
value: stepactions/use-trusted-artifact/use-trusted-artifact.yaml
170+
params:
171+
- name: workDir
172+
value: $(params.dataDir)
173+
- name: sourceDataArtifact
174+
value: $(params.sourceDataArtifact)
175+
176+
- name: sign-image
177+
# TODO: Change the image once the CLI is available in quay.io/konflux-ci/release-service-utils
178+
image: quay.io/konflux-ci/release-service-utils@sha256:3cb03b14ac9d90ff27070036ce2b50712e65aa285daeb28852254a745bb25dfc
179+
computeResources:
180+
limits:
181+
memory: 4Gi
182+
cpu: "2"
183+
requests:
184+
memory: 4Gi
185+
cpu: "2"
186+
volumeMounts:
187+
- name: pyxis-secret-vol
188+
mountPath: "/etc/secrets"
189+
env:
190+
- name: PYXIS_CERT_PATH
191+
value: /etc/secrets/cert
192+
- name: PYXIS_KEY_PATH
193+
value: /etc/secrets/key
194+
script: |
195+
#!/usr/bin/env bash
196+
set -eo pipefail
197+
198+
python rh_direct_sign_image.py \
199+
--pyxis-server "$(params.pyxisServer)" \
200+
--snapshot "$(params.dataDir)/$(params.snapshotPath)" \
201+
--data-file "$(params.dataDir)/$(params.dataPath)" \
202+
--sign-registry-access-file "$(params.dataDir)/$(params.signRegistryAccessPath)" \
203+
--batch-max-size "$(params.batchLimit)" \
204+
--requester "$(params.requester)" \
205+
--pipeline "$(params.signPipeline)" \
206+
--service-account "$(params.signPipelineServiceAccount)" \
207+
--request-timeout "$(params.requestTimeout)" \
208+
--task-id "$(context.taskRun.uid)" \
209+
--pipelinerun-uid "$(params.pipelineRunUid)" \
210+
--signing-repo "$(params.signingRepo)" \
211+
--signing-revision "$(params.signingRevision)" \
212+
--concurrent-limit "$(params.concurrentLimit)" \
213+
--pipeline-image "$(params.pipelineImage)" \
214+
--submit-requests
215+
216+
- name: create-trusted-artifact
217+
computeResources:
218+
limits:
219+
memory: 128Mi
220+
cpu: 500m
221+
requests:
222+
memory: 128Mi
223+
cpu: 250m
224+
ref:
225+
resolver: "git"
226+
params:
227+
- name: url
228+
value: "$(params.taskGitUrl)"
229+
- name: revision
230+
value: "$(params.taskGitRevision)"
231+
- name: pathInRepo
232+
value: stepactions/create-trusted-artifact/create-trusted-artifact.yaml
233+
params:
234+
- name: ociStorage
235+
value: $(params.ociStorage)
236+
- name: workDir
237+
value: $(params.dataDir)
238+
- name: sourceDataArtifact
239+
value: $(results.sourceDataArtifact.path)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
set -euxo pipefail
3+
4+
# mocks to be injected into task step scripts
5+
6+
function python() {
7+
if [[ "$1" == *"rh_direct_sign_image.py"* ]]; then
8+
echo "Mock rh_direct_sign_image.py called with: ${*:2}"
9+
echo "${*:2}" >> "$(params.dataDir)/mock_rh_direct_sign_image.txt"
10+
if [ -f "$(params.dataDir)/fail_rh_direct_sign_image" ]; then
11+
echo "Mock: simulating CLI failure"
12+
return 1
13+
fi
14+
else
15+
command python "$@"
16+
fi
17+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
#
4+
# Create a dummy pyxis secret (and delete it first if it exists)
5+
kubectl delete secret test-pyxis-image-cert --ignore-not-found
6+
kubectl create secret generic test-pyxis-image-cert --from-literal=cert=mycert --from-literal=key=mykey
7+
8+
# Add mocks to the beginning of task step script
9+
TASK_PATH="$1"
10+
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
11+
yq -i '.spec.steps[1].script = load_str("'"${SCRIPT_DIR}"'/mocks.sh") + .spec.steps[1].script' "$TASK_PATH"

0 commit comments

Comments
 (0)