Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,23 @@ tests:
- intranet
steps:
workflow: osac-project-cluster-tool-vmaas
- as: snapshot-vmaas
capabilities:
- intranet
cron: 0 2 * * *
steps:
cluster_profile: packet-assisted
env:
ASSISTED_CONFIG: |
OLM_OPERATORS=cnv,lvm
NUM_MASTERS=1
NUM_WORKERS=0
MASTER_MEMORY=65536
MASTER_DISK_COUNT=2
MASTER_DISK=200000000000
MASTER_CPU=24
OPENSHIFT_VERSION=4.20
workflow: osac-project-cluster-tool-snapshot-vmaas
- as: e2e-metal-vmaas-compute-instance-creation
capabilities:
- intranet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -679,3 +679,88 @@ periodics:
- name: result-aggregator
secret:
secretName: result-aggregator
- agent: kubernetes
cluster: build03
cron: 0 2 * * *
decorate: true
decoration_config:
sparse_checkout_files:
- Containerfile
extra_refs:
- base_ref: main
org: osac-project
repo: osac-test-infra
sparse_checkout_files:
- Containerfile
labels:
capability/intranet: intranet
ci-operator.openshift.io/cloud: packet-edge
ci-operator.openshift.io/cloud-cluster-profile: packet-assisted
ci.openshift.io/generator: prowgen
job-release: "4.20"
pj-rehearse.openshift.io/can-be-rehearsed: "true"
name: periodic-ci-osac-project-osac-test-infra-main-snapshot-vmaas
spec:
containers:
- args:
- --gcs-upload-secret=/secrets/gcs/service-account.json
- --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson
- --lease-server-credentials-file=/etc/boskos/credentials
- --report-credentials-file=/etc/report/credentials
- --secret-dir=/secrets/ci-pull-credentials
- --target=snapshot-vmaas
command:
- ci-operator
env:
- name: HTTP_SERVER_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest
imagePullPolicy: Always
name: ""
ports:
- containerPort: 8080
name: http
resources:
requests:
cpu: 10m
volumeMounts:
- mountPath: /etc/boskos
name: boskos
readOnly: true
- mountPath: /secrets/ci-pull-credentials
name: ci-pull-credentials
readOnly: true
- mountPath: /secrets/gcs
name: gcs-credentials
readOnly: true
- mountPath: /secrets/manifest-tool
name: manifest-tool-local-pusher
readOnly: true
- mountPath: /etc/pull-secret
name: pull-secret
readOnly: true
- mountPath: /etc/report
name: result-aggregator
readOnly: true
serviceAccountName: ci-operator
volumes:
- name: boskos
secret:
items:
- key: credentials
path: credentials
secretName: boskos-credentials
- name: ci-pull-credentials
secret:
secretName: ci-pull-credentials
- name: manifest-tool-local-pusher
secret:
secretName: manifest-tool-local-pusher
- name: pull-secret
secret:
secretName: registry-pull-credentials
- name: result-aggregator
secret:
secretName: result-aggregator
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
approvers:
- osac-cicd
reviewers:
- osac-cicd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"path": "osac-project/cluster-tool/snapshot-vmaas/osac-project-cluster-tool-snapshot-vmaas-workflow.yaml",
"owners": {
"approvers": [
"osac-cicd"
],
"reviewers": [
"osac-cicd"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
workflow:
as: osac-project-cluster-tool-snapshot-vmaas
steps:
cluster_profile: packet-assisted
allow_best_effort_post_steps: true
pre:
- ref: ofcir-acquire
- ref: assisted-ofcir-setup
- chain: assisted-common-pre
- ref: osac-project-installer
test:
- ref: osac-project-cluster-tool-snapshot
post:
- ref: osac-project-gather
- ref: ofcir-gather
- ref: ofcir-release
env:
CLUSTERTYPE: "assisted_large_el9"
documentation: |-
Provisions a baremetal cluster via assisted-installer, installs OSAC,
then snapshots the cluster using cluster-tool and pushes the snapshot
OCI image to a container registry. Used as a nightly job to keep the
snapshot current for presubmit cluster-tool boot jobs.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
approvers:
- osac-cicd
reviewers:
- osac-cicd
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/bash

set -o nounset
set -o errexit
set -o pipefail

echo "************ cluster-tool snapshot ************"
echo "CLUSTER_TOOL_COMMIT: ${CLUSTER_TOOL_COMMIT}"
echo "SNAPSHOT_REGISTRY: ${SNAPSHOT_REGISTRY}"
echo "-------------------------------------------"

FLAVOR_NAME="osac-vmaas"
QUAY_USER=$(cat /var/run/vault/osac-quay-creds/user)

set +x
QUAY_PASS=$(cat /var/run/vault/osac-quay-creds/password)
set -x

timeout -s 9 90m ssh -F "${SHARED_DIR}/ssh_config" ci_machine bash -s \
"${CLUSTER_TOOL_COMMIT}" \
"${SNAPSHOT_REGISTRY}" \
"${FLAVOR_NAME}" \
"${QUAY_USER}" \
"${QUAY_PASS}" \
<<'REMOTE_EOF'
Comment on lines +15 to +25
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

head -50 ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh

Repository: openshift/release

Length of output: 1570


🏁 Script executed:

tail -30 ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh

Repository: openshift/release

Length of output: 1221


🏁 Script executed:

# Let me verify the exact line numbers and check the context around the credential handling
wc -l ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh

Repository: openshift/release

Length of output: 172


🏁 Script executed:

cat -n ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh

Repository: openshift/release

Length of output: 2382


🏁 Script executed:

# Verify the fix syntax is correct by checking bash parameter expansion behavior
bash -c 'set -o nounset; was_xtrace=0; [[ "$-" == *x* ]] && was_xtrace=1; echo "was_xtrace=$was_xtrace"; set -x; echo "After set -x"; [[ "$-" == *x* ]] && was_xtrace=1; echo "was_xtrace=$was_xtrace"; (( was_xtrace )) && echo "Would re-enable xtrace"'

Repository: openshift/release

Length of output: 272


Prevent Quay password leakage through xtrace during SSH invocation.

Line 17 enables xtrace, and the ssh command on lines 19–24 passes QUAY_PASS as an argument. With xtrace enabled, bash expands and outputs the full command including the password to CI logs before execution. Save the xtrace state before disabling it for credential operations, then restore it afterward, rather than always re-enabling.

Suggested fix
- set +x
- QUAY_PASS=$(cat /var/run/vault/osac-quay-creds/password)
- set -x
+was_xtrace=0
+[[ "$-" == *x* ]] && was_xtrace=1
+set +x
+QUAY_PASS=$(cat /var/run/vault/osac-quay-creds/password)

 timeout -s 9 90m ssh -F "${SHARED_DIR}/ssh_config" ci_machine bash -s \
     "${CLUSTER_TOOL_COMMIT}" \
     "${SNAPSHOT_REGISTRY}" \
     "${FLAVOR_NAME}" \
     "${QUAY_USER}" \
     "${QUAY_PASS}" \
     <<'REMOTE_EOF'
@@
 REMOTE_EOF
+
+(( was_xtrace )) && set -x

Per coding guidelines, step registry command scripts should avoid accidental disclosure of passwords, tokens, API keys, and cluster URLs via xtrace. Apply the same pattern to the podman login invocation at lines 51–55.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh`
around lines 15 - 25, The script currently enables xtrace around the ssh
invocation and passes QUAY_PASS as a positional argument (QUAY_PASS and the
timeout/ssh invocation block), which risks leaking the password; change this by
saving the current xtrace state (e.g., store "$(set +x; false || true)" or check
$- for xtrace), then disable xtrace before reading/using QUAY_PASS and before
the ssh command that includes "${QUAY_PASS}", and finally restore the original
xtrace state immediately after; apply the identical save/disable/restore pattern
around the podman login invocation (the podman login block that uses QUAY_PASS)
so credentials are never printed to CI logs.

set -euo pipefail

COMMIT="$1"
REGISTRY="$2"
FLAVOR="$3"
QUAY_USER="$4"
QUAY_PASS="$5"

echo "=== Installing cluster-tool ==="
curl -fsSL "https://raw.githubusercontent.com/omer-vishlitzky/cluster-tool/${COMMIT}/cluster-tool" \
-o /usr/local/bin/cluster-tool
chmod +x /usr/local/bin/cluster-tool
Comment on lines +35 to +37
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find the file
find . -name "osac-project-cluster-tool-snapshot-commands.sh" -type f

Repository: openshift/release

Length of output: 171


🏁 Script executed:

#!/bin/bash
# Read the file to verify the exact content at lines 35-37
if [ -f "ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh" ]; then
  echo "=== File content (full) ==="
  wc -l ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh
  echo ""
  echo "=== Lines 30-45 for context ==="
  sed -n '30,45p' ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh
fi

Repository: openshift/release

Length of output: 899


🏁 Script executed:

#!/bin/bash
# Check for any environment variable definitions or setup related to CLUSTER_TOOL_SHA256
# Search across the directory structure for related references
rg -i "cluster_tool_sha256|CLUSTER_TOOL_SHA256" --type sh

Repository: openshift/release

Length of output: 43


🏁 Script executed:

#!/bin/bash
# Search for the COMMIT variable definition and usage context
rg -i "COMMIT" ci-operator/step-registry/osac-project/cluster-tool/snapshot/ -A 2 -B 2

Repository: openshift/release

Length of output: 3880


🏁 Script executed:

#!/bin/bash
# Check the ref.yaml file to see what env variables are defined
cat ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-ref.yaml

Repository: openshift/release

Length of output: 976


🏁 Script executed:

#!/bin/bash
# Check if there are any related steps that might define CLUSTER_TOOL_SHA256 or similar patterns
rg "SHA256|sha256|checksum" ci-operator/step-registry/osac-project/cluster-tool/ --type sh

Repository: openshift/release

Length of output: 43


🏁 Script executed:

#!/bin/bash
# Look at the full context of the commands.sh file to understand the overall flow
cat -n ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh

Repository: openshift/release

Length of output: 2382


Add integrity verification for downloaded cluster-tool binary.

Lines [35-37] download and execute a binary from a mutable GitHub ref (main by default) without checksum verification. This poses a supply-chain risk, particularly in a step with mounted credentials that could be compromised if the tool is hijacked.

Add SHA256 verification before execution:

Suggested hardening
 curl -fsSL "https://raw.githubusercontent.com/omer-vishlitzky/cluster-tool/${COMMIT}/cluster-tool" \
     -o /usr/local/bin/cluster-tool
+echo "${CLUSTER_TOOL_SHA256}  /usr/local/bin/cluster-tool" | sha256sum -c -
 chmod +x /usr/local/bin/cluster-tool

Note: Requires defining CLUSTER_TOOL_SHA256 as an environment variable in the step reference.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh`
around lines 35 - 37, Download of the cluster-tool binary should include SHA256
verification: download to a temp path (instead of writing directly to
/usr/local/bin/cluster-tool), ensure CLUSTER_TOOL_SHA256 environment variable is
present, compute the SHA256 of the downloaded file (e.g., via sha256sum or
shasum -a 256), compare it to CLUSTER_TOOL_SHA256 and exit non‑zero on mismatch,
only move the verified file into /usr/local/bin/cluster-tool and then run chmod
+x on that path; update the curl -> temp file step and references to COMMIT and
/usr/local/bin/cluster-tool accordingly so the file is never executed or
installed unless the checksum matches.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a plan to move cluster-tool to the osac-project org?


echo "=== Setting up cluster-tool ==="
python3 /usr/local/bin/cluster-tool connect ci --host local --data-path /home/cluster-tool

echo "=== Discovering cluster ID ==="
CLUSTER_ID=$(virsh list --name | grep test-infra-cluster | sed 's/test-infra-cluster-//;s/-master-0//' | head -1)
[[ -z "${CLUSTER_ID}" ]] && echo "ERROR: No running test-infra cluster found" && exit 1
echo "Found cluster ID: ${CLUSTER_ID}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This cluster ID discovery depends on the assisted-installer VM naming convention (test-infra-cluster-*-master-0). Just curious, is this pattern stable? Can it change?


echo "=== Creating snapshot ==="
python3 /usr/local/bin/cluster-tool snapshot --name "${FLAVOR}" --source "${CLUSTER_ID}"

echo "=== Authenticating to registry ==="
set +x
podman login "$(echo ${REGISTRY} | cut -d/ -f1)" \
-u "${QUAY_USER}" -p "${QUAY_PASS}"
set -x
Comment on lines +50 to +54
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and examine lines around 50-55
if [ -f "ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh" ]; then
  echo "=== File exists, showing lines 40-65 for context ==="
  sed -n '40,65p' "ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh"
else
  echo "File not found, checking what exists in the directory"
  find . -path "*/osac-project/cluster-tool/snapshot/*-commands.sh" 2>/dev/null || echo "No matching files found"
fi

Repository: openshift/release

Length of output: 1022


🌐 Web query:

podman login --password-stdin option documentation

💡 Result:

The --password-stdin option for the podman login command is used to provide a registry password via standard input (STDIN) rather than through command-line arguments or interactive prompts [1][2]. This approach is commonly used in automated scripts and CI/CD pipelines to enhance security by avoiding the exposure of passwords in process lists or shell history [1][3]. Usage Examples: 1. Using a pipe: echo $PASSWORD | podman login -u --password-stdin &lt;registry_url&gt; [1][3] 2. Using a file redirection: podman login -u --password-stdin &lt; password.txt &lt;registry_url&gt; [1][3] When using this option, Podman reads the password from STDIN and uses it to authenticate with the specified registry [1][2]. If no registry is specified, Podman defaults to the first registry listed in the [registries.search] section of the registries.conf configuration file [1][2]. Credentials are typically stored in the default authentication file, located at ${XDG_RUNTIME_DIR}/containers/auth.json [1][2].

Citations:


🏁 Script executed:

# Check if printf is available and test the approach
which printf
echo "Testing printf syntax for password piping:"
QUAY_PASS="test_password"
# Verify the printf syntax doesn't add newline
printf '%s' "${QUAY_PASS}" | wc -c
echo "Password length:"
echo -n "${QUAY_PASS}" | wc -c

Repository: openshift/release

Length of output: 189


Use --password-stdin instead of passing password via -p flag.

The current approach on line 54 exposes the password in the process list, which can be accessed via process inspection. Use stdin-based authentication as per the coding guidelines requiring sensitive data to bypass process visibility.

Suggested fix
 set +x
-podman login --root /home/cluster-tool/containers/storage \
-    "$(echo ${REGISTRY} | cut -d/ -f1)" \
-    -u "${QUAY_USER}" -p "${QUAY_PASS}"
+printf '%s' "${QUAY_PASS}" | podman login --root /home/cluster-tool/containers/storage \
+    "$(echo "${REGISTRY}" | cut -d/ -f1)" \
+    -u "${QUAY_USER}" --password-stdin
 set -x
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@ci-operator/step-registry/osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-commands.sh`
around lines 50 - 55, The podman login call currently passes the password with
-p which exposes QUAY_PASS in the process list; change it to use
--password-stdin and pipe the password into podman login instead of using -p.
Locate the podman login invocation (the line using podman login --root ...
"$(echo ${REGISTRY} | cut -d/ -f1)" -u "${QUAY_USER}" -p "${QUAY_PASS}") and
replace the -p usage by supplying QUAY_PASS via stdin (keep the --root, registry
host extraction, and -u "${QUAY_USER}" as-is) so the password is not visible in
process arguments.


echo "=== Pushing snapshot ==="
python3 /usr/local/bin/cluster-tool push --flavor "${FLAVOR}" --registry "${REGISTRY}"

echo "=== Snapshot push complete ==="
REMOTE_EOF

echo "Snapshot step finished successfully."
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"path": "osac-project/cluster-tool/snapshot/osac-project-cluster-tool-snapshot-ref.yaml",
"owners": {
"approvers": [
"osac-cicd"
],
"reviewers": [
"osac-cicd"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
ref:
as: osac-project-cluster-tool-snapshot
from: dev-scripts
grace_period: 10m
timeout: 2h0m0s
commands: osac-project-cluster-tool-snapshot-commands.sh
resources:
requests:
cpu: 100m
memory: 200Mi
credentials:
- namespace: test-credentials
name: osac-quay-creds
mount_path: /var/run/vault/osac-quay-creds
env:
- name: CLUSTER_TOOL_COMMIT
default: "main"
documentation: cluster-tool git ref to download (branch, tag, or commit)
- name: SNAPSHOT_REGISTRY
default: "quay.io/rh-ee-ovishlit/cluster-flavors:osac-vmaas-pruned"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question for the snapshot registry: should this move to an org-level quay namespace?

documentation: OCI image ref to push the snapshot to
documentation: |-
Snapshots a running OSAC cluster using cluster-tool and pushes the
resulting OCI image to a container registry. Expects the cluster to
have been provisioned by assisted-installer and OSAC installed via
osac-project-installer in a prior step.