fix(relay): staging director deploys run as relay-dir with rehome identity, and can register one cell's cap (#27118)

Rebased onto main as one commit after its parent squash-merged.
This commit is contained in:
Jinwoo Hong
2026-10-10 19:53:44 -04:00
committed by GitHub
parent 19f20c8b16
commit b154baf6d7
5 changed files with 122 additions and 5 deletions
@@ -544,7 +544,6 @@ jobs:
--capacity-service-account "${CAPACITY_SERVICE_ACCOUNT}" \
--capacity-cell-id "${cell_id}" \
--director-cells-json "${desired_cells_json}" \
--min-instances 0 \
--prune-revisions true \
--release-id "bootstrap-${cell_id}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}")"
echo "${director_result}"
@@ -13,6 +13,35 @@ on:
default: preserve
type: choice
options: [preserve, 'off', dry-run, 'on']
expected-rehome-generation:
description: Exact durable regional-rehome generation; it must remain disabled
required: true
type: string
bootstrap-runtime-identity:
description: One-time move from the stamped-cell identity to the director identity
required: true
default: false
type: boolean
predecessor-image-digest:
description: Bootstrap only. Exact immutable serving predecessor digest
required: false
type: string
capacity-cell-id:
description: Register this cell's reviewed staging.tfvars cap and bound with the director
required: true
default: none
type: choice
options: [none, staging-gce-c1, staging-gce-c2, staging-gce-c3, staging-gce-c4]
min-instances:
description: Director floor; preserve keeps the serving revision's, so a reserve run's 2 survives
required: true
default: preserve
type: choice
options: [preserve, '0', '2']
confirmation:
description: BOOTSTRAP_RELAY_DIRECTOR_REHOME_IDENTITY for a bootstrap
required: false
type: string
shadow-seat-feed-cells:
description: Preserve the step-3 shadow seat-feed cells, or set all or a comma list of cell ids; dropping a reserve cell is refused
required: true
@@ -47,11 +76,34 @@ jobs:
CAPACITY_SERVICE_ACCOUNT: ${{ vars.STAGING_GCP_RELAY_CAPACITY_SERVICE_ACCOUNT }}
ASIA_PROOF_SERVICE_ACCOUNT: ${{ vars.STAGING_GCP_RELAY_ASIA_PROOF_SERVICE_ACCOUNT }}
REGIONAL_PLACEMENT_SECRET: orca-cloud-relay-regional-placement-enabled
DIRECTOR_RUNTIME_SERVICE_ACCOUNT: orca-cloud-staging-relay-dir@onorca-cloud-staging.iam.gserviceaccount.com
PREDECESSOR_RUNTIME_SERVICE_ACCOUNT: orca-cloud-staging-relay@onorca-cloud-staging.iam.gserviceaccount.com
REHOME_AUDIENCE: https://relay-staging.onorca.dev/v1/admin/host-drain
EXPECTED_REHOME_GENERATION: ${{ inputs.expected-rehome-generation }}
BOOTSTRAP_RUNTIME_IDENTITY: ${{ inputs.bootstrap-runtime-identity }}
PREDECESSOR_IMAGE_DIGEST: ${{ inputs.predecessor-image-digest }}
CAPACITY_CELL_ID: ${{ inputs.capacity-cell-id }}
MIN_INSTANCES: ${{ inputs.min-instances }}
steps:
- uses: actions/checkout@v4
- name: Require the expected immutable image
run: '[[ "${EXPECTED_IMAGE_DIGEST}" =~ ^sha256:[a-f0-9]{64}$ ]]'
- name: Require the expected immutable image and identity request
shell: bash
env:
CONFIRMATION: ${{ inputs.confirmation }}
run: |
set -euo pipefail
[[ "${EXPECTED_IMAGE_DIGEST}" =~ ^sha256:[a-f0-9]{64}$ ]]
[[ "${EXPECTED_REHOME_GENERATION}" =~ ^(0|[1-9][0-9]*)$ ]]
[[ "${BOOTSTRAP_RUNTIME_IDENTITY}" =~ ^(true|false)$ ]]
[[ "${MIN_INSTANCES}" =~ ^(preserve|0|2)$ ]]
if test "${BOOTSTRAP_RUNTIME_IDENTITY}" = true; then
[[ "${PREDECESSOR_IMAGE_DIGEST}" =~ ^sha256:[a-f0-9]{64}$ ]]
test "${CAPACITY_CELL_ID}" = none
test "${CONFIRMATION}" = BOOTSTRAP_RELAY_DIRECTOR_REHOME_IDENTITY
else
test -z "${PREDECESSOR_IMAGE_DIGEST}"
fi
- uses: hashicorp/setup-terraform@v3
with:
@@ -79,6 +131,16 @@ jobs:
test "${IMAGE}" = \
"${GCP_REGION}-docker.pkg.dev/${GCP_PROJECT_ID}/${REPOSITORY_ID}/${IMAGE_NAME}@${EXPECTED_IMAGE_DIGEST}"
echo "IMAGE=${IMAGE}" >> "${GITHUB_ENV}"
if test "${CAPACITY_CELL_ID}" != none; then
# The deploy script refuses any topology change beyond this one cell's cap and bound.
DESIRED_CELLS_JSON="$(terraform -chdir=infra/terraform console \
-var-file=environments/staging.tfvars \
<<< 'local.relay_director_cells_json' | jq -er '.')"
jq -e --arg cell "${CAPACITY_CELL_ID}" \
'any(.[]; .id == $cell and .connectionHardCap != null)' \
<<< "${DESIRED_CELLS_JSON}" >/dev/null
echo "DESIRED_CELLS_JSON=${DESIRED_CELLS_JSON}" >> "${GITHUB_ENV}"
fi
- uses: google-github-actions/setup-gcloud@v2
@@ -109,6 +171,26 @@ jobs:
--format='value(name)' | awk -F/ '{print $NF}')"
[[ "${regional_version}" =~ ^[1-9][0-9]*$ ]]
RELEASE_ID="${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-${GITHUB_SHA:0:8}"
identity_args=()
if test "${BOOTSTRAP_RUNTIME_IDENTITY}" = true; then
identity_args=(
--bootstrap-runtime-identity true
--predecessor-runtime-service-account "${PREDECESSOR_RUNTIME_SERVICE_ACCOUNT}"
--predecessor-image-digest "${PREDECESSOR_IMAGE_DIGEST}"
)
fi
# Omitted, the deploy script inherits the serving revision's floor.
floor_args=()
if test "${MIN_INSTANCES}" != preserve; then
floor_args=(--min-instances "${MIN_INSTANCES}")
fi
topology_args=()
if test "${CAPACITY_CELL_ID}" != none; then
topology_args=(
--capacity-cell-id "${CAPACITY_CELL_ID}"
--director-cells-json "${DESIRED_CELLS_JSON}"
)
fi
node dev/scripts/deploy-relay-blue-green.mjs \
--project "${GCP_PROJECT_ID}" \
--region "${GCP_REGION}" \
@@ -119,7 +201,14 @@ jobs:
--capacity-service-account "${CAPACITY_SERVICE_ACCOUNT}" \
--asia-proof-service-account "${ASIA_PROOF_SERVICE_ACCOUNT}" \
--regional-placement-secret-version "${regional_version}" \
--min-instances 0 \
"${floor_args[@]}" \
--runtime-service-account "${DIRECTOR_RUNTIME_SERVICE_ACCOUNT}" \
"${identity_args[@]}" \
--rehome-director-service-account "${DIRECTOR_RUNTIME_SERVICE_ACCOUNT}" \
--rehome-audience "${REHOME_AUDIENCE}" \
--rehome-control-origin https://relay-staging.onorca.dev \
--expected-rehome-generation "${EXPECTED_REHOME_GENERATION}" \
"${topology_args[@]}" \
--admin-audience https://relay-staging.onorca.dev/v1/admin/drain \
--reserve-placement "${RESERVE_PLACEMENT}" \
--shadow-seat-feed-cells "${SHADOW_SEAT_FEED_CELLS}" \
@@ -417,7 +417,6 @@ jobs:
--capacity-service-account "${CAPACITY_SERVICE_ACCOUNT}" \
--capacity-cell-id "${TARGET_CELL_ID}" \
--director-cells-json "${DESIRED_CELLS_JSON}" \
--min-instances 0 \
--prune-revisions true \
--release-id "${RELEASE_ID}")"
echo "${DEPLOY_RESULT}"
@@ -40,6 +40,19 @@ function sample(flag) {
return `sample-${flag}`
}
// Flags a workflow passes through a bash array (`"${name[@]}"`), from every `name=(...)` it
// assigns; parsing them all at once is the widest set that workflow can send.
function arrayArguments(source, name) {
const flags = []
for (const match of source.matchAll(new RegExp(`\\b${name}=\\(([^)]*)\\)`, 'g'))) {
for (const entry of match[1].matchAll(/(--[a-z0-9-]+)\s+("[^"]*"|\S+)/g)) {
flags.push([entry[1], entry[2].replace(/^"(.*)"$/, '$1')])
}
}
if (flags.length === 0) throw new Error(`no flags assigned to ${name}`)
return flags
}
function invocations(source, script) {
const lines = source.split('\n')
const found = []
@@ -49,6 +62,13 @@ function invocations(source, script) {
let line = lines[index]
while (line.trimEnd().endsWith('\\')) {
line = lines[++index]
const array = /^\s*"\$\{([a-z_]+)\[@\]\}"\s*\\?\s*$/.exec(line)
if (array) {
for (const [flag, value] of arrayArguments(source, array[1])) {
argv.push(flag, value.includes('$') ? sample(flag.slice(2)) : value)
}
continue
}
const match = /^\s*(--[a-z0-9-]+)\s+(.+?)\s*\\?\s*$/.exec(line)
if (!match) throw new Error(`unparsed ${script} argument line: ${line.trim()}`)
const [, flag, raw] = match
@@ -223,3 +223,13 @@ test('the identity is exposed through its own outputs', () => {
assert.match(outputs, /output "github_staging_relay_deploy_workload_identity_provider"/)
assert.match(outputs, /output "github_staging_relay_deploy_service_account"/)
})
// Why: relay-deploy-workflow-argv.test.mjs proves the argv parses; this pins the identity it names.
test('the staging director deploy runs as relay-dir with its rehome identity', () => {
const source = workflow('deploy-relay-staging.yml')
const start = source.indexOf('node dev/scripts/deploy-relay-blue-green.mjs')
const block = source.slice(start, source.indexOf('\n\n', start))
assert.match(block, /--runtime-service-account "\$\{DIRECTOR_RUNTIME_SERVICE_ACCOUNT\}"/)
assert.match(block, /--rehome-director-service-account "\$\{DIRECTOR_RUNTIME_SERVICE_ACCOUNT\}"/)
assert.match(source, /DIRECTOR_RUNTIME_SERVICE_ACCOUNT: orca-cloud-staging-relay-dir@/)
})