Skip to content

Commit

Permalink
Windows Installer: switch to wix5
Browse files Browse the repository at this point in the history
The chocolatey tool that was fetching us wix v3 can no longer be used to
fetch wix v4+ so we had to switch to dotnet to fetch the latest wix.

This commit builds the installer with wix v5.
wix v5 is installed via the `dotnet` tool in the windows image itself
at containers/automation_images#354.

Going forward, the `dotnet` tool will also be used to build the installer.

In the process, the wix v3 files were converted to wix v4+ using `wix
convert` followed by manual modifications along with switch to wixproj
builds with dotnet.

Contributions from Mario Loriedo:
- bundle setup update to wix5
- updates to build and release process scripts
Ref: #3

- small fixes to windows installer theme
Ref: #4

Resolves: RUN-2055

Co-authored-by: Mario Loriedo <mario.loriedo@gmail.com>
Signed-off-by: Lokesh Mandvekar <lsm5@redhat.com>
  • Loading branch information
lsm5 and l0rd committed Jul 3, 2024
1 parent b3dab68 commit de9df45
Show file tree
Hide file tree
Showing 18 changed files with 489 additions and 495 deletions.
2 changes: 1 addition & 1 deletion .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ env:
DEBIAN_NAME: "debian-13"

# Image identifiers
IMAGE_SUFFIX: "c20240701t155130z-f40f39d13"
IMAGE_SUFFIX: "c20240702t180702z-f40f39d13"

