mirror of
https://github.com/containers/ansible-podman-collections.git
synced 2026-02-04 07:11:49 +00:00
1666 lines
53 KiB
YAML
1666 lines
53 KiB
YAML
- name: Test podman_container
|
|
block:
|
|
|
|
- name: Discover podman version
|
|
shell: podman version | grep "^Version:" | awk {'print $2'}
|
|
register: podman_v
|
|
|
|
- name: Set podman version to 3
|
|
set_fact:
|
|
podman_version: 3
|
|
when: podman_v.stdout is version('4.0.0', 'lt')
|
|
|
|
- name: Set podman version to 4
|
|
set_fact:
|
|
podman_version: 4
|
|
when: podman_v.stdout is version('4.0.0', '>=')
|
|
|
|
- name: Set podman version to 5
|
|
set_fact:
|
|
podman_version: 5
|
|
when: podman_v.stdout is version('5.0.0', '>=')
|
|
|
|
- name: Delete all container leftovers from tests
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: "{{ item }}"
|
|
state: absent
|
|
loop:
|
|
- "alpine:3.7"
|
|
- "container"
|
|
- "container1"
|
|
- "container2"
|
|
- "container3"
|
|
- "testidem-pod"
|
|
|
|
- name: Test no image with default action
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
ignore_errors: true
|
|
register: no_image
|
|
|
|
- name: Test no image with state 'started'
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: created
|
|
ignore_errors: true
|
|
register: no_image1
|
|
|
|
- name: Test no image with state 'present'
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: present
|
|
ignore_errors: true
|
|
register: no_image2
|
|
|
|
- name: Check no image
|
|
assert:
|
|
that:
|
|
- no_image is failed
|
|
- no_image1 is failed
|
|
- no_image2 is failed
|
|
- no_image.msg == "Cannot start container when image is not specified!"
|
|
- no_image1.msg == "State 'created' required image to be configured!"
|
|
- no_image2.msg == "State 'present' required image to be configured!"
|
|
fail_msg: No image test failed!
|
|
success_msg: No image test passed!
|
|
|
|
- name: Ensure image doesn't exist
|
|
containers.podman.podman_image:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: alpine:3.7
|
|
state: absent
|
|
|
|
- name: Check pulling image
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: alpine:3.7
|
|
state: started
|
|
command: sleep 1d
|
|
register: image
|
|
|
|
- name: Check using already pulled image
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container2
|
|
image: alpine:3.7
|
|
state: started
|
|
command: sleep 1d
|
|
register: image2
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- image is changed
|
|
- image.container is defined
|
|
- image.container['State']['Running']
|
|
- "'pulled image alpine:3.7' in image.actions"
|
|
- "'started container' in image.actions"
|
|
- image2 is changed
|
|
- image2.container is defined
|
|
- image2.container['State']['Running']
|
|
- "'pulled image alpine:3.7' not in image2.actions"
|
|
- "'started container2' in image2.actions"
|
|
fail_msg: Pulling image test failed!
|
|
success_msg: Pulling image test passed!
|
|
|
|
- name: Ensure image doesn't exist - TLS verify OFF
|
|
containers.podman.podman_image:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: alpine:3.20
|
|
state: absent
|
|
|
|
- name: Check pulling image - TLS verify OFF
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container_tls
|
|
image: alpine:3.20
|
|
state: started
|
|
command: sleep 1d
|
|
tls_verify: false
|
|
register: image_tls
|
|
|
|
- name: Check output is correct - TLS verify OFF
|
|
assert:
|
|
that:
|
|
- image_tls.podman_actions | select('search', '--tls-verify=False') | list | length > 0
|
|
|
|
- name: Check using already pulled image - TLS verify OFF
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container2_tls
|
|
image: alpine:3.20
|
|
state: started
|
|
command: sleep 1d
|
|
tls_verify: false
|
|
register: image2_tls
|
|
|
|
- name: Check output is correct - TLS verify OFF
|
|
assert:
|
|
that:
|
|
- image_tls is changed
|
|
- image_tls.container is defined
|
|
- image_tls.container['State']['Running']
|
|
- "'pulled image alpine:3.20' in image_tls.actions"
|
|
- "'started container_tls' in image_tls.actions"
|
|
- image2_tls is changed
|
|
- image2_tls.container is defined
|
|
- image2_tls.container['State']['Running']
|
|
- "'pulled image alpine:3.20' not in image2_tls.actions"
|
|
- "'started container2_tls' in image2_tls.actions"
|
|
fail_msg: Pulling image test failed!
|
|
success_msg: Pulling image test passed!
|
|
|
|
- name: Check failed image pull
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: ineverneverneverexist
|
|
state: started
|
|
command: sleep 1d
|
|
register: imagefail
|
|
ignore_errors: true
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- imagefail is failed
|
|
- imagefail.msg == "Can't pull image ineverneverneverexist"
|
|
|
|
- name: Force container recreate
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: alpine
|
|
state: started
|
|
command: sleep 1d
|
|
recreate: true
|
|
register: recreated
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- recreated is changed
|
|
- recreated.container is defined
|
|
- recreated.container['State']['Running']|bool
|
|
- "'recreated container' in recreated.actions"
|
|
fail_msg: Force recreate test failed!
|
|
success_msg: Force recreate test passed!
|
|
|
|
- name: Start container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: started
|
|
|
|
- name: Present container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: alpine
|
|
state: present
|
|
command: sleep 1d
|
|
register: start_present
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- start_present.container['State']['Running']
|
|
|
|
- name: Stop container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: stopped
|
|
register: stopped
|
|
|
|
- name: Stop the same container again (idempotency)
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: stopped
|
|
register: stopped_again
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- stopped is changed
|
|
- stopped.container is defined
|
|
- not stopped.container['State']['Running']
|
|
- "'stopped container' in stopped.actions"
|
|
- stopped_again is not changed
|
|
- stopped_again.container is defined
|
|
- not stopped_again.container['State']['Running']
|
|
- stopped_again.actions == []
|
|
fail_msg: Stopping container test failed!
|
|
success_msg: Stopping container test passed!
|
|
|
|
- name: Delete stopped container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: absent
|
|
register: deleted
|
|
|
|
- name: Delete again container (idempotency)
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: absent
|
|
register: deleted_again
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- deleted is changed
|
|
- deleted.container is defined
|
|
- deleted.container == {}
|
|
- "'deleted container' in deleted.actions"
|
|
- deleted_again is not changed
|
|
- deleted_again.container is defined
|
|
- deleted_again.container == {}
|
|
- deleted_again.actions == []
|
|
fail_msg: Deleting stopped container test failed!
|
|
success_msg: Deleting stopped container test passed!
|
|
|
|
- name: Create container in 'stopped' state
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: alpine:3.7
|
|
state: stopped
|
|
command: sleep 1d
|
|
register: created
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- created is changed
|
|
- created.container is defined
|
|
- created.container != {}
|
|
- not created.container['State']['Running']
|
|
- "'created container' in created.actions"
|
|
fail_msg: "Creating stopped container test failed!"
|
|
success_msg: "Creating stopped container test passed!"
|
|
|
|
- name: Force recreate stopped container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: alpine:3.7
|
|
state: started
|
|
command: sleep 1d
|
|
recreate: true
|
|
register: recreate_stopped
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- recreate_stopped is changed
|
|
- recreate_stopped.container is defined
|
|
- recreate_stopped.container['State']['Running']|bool
|
|
- "'recreated container' in recreate_stopped.actions"
|
|
fail_msg: Force recreate stopped test failed!
|
|
success_msg: Force recreate stopped test passed!
|
|
|
|
- name: Delete created container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: absent
|
|
|
|
- name: Create container in 'created' state
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: alpine:3.7
|
|
state: created
|
|
command: sleep 1d
|
|
register: created
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- created is changed
|
|
- created.container is defined
|
|
- created.container != {}
|
|
- not created.container['State']['Running']
|
|
- "'created container' in created.actions"
|
|
fail_msg: "Creating stopped container test failed!"
|
|
success_msg: "Creating stopped container test passed!"
|
|
|
|
- name: Force container recreate
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: alpine
|
|
state: created
|
|
command: sleep 1d
|
|
recreate: true
|
|
register: recreated
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- recreated is changed
|
|
- recreated.container is defined
|
|
- not recreated.container['State']['Running']
|
|
- "'recreated container' in recreated.actions"
|
|
fail_msg: Force recreate test failed!
|
|
|
|
- name: Restart container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
restart: true
|
|
register: restarted
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- restarted is changed
|
|
- restarted.container is defined
|
|
- restarted.container['State']['Running']
|
|
- "'restarted container' in restarted.actions"
|
|
fail_msg: Restart container test failed!
|
|
|
|
- name: Restart running container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
restart: true
|
|
register: restarted
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- restarted is changed
|
|
- restarted.container is defined
|
|
- restarted.container['State']['Running']
|
|
- "'restarted container' in restarted.actions"
|
|
fail_msg: Restart running container test failed!
|
|
|
|
- name: Delete created container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: absent
|
|
|
|
- name: Start container that was deleted
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: alpine:3.7
|
|
state: started
|
|
command: sleep 1d
|
|
register: started
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- started is changed
|
|
- started.container is defined
|
|
- started.container['State']['Running']
|
|
- "'pulled image alpine:3.7' not in started.actions"
|
|
|
|
- name: Delete started container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: absent
|
|
register: deleted
|
|
|
|
- name: Delete again container (idempotency)
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: absent
|
|
register: deleted_again
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- deleted is changed
|
|
- deleted.container is defined
|
|
- deleted.container == {}
|
|
- "'deleted container' in deleted.actions"
|
|
- deleted_again is not changed
|
|
- deleted_again.container is defined
|
|
- deleted_again.container == {}
|
|
- deleted_again.actions == []
|
|
fail_msg: Deleting started container test failed!
|
|
success_msg: Deleting started container test passed!
|
|
|
|
- name: Create container with security_opt
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: docker.io/alpine:3.7
|
|
state: started
|
|
command: sleep 1d
|
|
security_opt:
|
|
- label=level:s0
|
|
- label=type:spc_t
|
|
- label=filetype:container_share_t
|
|
- seccomp=unconfined
|
|
|
|
- name: Recreate container with same security_opt flags
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: docker.io/alpine:3.7
|
|
state: started
|
|
command: sleep 1d
|
|
security_opt:
|
|
- label=level:s0
|
|
- label=type:spc_t
|
|
- label=filetype:container_share_t
|
|
- seccomp=unconfined
|
|
register: recreate_security_opt
|
|
|
|
- name: Check if output is correct
|
|
assert:
|
|
that:
|
|
- recreate_security_opt is not changed
|
|
- recreate_security_opt.container is defined
|
|
- recreate_security_opt.container != {}
|
|
- recreate_security_opt.container['State']['Running']
|
|
- "'recreated container' not in recreate_security_opt.actions"
|
|
|
|
- name: Remove container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
state: absent
|
|
|
|
- name: Recreate container with parameters
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: docker.io/alpine:3.7
|
|
state: started
|
|
command: sleep 1d
|
|
recreate: true
|
|
etc_hosts:
|
|
host1: 127.0.0.1
|
|
host2: 127.0.0.1
|
|
annotation:
|
|
this: "annotation_value"
|
|
dns:
|
|
- 1.1.1.1
|
|
- 8.8.4.4
|
|
dns_search: example.com
|
|
cap_add:
|
|
- SYS_TIME
|
|
- NET_ADMIN
|
|
publish:
|
|
- "9000:80"
|
|
- "9001:8000"
|
|
workdir: "/bin"
|
|
env:
|
|
FOO: bar=1
|
|
BAR: foo
|
|
TEST: 1
|
|
BOOL: false
|
|
label:
|
|
somelabel: labelvalue
|
|
otheralbe: othervalue
|
|
volumes:
|
|
- /tmp:/data
|
|
mounts:
|
|
- type=devpts,destination=/dev/pts
|
|
register: test
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- test is changed
|
|
- test.container is defined
|
|
- test.container != {}
|
|
- test.container['State']['Running']
|
|
# test capabilities
|
|
- "'CAP_SYS_TIME' in test.container['BoundingCaps']"
|
|
- "'CAP_NET_ADMIN' in test.container['BoundingCaps']"
|
|
# test annotations
|
|
- test.container['Config']['Annotations']['this'] is defined
|
|
- test.container['Config']['Annotations']['this'] == "annotation_value"
|
|
# test DNS
|
|
- >-
|
|
(test.container['HostConfig']['Dns'] is defined and
|
|
test.container['HostConfig']['Dns'] == ['1.1.1.1', '8.8.4.4']) or
|
|
(test.container['HostConfig']['DNS'] is defined and
|
|
test.container['HostConfig']['DNS'] == ['1.1.1.1', '8.8.4.4'])
|
|
# test ports
|
|
- test.container['NetworkSettings']['Ports']|length == 2
|
|
# test working dir
|
|
- test.container['Config']['WorkingDir'] == "/bin"
|
|
# test dns search
|
|
- >-
|
|
(test.container['HostConfig']['DnsSearch'] is defined and
|
|
test.container['HostConfig']['DnsSearch'] == ['example.com']) or
|
|
(test.container['HostConfig']['DNSSearch'] is defined and
|
|
test.container['HostConfig']['DNSSearch'] == ['example.com'])
|
|
# test environment variables
|
|
- "'FOO=bar=1' in test.container['Config']['Env']"
|
|
- "'BAR=foo' in test.container['Config']['Env']"
|
|
- "'TEST=1' in test.container['Config']['Env']"
|
|
- "'BOOL=False' in test.container['Config']['Env']"
|
|
# test labels
|
|
- test.container['Config']['Labels'] | length == 2
|
|
- test.container['Config']['Labels']['somelabel'] == "labelvalue"
|
|
- test.container['Config']['Labels']['otheralbe'] == "othervalue"
|
|
# test mounts
|
|
- test.container['Mounts'][0]['Type'] is defined and test.container['Mounts'][0]['Type'] == 'bind'
|
|
- >-
|
|
test.container['Mounts'][0]['Source'] is defined and test.container['Mounts'][0]['Source'] == 'devpts' or
|
|
test.container['Mounts'][1]['Source'] is defined and test.container['Mounts'][1]['Source'] == 'devpts'
|
|
- >-
|
|
test.container['Mounts'][0]['Destination'] is defined and test.container['Mounts'][0]['Destination'] == '/dev/pts' or
|
|
test.container['Mounts'][1]['Destination'] is defined and test.container['Mounts'][1]['Destination'] == '/dev/pts'
|
|
# test volumes
|
|
# test volumes
|
|
- >-
|
|
(test.container['Mounts'][0]['Destination'] is defined and
|
|
'/data' in test.container['Mounts'] | map(attribute='Destination') | list)
|
|
- >-
|
|
(test.container['Mounts'][1]['Source'] is defined and
|
|
'/tmp' in test.container['Mounts'] | map(attribute='Source') | list)
|
|
fail_msg: Parameters container test failed!
|
|
success_msg: Parameters container test passed!
|
|
|
|
- name: Check basic idempotency of running container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem
|
|
image: docker.io/alpine
|
|
state: started
|
|
command: sleep 20m
|
|
|
|
- name: Check basic idempotency of running container - run it again
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem
|
|
image: alpine:latest
|
|
state: started
|
|
command: sleep 20m
|
|
register: idem
|
|
|
|
- name: Check that nothing was changed
|
|
assert:
|
|
that:
|
|
- not idem.changed
|
|
|
|
- name: Check force restart option - run again and force restart
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem
|
|
image: alpine:latest
|
|
state: started
|
|
command: sleep 20m
|
|
force_restart: true
|
|
register: idem_r
|
|
|
|
- name: Check that task was changed
|
|
assert:
|
|
that:
|
|
- idem_r is changed
|
|
|
|
- name: Check removing force_restart option
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem
|
|
image: alpine:latest
|
|
state: started
|
|
command: sleep 20m
|
|
register: idem_r1
|
|
|
|
- name: Check that task was not changed
|
|
assert:
|
|
that:
|
|
- idem_r1 is not changed
|
|
|
|
- name: Run changed container (with tty enabled)
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem
|
|
image: alpine
|
|
state: started
|
|
command: sleep 20m
|
|
tty: true
|
|
register: idem1
|
|
|
|
- name: Check that container is recreated when changed
|
|
assert:
|
|
that:
|
|
- idem1 is changed
|
|
|
|
- name: Run changed container without specifying an option, use defaults
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem
|
|
image: alpine
|
|
state: started
|
|
command: sleep 20m
|
|
register: idem2
|
|
|
|
- name: Check that container is recreated when changed to default value
|
|
assert:
|
|
that:
|
|
- idem2 is changed
|
|
|
|
- name: Remove container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem
|
|
state: absent
|
|
register: remove
|
|
|
|
- name: Check podman_actions
|
|
assert:
|
|
that:
|
|
- "'podman rm --force testidem' in remove.podman_actions"
|
|
|
|
# - name: Create a pod
|
|
# shell: podman pod create --name testidempod
|
|
|
|
- name: Check basic idempotency of pod container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem-pod
|
|
image: docker.io/alpine
|
|
state: started
|
|
command: sleep 20m
|
|
pod: "new:testidempod"
|
|
|
|
- name: Check basic idempotency of pod container - run it again
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem-pod
|
|
image: alpine:latest
|
|
state: started
|
|
command: sleep 20m
|
|
pod: testidempod
|
|
register: idem3
|
|
|
|
- name: Check that nothing was changed in pod containers
|
|
assert:
|
|
that:
|
|
- not idem3.changed
|
|
|
|
- name: Run changed pod container (with tty enabled)
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem-pod
|
|
image: alpine
|
|
state: started
|
|
command: sleep 20m
|
|
tty: true
|
|
pod: testidempod
|
|
register: idem4
|
|
|
|
- name: Check that container is recreated when changed
|
|
assert:
|
|
that:
|
|
- idem4 is changed
|
|
- idem4.podman_systemd.keys() | list | length > 0
|
|
- idem4.podman_systemd.values() | list | length > 0
|
|
|
|
- name: Run container with systemd generation parameters v4
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine
|
|
state: started
|
|
command: sleep 20m
|
|
generate_systemd:
|
|
path: /tmp/
|
|
restart_policy: always
|
|
no_header: true
|
|
names: true
|
|
pod_prefix: whocares
|
|
separator: zzzz
|
|
container_prefix: contain
|
|
restart_sec: 10
|
|
start_timeout: 20
|
|
stop_timeout: 15
|
|
register: system14
|
|
when: podman_version == 4
|
|
|
|
- name: Run container with systemd generation parameters v3
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine
|
|
state: started
|
|
command: sleep 20m
|
|
generate_systemd:
|
|
path: /tmp/
|
|
time: 120
|
|
restart_policy: always
|
|
no_header: true
|
|
names: true
|
|
pod_prefix: whocares
|
|
separator: zzzz
|
|
container_prefix: contain
|
|
register: system13
|
|
when: podman_version == 3
|
|
|
|
- name: Check service file presents
|
|
stat:
|
|
path: /tmp/containzzzzcontainer1.service
|
|
register: service_file
|
|
|
|
- name: Check that container has correct systemd output v4 and quadlet
|
|
assert:
|
|
that:
|
|
- system14.podman_systemd.keys() | list | first == 'containzzzzcontainer1'
|
|
- system14.podman_systemd.values() | list | length > 0
|
|
- service_file.stat.exists | bool
|
|
- "'Restart=always' in system14.podman_systemd.values() | list | first"
|
|
- "'autogenerated by Podman' not in system14.podman_systemd.values() | list | first"
|
|
- "'RestartSec=10' in system14.podman_systemd.values() | list | first"
|
|
- "'TimeoutStartSec=20' in system14.podman_systemd.values() | list | first"
|
|
- system14.podman_quadlet | length > 0
|
|
- system14.podman_quadlet | length > 0
|
|
- "'ContainerName=container1' in system14.podman_quadlet"
|
|
- "'Image=alpine' in system14.podman_quadlet"
|
|
|
|
when: podman_version == 4
|
|
|
|
- name: Check that container has correct systemd output v3
|
|
assert:
|
|
that:
|
|
- system13.podman_systemd.keys() | list | first == 'containzzzzcontainer1'
|
|
- system13.podman_systemd.values() | list | length > 0
|
|
- service_file.stat.exists | bool
|
|
- "'Restart=always' in system13.podman_systemd.values() | list | first"
|
|
- "'autogenerated by Podman' not in system13.podman_systemd.values() | list | first"
|
|
- "'-t 120 ' in system13.podman_systemd.values() | list | first"
|
|
when: podman_version == 3
|
|
|
|
- name: Delete container with systemd generation parameters v3
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine
|
|
state: absent
|
|
command: sleep 20m
|
|
generate_systemd:
|
|
path: /tmp/
|
|
time: 120
|
|
restart_policy: always
|
|
no_header: true
|
|
names: true
|
|
pod_prefix: whocares
|
|
separator: zzzz
|
|
container_prefix: contain
|
|
register: system1
|
|
when: podman_version == 3
|
|
|
|
- name: Delete container with systemd generation parameters v4
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine
|
|
state: absent
|
|
command: sleep 20m
|
|
generate_systemd:
|
|
path: /tmp/
|
|
restart_policy: always
|
|
no_header: true
|
|
names: true
|
|
pod_prefix: whocares
|
|
separator: zzzz
|
|
container_prefix: contain
|
|
restart_sec: 10
|
|
start_timeout: 20
|
|
stop_timeout: 15
|
|
register: system1
|
|
when: podman_version == 4
|
|
|
|
- name: Check service file doesn't present
|
|
stat:
|
|
path: /tmp/containzzzzcontainer1.service
|
|
register: service2_file
|
|
|
|
- name: Check that service file was deleted
|
|
assert:
|
|
that:
|
|
- not service2_file.stat.exists | bool
|
|
|
|
- name: Create environment variables files
|
|
copy:
|
|
dest: /tmp/envfile
|
|
content: |
|
|
FOO=bar
|
|
BAR=foo
|
|
TEST=1
|
|
BOOL=false
|
|
|
|
- name: Create another environment variables files
|
|
copy:
|
|
dest: /tmp/envfile2
|
|
content: |
|
|
TESTVAR=qwerty
|
|
|
|
- name: Create container with environment variables file
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine
|
|
state: started
|
|
command:
|
|
- sh
|
|
- -c
|
|
- echo $BAR
|
|
attach:
|
|
- stdout
|
|
- stderr
|
|
env_file: /tmp/envfile
|
|
register: envfile
|
|
|
|
- name: Check output is correct for env file
|
|
assert:
|
|
that:
|
|
- envfile.stdout == "foo\n"
|
|
|
|
- name: Create container with multiple environment variables files
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine
|
|
state: started
|
|
command:
|
|
- sh
|
|
- -c
|
|
- echo $TESTVAR
|
|
attach:
|
|
- stdout
|
|
- stderr
|
|
env_file:
|
|
- /tmp/envfile
|
|
- /tmp/envfile2
|
|
register: envfile2
|
|
|
|
- name: Check output is correct for multiple env files
|
|
assert:
|
|
that:
|
|
- envfile2.stdout == "qwerty\n"
|
|
|
|
- name: Delete container with environment variables file
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
state: absent
|
|
|
|
- name: Rootfs container tests
|
|
tags:
|
|
- no_build_version
|
|
block:
|
|
|
|
- name: Create temporary rootfs directory
|
|
ansible.builtin.tempfile:
|
|
state: directory
|
|
suffix: container-rootfs
|
|
register: container_tempdir
|
|
- name: Debug container_tempdir
|
|
ansible.builtin.debug:
|
|
var: container_tempdir
|
|
|
|
|
|
- name: Download alpine releases file
|
|
ansible.builtin.get_url:
|
|
url: "https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/{{ ansible_architecture }}/latest-releases.yaml"
|
|
dest: "{{ container_tempdir.path }}/latest-releases.yaml"
|
|
register: alpine_releases_file
|
|
|
|
- name: Get content of alpine releases file
|
|
ansible.builtin.slurp:
|
|
src: "{{ container_tempdir.path }}/latest-releases.yaml"
|
|
register: latest_releases_file
|
|
|
|
- name: Download alpine latest rootfs
|
|
vars:
|
|
latest_releases: "{{ latest_releases_file.content | b64decode }}"
|
|
latest_version: "{{ (latest_releases | from_yaml)[0].version }}"
|
|
latest_branch: "{{ (latest_releases | from_yaml)[0].branch }}"
|
|
ansible.builtin.unarchive:
|
|
src: "https://dl-cdn.alpinelinux.org/alpine/{{ latest_branch }}/releases/{{ ansible_architecture }}/alpine-minirootfs-{{ latest_version }}-{{ ansible_architecture }}.tar.gz"
|
|
dest: "{{ container_tempdir.path }}"
|
|
remote_src: true
|
|
|
|
- name: Check invalid rootfs image pull
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container
|
|
image: /ineverneverneverexist
|
|
rootfs: true
|
|
state: started
|
|
command: sleep 1d
|
|
register: imagerootfsfail
|
|
ignore_errors: true
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- imagerootfsfail is failed
|
|
- imagerootfsfail.msg == "Image rootfs doesn't exist /ineverneverneverexist"
|
|
|
|
- name: Check rootfs container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container3
|
|
image: "{{ container_tempdir.path }}"
|
|
rootfs: true
|
|
state: started
|
|
command: sleep 1d
|
|
register: image
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- image is changed
|
|
- image.container is defined
|
|
- image.container['State']['Running']
|
|
- image.container['Image'] == ""
|
|
- image.container['Rootfs'] == container_tempdir.path
|
|
- "'started container3' in image.actions"
|
|
fail_msg: Rootfs container test failed!
|
|
success_msg: Rootfs container test passed!
|
|
|
|
- name: Check basic idempotency of running rootfs container - run it again
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container3
|
|
image: "{{ container_tempdir.path }}"
|
|
rootfs: true
|
|
state: started
|
|
command: sleep 1d
|
|
register: idem
|
|
|
|
- name: Check that nothing was changed
|
|
assert:
|
|
that:
|
|
- not idem.changed
|
|
|
|
- name: Rebuild rootfs container with image
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container3
|
|
image: alpine:3.7
|
|
state: started
|
|
command: sleep 1d
|
|
register: image
|
|
|
|
- name: Debug image
|
|
ansible.builtin.debug:
|
|
var: image
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- image is changed
|
|
- image.container is defined
|
|
- image.container['State']['Running']
|
|
- image.container['Rootfs'] == ""
|
|
- "'alpine:3.7' in image.container['ImageName']"
|
|
- "'recreated container3' in image.actions"
|
|
fail_msg: Rootfs container test failed!
|
|
success_msg: Rootfs container test passed!
|
|
|
|
- name: Rebuild container with rootfs again
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container3
|
|
image: "{{ container_tempdir.path }}"
|
|
rootfs: true
|
|
state: started
|
|
command: sleep 1d
|
|
register: image
|
|
|
|
- name: Check output is correct
|
|
assert:
|
|
that:
|
|
- image is changed
|
|
- image.container is defined
|
|
- image.container['State']['Running']
|
|
- image.container['Image'] == ""
|
|
- image.container['Rootfs'] == container_tempdir.path
|
|
- "'recreated container3' in image.actions"
|
|
fail_msg: Rootfs container test failed!
|
|
success_msg: Rootfs container test passed!
|
|
|
|
- name: Run started container with attaching
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine:3.7
|
|
state: started
|
|
command: ls /nonexists
|
|
attach:
|
|
- stdout
|
|
- stderr
|
|
register: attach
|
|
ignore_errors: true
|
|
|
|
- name: Check output is correct for started container with attaching
|
|
assert:
|
|
that:
|
|
- attach is failed
|
|
- "'No such file or directory' in attach.stderr"
|
|
|
|
- name: Delete container with attaching
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
state: absent
|
|
|
|
- name: Create container with attaching in created state
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine:3.7
|
|
state: created
|
|
command: ls /nonexists
|
|
attach:
|
|
- stdout
|
|
- stderr
|
|
|
|
- name: Start container with attaching from created state
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
state: started
|
|
attach:
|
|
- stdout
|
|
- stderr
|
|
register: attach2
|
|
ignore_errors: true
|
|
|
|
- name: Check output is correct for started container with attaching from created state
|
|
assert:
|
|
that:
|
|
- attach2 is failed
|
|
- "'No such file or directory' in attach2.stderr"
|
|
|
|
- name: Delete container with attaching from created state
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
state: absent
|
|
|
|
- name: Create container without attaching in created state
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine:3.7
|
|
state: created
|
|
command: ls /nonexists
|
|
|
|
- name: Start container without attaching from created state
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
state: started
|
|
register: attach21
|
|
|
|
- name: Check output is correct for container without attaching from created state
|
|
assert:
|
|
that:
|
|
- attach21 is success
|
|
|
|
- name: Delete container without attaching from created state
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
state: absent
|
|
|
|
- name: Create container with detach False
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
image: alpine:3.7
|
|
state: created
|
|
command: ls /nonexists
|
|
detach: false
|
|
|
|
- name: Start container with detach False
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container1
|
|
state: started
|
|
detach: false
|
|
register: attach3
|
|
ignore_errors: true
|
|
|
|
- name: Check output is correct for started container with detach False
|
|
assert:
|
|
that:
|
|
- attach3 is failed
|
|
- "'No such file or directory' in attach3.stderr"
|
|
|
|
- name: Create a Quadlet for container with filename
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet
|
|
image: alpine
|
|
state: quadlet
|
|
quadlet_dir: /tmp
|
|
quadlet_filename: customfile
|
|
|
|
- name: Check if files exists
|
|
stat:
|
|
path: /tmp/customfile.container
|
|
register: quadlet_file_custom
|
|
|
|
- name: Fail if no file is present
|
|
assert:
|
|
that:
|
|
- quadlet_file_custom.stat.exists
|
|
|
|
- name: Create a Quadlet for container with filename w/o dir
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet
|
|
image: alpine
|
|
state: quadlet
|
|
quadlet_filename: container11.container
|
|
|
|
- name: Check if files exists
|
|
stat:
|
|
path: ~/.config/containers/systemd/container11.container
|
|
register: quadlet_file_custom2
|
|
|
|
- name: Fail if no file is present
|
|
assert:
|
|
that:
|
|
- quadlet_file_custom2.stat.exists
|
|
|
|
- name: Create a Quadlet for container with filename w/o dir
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet
|
|
image: alpine
|
|
state: quadlet
|
|
|
|
- name: Check if files exists
|
|
stat:
|
|
path: ~/.config/containers/systemd/container-quadlet.container
|
|
register: quadlet_file_custom3
|
|
|
|
- name: Fail if no file is present
|
|
assert:
|
|
that:
|
|
- quadlet_file_custom3.stat.exists
|
|
|
|
- name: Fail if wrong default file mode
|
|
assert:
|
|
that:
|
|
- quadlet_file_custom3.stat.mode == '0640'
|
|
|
|
- name: Create a Quadlet for container with file mode
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet-mode
|
|
image: alpine
|
|
state: quadlet
|
|
quadlet_file_mode: '0644'
|
|
|
|
- name: Check file mode
|
|
stat:
|
|
path: ~/.config/containers/systemd/container-quadlet-mode.container
|
|
register: quadlet_file_mode1
|
|
|
|
- name: Fail if file is present and with correct mode
|
|
assert:
|
|
that:
|
|
- quadlet_file_mode1.stat.exists
|
|
- quadlet_file_mode1.stat.mode == '0644'
|
|
|
|
- name: Create same Quadlet for container without file mode
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet-mode
|
|
image: alpine
|
|
state: quadlet
|
|
register: quad_mode2
|
|
|
|
- name: Check file mode
|
|
stat:
|
|
path: ~/.config/containers/systemd/container-quadlet-mode.container
|
|
register: quadlet_file_mode2
|
|
|
|
- name: Check if existing mode is preserve
|
|
assert:
|
|
that:
|
|
- quad_mode2 is not changed
|
|
- quadlet_file_mode2.stat.mode == '0644'
|
|
|
|
- name: Create same Quadlet for container with only file mode changed
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet-mode
|
|
image: alpine
|
|
state: quadlet
|
|
quadlet_file_mode: '0640'
|
|
register: quad_mode3
|
|
|
|
- name: Check file mode
|
|
stat:
|
|
path: ~/.config/containers/systemd/container-quadlet-mode.container
|
|
register: quadlet_file_mode3
|
|
|
|
- name: Fail if file is present and with correct mode
|
|
assert:
|
|
that:
|
|
- quad_mode3 is changed
|
|
- quadlet_file_mode3.stat.mode == '0640'
|
|
|
|
- name: Create a Quadlet for container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet
|
|
image: alpine:3.12
|
|
state: quadlet
|
|
quadlet_dir: /tmp
|
|
command: sleep 1d
|
|
recreate: true
|
|
stop_signal: 9 #SIGKILL
|
|
group_add:
|
|
- admin
|
|
- users
|
|
etc_hosts:
|
|
host1: 127.0.0.1
|
|
host2: 127.0.0.1
|
|
network_aliases:
|
|
- web
|
|
- db
|
|
cpus: 0.5
|
|
platform: linux/amd64
|
|
annotation:
|
|
this: "annotation_value"
|
|
dns:
|
|
- 1.1.1.1
|
|
- 8.8.4.4
|
|
dns_search: example.com
|
|
cap_add:
|
|
- SYS_TIME
|
|
- NET_ADMIN
|
|
publish:
|
|
- "9000:80"
|
|
- "9001:8000"
|
|
workdir: "/bin"
|
|
env:
|
|
FOO: bar=1
|
|
BAR: foo
|
|
TEST: 1
|
|
BOOL: false
|
|
WITH_SPACES: "a nice string"
|
|
label:
|
|
somelabel: labelvalue
|
|
otheralbe: othervalue
|
|
spacelabel: "a nice label"
|
|
log_opt:
|
|
max_size: 10mb
|
|
path: /var/log/container/mycontainer.json
|
|
tag: TestTag
|
|
volumes:
|
|
- /tmp:/data
|
|
cgroups: no-conmon
|
|
mounts:
|
|
- type=devpts,destination=/dev/pts
|
|
quadlet_options:
|
|
- AutoUpdate=registry
|
|
- Unmask=ALL
|
|
- SecurityLabelFileType=usr_t
|
|
- Annotation=key1=annotation_value1
|
|
- Annotation=key2=annotation_value2
|
|
- |
|
|
[Install]
|
|
WantedBy=default.target
|
|
|
|
- name: Check if files exists
|
|
stat:
|
|
path: /tmp/container-quadlet.container
|
|
register: quadlet_file
|
|
|
|
- name: Check output is correct for Quadlet container in /tmp/container-quadlet.container file
|
|
assert:
|
|
that:
|
|
- quadlet_file.stat.exists
|
|
|
|
- name: Check for the existence of lines in /tmp/container-quadlet.container
|
|
lineinfile:
|
|
path: /tmp/container-quadlet.container
|
|
line: "{{ item }}"
|
|
state: present
|
|
check_mode: yes
|
|
register: line_check
|
|
loop:
|
|
- "[Container]"
|
|
- "Annotation=this=annotation_value"
|
|
- "Annotation=key1=annotation_value1"
|
|
- "Annotation=key2=annotation_value2"
|
|
- "ContainerName=container-quadlet"
|
|
- "Image=alpine:3.12"
|
|
- "Exec=sleep 1d"
|
|
- "Volume=/tmp:/data"
|
|
- "CgroupsMode=no-conmon"
|
|
- "Mount=type=devpts,destination=/dev/pts"
|
|
- "WorkingDir=/bin"
|
|
- "Unmask=ALL"
|
|
- "SecurityLabelFileType=usr_t"
|
|
- "Environment=BOOL=False"
|
|
- "Environment='WITH_SPACES=a nice string'"
|
|
- "PublishPort=9001:8000"
|
|
- "AddHost=host2:127.0.0.1"
|
|
- "Label=somelabel=labelvalue"
|
|
- "Label='spacelabel=a nice label'"
|
|
- "WantedBy=default.target"
|
|
- "GroupAdd=admin"
|
|
- "GroupAdd=users"
|
|
- "NetworkAlias=web"
|
|
- "NetworkAlias=db"
|
|
- "StopSignal=9"
|
|
- "PodmanArgs=--cpus 0.5"
|
|
- "PodmanArgs=--platform linux/amd64"
|
|
- "LogOpt=max-size=10mb"
|
|
- "LogOpt=path=/var/log/container/mycontainer.json"
|
|
- "LogOpt=tag=TestTag"
|
|
loop_control:
|
|
label: "{{ item }}"
|
|
|
|
- name: Fail the task if any line is not present
|
|
fail:
|
|
msg: "The following line is not present in /tmp/container-quadlet.container: {{ item.item }}"
|
|
when: item.changed
|
|
loop: "{{ line_check.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Create a Quadlet for container - same
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet
|
|
image: alpine:3.12
|
|
state: quadlet
|
|
quadlet_dir: /tmp
|
|
command: sleep 1d
|
|
recreate: true
|
|
stop_signal: 9 #SIGKILL
|
|
group_add:
|
|
- admin
|
|
- users
|
|
etc_hosts:
|
|
host1: 127.0.0.1
|
|
host2: 127.0.0.1
|
|
network_aliases:
|
|
- web
|
|
- db
|
|
cpus: 0.5
|
|
platform: linux/amd64
|
|
annotation:
|
|
this: "annotation_value"
|
|
dns:
|
|
- 1.1.1.1
|
|
- 8.8.4.4
|
|
dns_search: example.com
|
|
cap_add:
|
|
- SYS_TIME
|
|
- NET_ADMIN
|
|
publish:
|
|
- "9000:80"
|
|
- "9001:8000"
|
|
workdir: "/bin"
|
|
env:
|
|
FOO: bar=1
|
|
BAR: foo
|
|
TEST: 1
|
|
BOOL: false
|
|
WITH_SPACES: "a nice string"
|
|
label:
|
|
somelabel: labelvalue
|
|
otheralbe: othervalue
|
|
spacelabel: "a nice label"
|
|
log_opt:
|
|
max_size: 10mb
|
|
path: /var/log/container/mycontainer.json
|
|
tag: TestTag
|
|
volumes:
|
|
- /tmp:/data
|
|
cgroups: no-conmon
|
|
mounts:
|
|
- type=devpts,destination=/dev/pts
|
|
quadlet_options:
|
|
- AutoUpdate=registry
|
|
- Unmask=ALL
|
|
- SecurityLabelFileType=usr_t
|
|
- Annotation=key1=annotation_value1
|
|
- Annotation=key2=annotation_value2
|
|
- |
|
|
[Install]
|
|
WantedBy=default.target
|
|
register: quad2
|
|
|
|
- name: Check if quadlet changed
|
|
assert:
|
|
that:
|
|
- quad2 is not changed
|
|
|
|
- name: Create a Quadlet for container - different
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-quadlet
|
|
image: alpine:3.12
|
|
state: quadlet
|
|
quadlet_dir: /tmp
|
|
command: sleep 1d
|
|
recreate: true
|
|
stop_signal: 9 #SIGKILL
|
|
group_add:
|
|
- admin
|
|
- users
|
|
etc_hosts:
|
|
host1: 127.0.0.45
|
|
host2: 127.0.0.1
|
|
network_aliases:
|
|
- web
|
|
- db
|
|
cpus: 0.5
|
|
platform: linux/amd64
|
|
annotation:
|
|
this: "annotation_value"
|
|
dns:
|
|
- 1.1.1.1
|
|
- 8.8.4.4
|
|
dns_search: example.com
|
|
cap_add:
|
|
- SYS_TIME
|
|
- NET_ADMIN
|
|
publish:
|
|
- "9000:80"
|
|
- "9001:8000"
|
|
workdir: "/bin"
|
|
env:
|
|
FOO: bar=1
|
|
BAR: foo
|
|
TEST: 1
|
|
BOOL: false
|
|
label:
|
|
somelabel: labelvalue
|
|
otheralbe: othervalue
|
|
log_opt:
|
|
max_size: 10mb
|
|
path: /var/log/container/mycontainer.json
|
|
tag: TestTag
|
|
volumes:
|
|
- /tmp:/data
|
|
cgroups: no-conmon
|
|
mounts:
|
|
- type=devpts,destination=/dev/pts
|
|
quadlet_options:
|
|
- AutoUpdate=registry
|
|
- Unmask=ALL
|
|
- SecurityLabelFileType=usr_t
|
|
- Annotation=key1=annotation_value1
|
|
- Annotation=key2=annotation_value2
|
|
- |
|
|
[Install]
|
|
WantedBy=default.target
|
|
register: quad3
|
|
|
|
- name: Print diff
|
|
debug:
|
|
var: quad3.diff
|
|
|
|
- name: Check if changed and diff
|
|
assert:
|
|
that:
|
|
- quad3 is changed
|
|
- "'127.0.0.45' in quad3.diff.after"
|
|
|
|
# Test for issue #913: restart_policy should go to [Service] section, not PodmanArgs
|
|
- name: Create a Quadlet for container with restart_policy
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-restart-test
|
|
image: alpine
|
|
state: quadlet
|
|
quadlet_dir: /tmp
|
|
restart_policy: always
|
|
register: quad_restart
|
|
|
|
- name: Check if Quadlet file contains [Service] section with Restart
|
|
shell: cat /tmp/container-restart-test.container
|
|
register: quad_restart_content
|
|
|
|
- name: Verify restart_policy is in [Service] section and not in PodmanArgs
|
|
assert:
|
|
that:
|
|
- quad_restart is changed
|
|
- "'[Service]' in quad_restart_content.stdout"
|
|
- "'Restart=always' in quad_restart_content.stdout"
|
|
- "'--restart' not in quad_restart_content.stdout"
|
|
fail_msg: "restart_policy should be in [Service] section, not as --restart in PodmanArgs"
|
|
|
|
- name: Test different restart policies
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: "container-restart-{{ item.name }}"
|
|
image: alpine
|
|
state: quadlet
|
|
quadlet_dir: /tmp
|
|
restart_policy: "{{ item.policy }}"
|
|
loop:
|
|
- { name: "on-failure", policy: "on-failure" }
|
|
- { name: "unless-stopped", policy: "unless-stopped" }
|
|
register: quad_restart_policies
|
|
|
|
- name: Verify all restart policies are correctly mapped
|
|
shell: cat /tmp/container-restart-{{ item.item.name }}.container
|
|
loop: "{{ quad_restart_policies.results }}"
|
|
register: quad_restart_files
|
|
|
|
- name: Check restart policy mapping
|
|
assert:
|
|
that:
|
|
- "'[Service]' in item.stdout"
|
|
- "'Restart=' in item.stdout"
|
|
- "'--restart' not in item.stdout"
|
|
loop: "{{ quad_restart_files.results }}"
|
|
|
|
# Test for issue #913: Verify no duplicate [Service] section when user provides custom one
|
|
- name: Create Quadlet with restart_policy and custom Service section in quadlet_options
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: container-restart-custom-service
|
|
image: alpine
|
|
state: quadlet
|
|
quadlet_dir: /tmp
|
|
restart_policy: always
|
|
command: sleep infinity
|
|
quadlet_options:
|
|
- |
|
|
[Service]
|
|
TimeoutStopSec=70
|
|
Restart=on-failure
|
|
register: quad_custom_service
|
|
|
|
- name: Read Quadlet file with custom Service section
|
|
shell: cat /tmp/container-restart-custom-service.container
|
|
register: quad_custom_service_content
|
|
|
|
- name: Count [Service] sections in Quadlet file
|
|
shell: grep -c "^\[Service\]" /tmp/container-restart-custom-service.container
|
|
register: service_section_count
|
|
failed_when: false
|
|
|
|
- name: Verify only one [Service] section exists (user's custom one takes precedence)
|
|
assert:
|
|
that:
|
|
- quad_custom_service is changed
|
|
- service_section_count.stdout == "1"
|
|
- "'TimeoutStopSec=70' in quad_custom_service_content.stdout"
|
|
- "'Restart=on-failure' in quad_custom_service_content.stdout"
|
|
- "'--restart' not in quad_custom_service_content.stdout"
|
|
fail_msg: "Should have exactly one [Service] section when user provides custom one"
|
|
|
|
- name: Cleanup restart test Quadlet files
|
|
file:
|
|
path: "{{ item }}"
|
|
state: absent
|
|
loop:
|
|
- /tmp/container-restart-test.container
|
|
- /tmp/container-restart-on-failure.container
|
|
- /tmp/container-restart-unless-stopped.container
|
|
- /tmp/container-restart-custom-service.container
|
|
|
|
always:
|
|
|
|
- name: Remove container
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidem-pod
|
|
state: absent
|
|
|
|
- name: Delete all container leftovers from tests
|
|
containers.podman.podman_container:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: "{{ item }}"
|
|
state: absent
|
|
loop:
|
|
- "alpine:3.7"
|
|
- "container"
|
|
- "container1"
|
|
- "container2"
|
|
- "container3"
|
|
- "testidem-pod"
|
|
- "container_tls"
|
|
- "container2_tls"
|
|
|
|
- name: Remove pod
|
|
containers.podman.podman_pod:
|
|
executable: "{{ test_executable | default('podman') }}"
|
|
name: testidempod
|
|
state: absent
|
|
|
|
- name: Remove podman images
|
|
containers.podman.podman_image:
|
|
name: "{{ item }}"
|
|
state: absent
|
|
loop:
|
|
- alpine:3.7
|
|
- alpine
|
|
- alpine:3.20
|
|
- alpine:3.12
|
|
|
|
- name: Remove temporary rootfs directory
|
|
ansible.builtin.file:
|
|
path: "{{ container_tempdir.path }}"
|
|
state: absent
|
|
when: container_tempdir is defined
|
|
ignore_errors: true
|