Skip to content

Commit

Permalink
feat(RELEASE-1158): introduce reduce-snapshot
Browse files Browse the repository at this point in the history
- This PR contains a StepAction and a new Task.
- Both are designed to reduce a Snapshot to a Single Component
  such that the Snapshot can be passed downstream to other tasks
- The StepAction will also be shared and used with the
  Enterprise Contract pipeline that is used for EC Integration
  Test Scenario
- Initially, the plan was to place the StepAction within the
  collect-data task, but due to
  tektoncd/pipeline#8255
  it needs to be part of a separate Task.

Signed-off-by: Scott Hebert <[email protected]>
  • Loading branch information
scoheb committed Sep 12, 2024
1 parent 9a9b19d commit e33473f
Show file tree
Hide file tree
Showing 11 changed files with 753 additions and 0 deletions.
13 changes: 13 additions & 0 deletions stepactions/reduce-snapshot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# reduce-snapshot-action

StepAction that reduces a snapshot to a single component based on the component that the snapshot was built for.

## Parameters

| Name | Description | Optional | Default value |
|---------------------------|----------------------------------------------|----------|---------------|
| IMAGES | String representation of Snapshot | No | - |
| SINGLE_COMPONENT | Single component enabled | No | - |
| CUSTOM_RESOURCE | Custom Resource to query for built Snapshot | No | - |
| CUSTOM_RESOURCE_NAMESPACE | Namespace where Custom Resource is found | Yes | "" |
| SNAPSHOT_PATH | The location to place the reduced Snapshot | No | - |
89 changes: 89 additions & 0 deletions stepactions/reduce-snapshot/reduce-snapshot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
apiVersion: tekton.dev/v1beta1
kind: StepAction
metadata:
name: reduce-snapshot-action
spec:
image: quay.io/konflux-ci/release-service-utils:12ba7676031d956761ebcb1d7254e766d045167e
params:
- name: SNAPSHOT
type: string
- name: SINGLE_COMPONENT
type: string
- name: CUSTOM_RESOURCE
type: string
- name: CUSTOM_RESOURCE_NAMESPACE
type: string
default: ""
- name: SNAPSHOT_PATH
type: string
env:
- name: SNAPSHOT
value: $(params.SNAPSHOT)
- name: SINGLE_COMPONENT
value: $(params.SINGLE_COMPONENT)
- name: CUSTOM_RESOURCE
value: $(params.CUSTOM_RESOURCE)
- name: CUSTOM_RESOURCE_NAMESPACE
value: $(params.CUSTOM_RESOURCE_NAMESPACE)
- name: SNAPSHOT_PATH
value: $(params.SNAPSHOT_PATH)
results:
- name: snapshotCreationComponent
description: Name of component that caused this Snapshot to be built.
script: |
#!/usr/bin/env bash
set -eux
echo "Single Component mode? ${SINGLE_COMPONENT}"
if [ "${SINGLE_COMPONENT}" == "true" ]; then
CR_NAMESPACE_ARG=
if [ -n "${CUSTOM_RESOURCE_NAMESPACE}" ]; then
CR_NAMESPACE_ARG="-n ${CUSTOM_RESOURCE_NAMESPACE}"
fi
SNAPSHOT_CREATION_TYPE=$(kubectl get "$CUSTOM_RESOURCE" ${CR_NAMESPACE_ARG:+$CR_NAMESPACE_ARG} -ojson \
| jq -r '.metadata.labels."test.appstudio.openshift.io/type" // ""')
SNAPSHOT_CREATION_COMPONENT=$(kubectl get "$CUSTOM_RESOURCE" ${CR_NAMESPACE_ARG:+$CR_NAMESPACE_ARG} -ojson \
| jq -r '.metadata.labels."appstudio.openshift.io/component" // ""')
echo "SNAPSHOT_CREATION_TYPE: ${SNAPSHOT_CREATION_TYPE}"
echo "SNAPSHOT_CREATION_COMPONENT: ${SNAPSHOT_CREATION_COMPONENT}"
if [ "${SNAPSHOT_CREATION_TYPE}" == "component" ] && [ "${SNAPSHOT_CREATION_COMPONENT}" != "" ]; then
echo "Single Component mode is ${SINGLE_COMPONENT} and Snapshot type is component"
# verify if in json form
set +e
echo "${SNAPSHOT}" | jq -e > /dev/null 2>&1
CHECK_JSON=$?
set -e
if [ "${CHECK_JSON}" != "0" ]; then
# try to load as file first
set +e
jq -e < "${SNAPSHOT}" > /dev/null 2>&1
CHECK_JSON_FILE=$?
set -e
if [ "${CHECK_JSON_FILE}" != "0" ]; then
echo "Cannot load snapshot from json string or file"
exit 1
fi
SNAPSHOT=$(cat "${SNAPSHOT}")
fi
REDUCED_SNAPSHOT=$(echo "${SNAPSHOT}" | jq --arg component "${SNAPSHOT_CREATION_COMPONENT}" \
'del(.components[] | select(.name != $component))')
## make sure we still have 1 component
COMPONENT_COUNT=$(echo "$REDUCED_SNAPSHOT" | jq -r '[ .components[] ] | length')
echo "COMPONENT_COUNT: ${COMPONENT_COUNT}"
if [ "${COMPONENT_COUNT}" != "1" ] ; then
echo "Error: Reduced Snapshot has ${COMPONENT_COUNT} components. It should contain 1"
echo " Verify that the Snapshot contains the built component: ${SNAPSHOT_CREATION_COMPONENT}"
exit 1
fi
echo "Reducing Snapshot to:"
echo "$REDUCED_SNAPSHOT" | jq .
SNAPSHOT=$(echo "$REDUCED_SNAPSHOT" | tr -d ' ' | tr -d '\n')
echo "$SNAPSHOT" > "${SNAPSHOT_PATH}"
echo -n "${SNAPSHOT_CREATION_COMPONENT}" | tee "$(step.results.snapshotCreationComponent.path)"
fi
fi
15 changes: 15 additions & 0 deletions tasks/reduce-snapshot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# reduce-snapshot

