Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert additional build context paths on Windows #23391

Merged
merged 1 commit into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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