Add a new Windows installer supporting user scope
Fixes #22994 and #25968 Signed-off-by: Mario Loriedo <mario.loriedo@gmail.com>
38
.github/workflows/release.yml
vendored
@@ -188,10 +188,18 @@ jobs:
|
||||
# functionality. We should avoid clobbering or re-building windows installers in most cases,
|
||||
# For build-only, the .exe is saved in the workflow artifacts for a human
|
||||
# to judge.
|
||||
- name: Build
|
||||
- name: Build the MSI
|
||||
id: build
|
||||
run: |
|
||||
Push-Location contrib\win-installer
|
||||
contrib\win-installer\build.ps1 `
|
||||
-Version ${{steps.getversion.outputs.version}} `
|
||||
-LocalReleaseDirPath ${{ github.workspace }}\release-artifacts `
|
||||
-Architecture ${{ matrix.arch }}
|
||||
Exit $LASTEXITCODE
|
||||
- name: Build the bundle (legacy)
|
||||
id: build-legacy
|
||||
run: |
|
||||
Push-Location contrib\win-installer-legacy
|
||||
.\build.ps1 ${{steps.getversion.outputs.version}} prod ${{ github.workspace }}\release-artifacts
|
||||
$code = $LASTEXITCODE
|
||||
if ($code -eq 2) {
|
||||
@@ -208,26 +216,40 @@ jobs:
|
||||
Push-Location contrib\win-installer
|
||||
Get-ChildItem
|
||||
Pop-Location
|
||||
- name: Rename the installer
|
||||
Push-Location contrib\win-installer-legacy
|
||||
Get-ChildItem
|
||||
Pop-Location
|
||||
- name: Rename the MSI
|
||||
run: |
|
||||
Push-Location contrib\win-installer
|
||||
Copy-Item -Path podman-${{steps.getversion.outputs.version}}.msi -Destination podman-installer-windows-${{ matrix.arch }}.msi
|
||||
Pop-Location
|
||||
- name: Rename the bundle (legacy)
|
||||
run: |
|
||||
Push-Location contrib\win-installer-legacy
|
||||
Copy-Item -Path podman-${{steps.getversion.outputs.version}}-setup.exe -Destination podman-installer-windows-${{ matrix.arch }}.exe
|
||||
Pop-Location
|
||||
- name: Upload the installer
|
||||
- name: Upload the MSI
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: win-msi-${{ matrix.arch }}
|
||||
path: |
|
||||
.\contrib\win-installer\podman-installer-windows-${{ matrix.arch }}.msi
|
||||
- name: Upload the bundle (legacy)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: win-installer-${{ matrix.arch }}
|
||||
path: |
|
||||
.\contrib\win-installer\podman-installer-windows-${{ matrix.arch }}.exe
|
||||
.\contrib\win-installer-legacy\podman-installer-windows-${{ matrix.arch }}.exe
|
||||
# For backwards compatibility, we also upload the amd64 windows
|
||||
# installer using the old name
|
||||
- name: Upload the installer (legacy)
|
||||
- name: Upload the bundle with the old name (legacy)
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ matrix.arch == 'amd64' }}
|
||||
with:
|
||||
name: win-installer
|
||||
path: |
|
||||
.\contrib\win-installer\podman-${{steps.getversion.outputs.version}}-setup.exe
|
||||
.\contrib\win-installer-legacy\podman-${{steps.getversion.outputs.version}}-setup.exe
|
||||
|
||||
release:
|
||||
name: Create Release
|
||||
@@ -266,6 +288,8 @@ jobs:
|
||||
mv mac-installers/* release-artifacts
|
||||
mv win-installer-amd64/* release-artifacts
|
||||
mv win-installer-arm64/* release-artifacts
|
||||
mv win-msi-amd64/* release-artifacts
|
||||
mv win-msi-arm64/* release-artifacts
|
||||
pushd release-artifacts
|
||||
sha256sum * > shasums
|
||||
popd
|
||||
|
||||
8
.github/workflows/upload-win-installer.yml
vendored
@@ -64,7 +64,7 @@ jobs:
|
||||
- name: Check
|
||||
id: check
|
||||
run: |
|
||||
Push-Location contrib\win-installer
|
||||
Push-Location contrib\win-installer-legacy
|
||||
.\check.ps1 ${{steps.getversion.outputs.version}}
|
||||
$code = $LASTEXITCODE
|
||||
if ($code -eq 2) {
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
id: build
|
||||
if: steps.check.outputs.already-exists != 'true' || steps.actual_dryrun.outputs.dryrun == 'true'
|
||||
run: |
|
||||
Push-Location contrib\win-installer
|
||||
Push-Location contrib\win-installer-legacy
|
||||
.\build.ps1 ${{steps.getversion.outputs.version}} prod
|
||||
$code = $LASTEXITCODE
|
||||
if ($code -eq 2) {
|
||||
@@ -125,7 +125,7 @@ jobs:
|
||||
name: installer
|
||||
path: |
|
||||
${{ steps.check.outputs.upload_asset_name }}
|
||||
.\contrib\win-installer\shasums
|
||||
.\contrib\win-installer-legacy\shasums
|
||||
- name: Upload
|
||||
if: >-
|
||||
steps.actual_dryrun.outputs.dryrun == 'false' &&
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
Push-Location contrib\win-installer
|
||||
Push-Location contrib\win-installer-legacy
|
||||
$version = "${{ steps.getversion.outputs.version }}"
|
||||
if ($version[0] -ne "v") {
|
||||
$version = "v$version"
|
||||
|
||||
279
build_windows.md
@@ -9,7 +9,7 @@ Windows.
|
||||
- [Requirements](#requirements)
|
||||
- [OS requirements](#os-requirements)
|
||||
- [Git and go](#git-and-go)
|
||||
- [Pandoc](#pandoc)
|
||||
- [Pandoc (optional)](#pandoc-optional)
|
||||
- [.NET SDK](#net-sdk)
|
||||
- [Virtualization Provider](#virtualization-provider)
|
||||
- [WSL](#wsl)
|
||||
@@ -25,9 +25,10 @@ Windows.
|
||||
- [Build and test the Podman Windows installer](#build-and-test-the-podman-windows-installer)
|
||||
- [Build the Windows installer](#build-the-windows-installer)
|
||||
- [Test the Windows installer](#test-the-windows-installer)
|
||||
- [Build and test the standalone `podman.msi` file](#build-and-test-the-standalone-podmanmsi-file)
|
||||
- [Verify the installation](#verify-the-installation)
|
||||
- [Run the Windows installer automated tests](#run-the-windows-installer-automated-tests)
|
||||
- [Verify the installation](#verify-the-installation)
|
||||
- [Uninstall and clean-up](#uninstall-and-clean-up)
|
||||
- [Retrieve Podman installed products](#retrieve-podman-installed-products)
|
||||
- [Validate changes before submitting a PR](#validate-changes-before-submitting-a-pr)
|
||||
- [winmake lint](#winmake-lint)
|
||||
- [winmake validatepr](#winmake-validatepr)
|
||||
@@ -86,9 +87,15 @@ winget install -e Microsoft.DotNet.SDK.8
|
||||
used too and can be installed using `dotnet install`:
|
||||
|
||||
```pwsh
|
||||
dotnet tool install --global wix
|
||||
dotnet tool install --global wix --version 5.0.2
|
||||
```
|
||||
|
||||
:information_source: Because WiX Toolset has changed its licensing model when v6
|
||||
was released, [Podman still uses the WiX Toolset
|
||||
v5.0.2](https://github.com/containers/podman/issues/27042)
|
||||
and we recommend using it as well for local development (although it's not
|
||||
strictly required).
|
||||
|
||||
### Virtualization Provider
|
||||
|
||||
Running Podman on Windows requires a virtualization provider. The supported
|
||||
@@ -125,7 +132,7 @@ Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
|
||||
After running this command, a restart of the Windows machine is required.
|
||||
|
||||
:information_source: Configure the VM provider used by podman (Hyper-V or WSL)
|
||||
in the file `%PROGRAMDATA%/containers/containers.conf`.
|
||||
in the file `%APPDATA%/containers/containers.conf`.
|
||||
[More on that later](#create-a-configuration-file-optional).
|
||||
|
||||
## Get the source code
|
||||
@@ -242,9 +249,9 @@ To test some particular configurations of Podman, create a `containers.conf`
|
||||
file:
|
||||
|
||||
```
|
||||
New-Item -ItemType Directory $env:PROGRAMDATA\containers\
|
||||
New-Item -ItemType File $env:PROGRAMDATA\containers\containers.conf
|
||||
notepad $env:PROGRAMDATA\containers\containers.conf
|
||||
New-Item -ItemType Directory $env:APPDATA\containers\
|
||||
New-Item -ItemType File $env:APPDATA\containers\containers.conf
|
||||
notepad $env:APPDATA\containers\containers.conf
|
||||
```
|
||||
|
||||
For example, to test with Hyper-V as the virtualization provider, use the
|
||||
@@ -288,15 +295,15 @@ To learn how to use the Podman client, refer to its
|
||||
|
||||
## Build and test the Podman Windows installer
|
||||
|
||||
The Podman Windows installer (e.g., `podman-5.1.0-dev-setup.exe`) is a bundle
|
||||
that includes an msi package (`podman.msi`). It's built using the
|
||||
[WiX Toolset](https://wixtoolset.org/) and the
|
||||
[PanelSwWixExtension](https://github.com/nirbar/PanelSwWixExtension/tree/master5)
|
||||
WiX extension. The source code is in the folder `contrib\win-installer`.
|
||||
The Podman Windows installer (e.g., `podman-5.7.0.msi`) is an MSI package
|
||||
built using the [WiX Toolset](https://wixtoolset.org/) v5. The installer
|
||||
supports installation at both user scope (per-user) and machine scope
|
||||
(per-machine/administrator). The source code is in the folder
|
||||
`contrib\win-installer`.
|
||||
|
||||
### Build the Windows installer
|
||||
|
||||
To build the installation bundle, run the following command:
|
||||
To build the MSI installer, run the following command:
|
||||
|
||||
```pwsh
|
||||
.\winmake.ps1 installer
|
||||
@@ -306,14 +313,15 @@ To build the installation bundle, run the following command:
|
||||
required before running this command.
|
||||
|
||||
Locate the installer in the `contrib\win-installer` folder (relative to checkout
|
||||
root) with a name like `podman-5.2.0-dev-setup.exe`.
|
||||
root) with a name like `podman-5.7.0.msi`, where `5.7.0` is the version of
|
||||
Podman on the local branch.
|
||||
|
||||
The `installer` target of `winmake.ps1` runs the script
|
||||
`contrib\win-installer\build.ps1` that, in turns, executes:
|
||||
- `dotnet build podman.wixproj`: builds `podman.msi` from the WiX source files `podman.wxs`,
|
||||
`pages.wxs`, `podman-ui.wxs` and `welcome-install-dlg.wxs`.
|
||||
- `dotnet build podman-setup.wixproj`: builds `podman-setup.exe` file from
|
||||
[WiX Burn bundle](https://wixtoolset.org/docs/tools/burn/) `burn.wxs`.
|
||||
`contrib\win-installer\build.ps1` that, in turn, executes:
|
||||
|
||||
- `dotnet build podman.wixproj`: builds `podman.msi` from the WiX source files
|
||||
`wix\podman-main.wxs`, `wix\podman-ui-main.wxs`, and
|
||||
`wix\podman-ui-welcome-dlg.wxs`.
|
||||
|
||||
### Test the Windows installer
|
||||
|
||||
@@ -321,37 +329,54 @@ Double-click on the Windows installer to run it. To get the installation logs
|
||||
with debug information, running it via the command line is recommended:
|
||||
|
||||
```pwsh
|
||||
contrib\win-installer\podman-5.1.0-dev-setup.exe /install /log podman-setup.log
|
||||
msiexec /package contrib\win-installer\podman-5.7.0.msi /l*v podman-msi.log
|
||||
```
|
||||
|
||||
It generates the files `podman-setup.log` and `podman-setup_000_Setup.log`,
|
||||
which include detailed installation information, in the current directory.
|
||||
It generates the file `podman-msi.log`, which includes detailed installation
|
||||
information, in the current directory.
|
||||
|
||||
Run it in `quiet` mode to automate the installation and avoid interacting with
|
||||
the GUI. Open the terminal **as an administrator**, add the `/quiet` option, and
|
||||
set the bundle variable `MachineProvider` (`wsl` or `hyperv`):
|
||||
The MSI installer supports both user-scope and machine-scope installations:
|
||||
|
||||
- **User scope (per-user)**: No administrator privileges required. Files are
|
||||
installed in the user's profile directory, and the PATH is updated only for
|
||||
the current user. This is the default scope.
|
||||
|
||||
- **Machine scope (per-machine)**: Requires administrator privileges. Files are
|
||||
installed in `Program Files`, and the PATH is updated for all users.
|
||||
|
||||
To run an automated installation in quiet, non-interactive mode and set the
|
||||
machine provider (`wsl` or `hyperv`), use the following command:
|
||||
|
||||
**User scope installation** (no administrator required):
|
||||
|
||||
```pwsh
|
||||
contrib\win-installer\podman-5.1.0-dev-setup.exe /install `
|
||||
/log podman-setup.log /quiet `
|
||||
MachineProvider=wsl
|
||||
msiexec /package contrib\win-installer\podman-5.7.0.msi /l*v podman-msi.log `
|
||||
/quiet MSIINSTALLPERUSER=1 MACHINE_PROVIDER=wsl
|
||||
```
|
||||
|
||||
**Machine scope installation** (requires administrator terminal):
|
||||
|
||||
```pwsh
|
||||
msiexec /package contrib\win-installer\podman-5.7.0.msi /l*v podman-msi.log `
|
||||
/quiet ALLUSERS=1 MACHINE_PROVIDER=wsl
|
||||
```
|
||||
|
||||
: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:
|
||||
inconsistent state. Podman results as uninstalled, but the MSI package is still
|
||||
tracked in the Windows registry and will affect further attempts to reinstall
|
||||
Podman. When this is the case, trying to reinstall Podman results in the
|
||||
installer returning zero (success) but no action is executed. The package
|
||||
`GUID` can be found in the installation logs:
|
||||
|
||||
```
|
||||
Detected related package: {<GID>}
|
||||
```log
|
||||
Product: Podman CLI -- Installation completed successfully.
|
||||
ProductCode: {<GUID>}
|
||||
```
|
||||
|
||||
To fix this problem remove the related packages:
|
||||
To fix this problem, remove the tracked package:
|
||||
|
||||
```pwsh
|
||||
msiexec /x "{<GID>}"
|
||||
msiexec /x "{<GUID>}"
|
||||
```
|
||||
|
||||
#### Run the Windows installer automated tests
|
||||
@@ -363,66 +388,46 @@ it requires an administrator terminal.
|
||||
.\winmake.ps1 installertest [wsl|hyperv]
|
||||
```
|
||||
|
||||
### Build and test the standalone `podman.msi` file
|
||||
#### Verify the installation
|
||||
|
||||
Building and testing the standalone `podman.msi` package during development may
|
||||
be useful. Even if this package is not published as a standalone file when
|
||||
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 command `dotnet build` to build the standalone `podman.msi` file:
|
||||
|
||||
```pwsh
|
||||
Push-Location .\contrib\win-installer\
|
||||
dotnet build podman.wixproj /property:DefineConstants="VERSION=9.9.9" -o .
|
||||
Pop-Location
|
||||
```
|
||||
|
||||
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\en-US\podman.msi /l*v podman-msi.log
|
||||
```
|
||||
|
||||
To run it in quiet, non-interactive mode, open the terminal **as an
|
||||
administrator**, add the `/quiet` option, and set the MSI property
|
||||
`MACHINE_PROVIDER` (`wsl` or `hyperv`):
|
||||
|
||||
```pwsh
|
||||
msiexec /package contrib\win-installer\en-US\podman.msi /l*v podman-msi.log /quiet MACHINE_PROVIDER=wsl
|
||||
```
|
||||
|
||||
:information_source: `podman.msi` GUI dialogs, defined in the file
|
||||
`contrib\win-installer\welcome-install-dlg.wxs`, are distinct from the installation bundle
|
||||
`podman-setup.exe` GUI dialogs, defined in
|
||||
`contrib\win-installer\podman-theme.xml`.
|
||||
|
||||
### Verify the installation
|
||||
|
||||
Inspect the msi installation log `podman-msi.log` (or
|
||||
`podman-setup_000_Setup.log` if testing with the bundle) to verify that the
|
||||
Inspect the MSI installation log `podman-msi.log` to verify that the
|
||||
installation was successful:
|
||||
|
||||
```pwsh
|
||||
Select-String -Path "podman-msi.log" -Pattern "Installation success or error status: 0"
|
||||
```
|
||||
|
||||
These commands too are helpful to check the installation:
|
||||
The following commands are helpful to check the installation:
|
||||
|
||||
**For machine scope (per-machine) installations:**
|
||||
|
||||
```pwsh
|
||||
# Check the copy of the podman client in the Podman folder
|
||||
Test-Path -Path "$ENV:PROGRAMFILES\RedHat\Podman\podman.exe"
|
||||
Test-Path -Path "$ENV:PROGRAMFILES\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 }
|
||||
# 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
|
||||
Test-Path -Path "HKLM:\SOFTWARE\Podman"
|
||||
Get-ItemProperty "HKLM:\SOFTWARE\Podman" InstallDir
|
||||
# Check that podman.exe is in the $PATH
|
||||
$env:PATH | Select-String -Pattern "Podman"
|
||||
```
|
||||
|
||||
**For user scope (per-user) installations:**
|
||||
|
||||
```pwsh
|
||||
# Check the copy of the podman client in the Podman folder
|
||||
Test-Path -Path "$ENV:LOCALAPPDATA\Programs\Podman\podman.exe"
|
||||
# Check the generation of the podman configuration file
|
||||
Test-Path -Path "$ENV:APPDATA\containers\containers.conf.d\99-podman-machine-provider.conf"
|
||||
# Check that the installer configured the right provider
|
||||
Get-Content "$ENV:APPDATA\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 "HKCU:\SOFTWARE\Podman"
|
||||
Get-ItemProperty "HKCU:\SOFTWARE\Podman" InstallDir
|
||||
# Check that podman.exe is in the $PATH
|
||||
$env:PATH | Select-String -Pattern "Podman"
|
||||
```
|
||||
|
||||
@@ -437,44 +442,125 @@ $ENV:CONTAINERS_MACHINE_PROVIDER='hyperv'; .\contrib\cirrus\win-installer-main.p
|
||||
|
||||
### Uninstall and clean-up
|
||||
|
||||
Podman can be uninstalled from the Windows Control Panel or running the
|
||||
following command from a terminal **as an administrator**:
|
||||
Podman can be uninstalled from the Windows Control Panel or using the MSI
|
||||
uninstall command. Administrator privileges will be required if Podman was
|
||||
installed for the machine, rather than for a user:
|
||||
|
||||
```pwsh
|
||||
contrib\win-installer\podman-5.1.0-dev-setup.exe /uninstall /quiet /log podman-setup-uninstall.log
|
||||
msiexec /x contrib\win-installer\podman-5.7.0.msi /quiet /l*v podman-msi-uninstall.log
|
||||
```
|
||||
|
||||
The uninstaller does not delete some folders. Clean them up manually:
|
||||
|
||||
**For machine scope installations:**
|
||||
|
||||
```pwsh
|
||||
$extraFolders = @(
|
||||
"$ENV:PROGRAMDATA\containers\"
|
||||
"$ENV:LOCALAPPDATA\containers\"
|
||||
"$env:USERPROFILE.config\containers\"
|
||||
"$env:USERPROFILE.local\share\containers\"
|
||||
)
|
||||
$extraFolders | ForEach-Object {Remove-Item -Recurse -Force $PSItem}
|
||||
"$env:USERPROFILE\.config\containers\"
|
||||
"$env:USERPROFILE\.local\share\containers\"
|
||||
)
|
||||
$extraFolders | ForEach-Object {Remove-Item -Recurse -Force $PSItem -ErrorAction SilentlyContinue}
|
||||
```
|
||||
|
||||
**For user scope installations:**
|
||||
|
||||
```pwsh
|
||||
$extraFolders = @(
|
||||
"$ENV:APPDATA\containers\"
|
||||
"$ENV:LOCALAPPDATA\containers\"
|
||||
"$env:USERPROFILE\.config\containers\"
|
||||
"$env:USERPROFILE\.local\share\containers\"
|
||||
)
|
||||
$extraFolders | ForEach-Object {Remove-Item -Recurse -Force $PSItem -ErrorAction SilentlyContinue}
|
||||
```
|
||||
|
||||
The following commands are helpful to verify that the uninstallation was
|
||||
successful:
|
||||
|
||||
**For machine scope installations:**
|
||||
|
||||
```pwsh
|
||||
# Inspect the uninstallation log for a success message
|
||||
Select-String -Path "podman-setup-uninstall_000_Setup.log" -Pattern "Removal success or error status: 0"
|
||||
Select-String -Path "podman-msi-uninstall.log" -Pattern "Removal success or error status: 0"
|
||||
# Check that the uninstaller removed Podman resources
|
||||
$foldersToCheck = @(
|
||||
"$ENV:PROGRAMFILES\RedHat\Podman\podman.exe"
|
||||
"HKLM:\SOFTWARE\Red Hat\Podman"
|
||||
"$ENV:PROGRAMFILES\Podman\podman.exe"
|
||||
"HKLM:\SOFTWARE\Podman"
|
||||
"$ENV:PROGRAMDATA\containers\"
|
||||
"$env:USERPROFILE.config\containers\"
|
||||
"$env:USERPROFILE.local\share\containers\"
|
||||
"$ENV:LOCALAPPDATA\containers\"
|
||||
"$env:USERPROFILE\.config\containers\"
|
||||
"$env:USERPROFILE\.local\share\containers\"
|
||||
"$ENV:APPDATA\containers\"
|
||||
"$ENV:PROGRAMDATA\containers\containers.conf.d\99-podman-machine-provider.conf"
|
||||
)
|
||||
$foldersToCheck | ForEach-Object {Test-Path -Path $PSItem}
|
||||
```
|
||||
|
||||
**For user scope installations:**
|
||||
|
||||
```pwsh
|
||||
# Inspect the uninstallation log for a success message
|
||||
Select-String -Path "podman-msi-uninstall.log" -Pattern "Removal success or error status: 0"
|
||||
# Check that the uninstaller removed Podman resources
|
||||
$foldersToCheck = @(
|
||||
"$ENV:PROGRAMFILES\Podman\podman.exe"
|
||||
"HKCU:\SOFTWARE\Podman"
|
||||
"$ENV:APPDATA\containers\"
|
||||
"$env:USERPROFILE\.config\containers\"
|
||||
"$env:USERPROFILE\.local\share\containers\"
|
||||
"$ENV:LOCALAPPDATA\containers\"
|
||||
"$ENV:APPDATA\containers\containers.conf.d\99-podman-machine-provider.conf"
|
||||
)
|
||||
$foldersToCheck | ForEach-Object {Test-Path -Path $PSItem}
|
||||
```
|
||||
|
||||
#### Retrieve Podman installed products
|
||||
|
||||
MSI uninstallations can leave the package tracked in the Windows registry. This
|
||||
can cause issues when trying to reinstall Podman. The following command can be
|
||||
used to retrieve the package information:
|
||||
|
||||
```pwsh
|
||||
$Installer = New-Object -ComObject WindowsInstaller.Installer
|
||||
$InstallerProducts = $Installer.ProductsEx("", "", 7)
|
||||
$InstalledProducts = ForEach($Product in $InstallerProducts){
|
||||
try {
|
||||
$ProductCode = $Product.ProductCode()
|
||||
$LocalPackage = try { $Product.InstallProperty("LocalPackage") } catch { "Unknown" }
|
||||
$VersionString = try { $Product.InstallProperty("VersionString") } catch { "Unknown" }
|
||||
$ProductName = $Product.InstallProperty("ProductName")
|
||||
|
||||
[PSCustomObject]@{
|
||||
ProductCode = $ProductCode
|
||||
LocalPackage = $LocalPackage
|
||||
VersionString = $VersionString
|
||||
ProductName = $ProductName
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to process product: $($_.Exception.Message)"
|
||||
# Skip this product and continue
|
||||
continue
|
||||
}
|
||||
}
|
||||
$InstalledProducts | Where-Object {$_.ProductName -match "podman"}
|
||||
```
|
||||
|
||||
This command returns a list of installed Podman products:
|
||||
|
||||
```log
|
||||
ProductCode LocalPackage VersionString ProductName
|
||||
----------- ------------ ------------- -----------
|
||||
{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} Unknown Unknown Podman
|
||||
```
|
||||
|
||||
The product code can be used to uninstall the Podman package:
|
||||
|
||||
```pwsh
|
||||
msiexec /x "{<product-code>}"
|
||||
```
|
||||
|
||||
## Validate changes before submitting a PR
|
||||
|
||||
The script `winmake.ps1` has a couple of targets to check the source code
|
||||
@@ -499,7 +585,6 @@ tools:
|
||||
pip install pre-commit
|
||||
```
|
||||
|
||||
|
||||
### winmake validatepr
|
||||
|
||||
Target `validatepr` performs a more exhaustive validation but takes
|
||||
|
||||
@@ -3,41 +3,71 @@
|
||||
. $PSScriptRoot\win-lib.ps1
|
||||
. $PSScriptRoot\..\win-installer\utils.ps1
|
||||
|
||||
if ($Env:CI -eq "true") {
|
||||
if ($Env:CIRRUS_CI -eq "true") {
|
||||
$WIN_INST_FOLDER = "$ENV:CIRRUS_WORKING_DIR\repo\contrib\win-installer"
|
||||
$RELEASE_DIR = "$ENV:CIRRUS_WORKING_DIR\repo"
|
||||
} else {
|
||||
$WIN_INST_FOLDER = "$PSScriptRoot\..\win-installer"
|
||||
$ENV:WIN_INST_VER = "9.9.9"
|
||||
$RELEASE_DIR = "$PSScriptRoot\..\..\contrib\win-installer\current"
|
||||
$RELEASE_DIR = Resolve-Path -Path "$PSScriptRoot\..\..\contrib\win-installer\current"
|
||||
if ($null -eq $ENV:CONTAINERS_MACHINE_PROVIDER) { $ENV:CONTAINERS_MACHINE_PROVIDER = 'wsl' }
|
||||
}
|
||||
$ENV:LATEST_GH_RELEASE_ID = "199677288" # v5.4.0
|
||||
|
||||
Push-Location $WIN_INST_FOLDER
|
||||
$ENV:PODMAN_ARCH = Get-Current-Architecture # on Cirrus CI this should always be amd64
|
||||
|
||||
# Build and test the windows installer
|
||||
# To get the a GitHub release ID run the following command:
|
||||
# curl -s -H "Accept: application/vnd.github+json" \
|
||||
# https://api.github.com/repos/containers/podman/releases/tags/v5.6.2 | jq '.id'
|
||||
$ENV:LATEST_GH_RELEASE_ID = "251232431" # v5.6.2
|
||||
$NEXT_WIN_INST_VER="9.9.10"
|
||||
|
||||
# Download the previous installer to test a major update
|
||||
|
||||
if (!$env:PREV_SETUP_EXE_PATH) {
|
||||
$env:PREV_SETUP_EXE_PATH = Get-Podman-Setup-From-GitHub $ENV:LATEST_GH_RELEASE_ID
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Build and test the new windows installer msi package
|
||||
#########################################################
|
||||
|
||||
$installer_folder = Resolve-Path -Path "$WIN_INST_FOLDER"
|
||||
|
||||
# Note: consumes podman-remote-release-windows_amd64.zip from repo.tar.zst
|
||||
Run-Command "${installer_folder}\build.ps1 -Version `"$Env:WIN_INST_VER`" -Architecture `"$ENV:PODMAN_ARCH`" -LocalReleaseDirPath `"$RELEASE_DIR`""
|
||||
|
||||
# Build a v9.9.10 installer to test an update from current to next version
|
||||
Run-Command "${installer_folder}\build.ps1 -Version `"$NEXT_WIN_INST_VER`" -Architecture `"$ENV:PODMAN_ARCH`" -LocalReleaseDirPath `"$RELEASE_DIR`""
|
||||
|
||||
# Run the installer silently and WSL/HyperV install options disabled (prevent reboots)
|
||||
$command = "${installer_folder}\test.ps1 "
|
||||
$command += "-scenario all "
|
||||
$command += "-provider $ENV:CONTAINERS_MACHINE_PROVIDER "
|
||||
$command += "-msiPath `"${installer_folder}\podman-$ENV:WIN_INST_VER.msi`" "
|
||||
$command += "-nextMsiPath `"${installer_folder}\podman-$NEXT_WIN_INST_VER.msi`" "
|
||||
$command += "-previousSetupExePath `"$env:PREV_SETUP_EXE_PATH`""
|
||||
Run-Command "${command}"
|
||||
|
||||
#########################################################
|
||||
# Build and test the legacy windows installer setup bundle
|
||||
#########################################################
|
||||
|
||||
$installer_folder = Resolve-Path -Path "$WIN_INST_FOLDER-legacy"
|
||||
|
||||
Push-Location "${installer_folder}"
|
||||
|
||||
# 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 = "${installer_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 += "-setupExePath `"${installer_folder}\podman-$ENV:WIN_INST_VER-dev-setup.exe`" "
|
||||
$command += "-previousSetupExePath `"$env:PREV_SETUP_EXE_PATH`" "
|
||||
$command += "-nextSetupExePath `"${installer_folder}\podman-$NEXT_WIN_INST_VER-dev-setup.exe`" "
|
||||
Run-Command "${command}"
|
||||
|
||||
13
contrib/win-installer-legacy/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
artifacts/
|
||||
current/
|
||||
docs/
|
||||
en-US/
|
||||
fetch/
|
||||
podman-*setup.exe
|
||||
engine.exe
|
||||
obj/
|
||||
shasums
|
||||
*.wixobj
|
||||
*.wixpdb
|
||||
*.log
|
||||
*.msi
|
||||
@@ -49,15 +49,28 @@ contrib\win-installer\podman-9.9.9-dev-setup.exe /x /log contrib\win-installer\p
|
||||
## retrieve installed podman msi package information
|
||||
|
||||
```pwsh
|
||||
$Installer = New-Object -ComObject WindowsInstaller.Installer;
|
||||
$InstallerProducts = $Installer.ProductsEx("", "", 7);
|
||||
$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")
|
||||
}
|
||||
};
|
||||
try {
|
||||
$ProductCode = $Product.ProductCode()
|
||||
$LocalPackage = try { $Product.InstallProperty("LocalPackage") } catch { "Unknown" }
|
||||
$VersionString = try { $Product.InstallProperty("VersionString") } catch { "Unknown" }
|
||||
$ProductName = $Product.InstallProperty("ProductName")
|
||||
|
||||
[PSCustomObject]@{
|
||||
ProductCode = $ProductCode
|
||||
LocalPackage = $LocalPackage
|
||||
VersionString = $VersionString
|
||||
ProductName = $ProductName
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to process product: $($_.Exception.Message)"
|
||||
# Skip this product and continue
|
||||
continue
|
||||
}
|
||||
}
|
||||
$InstalledProducts | Where-Object {$_.ProductName -match "podman"}
|
||||
```
|
||||
|
||||
156
contrib/win-installer-legacy/build.ps1
Normal file
@@ -0,0 +1,156 @@
|
||||
function ExitOnError() {
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Exit 1
|
||||
}
|
||||
}
|
||||
|
||||
function SignItem() {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string[]]$fileNames
|
||||
)
|
||||
|
||||
foreach ($val in $ENV:APP_ID, $ENV:TENANT_ID, $ENV:CLIENT_SECRET, $ENV:CERT_NAME) {
|
||||
if (!$val) {
|
||||
Write-Host "Skipping signing (no config)"
|
||||
Return
|
||||
}
|
||||
}
|
||||
|
||||
CheckCommand AzureSignTool.exe "AzureSignTool"
|
||||
|
||||
AzureSignTool.exe sign -du "https://github.com/containers/podman" `
|
||||
-kvu "https://$ENV:VAULT_ID.vault.azure.net" `
|
||||
-kvi $ENV:APP_ID `
|
||||
-kvt $ENV:TENANT_ID `
|
||||
-kvs $ENV:CLIENT_SECRET `
|
||||
-kvc $ENV:CERT_NAME `
|
||||
-tr http://timestamp.digicert.com $fileNames
|
||||
|
||||
ExitOnError
|
||||
}
|
||||
|
||||
function CheckCommand() {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $cmd,
|
||||
[Parameter(Mandatory)]
|
||||
[string] $description
|
||||
)
|
||||
|
||||
if (! (Get-Command $cmd -errorAction SilentlyContinue)) {
|
||||
Write-Host "Required dep `"$description`" is not installed"
|
||||
Exit 1
|
||||
}
|
||||
}
|
||||
|
||||
function CheckRequirements() {
|
||||
CheckCommand "wix" "WiX Toolset"
|
||||
CheckCommand "go" "Golang"
|
||||
}
|
||||
|
||||
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:PODMAN_ARCH - Installer target platform (x64 or arm64)'
|
||||
Write-Host 'Env Settings for signing (optional)'
|
||||
Write-Host ' $ENV:VAULT_ID'
|
||||
Write-Host ' $ENV:APP_ID'
|
||||
Write-Host ' $ENV:TENANT_ID'
|
||||
Write-Host ' $ENV:CLIENT_SECRET'
|
||||
Write-Host ' $ENV:CERT_NAME'
|
||||
Write-Host
|
||||
Write-Host "Example: Download and build from the official Github release (dev output): "
|
||||
Write-Host " .\build.ps1 4.2.0"
|
||||
Write-Host
|
||||
Write-Host "Example: Build a dev build from a pre-download release "
|
||||
Write-Host " .\build.ps1 4.2.0 dev fetchdir"
|
||||
Write-Host
|
||||
|
||||
Exit 1
|
||||
}
|
||||
|
||||
# Pre-set to standard locations in-case build env does not refresh paths
|
||||
$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
|
||||
|
||||
$version = $args[0]
|
||||
|
||||
if ($version[0] -eq "v") {
|
||||
$version = $version.Substring(1)
|
||||
}
|
||||
|
||||
$suffix = "-dev"
|
||||
if ($args.Count -gt 1 -and $args[1] -eq "prod") {
|
||||
$suffix = ""
|
||||
}
|
||||
|
||||
$releaseDir = ""
|
||||
if ($args.Count -gt 2) {
|
||||
$releaseDir = $args[2]
|
||||
}
|
||||
|
||||
Push-Location $PSScriptRoot
|
||||
.\process-release.ps1 $version $releaseDir
|
||||
if ($LASTEXITCODE -eq 2) {
|
||||
Write-Host "Skip signaled, relaying skip"
|
||||
Exit 2
|
||||
}
|
||||
if ($ENV:INSTVER -eq "") {
|
||||
Write-Host "process-release did not define an install version!"
|
||||
Exit 1
|
||||
}
|
||||
|
||||
$installerPlatform = ""
|
||||
if ($null -eq $ENV:PODMAN_ARCH -or "" -eq $ENV:PODMAN_ARCH -or "amd64" -eq $ENV:PODMAN_ARCH) {
|
||||
$installerPlatform = "x64"
|
||||
} elseif ($ENV:PODMAN_ARCH -eq "arm64") {
|
||||
$installerPlatform = "arm64"
|
||||
} else {
|
||||
Write-Host "Unknown architecture $ENV:PODMAN_ARCH. Valid options are amd64 or arm64."
|
||||
Exit 1
|
||||
}
|
||||
|
||||
SignItem @("artifacts/win-sshproxy.exe",
|
||||
"artifacts/podman.exe")
|
||||
$gvExists = Test-Path "artifacts/gvproxy.exe"
|
||||
if ($gvExists) {
|
||||
SignItem @("artifacts/gvproxy.exe")
|
||||
Remove-Item Env:\UseGVProxy -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
$env:UseGVProxy = "Skip"
|
||||
}
|
||||
|
||||
# Retaining for possible future additions
|
||||
# $pExists = Test-Path "artifacts/policy.json"
|
||||
# if ($pExists) {
|
||||
# Remove-Item Env:\IncludePolicyJSON -ErrorAction SilentlyContinue
|
||||
# } else {
|
||||
# $env:IncludePolicyJSON = "Skip"
|
||||
# }
|
||||
if (Test-Path ./obj) {
|
||||
Remove-Item ./obj -Recurse -Force -Confirm:$false
|
||||
}
|
||||
dotnet build podman.wixproj /property:DefineConstants="VERSION=$ENV:INSTVER" /property:InstallerPlatform="$installerPlatform" -o .; ExitOnError
|
||||
SignItem @("en-US\podman.msi")
|
||||
|
||||
dotnet build podman-setup.wixproj /property:DefineConstants="VERSION=$ENV:INSTVER" /property:InstallerPlatform="$installerPlatform" -o .; ExitOnError
|
||||
wix burn detach podman-setup.exe -engine engine.exe; ExitOnError
|
||||
SignItem @("engine.exe")
|
||||
|
||||
$file = "podman-$version$suffix-setup.exe"
|
||||
wix burn reattach -engine engine.exe podman-setup.exe -o $file; ExitOnError
|
||||
SignItem @("$file")
|
||||
|
||||
if (Test-Path -Path shasums) {
|
||||
$hash = (Get-FileHash -Algorithm SHA256 $file).Hash.ToLower()
|
||||
Write-Output "$hash $file" | Out-File -Append -FilePath shasums
|
||||
}
|
||||
|
||||
Write-Host "Complete"
|
||||
Get-ChildItem "podman-$version$suffix-setup.exe"
|
||||
Pop-Location
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -35,7 +35,7 @@ param (
|
||||
[switch]$skipConfigFileCreation=$false
|
||||
)
|
||||
|
||||
. $PSScriptRoot\utils.ps1
|
||||
. $PSScriptRoot\..\win-installer\utils.ps1
|
||||
|
||||
$MachineConfPath = "$env:ProgramData\containers\containers.conf.d\99-podman-machine-provider.conf"
|
||||
$PodmanFolderPath = "$env:ProgramFiles\RedHat\Podman"
|
||||
13
contrib/win-installer/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
artifacts/
|
||||
current/
|
||||
docs/
|
||||
en-US/
|
||||
fetch/
|
||||
podman-*setup.exe
|
||||
engine.exe
|
||||
obj/
|
||||
shasums
|
||||
*.wixobj
|
||||
*.wixpdb
|
||||
*.log
|
||||
*.msi
|
||||
@@ -1,154 +1,226 @@
|
||||
function ExitOnError() {
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Exit 1
|
||||
}
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Build Podman Windows MSI installer
|
||||
|
||||
.DESCRIPTION
|
||||
This script builds a Podman MSI installer for Windows using WiX Toolset.
|
||||
The release artifacts (podman.exe, gvproxy.exe, win-sshproxy.exe and
|
||||
docs) are either downloaded from GitHub or copied from a local directory,
|
||||
extracted, signed (if signing credentials are available), and packaged
|
||||
into an MSI installer.
|
||||
|
||||
.PARAMETER Version
|
||||
Podman version to build (e.g., "5.6.2" or "v5.6.2"). This will be the
|
||||
version of the MSI installer to be built.
|
||||
|
||||
.PARAMETER Architecture
|
||||
Target architecture for the installer. Valid values: 'amd64', 'arm64'.
|
||||
Default: 'amd64'
|
||||
|
||||
.PARAMETER LocalReleaseDirPath
|
||||
Optional path to a local directory containing the release zip file
|
||||
(podman-remote-release-windows_<arch>.zip). If not specified, the
|
||||
release will be downloaded from GitHub.
|
||||
|
||||
.PARAMETER RemoteReleaseRepoUrl
|
||||
URL of the Podman release repository to download from. Default is the
|
||||
official Podman GitHub repository. This parameter is primarily used by
|
||||
the Podman release scripts.
|
||||
|
||||
.EXAMPLE
|
||||
.\build.ps1 -Version 5.6.2
|
||||
Download and build amd64 MSI from the official GitHub release
|
||||
|
||||
.EXAMPLE
|
||||
.\build.ps1 -Version 5.6.2 -Architecture arm64
|
||||
Download and build arm64 MSI from the official GitHub release
|
||||
|
||||
.EXAMPLE
|
||||
.\build.ps1 -Version 5.6.2 -LocalReleaseDirPath .\current
|
||||
Build an MSI from a pre-downloaded release in the current directory
|
||||
|
||||
.EXAMPLE
|
||||
.\build.ps1 -Version 5.6.2 -Architecture arm64 `
|
||||
-LocalReleaseDirPath .\current
|
||||
Build an arm64 MSI from a local release directory
|
||||
|
||||
.NOTES
|
||||
Requirements:
|
||||
- .NET SDK (https://dotnet.microsoft.com/download)
|
||||
- WiX Toolset (install: dotnet tool install --global wix)
|
||||
|
||||
Environment Variables for signing (optional):
|
||||
$ENV:VAULT_ID $ENV:APP_ID $ENV:TENANT_ID
|
||||
$ENV:CLIENT_SECRET $ENV:CERT_NAME
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory = $true,
|
||||
ParameterSetName = 'LocalReleaseDirPath',
|
||||
Position = 0,
|
||||
HelpMessage = 'Podman version to build (MSI installer version)'
|
||||
)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[ValidatePattern('^v?([0-9]+\.[0-9]+\.[0-9]+)(-.*)?$')]
|
||||
[string]$Version,
|
||||
|
||||
[Parameter(
|
||||
Mandatory = $false,
|
||||
Position = 1,
|
||||
HelpMessage = 'Target Architecture'
|
||||
)]
|
||||
[ValidateSet('amd64', 'arm64')]
|
||||
[string]$Architecture = 'amd64',
|
||||
|
||||
[Parameter(
|
||||
Mandatory = $false,
|
||||
Position = 2,
|
||||
HelpMessage = 'Path to pre-downloaded release zip file'
|
||||
)]
|
||||
[ValidateScript({ Test-Path $_ -PathType Container })]
|
||||
[string]$LocalReleaseDirPath = '',
|
||||
|
||||
[Parameter(
|
||||
Mandatory = $false,
|
||||
Position = 3,
|
||||
HelpMessage = 'URL of the Podman release repository'
|
||||
)]
|
||||
[string]$RemoteReleaseRepoUrl = 'https://github.com/containers/podman'
|
||||
)
|
||||
|
||||
. $PSScriptRoot\utils.ps1
|
||||
|
||||
# Strip leading 'v' from version if present
|
||||
$Version = $Version.TrimStart('v')
|
||||
|
||||
################################################################################
|
||||
# REQUIREMENTS CHECK
|
||||
################################################################################
|
||||
Write-Host 'Checking requirements (dotnet and wix)'
|
||||
|
||||
# Check if .NET SDK is installed
|
||||
if (! (Get-Command 'dotnet' -errorAction SilentlyContinue)) {
|
||||
Write-Error "Required dep `".NET SDK`" is not installed. " `
|
||||
+ 'Please install it from https://dotnet.microsoft.com/download'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
function SignItem() {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string[]]$fileNames
|
||||
)
|
||||
# Check if WiX Toolset is installed
|
||||
Invoke-Expression 'dotnet tool list --global wix' `
|
||||
-ErrorAction SilentlyContinue | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Required dep `"Wix Toolset`" is not installed. " `
|
||||
+ 'Please install it with the command ' `
|
||||
+ "`"dotnet tool install --global wix`""
|
||||
Exit 1
|
||||
}
|
||||
|
||||
foreach ($val in $ENV:APP_ID, $ENV:TENANT_ID, $ENV:CLIENT_SECRET, $ENV:CERT_NAME) {
|
||||
if (!$val) {
|
||||
Write-Host "Skipping signing (no config)"
|
||||
Return
|
||||
}
|
||||
}
|
||||
################################################################################
|
||||
# COPY OR DOWNLOAD RELEASE ARTIFACTS AND SIGN THEM
|
||||
################################################################################
|
||||
Write-Host 'Deleting old directories if they exist (''docs'', ''artifacts'' ' `
|
||||
'and ''fetch'')'
|
||||
foreach ($dir in 'docs', 'artifacts', 'fetch') {
|
||||
Remove-Item -Force -Recurse -Path $PSScriptRoot\$dir `
|
||||
-ErrorAction SilentlyContinue | Out-Null
|
||||
}
|
||||
|
||||
CheckCommand AzureSignTool.exe "AzureSignTool"
|
||||
Write-Host 'Creating empty ''fetch'' and ''artifacts'' directories'
|
||||
foreach ($dir in 'fetch', 'artifacts') {
|
||||
New-Item $PSScriptRoot\$dir -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
AzureSignTool.exe sign -du "https://github.com/containers/podman" `
|
||||
-kvu "https://$ENV:VAULT_ID.vault.azure.net" `
|
||||
-kvi $ENV:APP_ID `
|
||||
-kvt $ENV:TENANT_ID `
|
||||
-kvs $ENV:CLIENT_SECRET `
|
||||
-kvc $ENV:CERT_NAME `
|
||||
-tr http://timestamp.digicert.com $fileNames
|
||||
$ProgressPreference = 'SilentlyContinue';
|
||||
|
||||
if (!$LocalReleaseDirPath) {
|
||||
$releaseZipUrl = "$RemoteReleaseRepoUrl/releases/download/" `
|
||||
+ "v$Version/podman-remote-release-windows_$Architecture.zip"
|
||||
Write-Host "Downloading $releaseZipUrl"
|
||||
DownloadReleaseFile -url $releaseZipUrl `
|
||||
-outputFile "$PSScriptRoot\fetch\release.zip" `
|
||||
-failOnError
|
||||
DownloadReleaseFile `
|
||||
-url "$RemoteReleaseRepoUrl/releases/download/v$Version/shasums" `
|
||||
-outputFile "$PSScriptRoot\shasums"
|
||||
}
|
||||
else {
|
||||
$sourceZip = "$LocalReleaseDirPath\" `
|
||||
+ "podman-remote-release-windows_$Architecture.zip"
|
||||
Write-Host "Copying $sourceZip to $PSScriptRoot\fetch\release.zip"
|
||||
Copy-Item -Path $sourceZip `
|
||||
-Destination "$PSScriptRoot\fetch\release.zip" `
|
||||
-ErrorAction Stop
|
||||
}
|
||||
|
||||
Write-Host "Expanding the podman release zip file to $PSScriptRoot\fetch"
|
||||
Expand-Archive -Path $PSScriptRoot\fetch\release.zip `
|
||||
-DestinationPath $PSScriptRoot\fetch `
|
||||
-ErrorAction Stop
|
||||
ExitOnError
|
||||
|
||||
Write-Host -NoNewline 'Copying artifacts: '
|
||||
Foreach ($fileName in 'podman.exe', 'win-sshproxy.exe', 'gvproxy.exe') {
|
||||
Write-Host -NoNewline "$fileName, "
|
||||
Get-ChildItem -Path "$PSScriptRoot\fetch\" `
|
||||
-Filter "$fileName" `
|
||||
-Recurse | `
|
||||
Copy-Item -Container:$false `
|
||||
-Destination "$PSScriptRoot\artifacts\" `
|
||||
-ErrorAction Stop
|
||||
ExitOnError
|
||||
}
|
||||
|
||||
function CheckCommand() {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $cmd,
|
||||
[Parameter(Mandatory)]
|
||||
[string] $description
|
||||
)
|
||||
Write-Host 'docs'
|
||||
Get-ChildItem -Path $PSScriptRoot\fetch\ -Filter 'docs' -Recurse | `
|
||||
Copy-Item -Recurse `
|
||||
-Container:$false `
|
||||
-Destination "$PSScriptRoot\docs" `
|
||||
-ErrorAction Stop
|
||||
ExitOnError
|
||||
|
||||
if (! (Get-Command $cmd -errorAction SilentlyContinue)) {
|
||||
Write-Host "Required dep `"$description`" is not installed"
|
||||
Exit 1
|
||||
}
|
||||
Write-Host 'Deleting the ''fetch'' folder'
|
||||
Remove-Item -Force -Recurse -Path $PSScriptRoot\fetch `
|
||||
-ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
SignItem @("$PSScriptRoot\artifacts\win-sshproxy.exe",
|
||||
"$PSScriptRoot\artifacts\podman.exe",
|
||||
"$PSScriptRoot\artifacts\gvproxy.exe")
|
||||
ExitOnError
|
||||
|
||||
################################################################################
|
||||
# BUILD THE MSI
|
||||
################################################################################
|
||||
dotnet clean $PSScriptRoot\wix\podman.wixproj
|
||||
Remove-Item $PSScriptRoot\wix\obj -Recurse -Force -Confirm:$false `
|
||||
-ErrorAction 'Ignore'
|
||||
|
||||
$archMap = @{
|
||||
'amd64' = 'x64'
|
||||
'arm64' = 'arm64'
|
||||
}
|
||||
$installerPlatform = $archMap[$Architecture]
|
||||
|
||||
Write-Host 'Building the MSI...'
|
||||
dotnet build $PSScriptRoot\wix\podman.wixproj `
|
||||
/property:DefineConstants="VERSION=$Version" `
|
||||
/property:InstallerPlatform="$installerPlatform" `
|
||||
/property:OutputName="podman-$Version" `
|
||||
-o $PSScriptRoot
|
||||
ExitOnError
|
||||
|
||||
$msiName = "podman-$Version.msi"
|
||||
|
||||
SignItem @("$PSScriptRoot\$msiName")
|
||||
|
||||
if (Test-Path -Path $PSScriptRoot\shasums) {
|
||||
$hash = (Get-FileHash -Algorithm SHA256 `
|
||||
$PSScriptRoot\$msiName).Hash.ToLower()
|
||||
Write-Output "$hash $msiName" | `
|
||||
Out-File -Append -FilePath $PSScriptRoot\shasums
|
||||
}
|
||||
|
||||
function CheckRequirements() {
|
||||
CheckCommand "wix" "WiX Toolset"
|
||||
CheckCommand "go" "Golang"
|
||||
}
|
||||
|
||||
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:PODMAN_ARCH - Installer target platform (x64 or arm64)'
|
||||
Write-Host 'Env Settings for signing (optional)'
|
||||
Write-Host ' $ENV:VAULT_ID'
|
||||
Write-Host ' $ENV:APP_ID'
|
||||
Write-Host ' $ENV:TENANT_ID'
|
||||
Write-Host ' $ENV:CLIENT_SECRET'
|
||||
Write-Host ' $ENV:CERT_NAME'
|
||||
Write-Host
|
||||
Write-Host "Example: Download and build from the official Github release (dev output): "
|
||||
Write-Host " .\build.ps1 4.2.0"
|
||||
Write-Host
|
||||
Write-Host "Example: Build a dev build from a pre-download release "
|
||||
Write-Host " .\build.ps1 4.2.0 dev fetchdir"
|
||||
Write-Host
|
||||
|
||||
Exit 1
|
||||
}
|
||||
|
||||
# Pre-set to standard locations in-case build env does not refresh paths
|
||||
$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
|
||||
|
||||
$version = $args[0]
|
||||
|
||||
if ($version[0] -eq "v") {
|
||||
$version = $version.Substring(1)
|
||||
}
|
||||
|
||||
$suffix = "-dev"
|
||||
if ($args.Count -gt 1 -and $args[1] -eq "prod") {
|
||||
$suffix = ""
|
||||
}
|
||||
|
||||
$releaseDir = ""
|
||||
if ($args.Count -gt 2) {
|
||||
$releaseDir = $args[2]
|
||||
}
|
||||
|
||||
.\process-release.ps1 $version $releaseDir
|
||||
if ($LASTEXITCODE -eq 2) {
|
||||
Write-Host "Skip signaled, relaying skip"
|
||||
Exit 2
|
||||
}
|
||||
if ($ENV:INSTVER -eq "") {
|
||||
Write-Host "process-release did not define an install version!"
|
||||
Exit 1
|
||||
}
|
||||
|
||||
$installerPlatform = ""
|
||||
if ($null -eq $ENV:PODMAN_ARCH -or "" -eq $ENV:PODMAN_ARCH -or "amd64" -eq $ENV:PODMAN_ARCH) {
|
||||
$installerPlatform = "x64"
|
||||
} elseif ($ENV:PODMAN_ARCH -eq "arm64") {
|
||||
$installerPlatform = "arm64"
|
||||
} else {
|
||||
Write-Host "Unknown architecture $ENV:PODMAN_ARCH. Valid options are amd64 or arm64."
|
||||
Exit 1
|
||||
}
|
||||
|
||||
SignItem @("artifacts/win-sshproxy.exe",
|
||||
"artifacts/podman.exe")
|
||||
$gvExists = Test-Path "artifacts/gvproxy.exe"
|
||||
if ($gvExists) {
|
||||
SignItem @("artifacts/gvproxy.exe")
|
||||
Remove-Item Env:\UseGVProxy -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
$env:UseGVProxy = "Skip"
|
||||
}
|
||||
|
||||
# Retaining for possible future additions
|
||||
# $pExists = Test-Path "artifacts/policy.json"
|
||||
# if ($pExists) {
|
||||
# Remove-Item Env:\IncludePolicyJSON -ErrorAction SilentlyContinue
|
||||
# } else {
|
||||
# $env:IncludePolicyJSON = "Skip"
|
||||
# }
|
||||
if (Test-Path ./obj) {
|
||||
Remove-Item ./obj -Recurse -Force -Confirm:$false
|
||||
}
|
||||
dotnet build podman.wixproj /property:DefineConstants="VERSION=$ENV:INSTVER" /property:InstallerPlatform="$installerPlatform" -o .; ExitOnError
|
||||
SignItem @("en-US\podman.msi")
|
||||
|
||||
dotnet build podman-setup.wixproj /property:DefineConstants="VERSION=$ENV:INSTVER" /property:InstallerPlatform="$installerPlatform" -o .; ExitOnError
|
||||
wix burn detach podman-setup.exe -engine engine.exe; ExitOnError
|
||||
SignItem @("engine.exe")
|
||||
|
||||
$file = "podman-$version$suffix-setup.exe"
|
||||
wix burn reattach -engine engine.exe podman-setup.exe -o $file; ExitOnError
|
||||
SignItem @("$file")
|
||||
|
||||
if (Test-Path -Path shasums) {
|
||||
$hash = (Get-FileHash -Algorithm SHA256 $file).Hash.ToLower()
|
||||
Write-Output "$hash $file" | Out-File -Append -FilePath shasums
|
||||
}
|
||||
|
||||
Write-Host "Complete"
|
||||
Get-ChildItem "podman-$version$suffix-setup.exe"
|
||||
Write-Host 'Complete'
|
||||
Get-ChildItem "$PSScriptRoot\$msiName"
|
||||
|
||||
783
contrib/win-installer/test.ps1
Normal file
@@ -0,0 +1,783 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Automated test script for the Podman Windows MSI installer.
|
||||
|
||||
.DESCRIPTION
|
||||
This script provides automated end-to-end tests for the Podman Windows MSI
|
||||
installer. It supports testing installation, update, and configuration
|
||||
scenarios for both user and machine scopes, as well as for different
|
||||
virtualization providers (WSL and Hyper-V).
|
||||
The script validates the presence and correctness of installed files,
|
||||
registry keys, and configuration files.
|
||||
|
||||
.PARAMETER scenario
|
||||
The test scenario to execute. Supported values:
|
||||
- test-objects-exist
|
||||
- test-objects-exist-not
|
||||
- installation-green-field
|
||||
- installation-skip-config-creation-flag
|
||||
- installation-with-pre-existing-podman-exe
|
||||
- update-from-current-to-next
|
||||
- update-from-current-to-next-with-modified-config
|
||||
- update-from-current-to-next-with-removed-config
|
||||
- update-from-legacy-to-current
|
||||
- all
|
||||
|
||||
.PARAMETER msiPath
|
||||
Path to the current Podman MSI installer to test.
|
||||
|
||||
.PARAMETER nextMsiPath
|
||||
Path to the next version Podman MSI installer (for update scenarios).
|
||||
|
||||
.PARAMETER previousSetupExePath
|
||||
Path to the legacy Podman setup EXE installer (for legacy update scenarios).
|
||||
|
||||
.PARAMETER provider
|
||||
The virtualization provider to test with. Supported values: 'wsl', 'hyperv'. Default: 'wsl'.
|
||||
|
||||
.PARAMETER skipConfigFileCreation
|
||||
Switch to skip creation of the configuration file during installation.
|
||||
|
||||
.PARAMETER scope
|
||||
Installation scope. Supported values: 'user', 'machine'. Default: 'user'.
|
||||
|
||||
.EXAMPLE
|
||||
.\test.ps1 -scenario all -msiPath "C:\path\to\podman.msi" -nextMsiPath "C:\path\to\next\podman.msi" -scope user
|
||||
|
||||
.NOTES
|
||||
- When using '-scope machine', this script must be run as Administrator.
|
||||
- This script is intended for use by Podman developers and CI pipelines to validate installer behavior.
|
||||
- See build_windows.md for more information and usage examples.
|
||||
#>
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateSet('test-objects-exist', 'test-objects-exist-not', 'installation-green-field', 'installation-skip-config-creation-flag', 'installation-with-pre-existing-podman-exe',
|
||||
#"update-from-prev-to-current", "update-from-prev-to-current-with-modified-config", "update-from-prev-to-current-with-removed-config",
|
||||
'update-from-current-to-next', 'update-from-current-to-next-with-modified-config', 'update-from-current-to-next-with-removed-config',
|
||||
'update-from-legacy-to-current',
|
||||
'all')]
|
||||
[string]$scenario,
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$msiPath,
|
||||
# [ValidateScript({Test-Path $_ -PathType Leaf})]
|
||||
# [string]$previousMsiPath,
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$nextMsiPath,
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$previousSetupExePath,
|
||||
[ValidateSet('wsl', 'hyperv')]
|
||||
[string]$provider = 'wsl',
|
||||
[switch]$skipConfigFileCreation = $false,
|
||||
[ValidateSet('machine', 'user')]
|
||||
[string]$scope = 'user'
|
||||
)
|
||||
|
||||
. $PSScriptRoot\utils.ps1
|
||||
|
||||
# Check if running as administrator when testing machine scope installation
|
||||
if ($scope -eq 'machine') {
|
||||
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
|
||||
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
if (-not $isAdmin) {
|
||||
throw 'The -scope machine parameter requires the script to be run as Administrator. Please run PowerShell as Administrator and try again.'
|
||||
}
|
||||
}
|
||||
|
||||
# Get the architecture of the current OS
|
||||
$osArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
||||
$arch = switch ($osArch) {
|
||||
'X64' { 'amd64' }
|
||||
'Arm64' { 'arm64' }
|
||||
default { throw "Unsupported architecture: $osArch" }
|
||||
}
|
||||
|
||||
# 99-podman-machine-provider.conf file path
|
||||
$MachineConfPathPerMachine = "$env:ProgramData\containers\containers.conf.d\99-podman-machine-provider.conf"
|
||||
$MachineConfPathPerMachineLegacy = $MachineConfPathPerMachine
|
||||
$MachineConfPathPerUser = "$env:AppData\containers\containers.conf.d\99-podman-machine-provider.conf"
|
||||
# Podman application folder path
|
||||
$PodmanFolderPathPerMachine = "$env:ProgramFiles\Podman"
|
||||
$PodmanFolderPathPerMachineLegacy = "$env:ProgramFiles\RedHat\Podman"
|
||||
$PodmanFolderPathPerUser = "$env:LocalAppData\Programs\Podman"
|
||||
# Podman.executable file path
|
||||
$PodmanExePathPerMachine = "$PodmanFolderPathPerMachine\podman.exe"
|
||||
$PodmanExePathPerMachineLegacy = "$PodmanFolderPathPerMachineLegacy\podman.exe"
|
||||
$PodmanExePathPerUser = "$PodmanFolderPathPerUser\podman.exe"
|
||||
|
||||
$WindowsPathsToTestPerMachine = @($PodmanExePathPerMachine,
|
||||
"$PodmanFolderPathPerMachine\win-sshproxy.exe",
|
||||
'HKLM:\SOFTWARE\Podman')
|
||||
$WindowsPathsToTestLegacy = @($PodmanExePathPerMachineLegacy,
|
||||
"$PodmanFolderPathPerMachineLegacy\win-sshproxy.exe",
|
||||
'HKLM:\SOFTWARE\Red Hat\Podman')
|
||||
$WindowsPathsToTestPerUser = @($PodmanExePathPerUser,
|
||||
"$PodmanFolderPathPerUser\win-sshproxy.exe",
|
||||
'HKCU:\SOFTWARE\Podman')
|
||||
|
||||
function Install-Podman-Bundle {
|
||||
param (
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$setupExePath = $script:previousSetupExePath
|
||||
)
|
||||
if ($script:skipConfigFileCreation) { $skipConfigFileCreationVar = '1' } else { $skipConfigFileCreationVar = '0' }
|
||||
|
||||
Write-Host "Running the installer ($setupExePath)..."
|
||||
Write-Host "(provider=`"$script:provider`", SkipConfigFileCreation=`"$skipConfigFileCreationVar`")"
|
||||
$ret = Start-Process -Wait `
|
||||
-PassThru "$setupExePath" `
|
||||
-ArgumentList "/install /quiet `
|
||||
MachineProvider=${script:provider} `
|
||||
SkipConfigFileCreation=${skipConfigFileCreationVar} `
|
||||
/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-Podman-Package {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$msiPath,
|
||||
[string]$msiProperties,
|
||||
[switch]$shouldFail = $false
|
||||
)
|
||||
|
||||
Write-Host "Running the installer ($msiPath)..."
|
||||
if ($msiProperties) {
|
||||
Write-Host "MSI Properties: $msiProperties"
|
||||
}
|
||||
else {
|
||||
Write-Host 'MSI Properties: none'
|
||||
}
|
||||
$msiExecArgs = "/package $msiPath /quiet /l*v $PSScriptRoot\podman-msi.log $msiProperties"
|
||||
Write-Host "msiexec $msiExecArgs"
|
||||
$ret = Start-Process -Wait `
|
||||
-PassThru 'msiexec' `
|
||||
-ArgumentList $msiExecArgs
|
||||
if ($ret.ExitCode -ne 0 -and -not $shouldFail) {
|
||||
Write-Host 'Install failed, dumping log'
|
||||
Get-Content $PSScriptRoot\podman-msi.log
|
||||
throw "Exit code is $($ret.ExitCode)"
|
||||
}
|
||||
if ($ret.ExitCode -eq 0 -and $shouldFail) {
|
||||
Write-Host 'Install completed successfully but a failure was expected, dumping log'
|
||||
Get-Content $PSScriptRoot\podman-msi.log
|
||||
throw "Exit code is $($ret.ExitCode) but a failure was expected"
|
||||
}
|
||||
if ($shouldFail) {
|
||||
Write-Host "Installation failed as expected!`n"
|
||||
}
|
||||
else {
|
||||
Write-Host "Installation completed successfully!`n"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-Podman-Package-with-Explicit-Properties {
|
||||
param (
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$msiPath = $script:msiPath,
|
||||
[ValidateSet('machine', 'user')]
|
||||
[string]$scope = $script:scope,
|
||||
[switch]$skipConfigFileCreation = $script:skipConfigFileCreation
|
||||
)
|
||||
|
||||
# MACHINE_PROVIDER
|
||||
$MACHINE_PROVIDER_PROP = "MACHINE_PROVIDER=$script:provider"
|
||||
# SKIP_CONFIG_FILE_CREATION
|
||||
if ($skipConfigFileCreation) {
|
||||
$SKIP_CONFIG_FILE_CREATION_PROP = 'SKIP_CONFIG_FILE_CREATION=1'
|
||||
}
|
||||
else {
|
||||
$SKIP_CONFIG_FILE_CREATION_PROP = 'SKIP_CONFIG_FILE_CREATION=0'
|
||||
}
|
||||
# ALLUSERS or MSIINSTALLPERUSER
|
||||
if ($scope -eq 'machine') {
|
||||
$ALLUSERS_OR_MSIINSTALLPERUSER_PROP = 'ALLUSERS=1'
|
||||
}
|
||||
else {
|
||||
$ALLUSERS_OR_MSIINSTALLPERUSER_PROP = 'MSIINSTALLPERUSER=1'
|
||||
}
|
||||
|
||||
Install-Podman-Package -msiPath $msiPath -msiProperties "${MACHINE_PROVIDER_PROP} ${ALLUSERS_OR_MSIINSTALLPERUSER_PROP} ${SKIP_CONFIG_FILE_CREATION_PROP}"
|
||||
}
|
||||
|
||||
function Update-Podman-Package {
|
||||
param (
|
||||
[ValidateSet('From-Previous', 'To-Next', 'From-Previous-Legacy', 'To-Next-Scope-Switch')]
|
||||
[string]$mode = 'From-Previous',
|
||||
[ValidateSet('none', 'switch-provider', 'delete-config-file')]
|
||||
[string]$configurationUpdate = 'none'
|
||||
)
|
||||
|
||||
# Step 1: Install the initial version
|
||||
switch ($mode) {
|
||||
# There is no "previous package" yet so this scenario cannot be tested.
|
||||
# This block, and those in STEP 3 and 5, should be commented out after the
|
||||
# release of dual scope MSI.
|
||||
# 'From-Previous' {
|
||||
# Install-Podman-Package-with-Explicit-Properties -msiPath $msiPreviousPath
|
||||
# Test-Installation -scope $script:scope
|
||||
# }
|
||||
'To-Next' {
|
||||
Install-Podman-Package-with-Explicit-Properties
|
||||
Test-Installation
|
||||
}
|
||||
'From-Previous-Legacy' {
|
||||
Install-Podman-Bundle
|
||||
Test-Installation -scope 'machine-legacy'
|
||||
}
|
||||
'To-Next-Scope-Switch' {
|
||||
if ($script:scope -eq 'machine') {
|
||||
$newScope = 'user'
|
||||
}
|
||||
else {
|
||||
$newScope = 'machine'
|
||||
}
|
||||
Install-Podman-Package-with-Explicit-Properties -scope $newScope
|
||||
Test-Installation -scope $newScope
|
||||
}
|
||||
}
|
||||
|
||||
# Step 2: Make some changes to the configration file if requested
|
||||
$newProvider = $script:provider
|
||||
$configFileRemoved = $false
|
||||
switch ($configurationUpdate) {
|
||||
'switch-provider' {
|
||||
$newProvider = Switch-Podman-Machine-Conf-Content -scope $script:scope
|
||||
}
|
||||
'delete-config-file' {
|
||||
Remove-Podman-Machine-Conf -scope $script:scope
|
||||
$configFileRemoved = $true
|
||||
}
|
||||
}
|
||||
|
||||
# Step 3: Install the next version
|
||||
$msiProperties = ''
|
||||
if ($script:scope -eq 'machine') {
|
||||
$msiProperties = 'ALLUSERS=1'
|
||||
}
|
||||
switch ($mode) {
|
||||
# 'From-Previous' {
|
||||
# Install-Podman-Package -msiPath $script:msiPath
|
||||
# Test-Installation -scope $script:scope -expectedConfiguredProvider $newProvider -configFileExistNot:$configFileRemoved
|
||||
# }
|
||||
'To-Next' {
|
||||
Install-Podman-Package -msiPath $script:nextMsiPath -msiProperties $msiProperties
|
||||
Test-Installation -scope $script:scope -expectedConfiguredProvider $newProvider -configFileExistNot:$configFileRemoved
|
||||
}
|
||||
'From-Previous-Legacy' {
|
||||
Install-Podman-Package -shouldFail -msiPath $script:msiPath -msiProperties $msiProperties
|
||||
}
|
||||
'To-Next-Scope-Switch' {
|
||||
Install-Podman-Package -shouldFail -msiPath $script:nextMsiPath -msiProperties $msiProperties
|
||||
}
|
||||
}
|
||||
|
||||
# Step 4: Check that the changes to the configuration file are persisted
|
||||
switch ($configurationUpdate) {
|
||||
'switch-provider' {
|
||||
Test-Podman-Machine-Conf-Content -expected $newProvider -scope $script:scope
|
||||
}
|
||||
'delete-config-file' {
|
||||
Test-Podman-Machine-Conf-Exist-Not -scope $script:scope -configFileRemoved:$configFileRemoved
|
||||
}
|
||||
}
|
||||
|
||||
# Step 5: Uninstall
|
||||
switch ($mode) {
|
||||
# 'From-Previous' {
|
||||
# Uninstall-Podman-Package -msiPath $msiPreviousPath -scope $script:scope
|
||||
# Test-Uninstallation -scope $script:scope
|
||||
# }
|
||||
'To-Next' {
|
||||
Uninstall-Podman-Package -msiPath $script:nextMsiPath
|
||||
Test-Uninstallation -scope $script:scope
|
||||
}
|
||||
'From-Previous-Legacy' {
|
||||
Uninstall-Podman-Bundle -setupExePath $script:previousSetupExePath
|
||||
Test-Uninstallation -scope 'machine-legacy'
|
||||
}
|
||||
'To-Next-Scope-Switch' {
|
||||
if ($script:scope -eq 'machine') {
|
||||
$newScope = 'user'
|
||||
}
|
||||
else {
|
||||
$newScope = 'machine'
|
||||
}
|
||||
Uninstall-Podman-Package -msiPath $script:msiPath
|
||||
Test-Uninstallation -scope $newScope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Test-Podman-Objects-Exist {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
Write-Host "Verifying that podman files, folders and registry entries exist...(scope=$scope)"
|
||||
if ($scope -eq 'machine') {
|
||||
$WindowsPathsToTest = $WindowsPathsToTestPerMachine
|
||||
}
|
||||
elseif ($scope -eq 'machine-legacy') {
|
||||
$WindowsPathsToTest = $WindowsPathsToTestLegacy
|
||||
}
|
||||
else {
|
||||
$WindowsPathsToTest = $WindowsPathsToTestPerUser
|
||||
}
|
||||
$WindowsPathsToTest | ForEach-Object {
|
||||
if (! (Test-Path -Path $_) ) {
|
||||
throw "Expected $_ but doesn't exist"
|
||||
}
|
||||
}
|
||||
Write-Host "Verification was successful!`n"
|
||||
}
|
||||
|
||||
function Test-Podman-Machine-Conf-Exist {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
if ($scope -eq 'machine') {
|
||||
$MachineConfPath = $MachineConfPathPerMachine
|
||||
}
|
||||
elseif ($scope -eq 'machine-legacy') {
|
||||
$MachineConfPath = $MachineConfPathPerMachineLegacy
|
||||
}
|
||||
else {
|
||||
$MachineConfPath = $MachineConfPathPerUser
|
||||
}
|
||||
Write-Host "Verifying that $MachineConfPath exist...(scope=$scope)"
|
||||
if (! (Test-Path -Path $MachineConfPath) ) {
|
||||
throw "Expected $MachineConfPath but doesn't exist"
|
||||
}
|
||||
Write-Host "Verification was successful!`n"
|
||||
}
|
||||
|
||||
function Test-Podman-Machine-Conf-Content {
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param (
|
||||
[ValidateSet('wsl', 'hyperv')]
|
||||
[string]$expected = $script:provider,
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
Write-Host "Verifying that the machine provider configuration is correct...(scope=$scope)"
|
||||
if ($scope -eq 'machine') {
|
||||
$MachineConfPath = $MachineConfPathPerMachine
|
||||
}
|
||||
elseif ($scope -eq 'machine-legacy') {
|
||||
$MachineConfPath = $MachineConfPathPerMachineLegacy
|
||||
}
|
||||
else {
|
||||
$MachineConfPath = $MachineConfPathPerUser
|
||||
}
|
||||
$machineProvider = Get-Content $MachineConfPath | Select-Object -Skip 1 | ConvertFrom-StringData | ForEach-Object { $_.provider }
|
||||
if ( $machineProvider -ne "`"$expected`"" ) {
|
||||
throw "Expected `"$expected`" as default machine provider but got $machineProvider"
|
||||
}
|
||||
Write-Host "Verification was successful!`n"
|
||||
}
|
||||
|
||||
function Uninstall-Podman-Bundle {
|
||||
param (
|
||||
# [Parameter(Mandatory)]
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$setupExePath
|
||||
)
|
||||
Write-Host "Running the uninstaller ($setupExePath)..."
|
||||
$ret = Start-Process -Wait `
|
||||
-PassThru "$setupExePath" `
|
||||
-ArgumentList "/uninstall `
|
||||
/quiet /log $PSScriptRoot\podman-setup-uninstall.log"
|
||||
if ($ret.ExitCode -ne 0) {
|
||||
Write-Host 'Uninstall failed, dumping log'
|
||||
Get-Content $PSScriptRoot\podman-setup-uninstall.log
|
||||
throw "Exit code is $($ret.ExitCode)"
|
||||
}
|
||||
Write-Host "The uninstallation completed successfully!`n"
|
||||
}
|
||||
|
||||
function Uninstall-Podman-Package {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$msiPath
|
||||
)
|
||||
Write-Host "Running the uninstaller ($msiPath)..."
|
||||
$ret = Start-Process -Wait `
|
||||
-PassThru 'msiexec' `
|
||||
-ArgumentList "/uninstall $msiPath /quiet /l*v $PSScriptRoot\podman-msi-uninstall.log"
|
||||
if ($ret.ExitCode -ne 0) {
|
||||
Write-Host 'Uninstall failed, dumping log'
|
||||
Get-Content $PSScriptRoot\podman-msi-uninstall.log
|
||||
throw "Exit code is $($ret.ExitCode)"
|
||||
}
|
||||
Write-Host "The uninstallation completed successfully!`n"
|
||||
}
|
||||
|
||||
function Test-Podman-Objects-Exist-Not {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
Write-Host "Verifying that podman files, folders and registry entries don't exist...(scope=$scope)"
|
||||
if ($scope -eq 'machine') {
|
||||
$WindowsPathsToTest = $WindowsPathsToTestPerMachine
|
||||
}
|
||||
elseif ($scope -eq 'machine-legacy') {
|
||||
$WindowsPathsToTest = $WindowsPathsToTestLegacy
|
||||
}
|
||||
else {
|
||||
$WindowsPathsToTest = $WindowsPathsToTestPerUser
|
||||
}
|
||||
$WindowsPathsToTest | ForEach-Object {
|
||||
if ( Test-Path -Path $_ ) {
|
||||
throw "Path $_ is present"
|
||||
}
|
||||
}
|
||||
Write-Host "Verification was successful!`n"
|
||||
}
|
||||
|
||||
function Test-Podman-Machine-Conf-Exist-Not {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
if ($scope -eq 'machine') {
|
||||
$MachineConfPath = $MachineConfPathPerMachine
|
||||
}
|
||||
elseif ($scope -eq 'machine-legacy') {
|
||||
$MachineConfPath = $MachineConfPathPerMachineLegacy
|
||||
}
|
||||
else {
|
||||
$MachineConfPath = $MachineConfPathPerUser
|
||||
}
|
||||
Write-Host "Verifying that $MachineConfPath doesn't exist...(scope=$scope)"
|
||||
if ( Test-Path -Path $MachineConfPath ) {
|
||||
throw "Path $MachineConfPath is present"
|
||||
}
|
||||
Write-Host "Verification was successful!`n"
|
||||
}
|
||||
|
||||
function New-Fake-Podman-Exe {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
if ($scope -eq 'machine') {
|
||||
$PodmanFolderPath = $PodmanFolderPathPerMachine
|
||||
$PodmanExePath = $PodmanExePathPerMachine
|
||||
}
|
||||
elseif ($scope -eq 'machine-legacy') {
|
||||
$PodmanFolderPath = $PodmanFolderPathPerMachineLegacy
|
||||
$PodmanExePath = $PodmanExePathPerMachineLegacy
|
||||
}
|
||||
else {
|
||||
$PodmanFolderPath = $PodmanFolderPathPerUser
|
||||
$PodmanExePath = $PodmanExePathPerUser
|
||||
}
|
||||
Write-Host "Creating a fake $PodmanExePath...(scope=$scope)"
|
||||
New-Item -ItemType Directory -Path $PodmanFolderPath -Force -ErrorAction Stop | out-null
|
||||
New-Item -ItemType File -Path $PodmanExePath -ErrorAction Stop | out-null
|
||||
Write-Host "Creation successful!`n"
|
||||
}
|
||||
|
||||
function Switch-Podman-Machine-Conf-Content {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
$currentProvider = $script:provider
|
||||
if ( $currentProvider -eq 'wsl' ) { $newProvider = 'hyperv' } else { $newProvider = 'wsl' }
|
||||
if ($scope -eq 'machine') {
|
||||
$MachineConfPath = $MachineConfPathPerMachine
|
||||
}
|
||||
elseif ($scope -eq 'machine-legacy') {
|
||||
$MachineConfPath = $MachineConfPathPerMachineLegacy
|
||||
}
|
||||
else {
|
||||
$MachineConfPath = $MachineConfPathPerUser
|
||||
}
|
||||
Write-Host "Editing $MachineConfPath content (was $currentProvider, will be $newProvider)..."
|
||||
"[machine]`nprovider=`"$newProvider`"" | Out-File -FilePath $MachineConfPath -ErrorAction Stop
|
||||
Write-Host "Edit successful!`n"
|
||||
return $newProvider
|
||||
}
|
||||
|
||||
function Remove-Podman-Machine-Conf {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
if ($scope -eq 'machine') {
|
||||
$MachineConfPath = $MachineConfPathPerMachine
|
||||
}
|
||||
elseif ($scope -eq 'machine-legacy') {
|
||||
$MachineConfPath = $MachineConfPathPerMachineLegacy
|
||||
}
|
||||
else {
|
||||
$MachineConfPath = $MachineConfPathPerUser
|
||||
}
|
||||
Write-Host "Deleting $MachineConfPath..."
|
||||
Remove-Item -Path $MachineConfPath -ErrorAction Stop | out-null
|
||||
Write-Host "Deletion successful!`n"
|
||||
}
|
||||
|
||||
function Test-Installation {
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param (
|
||||
[ValidateSet('wsl', 'hyperv')]
|
||||
[string]$expectedConfiguredProvider,
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope,
|
||||
[switch]$configFileExistNot = $false
|
||||
)
|
||||
|
||||
Test-Podman-Objects-Exist -scope $scope
|
||||
|
||||
if ($configFileExistNot) {
|
||||
Test-Podman-Machine-Conf-Exist-Not -scope $scope
|
||||
}
|
||||
else {
|
||||
Test-Podman-Machine-Conf-Exist -scope $scope
|
||||
if ($expectedConfiguredProvider) {
|
||||
Test-Podman-Machine-Conf-Content -expected $expectedConfiguredProvider -scope $scope
|
||||
}
|
||||
else {
|
||||
Test-Podman-Machine-Conf-Content -scope $scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Test-Installation-No-Config {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
Test-Podman-Objects-Exist -scope $scope
|
||||
Test-Podman-Machine-Conf-Exist-Not -scope $scope
|
||||
}
|
||||
|
||||
function Test-Uninstallation {
|
||||
param (
|
||||
[ValidateSet('machine-legacy', 'machine', 'user')]
|
||||
[string]$scope = $script:scope
|
||||
)
|
||||
Test-Podman-Objects-Exist-Not -scope $scope
|
||||
Test-Podman-Machine-Conf-Exist-Not -scope $scope
|
||||
}
|
||||
|
||||
# SCENARIOS
|
||||
function Start-Scenario-Installation-Green-Field {
|
||||
Write-Host "`n==========================================="
|
||||
Write-Host ' Running scenario: Installation-Green-Field'
|
||||
Write-Host '==========================================='
|
||||
Install-Podman-Package-with-Explicit-Properties -msiPath $script:msiPath -scope $script:scope
|
||||
Test-Installation
|
||||
Uninstall-Podman-Package -msiPath $script:msiPath
|
||||
Test-Uninstallation
|
||||
}
|
||||
|
||||
function Start-Scenario-Installation-Skip-Config-Creation-Flag {
|
||||
Write-Host "`n========================================================="
|
||||
Write-Host ' Running scenario: Installation-Skip-Config-Creation-Flag'
|
||||
Write-Host '========================================================='
|
||||
Install-Podman-Package-with-Explicit-Properties -msiPath $script:msiPath -scope $script:scope -skipConfigFileCreation:$true
|
||||
Test-Installation-No-Config
|
||||
Uninstall-Podman-Package -msiPath $script:msiPath
|
||||
Test-Uninstallation
|
||||
}
|
||||
|
||||
function Start-Scenario-Installation-With-Pre-Existing-Podman-Exe {
|
||||
Write-Host "`n============================================================"
|
||||
Write-Host ' Running scenario: Installation-With-Pre-Existing-Podman-Exe'
|
||||
Write-Host '============================================================'
|
||||
New-Fake-Podman-Exe
|
||||
Install-Podman-Package-with-Explicit-Properties -msiPath $script:msiPath -scope $script:scope
|
||||
Test-Installation-No-Config
|
||||
Uninstall-Podman-Package -msiPath $script:msiPath
|
||||
Test-Uninstallation
|
||||
|
||||
# remove the Podman folder created by `New-Fake-Podman-Exe` that
|
||||
# otherwise would remain after the uninstallation
|
||||
if ($script:scope -eq 'machine') {
|
||||
Remove-Item -Path $PodmanFolderPathPerMachine -Recurse -Force
|
||||
}
|
||||
elseif ($script:scope -eq 'machine-legacy') {
|
||||
Remove-Item -Path $PodmanFolderPathPerMachineLegacy -Recurse -Force
|
||||
}
|
||||
else {
|
||||
Remove-Item -Path $PodmanFolderPathPerUser -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
# function Start-Scenario-Update-From-Prev-To-Current {
|
||||
# Write-Host "`n======================================================"
|
||||
# Write-Host " Running scenario: Update-From-Prev-To-Current"
|
||||
# Write-Host "======================================================"
|
||||
# Update-Podman-Package -mode "From-Previous" -configurationUpdate "none"
|
||||
# }
|
||||
|
||||
# function Start-Scenario-Update-From-Prev-To-Current-With-Modified-Config {
|
||||
# Write-Host "`n=============================================================="
|
||||
# Write-Host " Running scenario: Update-From-Prev-To-Current-With-Modified-Config"
|
||||
# Write-Host "=============================================================="
|
||||
# Update-Podman-Package -mode "From-Previous" -configurationUpdate "switch-provider"
|
||||
# }
|
||||
|
||||
# function Start-Scenario-Update-From-Prev-To-Current-With-Removed-Config {
|
||||
# Write-Host "`n=============================================================="
|
||||
# Write-Host " Running scenario: Update-From-Prev-To-Current-With-Removed-Config"
|
||||
# Write-Host "=============================================================="
|
||||
# Update-Podman-Package -mode "From-Previous" -configurationUpdate "delete-config-file"
|
||||
# }
|
||||
|
||||
function Start-Scenario-Update-From-Current-To-Next {
|
||||
Write-Host "`n======================================================"
|
||||
Write-Host ' Running scenario: Update-From-Current-To-Next'
|
||||
Write-Host '======================================================'
|
||||
Update-Podman-Package -mode 'To-Next' -configurationUpdate 'none'
|
||||
}
|
||||
|
||||
function Start-Scenario-Update-From-Current-To-Next-With-Modified-Config {
|
||||
Write-Host "`n=============================================================="
|
||||
Write-Host ' Running scenario: Update-From-Current-To-Next-With-Modified-Config'
|
||||
Write-Host '=============================================================='
|
||||
Update-Podman-Package -mode 'To-Next' -configurationUpdate 'switch-provider'
|
||||
}
|
||||
|
||||
function Start-Scenario-Update-From-Current-To-Next-With-Removed-Config {
|
||||
Write-Host "`n=============================================================="
|
||||
Write-Host ' Running scenario: Update-From-Current-To-Next-With-Removed-Config'
|
||||
Write-Host '=============================================================='
|
||||
Update-Podman-Package -mode 'To-Next' -configurationUpdate 'delete-config-file'
|
||||
}
|
||||
|
||||
function Start-Scenario-Update-From-Legacy-To-Current {
|
||||
Write-Host "`n======================================================"
|
||||
Write-Host ' Running scenario: Update-From-Legacy-To-Current'
|
||||
Write-Host '======================================================'
|
||||
Update-Podman-Package -mode 'From-Previous-Legacy' -configurationUpdate 'none'
|
||||
}
|
||||
|
||||
switch ($script:scenario) {
|
||||
'test-objects-exist' {
|
||||
Test-Podman-Objects-Exist
|
||||
}
|
||||
'test-objects-exist-not' {
|
||||
Test-Podman-Objects-Exist-Not
|
||||
}
|
||||
'installation-green-field' {
|
||||
if (!$script:msiPath) {
|
||||
throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
}
|
||||
Start-Scenario-Installation-Green-Field
|
||||
}
|
||||
'installation-skip-config-creation-flag' {
|
||||
if (!$script:msiPath) {
|
||||
throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
}
|
||||
Start-Scenario-Installation-Skip-Config-Creation-Flag
|
||||
}
|
||||
'installation-with-pre-existing-podman-exe' {
|
||||
if (!$script:msiPath) {
|
||||
throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
}
|
||||
Start-Scenario-Installation-With-Pre-Existing-Podman-Exe
|
||||
}
|
||||
# 'update-from-prev-to-current' {
|
||||
# if (!$script:msiPath) {
|
||||
# throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
# }
|
||||
# if (!$script:previousMsiPath) {
|
||||
# $script:previousMsiPath = Get-Latest-Podman-MSI-From-GitHub -arch $script:arch
|
||||
# }
|
||||
# Start-Scenario-Update-From-Prev-To-Current
|
||||
# }
|
||||
# 'update-from-prev-to-current-with-modified-config' {
|
||||
# if (!$script:msiPath) {
|
||||
# throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
# }
|
||||
# if (!$script:previousMsiPath) {
|
||||
# $script:previousMsiPath = Get-Latest-Podman-MSI-From-GitHub -arch $script:arch
|
||||
# }
|
||||
# Start-Scenario-Update-From-Prev-To-Current-With-Modified-Config
|
||||
# }
|
||||
# 'update-from-prev-to-current-with-removed-config' {
|
||||
# if (!$script:msiPath) {
|
||||
# throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
# }
|
||||
# if (!$script:previousMsiPath) {
|
||||
# $script:previousMsiPath = Get-Latest-Podman-MSI-From-GitHub -arch $script:arch
|
||||
# }
|
||||
# Start-Scenario-Update-From-Prev-To-Current-With-Removed-Config
|
||||
# }
|
||||
'update-from-current-to-next' {
|
||||
if (!$script:msiPath) {
|
||||
throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
}
|
||||
if (!$script:nextMsiPath) {
|
||||
throw "Next version installer path is not defined. Use '-nextMsiPath <msi-path>' to define it."
|
||||
}
|
||||
Start-Scenario-Update-From-Current-To-Next
|
||||
}
|
||||
'update-from-current-to-next-with-modified-config' {
|
||||
if (!$script:msiPath) {
|
||||
throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
}
|
||||
if (!$script:nextMsiPath) {
|
||||
throw "Next version installer path is not defined. Use '-nextMsiPath <msi-path>' to define it."
|
||||
}
|
||||
Start-Scenario-Update-From-Current-To-Next-With-Modified-Config
|
||||
}
|
||||
'update-from-current-to-next-with-removed-config' {
|
||||
if (!$script:msiPath) {
|
||||
throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
}
|
||||
if (!$script:nextMsiPath) {
|
||||
throw "Next version installer path is not defined. Use '-nextMsiPath <msi-path>' to define it."
|
||||
}
|
||||
Start-Scenario-Update-From-Current-To-Next-With-Removed-Config
|
||||
}
|
||||
'update-from-legacy-to-current' {
|
||||
if (!$script:msiPath) {
|
||||
throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
}
|
||||
if (!$script:previousSetupExePath) {
|
||||
$script:previousSetupExePath = Get-Latest-Podman-Setup-From-GitHub -arch $script:arch
|
||||
}
|
||||
Start-Scenario-Update-From-Legacy-To-Current
|
||||
}
|
||||
'all' {
|
||||
if (!$script:msiPath) {
|
||||
throw "Current installer path is not defined. Use '-msiPath <msi-path>' to define it."
|
||||
}
|
||||
if (!$script:nextMsiPath) {
|
||||
throw "Next version installer path is not defined. Use '-nextMsiPath <msi-path>' to define it."
|
||||
}
|
||||
# if (!$script:previousMsiPath) {
|
||||
# $script:previousMsiPath = Get-Latest-Podman-MSI-From-GitHub -arch $script:arch
|
||||
# }
|
||||
if (!$script:previousSetupExePath) {
|
||||
$script:previousSetupExePath = Get-Latest-Podman-Setup-From-GitHub -arch $script:arch
|
||||
}
|
||||
Start-Scenario-Installation-Green-Field
|
||||
Start-Scenario-Installation-Skip-Config-Creation-Flag
|
||||
Start-Scenario-Installation-With-Pre-Existing-Podman-Exe
|
||||
# Start-Scenario-Update-From-Prev-To-Current
|
||||
# Start-Scenario-Update-From-Prev-To-Current-With-Modified-Config
|
||||
# Start-Scenario-Update-From-Prev-To-Current-With-Removed-Config
|
||||
Start-Scenario-Update-From-Current-To-Next
|
||||
Start-Scenario-Update-From-Current-To-Next-With-Modified-Config
|
||||
Start-Scenario-Update-From-Current-To-Next-With-Removed-Config
|
||||
Start-Scenario-Update-From-Legacy-To-Current
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,113 @@
|
||||
#!/usr/bin/env pwsh
|
||||
function Get-Latest-Podman-Setup-From-GitHub {
|
||||
return Get-Podman-Setup-From-GitHub "latest"
|
||||
param(
|
||||
[ValidateSet("amd64", "arm64")]
|
||||
[string] $arch = "amd64"
|
||||
)
|
||||
return Get-Podman-Setup-From-GitHub "latest" $arch
|
||||
}
|
||||
|
||||
function Get-Podman-Setup-From-GitHub {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $version
|
||||
[string] $version,
|
||||
[ValidateSet("amd64", "arm64")]
|
||||
[string] $arch = "amd64"
|
||||
)
|
||||
|
||||
Write-Host "Downloading the $version Podman windows setup from GitHub..."
|
||||
Write-Host "Downloading the $arch $version Podman windows setup from GitHub..."
|
||||
$apiUrl = "https://api.github.com/repos/containers/podman/releases/$version"
|
||||
$response = Invoke-RestMethod -Uri $apiUrl -Headers @{"User-Agent"="PowerShell"} -ErrorAction Stop
|
||||
$downloadUrl = $response.assets[0].browser_download_url
|
||||
Write-Host "Downloading URL: $downloadUrl"
|
||||
$latestTag = $response.tag_name
|
||||
$destinationPath = "$PSScriptRoot\podman-$latestTag-setup.exe"
|
||||
Write-Host "Looking for an asset named ""podman-installer-windows-$arch.exe"""
|
||||
$downloadAsset = $response.assets | Where-Object { $_.name -eq "podman-installer-windows-$arch.exe" } | Select-Object -First 1
|
||||
if (-not $downloadAsset) {
|
||||
# remove the first char from $latestTag if it is a "v"
|
||||
if ($latestTag[0] -eq "v") {
|
||||
$newLatestTag = $latestTag.Substring(1)
|
||||
}
|
||||
Write-Host "Not found. Looking for an asset named ""podman-$newLatestTag-setup.exe"""
|
||||
$downloadAsset = $response.assets | Where-Object { $_.name -eq "podman-$newLatestTag-setup.exe" } | Select-Object -First 1
|
||||
}
|
||||
$downloadUrl = $downloadAsset.browser_download_url
|
||||
Write-Host "Downloading URL: $downloadUrl"
|
||||
$destinationPath = "$PSScriptRoot\podman-${latestTag}-setup.exe"
|
||||
Write-Host "Destination Path: $destinationPath"
|
||||
Invoke-WebRequest -Uri $downloadUrl -OutFile $destinationPath
|
||||
Write-Host "Command completed successfully!`n"
|
||||
return $destinationPath
|
||||
}
|
||||
|
||||
function DownloadReleaseFile {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$url,
|
||||
[Parameter(Mandatory)]
|
||||
[string]$outputFile,
|
||||
[Parameter(Mandatory=$false, Position=3, HelpMessage="Fail if `Invoke-WebRequest` fails, silently continue if not specified")]
|
||||
[switch]$failOnError = $false
|
||||
)
|
||||
$ProgressPreference = 'SilentlyContinue';
|
||||
try {
|
||||
Invoke-WebRequest -UseBasicParsing -ErrorAction Stop -Uri $url -OutFile $outputFile
|
||||
} Catch {
|
||||
if ($FailOnError) {
|
||||
if ($_.Exception.Response.StatusCode -eq 404) {
|
||||
Write-Error "URL not available $url"
|
||||
Exit 2
|
||||
}
|
||||
|
||||
throw $_.Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ExitOnError() {
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Exit 1
|
||||
}
|
||||
}
|
||||
|
||||
function SignItem() {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string[]]$fileNames
|
||||
)
|
||||
|
||||
foreach ($val in $ENV:APP_ID, $ENV:TENANT_ID, $ENV:CLIENT_SECRET, $ENV:CERT_NAME) {
|
||||
if (!$val) {
|
||||
Write-Host 'Skipping signing (no config)'
|
||||
Return
|
||||
}
|
||||
}
|
||||
|
||||
CheckCommand AzureSignTool.exe 'AzureSignTool'
|
||||
|
||||
AzureSignTool.exe sign -du 'https://github.com/containers/podman' `
|
||||
-kvu "https://$ENV:VAULT_ID.vault.azure.net" `
|
||||
-kvi $ENV:APP_ID `
|
||||
-kvt $ENV:TENANT_ID `
|
||||
-kvs $ENV:CLIENT_SECRET `
|
||||
-kvc $ENV:CERT_NAME `
|
||||
-tr http://timestamp.digicert.com $fileNames
|
||||
|
||||
ExitOnError
|
||||
}
|
||||
|
||||
function Get-Current-Architecture {
|
||||
$arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
||||
if ($arch -eq 'X64') {
|
||||
return 'amd64'
|
||||
} elseif ($arch -eq 'Arm64') {
|
||||
return 'arm64'
|
||||
} else {
|
||||
throw "Unsupported architecture: $arch"
|
||||
}
|
||||
}
|
||||
|
||||
# Pre-set to standard locations in-case build env does not refresh paths
|
||||
$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'
|
||||
|
||||
180
contrib/win-installer/wix/podman-main.wxs
Normal file
@@ -0,0 +1,180 @@
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:PanelSW="http://schemas.panel-sw.co.il/wix/WixExtension" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||
|
||||
<?ifndef VERSION?>
|
||||
<?error VERSION must be defined via command line argument?>
|
||||
<?endif?>
|
||||
|
||||
<?ifdef env.UseGVProxy?>
|
||||
<?define UseGVProxy = "$(env.UseGVProxy)"?>
|
||||
<?else?>
|
||||
<?define UseGVProxy = ""?>
|
||||
<?endif?>
|
||||
|
||||
<Package Name="Podman CLI" Manufacturer="Podman" Version="$(VERSION)" UpgradeCode="a6a9dd9c-0732-44ba-9279-ffe22ea50671" Scope="perUserOrMachine">
|
||||
<Media Id="1" Cabinet="Podman.cab" EmbedCab="yes" />
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." Schedule="afterInstallExecute" />
|
||||
<Property Id="WINDOWSBUILDNUMBER" Secure="yes">
|
||||
<RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
|
||||
</Property>
|
||||
<Launch Condition="Installed OR (WINDOWSBUILDNUMBER >= 19041)"
|
||||
Message="Windows 10 (19041) or later is required to run this application." />
|
||||
<!--
|
||||
The installer fails during installation if the legacy Podman
|
||||
registry key is found. Otherwise the user would end up with two
|
||||
installations of Podman. This is because it's not possible to
|
||||
do an update from a machine scope bundle (the legacy installer) to a
|
||||
dual scope package (this MSI).
|
||||
-->
|
||||
<Property Id="LEGACY_PODMAN_REGISTRY_KEY_FOUND">
|
||||
<RegistrySearch Id="LegacyPodmanRegistryKeySearch"
|
||||
Root="HKLM"
|
||||
Key="SOFTWARE\Red Hat\Podman"
|
||||
Name="InstallDir"
|
||||
Type="raw" />
|
||||
</Property>
|
||||
<Launch Condition="Installed OR (NOT LEGACY_PODMAN_REGISTRY_KEY_FOUND)"
|
||||
Message="Found an older version of Podman that is not compatible with
|
||||
this installer. Uninstall it using 'Add or Remove
|
||||
Programs' and retry. During uninstallation, all containers, images, machines,
|
||||
and other data will be preserved." />
|
||||
<util:QueryNativeMachine />
|
||||
<Launch Condition='"$(sys.BUILDARCH)" ~= "x64" IMP WIX_NATIVE_MACHINE = 34404'
|
||||
Message="This version of the [ProductName] installer can only run on $(sys.BUILDARCH) machines." />
|
||||
<Property Id="DiskPrompt" Value="Podman $(VERSION) Installation" />
|
||||
<Property Id="MACHINE_PROVIDER" Value="wsl" />
|
||||
|
||||
<Property Id="MACHINE_PROVIDER_CONFIG_FILE_PATH">
|
||||
<DirectorySearch Id="CONFDIRFolderSearch" Path="[CONFDIR]">
|
||||
<FileSearch Name="99-podman-machine-provider.conf" />
|
||||
</DirectorySearch>
|
||||
</Property>
|
||||
|
||||
<!--
|
||||
ProgramFiles6432Folder corresponds to %ProgramFiles% when the scope
|
||||
is machine and to %LocalAppData%\Programs when the scope is user.
|
||||
https://learn.microsoft.com/en-us/windows/win32/msi/single-package-authoring
|
||||
-->
|
||||
<Property Id="MAIN_EXECUTABLE_FILE_PATH">
|
||||
<DirectorySearch Id="ProgramFiles64FolderSearch" Path="[ProgramFiles64Folder]">
|
||||
<DirectorySearch Id="PodmanFolderSearch" Path="Podman">
|
||||
<FileSearch Name="podman.exe" />
|
||||
</DirectorySearch>
|
||||
</DirectorySearch>
|
||||
</Property>
|
||||
|
||||
<SetProperty Id="CONFDIR"
|
||||
Action="SetCONFDIR_User"
|
||||
Value="[AppDataFolder]containers\containers.conf.d"
|
||||
Before="AppSearch"
|
||||
Condition="MSIINSTALLPERUSER=1 AND NOT IS_UPGRADE"
|
||||
Sequence="first" />
|
||||
|
||||
<SetProperty Id="CONFDIR"
|
||||
Action="SetCONFDIR_Machine"
|
||||
Value="[CommonAppDataFolder]containers\containers.conf.d"
|
||||
Before="AppSearch"
|
||||
Condition="ALLUSERS=1 AND NOT MSIINSTALLPERUSER=1 AND NOT IS_UPGRADE"
|
||||
Sequence="first" />
|
||||
|
||||
<!--
|
||||
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 (<PFILESDIR>/Podman/podman.exe) doesn't exist or, if it exists, the machine provider config file exists
|
||||
-->
|
||||
<SetProperty Id="CREATE_MACHINE_PROVIDER_CONFIG_FILE"
|
||||
After="AppSearch"
|
||||
Value="1"
|
||||
Sequence="first"
|
||||
Condition="(NOT (SKIP_CONFIG_FILE_CREATION = 1)) AND ((NOT MAIN_EXECUTABLE_FILE_PATH) OR (MACHINE_PROVIDER_CONFIG_FILE_PATH))" />
|
||||
|
||||
<!--
|
||||
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 (<CONFDIR>/containers/containers.conf.d/99-podman-machine-provider.conf) exists
|
||||
- The main executable file (<PFILESDIR>/Podman/podman.exe) exists
|
||||
-->
|
||||
<SetProperty Id="HIDE_PROVIDER_CHOICE"
|
||||
After="AppSearch"
|
||||
Value="1"
|
||||
Sequence="first"
|
||||
Condition="(SKIP_CONFIG_FILE_CREATION = 1) OR (MACHINE_PROVIDER_CONFIG_FILE_PATH) OR (MAIN_EXECUTABLE_FILE_PATH)" />
|
||||
|
||||
<CustomAction Id="OpenGuide" DllEntry="WixShellExec" Impersonate="yes" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" />
|
||||
<util:BroadcastEnvironmentChange />
|
||||
<Feature Id="Complete" Level="1">
|
||||
<ComponentRef Id="INSTALLDIR_Component" />
|
||||
<ComponentRef Id="EnvEntriesComponent" />
|
||||
<ComponentRef Id="MainExecutable" />
|
||||
<ComponentRef Id="WinSshProxyExecutable" />
|
||||
<?if $(var.UseGVProxy) != Skip?>
|
||||
<ComponentRef Id="GvProxyExecutable" />
|
||||
<?endif?>
|
||||
<ComponentRef Id="GuideHTMLComponent" />
|
||||
<ComponentGroupRef Id="ManFiles" />
|
||||
</Feature>
|
||||
<Feature Id="MachineProviderConfig" Level="1">
|
||||
<ComponentRef Id="MachineProviderConfigFile" />
|
||||
</Feature>
|
||||
|
||||
<Icon Id="podman.ico" SourceFile="resources/podman-logo.ico" />
|
||||
<Property Id="ARPPRODUCTICON" Value="podman.ico" />
|
||||
<Property Id="WixShellExecTarget" Value="[#GuideHTMLFile]" />
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Show Getting Started Guide" />
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
|
||||
<WixVariable Id="WixUIBannerBmp" Value="resources\podman-banner.png" />
|
||||
<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 Installed) AND (NOT UpdateStarted)" />
|
||||
</UI>
|
||||
|
||||
<!--
|
||||
ProgramFiles6432Folder corresponds to %ProgramFiles% when the scope
|
||||
is machine and to %LocalAppData%\Programs when the scope is user.
|
||||
https://learn.microsoft.com/en-us/windows/win32/msi/single-package-authoring
|
||||
-->
|
||||
<StandardDirectory Id="ProgramFiles6432Folder">
|
||||
<Directory Id="INSTALLDIR" Name="Podman">
|
||||
<Component Id="INSTALLDIR_Component" Guid="14B310C4-9B5D-4DA5-ADF9-B9D008E4CD82" Bitness="always64">
|
||||
<CreateFolder />
|
||||
<RegistryKey Root="HKMU" Key="SOFTWARE\Podman">
|
||||
<RegistryValue Name="InstallDir" Value="[INSTALLDIR]" Type="string" />
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
<Component Id="MainExecutable" Guid="73752F94-6589-4C7B-ABED-39D655A19714" Bitness="always64">
|
||||
<File Id="MainExecutableFile" Name="podman.exe" Source="..\artifacts\podman.exe" KeyPath="yes" />
|
||||
</Component>
|
||||
<Component Id="WinSshProxyExecutable" Guid="0DA730AB-2F97-40E8-A8FC-356E88EAA4D2" Bitness="always64">
|
||||
<File Id="WinSshProxyExecutableFile" Name="win-sshproxy.exe" Source="..\artifacts\win-sshproxy.exe" KeyPath="yes" />
|
||||
</Component>
|
||||
<?if $(var.UseGVProxy) != Skip?>
|
||||
<Component Id="GvProxyExecutable" Guid="1A4A2975-AD2D-44AA-974B-9B343C098333" Bitness="always64">
|
||||
<File Id="GvProxyExecutableFile" Name="gvproxy.exe" Source="..\artifacts\gvproxy.exe" KeyPath="yes" />
|
||||
</Component>
|
||||
<?endif?>
|
||||
<Component Id="GuideHTMLComponent" Guid="8B23C76B-F7D4-4030-8C46-1B5729E616B5" Bitness="always64">
|
||||
<File Id="GuideHTMLFile" Name="welcome-podman.html" Source="..\docs\podman-for-windows.html" KeyPath="yes" />
|
||||
</Component>
|
||||
</Directory>
|
||||
</StandardDirectory>
|
||||
<!--
|
||||
The following code creates the `<CONFDIR>/containers/containers.conf.d` directory
|
||||
CONFDIR is the logical target directory whose path will be set by the CONFDIR property.
|
||||
-->
|
||||
<Directory Id="CONFDIR">
|
||||
<Component Id="MachineProviderConfigFile" Guid="C32C0040-D9AF-4155-AC7E-465B63B6BE3B" Condition="CREATE_MACHINE_PROVIDER_CONFIG_FILE" Transitive="true">
|
||||
<CreateFolder />
|
||||
<IniFile Id="MachineProviderConfigFile" Action="createLine" Directory="CONFDIR" Section="machine" Name="99-podman-machine-provider.conf" Key="provider" Value=""[MACHINE_PROVIDER]""/>
|
||||
</Component>
|
||||
</Directory>
|
||||
<Directory Id="EnvEntries">
|
||||
<Component Id="EnvEntriesComponent" Guid="b662ec43-0e0e-4018-8bf3-061904bb8f5b" Bitness="always64">
|
||||
<CreateFolder />
|
||||
<Environment Id="UpdatePath" Name="PATH" Action="set" Permanent="no" Part="last" Value="[INSTALLDIR]" />
|
||||
</Component>
|
||||
</Directory>
|
||||
</Package>
|
||||
</Wix>
|
||||
48
contrib/win-installer/wix/podman-ui-main.wxs
Normal file
@@ -0,0 +1,48 @@
|
||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. -->
|
||||
|
||||
<!--
|
||||
First-time install dialog sequence:
|
||||
- WixUI_WelcomeEulaDlg
|
||||
|
||||
Maintenance dialog sequence:
|
||||
WixUI_MaintenanceWelcomeDlg
|
||||
- WixUI_MaintenanceTypeDlg
|
||||
- WixUI_VerifyReadyDlg
|
||||
|
||||
Patch dialog sequence:
|
||||
- WixUI_WelcomeDlg
|
||||
- WixUI_VerifyReadyDlg
|
||||
-->
|
||||
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
||||
<Fragment>
|
||||
<UI Id="PodmanUI">
|
||||
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
|
||||
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
|
||||
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
|
||||
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
|
||||
<Property Id="WixUI_Mode" Value="Minimal" />
|
||||
<DialogRef Id="ErrorDlg" />
|
||||
<DialogRef Id="FatalError" />
|
||||
<DialogRef Id="FilesInUse" />
|
||||
<DialogRef Id="MsiRMFilesInUse" />
|
||||
<DialogRef Id="PrepareDlg" />
|
||||
<DialogRef Id="ProgressDlg" />
|
||||
<DialogRef Id="ResumeDlg" />
|
||||
<DialogRef Id="UserExit" />
|
||||
<DialogRef Id="WelcomeInstallDlg" />
|
||||
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999" />
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" />
|
||||
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg" />
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg" />
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg" />
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg" />
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeInstallDlg" Order="2" Condition="Installed AND PATCH" />
|
||||
<InstallUISequence>
|
||||
<Show Dialog="WelcomeInstallDlg" Before="ProgressDlg" Condition="(NOT Installed) AND NOT AFTERREBOOT" />
|
||||
</InstallUISequence>
|
||||
<Property Id="ARPNOMODIFY" Value="1" />
|
||||
</UI>
|
||||
<UIRef Id="WixUI_Common" />
|
||||
</Fragment>
|
||||
</Wix>
|
||||
33
contrib/win-installer/wix/podman-ui-welcome-dlg.wxs
Normal file
@@ -0,0 +1,33 @@
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
||||
<Fragment>
|
||||
<UI>
|
||||
<Dialog Id="WelcomeInstallDlg" Width="370" Height="270" Title="!(loc.WelcomeDlg_Title)">
|
||||
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.WelcomeDlgBitmap)" />
|
||||
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgTitle)" />
|
||||
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
|
||||
<Control Id="DescriptionInstall" Type="Text" X="135" Y="50" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgDescription)" HideCondition="WIX_UPGRADE_DETECTED" />
|
||||
<Control Id="DescriptionUpdate" Type="Text" X="135" Y="50" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeUpdateDlgDescriptionUpdate)" HideCondition="NOT WIX_UPGRADE_DETECTED" />
|
||||
<Control Id="ProviderChoice" Type="Text" X="135" Y="115" Width="220" Height="18" Transparent="yes" NoPrefix="yes" Text="Select the Virtualization Provider for the Podman machine:" HideCondition="HIDE_PROVIDER_CHOICE" />
|
||||
<Control Type="RadioButtonGroup" Property="MACHINE_PROVIDER" Id="MachineProviderRadioButtonGroup" Width="226" Height="30" X="135" Y="135" HideCondition="HIDE_PROVIDER_CHOICE">
|
||||
<RadioButtonGroup Property="MACHINE_PROVIDER">
|
||||
<RadioButton Text="Windows Linux Subsystem (WSLv2)" Height="15" Value="wsl" Width="226" X="10" Y="0" />
|
||||
<RadioButton Text="Windows Hyper-V" Height="15" Value="hyperv" Width="226" X="10" Y="15" />
|
||||
</RadioButtonGroup>
|
||||
</Control>
|
||||
<Control Id="Back" Type="PushButton" X="156" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
|
||||
<Control Id="Install" Type="PushButton" ElevationShield="no" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.WixUINext)">
|
||||
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg" Condition="!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1" />
|
||||
<Publish Event="EndDialog" Value="Return" Condition="OutOfDiskSpace <> 1" />
|
||||
<Publish Event="SpawnDialog" Value="OutOfRbDiskDlg" Condition="OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)" />
|
||||
<Publish Event="EndDialog" Value="Return" Condition="OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"" />
|
||||
<Publish Event="EnableRollback" Value="False" Condition="OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"" />
|
||||
<Publish Event="SpawnDialog" Value="OutOfDiskDlg" Condition="(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")" />
|
||||
</Control>
|
||||
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
|
||||
<Publish Event="SpawnDialog" Value="CancelDlg" />
|
||||
</Control>
|
||||
|
||||
</Dialog>
|
||||
</UI>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
20
contrib/win-installer/wix/podman.wixproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="WixToolset.Sdk/5.0.2">
|
||||
<PropertyGroup>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<HarvestDirectory Include="..\docs">
|
||||
<ComponentGroupName>ManFiles</ComponentGroupName>
|
||||
<DirectoryRefId>INSTALLDIR</DirectoryRefId>
|
||||
<SuppressRootDirectory>true</SuppressRootDirectory>
|
||||
</HarvestDirectory>
|
||||
<BindPath Include="..\docs" />
|
||||
<Compile Include="podman-main.wxs;podman-ui-main.wxs;podman-ui-welcome-dlg.wxs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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>
|
||||
BIN
contrib/win-installer/wix/resources/podman-banner.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
contrib/win-installer/wix/resources/podman-dialog.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
contrib/win-installer/wix/resources/podman-logo.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
313
winmake.ps1
@@ -1,16 +1,16 @@
|
||||
|
||||
#!/usr/bin/env powershell
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param (
|
||||
[ValidateSet("amd64", "arm64")]
|
||||
[Alias("arch")]
|
||||
[ValidateSet('amd64', 'arm64')]
|
||||
[Alias('arch')]
|
||||
[string]$architecture = $(
|
||||
$defaultArchitecture = "amd64"
|
||||
$arch = try {& go env GOARCH} catch {
|
||||
$defaultArchitecture = 'amd64'
|
||||
$arch = try { & go env GOARCH } catch {
|
||||
Write-Warning "Failed retriving the host architecture, using default ($defaultArchitecture). Is Go installed?"
|
||||
return $defaultArchitecture
|
||||
}
|
||||
if ($arch -cnotin @("arm64", "amd64")) {
|
||||
if ($arch -cnotin @('arm64', 'amd64')) {
|
||||
Write-Warning "Unsupported architecture $arch. Using default ($defaultArchitecture)."
|
||||
return $defaultArchitecture
|
||||
}
|
||||
@@ -22,8 +22,8 @@ param (
|
||||
. ./contrib/cirrus/win-lib.ps1
|
||||
|
||||
# Targets
|
||||
function Podman-Remote{
|
||||
New-Item -ItemType Directory -Force -Path "./bin/windows"
|
||||
function Podman-Remote {
|
||||
New-Item -ItemType Directory -Force -Path './bin/windows'
|
||||
|
||||
$buildInfo = Get-Date -UFormat %s -Millisecond 0
|
||||
$buildInfo = "-X github.com/containers/podman/v5/libpod/define.buildInfo=$buildInfo "
|
||||
@@ -34,8 +34,8 @@ function Podman-Remote{
|
||||
Run-Command "go build --ldflags `"$commit $buildInfo `" --tags `"$remotetags`" --o ./bin/windows/podman.exe ./cmd/podman/."
|
||||
}
|
||||
|
||||
function Make-Clean{
|
||||
$paths= @(
|
||||
function Make-Clean {
|
||||
$paths = @(
|
||||
# Files generated by the `podman` target
|
||||
"$PSScriptRoot\bin\windows"
|
||||
# Files generated by the `installer` target
|
||||
@@ -43,12 +43,22 @@ function Make-Clean{
|
||||
"$PSScriptRoot\contrib\win-installer\artifacts"
|
||||
"$PSScriptRoot\contrib\win-installer\current"
|
||||
"$PSScriptRoot\contrib\win-installer\docs"
|
||||
"$PSScriptRoot\contrib\win-installer\en-us"
|
||||
"$PSScriptRoot\contrib\win-installer\fetch"
|
||||
"$PSScriptRoot\contrib\win-installer\obj"
|
||||
"$PSScriptRoot\contrib\win-installer\wix\obj"
|
||||
"$PSScriptRoot\contrib\win-installer\*.log"
|
||||
"$PSScriptRoot\contrib\win-installer\*.exe"
|
||||
"$PSScriptRoot\contrib\win-installer\*.msi"
|
||||
"$PSScriptRoot\contrib\win-installer\*.wixpdb"
|
||||
"$PSScriptRoot\contrib\win-installer\shasums"
|
||||
# Files generated by the `installer-legacy` target
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\artifacts"
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\current"
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\docs"
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\en-us"
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\fetch"
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\obj"
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\*.log"
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\*.exe"
|
||||
"$PSScriptRoot\contrib\win-installer-legacy\*.wixpdb"
|
||||
# Files generated by the Documentation target
|
||||
"$PSScriptRoot\docs\build\remote\podman-*.html"
|
||||
"$PSScriptRoot\docs\build\remote\podman-for-windows.html"
|
||||
@@ -57,7 +67,8 @@ function Make-Clean{
|
||||
foreach ($path in $paths) {
|
||||
if (Test-Path -Path $path -PathType Container) {
|
||||
Remove-Item $path -Recurse -Force -Confirm:$false
|
||||
} elseif (Test-Path -Path $path -PathType Leaf) {
|
||||
}
|
||||
elseif (Test-Path -Path $path -PathType Leaf) {
|
||||
Remove-Item $path -Force -Confirm:$false
|
||||
}
|
||||
}
|
||||
@@ -65,22 +76,23 @@ function Make-Clean{
|
||||
|
||||
function Local-Unit {
|
||||
Build-Ginkgo
|
||||
$skippackages="hack,internal\domain\infra\abi,internal\domain\infra\tunnel,libpod\lock\shm,pkg\api\handlers\libpod,pkg\api\handlers\utils,pkg\bindings,"
|
||||
$skippackages+="pkg\domain\infra\abi,pkg\emulation,pkg\machine\apple,pkg\machine\applehv,pkg\machine\e2e,pkg\machine\libkrun,"
|
||||
$skippackages+="pkg\machine\provider,pkg\machine\proxyenv,pkg\machine\qemu,pkg\specgen\generate,pkg\systemd,test\e2e,test\utils,cmd\rootlessport,"
|
||||
$skippackages+="pkg\pidhandle"
|
||||
$skippackages = 'hack,internal\domain\infra\abi,internal\domain\infra\tunnel,libpod\lock\shm,pkg\api\handlers\libpod,pkg\api\handlers\utils,pkg\bindings,'
|
||||
$skippackages += 'pkg\domain\infra\abi,pkg\emulation,pkg\machine\apple,pkg\machine\applehv,pkg\machine\e2e,pkg\machine\libkrun,'
|
||||
$skippackages += 'pkg\machine\provider,pkg\machine\proxyenv,pkg\machine\qemu,pkg\specgen\generate,pkg\systemd,test\e2e,test\utils,cmd\rootlessport,'
|
||||
$skippackages += 'pkg\pidhandle'
|
||||
if ($null -eq $ENV:GINKGOTIMEOUT) { $ENV:GINKGOTIMEOUT = '--timeout=15m' }
|
||||
Run-Command "./bin/ginkgo.exe -vv -r --tags `"$remotetags`" ${ENV:GINKGOTIMEOUT} --trace --no-color --skip-package `"$skippackages`""
|
||||
}
|
||||
|
||||
function Local-Machine {
|
||||
param (
|
||||
[string]$files
|
||||
[string]$files
|
||||
);
|
||||
Build-Ginkgo
|
||||
if ($files) {
|
||||
$files = "--focus-file ""$files"""
|
||||
} elseif ($FOCUS_FILE) {
|
||||
$files = "--focus-file ""$files"""
|
||||
}
|
||||
elseif ($FOCUS_FILE) {
|
||||
$files = "--focus-file ""$FOCUS_FILE"" --silence-skips"
|
||||
}
|
||||
if ($FOCUS) {
|
||||
@@ -97,25 +109,27 @@ function Win-SSHProxy {
|
||||
[string]$Version
|
||||
);
|
||||
|
||||
New-Item -ItemType Directory -Force -Path "./bin/windows"
|
||||
New-Item -ItemType Directory -Force -Path './bin/windows'
|
||||
if (-Not $Version) {
|
||||
$match = Select-String -Path "$PSScriptRoot\go.mod" -Pattern "github.com/containers/gvisor-tap-vsock\s+(v[\d\.]+)"
|
||||
$match = Select-String -Path "$PSScriptRoot\go.mod" -Pattern 'github.com/containers/gvisor-tap-vsock\s+(v[\d\.]+)'
|
||||
$Version = $match.Matches.Groups[1].Value
|
||||
}
|
||||
Write-Host "Downloading gvproxy version $version"
|
||||
if ($architecture -eq "amd64") {
|
||||
curl.exe -sSL -o "./bin/windows/gvproxy.exe" --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/gvproxy-windowsgui.exe"
|
||||
curl.exe -sSL -o "./bin/windows/win-sshproxy.exe" --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/win-sshproxy.exe"
|
||||
} else {
|
||||
curl.exe -sSL -o "./bin/windows/gvproxy.exe" --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/gvproxy-windows-arm64.exe"
|
||||
curl.exe -sSL -o "./bin/windows/win-sshproxy.exe" --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/win-sshproxy-arm64.exe"
|
||||
if ($architecture -eq 'amd64') {
|
||||
curl.exe -sSL -o './bin/windows/gvproxy.exe' --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/gvproxy-windowsgui.exe"
|
||||
curl.exe -sSL -o './bin/windows/win-sshproxy.exe' --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/win-sshproxy.exe"
|
||||
}
|
||||
else {
|
||||
curl.exe -sSL -o './bin/windows/gvproxy.exe' --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/gvproxy-windows-arm64.exe"
|
||||
curl.exe -sSL -o './bin/windows/win-sshproxy.exe' --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/win-sshproxy-arm64.exe"
|
||||
}
|
||||
}
|
||||
|
||||
function Installer{
|
||||
function Installer {
|
||||
param (
|
||||
[string]$version,
|
||||
[string]$suffix = "dev"
|
||||
[string]$suffix = 'dev',
|
||||
[string]$installerPath = "$PSScriptRoot\contrib\win-installer"
|
||||
);
|
||||
Write-Host "Building the windows installer for $architecture"
|
||||
|
||||
@@ -130,15 +144,15 @@ function Installer{
|
||||
if (!(Test-Path -Path $PSItem -PathType Leaf)) {
|
||||
Write-Host "$PSItem not found."
|
||||
Write-Host "Make 'podman', 'win-gvproxy' and 'docs' (or 'docs-using-podman') before making the installer:"
|
||||
Write-Host " .\winmake.ps1 podman-remote"
|
||||
Write-Host " .\winmake.ps1 win-gvproxy"
|
||||
Write-Host " .\winmake.ps1 docs or .\winmake.ps1 docs-using-podman"
|
||||
Write-Host ' .\winmake.ps1 podman-remote'
|
||||
Write-Host ' .\winmake.ps1 win-gvproxy'
|
||||
Write-Host ' .\winmake.ps1 docs or .\winmake.ps1 docs-using-podman'
|
||||
Exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Create the ZIP file with the full client distribution
|
||||
$zipFileDest = "$PSScriptRoot\contrib\win-installer\current"
|
||||
$zipFileDest = "$installerPath\current"
|
||||
Build-Distribution-Zip-File -destinationPath $zipFileDest
|
||||
|
||||
if (-Not $version) {
|
||||
@@ -146,20 +160,21 @@ function Installer{
|
||||
$version = Get-Podman-Version
|
||||
}
|
||||
|
||||
# Run \contrib\win-installer\build.ps1
|
||||
Push-Location $PSScriptRoot\contrib\win-installer
|
||||
$ENV:PODMAN_ARCH = $architecture # This is used by the "build.ps1" script
|
||||
Run-Command ".\build.ps1 $version $suffix `"$zipFileDest`""
|
||||
Pop-Location
|
||||
# Run build.ps1
|
||||
if ($installerPath -eq "$PSScriptRoot\contrib\win-installer-legacy") {
|
||||
$ENV:PODMAN_ARCH = $architecture # This is used by the "build.ps1" script
|
||||
Run-Command "$installerPath\build.ps1 $version $suffix `"$zipFileDest`""
|
||||
}
|
||||
else {
|
||||
Run-Command "$installerPath\build.ps1 -Version $version -Architecture $architecture -LocalReleaseDirPath `"$zipFileDest`""
|
||||
}
|
||||
}
|
||||
|
||||
function Test-Installer{
|
||||
function Test-Installer {
|
||||
param (
|
||||
[string]$version,
|
||||
[ValidateSet("dev", "prod")]
|
||||
[string]$flavor = "dev",
|
||||
[ValidateSet("wsl", "hyperv")]
|
||||
[string]$provider = "wsl"
|
||||
[ValidateSet('wsl', 'hyperv')]
|
||||
[string]$provider = 'wsl'
|
||||
);
|
||||
|
||||
if (-Not $version) {
|
||||
@@ -167,42 +182,82 @@ function Test-Installer{
|
||||
$version = Get-Podman-Version
|
||||
}
|
||||
|
||||
if ($flavor -eq "prod") {
|
||||
$suffix = ""
|
||||
} else {
|
||||
$suffix = "-dev"
|
||||
$msiPath = "$PSScriptRoot\contrib\win-installer\podman-${version}.msi"
|
||||
if (!(Test-Path -Path $msiPath -PathType Leaf)) {
|
||||
Write-Host "MSI executable not found in path $msiPath."
|
||||
Write-Host "Make 'installer' before making the installer test:"
|
||||
Write-Host ' .\winmake.ps1 installer'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
$setupExePath = "$PSScriptRoot\contrib\win-installer\podman-${version}${suffix}-setup.exe"
|
||||
$nextMsiPath = "$PSScriptRoot\contrib\win-installer\podman-9.9.9.msi"
|
||||
if (!(Test-Path -Path $nextMsiPath -PathType Leaf)) {
|
||||
Write-Host 'The automated tests include testing the upgrade from current version to a future version.'
|
||||
Write-Host 'That requires a version 9.9.9 of the installer:'
|
||||
Write-Host ' .\winmake.ps1 installer 9.9.9'
|
||||
Write-Host 'Build it and retry running installertest.'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
$command = "$PSScriptRoot\contrib\win-installer\test.ps1"
|
||||
$command += ' -scenario all'
|
||||
$command += " -provider $provider"
|
||||
$command += " -msiPath $msiPath"
|
||||
$command += " -nextMsiPath $nextMsiPath"
|
||||
Run-Command "${command}"
|
||||
}
|
||||
|
||||
function Test-Installer-Legacy {
|
||||
param (
|
||||
[string]$version,
|
||||
[ValidateSet('dev', 'prod')]
|
||||
[string]$flavor = 'dev',
|
||||
[ValidateSet('wsl', 'hyperv')]
|
||||
[string]$provider = 'wsl'
|
||||
);
|
||||
|
||||
if (-Not $version) {
|
||||
# Get Podman version from local source code
|
||||
$version = Get-Podman-Version
|
||||
}
|
||||
|
||||
if ($flavor -eq 'prod') {
|
||||
$suffix = ''
|
||||
}
|
||||
else {
|
||||
$suffix = '-dev'
|
||||
}
|
||||
|
||||
$setupExePath = "$PSScriptRoot\contrib\win-installer-legacy\podman-${version}${suffix}-setup.exe"
|
||||
if (!(Test-Path -Path $setupExePath -PathType Leaf)) {
|
||||
Write-Host "Setup executable not found in path $setupExePath."
|
||||
Write-Host "Make 'installer' before making the installer test:"
|
||||
Write-Host " .\winmake.ps1 installer"
|
||||
Write-Host ' .\winmake.ps1 installer-legacy'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
$nextSetupExePath = "$PSScriptRoot\contrib\win-installer\podman-9.9.9-dev-setup.exe"
|
||||
$nextSetupExePath = "$PSScriptRoot\contrib\win-installer-legacy\podman-9.9.9-dev-setup.exe"
|
||||
if (!(Test-Path -Path $nextSetupExePath -PathType Leaf)) {
|
||||
Write-Host "The automated tests include testing the upgrade from current version to a future version."
|
||||
Write-Host "That requires a version 9.9.9 of the installer:"
|
||||
Write-Host " .\winmake.ps1 installer 9.9.9"
|
||||
Write-Host "Build it and retry running installertest."
|
||||
Write-Host 'The automated tests include testing the upgrade from current version to a future version.'
|
||||
Write-Host 'That requires a version 9.9.9 of the installer:'
|
||||
Write-Host ' .\winmake.ps1 installer-legacy 9.9.9'
|
||||
Write-Host 'Build it and retry running installertest.'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
$command = "$PSScriptRoot\contrib\win-installer\test-installer.ps1"
|
||||
$command += " -scenario all"
|
||||
$command = "$PSScriptRoot\contrib\win-installer-legacy\test-installer.ps1"
|
||||
$command += ' -scenario all'
|
||||
$command += " -provider $provider"
|
||||
$command += " -setupExePath $setupExePath"
|
||||
$command += " -nextSetupExePath $nextSetupExePath"
|
||||
Run-Command "${command}"
|
||||
}
|
||||
|
||||
function Documentation{
|
||||
Write-Host "Generating the documentation artifacts"
|
||||
function Documentation {
|
||||
Write-Host 'Generating the documentation artifacts'
|
||||
# Check that pandoc is installed
|
||||
if (!(Get-Command -Name "pandoc" -ErrorAction SilentlyContinue)) {
|
||||
Write-Host "Pandoc not found. Pandoc is required to convert the documentation Markdown files into HTML files."
|
||||
if (!(Get-Command -Name 'pandoc' -ErrorAction SilentlyContinue)) {
|
||||
Write-Host 'Pandoc not found. Pandoc is required to convert the documentation Markdown files into HTML files.'
|
||||
Write-Host "Alternatively, use '.\winmake docs-using-podman' to use a container to run pandoc and generate the documentation."
|
||||
Exit 1
|
||||
}
|
||||
@@ -222,8 +277,8 @@ function Documentation{
|
||||
# The whole podman git repository is bind mounted in the container at /podman.
|
||||
# The documentation is generated by running the command `make podman-remote-windows-docs`.
|
||||
# The generated documentation is stored in the directory docs/build/remote.
|
||||
function DocumentationUsingPodman{
|
||||
Write-Host "Generating documentation artifacts"
|
||||
function DocumentationUsingPodman {
|
||||
Write-Host 'Generating documentation artifacts'
|
||||
# Check that podman has been built
|
||||
$podmanClient = "${PSScriptRoot}\bin\windows\podman.exe"
|
||||
if (!(Test-Path -Path $podmanClient -PathType Leaf)) {
|
||||
@@ -238,29 +293,29 @@ function DocumentationUsingPodman{
|
||||
}
|
||||
# Check that the podman machine is running
|
||||
$state = (& ${podmanClient} machine info -f json | ConvertFrom-Json).Host.MachineState
|
||||
if ($state -ne "Running") {
|
||||
Write-Host "Podman machine is not running. Start the machine before running the validate script."
|
||||
if ($state -ne 'Running') {
|
||||
Write-Host 'Podman machine is not running. Start the machine before running the validate script.'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
Write-Host "Building the image to generate the documentation"
|
||||
Write-Host 'Building the image to generate the documentation'
|
||||
Run-Command "${podmanClient} build --build-arg TARGET_OS=windows -t podman-docs-generator ${PSScriptRoot}/docs"
|
||||
|
||||
Write-Host "Starting the container to run the documentation build"
|
||||
Write-Host 'Starting the container to run the documentation build'
|
||||
Run-Command "${podmanClient} run -t --rm -v ${PSScriptRoot}:/podman podman-docs-generator"
|
||||
}
|
||||
|
||||
function Validate{
|
||||
$podmanExecutable = "podman"
|
||||
function Validate {
|
||||
$podmanExecutable = 'podman'
|
||||
$podmanSrcVolumeMount = "${PSScriptRoot}:/go/src/github.com/containers/podman"
|
||||
# All files bind mounted from a Windows host are marked as executable.
|
||||
# That makes the pre-commit hook "check-executables-have-shebangs" fail.
|
||||
# Setting the environment variable "SKIP=check-executables-have-shebangs"
|
||||
# allow to skip that pre-commit hook.
|
||||
$podmanEnvVariable = "-e SKIP=check-executables-have-shebangs"
|
||||
$podmanEnvVariable = '-e SKIP=check-executables-have-shebangs'
|
||||
$podmanRunArgs = "--rm -v $podmanSrcVolumeMount --security-opt label=disable -t -w /go/src/github.com/containers/podman $podmanEnvVariable"
|
||||
$validateImage = "quay.io/libpod/validatepr:latest"
|
||||
$validateCommand = "make .validatepr"
|
||||
$validateImage = 'quay.io/libpod/validatepr:latest'
|
||||
$validateCommand = 'make .validatepr'
|
||||
|
||||
# Check that podman is installed
|
||||
if (!(Get-Command -Name $podmanExecutable -ErrorAction SilentlyContinue)) {
|
||||
@@ -277,59 +332,59 @@ function Validate{
|
||||
|
||||
# Check that the podman machine is running
|
||||
$state = (podman machine info -f json | ConvertFrom-Json).Host.MachineState
|
||||
if ($state -ne "Running") {
|
||||
Write-Host "Podman machine is not running. Start the machine before running the validate script."
|
||||
if ($state -ne 'Running') {
|
||||
Write-Host 'Podman machine is not running. Start the machine before running the validate script.'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
Run-Command "$podmanExecutable run $podmanRunArgs $validateImage $validateCommand"
|
||||
}
|
||||
|
||||
function Lint{
|
||||
function Lint {
|
||||
# Check that golangci-lint is installed
|
||||
if (!(Get-Command -Name "golangci-lint" -ErrorAction SilentlyContinue)) {
|
||||
Write-Host "The tool ""golangci-lint"" not found. Install https://golangci-lint.run/ before running the lint script."
|
||||
if (!(Get-Command -Name 'golangci-lint' -ErrorAction SilentlyContinue)) {
|
||||
Write-Host 'The tool "golangci-lint" not found. Install https://golangci-lint.run/ before running the lint script.'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
# Check that pre-commit is installed
|
||||
if (!(Get-Command -Name "pre-commit" -ErrorAction SilentlyContinue)) {
|
||||
Write-Host "The tool ""pre-commit"" not found. Install https://pre-commit.com/ before running the lint script."
|
||||
if (!(Get-Command -Name 'pre-commit' -ErrorAction SilentlyContinue)) {
|
||||
Write-Host 'The tool "pre-commit" not found. Install https://pre-commit.com/ before running the lint script.'
|
||||
Exit 1
|
||||
}
|
||||
|
||||
Run-Command "pre-commit run --all-files"
|
||||
Run-Command 'pre-commit run --all-files'
|
||||
Run-Command "golangci-lint run --timeout=10m --build-tags=`"$remotetags`" $PSScriptRoot\cmd\podman"
|
||||
}
|
||||
|
||||
# Helpers
|
||||
function Build-Ginkgo{
|
||||
function Build-Ginkgo {
|
||||
if (Test-Path -Path ./bin/ginkgo.exe -PathType Leaf) {
|
||||
return
|
||||
}
|
||||
Write-Host "Building Ginkgo"
|
||||
Run-Command "go build -o ./bin/ginkgo.exe ./vendor/github.com/onsi/ginkgo/v2/ginkgo"
|
||||
Write-Host 'Building Ginkgo'
|
||||
Run-Command 'go build -o ./bin/ginkgo.exe ./vendor/github.com/onsi/ginkgo/v2/ginkgo'
|
||||
}
|
||||
|
||||
function Git-Commit{
|
||||
function Git-Commit {
|
||||
# git is not installed by default on windows,
|
||||
# so if we can't get the commit, we don't include this info
|
||||
Get-Command git -ErrorAction SilentlyContinue | out-null
|
||||
if(!$?){
|
||||
Get-Command git -ErrorAction SilentlyContinue | out-null
|
||||
if (!$?) {
|
||||
return
|
||||
}
|
||||
$commit = git rev-parse HEAD
|
||||
$dirty = git status --porcelain --untracked-files=no
|
||||
if ($dirty){
|
||||
if ($dirty) {
|
||||
$commit = "$commit-dirty"
|
||||
}
|
||||
return $commit
|
||||
}
|
||||
|
||||
function Build-Distribution-Zip-File{
|
||||
function Build-Distribution-Zip-File {
|
||||
param (
|
||||
[string]$destinationPath
|
||||
);
|
||||
);
|
||||
$binariesFolder = "$PSScriptRoot\bin\windows"
|
||||
$documentationFolder = "$PSScriptRoot\docs\build\remote\"
|
||||
$zipFile = "$destinationPath\podman-remote-release-windows_$architecture.zip"
|
||||
@@ -355,23 +410,23 @@ function Build-Distribution-Zip-File{
|
||||
Remove-Item -Recurse -Force -Path "$tempFolder"
|
||||
}
|
||||
|
||||
function Get-Podman-Version{
|
||||
function Get-Podman-Version {
|
||||
$versionSrc = "$PSScriptRoot\test\version\"
|
||||
$versionBin = "$PSScriptRoot\test\version\version.exe"
|
||||
Run-Command "go build --o `"$versionBin`" `"$versionSrc`""
|
||||
$version = Invoke-Expression "$versionBin"
|
||||
# Remove the '-dev' suffix from the version
|
||||
$version = $version -replace "-.*", ""
|
||||
$version = $version -replace '-.*', ''
|
||||
return $version
|
||||
}
|
||||
|
||||
# Init script
|
||||
$target = $params[0]
|
||||
|
||||
$remotetags = "remote exclude_graphdriver_btrfs containers_image_openpgp"
|
||||
$remotetags = 'remote exclude_graphdriver_btrfs containers_image_openpgp'
|
||||
|
||||
switch ($target) {
|
||||
{$_ -in '', 'podman-remote', 'podman'} {
|
||||
{ $_ -in '', 'podman-remote', 'podman' } {
|
||||
Podman-Remote
|
||||
}
|
||||
'localunit' {
|
||||
@@ -386,7 +441,7 @@ switch ($target) {
|
||||
'clean' {
|
||||
Make-Clean
|
||||
}
|
||||
{$_ -in 'win-sshproxy', 'win-gvproxy'} {
|
||||
{ $_ -in 'win-sshproxy', 'win-gvproxy' } {
|
||||
if ($params.Count -gt 1) {
|
||||
$ref = $params[1]
|
||||
}
|
||||
@@ -395,17 +450,35 @@ switch ($target) {
|
||||
'installer' {
|
||||
if ($params.Count -gt 1) {
|
||||
Installer -version $params[1]
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Installer
|
||||
}
|
||||
}
|
||||
'installertest' {
|
||||
if ($params.Count -gt 1) {
|
||||
Test-Installer -provider $params[1]
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Test-Installer
|
||||
}
|
||||
}
|
||||
'installer-legacy' {
|
||||
if ($params.Count -gt 1) {
|
||||
Installer -version $params[1] -installerPath $PSScriptRoot\contrib\win-installer-legacy
|
||||
}
|
||||
else {
|
||||
Installer -installerPath $PSScriptRoot\contrib\win-installer-legacy
|
||||
}
|
||||
}
|
||||
'installertest-legacy' {
|
||||
if ($params.Count -gt 1) {
|
||||
Test-Installer-Legacy -provider $params[1]
|
||||
}
|
||||
else {
|
||||
Test-Installer-Legacy
|
||||
}
|
||||
}
|
||||
'docs' {
|
||||
Documentation
|
||||
}
|
||||
@@ -419,39 +492,39 @@ switch ($target) {
|
||||
Lint
|
||||
}
|
||||
default {
|
||||
Write-Host "Usage: " $MyInvocation.MyCommand.Name "<target> [options] [<-architecture|-arch>=<amd64|arm64>]"
|
||||
Write-Host 'Usage: ' $MyInvocation.MyCommand.Name '<target> [options] [<-architecture|-arch>=<amd64|arm64>]'
|
||||
Write-Host
|
||||
Write-Host "Example: Build podman-remote "
|
||||
Write-Host " .\winmake podman-remote"
|
||||
Write-Host 'Example: Build podman-remote '
|
||||
Write-Host ' .\winmake podman-remote'
|
||||
Write-Host
|
||||
Write-Host "Example: Run all unit tests "
|
||||
Write-Host " .\winmake localunit"
|
||||
Write-Host 'Example: Run all unit tests '
|
||||
Write-Host ' .\winmake localunit'
|
||||
Write-Host
|
||||
Write-Host "Example: Run all machine tests "
|
||||
Write-Host " .\winmake localmachine"
|
||||
Write-Host 'Example: Run all machine tests '
|
||||
Write-Host ' .\winmake localmachine'
|
||||
Write-Host
|
||||
Write-Host "Example: Run specfic machine tests "
|
||||
Write-Host " .\winmake localmachine "basic_test.go""
|
||||
Write-Host 'Example: Run specfic machine tests '
|
||||
Write-Host ' .\winmake localmachine 'basic_test.go""
|
||||
Write-Host
|
||||
Write-Host "Example: Download win-gvproxy and win-sshproxy helpers"
|
||||
Write-Host " .\winmake win-gvproxy"
|
||||
Write-Host 'Example: Download win-gvproxy and win-sshproxy helpers'
|
||||
Write-Host ' .\winmake win-gvproxy'
|
||||
Write-Host
|
||||
Write-Host "Example: Build the windows installer"
|
||||
Write-Host " .\winmake installer"
|
||||
Write-Host 'Example: Build the windows installer'
|
||||
Write-Host ' .\winmake installer'
|
||||
Write-Host
|
||||
Write-Host "Example: Run windows installer tests"
|
||||
Write-Host " .\winmake installertest hyperv"
|
||||
Write-Host 'Example: Run windows installer tests'
|
||||
Write-Host ' .\winmake installertest hyperv'
|
||||
Write-Host
|
||||
Write-Host "Example: Generate the documentation artifacts"
|
||||
Write-Host " .\winmake docs"
|
||||
Write-Host 'Example: Generate the documentation artifacts'
|
||||
Write-Host ' .\winmake docs'
|
||||
Write-Host
|
||||
Write-Host "Example: Generate the documentation artifacts by running pandoc in a container"
|
||||
Write-Host " .\winmake docs-using-podman"
|
||||
Write-Host 'Example: Generate the documentation artifacts by running pandoc in a container'
|
||||
Write-Host ' .\winmake docs-using-podman'
|
||||
Write-Host
|
||||
Write-Host "Example: Validate code changes before submitting a PR"
|
||||
Write-Host " .\winmake validatepr"
|
||||
Write-Host 'Example: Validate code changes before submitting a PR'
|
||||
Write-Host ' .\winmake validatepr'
|
||||
Write-Host
|
||||
Write-Host "Example: Run linters"
|
||||
Write-Host " .\winmake lint"
|
||||
Write-Host 'Example: Run linters'
|
||||
Write-Host ' .\winmake lint'
|
||||
}
|
||||
}
|
||||
|
||||