diff --git a/build_windows.md b/build_windows.md index 299b1c682c..b7b180a9e4 100644 --- a/build_windows.md +++ b/build_windows.md @@ -367,13 +367,30 @@ contrib\win-installer\podman-5.1.0-dev-setup.exe /install ` MachineProvider=wsl WSLCheckbox=0 HyperVCheckbox=0 ``` +:information_source: If uninstallation fails, the installer may end up in an +inconsistent state. Podman results as uninstalled, but some install packages are +still tracked in the Windows registry and will affect further tentative to +re-install Podman. When this is the case, trying to re-install Podman results in +the installer returning zero (success) but no action is executed. The trailing +packages `GID` can be found in installation logs: + +``` +Detected related package: {} +``` + +To fix this problem remove the related packages: + +```pwsh +msiexec /x "{}" +``` + #### Run the Windows installer automated tests The following command executes a number of tests of the windows installer. Running it requires an administrator terminal. ```pwsh -.\winmake.ps1 installertest +.\winmake.ps1 installertest [wsl|hyperv] ``` ### Build and test the standalone `podman.msi` file @@ -443,7 +460,12 @@ $env:PATH | Select-String -Pattern "Podman" :information_source: Podman CI uses script `contrib\cirrus\win-installer-main.ps1`. Use it locally, too, to build and test -the installer. +the installer: + +```pwsh +$ENV:CONTAINERS_MACHINE_PROVIDER='wsl'; .\contrib\cirrus\win-installer-main.ps1 +$ENV:CONTAINERS_MACHINE_PROVIDER='hyperv'; .\contrib\cirrus\win-installer-main.ps1 +``` ### Uninstall and clean-up @@ -513,5 +535,6 @@ MacOS and Windows and then performs the same checks as the `lint` target plus many more. :information_source: Create and start a Podman machine before running -`winmake.ps1 lint`. Configure the Podman machine with at least 4GB of memory: +`winmake.ps1 validatepr`. Configure the Podman machine with at least 4GB of +memory: `podman machine init -m 4096`. diff --git a/contrib/cirrus/win-installer-main.ps1 b/contrib/cirrus/win-installer-main.ps1 index 033cf0df5e..57ec2a9888 100644 --- a/contrib/cirrus/win-installer-main.ps1 +++ b/contrib/cirrus/win-installer-main.ps1 @@ -9,7 +9,7 @@ if ($Env:CI -eq "true") { $WIN_INST_FOLDER = "$PSScriptRoot\..\win-installer" $ENV:WIN_INST_VER = "9.9.9" $RELEASE_DIR = "$PSScriptRoot\..\..\contrib\win-installer\current" - $ENV:CONTAINERS_MACHINE_PROVIDER = "wsl" + if ($null -eq $ENV:CONTAINERS_MACHINE_PROVIDER) { $ENV:CONTAINERS_MACHINE_PROVIDER = 'wsl' } } Push-Location $WIN_INST_FOLDER @@ -21,7 +21,6 @@ Run-Command ".\build.ps1 $Env:WIN_INST_VER dev `"$RELEASE_DIR`"" Pop-Location # Run the installer silently and WSL/HyperV install options disabled (prevent reboots) -# We need -skipWinVersionCheck for server 2019 (cirrus image), can be dropped after server 2022 $command = "$WIN_INST_FOLDER\test-installer.ps1 " $command += "-scenario all " $command += "-provider $ENV:CONTAINERS_MACHINE_PROVIDER " diff --git a/contrib/win-installer/burn.wxs b/contrib/win-installer/burn.wxs index 02f9c02829..9481b7a9e8 100644 --- a/contrib/win-installer/burn.wxs +++ b/contrib/win-installer/burn.wxs @@ -9,7 +9,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/contrib/win-installer/podman.wxs b/contrib/win-installer/podman.wxs index 0a6113dbf3..7157776821 100644 --- a/contrib/win-installer/podman.wxs +++ b/contrib/win-installer/podman.wxs @@ -35,36 +35,36 @@ + Property WSL_INSTALL is set at runtime and used as the condition to run the `WSLFeatureComponent` Component: + WSL is installed only if all these conditions are met: + - WSL isn't already installed + - The user has set property `MACHINE_PROVIDER` to "wsl" + - The user hasn't set property `WITH_WSL` to 0 + --> + Property HYPERV_INSTALL is set at runtime and used as the condition to run the `HyperVFeatureComponent` Component: + HyperV is installed only if all these conditions are met: + - HyperV isn't already installed + - The user has set property `MACHINE_PROVIDER` to "hyperv" + - The user hasn't set property `WITH_HYPERV` to 0 + --> + Property CREATE_MACHINE_PROVIDER_CONFIG_FILE is set at runtime and used as the condition to run the `MachineProviderConfigFile` Component: + The machine provider config file is created (or is not deleted if it already exist) if these conditions are met: + - The user hasn't set property `SKIP_CONFIG_FILE_CREATION` to 1 + - The main executable file ($PROGRAMDATA/RedHat/Podman/podman.exe) doesn't exist or, if it exists, the machine provider config file exists + --> + Property HIDE_PROVIDER_CHOICE is set at runtime and used as the condition to hide the Machine Provider + choice from the MSI GUI (the Radio Button Group and other related controls): + The machine provider choice isn't shown to the user if one of these conditions are met: + - The user has set the property `SKIP_CONFIG_FILE_CREATION` to 1 + - The machine provider config file ($PROGRAMDATA/containers/containers.conf.d/99-podman-machine-provider.conf) exists + - The main executable file ($PROGRAMDATA/RedHat/Podman/podman.exe) exists + --> @@ -72,14 +72,14 @@ - + - + @@ -110,13 +110,13 @@ - + - + @@ -147,10 +147,10 @@ + The following code creates the `containers/containers.conf.d` folder under the system wide + `$CommonAppDataFolder`. That's preferred to the user specific `$AppDataFolder` to avoid the + Windows Installer ICE91 warning https://learn.microsoft.com/en-us/windows/win32/msi/ice91. + --> diff --git a/contrib/win-installer/test-installer.ps1 b/contrib/win-installer/test-installer.ps1 index a26f60293c..88909c94c0 100644 --- a/contrib/win-installer/test-installer.ps1 +++ b/contrib/win-installer/test-installer.ps1 @@ -1,9 +1,19 @@ #!/usr/bin/env pwsh +# Example usage: +# rm .\contrib\win-installer\*.log && +# rm .\contrib\win-installer\*.exe && +# rm .\contrib\win-installer\*.wixpdb && +# .\winmake.ps1 installer 9.9.9 && +# .\contrib\win-installer\test-installer.ps1 ` +# -scenario update-without-user-changes ` +# -setupExePath ".\contrib\win-installer\podman-9.9.9-dev-setup.exe" ` +# -provider hyperv + # The Param statement must be the first statement, except for comments and any #Require statements. param ( [Parameter(Mandatory)] - [ValidateSet("installation-green-field", "installation-skip-config-creation-flag", "installation-with-pre-existing-podman-exe", "update-without-user-changes", "update-with-user-changed-config-file", "update-with-user-removed-config-file", "all")] + [ValidateSet("test-objects-exist", "test-objects-exist-not", "installation-green-field", "installation-skip-config-creation-flag", "installation-with-pre-existing-podman-exe", "update-without-user-changes", "update-with-user-changed-config-file", "update-with-user-removed-config-file", "all")] [string]$scenario, [ValidateScript({Test-Path $_ -PathType Leaf})] [string]$setupExePath, @@ -26,7 +36,7 @@ $WindowsPathsToTest = @($PodmanExePath, function Install-Podman { param ( - # [Parameter(Mandatory)] + [Parameter(Mandatory)] [ValidateScript({Test-Path $_ -PathType Leaf})] [string]$setupExePath ) @@ -54,14 +64,44 @@ function Install-Podman { Write-Host "Installation completed successfully!`n" } +# Install-Podman-With-Defaults is used to test updates. That's because when +# using the installer GUI the user can't change the default values. +function Install-Podman-With-Defaults { + param ( + [Parameter(Mandatory)] + [ValidateScript({Test-Path $_ -PathType Leaf})] + [string]$setupExePath + ) + + Write-Host "Running the installer using defaults ($setupExePath)..." + $ret = Start-Process -Wait ` + -PassThru "$setupExePath" ` + -ArgumentList "/install /quiet ` + /log $PSScriptRoot\podman-setup.log" + if ($ret.ExitCode -ne 0) { + Write-Host "Install failed, dumping log" + Get-Content $PSScriptRoot\podman-setup.log + throw "Exit code is $($ret.ExitCode)" + } + Write-Host "Installation completed successfully!`n" +} + function Install-Previous-Podman { Install-Podman -setupExePath $previousSetupExePath } +function Install-Previous-Podman-With-Defaults { + Install-Podman-With-Defaults -setupExePath $previousSetupExePath +} + function Install-Current-Podman { Install-Podman -setupExePath $setupExePath } +function Install-Current-Podman-With-Defaults { + Install-Podman-With-Defaults -setupExePath $setupExePath +} + function Test-Podman-Objects-Exist { Write-Host "Verifying that podman files, folders and registry entries exist..." $WindowsPathsToTest | ForEach-Object { @@ -222,7 +262,7 @@ function Start-Scenario-Update-Without-User-Changes { Test-Podman-Objects-Exist Test-Podman-Machine-Conf-Exist Test-Podman-Machine-Conf-Content - Install-Current-Podman + Install-Current-Podman-With-Defaults Test-Podman-Objects-Exist Test-Podman-Machine-Conf-Exist Test-Podman-Machine-Conf-Content @@ -240,7 +280,7 @@ function Start-Scenario-Update-With-User-Changed-Config-File { Test-Podman-Machine-Conf-Exist Test-Podman-Machine-Conf-Content $newProvider = Switch-Podman-Machine-Conf-Content - Install-Current-Podman + Install-Current-Podman-With-Defaults Test-Podman-Objects-Exist Test-Podman-Machine-Conf-Exist Test-Podman-Machine-Conf-Content -expected $newProvider @@ -258,7 +298,7 @@ function Start-Scenario-Update-With-User-Removed-Config-File { Test-Podman-Machine-Conf-Exist Test-Podman-Machine-Conf-Content Remove-Podman-Machine-Conf - Install-Current-Podman + Install-Current-Podman-With-Defaults Test-Podman-Objects-Exist Test-Podman-Machine-Conf-Exist-Not Uninstall-Current-Podman @@ -267,6 +307,12 @@ function Start-Scenario-Update-With-User-Removed-Config-File { } switch ($scenario) { + 'test-objects-exist' { + Test-Podman-Objects-Exist + } + 'test-objects-exist-not' { + Test-Podman-Objects-Exist-Not + } 'installation-green-field' { Start-Scenario-Installation-Green-Field } @@ -277,12 +323,21 @@ switch ($scenario) { Start-Scenario-Installation-With-Pre-Existing-Podman-Exe } 'update-without-user-changes' { + if (!$previousSetupExePath) { + $previousSetupExePath = Get-Latest-Podman-Setup-From-GitHub + } Start-Scenario-Update-Without-User-Changes } 'update-with-user-changed-config-file' { + if (!$previousSetupExePath) { + $previousSetupExePath = Get-Latest-Podman-Setup-From-GitHub + } Start-Scenario-Update-With-User-Changed-Config-File } 'update-with-user-removed-config-file' { + if (!$previousSetupExePath) { + $previousSetupExePath = Get-Latest-Podman-Setup-From-GitHub + } Start-Scenario-Update-With-User-Removed-Config-File } 'all' { diff --git a/winmake.ps1 b/winmake.ps1 index efb0170a2c..1deadc1b95 100644 --- a/winmake.ps1 +++ b/winmake.ps1 @@ -184,8 +184,8 @@ function Lint{ Exit 1 } - Run-Command "golangci-lint run --timeout=10m --build-tags=`"$remotetags`" $PSScriptRoot\cmd\podman" Run-Command "pre-commit run --all-files" + Run-Command "golangci-lint run --timeout=10m --build-tags=`"$remotetags`" $PSScriptRoot\cmd\podman" } # Helpers @@ -246,11 +246,7 @@ function Build-Distribution-Zip-File{ function Get-Podman-Version{ $versionSrc = "$PSScriptRoot\test\version\" $versionBin = "$PSScriptRoot\test\version\version.exe" - - # If version.exe doesn't exist, build it - if (-Not (Test-Path -Path "$versionBin" -PathType Leaf)) { - Run-Command "go build --o `"$versionBin`" `"$versionSrc`"" - } + Run-Command "go build --o `"$versionBin`" `"$versionSrc`"" $version = Invoke-Expression "$versionBin" # Remove the '-dev' suffix from the version $version = $version -replace "-.*", "" @@ -323,7 +319,7 @@ switch ($target) { Write-Host " .\winmake installer" Write-Host Write-Host "Example: Run windows installer tests" - Write-Host " .\winmake installertest" + Write-Host " .\winmake installertest hyperv" Write-Host Write-Host "Example: Generate the documetation artifacts" Write-Host " .\winmake docs"