add a podman-compose command

**podman compose** is a thin wrapper around an external compose provider
such as docker-compose or podman-compose.  This means that `podman
compose` is executing another tool that implements the compose
functionality but sets up the environment in a way to let the compose
provider communicate transparently with the local Podman socket.  The
specified options as well the command and argument are passed directly
to the compose provider.

The default compose providers are `docker-compose` and `podman-compose`.
If installed, `docker-compose` takes precedence since it is the original
implementation of the Compose specification and is widely used on the
supported platforms (i.e., Linux, Mac OS, Windows).

If you want to change the default behavior or have a custom installation
path for your provider of choice, please change the `compose_provider`
field in `containers.conf(5)`.  You may also set the
`PODMAN_COMPOSE_PROVIDER` environment variable.

Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2023-07-17 13:43:24 +02:00
parent b9383f41ac
commit e596b17fbe
26 changed files with 521 additions and 23 deletions

View File

@@ -17,6 +17,11 @@ function check_help() {
local -A found
for cmd in $(_podman_commands "$@"); do
# Skip the compose command which is calling `docker-compose --help`
# and hence won't match the assumptions made below.
if [[ "$cmd" == "compose" ]]; then
continue
fi
# Human-readable podman command string, with multiple spaces collapsed
command_string="podman $* $cmd"
command_string=${command_string// / } # 'podman x' -> 'podman x'

View File

@@ -37,6 +37,11 @@ function check_shell_completion() {
"
for cmd in $(_podman_commands "$@"); do
# Skip the compose command which is calling `docker-compose --help`
# and hence won't match the assumptions made below.
if [[ "$cmd" == "compose" ]]; then
continue
fi
# Human-readable podman command string, with multiple spaces collapsed
name="podman"
if is_remote; then

View File

@@ -55,6 +55,12 @@ can_run_stats=
# > run the command with --format '{{"\n"}}' and make sure it passes
function check_subcommand() {
for cmd in $(_podman_commands "$@"); do
# Skip the compose command which is calling `docker-compose --help`
# and hence won't match the assumptions made below.
if [[ "$cmd" == "compose" ]]; then
continue
fi
# Human-readable podman command string, with multiple spaces collapsed
# Special case: 'podman machine' can only be run under ideal conditions
if [[ "$cmd" = "machine" ]] && [[ -z "$can_run_podman_machine" ]]; then
continue

View File

@@ -0,0 +1,67 @@
#!/usr/bin/env bats -*- bats -*-
#
# Smoke tests for the podman-compose command. test/compose takes care of functional tests.
#
load helpers
@test "podman compose - smoke tests" {
fake_compose_bin="$PODMAN_TMPDIR/fake_compose"
cat >$fake_compose_bin <<EOF
#!/bin/bash
if [[ "\$@" == "fail" ]]; then
exit 42
fi
if [[ "\$@" == "env" ]]; then
printenv DOCKER_HOST DOCKER_BUILDKIT DOCKER_CONFIG
exit 0
fi
echo "arguments: \$@"
EOF
compose_conf="$PODMAN_TMPDIR/compose.conf"
cat >$compose_conf <<EOF
[engine]
compose_providers = ["$fake_compose_bin"]
compose_warning_logs = false
EOF
random_data="--foo=bar --random=$(random_string 15) -f /path/to/file ignore me"
# Make sure that the fake compose binary is used and that error reporting works
PODMAN_COMPOSE_PROVIDER=$fake_compose_bin run_podman 125 compose --help
is "$output" ".*executing $fake_compose_bin --help: .*: permission denied"
# Make the fake one executable and check the --help output
chmod +x $fake_compose_bin
PODMAN_COMPOSE_PROVIDER=$fake_compose_bin run_podman compose --help
is "$output" "Run compose workloads via an external provider .*arguments: --help"
# No argument yields the help message as well
PODMAN_COMPOSE_PROVIDER=$fake_compose_bin run_podman compose
is "$output" "Run compose workloads via an external provider .*arguments: "
# Make sure that the provider can be specified via containers.conf and that
# the warning logs can be turned off
CONTAINERS_CONF_OVERRIDE=$compose_conf run_podman compose --help
is "$output" "Run compose workloads via an external provider .*arguments: --help"
assert "$output" !~ ".*Executing external compose provider.*"
# Run with bogus arguments and make sure they're being returned
CONTAINERS_CONF_OVERRIDE=$compose_conf run_podman compose $random_data
is "$output" "arguments: $random_data"
# Make sure Podman returns the exit code of the compose provider
CONTAINERS_CONF_OVERRIDE=$compose_conf run_podman 42 compose fail
# Make sure the three env variables are set (and parsed)
CONTAINERS_CONF_OVERRIDE=$compose_conf run_podman compose env
is "${lines[0]}" ".*/podman.sock"
is "${lines[1]}" "0"
is "${lines[2]}" ""
DOCKER_HOST="$random_data" DOCKER_CONFIG="$random_data" CONTAINERS_CONF_OVERRIDE=$compose_conf run_podman compose env
is "${lines[0]}" "$random_data"
is "${lines[1]}" "0"
is "${lines[2]}" "$random_data"
}