fix(windows): ship Cloudbase-Init in templates and apply cipassword o…#6
Open
gabbelitoV2 wants to merge 1 commit into
Open
fix(windows): ship Cloudbase-Init in templates and apply cipassword o…#6gabbelitoV2 wants to merge 1 commit into
gabbelitoV2 wants to merge 1 commit into
Conversation
…n clones
Windows templates built "successfully" without Cloudbase-Init and without
sysprep. Root cause: Packer's default powershell execute_command ends with
`exit $LastExitCode` - when a provisioner starts right after a
windows-restart and the uploaded script path is not readable yet
(post-reboot settle race), the CommandNotFoundException leaves
$LastExitCode unset and the provisioner "succeeds" with exit 0 without
running the script. Finalize.ps1, the last provisioner, was skipped this
way in every build: the plugin shut the VM down seconds later and shipped
an image with no Cloudbase-Init, no cleanup and no sysprep.
Fixing the silent skip then exposed three more latent bugs in scripts
that had never actually executed:
- sysprep was a no-op: the /unattend:"C:\Program Files\..." argument
quoting breaks under Start-Process, sysprep logs "Unable to parse
command-line arguments" yet exits 0. Copy the answer file to a
space-free path and require Sysprep_succeeded.tag afterwards.
- the Proxmox cloud-init password was never applied on clones:
CreateUserPlugin sets a RANDOM password; the metadata admin_pass is
applied by SetUserPasswordPlugin, which was missing from
cloudbase-init.conf's plugin list.
- `winrm set ... @{...}` never worked from PowerShell (the hashtable
argument is stringified to "System.Collections.Hashtable"); route the
calls through cmd.exe /c with literal text.
Changes:
- recipes: hardened execute_command (waits up to 120 s for the uploaded
script, runs under ErrorActionPreference=Stop so any failure aborts
the build loudly) + pause_before=30s on every post-restart powershell
provisioner, in all three Windows recipes
- all scripts end with an explicit `exit 0` so a stale $LastExitCode
from an earlier native command cannot fail a successful run
- Cloudbase-Init is installed in Finalize.ps1, after the last Windows
Update pass and right before sysprep, instead of in Install.ps1
(survives Server 2025's UpdateAgent checkpoint-CU OS re-deploy)
- cloudbase-init.conf: add SetUserPasswordPlugin, replace deprecated
config_drive_* options with the [config_drive] section, set
local_scripts_path (LocalScriptsPlugin was a no-op without it),
check_latest_version=false, quieter default_log_levels
- scripts are kept pure ASCII: PowerShell 5.1 reads BOM-less files as
ANSI, where an em-dash byte-decays into a closing quote and breaks
parsing
Verified end-to-end on a live clone: the configdrive admin_pass is
applied (local credential validation passes), the hostname is set, the
volume is extended, and the image generalizes.
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.
…n clones
Windows templates built "successfully" without Cloudbase-Init and without sysprep. Root cause: Packer's default powershell execute_command ends with
exit $LastExitCode- when a provisioner starts right after a windows-restart and the uploaded script path is not readable yet (post-reboot settle race), the CommandNotFoundException leaves $LastExitCode unset and the provisioner "succeeds" with exit 0 without running the script. Finalize.ps1, the last provisioner, was skipped this way in every build: the plugin shut the VM down seconds later and shipped an image with no Cloudbase-Init, no cleanup and no sysprep.Fixing the silent skip then exposed three more latent bugs in scripts that had never actually executed:
winrm set ... @{...}never worked from PowerShell (the hashtable argument is stringified to "System.Collections.Hashtable"); route the calls through cmd.exe /c with literal text.Changes:
exit 0so a stale $LastExitCode from an earlier native command cannot fail a successful runVerified end-to-end on a live clone: the configdrive admin_pass is applied (local credential validation passes), the hostname is set, the volume is extended, and the image generalizes.