Add new windows installer and build

Signed-off-by: Jason T. Greene <jason.greene@redhat.com>
This commit is contained in:
Jason T. Greene
2022-08-30 23:23:14 -05:00
parent f4c39df25e
commit ecb9f99b88
29 changed files with 1334 additions and 11 deletions

View File

@ -0,0 +1,96 @@
name: Upload Windows Installer
on:
release:
types: [created, published, edited]
workflow_dispatch:
inputs:
version:
description: 'Release version to build and upload (e.g. "4.2.1")'
required: true
jobs:
build:
runs-on: windows-latest
env:
FETCH_BASE_URL: ${{ github.server_url }}/${{ github.repository }}
steps:
- name: Determine version
id: getversion
run: |
$version = "${{ inputs.version }}"
if ($version.Length -lt 1) {
$version = "${{ github.event.release.tag_name }}"
if ($version.Length -lt 1) {
Write-Host "Could not determine version!"
Exit 1
}
}
Write-Output "::set-output name=version::$version"
- uses: actions/checkout@v3
- name: Check
id: check
run: |
Push-Location contrib\win-installer
.\check.ps1 ${{steps.getversion.outputs.version}}
$code = $LASTEXITCODE
if ($code -eq 2) {
Write-Output "::set-output name=already-exists::true"
Pop-Location
Exit 0
}
Write-Output "UPLOAD_ASSET_NAME=$env:UPLOAD_ASSET_NAME" | Out-File -FilePath $env:GITHUB_ENV -Append
Pop-Location
Exit $code
- name: Set up Go
uses: actions/setup-go@v3
if: steps.check.outputs.already-exists != 'true'
with:
go-version: 1.18
- name: Setup Signature Tooling
if: steps.Check.outputs.already-exists != 'true'
run: |
dotnet tool install --global AzureSignTool --version 3.0.0
echo "CERT_NAME=${{secrets.AZ_CERT_NAME}}" | Out-File -FilePath $env:GITHUB_ENV -Append
echo "VAULT_ID=${{secrets.AZ_VAULT_ID}}" | Out-File -FilePath $env:GITHUB_ENV -Append
echo "APP_ID=${{secrets.AZ_APP_ID}}" | Out-File -FilePath $env:GITHUB_ENV -Append
echo "TENANT_ID=${{secrets.AZ_TENANT_ID}}" | Out-File -FilePath $env:GITHUB_ENV -Append
echo "CLIENT_SECRET=${{secrets.AZ_CLIENT_SECRET}}" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: Build
id: build
if: steps.check.outputs.already-exists != 'true'
run: |
Push-Location contrib\win-installer
.\build.ps1 ${{steps.getversion.outputs.version}} prod
$code = $LASTEXITCODE
if ($code -eq 2) {
Write-Output "::set-output name=artifact-missing::true"
Pop-Location
Exit 0
}
Pop-Location
Exit $code
- name: Upload
if: steps.check.outputs.already-exists != 'true' && steps.build.outputs.artifact-missing != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
Push-Location contrib\win-installer
$version = "${{ steps.getversion.outputs.version }}"
if ($version[0] -ne "v") {
$version = "v$version"
}
gh release upload $version $ENV:UPLOAD_ASSET_NAME
if ($LASTEXITCODE -ne 0) {
.\check.ps1 $version
if ($LASTEXITCODE -eq 2) {
Write-Host "Another job uploaded before us, skipping"
Pop-Location
Exit 0
}
Pop-Location
Exit 1
}
if (Test-Path -Path shasums) {
gh release upload --clobber $version shasums
}
Pop-Location

View File

@ -244,18 +244,17 @@ spelled with complete minutiae.
$ make podman-remote-release-darwin_amd64.zip \
podman-remote-release-darwin_arm64.zip \
podman-remote-release-windows_amd64.zip \
podman.msi \
podman-remote-static
$ mv podman-* bin/
$ cd bin/
$ tar -cvzf podman-remote-static.tar.gz podman-remote-static
$ sha256sum *.zip *.msi *.tar.gz > shasums
$ sha256sum *.zip *.tar.gz > shasums
```
1. The `podman-vX.Y.Z.dmg` file is produced manually by someone in
possession of a developer signing key.
1. In the directory where you downloaded the archives, run
`sha256sum *.tar.gz *.zip *.msi > shasums` to generate SHA sums.
`sha256sum *.tar.gz *.zip > shasums` to generate SHA sums.
1. Go to `https://github.com/containers/podman/releases/tag/vX.Y.Z` and
press the "Edit Release" button. Change the name to the form `vX.Y.Z`
1. If this is a release candidate be certain to click the pre-release
@ -273,4 +272,34 @@ spelled with complete minutiae.
* podman-vX.Y.Z.msi
* podman-remote-static.tar.gz
* shasums
1. Save the release.
1. Click the Publish button to make the release (or pre-release)
available.
1. Check the "Actions" tab, after the publish you should see a job
automatically launch to build the windows installer (named after
the release). There may be more than one running due to the multiple
event states triggered, but this can be ignored, as any duplicates
will gracefully back-off. The job takes 5-6 minutes to complete.
1. Confirm the podman-[version]-setup.exe file is now on the release
page. This might not be the case if you accidentally published the
release before uploading the binaries, as the job may look before
they are available. If that happens, you can either manually kick
off the job (see below), or just make a harmless edit to the
release (e.g. add an extra whitespace character somewhere). As
long as the body content is different in some way, a new run will
be triggered.
## Manually Triggering Windows Installer Build & Upload
### *CLI Approach*
1. Install the GitHub CLI (e.g. `sudo dnf install gh`)
1. Run (replacing below version number to release version)
```
gh workflow run "Upload Windows Installer" -F version="4.2.0"
```
### *GUI Approach*
1. Go to the "Actions" tab
1. On the left pick the "Update Windows Installer" category
1. A blue box will appear above the job list with a right side drop
-down. Click the drop-down and specify the version number in the
dialog that appears

