Skip to content

Commit

Permalink
Convert additional build context paths on Windows
Browse files Browse the repository at this point in the history
Signed-off-by: Mario Loriedo <[email protected]>
  • Loading branch information
l0rd committed Jul 29, 2024
1 parent c804f10 commit bf3f207
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 15 deletions.
6 changes: 3 additions & 3 deletions build_windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand 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}
```
Expand Down
20 changes: 20 additions & 0 deletions pkg/bindings/images/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
43 changes: 43 additions & 0 deletions pkg/bindings/images/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package images
import (
"testing"

"github.com/containers/buildah/define"
"github.com/stretchr/testify/assert"
)

Expand All @@ -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)
}
}
61 changes: 49 additions & 12 deletions pkg/machine/e2e/README.md
Original file line number Diff line number Diff line change
@@ -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.
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.

## 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. `.\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`

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"`
Expand Down
40 changes: 40 additions & 0 deletions pkg/machine/e2e/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit bf3f207

Please sign in to comment.