# EC2 images
FEDORA_AMI: "fedora-aws-${IMAGE_SUFFIX}"
Expand Down
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ release.txt
/test/copyimg/copyimg
/test/goecho/goecho
/test/version/version
/test/version/version.exe
/test/testvol/testvol
/test/tools/build
/test/e2e/ginkgo-node-*
Expand All @@ -45,12 +46,14 @@ result
/*runner_stats.log
.generate-bindings
contrib/win-installer/artifacts/
contrib/win-installer/current/
contrib/win-installer/docs/
contrib/win-installer/en-US/
contrib/win-installer/fetch/
contrib/win-installer/podman.msi
contrib/win-installer/podman-*setup.exe
contrib/win-installer/engine.exe
contrib/win-installer/obj/
contrib/win-installer/shasums
contrib/win-installer/pages.wxs
contrib/win-installer/*.wixobj
contrib/win-installer/*.wixpdb
contrib/win-installer/*.log
43 changes: 25 additions & 18 deletions build_windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Windows.
- [OS requirements](#os-requirements)
- [Git and go](#git-and-go)
- [Pandoc](#pandoc)
- [WiX Toolset v3](#wix-toolset-v3)
- [.NET SDK](#net-sdk)
- [Virtualization Provider](#virtualization-provider)
- [WSL](#wsl)
- [Hyper-V](#hyper-v)
Expand Down Expand Up @@ -70,14 +70,22 @@ Pandoc can be installed from https://pandoc.org/installing.html. When performing
the Pandoc installation one, has to choose the option "Install for all users"
(to put the binaries into "Program Files" directory).

### WiX Toolset v3
### .NET SDK

[WiX Toolset](https://wixtoolset.org) **v3** is used to develop and build the
Podman Windows installer. It's not required for the Podman Windows client.
Version 3 of the WiX Toolset can be obtained from
https://wixtoolset.org/docs/wix3/. Installing it into a clean VM might require
an additional installation of .NET Framework 3.5 in advance
([instructions for adding .NET Framework 3.5 via enabling the Windows feature](https://learn.microsoft.com/en-us/dotnet/framework/install/dotnet-35-windows#enable-the-net-framework-35-in-control-panel))
[.NET SDK](https://learn.microsoft.com/en-us/dotnet/core/sdk), version 6 or
later, is required to develop and build the Podman Windows installer. It's not
required for the Podman Windows client.

```pwsh
winget install -e Microsoft.DotNet.SDK.8
```

[WiX Toolset](https://wixtoolset.org) **v5**, distributed as a .NET SDK tool, is
used too and can be installed using `dotnet install`:

```pwsh
dotnet tool install --global wix
```

### Virtualization Provider

Expand Down Expand Up @@ -304,9 +312,9 @@ The `installer` target of `winmake.ps1` runs the script

- `build-hooks.bat`: builds `podman-wslkerninst.exe` (WSL kernel installer) and
`podman-msihooks.dll` (helper that checks if WSL and Hyper-V are installed).
- `build-msi.bat`: builds `podman.msi` from the WiX source files `podman.wxs`,
- `dotnet build podman.wixproj`: builds `podman.msi` from the WiX source files `podman.wxs`,
`pages.wxs`, `podman-ui.wxs` and `welcome-install-dlg.wxs`.
- `build-burn.bat`: builds `podman-setup.exe` file from
- `dotnet build podman-setup.wixproj`: builds `podman-setup.exe` file from
[WiX Burn bundle](https://wixtoolset.org/docs/tools/burn/) `burn.wxs`.

### Test the Windows installer
Expand Down Expand Up @@ -340,21 +348,20 @@ Podman is released (it's included in the `podman-setup.exe` bundle), it can be
faster to build and test that rather than the full bundle during the development
phase.

Run the script `contrib\win-installer\build-msi.bat` to build the standalone
`podman.msi` file:
Run the command `dotnet build` to build the standalone `podman.msi` file:

```pwsh
Push-Location .\contrib\win-installer\
.\build-msi.bat 9.9.9
dotnet build podman.wixproj /property:DefineConstants="VERSION=9.9.9" -o .
Pop-Location
```

It creates the file `.\contrib\win-installer\podman.msi`. Test it using the
It creates the file `.\contrib\win-installer\en-US\podman.msi`. Test it using the
[Microsoft Standard Installer](https://learn.microsoft.com/en-us/windows/win32/msi/standard-installer-command-line-options)
command line tool:

```pwsh
msiexec /package contrib\win-installer\podman.msi /l*v podman-msi.log
msiexec /package contrib\win-installer\en-US\podman.msi /l*v podman-msi.log
```

To run it in quiet, non-interactive mode, open the terminal **as an
Expand All @@ -364,7 +371,7 @@ of the installation, `0` otherwise) and `WITH_HYPERV` (`1` to install Hyper-V as
part of the installation, `0` otherwise):

```pwsh
msiexec /package contrib\win-installer\podman.msi /l*v podman-msi.log /quiet MACHINE_PROVIDER=wsl WITH_WSL=0 WITH_HYPERV=0
msiexec /package contrib\win-installer\en-US\podman.msi /l*v podman-msi.log /quiet MACHINE_PROVIDER=wsl WITH_WSL=0 WITH_HYPERV=0
```

:information_source: `podman.msi` GUI dialogs, defined in the file
Expand All @@ -390,12 +397,12 @@ Test-Path -Path "$ENV:PROGRAMFILES\RedHat\Podman\podman.exe"
# Check the generation of the podman configuration file
Test-Path -Path "$ENV:PROGRAMDATA\containers\containers.conf.d\99-podman-machine-provider.conf"
# Check that the installer configured the right provider
Get-Content '$ENV:PROGRAMDATA\containers\containers.conf.d\99-podman-machine-provider.conf' | Select -Skip 1 | ConvertFrom-StringData | % { $_.provider }
Get-Content "$ENV:PROGRAMDATA\containers\containers.conf.d\99-podman-machine-provider.conf" | Select -Skip 1 | ConvertFrom-StringData | % { $_.provider }
# Check the creation of the registry key
Test-Path -Path "HKLM:\SOFTWARE\Red Hat\Podman"
Get-ItemProperty "HKLM:\SOFTWARE\Red Hat\Podman" InstallDir
# Check the podman.exe is in the $PATH
$env:PATH | Select-String -Pattern "$ENV:PROGRAMFILES\RedHat\Podman"
$env:PATH | Select-String -Pattern "Podman"
```

:information_source: Podman CI uses script
Expand Down
10 changes: 8 additions & 2 deletions contrib/cirrus/win-installer-main.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if ($Env:CI -eq "true") {
} else {
$WIN_INST_FOLDER = "$PSScriptRoot\..\win-installer"
$ENV:WIN_INST_VER = "9.9.9"
$RELEASE_DIR = "$PSScriptRoot\..\.."
$RELEASE_DIR = "$PSScriptRoot\..\..\contrib\win-installer\current"
$ENV:CONTAINERS_MACHINE_PROVIDER = "wsl"
}

Expand All @@ -18,7 +18,7 @@ $WindowsPathsToTest = @("C:\Program Files\RedHat\Podman\podman.exe",
"$ConfFilePath",
"HKLM:\SOFTWARE\Red Hat\Podman")

Set-Location $WIN_INST_FOLDER
Push-Location $WIN_INST_FOLDER

# Build Installer
# Note: consumes podman-remote-release-windows_amd64.zip from repo.tbz2
Expand All @@ -30,15 +30,18 @@ $ret = Start-Process -Wait -PassThru ".\podman-${ENV:WIN_INST_VER}-dev-setup.exe
if ($ret.ExitCode -ne 0) {
Write-Host "Install failed, dumping log"
Get-Content inst.log
Pop-Location
throw "Exit code is $($ret.ExitCode)"
}
$WindowsPathsToTest | ForEach-Object {
if (! (Test-Path -Path $_) ) {
Pop-Location
throw "Expected $_ but it's not present after uninstall"
}
}
$machineProvider = Get-Content $ConfFilePath | Select-Object -Skip 1 | ConvertFrom-StringData | ForEach-Object { $_.provider }
if ( $machineProvider -ne "`"$ENV:CONTAINERS_MACHINE_PROVIDER`"" ) {
Pop-Location
throw "Expected `"$ENV:CONTAINERS_MACHINE_PROVIDER`" as default machine provider but got $machineProvider"
}

Expand All @@ -49,12 +52,15 @@ $ret = Start-Process -Wait -PassThru ".\podman-${ENV:WIN_INST_VER}-dev-setup.exe
if ($ret.ExitCode -ne 0) {
Write-Host "Uninstall failed, dumping log"
Get-Content uninst.log
Pop-Location
throw "Exit code is $($ret.ExitCode)"
}
$WindowsPathsToTest | ForEach-Object {
if ( Test-Path -Path $_ ) {
Pop-Location
throw "Path $_ is still present after uninstall"
}
}

Write-Host "Uninstaller verification successful!"
Pop-Location
7 changes: 0 additions & 7 deletions contrib/win-installer/build-burn.bat

This file was deleted.

8 changes: 0 additions & 8 deletions contrib/win-installer/build-msi.bat

This file was deleted.

44 changes: 10 additions & 34 deletions contrib/win-installer/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,6 @@ function ExitOnError() {
}
}

function FetchPanel() {
Remove-Item -Recurse -Force -Path fetch -ErrorAction SilentlyContinue | Out-Null
New-Item -Force -ItemType Directory fetch | Out-Null
Push-Location fetch

$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -UseBasicParsing -OutFile nuget.exe -ErrorAction Stop `
-Uri https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
# 3.3.3.224 generates invalid schema with RemoveFeature defaults.
# Lock the version to 211 until this issue is fixed (7/18/2023)
.\nuget.exe install PanelSwWixExtension -Version 3.3.3.211
$code = $LASTEXITCODE
Pop-Location
if ($code -gt 0) {
Exit 1
}
$loc = Get-ChildItem -Recurse -Path fetch -Name PanelSwWixExtension.dll
if (!$loc) {
Write-Host "Could not locate PanelSwWixExtension.dll"
Exit 1
}

Copy-Item -Path fetch/$loc -Destination artifacts/PanelSwWixExtension.dll -ErrorAction Stop
}

function SignItem() {
param(
[Parameter(Mandatory)]
Expand Down Expand Up @@ -71,7 +46,7 @@ function CheckCommand() {

function CheckRequirements() {
CheckCommand "gcc" "MingW CC"
CheckCommand "candle" "WiX Toolset"
CheckCommand "wix" "WiX Toolset"
CheckCommand "go" "Golang"
}

Expand Down Expand Up @@ -99,7 +74,7 @@ if ($args.Count -lt 1 -or $args[0].Length -lt 1) {
}

# Pre-set to standard locations in-case build env does not refresh paths
$Env:Path="$Env:Path;C:\Program Files (x86)\WiX Toolset v3.14\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin;;C:\Program Files\Go\bin"
$Env:Path="$Env:Path;C:\Users\micro\mingw64\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin;;C:\Program Files\Go\bin;C:\Program Files\dotnet"

CheckRequirements

Expand Down Expand Up @@ -129,8 +104,6 @@ if ($ENV:INSTVER -eq "") {
Exit 1
}

FetchPanel

.\build-hooks.bat; ExitOnError
SignItem @("artifacts/win-sshproxy.exe",
"artifacts/podman.exe",
Expand All @@ -151,15 +124,18 @@ if ($gvExists) {
# } else {
# $env:IncludePolicyJSON = "Skip"
# }
.\build-msi.bat $ENV:INSTVER; ExitOnError
SignItem @("podman.msi")
if (Test-Path ./obj) {
Remove-Item ./obj -Recurse -Force -Confirm:$false
}
dotnet build podman.wixproj /property:DefineConstants="VERSION=$ENV:INSTVER" -o .; ExitOnError
SignItem @("en-US\podman.msi")

.\build-burn.bat $ENV:INSTVER; ExitOnError
insignia -ib podman-setup.exe -o engine.exe; ExitOnError
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")

$file = "podman-$version$suffix-setup.exe"
insignia -ab engine.exe podman-setup.exe -o $file; ExitOnError
wix burn reattach -engine engine.exe podman-setup.exe -o $file; ExitOnError
SignItem @("$file")

if (Test-Path -Path shasums) {
Expand Down
87 changes: 37 additions & 50 deletions contrib/win-installer/burn.wxs
Original file line number Diff line number Diff line change
@@ -1,50 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?ifndef var.VERSION?>
<?error VERSION must be defined via command line argument?>
<?endif?>
<Bundle Name="Podman" Version="$(var.VERSION)" Manufacturer="Red Hat"
UpgradeCode="f3e1f40a-a791-49b7-9bc6-050975293353" IconSourceFile="resources\podman-logo.ico"
Compressed="yes">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkSidebarLicense">
<bal:WixStandardBootstrapperApplication LicenseUrl=""
ThemeFile="podman-theme.xml"
LocalizationFile="podman-theme.wxl"
LogoFile="resources\podman-banner2.png"
LogoSideFile="resources\podman-sidebar.png"
SuppressOptionsUI="yes"
ShowVersion="yes"/>
</BootstrapperApplicationRef>
<Variable Name='InstallFolder' Type='string' Value='[ProgramFiles64Folder]RedHat\Podman' bal:Overridable="yes"/>
<Variable Name="VERSION" Value="$(var.VERSION)"/>
<Variable Name="MachineProvider" Type="string" Value="wsl" bal:Overridable="yes"/>
<Variable Name="WSLCheckbox" Type="numeric" Value="1" bal:Overridable="yes"/>
<Variable Name="HyperVCheckbox" Type="numeric" Value="0" bal:Overridable="yes"/>
<Variable Name="AllowOldWin" Type="numeric" Value="0" bal:Overridable="yes"/>
<Variable Name="LaunchTarget" Value="explorer.exe"/>
<Variable Name="LaunchArguments" Value="&quot;[InstallFolder]\podman-for-windows.html&quot;"/>
<Variable Name="SkipConfigFileCreation" Value="0"/>

<util:RegistrySearch Id="PreviousVersionSearch" Variable="PreviousVersion" Result="value" Root="HKLM" Key="SOFTWARE\[WixBundleManufacturer]\Updates\[WixBundleName]" Value="PackageVersion"/>
<util:RegistrySearch Id="PreviousInstallFolderSearch" Root="HKLM" Key="SOFTWARE\[WixBundleManufacturer]\[WixBundleName]" Value="InstallDir" Variable="PreviousInstallFolder" Win64="yes"/>
<util:DirectorySearch Path="[PreviousInstallFolder]" Variable="InstallFolder" After="PreviousInstallFolderSearch" Condition="PreviousInstallFolder" />
<util:RegistrySearch Id="CurrentBuild" Variable="CBNumber" Result="value" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Value="CurrentBuildNumber"/>
<bal:Condition Message="Windows 10 (19041) or later is required to run this application.">
<![CDATA[VersionNT >= v10.0 AND (CBNumber >= 19041 OR AllowOldWin = 1)]]>
</bal:Condition>
<bal:Condition Message="You have an installed development, pre-release version, or alternative build identifying as the same version of this installer. You must uninstall the existing version of Podman first, before proceeding.">
<![CDATA[WixBundleAction <> 5 OR WixBundleInstalled OR WixBundleForcedRestartPackage OR PreviousVersion <> VERSION]]>
</bal:Condition>
<Chain>
<MsiPackage Id="Setup" SourceFile="podman.msi" Vital="yes">
<MsiProperty Name="INSTALLDIR" Value="[InstallFolder]" />
<MsiProperty Name="MACHINE_PROVIDER" Value="[MachineProvider]"/>
<MsiProperty Name="WITH_WSL" Value="[WSLCheckbox]"/>
<MsiProperty Name="WITH_HYPERV" Value="[HyperVCheckbox]"/>
<MsiProperty Name="SKIP_CONFIG_FILE_CREATION" Value="[SkipConfigFileCreation]"/>
</MsiPackage>
<ExePackage DisplayName="WSL Kernel Install" InstallCondition='(MachineProvider = "wsl") AND (WSLCheckbox = 1)' SourceFile="artifacts\podman-wslkerninst.exe"/>
</Chain>
<OptionalUpdateRegistration/>
</Bundle>
</Wix>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
<?ifndef var.VERSION?>
<?error VERSION must be defined via command line argument?>
<?endif?>
<Bundle Name="Podman" Version="$(var.VERSION)" Manufacturer="Red Hat" UpgradeCode="f3e1f40a-a791-49b7-9bc6-050975293353" IconSourceFile="resources\podman-logo.ico" Compressed="yes">
<BootstrapperApplication>
<bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkSidebarLicense" ThemeFile="podman-theme.xml" LocalizationFile="podman-theme.wxl" LogoFile="resources\podman-banner2.png" LogoSideFile="resources\podman-sidebar.png" SuppressOptionsUI="yes" ShowVersion="yes" />
</BootstrapperApplication>
<Variable Name="InstallFolder" Type="formatted" Value="[ProgramFiles64Folder]RedHat\Podman" bal:Overridable="yes" />
<Variable Name="VERSION" Value="$(var.VERSION)" />
<Variable Name="MachineProvider" Type="string" Value="wsl" bal:Overridable="yes" />
<Variable Name="WSLCheckbox" Type="numeric" Value="1" bal:Overridable="yes" />
<Variable Name="HyperVCheckbox" Type="numeric" Value="0" bal:Overridable="yes" />
<Variable Name="AllowOldWin" Type="numeric" Value="0" bal:Overridable="yes" />
<Variable Name="LaunchTarget" Value="explorer.exe" />
<Variable Name="LaunchArguments" Value="&quot;[InstallFolder]\podman-for-windows.html&quot;" />
<Variable Name="SkipConfigFileCreation" Value="0" />

<util:RegistrySearch Id="PreviousVersionSearch" Variable="PreviousVersion" Result="value" Root="HKLM" Key="SOFTWARE\[WixBundleManufacturer]\Updates\[WixBundleName]" Value="PackageVersion" />
<util:RegistrySearch Id="PreviousInstallFolderSearch" Root="HKLM" Key="SOFTWARE\[WixBundleManufacturer]\[WixBundleName]" Value="InstallDir" Variable="PreviousInstallFolder" Bitness="always64" />
<util:DirectorySearch Path="[PreviousInstallFolder]" Variable="InstallFolder" After="PreviousInstallFolderSearch" Condition="PreviousInstallFolder" />
<util:RegistrySearch Id="CurrentBuild" Variable="CBNumber" Result="value" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Value="CurrentBuildNumber" />
<bal:Condition Message="Windows 10 (19041) or later is required to run this application." Condition="VersionNT &gt;= v10.0 AND (CBNumber &gt;= 19041 OR AllowOldWin = 1)" />
<bal:Condition Message="You have an installed development, pre-release version, or alternative build identifying as the same version of this installer. You must uninstall the existing version of Podman first, before proceeding." Condition="WixBundleInstalled OR WixBundleForcedRestartPackage OR PreviousVersion &lt;&gt; VERSION" />
<Chain>
<MsiPackage Id="Setup" SourceFile="en-US\podman.msi" Vital="yes">
<MsiProperty Name="INSTALLDIR" Value="[InstallFolder]" />
<MsiProperty Name="MACHINE_PROVIDER" Value="[MachineProvider]" />
<MsiProperty Name="WITH_WSL" Value="[WSLCheckbox]" />
<MsiProperty Name="WITH_HYPERV" Value="[HyperVCheckbox]" />
<MsiProperty Name="SKIP_CONFIG_FILE_CREATION" Value="[SkipConfigFileCreation]" />
</MsiPackage>
<ExePackage DisplayName="WSL Kernel Install" InstallCondition="(MachineProvider = &quot;wsl&quot;) AND (WSLCheckbox = 1)" SourceFile="artifacts\podman-wslkerninst.exe" DetectCondition="" Permanent="true" />
</Chain>
<OptionalUpdateRegistration />
</Bundle>
</Wix>
12 changes: 12 additions & 0 deletions contrib/win-installer/podman-setup.wixproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="WixToolset.Sdk/5.0.0">
<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" />
<Compile Include="burn.wxs" />
</ItemGroup>
</Project>
Loading

0 comments on commit de9df45

Please sign in to comment.