github.com/containers/podman/v5@v5.1.0-rc1/test/system/150-login.bats (about) 1 #!/usr/bin/env bats -*- bats -*- 2 # 3 # tests for podman login 4 # 5 6 load helpers 7 load helpers.network 8 load helpers.registry 9 10 ############################################################################### 11 # BEGIN filtering - none of these tests will work with podman-remote 12 13 function setup() { 14 skip_if_remote "none of these tests work with podman-remote" 15 16 basic_setup 17 start_registry 18 } 19 20 # END filtering - none of these tests will work with podman-remote 21 ############################################################################### 22 # BEGIN actual tests 23 # BEGIN primary podman login/push/pull tests 24 25 @test "podman login - basic test" { 26 run_podman login --tls-verify=false \ 27 --username ${PODMAN_LOGIN_USER} \ 28 --password-stdin \ 29 localhost:${PODMAN_LOGIN_REGISTRY_PORT} <<<"${PODMAN_LOGIN_PASS}" 30 is "$output" "Login Succeeded!" "output from podman login" 31 32 # Now log out 33 run_podman logout localhost:${PODMAN_LOGIN_REGISTRY_PORT} 34 is "$output" "Removed login credentials for localhost:${PODMAN_LOGIN_REGISTRY_PORT}" \ 35 "output from podman logout" 36 } 37 38 @test "podman login - with wrong credentials" { 39 registry=localhost:${PODMAN_LOGIN_REGISTRY_PORT} 40 41 run_podman 125 login --tls-verify=false \ 42 --username ${PODMAN_LOGIN_USER} \ 43 --password-stdin \ 44 $registry <<< "x${PODMAN_LOGIN_PASS}" 45 is "$output" \ 46 "Error: logging into \"$registry\": invalid username/password" \ 47 'output from podman login' 48 } 49 50 @test "podman login - check generated authfile" { 51 authfile=${PODMAN_LOGIN_WORKDIR}/auth-$(random_string 10).json 52 rm -f $authfile 53 54 registry=localhost:${PODMAN_LOGIN_REGISTRY_PORT} 55 56 run_podman login --authfile=$authfile \ 57 --tls-verify=false \ 58 --username ${PODMAN_LOGIN_USER} \ 59 --password ${PODMAN_LOGIN_PASS} \ 60 $registry 61 62 # Confirm that authfile now exists 63 test -e $authfile || \ 64 die "podman login did not create authfile $authfile" 65 66 # Special bracket form needed because of colon in host:port 67 run jq -r ".[\"auths\"][\"$registry\"][\"auth\"]" <$authfile 68 is "$status" "0" "jq from $authfile" 69 70 expect_userpass="${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS}" 71 actual_userpass=$(base64 -d <<<"$output") 72 is "$actual_userpass" "$expect_userpass" "credentials stored in $authfile" 73 74 75 # Now log out and make sure credentials are removed 76 run_podman logout --authfile=$authfile $registry 77 78 run jq -r '.auths' <$authfile 79 is "$status" "0" "jq from $authfile" 80 is "$output" "{}" "credentials removed from $authfile" 81 } 82 83 @test "podman login inconsistent authfiles" { 84 ambiguous_file=${PODMAN_LOGIN_WORKDIR}/ambiguous-auth.json 85 echo '{}' > $ambiguous_file # To make sure we are not hitting the “file not found” path 86 87 run_podman 125 login --authfile "$ambiguous_file" --compat-auth-file "$ambiguous_file" localhost:5000 88 assert "$output" =~ "Error: options for paths to the credential file and to the Docker-compatible credential file can not be set simultaneously" 89 90 run_podman 125 logout --authfile "$ambiguous_file" --compat-auth-file "$ambiguous_file" localhost:5000 91 assert "$output" =~ "Error: options for paths to the credential file and to the Docker-compatible credential file can not be set simultaneously" 92 } 93 94 @test "podman login - check with --config global option" { 95 dockerconfig=${PODMAN_LOGIN_WORKDIR}/docker 96 rm -rf $dockerconfig 97 98 registry=localhost:${PODMAN_LOGIN_REGISTRY_PORT} 99 100 run_podman --config $dockerconfig login \ 101 --tls-verify=false \ 102 --username ${PODMAN_LOGIN_USER} \ 103 --password ${PODMAN_LOGIN_PASS} \ 104 $registry 105 106 # Confirm that config file now exists 107 test -e $dockerconfig/config.json || \ 108 die "podman login did not create config $dockerconfig/config.json" 109 110 # Special bracket form needed because of colon in host:port 111 run jq -r ".[\"auths\"][\"$registry\"][\"auth\"]" <$dockerconfig/config.json 112 is "$status" "0" "jq from $dockerconfig/config.json" 113 114 expect_userpass="${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS}" 115 actual_userpass=$(base64 -d <<<"$output") 116 is "$actual_userpass" "$expect_userpass" "credentials stored in $dockerconfig/config.json" 117 118 # Now log out and make sure credentials are removed 119 run_podman --config $dockerconfig logout $registry 120 121 run jq -r '.auths' <$dockerconfig/config.json 122 is "$status" "0" "jq from $dockerconfig/config.json" 123 is "$output" "{}" "credentials removed from $dockerconfig/config.json" 124 } 125 126 # Some push tests 127 @test "podman push fail" { 128 129 # Create an invalid authfile 130 authfile=${PODMAN_LOGIN_WORKDIR}/auth-$(random_string 10).json 131 rm -f $authfile 132 133 wrong_auth=$(base64 <<<"baduser:wrongpassword") 134 cat >$authfile <<EOF 135 { 136 "auths": { 137 "localhost:${PODMAN_LOGIN_REGISTRY_PORT}": { 138 "auth": "$wrong_auth" 139 } 140 } 141 } 142 EOF 143 144 run_podman 125 push --authfile=$authfile \ 145 --tls-verify=false $IMAGE \ 146 localhost:${PODMAN_LOGIN_REGISTRY_PORT}/badpush:1 147 is "$output" ".* checking whether a blob .* exists in localhost:${PODMAN_LOGIN_REGISTRY_PORT}/badpush: authentication required" \ 148 "auth error on push" 149 } 150 151 function _push_search_test() { 152 # Preserve image ID for later comparison against push/pulled image 153 run_podman inspect --format '{{.Id}}' $IMAGE 154 iid=$output 155 156 destname=ok-$(random_string 10 | tr A-Z a-z)-ok 157 # Use command-line credentials 158 run_podman push --tls-verify=$1 \ 159 --format docker \ 160 --cert-dir ${PODMAN_LOGIN_WORKDIR}/trusted-registry-cert-dir \ 161 --creds ${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS} \ 162 $IMAGE localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname 163 164 # Search a pushed image without --cert-dir should fail if --tls-verify=true 165 run_podman $2 search --tls-verify=$1 \ 166 --format "table {{.Name}}" \ 167 --creds ${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS} \ 168 localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname 169 170 # Search a pushed image without --creds should fail 171 run_podman 125 search --tls-verify=$1 \ 172 --format "table {{.Name}}" \ 173 --cert-dir ${PODMAN_LOGIN_WORKDIR}/trusted-registry-cert-dir \ 174 localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname 175 176 # Search a pushed image should succeed 177 run_podman search --tls-verify=$1 \ 178 --format "table {{.Name}}" \ 179 --cert-dir ${PODMAN_LOGIN_WORKDIR}/trusted-registry-cert-dir \ 180 --creds ${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS} \ 181 localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname 182 is "${lines[1]}" "localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname" "search output is destname" 183 184 # Yay! Pull it back 185 run_podman pull --tls-verify=$1 \ 186 --cert-dir ${PODMAN_LOGIN_WORKDIR}/trusted-registry-cert-dir \ 187 --creds ${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS} \ 188 localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname 189 190 # Compare to original image 191 run_podman inspect --format '{{.Id}}' $destname 192 is "$output" "$iid" "Image ID of pulled image == original IID" 193 194 run_podman rmi $destname 195 } 196 197 @test "podman push and search ok with --tls-verify=false" { 198 _push_search_test false 0 199 } 200 201 @test "podman push and search ok with --tls-verify=true" { 202 _push_search_test true 125 203 } 204 205 # END primary podman login/push/pull tests 206 ############################################################################### 207 # BEGIN cooperation with skopeo 208 209 # Skopeo helper - keep this separate, so we can test with different 210 # envariable settings 211 function _test_skopeo_credential_sharing() { 212 if ! type -p skopeo; then 213 skip "skopeo not available" 214 fi 215 216 registry=localhost:${PODMAN_LOGIN_REGISTRY_PORT} 217 218 run_podman login "$@" --tls-verify=false \ 219 --username ${PODMAN_LOGIN_USER} \ 220 --password ${PODMAN_LOGIN_PASS} \ 221 $registry 222 223 destname=skopeo-ok-$(random_string 10 | tr A-Z a-z)-ok 224 echo "# skopeo copy ..." 225 run skopeo copy "$@" \ 226 --format=v2s2 \ 227 --dest-tls-verify=false \ 228 containers-storage:$IMAGE \ 229 docker://$registry/$destname 230 echo "$output" 231 is "$status" "0" "skopeo copy - exit status" 232 is "$output" ".*Copying blob .*" "output of skopeo copy" 233 is "$output" ".*Copying config .*" "output of skopeo copy" 234 is "$output" ".*Writing manifest .*" "output of skopeo copy" 235 236 echo "# skopeo inspect ..." 237 run skopeo inspect "$@" --tls-verify=false docker://$registry/$destname 238 echo "$output" 239 is "$status" "0" "skopeo inspect - exit status" 240 241 got_name=$(jq -r .Name <<<"$output") 242 is "$got_name" "$registry/$destname" "skopeo inspect -> Name" 243 244 # Now try without a valid login; it should fail 245 run_podman logout "$@" $registry 246 echo "# skopeo inspect [with no credentials] ..." 247 run skopeo inspect "$@" --tls-verify=false docker://$registry/$destname 248 echo "$output" 249 is "$status" "1" "skopeo inspect - exit status" 250 is "$output" ".*: authentication required" \ 251 "auth error on skopeo inspect" 252 } 253 254 @test "podman login - shares credentials with skopeo - default auth file" { 255 if is_rootless; then 256 if [ -z "${XDG_RUNTIME_DIR}" ]; then 257 skip "skopeo does not match podman when XDG_RUNTIME_DIR unset; #823" 258 fi 259 fi 260 _test_skopeo_credential_sharing 261 } 262 263 @test "podman login - shares credentials with skopeo - via envariable" { 264 authfile=${PODMAN_LOGIN_WORKDIR}/auth-$(random_string 10).json 265 rm -f $authfile 266 267 REGISTRY_AUTH_FILE=$authfile _test_skopeo_credential_sharing 268 rm -f $authfile 269 } 270 271 @test "podman login - shares credentials with skopeo - via --authfile" { 272 # Also test that command-line --authfile overrides envariable 273 authfile=${PODMAN_LOGIN_WORKDIR}/auth-$(random_string 10).json 274 rm -f $authfile 275 276 fake_authfile=${PODMAN_LOGIN_WORKDIR}/auth-$(random_string 10).json 277 rm -f $fake_authfile 278 279 REGISTRY_AUTH_FILE=$authfile _test_skopeo_credential_sharing --authfile=$authfile 280 281 if [ -e $fake_authfile ]; then 282 die "REGISTRY_AUTH_FILE overrode command-line --authfile!" 283 fi 284 rm -f $authfile 285 } 286 287 @test "podman login -secret test" { 288 secret=$(random_string 10) 289 echo -n ${PODMAN_LOGIN_PASS} > $PODMAN_TMPDIR/secret.file 290 run_podman secret create $secret $PODMAN_TMPDIR/secret.file 291 secretID=${output} 292 run_podman login --tls-verify=false \ 293 --username ${PODMAN_LOGIN_USER} \ 294 --secret ${secretID} \ 295 localhost:${PODMAN_LOGIN_REGISTRY_PORT} 296 is "$output" "Login Succeeded!" "output from podman login" 297 # Now log out 298 run_podman logout localhost:${PODMAN_LOGIN_REGISTRY_PORT} 299 is "$output" "Removed login credentials for localhost:${PODMAN_LOGIN_REGISTRY_PORT}" \ 300 "output from podman logout" 301 run_podman secret rm $secret 302 303 # test using secret id as --username 304 run_podman secret create ${PODMAN_LOGIN_USER} $PODMAN_TMPDIR/secret.file 305 run_podman login --tls-verify=false \ 306 --secret ${PODMAN_LOGIN_USER} \ 307 localhost:${PODMAN_LOGIN_REGISTRY_PORT} 308 is "$output" "Login Succeeded!" "output from podman login" 309 # Now log out 310 run_podman logout localhost:${PODMAN_LOGIN_REGISTRY_PORT} 311 is "$output" "Removed login credentials for localhost:${PODMAN_LOGIN_REGISTRY_PORT}" \ 312 "output from podman logout" 313 run_podman secret rm ${PODMAN_LOGIN_USER} 314 315 bogus_secret=$(random_string 10) 316 echo -n ${bogus_secret} > $PODMAN_TMPDIR/secret.file 317 run_podman secret create $secret $PODMAN_TMPDIR/secret.file 318 secretID=${output} 319 run_podman 125 login --tls-verify=false \ 320 --username ${PODMAN_LOGIN_USER} \ 321 --secret ${secretID} \ 322 localhost:${PODMAN_LOGIN_REGISTRY_PORT} 323 324 is "$output" "Error: logging into \"localhost:${PODMAN_LOGIN_REGISTRY_PORT}\": invalid username/password" "output from failed podman login" 325 326 run_podman secret rm $secret 327 328 } 329 330 @test "podman pull images with retry" { 331 run_podman pull -q --retry 4 --retry-delay "10s" $IMAGE 332 run_podman 125 pull -q --retry 4 --retry-delay "bogus" $IMAGE 333 is "$output" 'Error: time: invalid duration "bogus"' "bad retry-delay" 334 335 skip_if_remote "running a local registry doesn't work with podman-remote" 336 start_registry 337 authfile=${PODMAN_LOGIN_WORKDIR}/auth-$(random_string 10).json 338 run_podman login --tls-verify=false \ 339 --username ${PODMAN_LOGIN_USER} \ 340 --password-stdin \ 341 --authfile=$authfile \ 342 localhost:${PODMAN_LOGIN_REGISTRY_PORT} <<<"${PODMAN_LOGIN_PASS}" 343 is "$output" "Login Succeeded!" "output from podman login" 344 345 image1="localhost:${PODMAN_LOGIN_REGISTRY_PORT}/test:1.0" 346 347 run_podman tag $IMAGE $image1 348 run_podman push --authfile=$authfile \ 349 --tls-verify=false $mid \ 350 $image1 351 run_podman rmi $image1 352 run_podman pull -q --retry 4 --retry-delay "0s" --authfile=$authfile \ 353 --tls-verify=false $image1 354 assert "${output:0:12}" = "$PODMAN_TEST_IMAGE_ID" "First pull (before stopping registry)" 355 run_podman rmi $image1 356 357 # This actually STOPs the registry, so the port is unbound... 358 pause_registry 359 # ...then, in eight seconds, we start it again 360 (sleep 8; unpause_registry) & 361 run_podman 0+w pull -q --retry 4 --retry-delay "5s" --authfile=$authfile \ 362 --tls-verify=false $image1 363 assert "$output" =~ "Failed, retrying in 5s.*Error: initializing.* connection refused" 364 assert "${lines[-1]:0:12}" = "$PODMAN_TEST_IMAGE_ID" "push should succeed via retry" 365 unpause_registry 366 367 run_podman rmi $image1 368 } 369 370 @test "podman containers.conf retry" { 371 skip_if_remote "containers.conf settings not set for remote connections" 372 run_podman pull --help 373 assert "$output" =~ "--retry .*performing pull \(default 3\)" 374 375 run_podman push --help 376 assert "$output" =~ "--retry .*performing push \(default 3\)" 377 378 containersConf=$PODMAN_TMPDIR/containers.conf 379 cat >$containersConf <<EOF 380 [engine] 381 retry=10 382 retry_delay="5s" 383 EOF 384 385 CONTAINERS_CONF="$containersConf" run_podman pull --help 386 assert "$output" =~ "--retry .*performing pull \(default 10\)" 387 assert "$output" =~ "--retry-delay .*pull failures \(default \"5s\"\)" 388 389 CONTAINERS_CONF="$containersConf" run_podman push --help 390 assert "$output" =~ "--retry .*performing push \(default 10\)" 391 assert "$output" =~ "--retry-delay .*push failures \(default \"5s\"\)" 392 393 CONTAINERS_CONF="$containersConf" run_podman create --help 394 assert "$output" =~ "--retry .*performing pull \(default 10\)" 395 assert "$output" =~ "--retry-delay .*pull failures \(default \"5s\"\)" 396 397 CONTAINERS_CONF="$containersConf" run_podman run --help 398 assert "$output" =~ "--retry .*performing pull \(default 10\)" 399 assert "$output" =~ "--retry-delay .*pull failures \(default \"5s\"\)" 400 } 401 402 # END cooperation with skopeo 403 # END actual tests 404 ############################################################################### 405 406 # vim: filetype=sh