Skip to content

feat: add generic Azure Linux patching - #9567

Open
chmill-zz wants to merge 4 commits into
mainfrom
azureLinuxGenericPatching
Open

chmill-zz wants to merge 4 commits into
mainfrom
azureLinuxGenericPatching

Conversation

@chmill-zz

Copy link
Copy Markdown
Contributor

What type of PR is this?

/kind feature

What this PR does / why we need it

Adds AgentBaker-side consumption of the generic LPC securityPatch contract for Azure Linux 3. The existing RPM repository, tdnf --snapshottime, network-isolated repository, custom patching, and kubelet update behavior remain OS-specific inside mariner-package-update.sh.

  • Validates the protected ConfigMap payload against the node goal hash.
  • Selects the current agent pool's goldenTimestamp and optional kubeletVersion.
  • Checkpoints successful component work before publishing live-patching-status, allowing status repair without repeating package updates.
  • Reports untargeted pools as successful no-action.
  • Preserves the existing annotation-driven path when Azure Linux 3 has no generic goal.
  • Keeps Mariner/Azure Linux 2 on the legacy path even if a generic goal is present.
  • Hotfix-delivers only mariner-package-update.sh for Mariner/Azure Linux nodes; systemd units remain unchanged and ACL/OSGuard/Flatcar stay excluded.
  • Adds VHD asset validation for Mariner/Azure Linux images.

The RP/LPC side already emits the OS-neutral securityPatch.nodeConfig consumed here. NPD generalization is separate work.

Which issue(s) this PR fixes

None.

Special notes for your reviewer

This intentionally starts with Azure Linux 3 generic consumption while preserving frozen v2 behavior. Existing custom-package validation, Kata package policy, and timer cadence are unchanged by this PR.

Does this PR introduce a user-facing change?

NONE

Validation

  • shellspec spec/parts/linux/cloud-init/artifacts/mariner-package-update_spec.sh: 42 examples, 0 failures
  • PYTHONDONTWRITEBYTECODE=1 python3 -m unittest hotfix.hotfix_generate_test: 26 tests passed
  • go test ./hotfix/render-nodecustomdata ./pkg/agent: passed
  • shellcheck parts/linux/cloud-init/artifacts/mariner/mariner-package-update.sh: passed
  • bash -n for updater and VHD content test: passed
  • git diff --check: passed

Requirements

  • I signed and signed-off the commits
  • I have added tests that prove my fix is effective or that my feature works
  • Any dependent changes have already been merged and published in downstream modules

@github-actions

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Windows Unit Test Results

  3 files   17 suites   1m 2s ⏱️
484 tests 484 ✅ 0 💤 0 ❌
487 runs  487 ✅ 0 💤 0 ❌

Results for commit 2dee3ce.

♻️ 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.

🟡 Changes recommended

A failed kubelet restart can later be reported as successful without retrying the restart.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds generic Azure Linux 3 security-patch reconciliation while retaining legacy behavior and hotfix delivery.

Changes:

  • Validates generic goals, selects pool-specific profiles, checkpoints progress, and reports status.
  • Adds ShellSpec coverage for reconciliation and failure paths.
  • Adds hotfix generation and VHD artifact validation.
File summaries
File Description
mariner-package-update.sh Implements generic patch reconciliation.
mariner-package-update_spec.sh Tests generic and legacy behavior.
nodecustomdata.yml Delivers the updater to supported images.
hotfix_generate.py Registers the updater for hotfixing.
hotfix_generate_test.py Tests hotfix selection and guards.
linux-vhd-content-test.sh Validates installed patching assets.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Balanced

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

Comment thread parts/linux/cloud-init/artifacts/mariner/mariner-package-update.sh
Copilot AI review requested due to automatic review settings September 17, 2026 22:53

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

Status handling can lose or skip sibling component results, and repository rewrite failures may be reported as successful.

Review details

Suppressed comments (3)

Previously missed (1) — in code that hasn't changed since the last review.

