mirror of
https://github.com/containers/podman.git
synced 2025-05-17 06:59:07 +08:00

When a user specifies a invalid connection in CONTAINER_CONNECTION then podman should return a proper error saying so. Currently it ignored the error and in rootFlags() just exited early with defining any flags. This caused a panic then when trying to use the flags later. In order to address this first store the connection error in the PodmanConfig struct and not abort right away during flag setup. This is important as the user might have specified a flag with a valid remote connection. As such we check all flags and only when none were given we return the connection error. Also while at it I noticed that the default connection reported via podman --help was wrong as it only used the old containers.conf field for it and did not consider the podman-connections.json default. New regression tests have been added to make sure it behaves correctly. This fixes the problem reported in the PR #22997. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
267 lines
11 KiB
Bash
267 lines
11 KiB
Bash
#!/usr/bin/env bats -*- bats -*-
|
|
#
|
|
# tests for podman system connection
|
|
#
|
|
|
|
load helpers
|
|
load helpers.network
|
|
|
|
# This will be set if we start a local service
|
|
_SERVICE_PID=
|
|
|
|
function setup() {
|
|
if ! is_remote; then
|
|
skip "only applicable when running remote"
|
|
fi
|
|
|
|
basic_setup
|
|
}
|
|
|
|
function teardown() {
|
|
if ! is_remote; then
|
|
return
|
|
fi
|
|
|
|
# In case test function failed to clean up
|
|
if [[ -n $_SERVICE_PID ]]; then
|
|
run kill $_SERVICE_PID
|
|
fi
|
|
|
|
# Aaaaargh! When running as root, 'system service' creates a tmpfs
|
|
# mount on $root/overlay. This in turn causes cleanup to fail.
|
|
mount \
|
|
| grep $PODMAN_TMPDIR \
|
|
| awk '{print $3}' \
|
|
| xargs -l1 --no-run-if-empty umount
|
|
|
|
# Remove all system connections
|
|
run_podman system connection rm --all
|
|
|
|
basic_teardown
|
|
}
|
|
|
|
# Helper function: invokes $PODMAN (which is podman-remote) _without_ --url opt
|
|
#
|
|
# Needed because, in CI, PODMAN="/path/to/podman-remote --url /path/to/socket"
|
|
# which of course overrides podman's detection and use of a connection.
|
|
function _run_podman_remote() {
|
|
PODMAN=${PODMAN%%--url*} run_podman "$@"
|
|
}
|
|
|
|
# Very basic test, does not actually connect at any time
|
|
@test "podman system connection - basic add / ls / remove" {
|
|
run_podman system connection ls
|
|
is "$output" "Name URI Identity Default ReadWrite" \
|
|
"system connection ls: no connections"
|
|
|
|
c1="c1_$(random_string 15)"
|
|
c2="c2_$(random_string 15)"
|
|
|
|
run_podman system connection add $c1 tcp://localhost:12345
|
|
run_podman context create --docker "host=tcp://localhost:54321" $c2
|
|
run_podman system connection ls
|
|
is "$output" \
|
|
".*$c1[ ]\+tcp://localhost:12345[ ]\+true[ ]\+true
|
|
$c2[ ]\+tcp://localhost:54321[ ]\+false[ ]\+true" \
|
|
"system connection ls"
|
|
run_podman system connection ls -q
|
|
is "$(echo $(sort <<<$output))" \
|
|
"$c1 $c2" \
|
|
"system connection ls -q should show two names"
|
|
run_podman context ls -q
|
|
is "$(echo $(sort <<<$output))" \
|
|
"$c1 $c2" \
|
|
"context ls -q should show two names"
|
|
run_podman context use $c2
|
|
run_podman system connection ls
|
|
is "$output" \
|
|
".*$c1[ ]\+tcp://localhost:12345[ ]\+false[ ]\+true
|
|
$c2[ ]\+tcp://localhost:54321[ ]\+true[ ]\+true" \
|
|
"system connection ls"
|
|
|
|
# Remove default connection; the remaining one should still not be default
|
|
run_podman system connection rm $c2
|
|
run_podman context ls
|
|
is "$output" ".*$c1[ ]\+tcp://localhost:12345[ ]\+false[ ]\+true" \
|
|
"system connection ls (after removing default connection)"
|
|
|
|
run_podman context rm $c1
|
|
}
|
|
|
|
# Test tcp socket; requires starting a local server
|
|
@test "podman system connection - tcp" {
|
|
# Start server
|
|
_SERVICE_PORT=$(random_free_port 63000-64999)
|
|
|
|
# Add the connection, and run podman info *before* starting the service.
|
|
# This should fail.
|
|
run_podman system connection add myconnect tcp://localhost:$_SERVICE_PORT
|
|
# IMPORTANT NOTE: in CI, podman-remote is tested by setting PODMAN
|
|
# to "podman-remote --url sdfsdf". This of course overrides the default
|
|
# podman-remote action. Our solution: strip off the "--url xyz" part
|
|
# when invoking podman.
|
|
_run_podman_remote 125 info
|
|
is "$output" \
|
|
"OS: .*provider:.*Cannot connect to Podman. Please verify.*dial tcp.*connection refused" \
|
|
"podman info, without active service"
|
|
|
|
# Start service. Now podman info should work fine. The %%-remote*
|
|
# converts "podman-remote --opts" to just "podman", which is what
|
|
# we need for the server.
|
|
${PODMAN%%-remote*} $(podman_isolation_opts ${PODMAN_TMPDIR}) \
|
|
system service -t 99 tcp://localhost:$_SERVICE_PORT &
|
|
_SERVICE_PID=$!
|
|
# Wait for the port and the podman-service to be ready.
|
|
wait_for_port 127.0.0.1 $_SERVICE_PORT
|
|
local timeout=10
|
|
while [[ $timeout -gt 1 ]]; do
|
|
_run_podman_remote '?' info --format '{{.Host.RemoteSocket.Path}}'
|
|
if [[ $status == 0 ]]; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
let timeout=$timeout-1
|
|
done
|
|
is "$output" "tcp://localhost:$_SERVICE_PORT" \
|
|
"podman info works, and talks to the correct server"
|
|
|
|
_run_podman_remote info --format '{{.Store.GraphRoot}}'
|
|
is "$output" "${PODMAN_TMPDIR}/root" \
|
|
"podman info, talks to the right service"
|
|
|
|
# Add another connection; make sure it does not get set as default
|
|
_run_podman_remote system connection add fakeconnect tcp://localhost:$(( _SERVICE_PORT + 1))
|
|
_run_podman_remote info --format '{{.Store.GraphRoot}}'
|
|
# (Don't bother checking output; we just care about exit status)
|
|
|
|
# Stop server. Use 'run' to avoid failing on nonzero exit status
|
|
run kill $_SERVICE_PID
|
|
run wait $_SERVICE_PID
|
|
_SERVICE_PID=
|
|
|
|
run_podman system connection rm fakeconnect
|
|
run_podman system connection rm myconnect
|
|
}
|
|
|
|
# If we have ssh access to localhost (unlikely in CI), test that.
|
|
@test "podman system connection - ssh" {
|
|
# system connection only really works if we have an agent
|
|
run ssh-add -l
|
|
test "$status" -eq 0 || skip "Not running under ssh-agent"
|
|
test "${#lines[@]}" -ge 1 || skip "ssh agent has no identities"
|
|
|
|
# Can we actually ssh to localhost?
|
|
rand=$(random_string 20)
|
|
echo $rand >$PODMAN_TMPDIR/testfile
|
|
run ssh -q -o BatchMode=yes \
|
|
-o UserKnownHostsFile=/dev/null \
|
|
-o StrictHostKeyChecking=no \
|
|
-o CheckHostIP=no \
|
|
localhost \
|
|
cat $PODMAN_TMPDIR/testfile
|
|
test "$status" -eq 0 || skip "cannot ssh to localhost"
|
|
is "$output" "$rand" "weird! ssh worked, but could not cat local file"
|
|
|
|
# OK, ssh works.
|
|
# Create a new connection, over ssh, but using existing socket file
|
|
# (Remember, we're already podman-remote, there's a service running)
|
|
run_podman info --format '{{.Host.RemoteSocket.Path}}'
|
|
local socketpath="$output"
|
|
run_podman system connection add --socket-path "$socketpath" \
|
|
mysshcon ssh://localhost
|
|
is "$output" "" "output from system connection add"
|
|
|
|
# debug logs will confirm that we use ssh connection
|
|
_run_podman_remote --log-level=debug info --format '{{.Host.RemoteSocket.Path}}'
|
|
is "$output" ".*msg=\"SSH Agent Key .*" "we are truly using ssh"
|
|
|
|
# Clean up
|
|
run_podman system connection rm mysshconn
|
|
}
|
|
|
|
@test "podman-remote: non-default connection" {
|
|
# priority:
|
|
# 1. cli flags (--connection ,--url ,--context ,--host)
|
|
# 2. Env variables (CONTAINER_HOST and CONTAINER_CONNECTION)
|
|
# 3. ActiveService from containers.conf
|
|
# 4. RemoteURI
|
|
|
|
# Prerequisite check: there must be no defined system connections
|
|
run_podman system connection ls -q
|
|
assert "$output" = "" "This test requires an empty list of system connections"
|
|
|
|
# setup
|
|
run_podman 0+w system connection add defaultconnection unix:///run/user/defaultconnection/podman/podman.sock
|
|
run_podman 0+w system connection add env-override unix:///run/user/env-override/podman/podman.sock
|
|
run_podman 0+w system connection add cli-override unix:///run/user/cli-override/podman/podman.sock
|
|
|
|
# Test priority of Env variables wrt cli flags
|
|
CONTAINER_CONNECTION=env-override _run_podman_remote 125 --connection=cli-override ps
|
|
assert "$output" =~ "/run/user/cli-override/podman/podman.sock" "test env variable CONTAINER_CONNECTION wrt --connection cli flag"
|
|
|
|
CONTAINER_HOST=foo://124.com _run_podman_remote 125 --connection=cli-override ps
|
|
assert "$output" =~ "/run/user/cli-override/podman/podman.sock" "test env variable CONTAINER_HOST wrt --connection cli flag"
|
|
|
|
CONTAINER_CONNECTION=env-override _run_podman_remote 125 --url=tcp://localhost ps
|
|
assert "$output" =~ "localhost" "test env variable CONTAINER_CONNECTION wrt --url cli flag"
|
|
|
|
CONTAINER_HOST=foo://124.com _run_podman_remote 125 --url=tcp://localhost ps
|
|
assert "$output" =~ "localhost" "test env variable CONTAINER_HOST wrt --url cli flag"
|
|
|
|
# Docker-compat
|
|
CONTAINER_CONNECTION=env-override _run_podman_remote 125 --context=cli-override ps
|
|
assert "$output" =~ "/run/user/cli-override/podman/podman.sock" "test env variable CONTAINER_CONNECTION wrt --context cli flag"
|
|
|
|
CONTAINER_HOST=foo://124.com _run_podman_remote 125 --context=cli-override ps
|
|
assert "$output" =~ "/run/user/cli-override/podman/podman.sock" "test env variable CONTAINER_HOST wrt --context cli flag"
|
|
|
|
CONTAINER_CONNECTION=env-override _run_podman_remote 125 --host=tcp://localhost ps
|
|
assert "$output" =~ "localhost" "test env variable CONTAINER_CONNECTION wrt --host cli flag"
|
|
|
|
CONTAINER_HOST=foo://124.com _run_podman_remote 125 --host=tcp://localhost ps
|
|
assert "$output" =~ "localhost" "test env variable CONTAINER_HOST wrt --host cli flag"
|
|
|
|
_run_podman_remote 125 --remote ps
|
|
assert "$output" =~ "/run/user/defaultconnection/podman/podman.sock" "test default connection"
|
|
|
|
CONTAINER_CONNECTION=env-override _run_podman_remote 125 --remote ps
|
|
assert "$output" =~ "/run/user/env-override/podman/podman.sock" "test env variable CONTAINER_CONNECTION wrt config"
|
|
|
|
CONTAINER_HOST=foo://124.com _run_podman_remote 125 --remote ps
|
|
assert "$output" =~ "foo" "test env variable CONTAINER_HOST wrt config"
|
|
|
|
# There was a bug where this would panic instead of returning a proper error (#22997)
|
|
CONTAINER_CONNECTION=invalid-env _run_podman_remote 125 --remote ps
|
|
assert "$output" =~ "read cli flags: connection \"invalid-env\" not found" "connection error from env"
|
|
|
|
# Check again with cli overwrite to ensure correct connection name in error is reported
|
|
CONTAINER_CONNECTION=invalid-env _run_podman_remote 125 --connection=invalid-cli ps
|
|
assert "$output" =~ "read cli flags: connection \"invalid-cli\" not found" "connection error from --connection cli"
|
|
|
|
# Invalid env is fine if valid connection is given via cli
|
|
CONTAINER_CONNECTION=invalid-env _run_podman_remote 125 --connection=cli-override ps
|
|
assert "$output" =~ "/run/user/cli-override/podman/podman.sock" "no CONTAINER_CONNECTION connection error with valid --connection cli"
|
|
|
|
# Clean up
|
|
run_podman system connection rm defaultconnection
|
|
run_podman system connection rm env-override
|
|
run_podman system connection rm cli-override
|
|
|
|
# With all system connections removed, test the default connection.
|
|
# This only works in upstream CI, where we run with a nonstandard socket.
|
|
# In gating we use the default /run/...
|
|
run_podman info --format '{{.Host.RemoteSocket.Path}}'
|
|
local sock="$output"
|
|
if [[ "$sock" =~ //run/ ]]; then
|
|
_run_podman_remote --remote info --format '{{.Host.RemoteSocket.Path}}'
|
|
assert "$output" = "$sock" "podman-remote is using default socket path"
|
|
else
|
|
# Nonstandard socket
|
|
_run_podman_remote 125 --remote ps
|
|
assert "$output" =~ "/run/[a-z0-9/]*podman/podman.sock"\
|
|
"test absence of default connection"
|
|
fi
|
|
}
|
|
|
|
# vim: filetype=sh
|