View File

@ -0,0 +1,46 @@
//go:build windows
// +build windows
package main
import (
"C"
"syscall"
"unsafe"
"github.com/containers/podman/v4/pkg/machine/wsl"
)
const KernelWarning = "WSL Kernel installation did not complete successfully. " +
"Podman machine will attempt to install this at a later time. " +
"You can also manually complete the installation using the " +
"\"wsl --update\" command."
//export CheckWSL
func CheckWSL(hInstall uint32) uint32 {
installed := wsl.IsWSLInstalled()
feature := wsl.IsWSLFeatureEnabled()
setMsiProperty(hInstall, "HAS_WSL", strBool(installed))
setMsiProperty(hInstall, "HAS_WSLFEATURE", strBool(feature))
return 0
}
func setMsiProperty(hInstall uint32, name string, value string) {
nameW, _ := syscall.UTF16PtrFromString(name)
valueW, _ := syscall.UTF16PtrFromString(value)
msi := syscall.NewLazyDLL("msi")
proc := msi.NewProc("MsiSetPropertyW")
_, _, _ = proc.Call(uintptr(hInstall), uintptr(unsafe.Pointer(nameW)), uintptr(unsafe.Pointer(valueW)))
}
func strBool(val bool) string {
if val {
return "1"
}
return "0"
}
func main() {}

View File

@ -0,0 +1,73 @@
//go:build windows
// +build windows
package main
import (
"bytes"
"fmt"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows/svc/eventlog"
)
// Logrus hook that delegates to windows event log
type EventLogHook struct {
events *eventlog.Log
}
type LogFormat struct {
name string
}
func (f *LogFormat) Format(entry *logrus.Entry) ([]byte, error) {
var b *bytes.Buffer
if entry.Buffer != nil {
b = entry.Buffer
} else {
b = &bytes.Buffer{}
}
fmt.Fprintf(b, "[%-5s] %s: %s", entry.Level.String(), f.name, entry.Message)
for key, value := range entry.Data {
fmt.Fprintf(b, " {%s = %s}", key, value)
}
b.WriteByte('\n')
return b.Bytes(), nil
}
func NewEventHook(events *eventlog.Log, name string) *EventLogHook {
logrus.SetFormatter(&LogFormat{name})
return &EventLogHook{events}
}
func (hook *EventLogHook) Fire(entry *logrus.Entry) error {
line, err := entry.String()
if err != nil {
return err
}
switch entry.Level {
case logrus.PanicLevel:
return hook.events.Error(1002, line)
case logrus.FatalLevel:
return hook.events.Error(1001, line)
case logrus.ErrorLevel:
return hook.events.Error(1000, line)
case logrus.WarnLevel:
return hook.events.Warning(1000, line)
case logrus.InfoLevel:
return hook.events.Info(1000, line)
case logrus.DebugLevel, logrus.TraceLevel:
return hook.events.Info(1001, line)
default:
return nil
}
}
func (hook *EventLogHook) Levels() []logrus.Level {
return logrus.AllLevels
}

View File

@ -0,0 +1,103 @@
//go:build windows
// +build windows
package main
import (
"fmt"
"os"
"path"
"syscall"
"time"
"unsafe"
"github.com/containers/podman/v4/pkg/machine/wsl"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows/svc/eventlog"
)
const (
MB_ICONWARNING = 0x00000030
MB_OK = 0x00000000
MB_DEFBUTTON1 = 0x00000000
)
const KernelWarning = "WSL Kernel installation did not complete successfully. " +
"Podman machine will attempt to install this at a later time. " +
"You can also manually complete the installation using the " +
"\"wsl --update\" command."
func setupLogging(name string) (*eventlog.Log, error) {
// Reuse the Built-in .NET Runtime Source so that we do not
// have to provide a messaage table and modify the system
// event configuration
log, err := eventlog.Open(".NET Runtime")
if err != nil {
return nil, err
}
logrus.AddHook(NewEventHook(log, name))
logrus.SetLevel(logrus.InfoLevel)
return log, nil
}
func installWslKernel() error {
logrus.Info("Installing WSL Kernel update")
var (
err error
)
backoff := 500 * time.Millisecond
for i := 1; i < 6; i++ {
err = wsl.SilentExec("wsl", "--update")
if err == nil {
break
}
// In case of unusual circumstances (e.g. race with installer actions)
// retry a few times
logrus.Warn("An error occurred attempting the WSL Kernel update, retrying...")
time.Sleep(backoff)
backoff *= 2
}
if err != nil {
err = fmt.Errorf("could not install WSL Kernel: %w", err)
}
return err
}
// Creates an "warn" style pop-up window
func warn(title string, caption string) int {
format := MB_ICONWARNING | MB_OK | MB_DEFBUTTON1
user32 := syscall.NewLazyDLL("user32.dll")
captionPtr, _ := syscall.UTF16PtrFromString(caption)
titlePtr, _ := syscall.UTF16PtrFromString(title)
ret, _, _ := user32.NewProc("MessageBoxW").Call(
uintptr(0),
uintptr(unsafe.Pointer(captionPtr)),
uintptr(unsafe.Pointer(titlePtr)),
uintptr(format))
return int(ret)
}
func main() {
args := os.Args
setupLogging(path.Base(args[0]))
if wsl.IsWSLInstalled() {
// nothing to do
logrus.Info("WSL Kernel already installed")
return
}
result := installWslKernel()
if result != nil {
logrus.Error(result.Error())
_ = warn("Podman Setup", KernelWarning)
}
logrus.Info("WSL Kernel update successful")
}

