AzLocal.UpdateManagement v0.8.7 - on-prem solution-update sideloading automation (5 new cmdlets, Step.6 pipeline, de-numbered filenames)#76
Merged
Conversation
…tag const, examples
…behaviour-preserving) + reuse in Start-AzLocalClusterUpdate
…e helper (Solution download/verify, SBE staged-folder, atomic concurrent-safe cache)
…on, import-share target resolver, detached robocopy worker script + scheduled-task register/cleanup
…remote SHA256 verify, remote solution import (Expand-Archive/Add-SolutionUpdate/Get-SolutionUpdate poll + SBE AdditionalContentRequired)
…, fleet-update->9, fleet-health->10) Vacates Step.6 for the upcoming on-prem sideload pipeline (Group G). Renames the 8 GH/ADO YAMLs via git mv and updates all current-state references across .ps1 source, Pester tests, the schedule example YAML, the module README, and operator docs (Automation-Pipeline-Examples README + appendix-pipelines). Immutable historical changelog/release-history entries preserved; one-level 'formerly Step.N' annotations shifted; multi-level history chains appended (not mutated). Module imports clean (60 commands), no parse errors.
Step.1 (Get-/Invoke-AzLocalClusterInventory): opt-in -IncludeSideloadColumns switch (auto-resolved from SIDELOAD_UPDATES repo var) exports a numeric UpdateAuthAccountId column before ResourceId in cluster-inventory CSV/JSON. Step.2 (Set-AzLocalClusterUpdateRingTag): new -UpdateAuthAccountIdValue param (ByResourceId) + UpdateAuthAccountId CSV column handling, validated ^\d{1,3}$ (invalid -> per-cluster Failed), written via existing merge-tags PATCH. Byte-identical output when SIDELOAD_UPDATES is unset/false (column omitted, tag not required). Module imports clean (60 commands).
…3 sideload advisor
- New Automation-Pipeline-Examples/{github-actions,azure-devops}/Step.6_sideload-updates.yml:
opt-in, self-hosted runner/agent (label/demand azlocal-sideload), re-entrant
state-machine, no default schedule, master gate SIDELOAD_UPDATES=='true',
KV auth via OIDC (GH) / federated SP (ADO).
- Export-AzLocalApplyUpdatesScheduleAudit: new -SideloadEnabled / -SideloadLeadDays
params and a 'Recommended sideload schedule (Step.6 - opt-in)' section that
derives a per-apply-window kickoff cron (apply firing shifted back LeadDays)
plus the */30 poll cron. Gated on param override -> SIDELOAD_UPDATES env.
- FIX: local accumulator renamed to \; PowerShell vars are
case-insensitive so \ aliased the [bool]\ param
and clobbered it to \False (explicit -SideloadEnabled \True rendered nothing).
- Step.3 apply-updates-schedule-audit.yml (GH+ADO): wire SIDELOAD_UPDATES /
SIDELOAD_LEAD_DAYS env/vars through to the audit step.
…name-aware Update Breaking change (no consumers yet): drop the Step.N_ prefix from all bundled pipeline example filenames so renames/renumbering no longer strand customer CRONs. Pipelines are now matched to their destination by a stable logical ID. - Add Private/Get-AzLocalPipelineManifest.ps1: 11-row manifest mapping each logical pipeline Id -> canonical FileName, DisplayStep, IntroducedIn, and legacy Step.N_*.yml Aliases (post-R and pre-R names for the 4 renumbered ones). - Add Private/Get-AzLocalPipelineId.ps1: parse the AZLOCAL-PIPELINE-ID header comment from a YAML body. - Register both privates in the .psd1 NestedModules. - Rename 22 example YAMLs (GH + ADO) dropping Step.N_ prefix; prepend the AZLOCAL-PIPELINE-ID header comment as line 1. Display names/artifacts inside the YAML keep Step.N labels (intentional). - Update-AzLocalPipelineExample: match destination files by logical ID (canonical name -> embedded ID -> legacy alias filename), rename matched files to the canonical name while preserving BEGIN/END-AZLOCAL-CUSTOMIZE bodies (e.g. schedule CRONs), and emit a new RenamedFrom output field plus rename/platform-implication warnings. Updated .DESCRIPTION + OUTPUTS docs. - Read-AzLocalApplyUpdatesYamlCrons: switch directory discovery to ID-based matching (ID == apply-updates), with a name fallback that explicitly EXCLUDES the de-numbered apply-updates-schedule-audit.yml sibling so its poll crons are never mistaken for apply-updates windows. - Update advisor + doc-comment filename references to the de-numbered names.
…s in current-state docs De-numbered Step.N_ filename references in current-state docs (Automation README + appendix-pipelines, module README body, cmdlet-reference, rbac) to match the Group P file renames. Left Step.N display labels, #step-N anchors, and all historical records (CHANGELOG, release-history, README Release History appendix, ITSM planning docs) untouched. Also removed 4 stray untracked numbered duplicate YAMLs left by an earlier Update/test run.
…appendix entry Added the missing Step.6 sideload row to the section-1 pipeline table, a full Step 6 reference section in appendix-pipelines.md, and two new docs (sideload.md architecture/runbook + sideload-robocopy.md throttling). Updated pipeline count nine/ten -> eleven and fixed the section 1.1 naming explanation to reflect de-numbered filenames.
psd1/psm1 ModuleVersion 0.8.6->0.8.7; ReleaseNotes prepend v0.8.7 (4959 chars); 55->60 export count; CHANGELOG + README What's New + release-history pointer; GENERATED_AGAINST_MODULE_VERSION 0.8.6->0.8.7 across all 22 bundled pipeline templates; Tests version + function-count (55->60) assertions.
…unc assertion Updated all test filename literals from Step.N_*.yml to de-numbered names (glob filters, ForEach paths, banner/Node24/smoke/calendar/copy/update tests); added the 5 v0.8.7 sideload cmdlets to the expected-functions list; bumped both function-count assertions 55->60; de-numbered the Ring CRON calendar column header to '(apply-updates pipeline)' in the cmdlet + audit doc + 3 tests; added the Node24 opt-in to sideload-updates.yml (GH). Full suite: 1070 passed, 0 failed, 1 skipped.
…load cmdlets Adds 18 behaviour tests covering the 5 new on-prem sideloading public cmdlets: Update-AzLocalSideloadCatalog (offline HTML parse + SBE-preserving merge + WhatIf no-write), Resolve-AzLocalSideloadPlan (UnknownAuthAccountId, due/Planned with catalog, NoCatalogEntry), Invoke-AzLocalSideloadUpdate state machine (Skip/Start/Imported/InProgress/stale-Failed/Copied-import/Error), Export-AzLocalSideloadStatusReport (markdown+JUnit, Failed flagging, plan-error rows, OutputPath file writes), and Add-AzLocalSideloadStepSummary (delegates to report + step summary). Full suite: 1088 passed, 0 failed, 1 skipped.
…t active step, not 'Start update' wrapper
Format-AzLocalUpdateRun (and the duplicate logic in Get-AzLocalFleetStatusData) selected CurrentStep from the TOP-LEVEL progress.steps array only. Azure Local nests a coarse wrapper step ('Start update') that stays InProgress for the entire run, so CurrentStep always rendered 'Start update' in the in-flight monitor. Now both paths reuse Get-DeepestActiveStep to walk to the deepest InProgress/Error/Failed leaf (preserving the (FAILED) suffix), matching CurrentStepDetail / Get-CurrentStepPath and the standard update-progress output. Adds 2 Format-AzLocalUpdateRun regression tests.
…ANGELOG + README (v0.8.7)
… Step.6 smoke coverage + test timing ledger
…t on UpdateStarted rows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AzLocal.UpdateManagement v0.8.7 - On-prem solution-update sideloading automation
Opt-in, off-by-default automation for Azure Local clusters that cannot pull solution updates from Azure directly. A new self-hosted Step.6 pipeline robocopies update media to each cluster's import share, verifies the SHA256 over WinRM, runs
Add-SolutionUpdate, and flips theUpdateSideloaded=Truecluster tag so the downstream apply (now Step.7) picks it up. The multi-hour copy runs in a detached Windows Scheduled Task and the pipeline is driven as a re-entrant state machine on a frequent CRON, so no individual run is long-lived.Module export count grows 55 -> 60.
Summary
.psm1version pinned to0.8.7; all bundled pipeline templates pinGENERATED_AGAINST_MODULE_VERSION = '0.8.7'.New Public cmdlets (5)
Update-AzLocalSideloadCatalogpackageTypeentries) used to resolve which media to stage.Resolve-AzLocalSideloadPlanInvoke-AzLocalSideloadUpdateAdd-SolutionUpdate, setsUpdateSideloaded=True.Export-AzLocalSideloadStatusReportAdd-AzLocalSideloadStepSummaryNew Step.6 sideload pipeline
sideload-updates.yml(GitHub Actions + Azure DevOps), opt-in via theSIDELOAD_UPDATESrepository variable.runs-on: [self-hosted, azlocal-sideload]) / agent pool (pool: { name, demands: azlocal-sideload }).*/30CRON poll advances the state machine between runs.Automation-Pipeline-Examples/docs/sideload.mdandsideload-robocopy.md.BREAKING changes
Step.N_filename prefix is removed (e.g.Step.7_apply-updates.yml->apply-updates.yml). The in-pipelineStep.N -display names are unchanged, so operator-facing ordering is preserved.Update-AzLocalPipelineExampleis now rename-aware: it matches each destination pipeline by a stable logical id (embedded# AZLOCAL-PIPELINE-ID:marker, with legacy-filename aliases) and AUTO-RENAMES any olderStep.N_*.ymlon disk to the new name while preserving the consumer'sBEGIN/END-AZLOCAL-CUSTOMIZECRON edits (emits aRenamedFromresult field + a required-check warning).Sideload-aware existing steps (byte-identical output when sideload is off)
UpdateAuthAccountIdcolumn (-IncludeSideloadColumns, auto-enabled whenSIDELOAD_UPDATESis set).UpdateAuthAccountIdtag from CSV.SIDELOAD_LEAD_DAYS).Bug fix - in-flight monitor "Current Step"
Format-AzLocalUpdateRun(and the duplicate logic inGet-AzLocalFleetStatusData) selectedCurrentStepfrom the top-levelproperties.progress.stepsarray only. Azure Local nests a coarse wrapper step that staysInProgressfor the entire run, so the Step.8 monitor and fleet-status report always rendered "Start update" instead of the real current activity. Both paths now reuseGet-DeepestActiveStepto walk to the deepestInProgress/Error/Failedleaf (preserving the(FAILED)suffix), matchingCurrentStepDetail/Get-CurrentStepPathand the standard update-progress output. Adds two regression tests.Tests
Format-AzLocalUpdateRunregression tests for the deepest-stepCurrentStepfix.Documentation
CHANGELOG.md- full v0.8.7 entry incl. the "Current Step" fix.README.md- "What's New in v0.8.7" section + all 5 new cmdlets referenced.Automation-Pipeline-Examples/README.mdanddocs/appendix-pipelines.md- sideload pipeline coverage.Automation-Pipeline-Examples/docs/sideload.md+sideload-robocopy.md- new sideload operator docs.PSGallery readiness
ModuleVersion = '0.8.7'(matches.psm1$script:ModuleVersion).0.8.6/0.8.5references).Publish-Module.ps1after this PR merges tomain(not run as part of this PR).