Tekton task to reduce a snapshot to a single component based on the component that the snapshot was built for.

It uses the `reduce-snapshot-action` StepAction to perform the reduction.

## Parameters

| Name | Description | Optional | Default value |
|----------------------------|----------------------------------------------|----------|---------------|
| IMAGES | String representation of Snapshot | No | - |
| SINGLE_COMPONENT | Single component enabled | No | - |
| CUSTOM_RESOURCE | Custom Resource to query for built Snapshot | No | - |
| CUSTOM_RESOURCE_NAMESPACE | Namespace where Custom Resource is found | No | - |
| SNAPSHOT_PATH | The location to place the reduced Snapshot | No | - |
50 changes: 50 additions & 0 deletions tasks/reduce-snapshot/reduce-snapshot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: reduce-snapshot
labels:
app.kubernetes.io/version: "0.0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: release
spec:
description: >-
Tekton task to reduce snapshot
params:
- name: SNAPSHOT
type: string
- name: SINGLE_COMPONENT
type: string
- name: CUSTOM_RESOURCE
type: string
- name: CUSTOM_RESOURCE_NAMESPACE
type: string
default: ""
- name: SNAPSHOT_PATH
type: string
workspaces:
- name: data
description: Workspace to save the CR jsons to
steps:
- name: reduce
params:
- name: SNAPSHOT
value: $(params.SNAPSHOT)
- name: SINGLE_COMPONENT
value: $(params.SINGLE_COMPONENT)
- name: CUSTOM_RESOURCE
value: $(params.CUSTOM_RESOURCE)
- name: CUSTOM_RESOURCE_NAMESPACE
value: $(params.CUSTOM_RESOURCE_NAMESPACE)
- name: SNAPSHOT_PATH
value: $(params.SNAPSHOT_PATH)
ref:
resolver: git
params:
- name: url
value: https://github.com/konflux-ci/release-service-catalog
- name: revision
value: main
- name: pathInRepo
value: stepactions/reduce-snapshot/reduce-snapshot.yaml
20 changes: 20 additions & 0 deletions tasks/reduce-snapshot/tests/pre-apply-task-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

# Install the CRDs so we can create/get them
.github/scripts/install_crds.sh

# Add RBAC so that the SA executing the tests can retrieve CRs
kubectl apply -f .github/resources/crd_rbac.yaml

# enable 'enable-step-actions' feature flag (already enabled in staging and production)
kubectl get cm/feature-flags -n tekton-pipelines -oyaml | \
sed 's/\(enable-step-actions: .*$\)/enable-step-actions: "true"/' | \
kubectl replace -f -

# install dependent stepaction
kubectl apply -f stepactions/reduce-snapshot/reduce-snapshot.yaml

