-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy path272-system-connection.bats
More file actions
440 lines (367 loc) · 18.3 KB
/
Copy path272-system-connection.bats
File metadata and controls
440 lines (367 loc) · 18.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
#!/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" {
unset REMOTESYSTEM_TRANSPORT REMOTESYSTEM_TLS_{CLIENT,SERVER,CA}_{CRT,KEY}
run_podman system connection ls
is "$output" "Name URI Identity Default ReadWrite" \
"system connection ls: no connections"
run_podman system connection ls --format=tls
is "$output" "Name URI Identity TLSCA TLSCert TLSKey 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 system connection add bad identities with ssh/unix/tcp
@test "podman system connection --identity" {
run_podman system connection ls -q
assert "$output" == "" ""
run_podman 125 system connection add ssh-conn --identity $PODMAN_TMPDIR/nonexistent ssh://localhost
assert "$output" =~ \
"Error: failed to validate: failed to read identity *" ""
run_podman 125 system connection add unix-conn --identity $PODMAN_TMPDIR/identity unix://path
assert "$output" == \
"Error: --identity option not supported for unix scheme" ""
run_podman 125 system connection add tcp-conn --identity $PODMAN_TEMPDIR/identity tcp://path
assert "$output" =~ \
"Error: --identity option not supported for tcp scheme" ""
run touch $PODMAN_TEMPDIR/badfile
run chmod -r $PODMAN_TEMPDIR/badfile
run_podman 125 system connection add bad-conn --identity $PODMAN_TEMPDIR/badfile ssh://localhost
assert "$output" =~ \
"Error: failed to validate: failed to read identity*" ""
# Ensure no connections were added
run_podman system connection ls -q
assert "$output" == "" ""
}
# Test tcp socket; requires starting a local server
@test "podman system connection - tcp" {
unset REMOTESYSTEM_TRANSPORT REMOTESYSTEM_TLS_{CLIENT,SERVER,CA}_{CRT,KEY}
# 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
}
# Test tcp socket with server authentication; requires starting a local server
@test "podman system connection - tls" {
unset REMOTESYSTEM_TRANSPORT REMOTESYSTEM_TLS_{CLIENT,SERVER,CA}_{CRT,KEY}
# 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 \
--tls-ca="${REMOTESYSTEM_TLS_CA_CRT}"
# 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 \
--tls-cert="${REMOTESYSTEM_TLS_SERVER_CRT}" \
--tls-key="${REMOTESYSTEM_TLS_SERVER_KEY}" \
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
}
# Test tcp socket with mutual authentication; requires starting a local server
@test "podman system connection - mtls" {
unset REMOTESYSTEM_TRANSPORT REMOTESYSTEM_TLS_{CLIENT,SERVER,CA}_{CRT,KEY}
# 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 \
--tls-ca="${REMOTESYSTEM_TLS_CA_CRT}" \
--tls-cert="${REMOTESYSTEM_TLS_CLIENT_CRT}" \
--tls-key="${REMOTESYSTEM_TLS_CLIENT_KEY}"
# 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 \
--tls-client-ca="${REMOTESYSTEM_TLS_CA_CRT}" \
--tls-cert="${REMOTESYSTEM_TLS_SERVER_CRT}" \
--tls-key="${REMOTESYSTEM_TLS_SERVER_KEY}" \
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" {
unset REMOTESYSTEM_TRANSPORT REMOTESYSTEM_TLS_{CLIENT,SERVER,CA}_{CRT,KEY}
# 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
(
unset REMOTESYSTEM_TRANSPORT REMOTESYSTEM_TLS_{CLIENT,SERVER,CA}_{CRT,KEY}
# 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.
if [[ "${REMOTESYSTEM_TRANSPORT}" =~ tcp|tls|mtls ]]; then
run_podman_remote --remote info --format '{{.Host.RemoteSocket.Path}}'
assert "$output" =~ "tcp://localhost:${REMOTESYSTEM_TCP_PORT}"
elif [[ "${REMOTESYSTEM_TRANSPORT}" =~ unix ]]; then
run_podman_remote --remote info --format '{{.Host.RemoteSocket.Path}}'
assert "$output" =~ "unix://${REMOTESYSTEM_UNIX_SOCK}"
else
# 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
fi
}
# vim: filetype=sh