Skip to content

feat(acl): convert ACL VHDs to COSI and publish to PMC - #8848

Open
Adams Anaglo (adamsanaglo) wants to merge 82 commits into
mainfrom
aa/cosi-pmc-reconcile
Open

Adams Anaglo (adamsanaglo) wants to merge 82 commits into
mainfrom
aa/cosi-pmc-reconcile

Conversation

@adamsanaglo

@adamsanaglo Adams Anaglo (adamsanaglo) commented Jul 7, 2026 •

Copy link
Copy Markdown

What this PR does / why we need it:
Builds on the ACL VHD->COSI conversion work to upload the COSI directly to PMC via its AFD upload endpoint under PMC's service connection.

  • Add cosi-upload, a Go tool that uploads via the Azure Blob SDK's chunked block-blob upload to avoid the single Put Blob size limit on large COSI images.
  • Add upload-cosi-to-pmc.sh and packer.mk targets.
  • convert-vhd-to-cosi.sh stages the COSI for upload; cosi-publishing-info.json uses the AFD download URL and adds sha1.
  • Normalize the COSI package version to strict SemVer for Nebraska: convert-vhd-to-cosi.sh strips per-component leading zeros (e.g. 202608.06.0 -> 202608.6.0) and appends -fips for FIPS builds (driven by ENABLE_FIPS, never duplicated), writing the result to cosi-publishing-info.json.image_version. IMAGE_VERSION and SIG versions are unchanged. COSI blob names include the SKU to keep architecture/FIPS variants distinct. Covered by ShellSpec tests.
  • Distinguish the ARM64 COSI conversion jobs in the release pipeline.
  • Keep PMC publishing out of PR/non-ACL template expansion, and wait for immutable VHD copy completion before handing a read-only SAS to native-arm64 conversion.
  • Add azblob and azidentity dependencies.

Which issue(s) this PR fixes:

Fixes #

bfjelds (bfjelds) and others added 23 commits June 29, 2026 20:38
Add a post-build pipeline step that converts AzureContainerLinux (ACL) VHD
images to COSI format using ImageCustomizer's convert command (v1.2.0-2).

Changes:
- New script: convert-vhd-to-cosi.sh downloads ACL VHD from blob storage,
  runs ImageCustomizer convert (VHD -> COSI), and uploads the COSI file
- New make target: convert-vhd-to-cosi in packer.mk
- Pipeline vars: set IMG_CUSTOMIZER_CONTAINER and IMG_CUSTOMIZER_VERSION
  on ACL build jobs in both PR and release pipelines
- Builder template: add Convert ACL VHD to COSI step after SIG->classic
  conversion, conditioned on OS_SKU=AzureContainerLinux
- Immutable copy: updated to also copy/remove .cosi files for ACL builds

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move the ACL COSI 'az storage blob copy start' from the VHD immutable
copy task into a dedicated task with its own condition gating on
OS_SKU=AzureContainerLinux, rather than using a bash if-block inside
the VHD copy step.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move 'Convert ACL VHD to COSI' task to after 'Copy to Immutable Storage
Container' so the VHD is safely in immutable storage before conversion.
Revert echo to original 'Successfully copied to immutable container'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move 'Copy to Immutable Storage Container' (VHD) after
'Copy COSI to Immutable Storage Container'. New order:
1. Convert ACL VHD to COSI
2. Copy COSI to Immutable Storage Container
3. Copy to Immutable Storage Container (VHD)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use less specific version tag to pick up patch releases automatically.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SIG_SOURCE_GALLERY_UNIQUE_NAME, SIG_SOURCE_IMAGE_NAME, and
SIG_SOURCE_IMAGE_VERSION are set but never consumed by any script
or template in the repo.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
FIPS jobs were missing IMG_CUSTOMIZER_CONTAINER and IMG_CUSTOMIZER_VERSION,
which are required for the COSI conversion step.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Create generate-cosi-publishing-info.sh that writes cosi-publishing-info.json
with the immutable storage URL and image metadata, paralleling
generate-vhd-publishing-info.sh for VHDs.

