Skip to content

Commit

Permalink
Merge pull request #24827 from l0rd/win-installer-patch
Browse files Browse the repository at this point in the history
Add a Windows Installer patch to avoid unrequested reboots
  • Loading branch information
openshift-merge-bot[bot] authored Dec 13, 2024
2 parents 27eb8e4 + 5f79cd3 commit f325054
Show file tree
Hide file tree
Showing 11 changed files with 345 additions and 101 deletions.
2 changes: 1 addition & 1 deletion build_windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ The Podman Windows installer (e.g., `podman-5.1.0-dev-setup.exe`) is a bundle
that includes an msi package (`podman.msi`) and installs the WSL kernel
(`podman-wslkerninst.exe`). It's built using the
[WiX Toolset](https://wixtoolset.org/) and the
[PanelSwWixExtension](https://github.com/nirbar/PanelSwWixExtension/tree/wix3-v3.11.1.353)
[PanelSwWixExtension](https://github.com/nirbar/PanelSwWixExtension/tree/master5)
WiX extension. The source code is in the folder `contrib\win-installer`.

### Build the Windows installer
Expand Down
26 changes: 25 additions & 1 deletion contrib/cirrus/win-installer-main.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env powershell

. $PSScriptRoot\win-lib.ps1
. $PSScriptRoot\..\win-installer\utils.ps1

if ($Env:CI -eq "true") {
$WIN_INST_FOLDER = "$ENV:CIRRUS_WORKING_DIR\repo\contrib\win-installer"
Expand All @@ -14,15 +15,38 @@ if ($Env:CI -eq "true") {

Push-Location $WIN_INST_FOLDER

# Build Installer
# Build and test the windows installer

# Download v5.3.1 installer as `build.ps1` uses it to build the patch
# (podman.msp). `build.ps1` reads `$env:V531_SETUP_EXE_PATH` to get its path.
# The v5.3.1 installer is also used to test the "v5.3.1 -> current" version minor
# update (with patch).
if (!$env:V531_SETUP_EXE_PATH) {
$env:V531_SETUP_EXE_PATH = Get-Podman-Setup-From-GitHub -version "tags/v5.3.1"
}

# Download the previous installer to test a major update (without patch)
# After v5.3.2 release we should download latest instead of v5.3.0 (i.e.
# `Get-Latest-Podman-Setup-From-GitHub`)
if (!$env:PREV_SETUP_EXE_PATH) {
$env:PREV_SETUP_EXE_PATH = Get-Podman-Setup-From-GitHub -version "tags/v5.3.0"
}

# Note: consumes podman-remote-release-windows_amd64.zip from repo.tar.zst
Run-Command ".\build.ps1 $Env:WIN_INST_VER dev `"$RELEASE_DIR`""

# Build a v9.9.10 installer to test an update from current to next version
$NEXT_WIN_INST_VER="9.9.10"
Run-Command ".\build.ps1 `"$NEXT_WIN_INST_VER`" dev `"$RELEASE_DIR`""

Pop-Location

# Run the installer silently and WSL/HyperV install options disabled (prevent reboots)
$command = "$WIN_INST_FOLDER\test-installer.ps1 "
$command += "-scenario all "
$command += "-provider $ENV:CONTAINERS_MACHINE_PROVIDER "
$command += "-setupExePath `"$WIN_INST_FOLDER\podman-$ENV:WIN_INST_VER-dev-setup.exe`""
$command += "-previousSetupExePath `"$env:PREV_SETUP_EXE_PATH`""
$command += "-nextSetupExePath `"$WIN_INST_FOLDER\podman-$NEXT_WIN_INST_VER-dev-setup.exe`""
$command += "-v531SetupExePath `"$env:V531_SETUP_EXE_PATH`""
Run-Command "${command}"
61 changes: 61 additions & 0 deletions contrib/win-installer/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,64 @@
# Windows Installer Build

Instructions [have moved here](Build and test the Podman Windows installer](#build-and-test-the-podman-windows-installer)).

## How to run a full tests scenarios

Manual tests to validate changes the wxs files or a WiX upgrade.

## Preparation

- checkout previous release tag (e.g. 5.3.0)
`git fetch --all --tags --prune && git tag --list v5.* && git checkout tags/v5.3.0`
- make the installer
`./winmake podman && ./winmake docs && ./winmake win-gvproxy && ./winmake installer`
- checkout tag `v5.3.1` make the installer
`./winmake podman && ./winmake docs && ./winmake win-gvproxy && ./winmake installer`
- get the `v5.3.1` msi product id (with superorca)
- checkout the main branch and change the product id on `podman.wxs` to match `v5.3.1` product id
- set `$env:V531_SETUP_EXE_PATH` and make current and next installer
`$env:V531_SETUP_EXE_PATH=<path> && ./winmake podman && ./winmake docs && ./winmake win-gvproxy && ./winmake installer && ./winmake installer 9.9.9`
- patch installertest to make sure it doesn't download the setup.exe from internet but uses the one just built

## Run the tests

1. Uninstall the virtualization providers (WSL and Hyper-V) using the "Windows Features" app
2. Run installtest for both `wsl` and `hyperv` (**as an admin**)
```pwsh
.\contrib\win-installer\test-installer.ps1 `
-scenario all `
-setupExePath ".\contrib\win-installer\podman-5.4.0-dev-setup.exe" `
-previousSetupExePath ".\contrib\win-installer\podman-5.3.0-dev-setup.exe" `
-nextSetupExePath ".\contrib\win-installer\podman-9.9.9-dev-setup.exe" `
-v531SetupExePath ".\contrib\win-installer\podman-5.3.1-dev-setup.exe" `
-provider hyperv
```
3. Manually test the upgrade "from v5.3.1 to current to next"
```pwsh
contrib\win-installer\podman-5.3.1-dev-setup.exe /install /log contrib\win-installer\podman-setup-531.log
contrib\win-installer\podman-5.4.0-dev-setup.exe /install /log contrib\win-installer\podman-setup-540.log
contrib\win-installer\podman-9.9.9-dev-setup.exe /install /log contrib\win-installer\podman-setup-999.log
contrib\win-installer\podman-9.9.9-dev-setup.exe /x /log contrib\win-installer\podman-uninstall-999.log
```
4. manually run the current installer with the option to install wsl and confirm it reboots and install both podman and wsl
5. manually run the current installer with the option to install hyperv and confirm it reboots and install both podman and wsl
6. run installtest for both wsl and hyperv
7. manually run the current installer with the option to install wsl and confirm it doesn't reboot
8. manually run the current installer with the option to install hyperv and confirm it doesn't reboot

## retrieve installed podman msi package information

```pwsh
$Installer = New-Object -ComObject WindowsInstaller.Installer;
$InstallerProducts = $Installer.ProductsEx("", "", 7);
$InstalledProducts = ForEach($Product in $InstallerProducts){
[PSCustomObject]@{ProductCode = $Product.ProductCode();
LocalPackage = $Product.InstallProperty("LocalPackage");
VersionString = $Product.InstallProperty("VersionString");
ProductName = $Product.InstallProperty("ProductName")
}
};
$InstalledProducts | Where-Object {$_.ProductName -match "podman"}
```

and uninstall it with `msiexec /x "{<product-code>}"`
20 changes: 20 additions & 0 deletions contrib/win-installer/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,28 @@ function CheckRequirements() {
CheckCommand "go" "Golang"
}

function Build-531-Patch() {
param(
[ValidateScript({Test-Path $_ -PathType Leaf})]
[string]$v531SetupExePath=$ENV:V531_SETUP_EXE_PATH
)

if (!$v531SetupExePath) {
. $PSScriptRoot\utils.ps1
$v531SetupExePath=Get-Podman-Setup-From-GitHub "tags/v5.3.1"
}
wix burn extract $v531SetupExePath -o $PSScriptRoot\prevPodmanMsi; ExitOnError
Move-Item $PSScriptRoot\prevPodmanMsi\a1 $PSScriptRoot\en-US\prev-podman.wixpdb -Force; ExitOnError
Move-Item $PSScriptRoot\prevPodmanMsi\a0 $PSScriptRoot\en-US\prev-podman.msi -Force; ExitOnError
wix build -define "Version=$ENV:INSTVER" -bindpath $PSScriptRoot\en-US -out $PSScriptRoot\en-US\podman.msp podman-patch.wxs; ExitOnError
}

if ($args.Count -lt 1 -or $args[0].Length -lt 1) {
Write-Host "Usage: " $MyInvocation.MyCommand.Name "<version> [dev|prod] [release_dir]"
Write-Host
Write-Host 'Uses Env Vars: '
Write-Host ' $ENV:FETCH_BASE_URL - GitHub Repo Address to locate release on'
Write-Host ' $ENV:V531_SETUP_EXE_PATH - Path to v5.3.1 setup.exe used to build the patch'
Write-Host 'Env Settings for signing (optional)'
Write-Host ' $ENV:VAULT_ID'
Write-Host ' $ENV:APP_ID'
Expand Down Expand Up @@ -129,6 +145,10 @@ if (Test-Path ./obj) {
dotnet build podman.wixproj /property:DefineConstants="VERSION=$ENV:INSTVER" -o .; ExitOnError
SignItem @("en-US\podman.msi")

# Build the Patch for 5.3.1
Build-531-Patch
SignItem @("en-US\podman.msp")

dotnet build podman-setup.wixproj /property:DefineConstants="VERSION=$ENV:INSTVER" -o .; ExitOnError
wix burn detach podman-setup.exe -engine engine.exe; ExitOnError
SignItem @("engine.exe")
Expand Down
1 change: 1 addition & 0 deletions contrib/win-installer/burn.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<MsiProperty Name="WITH_HYPERV" Value="[HyperVCheckbox]" />
<MsiProperty Name="SKIP_CONFIG_FILE_CREATION" Value="[SkipConfigFileCreation]" />
</MsiPackage>
<MspPackage Id="Patch" SourceFile="en-US\podman.msp" Vital="yes" />
<ExePackage DisplayName="WSL Kernel Install" InstallCondition="(MachineProvider = &quot;wsl&quot;) AND (WSLCheckbox = 1) AND (NOT PreviousInstallFolder)" SourceFile="artifacts\podman-wslkerninst.exe" DetectCondition="" Permanent="true" />
</Chain>
<OptionalUpdateRegistration />
Expand Down
21 changes: 21 additions & 0 deletions contrib/win-installer/podman-patch.wxs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Patch
AllowRemoval="yes"
Classification="Update"
DisplayName="Podman Patch v$(Version)"
Description="Podman Patch v$(Version)"
Manufacturer="Red Hat Inc.">

<Media Id="1000" Cabinet="PodmanPatch.cab">
<PatchBaseline
Id="podmanPatch"
BaselineFile="podman.msi"
UpdateFile="prev-podman.msi"/>
</Media>

<PatchFamily
Id="PodmanPatches"
Version="$(Version)"
Supersede="yes" />
</Patch>
</Wix>
6 changes: 3 additions & 3 deletions contrib/win-installer/podman-setup.wixproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<Project Sdk="WixToolset.Sdk/5.0.0">
<Project Sdk="WixToolset.Sdk/5.0.2">
<PropertyGroup>
<InstallerPlatform>x64</InstallerPlatform>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<OutputType>Bundle</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="WixToolset.BootstrapperApplications.wixext" Version="5.0.0" />
<PackageReference Include="WixToolset.Util.wixext" Version="5.0.0" />
<PackageReference Include="WixToolset.BootstrapperApplications.wixext" Version="5.0.2" />
<PackageReference Include="WixToolset.Util.wixext" Version="5.0.2" />
<Compile Include="burn.wxs" />
</ItemGroup>
</Project>
10 changes: 5 additions & 5 deletions contrib/win-installer/podman.wixproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="WixToolset.Sdk/5.0.0">
<Project Sdk="WixToolset.Sdk/5.0.2">
<PropertyGroup>
<InstallerPlatform>x64</InstallerPlatform>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
Expand All @@ -13,9 +13,9 @@
<Compile Include="podman.wxs;podman-ui.wxs;welcome-install-dlg.wxs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="PanelSwWixExtension4" Version="5.1.1.375" />
<PackageReference Include="WixToolset.Heat" Version="5.0.0" />
<PackageReference Include="WixToolset.UI.wixext" Version="5.0.0" />
<PackageReference Include="WixToolset.Util.wixext" Version="5.0.0" />
<PackageReference Include="PanelSwWixExtension4" Version="5.4.5.422" />
<PackageReference Include="WixToolset.Heat" Version="5.0.2" />
<PackageReference Include="WixToolset.UI.wixext" Version="5.0.2" />
<PackageReference Include="WixToolset.Util.wixext" Version="5.0.2" />
</ItemGroup>
</Project>
12 changes: 6 additions & 6 deletions contrib/win-installer/podman.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<?define UseGVProxy = ""?>
<?endif?>

<Package Name="podman" Manufacturer="Red Hat Inc." Version="$(VERSION)" UpgradeCode="a6a9dd9c-0732-44ba-9279-ffe22ea50671">
<Package Name="podman" Manufacturer="Red Hat Inc." Version="$(VERSION)" UpgradeCode="a6a9dd9c-0732-44ba-9279-ffe22ea50671" ProductCode="18107131-1820-4878-8AEE-65AAE37BC1E3">
<Media Id="1" Cabinet="Podman.cab" EmbedCab="yes" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." RemoveFeatures="Complete" Schedule="afterInstallExecute" />
<Property Id="DiskPrompt" Value="Red Hat's Podman $(VERSION) Installation" />
Expand Down Expand Up @@ -72,14 +72,14 @@
<CustomAction Id="CheckHyperV" Execute="firstSequence" DllEntry="CheckHyperV" BinaryRef="PodmanHooks" />
<util:BroadcastEnvironmentChange />
<ComponentGroup Id="WSLFeature" Directory="INSTALLDIR">
<Component Id="WSLFeatureComponent" Guid="F6A693BC-186C-4E64-8015-C3073013B3A8" Condition="(NOT WIX_UPGRADE_DETECTED) AND (WSL_INSTALL = 1)">
<Component Id="WSLFeatureComponent" Guid="F6A693BC-186C-4E64-8015-C3073013B3A8" Condition="(NOT Installed) AND (WSL_INSTALL = 1)">
<CreateFolder />
<PanelSW:Dism EnableFeature="VirtualMachinePlatform" ErrorHandling="prompt" />
<PanelSW:Dism EnableFeature="Microsoft-Windows-Subsystem-Linux" ErrorHandling="prompt" />
</Component>
</ComponentGroup>
<ComponentGroup Id="HyperVFeature" Directory="INSTALLDIR">
<Component Id="HyperVFeatureComponent" Guid="F7B2D4C9-6C89-46BB-B4EA-FF39424972F3" Condition="(NOT WIX_UPGRADE_DETECTED) AND (HYPERV_INSTALL = 1)">
<Component Id="HyperVFeatureComponent" Guid="F7B2D4C9-6C89-46BB-B4EA-FF39424972F3" Condition="(NOT Installed) AND (HYPERV_INSTALL = 1)">
<CreateFolder />
<PanelSW:Dism EnableFeature="Microsoft-Hyper-V" ErrorHandling="prompt" />
</Component>
Expand Down Expand Up @@ -110,13 +110,13 @@
<WixVariable Id="WixUIDialogBmp" Value="resources\podman-dialog.png" />
<UIRef Id="PodmanUI" />
<UI>
<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="OpenGuide" Condition="(WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1) AND (NOT WIX_UPGRADE_DETECTED)" />
<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="OpenGuide" Condition="(WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1) AND (NOT Installed) AND (NOT UpdateStarted)" />
</UI>

<InstallExecuteSequence>
<Custom Action="CheckWSL" Before="SetWSL_INSTALL" />
<Custom Action="CheckHyperV" Before="SetHYPERV_INSTALL" />
<ForceReboot Before="StopServices" Condition="(NOT WIX_UPGRADE_DETECTED) AND (NOT BURNMSIUNINSTALL) AND ((WSL_INSTALL = 1) OR (HYPERV_INSTALL = 1)) AND (NOT AFTERREBOOT)" />
<ForceReboot After="DismX86" Condition="(NOT Installed) AND (NOT UpdateStarted) AND (NOT BURNMSIUNINSTALL) AND ((WSL_INSTALL = 1) OR (HYPERV_INSTALL = 1)) AND (NOT AFTERREBOOT)" />
</InstallExecuteSequence>
<Binary Id="PodmanHooks" SourceFile="artifacts/podman-msihooks.dll" />

Expand Down Expand Up @@ -154,7 +154,7 @@
<StandardDirectory Id="CommonAppDataFolder">
<Directory Id="CONFIGDIR" Name="containers">
<Directory Id="ContainersConfigSubDir" Name="containers.conf.d">
<Component Id="MachineProviderConfigFile" Guid="C32C0040-D9AF-4155-AC7E-465B63B6BE3B" Condition="CREATE_MACHINE_PROVIDER_CONFIG_FILE">
<Component Id="MachineProviderConfigFile" Guid="C32C0040-D9AF-4155-AC7E-465B63B6BE3B" Condition="CREATE_MACHINE_PROVIDER_CONFIG_FILE" Transitive="true">
<CreateFolder />
<IniFile Id="MachineProviderConfigFile" Action="createLine" Directory="ContainersConfigSubDir" Section="machine" Name="99-podman-machine-provider.conf" Key="provider" Value="&quot;[MACHINE_PROVIDER]&quot;" />
</Component>
Expand Down
Loading

0 comments on commit f325054

Please sign in to comment.