Merge pull request #21825 from Luap99/compose

some podman compose fixes
This commit is contained in:
openshift-merge-bot[bot]
2024-02-27 15:11:30 +00:00
committed by GitHub
6 changed files with 135 additions and 75 deletions

View File

@ -1,5 +1,3 @@
//go:build amd64 || arm64
package main
import (
@ -16,10 +14,6 @@ import (
"github.com/containers/podman/v5/cmd/podman/registry"
"github.com/containers/podman/v5/pkg/errorhandling"
"github.com/containers/podman/v5/pkg/machine"
"github.com/containers/podman/v5/pkg/machine/define"
"github.com/containers/podman/v5/pkg/machine/provider"
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@ -114,10 +108,8 @@ func composeDockerHost() (string, error) {
return registry.DefaultAPIAddress(), nil
}
// TODO need to add support for --connection and --url
connection, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetConnection("", true)
if err != nil {
logrus.Info(err)
conf := registry.PodmanConfig()
if conf.URI == "" {
switch runtime.GOOS {
// If no default connection is set on Linux or FreeBSD,
// we just use the local socket by default - just as
@ -132,71 +124,27 @@ func composeDockerHost() (string, error) {
}
}
parsedConnection, err := url.Parse(connection.URI)
parsedConnection, err := url.Parse(conf.URI)
if err != nil {
return "", fmt.Errorf("preparing connection to remote machine: %w", err)
}
// If the default connection does not point to a `podman
// machine`, we cannot use a local path and need to use SSH.
if !connection.IsMachine {
// Compose doesn't like paths, so we optimistically
if !conf.MachineMode {
// Docker Compose v1 doesn't like paths for ssh, so we optimistically
// assume the presence of a Docker socket on the remote
// machine which is the case for podman machines.
return strings.TrimSuffix(connection.URI, parsedConnection.Path), nil
}
machineProvider, err := provider.Get()
if err != nil {
return "", fmt.Errorf("getting machine provider: %w", err)
}
dirs, err := machine.GetMachineDirs(machineProvider.VMType())
if err != nil {
return "", err
}
machineList, err := vmconfigs.LoadMachinesInDir(dirs)
if err != nil {
return "", fmt.Errorf("listing machines: %w", err)
}
// Now we know that the connection points to a machine and we
// can find the machine by looking for the one with the
// matching port.
connectionPort, err := strconv.Atoi(parsedConnection.Port())
if err != nil {
return "", fmt.Errorf("parsing connection port: %w", err)
}
for _, item := range machineList {
if connectionPort != item.SSH.Port {
continue
if parsedConnection.Scheme == "ssh" {
return strings.TrimSuffix(conf.URI, parsedConnection.Path), nil
}
state, err := machineProvider.State(item, false)
if err != nil {
return "", err
}
if state != define.Running {
return "", fmt.Errorf("machine %s is not running but in state %s", item.Name, state)
}
// TODO This needs to be wired back in when all providers are complete
// TODO Need someoone to plumb in the connection information below
// if machineProvider.VMType() == define.WSLVirt || machineProvider.VMType() == define.HyperVVirt {
// if info.ConnectionInfo.PodmanPipe == nil {
// return "", errors.New("pipe of machine is not set")
// }
// return strings.Replace(info.ConnectionInfo.PodmanPipe.Path, `\\.\pipe\`, "npipe:////./pipe/", 1), nil
// }
// if info.ConnectionInfo.PodmanSocket == nil {
// return "", errors.New("socket of machine is not set")
// }
// return "unix://" + info.ConnectionInfo.PodmanSocket.Path, nil
return "", nil
return conf.URI, nil
}
return "", fmt.Errorf("could not find a matching machine for connection %q", connection.URI)
uri, err := getMachineConn(conf.URI, parsedConnection)
if err != nil {
return "", fmt.Errorf("get machine connection URI: %w", err)
}
return uri, nil
}
// composeEnv returns the compose-specific environment variables.

View File

@ -0,0 +1,67 @@
//go:build amd64 || arm64
package main
import (
"fmt"
"net/url"
"strconv"
"github.com/containers/podman/v5/pkg/machine"
"github.com/containers/podman/v5/pkg/machine/define"
"github.com/containers/podman/v5/pkg/machine/provider"
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
)
func getMachineConn(connectionURI string, parsedConnection *url.URL) (string, error) {
machineProvider, err := provider.Get()
if err != nil {
return "", fmt.Errorf("getting machine provider: %w", err)
}
dirs, err := machine.GetMachineDirs(machineProvider.VMType())
if err != nil {
return "", err
}
machineList, err := vmconfigs.LoadMachinesInDir(dirs)
if err != nil {
return "", fmt.Errorf("listing machines: %w", err)
}
// Now we know that the connection points to a machine and we
// can find the machine by looking for the one with the
// matching port.
connectionPort, err := strconv.Atoi(parsedConnection.Port())
if err != nil {
return "", fmt.Errorf("parsing connection port: %w", err)
}
for _, item := range machineList {
if connectionPort != item.SSH.Port {
continue
}
state, err := machineProvider.State(item, false)
if err != nil {
return "", err
}
if state != define.Running {
return "", fmt.Errorf("machine %s is not running but in state %s", item.Name, state)
}
// TODO This needs to be wired back in when all providers are complete
// TODO Need someoone to plumb in the connection information below
// if machineProvider.VMType() == define.WSLVirt || machineProvider.VMType() == define.HyperVVirt {
// if info.ConnectionInfo.PodmanPipe == nil {
// return "", errors.New("pipe of machine is not set")
// }
// return strings.Replace(info.ConnectionInfo.PodmanPipe.Path, `\\.\pipe\`, "npipe:////./pipe/", 1), nil
// }
// if info.ConnectionInfo.PodmanSocket == nil {
// return "", errors.New("socket of machine is not set")
// }
// return "unix://" + info.ConnectionInfo.PodmanSocket.Path, nil
return "", nil
}
return "", fmt.Errorf("could not find a matching machine for connection %q", connectionURI)
}

View File

@ -0,0 +1,12 @@
//go:build !(amd64 || arm64)
package main
import (
"errors"
"net/url"
)
func getMachineConn(connection string, parsedConnection *url.URL) (string, error) {
return "", errors.New("podman machine not supported on this architecture")
}

View File

@ -247,6 +247,15 @@ function podman() {
return $rc
}
# as rootless we want to test the remote connection so we add --connection
function podman_compose() {
if is_rootless; then
$PODMAN_BIN --connection compose-sock compose "$@"
else
podman compose "$@"
fi
}
###################
# random_string # Returns a pseudorandom human-readable string
###################
@ -271,12 +280,26 @@ done
# When rootless use a socket path accessible by the rootless user
if is_rootless; then
# lets test two cases here, for rootless we try to connect to the connection as this should be respected
DOCKER_SOCK="$WORKDIR/docker.sock"
# use PODMAN_CONNECTIONS_CONF so we do not overwrite user settings
PODMAN_CONNECTIONS_CONF="$WORKDIR/connections.json"
export PODMAN_CONNECTIONS_CONF
$PODMAN_BIN system connection add --default notexists "unix:///I/do/not/exist"
$PODMAN_BIN system connection add compose-sock "unix://$DOCKER_SOCK"
else
# export DOCKER_HOST docker-compose will use it
DOCKER_HOST="unix://$DOCKER_SOCK"
export DOCKER_HOST
fi
# export DOCKER_HOST docker-compose will use it
DOCKER_HOST="unix://$DOCKER_SOCK"
export DOCKER_HOST
# hide annoying podman compose warnings, some tests want to check compose stderr and this breaks it.
CONTAINERS_CONF_OVERRIDE="$WORKDIR/containers.conf"
echo '[engine]
compose_warning_logs=false' > "$CONTAINERS_CONF_OVERRIDE"
export CONTAINERS_CONF_OVERRIDE
# Identify the tests to run. If called with args, use those as globs.
tests_to_run=()
@ -336,12 +359,12 @@ for t in "${tests_to_run[@]}"; do
trap - ERR
fi
podman compose up -d &> $logfile
podman_compose up -d &> $logfile
docker_compose_rc=$?
if [[ $docker_compose_rc -ne 0 ]]; then
_show_ok 0 "$testname - up" "[ok]" "status=$docker_compose_rc"
sed -e 's/^/# /' <$logfile
podman compose down >>$logfile 2>&1 # No status check here
podman_compose down >>$logfile 2>&1 # No status check here
exit 1
fi
_show_ok 1 "$testname - up"
@ -361,7 +384,7 @@ for t in "${tests_to_run[@]}"; do
fi
# Done. Clean up.
podman compose down &>> $logfile
podman_compose down &>> $logfile
rc=$?
if [[ $rc -eq 0 ]]; then
_show_ok 1 "$testname - down"

View File

@ -5,7 +5,7 @@ NL=$'\n'
cp docker-compose.yml docker-compose.yml.bak
sed -i -e 's/10001/10002/' docker-compose.yml
output=$(docker-compose up -d 2>&1)
output=$(podman_compose up -d 2>&1)
# Horrible output check here but we really want to make sure that there are
# no unexpected warning/errors and the normal messages are send on stderr as

View File

@ -55,10 +55,20 @@ EOF
CONTAINERS_CONF_OVERRIDE=$compose_conf run_podman 42 compose fail
# Make sure the three env variables are set (and parsed)
op='=~'
url=".*/podman.sock"
# if we run remote with --url check the url arg is honored
if [[ "$PODMAN" =~ "--url" ]]; then
# get the url from the podman string
url="${PODMAN##*--url }"
url="${url%% *}"
op='='
fi
# podman-remote test might run with --url so unset this because the socket will be used otherwise
CONTAINERS_CONF_OVERRIDE=$compose_conf run_podman compose env
is "${lines[0]}" ".*/podman.sock"
is "${lines[1]}" "0"
is "${lines[2]}" ""
assert "${lines[0]}" $op "$url" "line 1 of 3 (DOCKER_HOST)"
assert "${lines[1]}" = "0" "line 2 of 3 (DOCKER_BUILDKIT)"
assert "${lines[2]}" = "" "line 3 of 3 (DOCKER_CONFIG)"
DOCKER_HOST="$random_data" DOCKER_CONFIG="$random_data" CONTAINERS_CONF_OVERRIDE=$compose_conf run_podman compose env
is "${lines[0]}" "$random_data"