Pipeline steps added after 'Copy COSI to Immutable Storage Container':
- Generate COSI Publishing Info (bash, no az-login needed)
- Publish COSI Publishing Info (artifact: cosi-publishing-info-{artifactName})

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Generate cosi-publishing-info.json (with sha256, size, cosi_url, and
image metadata) directly in convert-vhd-to-cosi.sh while the COSI
artifact is still on disk. Remove the standalone script and make target.

Pipeline order: Convert + generate info -> Publish artifact -> Copy to immutable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
OS_NAME was referenced in cosi-publishing-info.json but never set.
ACL COSI artifacts are always Linux, so hardcode it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The container entrypoint is already 'imagecustomizer', so the first
argument should be the subcommand 'convert' directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add an opt-in fallback to convert-vhd-to-cosi.sh so that when the MCR
ImageCustomizer image for the requested version is unavailable, the
script can pull from a configurable fallback registry
(IMG_CUSTOMIZER_CONTAINER_FALLBACK, e.g. ghcr.io/microsoft/imagecustomizer).
The fallback is gated by a script param defaulting to off, normalizes
major.minor versions to major.minor.0 for GHCR's full semver tags, and
is enabled for the ACL COSI conversion step. Bump IMG_CUSTOMIZER_VERSION
from 1.4 to 1.5 for ACL jobs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Include the tag directly in IMG_CUSTOMIZER_CONTAINER
(mcr.microsoft.com/azurelinux/imagecustomizer:1.5) and
IMG_CUSTOMIZER_CONTAINER_FALLBACK
(ghcr.io/microsoft/imagecustomizer:1.5.0) for the ACL COSI conversion.
Drop the separate IMG_CUSTOMIZER_VERSION variable and the major.minor
to major.minor.0 normalization from convert-vhd-to-cosi.sh, since both
registries now carry fully-qualified tags.

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

- convert-vhd-to-cosi.sh: convert+stage only; emit AFD cosi_url + sha1 for aks-rp cosi register
- upload-cosi-to-pmc.sh (new) + make target: upload staged COSI under PMC's SC (no az-login dep)
- pipeline: Upload COSI to PMC task under COSI_PMC_SERVICE_CONNECTION; drop obsolete COSI immutable-copy step
- fix azExitCode masking + set -u guards
…copy

azcopy cannot infer the service type for a custom *.azurefd.net host and
won't send the AAD token to a non-default trusted suffix. Mint a
storage-scoped token and PUT the staged .cosi directly to PMC's AFD
upload endpoint (AFD passthrough-forwards the Bearer token to the blob
origin), matching the proven Nebraska POC. Stream with curl -T to avoid
loading a multi-GB COSI into memory.
A single Blob REST PUT is capped at 5000 MiB, so the real converted COSI
(>5 GiB) failed with HTTP 413 RequestBodyTooLarge. Replace the curl PUT
with a small cmd/cosi-upload Go tool that uses the Azure Blob SDK's
UploadFile (16 MiB blocks, concurrency 8), which chunks via Put Block +
Put Block List and is not subject to the single-PUT limit. Auth is
unchanged (Microsoft Entra via the AzureCLI@2 login); AFD forwards the
bearer token to the blob origin. azblob/azidentity are pinned to the
versions already used by the e2e module.

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.

Pull request overview

This PR extends the Azure Container Linux (ACL) VHD → COSI flow by adding a dedicated upload path to PMC via an Azure Front Door (AFD) upload endpoint, wiring the new conversion + upload steps into the VHD builder release pipeline, and introducing a small Go-based uploader that uses Azure Blob SDK block uploads to avoid single-request size limits.

