Skip to content

fix: publish provision result atomically - #9401

Open
r2k1 wants to merge 8 commits into
mainfrom
r2k1-analyze-provision-state
Open

fix: publish provision result atomically#9401
r2k1 wants to merge 8 commits into
mainfrom
r2k1-analyze-provision-state

Conversation

@r2k1

@r2k1 r2k1 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

Both Linux writers stage provision.json beside the target and rename it into place to prevent partial reads. Bash keeps the detailed CSE result; ANC writes a fallback when no result exists. Quoted printf preserves the shell payload on stdout and disk. Bash logs publication errors without changing the CSE exit code or skipping log upload.

Bash pre-provisioning keeps the existing marker behavior: it writes only base_prep.complete, not provision.complete. Dual-marker support is deferred until AKS-RP generalization cleanup is globally deployed.

We keep provision.complete for normal provisioning compatibility and plan to remove it after 2026-10-01, once compatible VHDs have shipped. This change does not add fsync or guarantee power-loss durability.

Which issue(s) this PR fixes:

N/A

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Windows Unit Test Results

  3 files   14 suites   57s ⏱️
415 tests 415 ✅ 0 💤 0 ❌
418 runs  418 ✅ 0 💤 0 ❌

Results for commit 4c730ed.

♻️ This comment has been updated with latest results.

Copilot AI left a comment

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

This PR makes provisioning result publication atomic so readers never observe a partially-written provision.json, while keeping provision.complete as a compatibility signal until the deprecation window ends.

Changes:

  • Add atomic “stage then rename” publishing for provision.json in cse_start.sh, and ensure completion markers are created after publication.
  • Add Go-side atomic fallback publishing (writeProvisionResultAtomically) and tests covering preservation/idempotency/error paths.
  • Update documentation to describe the new provisioning result semantics and compatibility plan.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
spec/parts/linux/cloud-init/artifacts/cse_start_spec.sh Adds shellspec coverage for atomic provision result publishing and failure modes.
parts/linux/cloud-init/artifacts/cse_start.sh Introduces publishProvisionResponse to stage+rename provision.json and write completion markers.
aks-node-controller/const.go Documents future removal of provision.complete compatibility.
aks-node-controller/app_test.go Adds tests for atomic publishing, preservation, and fsnotify event semantics.
aks-node-controller/app.go Implements Go fallback atomic write + completion marker logic.
aks-node-controller/README.md Updates provisioning flow docs to emphasize atomic provision.json publication and compatibility behavior.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread parts/linux/cloud-init/artifacts/cse_start.sh Outdated
Comment thread aks-node-controller/app.go
Comment thread aks-node-controller/app.go
Comment thread aks-node-controller/app.go
Comment thread aks-node-controller/app_test.go
Comment thread aks-node-controller/app_test.go
Comment thread spec/parts/linux/cloud-init/artifacts/cse_start_spec.sh
Comment thread spec/parts/linux/cloud-init/artifacts/cse_start_spec.sh
Comment thread aks-node-controller/README.md Outdated
Comment thread aks-node-controller/app.go
Copilot AI review requested due to automatic review settings September 4, 2026 09:32

Copilot AI left a comment

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.

🟡 Changes recommended

Unquoted JSON expansion can corrupt results, and baked PIS results can mask real-node bootstrap failures.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

parts/linux/cloud-init/artifacts/cse_start.sh:17

  • 🟡 Medium Risk — 🔧 Script Logic: Expanding response unquoted allows field splitting and pathname expansion in both emitted and staged JSON. For example, an Output value containing files * here is rewritten using filenames from the working directory, corrupting diagnostics and potentially producing invalid JSON. Use printf with a quoted argument for both writes.
    if ! echo ${response} > "${response_tmp}" ||
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread aks-node-controller/app.go
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 7, 2026 02:26

Copilot AI left a comment

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.

🟢 Approval recommended

Atomic publication, failure handling, compatibility behavior, and relevant tests are consistent and complete.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 9, 2026 09:11

Copilot AI left a comment

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.

🟢 Approval recommended

Atomic publication, compatibility behavior, error handling, and relevant tests are complete and consistent.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 9, 2026 09:31
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

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.

🔵 Needs a closer look

The fallback can preserve successful or stale JSON and then signal completion after the actual provisioning command failed.

Review details

Suppressed comments (1)

