Improve platform specific URL handling in `podman compose` for machines

Use filepath utility instead of generic string replace to convert path
on Windows. This also separates OS specific implementations to separate
compilation sources and removes redundant check for virtualization
provider on Windows platform.

Signed-off-by: Arthur Sengileyev <arthur.sengileyev@gmail.com>
This commit is contained in:
Arthur Sengileyev 2024-08-31 20:56:16 +03:00
parent ceee7cb0a6
commit ededb4c3c4
8 changed files with 132 additions and 12 deletions

View File

@ -3,11 +3,9 @@
package main
import (
"errors"
"fmt"
"net/url"
"strconv"
"strings"
"github.com/containers/podman/v5/pkg/machine/define"
"github.com/containers/podman/v5/pkg/machine/env"
@ -55,16 +53,7 @@ func getMachineConn(connectionURI string, parsedConnection *url.URL) (string, er
if err != nil {
return "", err
}
if machineProvider.VMType() == define.WSLVirt || machineProvider.VMType() == define.HyperVVirt {
if podmanPipe == nil {
return "", errors.New("pipe of machine is not set")
}
return strings.Replace(podmanPipe.Path, `\\.\pipe\`, "npipe:////./pipe/", 1), nil
}
if podmanSocket == nil {
return "", errors.New("socket of machine is not set")
}
return "unix://" + podmanSocket.Path, nil
return extractConnectionString(podmanSocket, podmanPipe)
}
return "", fmt.Errorf("could not find a matching machine for connection %q", connectionURI)
}

View File

@ -0,0 +1,16 @@
//go:build (amd64 || arm64) && !windows
package main
import (
"errors"
"github.com/containers/podman/v5/pkg/machine/define"
)
func extractConnectionString(podmanSocket *define.VMFile, podmanPipe *define.VMFile) (string, error) {
if podmanSocket == nil {
return "", errors.New("socket of machine is not set")
}
return "unix://" + podmanSocket.Path, nil
}

View File

@ -0,0 +1,15 @@
package main
import (
"errors"
"path/filepath"
"github.com/containers/podman/v5/pkg/machine/define"
)
func extractConnectionString(podmanSocket *define.VMFile, podmanPipe *define.VMFile) (string, error) {
if podmanPipe == nil {
return "", errors.New("pipe of machine is not set")
}
return "npipe://" + filepath.ToSlash(podmanPipe.Path), nil
}

View File

@ -0,0 +1,48 @@
package e2e_test
import (
"path/filepath"
"runtime"
"strings"
"github.com/containers/podman/v5/pkg/machine"
jsoniter "github.com/json-iterator/go"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
)
var _ = Describe("podman machine compose", func() {
It("compose test environment variable setup", func() {
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))
inspectJSON := new(inspectMachine)
inspectSession, err := mb.setName(name).setCmd(inspectJSON).run()
Expect(err).ToNot(HaveOccurred())
Expect(inspectSession).To(Exit(0))
var inspectInfo []machine.InspectInfo
err = jsoniter.Unmarshal(inspectSession.Bytes(), &inspectInfo)
Expect(err).ToNot(HaveOccurred())
compose := new(fakeCompose)
composeSession, err := mb.setName(name).setCmd(compose).run()
Expect(err).ToNot(HaveOccurred())
Expect(composeSession).To(Exit(0))
lines := composeSession.outputToStringSlice()
if runtime.GOOS != "windows" {
Expect(lines[0]).To(Equal("unix://" + inspectInfo[0].ConnectionInfo.PodmanSocket.GetPath()))
} else {
Expect(strings.TrimSuffix(lines[0], "\r")).To(Equal("npipe://" + filepath.ToSlash(inspectInfo[0].ConnectionInfo.PodmanPipe.GetPath())))
}
Expect(strings.TrimSuffix(lines[1], "\r")).To(Equal("0"))
})
})

View File

@ -0,0 +1,12 @@
package e2e_test
type fakeCompose struct {
cmd []string
}
func (f *fakeCompose) buildCmd(m *machineTestBuilder) []string {
cmd := []string{"compose"}
cmd = append(cmd, "env")
f.cmd = cmd
return cmd
}

View File

@ -154,6 +154,22 @@ func setup() (string, *machineTestBuilder) {
if err := os.Setenv("PODMAN_CONNECTIONS_CONF", filepath.Join(homeDir, "connections.json")); err != nil {
Fail("failed to set PODMAN_CONNECTIONS_CONF")
}
if err := os.Setenv("PODMAN_COMPOSE_WARNING_LOGS", "false"); err != nil {
Fail("failed to set PODMAN_COMPOSE_WARNING_LOGS")
}
cwd, err := os.Getwd()
if err != nil {
Fail("unable to get working directory")
}
var fakeComposeBin string
if runtime.GOOS != "windows" {
fakeComposeBin = "fake_compose"
} else {
fakeComposeBin = "fake_compose.bat"
}
if err := os.Setenv("PODMAN_COMPOSE_PROVIDER", filepath.Join(cwd, "scripts", fakeComposeBin)); err != nil {
Fail("failed to set PODMAN_COMPOSE_PROVIDER")
}
mb, err := newMB()
if err != nil {
Fail(fmt.Sprintf("failed to create machine test: %q", err))

View File

@ -0,0 +1,6 @@
#!/bin/bash
if [[ "$@" == "env" ]]; then
printenv DOCKER_HOST DOCKER_BUILDKIT
exit 0
fi
echo "arguments: $@"

View File

@ -0,0 +1,18 @@
@ECHO off
IF "%1"=="env" (
goto procenv
)
echo arguments: %*
exit
:procenv
if NOT "%DOCKER_HOST%" == "" (
echo %DOCKER_HOST%
)
if NOT "%DOCKER_BUILDKIT%" == "" (
echo %DOCKER_BUILDKIT%
)