Changes:

  • Add an ImageCustomizer-based VHD→COSI conversion script that stages the artifact and emits cosi-publishing-info.json (including sha1).
  • Add a Go CLI (cmd/cosi-upload) plus a wrapper script to upload large COSI artifacts via chunked block-blob upload using Azure CLI (Entra ID) auth.
  • Wire new “Convert ACL VHD to COSI” and “Upload COSI to PMC” steps into the builder release template and set ImageCustomizer image variables in pipeline definitions.

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vhdbuilder/packer/imagecustomizer/scripts/convert-vhd-to-cosi.sh Downloads the staged ACL VHD, converts it to COSI via ImageCustomizer, stages the COSI, and generates cosi-publishing-info.json with hashes.
vhdbuilder/packer/imagecustomizer/scripts/upload-cosi-to-pmc.sh Validates expected environment + artifacts and invokes the Go uploader to push to the PMC AFD upload endpoint.
cmd/cosi-upload/main.go Implements block/chunked upload using azblob with Azure CLI credential for pipeline auth.
packer.mk Adds convert-vhd-to-cosi, build-cosi-upload, and upload-cosi-to-pmc targets used by pipeline steps.
.pipelines/templates/.builder-release-template.yaml Adds pipeline tasks to convert ACL VHD to COSI and upload COSI to PMC, and publishes cosi-publishing-info.json.
.pipelines/.vsts-vhd-builder.yaml Sets ImageCustomizer container image variables (primary + GHCR fallback) for relevant stages.
.pipelines/.vsts-vhd-builder-release.yaml Sets ImageCustomizer container image variables (primary + GHCR fallback) for relevant stages.
go.mod Adds Azure Blob SDK + Azure Identity dependencies required by the new uploader tool.
go.sum Updates module checksums for newly introduced Go dependencies.

Comment thread packer.mk Outdated
Comment thread .pipelines/templates/.builder-release-template.yaml Outdated
Copilot AI review requested due to automatic review settings July 7, 2026 16:58
@aks-node-assistant

Copy link
Copy Markdown
Contributor

AgentBaker Linux gate detective

Run: https://msazure.visualstudio.com/CloudNativeCompute/_build/results?buildId=182176653
Failed job/stage/task: build / build2204fipsgen2containerd / Test, Scan, and Cleanup.

Detective summary: Test/Scan completed the VHD scan, then the CIS baseline comparison again found Ubuntu 22.04 FIPS rules 5.1.18 and 5.1.6 regressed from pass to fail. This is the existing repair-linked CIS baseline-drift signature.

Likely cause / signature: $sig.

Confidence: High for recurring baseline drift.

Recommended owner/action: VHD validation owners should work repair #39802117 to reconcile the CIS baseline or fix image content.

Strongest alternative: PR-specific component changes caused the CIS diff; less likely because the same two CIS rules reproduced across unrelated PRs and manual branches.

Evidence: Timeline marks Test/Scan as succeededWithIssues; task log reports CIS regressions detected: 2 with 5.1.18|pass->fail and 5.1.6|pass->fail; existing wiki row and repair item track this recurring signature.

Wiki signature: $sig; repair #39802117

Integrate upstream/user/bfjelds/acl-cosi-simplified with the resolved COSI pipeline, validation, and ACL agent changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Retain the production ACG default and current image pins while preserving selectable Marketplace and development images. Integrate upstream ACL CVM support and align COSI scenarios with the updated compute SDK.

Co-authored-by: Copilot <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.

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.

Copilot review overview

1 open finding
1 resolved since last review

🧠 Review effort: Lite

Comment thread .pipelines/scripts/e2e_run.sh Outdated

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

Marketplace metadata and COSI acceptance checks need correction, and the cross-architecture publishing path warrants final human review.

5 open findings

🧠 Review effort: Lite

Comment thread .pipelines/templates/.acl-base-image-vars.yaml Outdated
Comment thread e2e/scenario/scenario_cosi_content.go Outdated
Comment thread e2e/scenario/scenario_cosi_content.go Outdated
Comment thread e2e/scenario/scenario_cosi_content.go Outdated
Co-authored-by: Copilot <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.

Comment on lines +48 to +49
source_exists="$(az storage blob exists --blob-url "$source_uri" --auth-mode login \
--query exists --output tsv)"
Comment thread e2e/scenario/scenario_cosi_content.go Outdated
Comment thread e2e/scenario/scenario_cosi_content.go Outdated
Comment thread e2e/scenario/scenario_cosi_content.go Outdated
Upstream main builds ACL only from the production Azure Compute Gallery. Keep acg (default) and acldevel, both gallery sources, and restore main's gallery-only Packer source wiring. This also resolves the review comment about empty base image fields in vhd-publishing-info.json for marketplace builds.

Co-authored-by: Copilot <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.