View File

@ -0,0 +1,28 @@
# Windows Installer Build
## Requirements
1. Win 10+
2. Golang
3. MingW
4. Dotnet SDK (if AzureSignTool)
5. AzureSignTool (optional)
6. WiX Toolset
## Usage
```
.\build.ps1 <version> [prod|dev] [release_dir]
```
## One off build (-dev output (default), unsigned (default))
```
.\build.ps1 4.2.0
```
## Build with a pre-downloaded win release zip in my-download dir
```
.\build.ps1 4.2.0 dev my-download
```

View File

@ -0,0 +1,7 @@
@if "%1" == "" (
@echo "usage: build-burn.bat <version>"
@exit /b 1
)
candle -ext WixUIExtension -ext WixUtilExtension -ext WixBalExtension -arch x64 -dManSource="docs" -dVERSION="%1" burn.wxs || exit /b 1
light -ext WixUIExtension -ext WixUtilExtension -ext WixBalExtension .\burn.wixobj -out podman-setup.exe || exit /b 1

View File

@ -0,0 +1,4 @@
cd ../..
go build -buildmode=c-shared -o contrib/win-installer/artifacts/podman-msihooks.dll ./cmd/podman-msihooks || exit /b 1
go build -ldflags -H=windowsgui -o contrib/win-installer/artifacts/podman-wslkerninst.exe ./cmd/podman-wslkerninst || exit /b 1
cd contrib/win-installer

View File

@ -0,0 +1,8 @@
@if "%1" == "" (
@echo "usage: build-msi.bat <version>"
@exit /b 1
)
heat dir docs -var var.ManSource -cg ManFiles -dr INSTALLDIR -gg -g1 -srd -out pages.wxs || exit /b 1
candle -ext WixUIExtension -ext WixUtilExtension -ext .\artifacts\PanelSwWixExtension.dll -arch x64 -dManSource="docs" -dVERSION="%1" podman.wxs pages.wxs podman-ui.wxs welcome-install-dlg.wxs || exit /b 1
light -ext WixUIExtension -ext WixUtilExtension -ext .\artifacts\PanelSwWixExtension.dll .\podman.wixobj .\pages.wixobj .\podman-ui.wixobj .\welcome-install-dlg.wixobj -out podman.msi || exit /b 1

View File

