Add new targets on Windows makefile (winmake.ps1)

Add the following targets in winmake.ps1:
- `installer`: builds the Windows installer
- `docs`: builds the documentation HTML pages
- `validatepr`: runs the Linux Makefile `.valiatepr`
                target using podman.
- `lint`: faster validation that runs linter locally

Update of `build_windows.md`:
- removed every reference to the MSYS2 platform
- added instructions to build the installer and linters

Fix https://github.com/containers/podman/issues/21821 and https://github.com/containers/podman/issues/21911

Signed-off-by: Mario Loriedo <mario.loriedo@gmail.com>
This commit is contained in:
Mario Loriedo
2024-05-08 11:59:55 +02:00
parent 5bfea70e87
commit dcec81e694
5 changed files with 704 additions and 221 deletions

View File

@ -4,13 +4,15 @@ repos:
- repo: https://github.com/pre-commit/pre-commit-hooks.git
rev: v3.4.0
hooks:
# buildah-tests.diff is generated by 'git format-patch' and includes
# `buildah-tests.diff` is generated by 'git format-patch' and includes
# trailing whitespace as part of its format. We can work around that,
# but unfortunately the buildah repo has some files with tabs, which
# git-diff formats as '[+/-]<space><tab>', which these hooks choke on.
# Just disable checks on this diff file as a special case.
# `contrib/systemd/user` is a symlink but for some reason, on windows,
# pre-commit consider it as a regular file and tries to fix it.
# Just disable checks on these files as a special case.
- id: end-of-file-fixer
exclude: test/buildah-bud/buildah-tests.diff
exclude: test/buildah-bud/buildah-tests.diff|contrib/systemd/user
- id: trailing-whitespace
exclude: test/buildah-bud/buildah-tests.diff|test/e2e/quadlet/remap-keep-id2.container|test/e2e/quadlet/line-continuation-whitespace.container
- id: mixed-line-ending

View File