Comment thread e2e/scenario/scenario_cosi_content.go Outdated
Per Brian, drop the ACL_COSIContent_* scenarios. ACL may not move from 3.0 to 3.1, the 3.1 partition checks were never finished, and the layout may gain partitions. The COSI update scenarios now cover the contents: Trident verifies the metadata SHA-384 while staging. Keep the download and URL-sanitizing helpers the update scenarios use, in cosi_download.go, and remove the LocalValidator hook that only these scenarios needed.

Co-authored-by: Copilot <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.

Comment on lines +6 to +7
vhd_name="${CAPTURED_SIG_VERSION}.vhd"
source_uri="${DESTINATION_STORAGE_CONTAINER}/${vhd_name}"
Comment on lines +735 to +746
# Configuration for the Trident ACL Agent, which drives A/B OS updates on
# ACL nodes. The agent itself and its unit come from the trident-acl-agent
# package in the ACL base image; only its configuration and its start
# trigger are supplied here.
# cpAndMode creates the .service.d directory, so no mkdir is needed.
TAA_OVERRIDE_SRC=/home/packer/trident-acl-agent-override.conf
TAA_OVERRIDE_DEST=/etc/systemd/system/trident-acl-agent.service.d/10-aks.conf
cpAndMode $TAA_OVERRIDE_SRC $TAA_OVERRIDE_DEST 600

TAA_PATH_UNIT_SRC=/home/packer/trident-acl-agent.path
TAA_PATH_UNIT_DEST=/etc/systemd/system/trident-acl-agent.path
cpAndMode $TAA_PATH_UNIT_SRC $TAA_PATH_UNIT_DEST 600
return nil
}