# ensure local stepaction is used
TASK_PATH="$1"
yq -i 'del(.spec.steps[0].ref)' "$TASK_PATH"
yq -i '.spec.steps[0].ref.name = "reduce-snapshot-action"' "$TASK_PATH"
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: test-reduce-snapshot-disabled-single-component-mode
spec:
description: |
Run the reduce snapshot task with single component mode being false
workspaces:
- name: tests-workspace
tasks:
- name: setup
taskSpec:
steps:
- name: create-crs
image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f
script: |
#!/usr/bin/env bash
set -eux
cat > snapshot << EOF
apiVersion: appstudio.redhat.com/v1alpha1
kind: Snapshot
metadata:
name: snapshot-sample
namespace: default
spec:
application: foo
components:
- name: scott
containerImage: newimage
- name: tom
containerImage: newimage2
EOF
kubectl apply -f snapshot
kubectl get snapshot/snapshot-sample -ojson | jq .spec | tee "$(workspaces.data.path)/snapshot.json"
workspaces:
- name: data
workspace: tests-workspace
- name: run-task
taskRef:
name: reduce-snapshot
params:
- name: SNAPSHOT
value: $(workspaces.data.path)/snapshot.json
- name: SINGLE_COMPONENT
value: false
- name: CUSTOM_RESOURCE
value: snapshot/snapshot-sample
- name: CUSTOM_RESOURCE_NAMESPACE
value: default
- name: SNAPSHOT_PATH
value: $(workspaces.data.path)/snapshot.json
runAfter:
- setup
workspaces:
- name: data
workspace: tests-workspace
- name: check-result
workspaces:
- name: data
workspace: tests-workspace
runAfter:
- run-task
taskSpec:
workspaces:
- name: data
steps:
- name: check-result
image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f
script: |
#!/usr/bin/env bash
set -eux
cat "$(workspaces.data.path)/snapshot.json"
if [ "$(jq '.components | length' < "$(workspaces.data.path)/snapshot.json")" -ne 2 ]; then
echo "ERROR: Resulting snapshot does not contain 2 components"
exit 1
fi
finally:
- name: cleanup
taskSpec:
steps:
- name: delete-crs
image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f
script: |
#!/usr/bin/env sh
set -eux
kubectl delete snapshot snapshot-sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: test-reduce-snapshot-missing-resources
spec:
description: |
Run the reduce task to reduce to a single component but CR to query is missing
workspaces:
- name: tests-workspace
tasks:
- name: setup
taskSpec:
steps:
- name: create-crs
image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f
script: |
#!/usr/bin/env bash
set -eux
cat > snapshot << EOF
apiVersion: appstudio.redhat.com/v1alpha1
kind: Snapshot
metadata:
name: snapshot-sample
namespace: default
labels:
test.appstudio.openshift.io/type: component
appstudio.openshift.io/component: tom
spec:
application: foo
components:
- name: scott
containerImage: newimage
- name: tom
containerImage: newimage2
EOF
kubectl apply -f snapshot
kubectl get snapshot/snapshot-sample -ojson | jq .spec | tee "$(workspaces.data.path)/snapshot.json"
workspaces:
- name: data
workspace: tests-workspace
- name: run-task
taskRef:
name: reduce-snapshot
params:
- name: SNAPSHOT
value: $(workspaces.data.path)/snapshot.json
- name: SINGLE_COMPONENT
value: true
- name: CUSTOM_RESOURCE
value: snapshot/snapshot-unknown
- name: CUSTOM_RESOURCE_NAMESPACE
value: default
- name: SNAPSHOT_PATH
value: $(workspaces.data.path)/snapshot.json
runAfter:
- setup
workspaces:
- name: data
workspace: tests-workspace
- name: check-result
workspaces:
- name: data
workspace: tests-workspace
runAfter:
- run-task
taskSpec:
workspaces:
- name: data
steps:
- name: check-result
image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f
script: |
#!/usr/bin/env bash
set -eux
cat "$(workspaces.data.path)/snapshot.json"
if [ "$(jq '.components | length' < "$(workspaces.data.path)/snapshot.json")" -ne 2 ]; then
echo "ERROR: Resulting snapshot does not contain 2 components"
exit 1
fi
finally:
- name: cleanup
taskSpec:
steps:
- name: delete-crs
image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f
script: |
#!/usr/bin/env sh
set -eux
kubectl delete snapshot snapshot-sample
Loading

0 comments on commit e33473f

Please sign in to comment.