Convert additional build context paths on Windows

Signed-off-by: Mario Loriedo <mario.loriedo@gmail.com>
This commit is contained in:
Mario Loriedo 2024-07-24 16:26:16 +02:00
parent c804f10686
commit bf3f207a49
5 changed files with 156 additions and 16 deletions

View File

@ -24,8 +24,8 @@ Windows.
- [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 the Windows installer](#build-the-windows-installer)
- [Test the Windows installer](#test-the-windows-installer)
- [Build and test the standalone `podman.msi` file](#build-and-test-the-standalone-podmanmsi-file)
- [Verify the installation](#verify-the-installation)
- [Uninstall and clean-up](#uninstall-and-clean-up)
@ -480,7 +480,7 @@ $foldersToCheck = @(
"$env:USERPROFILE.config\containers\"
"$env:USERPROFILE.local\share\containers\"
"$ENV:LOCALAPPDATA\containers\"
"$ENV:APPDATA\containers\containers.conf.d\99-podman-machine-provider.conf"
"$ENV:PROGRAMDATA\containers\containers.conf.d\99-podman-machine-provider.conf"
)
$foldersToCheck | ForEach-Object {Test-Path -Path $PSItem}
```

View File

@ -22,6 +22,7 @@ import (
"github.com/containers/podman/v5/pkg/auth"
"github.com/containers/podman/v5/pkg/bindings"
"github.com/containers/podman/v5/pkg/domain/entities/types"
"github.com/containers/podman/v5/pkg/specgen"
"github.com/containers/podman/v5/pkg/util"
"github.com/containers/storage/pkg/fileutils"
"github.com/containers/storage/pkg/ioutils"
@ -49,6 +50,21 @@ type BuildResponse struct {
Aux json.RawMessage `json:"aux,omitempty"`
}
// Modify the build contexts that uses a local windows path. The windows path is
// converted into the corresping guest path in the default Windows machine
// (e.g. C:\test ==> /mnt/c/test).
func convertAdditionalBuildContexts(additionalBuildContexts map[string]*define.AdditionalBuildContext) {
for _, context := range additionalBuildContexts {
if !context.IsImage && !context.IsURL {
path, err := specgen.ConvertWinMountPath(context.Value)
// It's not worth failing if the path can't be converted
if err == nil {
context.Value = path
}
}
}
}
// Build creates an image using a containerfile reference
func Build(ctx context.Context, containerFiles []string, options types.BuildOptions) (*types.BuildReport, error) {
if options.CommonBuildOpts == nil {
@ -90,6 +106,10 @@ func Build(ctx context.Context, containerFiles []string, options types.BuildOpti
params.Add("t", tag)
}
if additionalBuildContexts := options.AdditionalBuildContexts; len(additionalBuildContexts) > 0 {
// TODO: Additional build contexts should be packaged and sent as tar files
// For the time being we make our best to make them accessible on remote
// machines too (i.e. on macOS and Windows).
convertAdditionalBuildContexts(additionalBuildContexts)
additionalBuildContextMap, err := jsoniter.Marshal(additionalBuildContexts)
if err != nil {
return nil, err

View File

@ -3,6 +3,7 @@ package images
import (
"testing"
"github.com/containers/buildah/define"
"github.com/stretchr/testify/assert"
)
@ -15,3 +16,45 @@ func TestBuildMatchIID(t *testing.T) {
func TestBuildNotMatchStatusMessage(t *testing.T) {
assert.False(t, iidRegex.MatchString("Copying config a883dafc480d466ee04e0d6da986bd78eb1fdd2178d04693723da3a8f95d42f4"))
}
func TestConvertAdditionalBuildContexts(t *testing.T) {
additionalBuildContexts := map[string]*define.AdditionalBuildContext{
"context1": {
IsURL: false,
IsImage: false,
Value: "C:\\test",
DownloadedCache: "",
},
"context2": {
IsURL: false,
IsImage: false,
Value: "/test",
DownloadedCache: "",
},
"context3": {
IsURL: true,
IsImage: false,
Value: "https://a.com/b.tar",
DownloadedCache: "",
},
"context4": {
IsURL: false,
IsImage: true,
Value: "quay.io/a/b:c",
DownloadedCache: "",
},
}
convertAdditionalBuildContexts(additionalBuildContexts)
expectedGuestValues := map[string]string{
"context1": "/mnt/c/test",
"context2": "/test",
"context3": "https://a.com/b.tar",
"context4": "quay.io/a/b:c",
}
for key, value := range additionalBuildContexts {
assert.Equal(t, expectedGuestValues[key], value.Value)
}
}

View File

@ -1,49 +1,86 @@
# Running the machine tests
This document is a quick how-to run machine tests. Not all dependencies, like
`gvproxy` are documented. You must install `gvproxy` in all cases described below.
`gvproxy` are documented. You must install `gvproxy` in all cases described
below.
## General notes
### Environment must be clean
You must not have any machines defined before running tests. Consider running `podman machine reset` prior to running tests.
You must not have any machines defined before running tests. Consider running
`podman machine reset` prior to running tests.
###
### Scoping tests
You can scope tests in the machine suite by adding various incantations of `FOCUS=`. For example, add `FOCUS_FILE=basic_test.go` to only run basic test. Or add `FOCUS="simple init with start"` to only run one test case. For windows, the syntax differs slightly. In windows, executing something like following achieves the same result:
You can scope tests in the machine suite by adding various incantations of
`FOCUS=`. For example, add `FOCUS_FILE=basic_test.go` to only run basic test. Or
add `FOCUS="simple init with start"` to only run one test case. For windows, the
syntax differs slightly. In windows, executing something like following achieves
the same result:
`./winmake localmachine "basic_test.go start_test.go"`
To focus on one specific test on windows, run `ginkgo` manually:
```pwsh
$remotetags = "remote exclude_graphdriver_btrfs btrfs_noversion exclude_graphdriver_devicemapper containers_image_openpgp"
$focus_file = "basic_test.go"
$focus_test = "podman build contexts"
./test/tools/build/ginkgo.exe `
-v --tags "$remotetags" -timeout=90m --trace --no-color `
--focus-file $focus_file `
--focus "$focus_test" `
./pkg/machine/e2e/.
```
Note that ginkgo.exe is built when running the command
`winmake.ps1 localmachine` so make sure to run it before trying the command
above.
## Linux
### QEMU
1. `make localmachine`
1. `make localmachine`
## Microsoft Windows
### Hyper-V
1. Open a powershell as admin
1. `$env:CONTAINERS_MACHINE_PROVIDER="hyperv"`
1. `./winmake localmachine`
1. Open a powershell as admin
1. `.\winmake.ps1 podman-remote && .\winmake.ps1 win-gvproxy`
1. `$env:CONTAINERS_HELPER_BINARY_DIR="$pwd\bin\windows"`
1. `$env:CONTAINERS_MACHINE_PROVIDER="hyperv"`
1. `.\winmake localmachine`
### WSL
1. Open a powershell as a regular user
1. Build and copy win-sshproxy into bin/
1. `./winmake localmachine`
1. `.\winmake.ps1 podman-remote && .\winmake.ps1 win-gvproxy`
1. `$env:CONTAINERS_HELPER_BINARY_DIR="$pwd\bin\windows"`
1. `$env:CONTAINERS_MACHINE_PROVIDER="wsl"`
1. `.\winmake localmachine`
## MacOS
Macs now support two different machine providers: `applehv` and `libkrun`. The `applehv` provider is the default.
Note: On macOS, an error will occur if the path length of `$TMPDIR` is longer than 22 characters. Please set the appropriate path to `$TMPDIR`. Also, if `$TMPDIR` is empty, `/private/tmp` will be set.
Macs now support two different machine providers: `applehv` and `libkrun`. The
`applehv` provider is the default.
Note: On macOS, an error will occur if the path length of `$TMPDIR` is longer
than 22 characters. Please set the appropriate path to `$TMPDIR`. Also, if
`$TMPDIR` is empty, `/private/tmp` will be set.
### Apple Hypervisor
1. `brew install vfkit`
1. `make podman-remote`
1. `make localmachine`
### [Libkrun](https://github.com/containers/libkrun)
1. `brew install krunkit`
1. `make podman-remote`
1. `export CONTAINERS_MACHINE_PROVIDER="libkrun"`

View File

@ -207,6 +207,46 @@ var _ = Describe("run basic podman commands", func() {
Expect(ls).To(Exit(0))
Expect(ls.outputToString()).To(ContainSubstring(testString))
})
It("podman build contexts", func() {
skipIfVmtype(define.HyperVVirt, "FIXME: #23429 - Error running podman build with option --build-context on Hyper-V")
skipIfVmtype(define.QemuVirt, "FIXME: #23433 - Additional build contexts should be sent as additional tar files")
name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImage(mb.imagePath).withNow()).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
mainContextDir := GinkgoT().TempDir()
cfile := filepath.Join(mainContextDir, "test1")
err = os.WriteFile(cfile, []byte(name), 0o644)
Expect(err).ToNot(HaveOccurred())
additionalContextDir := GinkgoT().TempDir()
cfile = filepath.Join(additionalContextDir, "test2")
err = os.WriteFile(cfile, []byte(name), 0o644)
Expect(err).ToNot(HaveOccurred())
cfile = filepath.Join(mainContextDir, "Containerfile")
err = os.WriteFile(cfile, []byte("FROM quay.io/libpod/alpine_nginx\nCOPY test1 /\nCOPY --from=test-context test2 /\n"), 0o644)
Expect(err).ToNot(HaveOccurred())
bm := basicMachine{}
build, err := mb.setCmd(bm.withPodmanCommand([]string{"build", "-t", name, "--build-context", "test-context=" + additionalContextDir, mainContextDir})).run()
Expect(err).ToNot(HaveOccurred())
Expect(build).To(Exit(0))
Expect(build.outputToString()).To(ContainSubstring("COMMIT"))
run, err := mb.setCmd(bm.withPodmanCommand([]string{"run", name, "cat", "/test1"})).run()
Expect(err).ToNot(HaveOccurred())
Expect(run).To(Exit(0))
Expect(build.outputToString()).To(ContainSubstring(name))
run, err = mb.setCmd(bm.withPodmanCommand([]string{"run", name, "cat", "/test2"})).run()
Expect(err).ToNot(HaveOccurred())
Expect(run).To(Exit(0))
Expect(build.outputToString()).To(ContainSubstring(name))
})
})
func testHTTPServer(port string, shouldErr bool, expectedResponse string) {