func stageCOSIUpdateImage(ctx context.Context, sourceURL string, upload func(context.Context, string, *os.File) (string, error)) (string, string, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

in my previous testing, i modified the test framework's firewall to allow the POC nebraska server instead of this download-upload-download cycle ... when i try this approach, i see timeouts in the test.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

in case it is helpful, here are the firewall changes (i think) that i was using:

The Nebraska firewall change is entirely in two files, introduced by  cf69abae3e : 45 added lines, 8 removed. It has two parts—allowing the endpoint and ensuring existing shared firewalls receive the rule.

1. Define and install the Nebraska allow rule

In  e2e/scenario/aks_model.go :

Declare the endpoint:

const nebraskaPocFqdn = "nebraska-poc-download-ep-hjf7e5fseafnejha.b01.azurefd.net"

Create an application rule permitting HTTPS on port 443:

nebraskaPocRule := armnetwork.AzureFirewallApplicationRule{
    Name:            to.Ptr("nebraska-poc-fqdn"),
    SourceAddresses: []*string{to.Ptr("*")},
    Protocols: []*armnetwork.AzureFirewallApplicationRuleProtocol{
        {
            ProtocolType: to.Ptr(armnetwork.AzureFirewallApplicationRuleProtocolTypeHTTPS),
            Port:         to.Ptr[int32](443),
        },
    },
    TargetFqdns: []*string{to.Ptr(nebraskaPocFqdn)},
}

Append it to the existing Allow application-rule collection:

Rules: []*armnetwork.AzureFirewallApplicationRule{
    &aksAppRule,
    &blobStorageAppRule,
    &mooncakeMARRule,
    &dmcRule,
    &nebraskaPocRule,
},

This modifies the shared E2E firewall, not just the COSI scenario’s VM.

2. Detect existing firewalls missing the rule

In  e2e/scenario/shared_infra.go:491–533 ,  firewallAppRulesUpToDate()  previously checked only the test-storage hostname. The change requires both rules:

expectedStaticRuleFqdns := map[string]string{
    "blob-storage-fqdn": config.Config.BlobStorageAccount() + ".blob.core.windows.net",
    "nebraska-poc-fqdn": "nebraska-poc-download-ep-hjf7e5fseafnejha.b01.azurefd.net",
}

It scans the existing application rules, records their target FQDNs, and returns  false  if either expected rule is missing or points elsewhere:

for name, expectedFqdn := range expectedStaticRuleFqdns {
    if foundRuleFqdns[name] != expectedFqdn {
        return false
    }
}
return true

Why this second part matters: the firewall persists between runs. Adding a rule to its creation model alone wouldn’t update an already-existing firewall.

The pre-existing  ensureSharedFirewall()  reconciliation code then updates a stale firewall in place, preserving its public IP and waiting for completion. No new reconciliation machinery, YAML variable, or manual firewall change was needed.

- bash: echo '##vso[task.setvariable variable=ACL_BASE_IMAGE_SIGNED]true'
displayName: Set ACL_BASE_IMAGE_SIGNED (default signed)

- ${{ if eq(parameters.aclBaseImageSource, 'acldevel') }}:

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.

I'd just use an if/else here rather than having a needless step in the acldevel case

default: mcr.microsoft.com/azurelinux/imagecustomizer:1.5@sha256:b1a46447f67d73dce1a76163d3f8dbcbe12988b65c51393621529c52af160729
- name: imgCustomizerContainerFallback
type: string
default: ghcr.io/microsoft/imagecustomizer:1.5.0@sha256:c74e16c636e08486f517cd3b446e3577e52b24feea06aa245a8742a9f1c4a70a

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.

why do we need the fallback? using not using mcr.microsoft.com will most likely raise supply chain analysis warnings

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

agree. in early development it was because imagecustomizer azurelinux release was lagging, but at this point we probably don't need it.

# directly by e2e-template.yaml (which only needs the signed flag, not the
# variant-specific image-pinning vars).
parameters:
- name: aclBaseImageSource

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.

would prefer if we align all parameter/variable naming style to CAPITAL_SNAKE_CASE

Comment thread cmd/cosi-upload/main.go
// images. Authentication is Microsoft Entra ID via the Azure CLI login supplied
// by the pipeline's AzureCLI@2 task; the AFD endpoint transparently forwards the
// bearer token to the blob origin.
package main

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.

let's create a separate go module

- group: "AKS Node SIG UA Token (KV)"
- group: build_performance
- group: aks-vuln-to-kusto-tme
- group: "AKS Node SIG - PMC COSI TME"

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.

this YAML Is sourced by pipelines running in other tenants, not just TME - would prefer we attach at this. via the ADO library rather than directly through YAML

echo '##vso[task.setvariable variable=IMG_CUSTOMIZER_CONTAINER_FALLBACK]ghcr.io/microsoft/imagecustomizer:1.5.0@sha256:c74e16c636e08486f517cd3b446e3577e52b24feea06aa245a8742a9f1c4a70a'
displayName: Setup Build Variables
- template: ./.builder-cosi-convert-template.yaml

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.

do we plan on using this template elsewhere? if not it would be simpler to just include that template's content directly within this template

# via `command -v` guards, so it's a no-op on any tool that's already present.
- bash: |
set -euo pipefail
echo "==== Bootstrapping tooling on $(uname -a) ===="

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.

this is a large script, would prefer we factor it out to a dedicated bash file somewhere under vhdbuilder - that way we can also write shellspec tests against it as well

Isolate the COSI uploader module, simplify conversion templates, extract and test tooling bootstrap, remove the non-MCR fallback, and align pipeline parameter and variable names. Keep tenant-specific PMC settings out of shared YAML and preserve unsigned ACL test/scan support.

Co-authored-by: Copilot <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 broad release and pipeline scope includes an unresolved conversion-job dependency issue requiring human review.

4 open issues

Review effort: Lite

@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Health
parts_windows Package 1 73% ➖
staging_cse_windows Package 1 65% ➖
debug 0% ❌
provisioningscripts 2% ❌
test 0% ❌
windows 27% ❌
Summary 38% (1652 / 6834) ❌

@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Health
shellspec spec 28% ❌
Summary 28% (4618 / 16254) ❌

@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 68% ➖
github.com/Azure/agentbaker/aks-node-controller/parser 88% ✔
github.com/Azure/agentbaker/aks-node-controller/pkg/gpu 100% ✔
github.com/Azure/agentbaker/aks-node-controller/pkg/nodeconfigutils 89% ✔
github.com/Azure/agentbaker/aks-node-controller/utils 0% ❌
github.com/Azure/agentbaker/apiserver 24% ❌
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 78% ➖
github.com/Azure/agentbaker/pkg/agent/datamodel 77% ➖
github.com/Azure/agentbaker/pkg/agent/toggles 0% ❌
github.com/Azure/agentbaker/pkg/vhdbuilder/datamodel 87% ✔
Summary 74% (5833 / 7825) ➖

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

Unresolved critical Azure CLI bootstrap and additional pipeline, version propagation, and COSI execution issues block approval.

5 open issues

Review effort: Lite

Comment on lines +101 to +103
tdnf|dnf)
pkg_install azure-cli
;;
# node was provisioned from and is not replaced by an A/B update of /usr.
if isACL "$OS" "$OS_VARIANT"; then
if [ -z "${IMAGE_VERSION:-}" ]; then
IMAGE_VERSION=$(date +%Y%m.%d.0)

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.

