From cedc3b2d808cf3b9404f4e1e1e51fff7e942d99a Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Fri, 28 Aug 2026 12:42:56 -0500 Subject: [PATCH 1/2] feat(ironic): use infrasetup-system creds for runbook controller Mount the system-scoped infrasetup-system secret instead of baremetal-manage for the shell-operator clouds.yaml, granting the runbook controller system-readwrite scope. --- .../ironic/runbook-operator/shell-operator-ironic.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/ironic/runbook-operator/shell-operator-ironic.yaml b/components/ironic/runbook-operator/shell-operator-ironic.yaml index 763df655d..a14fb1598 100644 --- a/components/ironic/runbook-operator/shell-operator-ironic.yaml +++ b/components/ironic/runbook-operator/shell-operator-ironic.yaml @@ -24,11 +24,11 @@ spec: value: understack volumeMounts: - mountPath: /etc/openstack - name: baremetal-manage + name: infrasetup-system volumes: - - name: baremetal-manage + - name: infrasetup-system secret: - secretName: baremetal-manage + secretName: infrasetup-system items: - key: clouds.yaml path: clouds.yaml From 319dabc0af6ef911f1e77bc7efd4e6b93d8e00e0 Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Fri, 28 Aug 2026 13:21:43 -0500 Subject: [PATCH 2/2] fix(ironic-runbooks): fix the runbook update script to create or update Fixed up the ironic runhook update script to create or update the runbook depending on if it exists. Switch to using the UUID for the curl calls since that is required. --- .../hooks/update_runbook.sh | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/containers/shell-operator-ironic/hooks/update_runbook.sh b/containers/shell-operator-ironic/hooks/update_runbook.sh index 030b4f96e..400f7fdc6 100755 --- a/containers/shell-operator-ironic/hooks/update_runbook.sh +++ b/containers/shell-operator-ironic/hooks/update_runbook.sh @@ -60,7 +60,7 @@ PATCH # obj_path is a jq filter expression (e.g. "." or ".[0].object") # pointing at the IronicRunbook object within BINDING_CONTEXT_PATH. local obj_path="$1" - local resource_name namespace kind runbook_name description public owner + local resource_name namespace kind runbook_name description public owner runbook_uuid resource_name=$(jq -r "${obj_path} | .metadata.name" "${BINDING_CONTEXT_PATH}") namespace=$(jq -r "${obj_path} | .metadata.namespace" "${BINDING_CONTEXT_PATH}") @@ -80,7 +80,16 @@ PATCH return 1 fi - command_args=(baremetal runbook set "${runbook_name}") + # Look up the existing runbook by name to get its UUID. If the show fails + # the runbook does not exist yet and we need to create it instead of set. + if runbook_uuid=$(openstack baremetal runbook show "${runbook_name}" -f value -c uuid 2>/dev/null); then + echo "[update_runbook] Found existing runbook name=${runbook_name} uuid=${runbook_uuid}" + command_args=(baremetal runbook set "${runbook_uuid}") + else + echo "[update_runbook] Runbook name=${runbook_name} not found, creating" + runbook_uuid="" + command_args=(baremetal runbook create) + fi command_args+=(--name "${runbook_name}" --steps /tmp/steps.json) if [[ -n "${description}" ]]; then @@ -98,19 +107,24 @@ PATCH traits_json=$(jq -c "${obj_path} | .spec.traits // []" "${BINDING_CONTEXT_PATH}") if [[ "${traits_json}" != "[]" ]]; then echo "[update_runbook] Setting traits name=${resource_name} traits=${traits_json}" + # The traits endpoint requires the UUID; look it up if we just created + # the runbook and don't have it yet. + if [[ -z "${runbook_uuid}" ]]; then + runbook_uuid=$(openstack baremetal runbook show "${runbook_name}" -f value -c uuid 2>/dev/null) + fi ironic_endpoint=$(openstack endpoint list --service baremetal --interface internal -f value -c URL 2>/dev/null | head -1) - if [[ -n "${ironic_endpoint}" ]]; then + if [[ -n "${ironic_endpoint}" && -n "${runbook_uuid}" ]]; then token=$(openstack token issue -f value -c id) - echo "[update_runbook] PUT ${ironic_endpoint}/v1/runbooks/${runbook_name}/traits" + echo "[update_runbook] PUT ${ironic_endpoint}/v1/runbooks/${runbook_uuid}/traits" trait_response=$(curl -s -X PUT \ -H "Content-Type: application/json" \ -H "X-Auth-Token: ${token}" \ -H "X-OpenStack-Ironic-API-Version: 1.112" \ -d "{\"traits\": ${traits_json}}" \ - "${ironic_endpoint}/v1/runbooks/${runbook_name}/traits") + "${ironic_endpoint}/v1/runbooks/${runbook_uuid}/traits") echo "[update_runbook] Traits response name=${resource_name} response=${trait_response}" else - echo "[update_runbook] WARNING: Could not determine Ironic endpoint for traits" + echo "[update_runbook] WARNING: Could not determine Ironic endpoint or runbook UUID for traits" fi else echo "[update_runbook] No traits to set name=${resource_name}"