diff options
37 files changed, 1465 insertions, 68 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index dc0735836..5d9500e92 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -14,6 +14,8 @@ env: GOPATH: &gopath "/var/tmp/go" GOCACHE: "${GOPATH}/cache" GOSRC: &gosrc "/var/tmp/go/src/github.com/containers/podman" + # Store the unaltered default location, for tasks that need it + CIRRUS_DEFAULT_WORK: ${CIRRUS_WORKING_DIR} CIRRUS_WORKING_DIR: *gosrc # The default is 'sh' if unspecified CIRRUS_SHELL: "/bin/bash" @@ -60,9 +62,10 @@ env: # Curl-command prefix for downloading task artifacts, simply add the # the url-encoded task name, artifact name, and path as a suffix. + ART_URL: https://api.cirrus-ci.com/v1/artifact/build/${CIRRUS_BUILD_ID} ARTCURL: >- curl --retry 5 --retry-delay 8 --fail --location -O - --url https://api.cirrus-ci.com/v1/artifact/build/${CIRRUS_BUILD_ID} + --url ${ART_URL} # Default timeout for each task @@ -1019,6 +1022,7 @@ success_task: - consistency_aarch64 - alt_build - osx_alt_build + - win_installer - docker-py_test - unit_test - apiv2_test @@ -1103,6 +1107,24 @@ artifacts_task: type: application/octet-stream +win_installer_task: + name: "Verify Win Installer Build" + alias: win_installer + depends_on: + - alt_build + windows_container: + image: cirrusci/windowsservercore:2019 + env: + PATH: "${PATH};C:\\ProgramData\\chocolatey\\bin" + CIRRUS_SHELL: powershell + CIRRUS_CLONE_DEPTH: 1 + # Fake version, we are only testing the installer functions, so version doesn't matter + WIN_INST_VER: 9.9.9 + CIRRUS_WORKING_DIR: "${CIRRUS_DEFAULT_WORK}" + install_script: '.\contrib\cirrus\win-installer-install.ps1' + main_script: '.\contrib\cirrus\win-installer-main.ps1' + + # When a new tag is pushed, confirm that the code and commits # meet criteria for an official release. release_task: diff --git a/.github/workflows/upload-win-installer.yml b/.github/workflows/upload-win-installer.yml new file mode 100644 index 000000000..125100a28 --- /dev/null +++ b/.github/workflows/upload-win-installer.yml @@ -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 @@ -690,6 +690,9 @@ podman-remote-release-%.zip: test/version/version ## Build podman-remote for %=$ else \ $(MAKE) $(GOPLAT) podman-remote; \ fi + if [[ "$(GOOS)" == "windows" ]]; then \ + $(MAKE) $(GOPLAT) TMPDIR="" win-sshproxy; \ + fi cp -r ./docs/build/remote/$(GOOS) "$(TMPDIR)/$(SUBDIR)/docs/" cp ./contrib/remote/containers.conf "$(TMPDIR)/$(SUBDIR)/" $(MAKE) $(GOPLAT) $(_DSTARGS) SELINUXOPT="" install.remote @@ -752,6 +755,8 @@ install.remote: install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(BINDIR) install ${SELINUXOPT} -m 755 $(SRCBINDIR)/podman$(BINSFX) \ $(DESTDIR)$(BINDIR)/podman$(BINSFX) + test "${GOOS}" != "windows" || \ + install -m 755 $(SRCBINDIR)/win-sshproxy.exe $(DESTDIR)$(BINDIR) test -z "${SELINUXOPT}" || \ chcon --verbose --reference=$(DESTDIR)$(BINDIR)/podman-remote \ bin/podman-remote diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md index 66cc74693..17590be97 100644 --- a/RELEASE_PROCESS.md +++ b/RELEASE_PROCESS.md @@ -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 diff --git a/cmd/podman-msihooks/main.go b/cmd/podman-msihooks/main.go new file mode 100644 index 000000000..903c91abb --- /dev/null +++ b/cmd/podman-msihooks/main.go @@ -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() {} diff --git a/cmd/podman-wslkerninst/event-hook.go b/cmd/podman-wslkerninst/event-hook.go new file mode 100644 index 000000000..a5c23e4cf --- /dev/null +++ b/cmd/podman-wslkerninst/event-hook.go @@ -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 +} diff --git a/cmd/podman-wslkerninst/main.go b/cmd/podman-wslkerninst/main.go new file mode 100644 index 000000000..0485db13c --- /dev/null +++ b/cmd/podman-wslkerninst/main.go @@ -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") +} diff --git a/contrib/cirrus/win-installer-install.ps1 b/contrib/cirrus/win-installer-install.ps1 new file mode 100644 index 000000000..f3fc4508d --- /dev/null +++ b/contrib/cirrus/win-installer-install.ps1 @@ -0,0 +1,6 @@ +# Update service is required for dotnet 3.5 (dep of wix) +Set-Service -Name wuauserv -StartupType "Manual" +choco install -y wixtoolset mingw golang archiver +if ($LASTEXITCODE -ne 0) { + Exit 1 +} diff --git a/contrib/cirrus/win-installer-main.ps1 b/contrib/cirrus/win-installer-main.ps1 new file mode 100644 index 000000000..64a94ee63 --- /dev/null +++ b/contrib/cirrus/win-installer-main.ps1 @@ -0,0 +1,60 @@ + # Powershell doesn't exit after + function CheckExit { + if ($LASTEXITCODE -ne 0) { + Exit $LASTEXITCODE + } +} +function DownloadFile { + param( + [Parameter(Mandatory)] + [string]$url, + [Parameter(Mandatory)] + [string]$file, + [Int]$retries=5, + [Int]$delay=8 + ) + $ProgressPreference = 'SilentlyContinue'; + Write-Host "Downloading $url to $file" + For($i = 0;;) { + Try { + Invoke-WebRequest -UseBasicParsing -ErrorAction Stop -Uri $url -OutFile $file + Break + } Catch { + if (++$i -gt $retries) { + throw $_.Exception + } + Write-Host "Download failed - retrying:" $_.Exception.Response.StatusCode + Start-Sleep -Seconds $delay + } + } +} +# Drop global envs which have unix paths, defaults are fine +Remove-Item Env:\GOPATH +Remove-Item Env:\GOSRC +Remove-Item Env:\GOCACHE + +Set-Location contrib\win-installer + +# Download and extract alt_build win release zip +$url = "${ENV:ART_URL}/Windows Cross/repo/repo.tbz" +# Arc requires extension to be "tbz2" +DownloadFile "$url" "repo.tbz2" +arc unarchive repo.tbz2 .; CheckExit + +# Build Installer +.\build.ps1 $Env:WIN_INST_VER dev repo; CheckExit + +# Run the installer silently and WSL install option disabled (prevent reboots, wsl requirements) +# We need AllowOldWin=1 for server 2019 (cirrus image), can be dropped after server 2022 +$ret = Start-Process -Wait -PassThru ".\podman-${ENV:WIN_INST_VER}-dev-setup.exe" -ArgumentList "/install /quiet WSLCheckbox=0 AllowOldWin=1 /log inst.log" +if ($ret.ExitCode -ne 0) { + Write-Host "Install failed, dumping log" + Get-Content inst.log + Exit $ret.ExitCode +} +if (! ((Test-Path -Path "C:\Program Files\RedHat\Podman\podman.exe") -and ` + (Test-Path -Path "C:\Program Files\RedHat\Podman\win-sshproxy.exe"))) { + Write-Host "Expected podman.exe and win-sshproxy.exe, one or both not present after install" + Exit 1 +} +Write-Host "Installer verification successful!" diff --git a/contrib/win-installer/README.md b/contrib/win-installer/README.md new file mode 100644 index 000000000..9cd1d29a5 --- /dev/null +++ b/contrib/win-installer/README.md @@ -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 +``` diff --git a/contrib/win-installer/build-burn.bat b/contrib/win-installer/build-burn.bat new file mode 100644 index 000000000..637a4e744 --- /dev/null +++ b/contrib/win-installer/build-burn.bat @@ -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 diff --git a/contrib/win-installer/build-hooks.bat b/contrib/win-installer/build-hooks.bat new file mode 100644 index 000000000..d663f87b8 --- /dev/null +++ b/contrib/win-installer/build-hooks.bat @@ -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 diff --git a/contrib/win-installer/build-msi.bat b/contrib/win-installer/build-msi.bat new file mode 100644 index 000000000..28a77734d --- /dev/null +++ b/contrib/win-installer/build-msi.bat @@ -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 diff --git a/contrib/win-installer/build.ps1 b/contrib/win-installer/build.ps1 new file mode 100644 index 000000000..ba1b97548 --- /dev/null +++ b/contrib/win-installer/build.ps1 @@ -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" diff --git a/contrib/win-installer/burn.wxs b/contrib/win-installer/burn.wxs new file mode 100644 index 000000000..f4534e5fd --- /dev/null +++ b/contrib/win-installer/burn.wxs @@ -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=""[InstallFolder]\podman-for-windows.html""/> + + <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> diff --git a/contrib/win-installer/check.ps1 b/contrib/win-installer/check.ps1 new file mode 100644 index 000000000..6e3aa9c2e --- /dev/null +++ b/contrib/win-installer/check.ps1 @@ -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" diff --git a/contrib/win-installer/podman-theme.wxl b/contrib/win-installer/podman-theme.wxl new file mode 100644 index 000000000..7fea09054 --- /dev/null +++ b/contrib/win-installer/podman-theme.wxl @@ -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">&Close</String> + <String Id="InstallLicenseLinkText">[WixBundleName] <a href="#">license terms</a>.</String> + <String Id="InstallAcceptCheckbox">I &agree to the license terms and conditions</String> + <String Id="InstallOptionsButton">&Options</String> + <String Id="InstallInstallButton">&Install</String> + <String Id="InstallCloseButton">&Close</String> + <String Id="OptionsHeader">Setup Options</String> + <String Id="OptionsLocationLabel">Install location:</String> + <String Id="OptionsBrowseButton">&Browse</String> + <String Id="OptionsOkButton">&OK</String> + <String Id="OptionsCancelButton">&Cancel</String> + <String Id="ProgressHeader">Setup Progress</String> + <String Id="ProgressLabel">Processing:</String> + <String Id="OverallProgressPackageText">Initializing...</String> + <String Id="ProgressCancelButton">&Cancel</String> + <String Id="ModifyHeader">Modify Setup</String> + <String Id="ModifyRepairButton">&Repair</String> + <String Id="ModifyUninstallButton">&Uninstall</String> + <String Id="ModifyCloseButton">&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">&Open Guide && Close</String> + <String Id="SuccessRestartText">You must restart your computer before you can use the software.</String> + <String Id="SuccessRestartButton">&Restart</String> + <String Id="SuccessCloseButton">&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 <a href="#">log file</a>.</String> + <String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String> + <String Id="FailureRestartButton">&Restart</String> + <String Id="FailureCloseButton">&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 &applications and attempt to restart them.</String> + <String Id="FilesInUseDontCloseRadioButton">&Do not close applications. A reboot will be required.</String> + <String Id="FilesInUseOkButton">&OK</String> + <String Id="FilesInUseCancelButton">&Cancel</String> + <String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String> +</WixLocalization> diff --git a/contrib/win-installer/podman-theme.xml b/contrib/win-installer/podman-theme.xml new file mode 100644 index 000000000..8d7be5d72 --- /dev/null +++ b/contrib/win-installer/podman-theme.xml @@ -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> diff --git a/contrib/win-installer/podman-ui.wxs b/contrib/win-installer/podman-ui.wxs new file mode 100644 index 000000000..127045950 --- /dev/null +++ b/contrib/win-installer/podman-ui.wxs @@ -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> diff --git a/contrib/win-installer/podman.wxs b/contrib/win-installer/podman.wxs new file mode 100644 index 000000000..b61bb2802 --- /dev/null +++ b/contrib/win-installer/podman.wxs @@ -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> diff --git a/contrib/win-installer/process-release.ps1 b/contrib/win-installer/process-release.ps1 new file mode 100644 index 000000000..ba7b47f4b --- /dev/null +++ b/contrib/win-installer/process-release.ps1 @@ -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 diff --git a/contrib/win-installer/resources/podman-banner.png b/contrib/win-installer/resources/podman-banner.png Binary files differnew file mode 100644 index 000000000..e5070db98 --- /dev/null +++ b/contrib/win-installer/resources/podman-banner.png diff --git a/contrib/win-installer/resources/podman-banner2.png b/contrib/win-installer/resources/podman-banner2.png Binary files differnew file mode 100644 index 000000000..88ee1bfad --- /dev/null +++ b/contrib/win-installer/resources/podman-banner2.png diff --git a/contrib/win-installer/resources/podman-dialog.png b/contrib/win-installer/resources/podman-dialog.png Binary files differnew file mode 100644 index 000000000..cf0c49d98 --- /dev/null +++ b/contrib/win-installer/resources/podman-dialog.png diff --git a/contrib/win-installer/resources/podman-logo.ico b/contrib/win-installer/resources/podman-logo.ico Binary files differnew file mode 100644 index 000000000..cb1dab6a7 --- /dev/null +++ b/contrib/win-installer/resources/podman-logo.ico diff --git a/contrib/win-installer/resources/podman-logo.png b/contrib/win-installer/resources/podman-logo.png Binary files differnew file mode 100644 index 000000000..5df6453a8 --- /dev/null +++ b/contrib/win-installer/resources/podman-logo.png diff --git a/contrib/win-installer/resources/podman-sidebar.png b/contrib/win-installer/resources/podman-sidebar.png Binary files differnew file mode 100644 index 000000000..cc0249706 --- /dev/null +++ b/contrib/win-installer/resources/podman-sidebar.png diff --git a/contrib/win-installer/welcome-install-dlg.wxs b/contrib/win-installer/welcome-install-dlg.wxs new file mode 100644 index 000000000..cc0f1c643 --- /dev/null +++ b/contrib/win-installer/welcome-install-dlg.wxs @@ -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> diff --git a/docs/source/markdown/options/userns.pod.md b/docs/source/markdown/options/userns.pod.md new file mode 100644 index 000000000..389f47bd5 --- /dev/null +++ b/docs/source/markdown/options/userns.pod.md @@ -0,0 +1,28 @@ +#### **--userns**=*mode* + +Set the user namespace mode for all the containers in a pod. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled. + +Rootless user --userns=Key mappings: + +Key | Host User | Container User +----------|---------------|--------------------- +"" |$UID |0 (Default User account mapped to root user in container.) +keep-id |$UID |$UID (Map user account to same UID within container.) +auto |$UID | nil (Host User UID is not mapped into container.) +nomap |$UID | nil (Host User UID is not mapped into container.) + +Valid _mode_ values are: + + - *auto[:*_OPTIONS,..._*]*: automatically create a namespace. It is possible to specify these options to `auto`: + + - *gidmapping=*_CONTAINER_GID:HOST_GID:SIZE_ to force a GID mapping to be present in the user namespace. + + - *size=*_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace. + + - *uidmapping=*_CONTAINER_UID:HOST_UID:SIZE_ to force a UID mapping to be present in the user namespace. + + - *host*: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default). + + - *keep-id*: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is not allowed for containers created by the root user. + + - *nomap*: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is not allowed for containers created by the root user. diff --git a/docs/source/markdown/podman-pod-clone.1.md.in b/docs/source/markdown/podman-pod-clone.1.md.in index 193f4eae2..011efc5b7 100644 --- a/docs/source/markdown/podman-pod-clone.1.md.in +++ b/docs/source/markdown/podman-pod-clone.1.md.in @@ -118,34 +118,7 @@ clone process has completed. All containers within the pod are started. @@option uidmap.pod -#### **--userns**=*mode* - -Set the user namespace mode for all the containers in a pod. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled. - -Rootless user --userns=Key mappings: - -Key | Host User | Container User -----------|---------------|--------------------- -"" |$UID |0 (Default User account mapped to root user in container.) -keep-id |$UID |$UID (Map user account to same UID within container.) -auto |$UID | nil (Host User UID is not mapped into container.) -nomap |$UID | nil (Host User UID is not mapped into container.) - -Valid _mode_ values are: - - - *auto[:*_OPTIONS,..._*]*: automatically create a namespace. It is possible to specify these options to `auto`: - - - *gidmapping=*_CONTAINER_GID:HOST_GID:SIZE_ to force a GID mapping to be present in the user namespace. - - - *size=*_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace. - - - *uidmapping=*_CONTAINER_UID:HOST_UID:SIZE_ to force a UID mapping to be present in the user namespace. - - - *host*: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default). - - - *keep-id*: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user. - - - *nomap*: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is ignored for containers created by the root user. +@@option userns.pod @@option uts.pod diff --git a/docs/source/markdown/podman-pod-create.1.md.in b/docs/source/markdown/podman-pod-create.1.md.in index 7dc5fd052..24edbb918 100644 --- a/docs/source/markdown/podman-pod-create.1.md.in +++ b/docs/source/markdown/podman-pod-create.1.md.in @@ -259,34 +259,7 @@ When size is `0`, there is no limit on the amount of memory used for IPC by the @@option uidmap.pod -#### **--userns**=*mode* - -Set the user namespace mode for all the containers in a pod. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled. - -Rootless user --userns=Key mappings: - -Key | Host User | Container User -----------|---------------|--------------------- -"" |$UID |0 (Default User account mapped to root user in container.) -keep-id |$UID |$UID (Map user account to same UID within container.) -auto |$UID | nil (Host User UID is not mapped into container.) -nomap |$UID | nil (Host User UID is not mapped into container.) - -Valid _mode_ values are: - - - *auto[:*_OPTIONS,..._*]*: automatically create a namespace. It is possible to specify these options to `auto`: - - - *gidmapping=*_CONTAINER_GID:HOST_GID:SIZE_ to force a GID mapping to be present in the user namespace. - - - *size=*_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace. - - - *uidmapping=*_CONTAINER_UID:HOST_UID:SIZE_ to force a UID mapping to be present in the user namespace. - - - *host*: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default). - - - *keep-id*: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is not allowed for containers created by the root user. - - - *nomap*: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is not allowed for containers created by the root user. +@@option userns.pod @@option uts.pod diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index 8b6d74817..7e453823f 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -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) { diff --git a/pkg/machine/wsl/util_windows.go b/pkg/machine/wsl/util_windows.go index 6c74e5652..6613bde1f 100644 --- a/pkg/machine/wsl/util_windows.go +++ b/pkg/machine/wsl/util_windows.go @@ -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 +} diff --git a/test/e2e/run_staticip_test.go b/test/e2e/run_staticip_test.go index 8207f6d0b..12783cd29 100644 --- a/test/e2e/run_staticip_test.go +++ b/test/e2e/run_staticip_test.go @@ -105,6 +105,13 @@ var _ = Describe("Podman run with --ip flag", func() { result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) + // We need to set "no_proxy" in proxy environment + if env, found := os.LookupEnv("no_proxy"); found { + defer os.Setenv("no_proxy", env) + } else { + defer os.Unsetenv("no_proxy") + } + os.Setenv("no_proxy", ip) for retries := 20; retries > 0; retries-- { response, err := http.Get(fmt.Sprintf("http://%s", ip)) if err == nil && response.StatusCode == http.StatusOK { diff --git a/vendor/golang.org/x/sys/windows/svc/eventlog/install.go b/vendor/golang.org/x/sys/windows/svc/eventlog/install.go new file mode 100644 index 000000000..43e324f4b --- /dev/null +++ b/vendor/golang.org/x/sys/windows/svc/eventlog/install.go @@ -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) +} diff --git a/vendor/golang.org/x/sys/windows/svc/eventlog/log.go b/vendor/golang.org/x/sys/windows/svc/eventlog/log.go new file mode 100644 index 000000000..f37b4b510 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/svc/eventlog/log.go @@ -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) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index cc3d7b6a7..f1d4758e4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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 |