I dont think we should create an image version to set if packer doesn't pass in $IMAGE_VERSION, we should probably just fail

fi
IMAGE_VERSION_FILEPATH=/opt/azure/containers/image-version
mkdir -p "$(dirname ${IMAGE_VERSION_FILEPATH})"
echo "IMAGE_VERSION=${IMAGE_VERSION}" > ${IMAGE_VERSION_FILEPATH}

@pdamianov-dev Peter Damianov (pdamianov-dev) Oct 21, 2026 •

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.

does this IMAGE_VERSION_FILEPATH file need to be updated or does trident agent know to switch its context to the new partition's image and corresponding image version file path?

@pdamianov-dev Peter Damianov (pdamianov-dev) Oct 21, 2026 •

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.

like is there a mechanism on trident side that knows it has to change to the new image version? the comments for this file suggest this file DOES NOT change during update

context: Line 120: This file lives on the root partition, so it describes the node image the node was provisioned from and is not replaced by an A/B update of /usr.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is a complicated question. the problem is that ACL creates an updatable partition /usr and AgentBaker cannot currently change that parition because it cannot reseal/resign /usr and the ukis. that is why the comment is left here.

in the future, the AKS ACL image build will need to be changed to make everything updatable that the current build puts on /opt and /etc. but that hasn't been invented yet.

METADATA_SHA384=$(tar -xOf "$STAGED_COSI" --occurrence=1 metadata.json | openssl dgst -sha384 -binary | base64)

# Normalize only the Nebraska-facing version; IMAGE_VERSION itself is unchanged.
if ! COSI_IMAGE_VERSION="$(generate_cosi_package_version "${IMAGE_VERSION}" "${ENABLE_FIPS:-false}")"; then

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 current/target version mismatch: this normalizes the published version (for example, 202608.06.0 -> 202608.6.0, adding -fips when enabled), but post-install-dependencies.sh writes the raw IMAGE_VERSION into /opt/azure/containers/image-version, which the agent override configures as its current-version source.

The Trident agent source currently reads that file value directly (version.rs:90-97) and uses literal string equality against request.target_version for its AlreadyAtTarget checks (stage, finalize). If requests carry the normalized published version, the same image can compare unequal and miss the already-at-target short-circuit.

Could we ensure the agent-readable stamp and requested target use the same canonical version, including FIPS handling, and add a regression case with a zero-padded component? Please also confirm the agent revision shipped in these images uses the linked comparison path; the exact runtime impact depends on that revision and the targetVersion supplied by RP.

@bfjelds bfjelds (bfjelds) Oct 22, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

agree that we need to trace through aks-rp abupdate annotations and image-version file to ensure that these are all consistent!

trident-acl-agent should not understand fips vs not-fips (and the AlreadyAtTarget is really just a nice-to-have, as aks-rp should know what the node is), it really just passes the aks-rp request along to Nebraska.

@bfjelds bfjelds (bfjelds) Oct 22, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

until the image version is updatable, it might be better to use this in parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf:

TRIDENT_ACL_AGENT_CURRENT_VERSION_PATH=/dev/null
TRIDENT_ACL_AGENT_CURRENT_VERSION_FALLBACK=0.0.0

This branch was successfully deployed

1 active deployment
test — 832a6d39 Deployed Oct 21, 2026 by aks-node-assistant[bot] via auto-tidy #765
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.

6 participants