@ -0,0 +1,156 @@
function ExitOnError() {
if ($LASTEXITCODE -ne 0) {
Exit 1
}
}
function FetchPanel() {
Remove-Item -Recurse -Force -Path fetch -ErrorAction SilentlyContinue | Out-Null
New-Item -Force -ItemType Directory fetch | Out-Null
Push-Location fetch
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -UseBasicParsing -OutFile nuget.exe -ErrorAction Stop `
-Uri https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
.\nuget.exe install PanelSwWixExtension
$code = $LASTEXITCODE
Pop-Location
if ($code -gt 0) {
Exit 1
}
$loc = Get-ChildItem -Recurse -Path fetch -Name PanelSwWixExtension.dll
if (!$loc) {
Write-Host "Could not locate PanelSwWixExtension.dll"
Exit 1
}
Copy-Item -Path fetch/$loc -Destination artifacts/PanelSwWixExtension.dll -ErrorAction Stop
}
function SignItem() {
param(
[Parameter(Mandatory)]
[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 "gcc" "MingW CC"
CheckCommand "candle" "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 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:\Program Files (x86)\WiX Toolset v3.11\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin;;C:\Program Files\Go\bin"
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
}
FetchPanel
.\build-hooks.bat; ExitOnError
SignItem @("artifacts/win-sshproxy.exe",
"artifacts/podman.exe",
"artifacts/podman-msihooks.dll",
"artifacts/podman-wslkerninst.exe")
.\build-msi.bat $ENV:INSTVER; ExitOnError
SignItem @("podman.msi")
.\build-burn.bat $ENV:INSTVER; ExitOnError
insignia -ib podman-setup.exe -o engine.exe; ExitOnError
SignItem @("engine.exe")
$file = "podman-$version$suffix-setup.exe"
insignia -ab 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"

View File

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

View File

@ -0,0 +1,63 @@
function SkipExists {
param(
[Parameter(Mandatory)]
[string]$url,
[Parameter(Mandatory)]
[string]$desc
)
try {
Invoke-WebRequest -Method HEAD -UseBasicParsing -ErrorAction Stop -Uri $url
Write-Host "$desc already uploaded, skipping..."
Exit 2
} Catch {
if ($_.Exception.Response.StatusCode -eq 404) {
Write-Host "$desc does not exist, continuing..."
Return
}
throw $_.Exception
}
}
function SkipNotExists {
param(
[Parameter(Mandatory)]
[string]$url,
[Parameter(Mandatory)]
[string]$desc
)
$ret = ""
try {
Invoke-WebRequest -Method HEAD -UseBasicParsing -ErrorAction Stop -Uri $url
Write-Host "$desc exists, continuing..."
} Catch {
if ($_.Exception.Response.StatusCode -eq 404) {
Write-Host "$desc does not exist, skipping ..."
Exit 2
}
throw $_.Exception
}
}
if ($args.Count -lt 1 -or $args[0].Length -lt 2) {
Write-Host "Usage: " $MyInvocation.MyCommand.Name "<version>"
Exit 1
}
$release = $args[0]
$version = $release
if ($release[0] -eq "v") {
$version = $release.Substring(1)
} else {
$release = "v$release"
}
$base_url = "$ENV:FETCH_BASE_URL"
if ($base_url.Length -le 0) {
$base_url = "https://github.com/containers/podman"
}
$ENV:UPLOAD_ASSET_NAME = "podman-$version-setup.exe"
SkipExists "$base_url/releases/download/$release/podman-$version-setup.exe" "Installer"
SkipNotExists "$base_url/releases/download/$release/podman-remote-release-windows_amd64.zip" "Windows client zip"

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. -->
<WixLocalization Culture="en-us" Language="1033" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="Caption">[WixBundleName] [VERSION] Setup</String>
<String Id="Title">[WixBundleName] [VERSION]</String>
<String Id="InstallHeader">Welcome to [WixBundleName] Setup</String>
<String Id="InstallMessage">Welcome to the [WixBundleName] [VERSION] setup wizard. This will install [WixBundleName] on your computer.
Additionally, you have the option to also install WSL (required by podman) if it is not already enabled. This operation requires a reboot during the installation process. Alternatively, you can deselect the WSL checkbox, and install WSL manually using the wsl --install command.
Finally, click install to continue, or Close to abort the installation.</String>
<String Id="InstallVersion">Version [WixBundleVersion]</String>
<String Id="ConfirmCancelMessage">Are you sure you want to cancel?</String>
<String Id="ExecuteUpgradeRelatedBundleMessage">Previous version</String>
<String Id="HelpHeader">Setup Help</String>
<String Id="HelpText">/install | /repair | /uninstall | /layout [directory] - installs, repairs, uninstalls or
creates a complete local copy of the bundle in directory. Install is the default.
/passive | /quiet - displays minimal UI with no prompts or displays no UI and
no prompts. By default UI and all prompts are displayed.
/norestart - suppress any attempts to restart. By default UI will prompt before restart.
/log log.txt - logs to a specific file. By default a log file is created in %TEMP%.</String>
<String Id="HelpCloseButton">&amp;Close</String>
<String Id="InstallLicenseLinkText">[WixBundleName] &lt;a href="#"&gt;license terms&lt;/a&gt;.</String>
<String Id="InstallAcceptCheckbox">I &amp;agree to the license terms and conditions</String>
<String Id="InstallOptionsButton">&amp;Options</String>
<String Id="InstallInstallButton">&amp;Install</String>
<String Id="InstallCloseButton">&amp;Close</String>
<String Id="OptionsHeader">Setup Options</String>
<String Id="OptionsLocationLabel">Install location:</String>
<String Id="OptionsBrowseButton">&amp;Browse</String>
<String Id="OptionsOkButton">&amp;OK</String>
<String Id="OptionsCancelButton">&amp;Cancel</String>
<String Id="ProgressHeader">Setup Progress</String>
<String Id="ProgressLabel">Processing:</String>
<String Id="OverallProgressPackageText">Initializing...</String>
<String Id="ProgressCancelButton">&amp;Cancel</String>
<String Id="ModifyHeader">Modify Setup</String>
<String Id="ModifyRepairButton">&amp;Repair</String>
<String Id="ModifyUninstallButton">&amp;Uninstall</String>
<String Id="ModifyCloseButton">&amp;Close</String>
<String Id="SuccessRepairHeader">Repair Successfully Completed</String>
<String Id="SuccessUninstallHeader">Uninstall Successfully Completed</String>
<String Id="SuccessInstallHeader">Installation Successfully Completed</String>
<String Id="SuccessHeader">Setup Successful</String>
<String Id="SuccessLaunchButton">&amp;Open Guide &amp;&amp; Close</String>
<String Id="SuccessRestartText">You must restart your computer before you can use the software.</String>
<String Id="SuccessRestartButton">&amp;Restart</String>
<String Id="SuccessCloseButton">&amp;Close</String>
<String Id="FailureHeader">Setup Failed</String>
<String Id="FailureInstallHeader">Setup Failed</String>
<String Id="FailureUninstallHeader">Uninstall Failed</String>
<String Id="FailureRepairHeader">Repair Failed</String>
<String Id="FailureHyperlinkLogText">One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the &lt;a href="#"&gt;log file&lt;/a&gt;.</String>
<String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String>
<String Id="FailureRestartButton">&amp;Restart</String>
<String Id="FailureCloseButton">&amp;Close</String>
<String Id="FilesInUseHeader">Files In Use</String>
<String Id="FilesInUseLabel">The following applications are using files that need to be updated:</String>
<String Id="FilesInUseCloseRadioButton">Close the &amp;applications and attempt to restart them.</String>
<String Id="FilesInUseDontCloseRadioButton">&amp;Do not close applications. A reboot will be required.</String>
<String Id="FilesInUseOkButton">&amp;OK</String>
<String Id="FilesInUseCancelButton">&amp;Cancel</String>
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
</WixLocalization>

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. -->
<Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010">
<Window Width="600" Height="450" HexStyle="100a0000" FontId="0">#(loc.Title) Setup</Window>
<Font Id="0" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
<Font Id="1" Height="-24" Weight="500" Foreground="000000">Segoe UI</Font>
<Font Id="2" Height="-22" Weight="500" Foreground="666666">Segoe UI</Font>
<Font Id="3" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
<Font Id="4" Height="-12" Weight="500" Foreground="ff0000" Background="FFFFFF" Underline="yes">Segoe UI</Font>
<Font Id="5" Height="-28" Weight="500" Foreground="666666">Segoe UI</Font>
<Font Id="6" Height="-12" Weight="600" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
<!-- Divider -->
<Font Id="7" Height="-24" Weight="500" Foreground="000000" Background="E0E0E0">Segoe UI</Font>
<Text X="11" Y="-45" Width="-11" Height="2" FontId="7" Visible="yes"></Text>
<Page Name="Help">
<Image X="11" Y="11" Width="206" Height="64" ImageFile="logo.png"/>
<Text X="11" Y="80" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Text>
<Text X="11" Y="121" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Text>
<Button Name="HelpCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.HelpCloseButton)</Button>
</Page>
<Page Name="Install">
<Image X="11" Y="11" Width="165" Height="364" ImageFile="logoside.png"/>
<Text X="185" Y="11" Width="-11" Height="40" FontId="5" DisablePrefix="yes">#(loc.InstallHeader)</Text>
<Text X="185" Y="82" Width="-11" Height="160" FontId="3" DisablePrefix="yes">#(loc.InstallMessage)</Text><!-- HexStyle="0x800000" -->
<Hypertext Name="EulaHyperlink" X="185" Y="-111" Width="-11" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallLicenseLinkText)</Hypertext>
<Text Name="InstallVersion" X="185" Y="-61" Width="-11" Height="17" FontId="3" DisablePrefix="yes" HideWhenDisabled="yes">#(loc.InstallVersion)</Text>
<Checkbox Name="WSLCheckbox" X="185" Y="250" Width="-11" Height="17" TabStop="yes" FontId="6" HideWhenDisabled="yes">Install WSL if not present</Checkbox>
<Button Name="OptionsButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.InstallOptionsButton)</Button>
<Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
<Button Name="WelcomeCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
</Page>
<Page Name="Options">
<Image X="11" Y="11" Width="206" Height="64" ImageFile="logo.png"/>
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.OptionsHeader)</Text>
<Text X="11" Y="121" Width="-11" Height="17" FontId="3">#(loc.OptionsLocationLabel)</Text>
<Editbox Name="FolderEditbox" X="11" Y="143" Width="-91" Height="21" TabStop="yes" FontId="3" FileSystemAutoComplete="yes" />
<Button Name="BrowseButton" X="-11" Y="142" Width="75" Height="23" TabStop="yes" FontId="3">#(loc.OptionsBrowseButton)</Button>
<Button Name="OptionsOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.OptionsOkButton)</Button>
<Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.OptionsCancelButton)</Button>
</Page>
<Page Name="FilesInUse">
<Image X="11" Y="11" Width="206" Height="64" ImageFile="logo.png"/>
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.FilesInUseHeader)</Text>
<Text X="11" Y="121" Width="-11" Height="34" FontId="3" DisablePrefix="yes">#(loc.FilesInUseLabel)</Text>
<Text Name="FilesInUseText" X="11" Y="150" Width="-11" Height="-86" FontId="3" DisablePrefix="yes" HexStyle="0x0000000C"></Text>
<Button Name="FilesInUseCloseRadioButton" X="11" Y="-70" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseCloseRadioButton)</Button>
<Button Name="FilesInUseDontCloseRadioButton" X="11" Y="-50" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseDontCloseRadioButton)</Button>
<Button Name="FilesInUseOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FilesInUseOkButton)</Button>
<Button Name="FilesInUseCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FilesInUseCancelButton)</Button>
</Page>
<Page Name="Progress">
<Image X="11" Y="11" Width="206" Height="64" ImageFile="logo.png"/>
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
<Text X="11" Y="141" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Text>
<Text Name="OverallProgressPackageText" X="85" Y="141" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
<Progressbar Name="OverallCalculatedProgressbar" X="11" Y="163" Width="-11" Height="20" />
<Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
</Page>
<Page Name="Modify">
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
<Image X="11" Y="11" Width="165" Height="364" ImageFile="logoside.png"/>
<Text X="185" Y="50" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Text>
<Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button>
<Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
<Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyCloseButton)</Button>
</Page>
<Page Name="Success">
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
<Image X="11" Y="11" Width="165" Height="364" ImageFile="logoside.png"/>
<Text Name="SuccessHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessHeader)</Text>
<Text Name="SuccessInstallHeader" X="185" Y="50" Width="-11" Height="100" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessInstallHeader)</Text>
<Text Name="SuccessRepairHeader" X="185" Y="50" Width="-11" Height="100" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRepairHeader)</Text>
<Text Name="SuccessUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessUninstallHeader)</Text>
<Button Name="LaunchButton" X="-91" Y="-11" Width="125" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
<Text Name="SuccessRestartText" X="185" Y="-51" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRestartText)</Text>
<Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
<Button Name="SuccessCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.SuccessCloseButton)</Button>
</Page>
<Page Name="Failure">
<Image X="11" Y="11" Width="165" Height="364" ImageFile="logoside.png"/>
<Text Name="FailureHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureHeader)</Text>
<Text Name="FailureInstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureInstallHeader)</Text>
<Text Name="FailureUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureUninstallHeader)</Text>
<Text Name="FailureRepairHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRepairHeader)</Text>
<Hypertext Name="FailureLogFileLink" X="185" Y="121" Width="-11" Height="68" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
<Hypertext Name="FailureMessageText" X="185" Y="-115" Width="-11" Height="80" FontId="3" TabStop="yes" HideWhenDisabled="yes" />
<Text Name="FailureRestartText" X="185" Y="-57" Width="-11" Height="80" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
</Page>
</Theme>

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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://schemas.microsoft.com/wix/2006/wi">
<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="WelcomeDlg" />
<DialogRef Id="WelcomeInstallDlg" />
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
<InstallUISequence>
<Show Dialog="WelcomeDlg" Before="WelcomeInstallDlg">Installed AND PATCH</Show>
<Show Dialog="WelcomeInstallDlg" Before="ProgressDlg">(NOT Installed) AND NOT AFTERREBOOT</Show>
</InstallUISequence>
<Property Id="ARPNOMODIFY" Value="1" />
</UI>
<UIRef Id="WixUI_Common" />
</Fragment>
</Wix>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:PanelSW="http://schemas.panel-sw.co.il/wix/WixExtension">
<?ifndef var.VERSION?>
<?error VERSION must be defined via command line argument?>
<?endif?>
<Product Name="Podman $(var.VERSION)" Id="*" UpgradeCode="696BAB5D-CA1F-4B05-B123-320F245B8D6D" Version="$(var.VERSION)" Language="1033" Manufacturer="Red Hat Inc.">
<Package Id="*" Platform="x64" Keywords="Installer" Description="Red Hat's Podman $(var.VERSION) Installer" Comments="Apache 2.0 License" Manufacturer="Red Hat Inc." InstallScope="perMachine" InstallerVersion="200" Compressed="yes"/>
<Media Id="1" Cabinet="Podman.cab" EmbedCab="yes"/>
<MajorUpgrade AllowDowngrades="yes"/>
<Property Id="DiskPrompt" Value="Red Hat's Podman $(var.VERSION) Installation"/>
<SetProperty Id="WSL_INSTALL" Before="AppSearch" Value="1" Sequence="first">NOT (WITH_WSL = 0)</SetProperty>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder" Name="PFiles">
<Directory Id="RedHatPFiles" Name="RedHat">
<Directory Id="INSTALLDIR" Name="Podman">
<Component Id="INSTALLDIR_Component" Guid="14B310C4-9B5D-4DA5-ADF9-B9D008E4CD82" Win64="yes">
<CreateFolder/>
</Component>
<Component Id="MainExecutable" Guid="73752F94-6589-4C7B-ABED-39D655A19714" Win64="yes">
<File Id="MainExecutableFile" Name="podman.exe" Source="artifacts/podman.exe" KeyPath="yes"/>
</Component>
<Component Id="WinSshProxyExecutable" Guid="0DA730AB-2F97-40E8-A8FC-356E88EAA4D2" Win64="yes">
<File Id="WinSshProxyExecutableFile" Name="win-sshproxy.exe" Source="artifacts/win-sshproxy.exe" KeyPath="yes"/>
</Component>
<Component Id="GuideHTMLComponent" Guid="8B23C76B-F7D4-4030-8C46-1B5729E616B5" Win64="yes">
<File Id="GuideHTMLFile" Name="welcome-podman.html" Source="docs/podman-for-windows.html" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
<Directory Id="EnvEntries">
<Component Id="EnvEntriesComponent" Guid="b662ec43-0e0e-4018-8bf3-061904bb8f5b" Win64="yes">
<CreateFolder />
<Environment Id='UpdatePath' Name='PATH' Action='set' Permanent='no' System='yes' Part='last' Value='[INSTALLDIR]' />
</Component>
</Directory>
</Directory>
<CustomAction Id="OpenGuide" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<CustomAction Id="CheckWSL" BinaryKey="PodmanHooks" Execute="immediate" DllEntry="CheckWSL" />
<CustomActionRef Id="WixBroadcastEnvironmentChange" />
<ComponentGroup Id="WSLFeature" Directory="INSTALLDIR">
<Component>
<Condition>(NOT Installed) AND WSL_INSTALL = 1 AND HAS_WSLFEATURE = 0</Condition>
<File Source="$(sys.SOURCEFILEPATH)"/>
<PanelSW:Dism EnableFeature="VirtualMachinePlatform" ErrorHandling="prompt"/>
<PanelSW:Dism EnableFeature="Microsoft-Windows-Subsystem-Linux" ErrorHandling="prompt"/>
</Component>
</ComponentGroup>
<Feature Id="Complete" Level="1">
<ComponentRef Id="INSTALLDIR_Component"/>
<ComponentRef Id="EnvEntriesComponent"/>
<ComponentRef Id="MainExecutable"/>
<ComponentRef Id="WinSshProxyExecutable"/>
<ComponentRef Id="GuideHTMLComponent"/>
<ComponentGroupRef Id="ManFiles"/>
<ComponentGroupRef Id="WSLFeature"/>
</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">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<InstallExecuteSequence>
<Custom Action="CheckWSL" After="SetWSL_INSTALL">WSL_INSTALL = 1</Custom>
<ForceReboot Before="StopServices">(NOT Installed) AND WSL_INSTALL = 1 AND HAS_WSLFEATURE = 0 AND NOT AFTERREBOOT</ForceReboot>
</InstallExecuteSequence>
<Binary Id="PodmanHooks" SourceFile="artifacts/podman-msihooks.dll" />
</Product>
</Wix>

View File

@ -0,0 +1,158 @@
function Copy-Artifact {
param(
[Parameter(Mandatory)]
[string]$fileName
)
$file = Get-ChildItem -Recurse -Path . -Name $fileName
if (!$file) {
throw "Could not find $filename"
}
Write-Host "file:" $file
Copy-Item -Path $file -Destination "..\artifacts\$filename" -ErrorAction Stop
}
function DownloadOrSkip {
param(
[Parameter(Mandatory)]
[string]$url,
[Parameter(Mandatory)]
[string]$file
)
$ProgressPreference = 'SilentlyContinue';
try {
Invoke-WebRequest -UseBasicParsing -ErrorAction Stop -Uri $url -OutFile $file
} Catch {
if ($_.Exception.Response.StatusCode -eq 404) {
Write-Host "URL not available, signaling skip:"
Write-Host "URL: $url"
Exit 2
}
throw $_.Exception
}
}
function DownloadOptional {
param(
[Parameter(Mandatory)]
[string]$url,
[Parameter(Mandatory)]
[string]$file
)
$ProgressPreference = 'SilentlyContinue';
try {
Invoke-WebRequest -UseBasicParsing -ErrorAction Stop -Uri $url -OutFile $file
} Catch {
}
Return
}
if ($args.Count -lt 1) {
Write-Host "Usage: " $MyInvocation.MyCommand.Name "<version> [release_dir]"
Exit 1
}
$releaseDir = ""
if ($args.Count -gt 1 -and $args[1].Length -gt 0) {
$path = $args[1]
$releaseDir = (Resolve-Path -Path "$path" -ErrorAction Stop).Path
}
$base_url = "$ENV:FETCH_BASE_URL"
if ($base_url.Length -le 0) {
$base_url = "https://github.com/containers/podman"
}
$version = $args[0]
if ($version -notmatch '^v?([0-9]+\.[0-9]+\.[0-9]+)(-.*)?$') {
Write-Host "Invalid version"
Exit 1
}
# WiX burn requires a QWORD version only, numeric only
$Env:INSTVER=$Matches[1]
if ($version[0] -ne 'v') {
$version = 'v' + $version
}
$restore = 0
$exitCode = 0
try {
Write-Host "Cleaning up old artifacts"
Remove-Item -Force -Recurse -Path .\docs -ErrorAction SilentlyContinue | Out-Null
Remove-Item -Force -Recurse -Path .\artifacts -ErrorAction SilentlyContinue | Out-Null
Remove-Item -Force -Recurse -Path .\fetch -ErrorAction SilentlyContinue | Out-Null
New-Item fetch -ItemType Directory | Out-Null
New-Item artifacts -ItemType Directory | Out-Null
Write-Host "Fetching zip release"
Push-Location fetch -ErrorAction Stop
$restore = 1
$ProgressPreference = 'SilentlyContinue';
if ($releaseDir.Length -gt 0) {
Copy-Item -Path "$releaseDir/podman-remote-release-windows_amd64.zip" "release.zip"
} else {
DownloadOrSkip "$base_url/releases/download/$version/podman-remote-release-windows_amd64.zip" "release.zip"
DownloadOptional "$base_url/releases/download/$version/shasums" ..\shasums
}
Expand-Archive -Path release.zip
$loc = Get-ChildItem -Recurse -Path . -Name win-sshproxy.exe
if (!$loc) {
if ($releaseDir.Length -gt 0) {
throw "Release dir only supports zip which includes win-sshproxy.exe"
}
Write-Host "Old release, zip does not include win-sshproxy.exe, fetching via msi"
DownloadOrSkip "$base_url/releases/download/$version/podman-$version.msi" "podman.msi"
dark -x expand ./podman.msi
if (!$?) {
throw "Dark command failed"
}
$loc = Get-ChildItem -Recurse -Path expand -Name 4A2AD125-34E7-4BD8-BE28-B2A9A5EDBEB5
if (!$loc) {
throw "Could not obtain win-sshproxy.exe"
}
Copy-Item -Path "expand\$loc" -Destination "win-sshproxy.exe" -ErrorAction Stop
Remove-Item -Recurse -Force -Path expand
}
Write-Host "Copying artifacts"
Foreach ($fileName in "win-sshproxy.exe", "podman.exe") {
Copy-Artifact($fileName)
}
$docsloc = Get-ChildItem -Path . -Name docs -Recurse
$loc = Get-ChildItem -Recurse -Path . -Name podman-for-windows.html
if (!$loc) {
Write-Host "Old release did not include welcome page, using podman-machine instead"
$loc = Get-ChildItem -Recurse -Path . -Name podman-machine.html
Copy-Item -Path $loc -Destination "$docsloc\podman-for-windows.html"
}
Write-Host "Copying docs"
Copy-Item -Recurse -Path $docsloc -Destination ..\docs -ErrorAction Stop
Write-Host "Done!"
if (!$loc) {
throw "Could not find docs"
}
}
catch {
Write-Host $_
$exitCode = 1
}
finally {
if ($restore) {
Pop-Location
}
}
exit $exitCode

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,31 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<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="Description" Type="Text" X="135" Y="80" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgDescription)" />
<Control Id="WSLInstallCheckbox" Type="CheckBox" X="135" Y="135" Width="226" Height="18" CheckBoxValue="1" Property="WSL_INSTALL" Default="no" Text="Install WSL Feature (if needed)" />
<Control Id="Back" Type="PushButton" X="156" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)"/>
<Control Id="Install" Type="PushButton" ElevationShield="yes" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.WelcomeEulaDlgInstall)">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1</Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
<Publish Event="SpawnDialog" Value="OutOfRbDiskDlg">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)</Publish>
<Publish Event="EndDialog" Value="Return">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="EnableRollback" Value="False">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="SpawnDialog" Value="OutOfDiskDlg">(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")</Publish>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
</Dialog>
</UI>
<InstallUISequence>
<Show Dialog="WelcomeInstallDlg" Before="ProgressDlg" Overridable="yes">NOT Installed</Show>
</InstallUISequence>
</Fragment>
</Wix>

View File

@ -638,13 +638,13 @@ func installScripts(dist string) error {
}
func checkAndInstallWSL(opts machine.InitOptions) (bool, error) {
if isWSLInstalled() {
if IsWSLInstalled() {
return true, nil
}
admin := hasAdminRights()
if !isWSLFeatureEnabled() {
if !IsWSLFeatureEnabled() {
return false, attemptFeatureInstall(opts, admin)
}
@ -1105,9 +1105,10 @@ func waitPipeExists(pipeName string, retries int, checkFailure func() error) err
return err
}
func isWSLInstalled() bool {
cmd := exec.Command("wsl", "--status")
func IsWSLInstalled() bool {
cmd := SilentExecCmd("wsl", "--status")
out, err := cmd.StdoutPipe()
cmd.Stderr = nil
if err != nil {
return false
}
@ -1131,9 +1132,8 @@ func isWSLInstalled() bool {
return true
}
func isWSLFeatureEnabled() bool {
cmd := exec.Command("wsl", "--set-default-version", "2")
return cmd.Run() == nil
func IsWSLFeatureEnabled() bool {
return SilentExec("wsl", "--set-default-version", "2") == nil
}
func isWSLRunning(dist string) (bool, error) {

View File

@ -6,6 +6,7 @@ import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"
@ -343,3 +344,17 @@ func sendQuit(tid uint32) {
postMessage := user32.NewProc("PostThreadMessageW")
postMessage.Call(uintptr(tid), WM_QUIT, 0, 0)
}
func SilentExec(command string, args ...string) error {
cmd := exec.Command(command, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000}
cmd.Stdout = nil
cmd.Stderr = nil
return cmd.Run()
}
func SilentExecCmd(command string, args ...string) *exec.Cmd {
cmd := exec.Command(command, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000}
return cmd
}

View File

@ -0,0 +1,81 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build windows
// +build windows
package eventlog
import (
"errors"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
)
const (
// Log levels.
Info = windows.EVENTLOG_INFORMATION_TYPE
Warning = windows.EVENTLOG_WARNING_TYPE
Error = windows.EVENTLOG_ERROR_TYPE
)
const addKeyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application`
// Install modifies PC registry to allow logging with an event source src.
// It adds all required keys and values to the event log registry key.
// Install uses msgFile as the event message file. If useExpandKey is true,
// the event message file is installed as REG_EXPAND_SZ value,
// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and
// log.Info to specify events supported by the new event source.
func Install(src, msgFile string, useExpandKey bool, eventsSupported uint32) error {
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.CREATE_SUB_KEY)
if err != nil {
return err
}
defer appkey.Close()
sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE)
if err != nil {
return err
}
defer sk.Close()
if alreadyExist {
return errors.New(addKeyName + `\` + src + " registry key already exists")
}
err = sk.SetDWordValue("CustomSource", 1)
if err != nil {
return err
}
if useExpandKey {
err = sk.SetExpandStringValue("EventMessageFile", msgFile)
} else {
err = sk.SetStringValue("EventMessageFile", msgFile)
}
if err != nil {
return err
}
err = sk.SetDWordValue("TypesSupported", eventsSupported)
if err != nil {
return err
}
return nil
}
// InstallAsEventCreate is the same as Install, but uses
// %SystemRoot%\System32\EventCreate.exe as the event message file.
func InstallAsEventCreate(src string, eventsSupported uint32) error {
return Install(src, "%SystemRoot%\\System32\\EventCreate.exe", true, eventsSupported)
}
// Remove deletes all registry elements installed by the correspondent Install.
func Remove(src string) error {
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.SET_VALUE)
if err != nil {
return err
}
defer appkey.Close()
return registry.DeleteKey(appkey, src)
}

70
vendor/golang.org/x/sys/windows/svc/eventlog/log.go generated vendored Normal file
View File

@ -0,0 +1,70 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build windows
// +build windows
// Package eventlog implements access to Windows event log.
package eventlog
import (
"errors"
"syscall"
"golang.org/x/sys/windows"
)
// Log provides access to the system log.
type Log struct {
Handle windows.Handle
}
// Open retrieves a handle to the specified event log.
func Open(source string) (*Log, error) {
return OpenRemote("", source)
}
// OpenRemote does the same as Open, but on different computer host.
func OpenRemote(host, source string) (*Log, error) {
if source == "" {
return nil, errors.New("Specify event log source")
}
var s *uint16
if host != "" {
s = syscall.StringToUTF16Ptr(host)
}
h, err := windows.RegisterEventSource(s, syscall.StringToUTF16Ptr(source))
if err != nil {
return nil, err
}
return &Log{Handle: h}, nil
}
// Close closes event log l.
func (l *Log) Close() error {
return windows.DeregisterEventSource(l.Handle)
}
func (l *Log) report(etype uint16, eid uint32, msg string) error {
ss := []*uint16{syscall.StringToUTF16Ptr(msg)}
return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil)
}
// Info writes an information event msg with event id eid to the end of event log l.
// When EventCreate.exe is used, eid must be between 1 and 1000.
func (l *Log) Info(eid uint32, msg string) error {
return l.report(windows.EVENTLOG_INFORMATION_TYPE, eid, msg)
}
// Warning writes an warning event msg with event id eid to the end of event log l.
// When EventCreate.exe is used, eid must be between 1 and 1000.
func (l *Log) Warning(eid uint32, msg string) error {
return l.report(windows.EVENTLOG_WARNING_TYPE, eid, msg)
}
// Error writes an error event msg with event id eid to the end of event log l.
// When EventCreate.exe is used, eid must be between 1 and 1000.
func (l *Log) Error(eid uint32, msg string) error {
return l.report(windows.EVENTLOG_ERROR_TYPE, eid, msg)
}

1
vendor/modules.txt vendored
View File

@ -794,6 +794,7 @@ golang.org/x/sys/plan9
golang.org/x/sys/unix
golang.org/x/sys/windows
golang.org/x/sys/windows/registry
golang.org/x/sys/windows/svc/eventlog
# golang.org/x/term v0.0.0-20220526004731-065cf7ba2467
## explicit
golang.org/x/term