Correcting for install failures in chef-upgrader cookbooks - #431
Draft
johnmccrae wants to merge 3 commits into
Draft
Correcting for install failures in chef-upgrader cookbooks#431johnmccrae wants to merge 3 commits into
johnmccrae wants to merge 3 commits into
Conversation
Signed-off-by: John McCrae <john.mccrae@progress.com>
Signed-off-by: John McCrae <john.mccrae@progress.com>
Signed-off-by: John McCrae <john.mccrae@progress.com>
johnmccrae
force-pushed
the
jfm/windows_install_issue
branch
from
July 22, 2026 21:00
0ed9660 to
0e00da1
Compare
tpowell-progress
approved these changes
Jul 22, 2026
Stromweld
requested changes
Jul 22, 2026
Collaborator
There was a problem hiding this comment.
These changes break things as the mixlib-install is not generating the scripts to do the install for chef_client_updater cookbook. These generator scripts are for the install.sh/ps1 scripts generated for the downloads api.
Stromweld
reviewed
Jul 22, 2026
Comment on lines
+317
to
+340
| # CAUTION: chef_client_updater cookbook compatibility | ||
| # | ||
| # The chef_client_updater cookbook calls Install-Project indirectly on Windows. | ||
| # Its upgrade flow: | ||
| # 1. Calls mixlib_install.install_command to get the install script. | ||
| # 2. Calls prepare_windows, which copies C:\opscode\chef -> C:\opscode\chef.upgrade | ||
| # and creates a scheduled task named chef_upgrade (or <product>_upgrade). | ||
| # 3. The scheduled task script runs Remove-Item "C:\opscode\chef" -Recurse -Force, | ||
| # then invokes the install script from step 1, which calls Install-Project. | ||
| # 4. On Install-Project failure the scheduled task catch block runs: | ||
| # Move-Item "C:\opscode\chef.upgrade" "C:\opscode\chef" to restore from backup. | ||
| # | ||
| # Because the install directory is removed before Install-Project is called, | ||
| # Backup-ChefInstallation finds no directory at that path and returns $null. | ||
| # Restore-ChefInstallation and Remove-ChefBackup both guard on $null and return | ||
| # early. All three functions are no-ops in the chef_client_updater flow. | ||
| # | ||
| # There is no directory naming conflict: chef_client_updater uses the suffix | ||
| # .upgrade (e.g. C:\opscode\chef.upgrade) while Install-Project uses | ||
| # .upgrade-backup (e.g. C:\opscode\chef.upgrade-backup). | ||
|
|
||
| # Copies the existing product installation directory to a timestamped backup path | ||
| # before a destructive upgrade begins. Returns the backup path, or $null if there | ||
| # was no existing installation to back up. |
Collaborator
There was a problem hiding this comment.
This assumes this is only used for the chef_client_updater CB and not for omnitruck, commercial downloads api, and test-kitchen install.sh/ps1 script generation for installing chef-client on a new system.
tpowell-progress
marked this pull request as draft
July 28, 2026 20:14
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.
Summary
This PR addresses a race condition between CDN cache propagation and Chef package
availability that could leave Windows nodes without a working Chef client after a
failed upgrade.
Two independent fixes are included, both working together to harden the upgrade path.
Problem
When Expeditor promotes a new Chef package from
currenttostable:mixlib-installcalls the packages API and receives the new version metadataC:\opscode\chefdirectorybefore installing, a failed download leaves the node with no Chef directory and
no working client — the node becomes unreachable
Fix 1: Download URL Validation with Exponential Backoff
File:
lib/mixlib/install/backend/package_router.rbBefore returning artifact information to any caller,
mixlib-installnow validatesthat the resolved download URL is actually reachable. If the URL is not yet available,
it retries with exponential backoff before giving up.
infoto callvalidate_artifact_urlwhen platform filters are presentMAX_DOWNLOAD_VALIDATE_RETRIES(3) HTTP HEAD requests against thedownload URL
2^nseconds between attempts (2s, then 4s) to allow CDN propagationArtifactsNotFoundwith a clear message if the URL never becomes reachable,preventing the upgrade from starting at all
errors rather than being masked as CDN issues
ArtifactsNotFoundimmediatelyThis fix benefits all
mixlib-installconsumers on all platforms.Fix 2: Windows Backup and Restore Recovery
File:
lib/mixlib/install/generator/powershell/scripts/install_project.ps1.erbThree new PowerShell helper functions wrap the Windows install loop to ensure that a
failed upgrade always leaves the node with a working Chef installation.
Backup-ChefInstallation<install_dir>.upgrade-backupbefore anydestructive operation begins
$nullon fresh installs (no existing directory), which causes alldownstream restore logic to no-op safely
is touched
Restore-ChefInstallationplace
Move-Itemwith a post-removeTest-Pathcheck: if the directory couldnot be fully removed (e.g., locked files), it throws explicitly rather than moving
the backup inside the partial directory
Remove-ChefBackuptry/catchblock outside the installtry/catch, so a cleanup failure after a successful upgrade never triggers a rollback
Manual Recovery
If the restore itself fails, the operator receives:
backup, avoiding the need to re-image the node
Tests Added
spec/unit/mixlib/install/backend/package_router_spec.rbArtifactsNotFound, retries correct number of times,sleeps with exponential backoff, includes product info in error message
sleeps once
spec/unit/mixlib/install/generator_spec.rbRelated Issue
Types of changes
Checklist:
Gemfile.lockhas changed, I have used--conservativeto do it and included the full output in the Description above.