parts/linux/cloud-init/artifacts/mariner/mariner-package-update.sh:247

  • 🟡 Medium Risk — 🔧 Script Logic: apply_security_patch is evaluated in an elif ... && ... condition, so Bash suppresses errexit throughout its nested calls. rewrite_repos still relies on set -e; a failed cat/sed can therefore be followed by a successful update and checkpoint, leaving a network-isolated node's repository configuration stale while reporting success. Add explicit failure checks for repository reads and mutations and propagate a nonzero result before running package updates.

This issue also appears in the following locations of the same file:

  • line 500
  • line 522

parts/linux/cloud-init/artifacts/mariner/mariner-package-update.sh:502

  • 🟡 Medium Risk — 🏗️ Architecture: This rebuilds components only from this updater's local results and annotate --overwrite then erases any sibling component status already published for the same goal. Since the envelope supports multiple components and NPD is a separate consumer, a later security-patch reconciliation can discard NPD's result. Merge the existing annotation's components when its currentHash matches, then overwrite only securityPatch; never merge components from a stale hash.
    status=$(printf '%s' "${LIVE_PATCHING_COMPONENT_RESULTS}" | jq -c --arg currentHash "${goal}" '{currentHash:$currentHash,components:.}') || return 1
    # shellcheck disable=SC2086
    $KUBECTL annotate --overwrite node "${node_name}" "${LIVE_PATCHING_STATUS_ANNOTATION}=${status}"

parts/linux/cloud-init/artifacts/mariner/mariner-package-update.sh:523

  • 🟡 Medium Risk — 🔧 Script Logic: This considers any same-hash status with only successful entries converged, even {components:{}} or a status containing only a sibling such as npd. In a multi-component goal, another reconciler can publish its result first and cause this updater to skip a pending securityPatch. The fast path must require this updater's own component result to be Succeeded.
    if [ -n "${status}" ] && printf '%s' "${status}" | jq -e --arg goal "${goal}" \
        '.currentHash == $goal and (.components | type == "object") and (.components | all(.code == "Succeeded"))' > /dev/null 2>&1; then
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI review requested due to automatic review settings September 18, 2026 18:50
@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Health
github.com/Azure/agentbaker/aks-node-controller 72%
github.com/Azure/agentbaker/aks-node-controller/common 100%
github.com/Azure/agentbaker/aks-node-controller/helpers 71%
github.com/Azure/agentbaker/aks-node-controller/parser 89%
github.com/Azure/agentbaker/aks-node-controller/pkg/gpu 100%
github.com/Azure/agentbaker/aks-node-controller/pkg/nodeconfigutils 66%
github.com/Azure/agentbaker/aks-node-controller/utils 0%
github.com/Azure/agentbaker/apiserver 25%
github.com/Azure/agentbaker/cmd 0%
github.com/Azure/agentbaker/cmd/starter 0%
github.com/Azure/agentbaker/fuzz/api 0%
github.com/Azure/agentbaker/hotfix/render-nodecustomdata 0%
github.com/Azure/agentbaker/pkg/agent 76%
github.com/Azure/agentbaker/pkg/agent/datamodel 76%
github.com/Azure/agentbaker/pkg/agent/toggles 0%
github.com/Azure/agentbaker/pkg/vhdbuilder/datamodel 88%
Summary 74% (6311 / 8577)

@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Health
staging_cse_windows Package 1 58%
debug 0%
provisioningscripts 2%
parts_windows Package 1 76%
test 0%
windows 21%
Summary 36% (1434 / 6706)

@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Health
shellspec spec 21%
Summary 21% (2982 / 14084)

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

Unsupported components can incorrectly cause the complete goal to be reported and cached as converged.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

parts/linux/cloud-init/artifacts/mariner/mariner-package-update.sh:548

  • 🟡 Medium Risk — 🔄 Backward Compatibility: An unknown component is only logged, so the function still publishes the full goal hash as successful. On the next timer run, the all(.code == "Succeeded") fast path accepts the partial/empty result map; if a later updater adds support for that component (for example the planned NPD work) while the goal is unchanged, it will never process it. Record unsupported components as failed so this version cannot claim convergence for work it did not perform.
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

This branch has not been deployed

No deployments
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