@ -1,115 +1,219 @@
# Building the Podman client and client installer on Windows
The following describes the process for building the Podman client on Windows.
The following describes the process for building and testing the Podman Windows
client (`podman.exe`) and the Podman Windows installer (`podman-setup.exe`) on
Windows.
## OS requirements
## Topics
Windows OS can behave very differently depending on how it was configured. This documentation assumes that one is using
a [Windows 11 development machine](https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/) or a
configuration close to this one. The Podman Windows client installer bundles several tools, which are unnecessary for Podman builds, but this
set of packages is well aligned with GitHub's `windows-latest` offerings. Some of the tools will still be missing from
this distribution and will have to be manually added after this installation completes.
- [Requirements](#requirements)
- [OS requirements](#os-requirements)
- [Git and go](#git-and-go)
- [Pandoc](#pandoc)
- [WiX Toolset v3](#wix-toolset-v3)
- [Virtualization Provider](#virtualization-provider)
- [WSL](#wsl)
- [Hyper-V](#hyper-v)
- [Get the source code](#get-the-source-code)
- [Allow local PowerShell scripts execution](#allow-local-powershell-scripts-execution)
- [Build and test the Podman client for Windows](#build-and-test-the-podman-client-for-windows)
- [Build the Podman client](#build-the-podman-client)
- [Download gvproxy.exe and win-sshproxy.exe](#download-gvproxyexe-and-win-sshproxyexe)
- [Create a configuration file (optional)](#create-a-configuration-file-optional)
- [Create and start a podman machine](#create-and-start-a-podman-machine)
- [Run a container using podman](#run-a-container-using-podman)
- [Build and test the Podman Windows installer](#build-and-test-the-podman-windows-installer)
- [Build the installer](#build-the-installer)
- [Test the installer](#test-the-installer)
- [Build and test the standalone `podman.msi` file](#build-and-test-the-standalone-podmanmsi-file)
- [Verify the installation](#verify-the-installation)
- [Uninstall and clean-up](#uninstall-and-clean-up)
- [Validate changes before submitting a PR](#validate-changes-before-submitting-a-pr)
- [winmake lint](#winmake-lint)
- [winmake validatepr](#winmake-validatepr)
## Install Pandoc
## Requirements
Pandoc could be installed from https://pandoc.org/installing.html When performing the Pandoc installation one, has to choose the option
"Install for all users" (to put the binaries into "Program Files" directory).
### OS requirements
## Install WiX Toolset v3 (is preinstalled in GitHub runner)
The latest release of the WiX Toolset can be obtained from https://wixtoolset.org/docs/wix3/. Installing it into a clean VM might require
an additional installation of .NET Framework 3.5 in advance
([instructions for adding .NET Framework 3.5 via enabling the Windows feature](https://learn.microsoft.com/en-us/dotnet/framework/install/dotnet-35-windows#enable-the-net-framework-35-in-control-panel))
This documentation assumes one uses a Windows 10 or 11 development machine and a
PowerShell terminal.
## Building and running
### Git and go
### Install git and go
To build Podman, the [git](https://gitforwindows.org/) and [go](https://go.dev)
tools are required. In case they are not yet installed, open a Windows
PowerShell terminal and run the following command (it assumes that
[winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/) is
installed):
To build Podman, the [git](https://gitforwindows.org/) and [go](https://go.dev) tools are required. In case they are not yet installed,
open a Windows Terminal and run the following command (it assumes that [winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/) is installed):
```
```pwsh
winget install -e GoLang.Go Git.Git
```
:information_source: A terminal restart is advised for the `PATH` to be reloaded. This can also be manually changed by configuring the `PATH`:
:information_source: A terminal restart is advised for the `PATH` to be
reloaded. This can also be manually changed by configuring the `PATH`:
```
```pwsh
$env:Path += ";C:\Program Files\Go\bin\;C:\Program Files\Git\cmd\"
```
### Enable Hyper-V (optional)
### Pandoc
Podman on Windows can run on the [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/) or
on [Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v).
[Pandoc](https://pandoc.org/) is used to generate Podman documentation. It is
required for building the documentation and the
[bundle installer](#build-the-installer). It can be avoided when building and
testing the
[Podman client for Windows](#build-and-test-the-podman-client-for-windows) or
[the standalone `podman.msi` installer](#build-and-test-the-standalone-podmanmsi-file).
Pandoc can be installed from https://pandoc.org/installing.html. When performing
the Pandoc installation one, has to choose the option "Install for all users"
(to put the binaries into "Program Files" directory).
Hyper-V is built into Windows Enterprise, Pro, or Education (not Home) as an optional feature. It is available on Windows 10 and 11 only
and [has some particular requirements in terms of CPU and memory](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v#check-requirements).
### WiX Toolset v3
[WiX Toolset](https://wixtoolset.org) **v3** is used to develop and build the
Podman Windows installer. It's not required for the Podman Windows client.
Version 3 of the WiX Toolset can be obtained from
https://wixtoolset.org/docs/wix3/. Installing it into a clean VM might require
an additional installation of .NET Framework 3.5 in advance
([instructions for adding .NET Framework 3.5 via enabling the Windows feature](https://learn.microsoft.com/en-us/dotnet/framework/install/dotnet-35-windows#enable-the-net-framework-35-in-control-panel))
### Virtualization Provider
Running Podman on Windows requires a virtualization provider. The supported
providers are the
[Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/)
and
[Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v).
At least one of those two is required to test podman on a local Windows machine.
#### WSL
WSL can be installed on Windows 10 and Windows 11, including Windows Home, with
the following command, from a PowerShell or Windows Command Prompt terminal in
**administrator mode**:
```pwsh
wsl --install
```
For more information refer to
[the official documentation](https://learn.microsoft.com/en-us/windows/wsl/).
#### Hyper-V
Hyper-V is an optional feature of Windows Enterprise, Pro, or Education (not
Home). It is available on Windows 10 and 11 only and
[has some particular requirements in terms of CPU and memory](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v#check-requirements).
To enable it on a supported system, enter the following command:
```
```pwsh
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
```
After running this command a restart of the Windows machine is required.
After running this command, a restart of the Windows machine is required.
:information_source: The VM provider used by podman (Hyper-V or WSL) can be configured in the file
`%APPDATA%/containers/containers.conf`. [More on that later](#configure-podman).
:information_source: Configure the VM provider used by podman (Hyper-V or WSL)
in the file `%PROGRAMDATA%/containers/containers.conf`.
[More on that later](#create-a-configuration-file-optional).
### Get the source code
## Get the source code
Open a Windows Terminal and run the following command:
```
```pwsh
git config --global core.autocrlf false
```
This configures git so that it does **not** automatically convert LF to CRLF. Files are expected to use the Unix LF rather
Windows CRLF in the Podman git repository.
It configures git so that it does **not** automatically convert LF to CRLF. In
the Podman git repository, files are expected to use Unix LF rather than Windows
CRLF.
Then run the command to clone the Podman git repository:
```
```pwsh
git clone https://github.com/containers/podman
```
This will create the folder `podman` in the current directory and clone the Podman git repository into it.
It creates the folder `podman` in the current directory and clones the Podman
git repository into it.
### Build the podman client for windows
### Allow local PowerShell scripts execution
The Podman client for Windows can be built with the PowerShell script [winmake.ps1](https://github.com/containers/podman/blob/main/winmake.ps1).
A developer can build the Podman client for Windows and the Windows installer
with the PowerShell script
[winmake.ps1](https://github.com/containers/podman/blob/main/winmake.ps1).
The ExecutionPolicy is set to `Restricted` on Windows computers by default: running scripts is not allowed.
The ExecutionPolicy on the machine can be determined with this command:
Windows sets the ExecutionPolicy to `Restricted` by default; running scripts is
prohibited. Determine the ExecutionPolicy on the machine with this command:
```
```pwsh
Get-ExecutionPolicy
```
If the command returns `Restricted`, the ExecutionPolicy should be changed to `RemoteSigned`:
If the command returns `Restricted`, the ExecutionPolicy should be changed to
`RemoteSigned`:
```
```pwsh
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
This policy allows the execution of local PowerShell scripts, such as `winmake.ps1`, for the current user:
This policy allows the execution of local PowerShell scripts, such as
`winmake.ps1`, for the current user.
## Build and test the Podman client for Windows
The following steps describe how to build the `podman.exe` binary from sources
and test it.
### Build the Podman client
Open a PowerShell terminal and move to Podman local git repository directory:
```pwsh
Set-Location .\podman
```
Build `podman.exe`
```
# Get in the podman git repository directory
cd podman
# Build podman.exe
.\winmake.ps1 podman-remote
```
# Download gvproxy.exe and win-sshproxy.exe
# that are needed to execute the podman client
:information_source: Verify build's success by checking the content of the
`.\bin\windows` folder. Upon successful completion, the executable `podman.exe`
should be there:
```pwsh
Get-ChildItem .\bin\windows\
Directory: C:\Users\mario\Git\podman\bin\windows
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2/27/2024 11:59 AM 45408256 podman.exe
```
### Download gvproxy.exe and win-sshproxy.exe
[gvisor-tap-vsock](https://github.com/containers/gvisor-tap-vsock/) binaries
(`gvproxy-windowsgui.exe` and `win-sshproxy.exe`) are required to run the Podman
client on Windows. The executables are expected to be in the same folder as
`podman.exe`. The following command downloads the latest version in the
`.\bin\windows\` folder:
```pwsh
.\winmake.ps1 win-gvproxy
```
:information_source: To verify that the build was completed successfully, check the content of the .\bin\windows` folder.
Upon successful completion three executables should be shown:
:information_source: To verify that the binaries have been downloaded
successfully, check the content of the .\bin\windows` folder.
```
ls .\bin\windows\
```pwsh
Get-ChildItem .\bin\windows\
Directory: C:\Users\mario\Git\podman\bin\windows
@ -122,161 +226,249 @@ Mode LastWriteTime Length Name
-a---- 2/29/2024 12:10 PM 4089856 win-sshproxy.exe
```
### Configure podman
### Create a configuration file (optional)
Create a containers.conf file:
To test some particular configurations of Podman, create a `containers.conf`
file:
```
mkdir $env:APPDATA\containers\
New-Item -ItemType File $env:APPDATA\containers\containers.conf
notepad $env:APPDATA\containers\containers.conf
New-Item -ItemType Directory $env:PROGRAMDATA\containers\
New-Item -ItemType File $env:PROGRAMDATA\containers\containers.conf
notepad $env:PROGRAMDATA\containers\containers.conf
```
and add the following lines in it:
For example, to test with Hyper-V as the virtualization provider, use the
following content:
```toml
[machine]
# Specify the provider
# Values can be "hyperv" or "wsl"
provider="hyperv"
[engine]
# Specify the path of the helper binaries.
# NOTE: path should use slashes instead of anti-slashes
helper_binaries_dir=["C:/Users/mario/git/podman/bin/windows"]
```
Create a policy.json file:
```
New-Item -ItemType File $env:APPDATA\containers\policy.json
notepad $env:APPDATA\containers\policy.json
````
and add the following lines in it:
```json
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports": {
"docker-daemon": {
"": [{ "type": "insecureAcceptAnything" }]
}
}
}
```
Find the complete list of configuration options in the
[documentation](https://github.com/containers/common/blob/main/docs/containers.conf.5.md).
### Create and start a podman machine
Run a terminal **as an administrator** and execute the following commands to create a Podman machine:
Execute the following commands in a terminal to create a Podman machine:
```
```pwsh
.\bin\windows\podman.exe machine init
```
When `machine init` completes run `machine start`:
When `machine init` completes, run `machine start`:
```
```pwsh
.\bin\windows\podman.exe machine start
```
:information_source: If the virtualization provider is Hyperv-V, execute the
above commands in an administrator terminal.
### Run a container using podman
The locally built Podman client for Windows can now be used to run containers:
Use the locally built Podman client for Windows to run containers:
```
```pwsh
.\bin\windows\podman.exe run hello-world
```
:information_source: Unlike the previous machine commands, this one doesn't require administrative privileges.
## Building the Podman client and installer with MSYS2
### Install msys2
Podman requires brew -- a collection of Unix like build tools and libraries adapted for Windows. More details and
installation instructions are available from their [home page](https://www.msys2.org/). There are also premade GitHub
actions for this tool that are available.
### Install build dependencies
Podman requires some software from msys2 to be able to build. This can be done using msys2 shell. One can start it
from the Start menu. This documentation covers only usage of MSYS2 UCRT64 shell (msys2 shells come preconfigured for
different [environments](https://www.msys2.org/docs/environments/)).
```
$ pacman -S git make zip mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-go mingw-w64-ucrt-x86_64-python
```
The Pandoc tool installed in a prior step is specific, that is the installer doesn't add the tool to any PATH environment
variable known to msys2, so, it has to be linked explicitly to work.
```
$ mkdir -p /usr/local/bin
$ ln -sf "/c/Program Files/Pandoc/pandoc.exe" "/usr/local/bin/pandoc.exe"
```
### Restart shell (important)
One needs to restart the [msys2](https://www.msys2.org/) shell after dependency installation before proceeding with the build.
### Obtain Podman source code
One can obtain the latest source code for Podman from its [GitHub](https://github.com/containers/podman) repository.
```
$ git clone https://github.com/containers/podman.git go/src/github.com/containers/podman
```
### Build client
After completing the preparatory steps of obtaining the Podman source code and installing its dependencies, the client
can now be built.
```
$ cd go/src/github.com/containers/podman
$ make clean podman-remote-release-windows_amd64.zip
```
The complete distribution will be packaged to the `podman-remote-release-windows_amd64.zip` file. It is possible to
unzip it and replace files in the default Podman installation with the built ones to use the custom build.
#### Build client only (for faster feedback loop)
Building Podman by following this documentation can take a fair amount of time and effort. Packaging the installer adds even more overhead. If
the only needed artifact is the Podman binary itself, it is possible to build only it with this command:
```
$ make podman-remote
```
The binary will be located in `bin/windows/`. It could be used as drop in replacement for the installed version of
Podman.
It is also possible to cross-build for other platforms by providing GOOS and GOARCH environment variables.
### Build client installer
As Windows requires more effort in comparison to Unix systems for installation procedures, it is sometimes
easier to pack the changes into a ready-to-use installer. To create the installer, the full client distribution in ZIP
format has to be built beforehand.
```
$ export BUILD_PODMAN_VERSION=$(test/version/version | sed 's/-.*//')
$ mkdir -p contrib/win-installer/current
$ cp podman-remote-release-windows_amd64.zip contrib/win-installer/current/
$ cd contrib/win-installer
$ powershell -ExecutionPolicy Bypass -File build.ps1 $BUILD_PODMAN_VERSION dev current
```
The installer will be located in the `contrib/win-installer` folder (relative to checkout root) and will have a name
like `podman-4.5.0-dev-setup.exe`. This could be installed in a similar manner as the official Podman for Windows installers
(when installing unsigned binaries is allowed on the host).
## Using the client
To learn how to use the Podman client, refer to its
[tutorial](https://github.com/containers/podman/blob/main/docs/tutorials/remote_client.md).
## Build and test the Podman Windows installer
The Podman Windows installer (e.g., `podman-5.1.0-dev-setup.exe`) is a bundle
that includes an msi package (`podman.msi`) and installs the WSL kernel
(`podman-wslkerninst.exe`). It's built using the
[WiX Toolset](https://wixtoolset.org/) and the
[PanelSwWixExtension](https://github.com/nirbar/PanelSwWixExtension/tree/wix3-v3.11.1.353)
WiX extension. The source code is in the folder `contrib\win-installer`.
### Build the Windows installer
To build the installation bundle, run the following command:
```pwsh
.\winmake.ps1 installer
```
:information_source: making `podman-remote`, `win-gvproxy`, and `docs` is
required before running this command.
Locate the installer in the `contrib\win-installer` folder (relative to checkout
root) with a name like `podman-5.2.0-dev-setup.exe`.
The `installer` target of `winmake.ps1` runs the script
`contrib\win-installer\build.ps1` that, in turns, executes:
- `build-hooks.bat`: builds `podman-wslkerninst.exe` (WSL kernel installer) and
`podman-msihooks.dll` (helper that checks if WSL and Hyper-V are installed).
- `build-msi.bat`: builds `podman.msi` from the WiX source files `podman.wxs`,
`pages.wxs`, `podman-ui.wxs` and `welcome-install-dlg.wxs`.
- `build-burn.bat`: builds `podman-setup.exe` file from
[WiX Burn bundle](https://wixtoolset.org/docs/tools/burn/) `burn.wxs`.
### Test the Windows installer
Double-click on the Windows installer to run it. To get the installation logs
with debug information, running it via the command line is recommended:
```pwsh
contrib\win-installer\podman-5.1.0-dev-setup.exe /install /log podman-setup.log
```
It generates the files `podman-setup.log` and `podman-setup_000_Setup.log`,
which include detailed installation information, in the current directory.
Run it in `quiet` mode to automate the installation and avoid interacting with
the GUI. Open the terminal **as an administrator**, add the `/quiet` option, and
set the bundle variables `MachineProvider` (`wsl` or `hyperv`), `WSLCheckbox`
(`1` to install WSL as part of the installation, `0` otherwise), and
`HyperVCheckbox` (`1` to install Hyper-V as part of the installation, `0`
otherwise):
```pwsh
contrib\win-installer\podman-5.1.0-dev-setup.exe /install /log podman-setup.log /quiet MachineProvider=wsl WSLCheckbox=0 HyperVCheckbox=0
```
### Build and test the standalone `podman.msi` file
Building and testing the standalone `podman.msi` package during development may
be useful. Even if this package is not published as a standalone file when
Podman is released (it's included in the `podman-setup.exe` bundle), it can be
faster to build and test that rather than the full bundle during the development
phase.
Run the script `contrib\win-installer\build-msi.bat` to build the standalone
`podman.msi` file:
```pwsh
Push-Location .\contrib\win-installer\
.\build-msi.bat 9.9.9
Pop-Location
```
It creates the file `.\contrib\win-installer\podman.msi`. Test it using the
[Microsoft Standard Installer](https://learn.microsoft.com/en-us/windows/win32/msi/standard-installer-command-line-options)
command line tool:
```pwsh
msiexec /package contrib\win-installer\podman.msi /l*v podman-msi.log
```
To run it in quiet, non-interactive mode, open the terminal **as an
administrator**, add the `/quiet` option, and set the MSI properties
`MACHINE_PROVIDER` (`wsl` or `hyperv`), `WITH_WSL` (`1` to install WSL as part
of the installation, `0` otherwise) and `WITH_HYPERV` (`1` to install Hyper-V as
part of the installation, `0` otherwise):
```pwsh
msiexec /package contrib\win-installer\podman.msi /l*v podman-msi.log /quiet MACHINE_PROVIDER=wsl WITH_WSL=0 WITH_HYPERV=0
```
:information_source: `podman.msi` GUI dialogs, defined in the file
`contrib\win-installer\podman-ui.wxs`, are distinct from the installation bundle
`podman-setup.exe` GUI dialogs, defined in
`contrib\win-installer\welcome-install-dlg.wxs`.
### Verify the installation
Inspect the msi installation log `podman-msi.log` (or
`podman-setup_000_Setup.log` if testing with the bundle) to verify that the
installation was successful:
```pwsh
Select-String -Path "podman-msi.log" -Pattern "Installation success or error status: 0"
```
These commands too are helpful to check the installation:
```pwsh
# Check the copy of the podman client in the Podman folder
Test-Path -Path "$ENV:PROGRAMFILES\RedHat\Podman\podman.exe"
# Check the generation of the podman configuration file
Test-Path -Path "$ENV:PROGRAMDATA\containers\containers.conf.d\99-podman-machine-provider.conf"
# Check that the installer configured the right provider
Get-Content '$ENV:PROGRAMDATA\containers\containers.conf.d\99-podman-machine-provider.conf' | Select -Skip 1 | ConvertFrom-StringData | % { $_.provider }
# Check the creation of the registry key
Test-Path -Path "HKLM:\SOFTWARE\Red Hat\Podman"
Get-ItemProperty "HKLM:\SOFTWARE\Red Hat\Podman" InstallDir
# Check the podman.exe is in the $PATH
$env:PATH | Select-String -Pattern "$ENV:PROGRAMFILES\RedHat\Podman"
```
:information_source: Podman CI uses script
`contrib\cirrus\win-installer-main.ps1`. Use it locally, too, to build and test
the installer.
### Uninstall and clean-up
Podman can be uninstalled from the Windows Control Panel or running the
following command from a terminal **as an administrator**:
```pwsh
contrib\win-installer\podman-5.1.0-dev-setup.exe /uninstall /quiet /log podman-setup-uninstall.log
```
The uninstaller does not delete some folders. Clean them up manually:
```pwsh
$extraFolders = @(
"$ENV:PROGRAMDATA\containers\"
"$ENV:LOCALAPPDATA\containers\"
"$env:USERPROFILE.config\containers\"
"$env:USERPROFILE.local\share\containers\"
)
$extraFolders | ForEach-Object {Remove-Item -Recurse -Force $PSItem}
```
The following commands are helpful to verify that the uninstallation was
successful:
```pwsh
# Inspect the uninstallation log for a success message
Select-String -Path "podman-setup-uninstall_000_Setup.log" -Pattern "Removal success or error status: 0"
# Check that the uninstaller removed Podman resources
$foldersToCheck = @(
"$ENV:PROGRAMFILES\RedHat\Podman\podman.exe"
"HKLM:\SOFTWARE\Red Hat\Podman"
"$ENV:PROGRAMDATA\containers\"
"$env:USERPROFILE.config\containers\"
"$env:USERPROFILE.local\share\containers\"
"$ENV:LOCALAPPDATA\containers\"
"$ENV:APPDATA\containers\containers.conf.d\99-podman-machine-provider.conf"
)
$foldersToCheck | ForEach-Object {Test-Path -Path $PSItem}
```
## Validate changes before submitting a PR
The script `winmake.ps1` has a couple of targets to check the source code
statically. GitHub Pull request checks execute the same statical analysis. It is
highly recommended that you run them locally before submitting a PR.
### winmake lint
The `lint` target provides a fast validation target. It runs the following
tools:
- `golangci-lint`: runs go-specific linters configured in
[`.golangci.yml`](.golangci.yml)
- `pre-commit`: runs more linters configured in
[`.pre-commit-config.yaml`](.pre-commit-config.yaml)
:information_source: Install [golangci-lint](https://golangci-lint.run) and
[pre-commit](https://pre-commit.com) to run `winmake.ps1 lint`.
### winmake validatepr
Target `validatepr` performs a more exhaustive validation but takes
significantly more time to complete. It uses `podman` to run the target
`.validatepr` of the [Linux `Makefile`](Makefile). It builds Podman for Linux,
MacOS and Windows and then performs the same checks as the `lint` target plus
many more.
:information_source: Create and start a Podman machine before running
`winmake.ps1 lint`. Configure the Podman machine with at least 4GB of memory:
`podman machine init -m 4096`.

View File

@ -1,35 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

147
docs/make.ps1 Normal file
View File

@ -0,0 +1,147 @@
function Get-Podman-Commands-List{
param (
[string]$podmanClient,
[string]$command
);
if(!$podmanClient) {
$podmanClient="$PSScriptRoot\..\bin\windows\podman.exe"
}
if($command) {
$podmanHelpCommand="help $command"
Write-Host "Retrieving the list of ""podman $command"" subcommands."
} else {
$podmanHelpCommand="help"
Write-Host "Retrieving the list of ""podman"" commands."
}
# Retrieve the list of subcommands of $command
# e.g. "podman help machine" returns the list of
# "podman machine" subcommands: info, init, etc...
$subCommands = @()
$subCommands = Invoke-Expression "$podmanClient $podmanHelpCommand" |
Select-String -Pattern "^\s*Available Commands:" -Context 0, 1000 | Out-String -Stream |
Select-String -Pattern "^\s+$" -Context 1000, 0 | Out-String -Stream |
Select-String -Pattern ">\s*Available Commands:|^>\s*$|^\s*$" -NotMatch | Out-String -Stream |
ForEach-Object { $_ -replace '^\s*(\w+)\s+.*$', '$1' } | Where-Object { $_ -ne "" }
if ($command) {
$subCommands = $subCommands | ForEach-Object { "$command $_" }
}
# Recursively get the list of sub-subcommands for each subcommand
foreach ($subCommand in $subCommands) {
$subSubCommands = @()
$subSubCommands = Get-Podman-Commands-List -podmanClient "$podmanClient" -command "${subCommand}"
if ($subSubCommands) {
$subCommands += $subSubCommands
}
}
return $subCommands
}
function Build-Podman-For-Windows-HTML-Page{
$srcFolder = "$PSScriptRoot\tutorials"
$srcFile = "$srcFolder\podman-for-windows.md"
$destFolder = "$PSScriptRoot\build\remote"
$destFile = "$destFolder\podman-for-windows.html"
$cssFile = "$PSScriptRoot\standalone-styling.css"
$pandocOptions = "--ascii --from markdown-smart -c $cssFile --standalone " +
"--embed-resources --metadata title=""Podman for Windows"" " +
"-V title="
Write-Host -NoNewline "Generating $destFile from $srcFile..."
Push-Location $srcFolder
New-Item -ItemType Directory -Force -Path $destFolder | Out-Null
Invoke-Expression "pandoc $pandocOptions $srcFile > $destFile"
Pop-Location
Write-Host "done."
}
function Build-Podman-Remote-HTML-Page{
$markdownFolder = "$PSScriptRoot\source\markdown"
# Look for all podman-remote*.md files in the markdown folder
Get-ChildItem -Path "$markdownFolder" -Filter "podman-remote*.md" | ForEach-Object {
# Extract the command name from the file name
$command = $_.Name -replace '^podman-(.*).1.md$','$1'
# Generate the documentation HTML page
Build-Podman-Command-HTML-Page -command $command
}
}
function Find-Podman-Command-Markdown-File{
param (
[string]$command
);
# A podman command documentation can be in one of the following files
$markdownFolder = "$PSScriptRoot\source\markdown"
$srcFileMdIn = "$markdownFolder\podman-$command.1.md.in"
$srcFileMd = "$markdownFolder\podman-$command.1.md"
$linkFile = "$markdownFolder\links\podman-$command.1"
if (Test-Path -Path $srcFileMdIn -PathType Leaf) {
return $srcFileMdIn
} elseif (Test-Path -Path $srcFileMd -PathType Leaf) {
return $srcFileMd
} elseif (Test-Path -Path $linkFile -PathType Leaf) {
# In $linkFile there is a link to a markdown file
$srcFile = Get-Content -Path $linkFile
# $srcFile is something like ".so man1/podman-attach.1"
# and the markdown file is "podman-attach.1.md"
$srcFile = $srcFile -replace ".so man1/", ""
$srcFileMdIn = "$markdownFolder\$srcFile.md.in"
$srcFileMd = "$markdownFolder\$srcFile.md"
if (Test-Path -Path "$srcFileMdIn" -PathType Leaf) {
return "$srcFileMdIn"
} elseif (Test-Path -Path $srcFileMd -PathType Leaf) {
return "$srcFileMd"
}
}
return $null
}
function Build-Podman-Command-HTML-Page{
param (
[string]$command
);
$destFile = "$PSScriptRoot\build\remote\podman-$command.html"
$srcFile = Find-Podman-Command-Markdown-File -command $command
if (!$srcFile) {
Write-Host "Couldn't find the documentation source file for $command. Skipping."
continue
}
$pandocOptions = "--ascii --standalone --from markdown-smart " +
"--lua-filter=$PSScriptRoot\links-to-html.lua " +
"--lua-filter=$PSScriptRoot\use-pagetitle.lua"
Write-Host -NoNewline "Generating $command documentation..."
Invoke-Expression "pandoc $pandocOptions -o $destFile $srcFile" | Out-Null
Write-Host "done."
}
# Generate podman-for-windows.html
Build-Podman-For-Windows-HTML-Page
# Generate podman-remote*.html
Build-Podman-Remote-HTML-Page
# Get the list of podman commands on Windows
if ($args[1]) {
$commands = Get-Podman-Commands-List "-podmanClient $args[1]"
}
else {
$commands = Get-Podman-Commands-List
}
# Generate podman commands documentation
foreach ($command in $commands) {
# Replace spaces with hyphens in the command name
# e.g. machine os apply becomes machine-os-apply
$command = $command -replace ' ', '-'
Build-Podman-Command-HTML-Page -command $command
}

View File

@ -1,4 +1,6 @@
#!/usr/bin/env powershell
. ./contrib/cirrus/win-lib.ps1
# Targets
@ -43,6 +45,114 @@ function Win-SSHProxy {
curl.exe -sSL -o "./bin/windows/win-sshproxy.exe" --retry 5 "https://github.com/containers/gvisor-tap-vsock/releases/download/$Version/win-sshproxy.exe"
}
function Installer{
param (
[string]$version,
[string]$suffix = "dev"
);
Write-Host "Building the windows installer"
# Check for the files to include in the installer
$requiredArtifacts = @(
"$PSScriptRoot\bin\windows\podman.exe"
"$PSScriptRoot\bin\windows\gvproxy.exe"
"$PSScriptRoot\bin\windows\win-sshproxy.exe"
"$PSScriptRoot\docs\build\remote\podman-for-windows.html"
)
$requiredArtifacts | ForEach-Object {
if (!(Test-Path -Path $PSItem -PathType Leaf)) {
Write-Host "$PSItem not found."
Write-Host "Make 'podman', 'win-gvproxy' and 'docs' before making the installer:"
Write-Host " .\winmake.ps1 podman-remote"
Write-Host " .\winmake.ps1 win-gvproxy"
Write-Host " .\winmake.ps1 docs"
Exit 1
}
}
# Create the ZIP file with the full client distribution
$zipFileDest = "$PSScriptRoot\contrib\win-installer\current"
Build-Distribution-Zip-File -destinationPath $zipFileDest
if (-Not $version) {
# Get Podman version from local source code
$version = Get-Podman-Version
}
# Run \contrib\win-installer\build.ps1
Push-Location $PSScriptRoot\contrib\win-installer
Run-Command ".\build.ps1 $version $suffix `"$zipFileDest`""
Pop-Location
}
function Documentation{
Write-Host "Generating the documentation artifacts"
# Check that pandoc is installed
if (!(Get-Command -Name "pandoc" -ErrorAction SilentlyContinue)) {
Write-Host "Pandoc not found. Pandoc is required to convert the documentation Markdown files into HTML files."
Exit 1
}
# Check that the podman client is built
$podmanClient = "$PSScriptRoot\bin\windows\podman.exe"
if (!(Test-Path -Path $podmanClient -PathType Leaf)) {
Write-Host "$podmanClient not found. Make 'podman-remote' before 'documentation'."
Exit 1
}
Run-Command "$PSScriptRoot\docs\make.ps1 $podmanClient"
}
function Validate{
$podmanExecutable = "podman"
$podmanSrcVolumeMount = "${PSScriptRoot}:/go/src/github.com/containers/podman"
# All files bind mounted from a Windows host are marked as executable.
# That makes the pre-commit hook "check-executables-have-shebangs" fail.
# Setting the environment variable "SKIP=check-executables-have-shebangs"
# allow to skip that pre-commit hook.
$podmanEnvVariable = "-e SKIP=check-executables-have-shebangs"
$podmanRunArgs = "--rm -v $podmanSrcVolumeMount --security-opt label=disable -t -w /go/src/github.com/containers/podman $podmanEnvVariable"
$validateImage = "quay.io/libpod/validatepr:latest"
$validateCommand = "make .validatepr"
# Check that podman is installed
if (!(Get-Command -Name $podmanExecutable -ErrorAction SilentlyContinue)) {
Write-Host "$podmanExecutable not found. $podmanExecutable is required to run the validate script."
Exit 1
}
# Check that a podman machine exist
$currentMachine = (podman machine info -f json | ConvertFrom-Json).Host.CurrentMachine
if (!$currentMachine) {
Write-Host "Podman machine doesn't exist. Initialize and start one before running the validate script."
Exit 1
}
# Check that the podman machine is running
$state = (podman machine info -f json | ConvertFrom-Json).Host.MachineState
if ($state -ne "Running") {
Write-Host "Podman machine is not running. Start the machine before running the validate script."
Exit 1
}
Run-Command "$podmanExecutable run $podmanRunArgs $validateImage $validateCommand"
}
function Lint{
# Check that golangci-lint is installed
if (!(Get-Command -Name "golangci-lint" -ErrorAction SilentlyContinue)) {
Write-Host "The tool ""golangci-lint"" not found. Install https://golangci-lint.run/ before running the lint script."
Exit 1
}
# Check that pre-commit is installed
if (!(Get-Command -Name "pre-commit" -ErrorAction SilentlyContinue)) {
Write-Host "The tool ""pre-commit"" not found. Install https://pre-commit.com/ before running the lint script."
Exit 1
}
Run-Command "golangci-lint run --timeout=10m --build-tags=`"$remotetags`" $PSScriptRoot\cmd\podman"
Run-Command "pre-commit run --all-files"
}
# Helpers
function Build-Ginkgo{
if (Test-Path -Path ./test/tools/build/ginkgo.exe -PathType Leaf) {
@ -69,6 +179,49 @@ function Git-Commit{
return $commit
}
function Build-Distribution-Zip-File{
param (
[string]$destinationPath
);
$binariesFolder = "$PSScriptRoot\bin\windows"
$documentationFolder = "$PSScriptRoot\docs\build\remote\"
$zipFile = "$destinationPath\podman-remote-release-windows_amd64.zip"
# Create a temporary folder to store the distribution files
$tempFolder = New-Item -ItemType Directory -Force -Path "$env:TEMP\podman-windows"
# Copy bin\windows\ content to the temporary folder
Copy-Item -Recurse -Force -Path "$binariesFolder\*" -Destination "$tempFolder\"
# Copy docs\build\remote to the temporary folder
Copy-Item -Recurse -Force -Path "$documentationFolder" -Destination "$tempFolder\docs\"
# If $destination path doesn't exist, create it
if (-Not (Test-Path -Path $destinationPath -PathType Container)) {
New-Item -ItemType Directory -Force -Path $destinationPath
}
# Create the ZIP file with the full client distribution
Compress-Archive -Path "$tempFolder\*" -DestinationPath $zipFile -Force
# Delete the temporary folder
Remove-Item -Recurse -Force -Path "$tempFolder"
}
function Get-Podman-Version{
$versionSrc = "$PSScriptRoot\test\version\"
$versionBin = "$PSScriptRoot\test\version\version.exe"
# If version.exe doesn't exist, build it
if (-Not (Test-Path -Path "$versionBin" -PathType Leaf)) {
Run-Command "go build --o `"$versionBin`" `"$versionSrc`""
}
$version = Invoke-Expression "$versionBin"
# Remove the '-dev' suffix from the version
$version = $version -replace "-.*", ""
return $version
}
# Init script
$target = $args[0]
@ -93,6 +246,18 @@ switch ($target) {
}
Win-SSHProxy -Ref $ref
}
'installer' {
Installer
}
'docs' {
Documentation
}
'validatepr' {
Validate
}
'lint' {
Lint
}
default {
Write-Host "Usage: " $MyInvocation.MyCommand.Name "<target> [options]"
Write-Host
@ -107,5 +272,17 @@ switch ($target) {
Write-Host
Write-Host "Example: Download win-gvproxy and win-sshproxy helpers"
Write-Host " .\winmake win-gvproxy"
Write-Host
Write-Host "Example: Build the windows installer"
Write-Host " .\winmake installer"
Write-Host
Write-Host "Example: Generate the documetation artifacts"
Write-Host " .\winmake docs"
Write-Host
Write-Host "Example: Validate code changes before submitting a PR"
Write-Host " .\winmake validatepr"
Write-Host
Write-Host "Example: Run linters"
Write-Host " .\winmake lint"
}
}