aks-node-controller/app.go:727

  • 🔴 High Risk — 🔧 Script Logic: Preserving every existing result can turn a publisher failure into a reported success. cse_start.sh renames a JSON containing the underlying EXIT_CODE before creating the markers; if marker creation then fails (the new ShellSpec explicitly covers this), the script exits non-zero and this handler runs. This branch preserves the already-written ExitCode: "0", creates provision.complete, and provision-wait consequently returns success even though runProvisionCommand failed (the same issue occurs with a stale successful destination after a failed rename). Preserve an existing result only when it represents the current failed CSE attempt; otherwise publish the non-zero provisionResult before signaling completion.
	if _, statErr := os.Stat(filepaths.ProvisionJSONFile); errors.Is(statErr, os.ErrNotExist) {
  • Files reviewed: 7/7 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI review requested due to automatic review settings September 9, 2026 09:35

Copilot AI left a comment

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.

🟡 Changes recommended

The updated documentation incorrectly presents the systemd service as the standard Linux launch path.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Balanced

### Provisioning Flow

Here is an indepth explanation of the provisioning flow. Upon first startup, CustomData is made available to the VM, after which cloud-init is able to process the content, in this case, writing the bootstrap config to disk. The binary is triggered by a systemd unit, [`aks-node-controller.service`](https://github.com/Azure/AgentBaker/blob/dev/parts/linux/cloud-init/artifacts/aks-node-controller.service) which is automatically run once cloud-init is complete. In this way, we are ensuring the bootstrapping config is present on the node and can proceeed to run the go binary to start the bootstrapping process.
On first startup, cloud-init processes CustomData and writes the bootstrap configuration to disk. The cloud-boothook starts [`aks-node-controller.service`](../parts/linux/cloud-init/artifacts/aks-node-controller.service) after the configuration is available, and the controller starts the bootstrap process.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 9, 2026 09:44

Copilot AI left a comment

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.

🟢 Approval recommended

Atomic publication, compatibility behavior, cleanup, and failure paths are adequately implemented and tested.

Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 9, 2026 10:06

Copilot AI left a comment

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.

🔵 Needs a closer look

The provisioning documentation incorrectly presents the compatibility service fallback as the standard launcher path.

Review details

Suppressed comments (1)

aks-node-controller/README.md:85

  • 🟡 Medium Risk — 🔄 Backward Compatibility: This still describes the service as the normal entrypoint, but standard Linux boothooks invoke aks-node-controller-launcher.sh directly and only fall back to systemctl start aks-node-controller.service on older VHDs without the launcher (pkg/agent/baker.go:84-90). Documenting both paths is important because supported VHDs can use either entrypoint.
On first startup, cloud-init processes CustomData and writes the bootstrap configuration to disk. The cloud-boothook starts [`aks-node-controller.service`](../parts/linux/cloud-init/artifacts/aks-node-controller.service) after the configuration is available, and the controller starts the bootstrap process.
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@aks-node-assistant

Copy link
Copy Markdown
Contributor

AgentBaker Linux gate detective

Run: https://msazure.visualstudio.com/CloudNativeCompute/_build/results?buildId=180296613
Failed job/stage/task: Build VHD / build2004fipsgen2containerd / Ubuntu Pro attach

TL;DR: Ubuntu 20.04 FIPS Build VHD failed during Ubuntu Pro attach after repeated /v1/context/machines/token 503/502 responses, then the final attach path exited because the machine was already attached.

Likely cause / signature: $signature - Ubuntu Pro/UA dependency or attach-state flake during FIPS Packer provisioning.

Confidence: Medium

Recommended owner/action: Node Lifecycle/VHD owner should inspect Ubuntu Pro token service availability and make the FIPS attach flow idempotent around transient 502/503 plus already-attached state.

Strongest alternative: PR-caused pre-provision marker regression is possible because this PR changes pre-provision publication/marker behavior, but the direct failing signal is external token-service 503/502 followed by UA attach state, not a local marker parse/assertion failure.

Evidence: timeline failed Build VHD for build2004fipsgen2containerd; Build VHD log shows repeated token endpoint 503/502, This machine is already attached, Packer exit status 182, and cleanup/artifact publish path; build metadata associates the run with PR 9401.

Wiki signature: vhd-ubuntu-pro-machine-token-service-unavailable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants