mirror of
https://github.com/containers/ansible-podman-collections.git
synced 2026-02-04 07:11:49 +00:00
Add podman_containers module for multiple containers (#141)
This commit is contained in:
parent
fecc0739d6
commit
2a84642c3f
5 changed files with 930 additions and 0 deletions
115
.github/workflows/podman_containers.yml
vendored
Normal file
115
.github/workflows/podman_containers.yml
vendored
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
name: Podman multi-containers
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/podman_containers.yml'
|
||||||
|
- 'ci/*.yml'
|
||||||
|
- 'ci/run_containers_tests.sh'
|
||||||
|
- 'ci/playbooks/containers/podman_containers.yml'
|
||||||
|
- 'plugins/modules/podman_container.py'
|
||||||
|
- 'plugins/modules/podman_containers.py'
|
||||||
|
- 'tests/integration/targets/podman_containers/**'
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/podman_containers.yml'
|
||||||
|
- 'ci/*.yml'
|
||||||
|
- 'ci/run_containers_tests.sh'
|
||||||
|
- 'ci/playbooks/containers/podman_container.yml'
|
||||||
|
- 'plugins/modules/podman_container.py'
|
||||||
|
- 'plugins/modules/podman_containers.py'
|
||||||
|
- 'tests/integration/targets/podman_containers/**'
|
||||||
|
schedule:
|
||||||
|
- cron: 4 0 * * * # Run daily at 0:03 UTC
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
test_podman_containers:
|
||||||
|
name: Podman multi containers ${{ matrix.ansible-version }}-${{ matrix.os || 'ubuntu-latest' }}
|
||||||
|
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ansible-version:
|
||||||
|
- ansible<2.10
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
python-version:
|
||||||
|
- 3.7
|
||||||
|
include:
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
ansible-version: ansible<2.11
|
||||||
|
python-version: 3.7
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
ansible-version: git+https://github.com/ansible/ansible.git@devel
|
||||||
|
python-version: 3.8
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
|
- name: Upgrade pip and display Python and PIP versions
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y python*-wheel python*-yaml
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -V
|
||||||
|
pip --version
|
||||||
|
|
||||||
|
- name: Set up pip cache
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ~/.cache/pip
|
||||||
|
key: ${{ runner.os }}-pip-${{ github.ref }}-units-VMs
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pip-
|
||||||
|
${{ runner.os }}-
|
||||||
|
|
||||||
|
- name: Install Ansible ${{ matrix.ansible-version }}
|
||||||
|
run: python3 -m pip install --user --force-reinstall --upgrade '${{ matrix.ansible-version }}'
|
||||||
|
|
||||||
|
- name: Build and install the collection tarball
|
||||||
|
run: |
|
||||||
|
export PATH=~/.local/bin:$PATH
|
||||||
|
|
||||||
|
echo "Run ansible version"
|
||||||
|
command -v ansible
|
||||||
|
ansible --version
|
||||||
|
rm -rf /tmp/just_new_collection
|
||||||
|
~/.local/bin/ansible-galaxy collection build --output-path /tmp/just_new_collection --force
|
||||||
|
~/.local/bin/ansible-galaxy collection install -vvv --force /tmp/just_new_collection/*.tar.gz
|
||||||
|
|
||||||
|
- name: Run collection tests for podman containers
|
||||||
|
run: |
|
||||||
|
export PATH=~/.local/bin:$PATH
|
||||||
|
|
||||||
|
if [[ '${{ matrix.ansible-version }}' == 'git+https://github.com/ansible/ansible.git@devel' ]]; then
|
||||||
|
export ANSIBLE_CONFIG=$(pwd)/ci/ansible-dev.cfg
|
||||||
|
elif [[ '${{ matrix.ansible-version }}' == 'ansible<2.10' ]]; then
|
||||||
|
export ANSIBLE_CONFIG=$(pwd)/ci/ansible-2.9.cfg
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $ANSIBLE_CONFIG
|
||||||
|
command -v ansible-playbook
|
||||||
|
pip --version
|
||||||
|
python --version
|
||||||
|
ansible-playbook --version
|
||||||
|
|
||||||
|
ansible-playbook -vv ci/playbooks/pre.yml \
|
||||||
|
-e host=localhost \
|
||||||
|
-i localhost, \
|
||||||
|
-e ansible_connection=local \
|
||||||
|
-e setup_python=false
|
||||||
|
|
||||||
|
TEST2RUN=podman_containers ./ci/run_containers_tests.sh
|
||||||
|
shell: bash
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -384,4 +384,6 @@ $RECYCLE.BIN/
|
||||||
# Windows shortcuts
|
# Windows shortcuts
|
||||||
*.lnk
|
*.lnk
|
||||||
|
|
||||||
|
# Custom
|
||||||
|
changelogs/.plugin-cache.yaml
|
||||||
# End of https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
# End of https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
||||||
|
|
|
||||||
9
ci/playbooks/containers/podman_containers.yml
Normal file
9
ci/playbooks/containers/podman_containers.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
gather_facts: true
|
||||||
|
tasks:
|
||||||
|
- include_role:
|
||||||
|
name: podman_containers
|
||||||
|
vars:
|
||||||
|
idem_image: idempotency_test
|
||||||
|
ansible_python_interpreter: "{{ _ansible_python_interpreter }}"
|
||||||
162
plugins/modules/podman_containers.py
Normal file
162
plugins/modules/podman_containers.py
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# Copyright (c) 2020 Red Hat
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
---
|
||||||
|
module: podman_containers
|
||||||
|
author:
|
||||||
|
- "Sagi Shnaidman (@sshnaidm)"
|
||||||
|
version_added: '1.4.0'
|
||||||
|
short_description: Manage podman containers in a batch
|
||||||
|
description:
|
||||||
|
- Manage groups of podman containers
|
||||||
|
requirements:
|
||||||
|
- "podman"
|
||||||
|
options:
|
||||||
|
containers:
|
||||||
|
description:
|
||||||
|
- List of dictionaries with data for running containers for podman_container module.
|
||||||
|
required: True
|
||||||
|
type: list
|
||||||
|
elements: dict
|
||||||
|
debug:
|
||||||
|
description:
|
||||||
|
- Return additional information which can be helpful for investigations.
|
||||||
|
type: bool
|
||||||
|
default: False
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
- name: Run three containers at once
|
||||||
|
podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: alpine
|
||||||
|
image: alpine
|
||||||
|
command: sleep 1d
|
||||||
|
- name: web
|
||||||
|
image: nginx
|
||||||
|
- name: test
|
||||||
|
image: python:3-alpine
|
||||||
|
command: python -V
|
||||||
|
'''
|
||||||
|
|
||||||
|
from copy import deepcopy # noqa: F402
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule # noqa: F402
|
||||||
|
from ..module_utils.podman.podman_container_lib import PodmanManager # noqa: F402
|
||||||
|
from ..module_utils.podman.podman_container_lib import ARGUMENTS_SPEC_CONTAINER # noqa: F402
|
||||||
|
|
||||||
|
|
||||||
|
def init_options():
|
||||||
|
default = {}
|
||||||
|
opts = ARGUMENTS_SPEC_CONTAINER
|
||||||
|
for k, v in opts.items():
|
||||||
|
if 'default' in v:
|
||||||
|
default[k] = v['default']
|
||||||
|
else:
|
||||||
|
default[k] = None
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def update_options(opts_dict, container):
|
||||||
|
aliases = {}
|
||||||
|
for k, v in ARGUMENTS_SPEC_CONTAINER.items():
|
||||||
|
if 'aliases' in v:
|
||||||
|
for alias in v['aliases']:
|
||||||
|
aliases[alias] = k
|
||||||
|
for k in list(container):
|
||||||
|
if k in aliases:
|
||||||
|
key = aliases[k]
|
||||||
|
opts_dict[key] = container[k]
|
||||||
|
container.pop(k)
|
||||||
|
opts_dict.update(container)
|
||||||
|
return opts_dict
|
||||||
|
|
||||||
|
|
||||||
|
def combine(results):
|
||||||
|
changed = any([i.get('changed', False) for i in results])
|
||||||
|
failed = any([i.get('failed', False) for i in results])
|
||||||
|
actions = []
|
||||||
|
podman_actions = []
|
||||||
|
containers = []
|
||||||
|
podman_version = ''
|
||||||
|
diffs = {}
|
||||||
|
stderr = ''
|
||||||
|
stdout = ''
|
||||||
|
for i in results:
|
||||||
|
if 'actions' in i and i['actions']:
|
||||||
|
actions += i['actions']
|
||||||
|
if 'podman_actions' in i and i['podman_actions']:
|
||||||
|
podman_actions += i['podman_actions']
|
||||||
|
if 'container' in i and i['container']:
|
||||||
|
containers.append(i['container'])
|
||||||
|
if 'podman_version' in i:
|
||||||
|
podman_version = i['podman_version']
|
||||||
|
if 'diff' in i:
|
||||||
|
diffs[i['container']['Name']] = i['diff']
|
||||||
|
if 'stderr' in i:
|
||||||
|
stderr += i['stderr']
|
||||||
|
if 'stdout' in i:
|
||||||
|
stdout += i['stdout']
|
||||||
|
|
||||||
|
total = {
|
||||||
|
'changed': changed,
|
||||||
|
'failed': failed,
|
||||||
|
'actions': actions,
|
||||||
|
'podman_actions': podman_actions,
|
||||||
|
'containers': containers,
|
||||||
|
'stdout': stdout,
|
||||||
|
'stderr': stderr,
|
||||||
|
}
|
||||||
|
if podman_version:
|
||||||
|
total['podman_version'] = podman_version
|
||||||
|
if diffs:
|
||||||
|
before = after = ''
|
||||||
|
for k, v in diffs.items():
|
||||||
|
before += "".join([str(k), ": ", str(v['before']), "\n"])
|
||||||
|
after += "".join([str(k), ": ", str(v['after']), "\n"])
|
||||||
|
total['diff'] = {
|
||||||
|
'before': before,
|
||||||
|
'after': after
|
||||||
|
}
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def check_input_strict(container):
|
||||||
|
if container['state'] in ['started', 'present'] and not container['image']:
|
||||||
|
return "State '%s' required image to be configured!" % container['state']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
module = AnsibleModule(
|
||||||
|
argument_spec=dict(
|
||||||
|
containers=dict(type='list', elements='dict', required=True),
|
||||||
|
debug=dict(type='bool', default=False),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
# work on input vars
|
||||||
|
|
||||||
|
results = []
|
||||||
|
default_options_templ = init_options()
|
||||||
|
for container in module.params['containers']:
|
||||||
|
options_dict = deepcopy(default_options_templ)
|
||||||
|
options_dict = update_options(options_dict, container)
|
||||||
|
options_dict['debug'] = module.params['debug'] or options_dict['debug']
|
||||||
|
test_input = check_input_strict(options_dict)
|
||||||
|
if test_input:
|
||||||
|
module.fail_json(
|
||||||
|
msg="Failed to run container %s because: %s" % (options_dict['name'], test_input))
|
||||||
|
res = PodmanManager(module, options_dict).execute()
|
||||||
|
results.append(res)
|
||||||
|
total_results = combine(results)
|
||||||
|
module.exit_json(**total_results)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
642
tests/integration/targets/podman_containers/tasks/main.yml
Normal file
642
tests/integration/targets/podman_containers/tasks/main.yml
Normal file
|
|
@ -0,0 +1,642 @@
|
||||||
|
- name: Test multiple podman_containers
|
||||||
|
block:
|
||||||
|
- name: Delete all containers leftovers from tests
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: "alpine:3.7"
|
||||||
|
state: absent
|
||||||
|
- name: "container"
|
||||||
|
state: absent
|
||||||
|
- name: "container1"
|
||||||
|
state: absent
|
||||||
|
- name: "container2"
|
||||||
|
state: absent
|
||||||
|
- name: "container3"
|
||||||
|
state: absent
|
||||||
|
- name: "container4"
|
||||||
|
state: absent
|
||||||
|
- name: "testidem"
|
||||||
|
state: absent
|
||||||
|
- name: "testidem1"
|
||||||
|
state: absent
|
||||||
|
- name: "testidem2"
|
||||||
|
state: absent
|
||||||
|
- name: "testidem3"
|
||||||
|
state: absent
|
||||||
|
- name: "testidem-pod"
|
||||||
|
state: absent
|
||||||
|
- name: "testidem-pod2"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Test no image with default action
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: "container"
|
||||||
|
- name: "container2"
|
||||||
|
- name: "container3"
|
||||||
|
image: alpine
|
||||||
|
ignore_errors: true
|
||||||
|
register: no_image
|
||||||
|
|
||||||
|
- name: Test no image with state 'started'
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: "container"
|
||||||
|
state: started
|
||||||
|
- name: "container2"
|
||||||
|
state: started
|
||||||
|
ignore_errors: true
|
||||||
|
register: no_image1
|
||||||
|
|
||||||
|
- name: Test no image with state 'present'
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: "container"
|
||||||
|
state: present
|
||||||
|
- name: "container2"
|
||||||
|
state: present
|
||||||
|
- name: "container3"
|
||||||
|
state: present
|
||||||
|
image: alpine
|
||||||
|
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 is search("State 'started' required image to be configured!")
|
||||||
|
- no_image1.msg is search ("State 'started' required image to be configured!")
|
||||||
|
- no_image2.msg is search("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:
|
||||||
|
name: alpine:3.7
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Check pulling image
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
image: alpine:3.7
|
||||||
|
state: present
|
||||||
|
command: sleep 1d
|
||||||
|
- name: container1
|
||||||
|
image: alpine:3.7
|
||||||
|
state: present
|
||||||
|
command: sleep 1d
|
||||||
|
register: image
|
||||||
|
|
||||||
|
- name: Check using already pulled image
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container1
|
||||||
|
image: alpine:3.7
|
||||||
|
state: present
|
||||||
|
command: sleep 1d
|
||||||
|
- name: container3
|
||||||
|
image: alpine:3.7
|
||||||
|
state: present
|
||||||
|
command: sleep 1d
|
||||||
|
register: image2
|
||||||
|
|
||||||
|
- name: Check output is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- image is changed
|
||||||
|
- image.containers[0] is defined
|
||||||
|
- image.containers[0]['State']['Running']
|
||||||
|
- image.containers[1] is defined
|
||||||
|
- image.containers[1]['State']['Running']
|
||||||
|
- "'pulled image alpine:3.7' in image.actions"
|
||||||
|
- "'started container' in image.actions"
|
||||||
|
- "'started container1' in image.actions"
|
||||||
|
- image2 is changed
|
||||||
|
- image2.containers is defined
|
||||||
|
- image2.containers[0]['State']['Running']
|
||||||
|
- image2.containers[1]['State']['Running']
|
||||||
|
- "'pulled image alpine:3.7' not in image2.actions"
|
||||||
|
- "'started container3' in image2.actions"
|
||||||
|
fail_msg: Pulling image test failed!
|
||||||
|
success_msg: Pulling image test passed!
|
||||||
|
|
||||||
|
- name: Check failed image pull
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container1
|
||||||
|
image: alpine:3.7
|
||||||
|
state: present
|
||||||
|
command: sleep 1d
|
||||||
|
- name: container
|
||||||
|
image: ineverneverneverexist
|
||||||
|
state: present
|
||||||
|
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 containers recreate
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container1
|
||||||
|
image: alpine:3.7
|
||||||
|
state: present
|
||||||
|
command: sleep 1d
|
||||||
|
- name: container
|
||||||
|
image: alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 1d
|
||||||
|
recreate: true
|
||||||
|
register: recreated
|
||||||
|
|
||||||
|
- name: Check output is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- recreated is changed
|
||||||
|
- recreated.containers is defined
|
||||||
|
- recreated.containers[1]['State']['Running']
|
||||||
|
- "'recreated container' in recreated.actions"
|
||||||
|
fail_msg: Force recreate test failed!
|
||||||
|
success_msg: Force recreate test passed!
|
||||||
|
|
||||||
|
- name: Stop containers
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
state: stopped
|
||||||
|
- name: container1
|
||||||
|
state: stopped
|
||||||
|
register: stopped
|
||||||
|
|
||||||
|
- name: Stop the same containers again (idempotency)
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
state: stopped
|
||||||
|
- name: container1
|
||||||
|
state: stopped
|
||||||
|
register: stopped_again
|
||||||
|
|
||||||
|
- name: Check output is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- stopped is changed
|
||||||
|
- stopped.containers is defined
|
||||||
|
- not stopped.containers[0]['State']['Running']
|
||||||
|
- not stopped.containers[1]['State']['Running']
|
||||||
|
- "'stopped container' in stopped.actions"
|
||||||
|
- stopped_again is not changed
|
||||||
|
- stopped_again.containers is defined
|
||||||
|
- not stopped_again.containers[0]['State']['Running']
|
||||||
|
- not stopped_again.containers[1]['State']['Running']
|
||||||
|
- stopped_again.actions == []
|
||||||
|
fail_msg: Stopping container test failed!
|
||||||
|
success_msg: Stopping container test passed!
|
||||||
|
|
||||||
|
- name: Delete stopped containers
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
state: absent
|
||||||
|
- name: container1
|
||||||
|
state: absent
|
||||||
|
register: deleted
|
||||||
|
|
||||||
|
- name: Delete again containers (idempotency)
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
state: absent
|
||||||
|
- name: container1
|
||||||
|
state: absent
|
||||||
|
register: deleted_again
|
||||||
|
|
||||||
|
- name: Check output is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- deleted is changed
|
||||||
|
- deleted.containers is defined
|
||||||
|
- deleted.containers == []
|
||||||
|
- "'deleted container' in deleted.actions"
|
||||||
|
- "'deleted container1' in deleted.actions"
|
||||||
|
- deleted_again is not changed
|
||||||
|
- deleted_again.containers is defined
|
||||||
|
- deleted_again.containers == []
|
||||||
|
- deleted_again.actions == []
|
||||||
|
fail_msg: Deleting stopped container test failed!
|
||||||
|
success_msg: Deleting stopped container test passed!
|
||||||
|
|
||||||
|
- name: Create containers, but don't run
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
image: alpine:3.7
|
||||||
|
state: stopped
|
||||||
|
command: sleep 1d
|
||||||
|
- name: container1
|
||||||
|
image: alpine:3.7
|
||||||
|
state: stopped
|
||||||
|
command: sleep 1d
|
||||||
|
register: created
|
||||||
|
|
||||||
|
- name: Create containers, but don't run again
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
image: alpine:3.7
|
||||||
|
state: stopped
|
||||||
|
command: sleep 1d
|
||||||
|
- name: container1
|
||||||
|
image: alpine:3.7
|
||||||
|
state: stopped
|
||||||
|
command: sleep 1d
|
||||||
|
register: created_again
|
||||||
|
|
||||||
|
- name: Check output is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- created is changed
|
||||||
|
- created.containers is defined
|
||||||
|
- created.containers != []
|
||||||
|
- not created.containers[0]['State']['Running']
|
||||||
|
- not created.containers[1]['State']['Running']
|
||||||
|
- "'created container' in created.actions"
|
||||||
|
fail_msg: "Creating stopped container test failed!"
|
||||||
|
success_msg: "Creating stopped container test passed!"
|
||||||
|
|
||||||
|
- name: Delete created containers
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
state: absent
|
||||||
|
- name: container1
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Start containers that were deleted
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
image: alpine:3.7
|
||||||
|
state: started
|
||||||
|
command: sleep 1d
|
||||||
|
- name: container1
|
||||||
|
image: alpine:3.7
|
||||||
|
state: started
|
||||||
|
command: sleep 1d
|
||||||
|
register: started
|
||||||
|
|
||||||
|
- name: Check output is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- started.containers is defined
|
||||||
|
- started.containers[0]['State']['Running']
|
||||||
|
- started.containers[1]['State']['Running']
|
||||||
|
- "'started container' in started.actions"
|
||||||
|
- "'pulled image alpine:3.7' not in started.actions"
|
||||||
|
|
||||||
|
- name: Delete started container
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
state: absent
|
||||||
|
- name: container1
|
||||||
|
state: absent
|
||||||
|
register: deleted
|
||||||
|
|
||||||
|
- name: Delete again container (idempotency)
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
state: absent
|
||||||
|
- name: container1
|
||||||
|
state: absent
|
||||||
|
register: deleted_again
|
||||||
|
|
||||||
|
- name: Check output is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- deleted is changed
|
||||||
|
- deleted.containers is defined
|
||||||
|
- deleted.containers == []
|
||||||
|
- "'deleted container' in deleted.actions"
|
||||||
|
- "'deleted container1' in deleted.actions"
|
||||||
|
- deleted_again is not changed
|
||||||
|
- deleted_again.containers is defined
|
||||||
|
- deleted_again.containers == []
|
||||||
|
- deleted_again.actions == []
|
||||||
|
fail_msg: Deleting started container test failed!
|
||||||
|
success_msg: Deleting started container test passed!
|
||||||
|
|
||||||
|
- name: Recreate container with parameters
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- 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_servers:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.4.4
|
||||||
|
dns_search_domains: example.com
|
||||||
|
capabilities:
|
||||||
|
- SYS_TIME
|
||||||
|
- NET_ADMIN
|
||||||
|
ports:
|
||||||
|
- "9000:80"
|
||||||
|
- "9001:8000"
|
||||||
|
workdir: "/bin"
|
||||||
|
env:
|
||||||
|
FOO: bar=1
|
||||||
|
BAR: foo
|
||||||
|
TEST: 1
|
||||||
|
BOOL: false
|
||||||
|
label:
|
||||||
|
somelabel: labelvalue
|
||||||
|
otheralbe: othervalue
|
||||||
|
volumes:
|
||||||
|
- /tmp:/data
|
||||||
|
- name: container1
|
||||||
|
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_servers:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.4.4
|
||||||
|
dns_search_domains: example.com
|
||||||
|
capabilities:
|
||||||
|
- SYS_TIME
|
||||||
|
- NET_ADMIN
|
||||||
|
ports:
|
||||||
|
- "9002:80"
|
||||||
|
- "9003:8000"
|
||||||
|
workdir: "/bin"
|
||||||
|
env:
|
||||||
|
FOO: bar=1
|
||||||
|
BAR: foo
|
||||||
|
TEST: 1
|
||||||
|
BOOL: false
|
||||||
|
label:
|
||||||
|
somelabel: labelvalue
|
||||||
|
otheralbe: othervalue
|
||||||
|
volumes:
|
||||||
|
- /tmp:/data
|
||||||
|
register: test
|
||||||
|
|
||||||
|
- name: Check output is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- test is changed
|
||||||
|
- test.containers is defined
|
||||||
|
- test.containers != []
|
||||||
|
- test.containers[0]['State']['Running']
|
||||||
|
# test capabilities
|
||||||
|
- "'CAP_SYS_TIME' in test.containers[0]['BoundingCaps']"
|
||||||
|
- "'CAP_NET_ADMIN' in test.containers[0]['BoundingCaps']"
|
||||||
|
# test annotations
|
||||||
|
- test.containers[0]['Config']['Annotations']['this'] is defined
|
||||||
|
- test.containers[0]['Config']['Annotations']['this'] == "annotation_value"
|
||||||
|
# test DNS
|
||||||
|
- >-
|
||||||
|
(test.containers[0]['HostConfig']['Dns'] is defined and
|
||||||
|
test.containers[0]['HostConfig']['Dns'] == ['1.1.1.1', '8.8.4.4']) or
|
||||||
|
(test.containers[0]['HostConfig']['DNS'] is defined and
|
||||||
|
test.containers[0]['HostConfig']['DNS'] == ['1.1.1.1', '8.8.4.4'])
|
||||||
|
# test ports
|
||||||
|
- test.containers[0]['NetworkSettings']['Ports']|length == 2
|
||||||
|
# test working dir
|
||||||
|
- test.containers[0]['Config']['WorkingDir'] == "/bin"
|
||||||
|
# test dns search
|
||||||
|
- >-
|
||||||
|
(test.containers[0]['HostConfig']['DnsSearch'] is defined and
|
||||||
|
test.containers[0]['HostConfig']['DnsSearch'] == ['example.com']) or
|
||||||
|
(test.containers[0]['HostConfig']['DNSSearch'] is defined and
|
||||||
|
test.containers[0]['HostConfig']['DNSSearch'] == ['example.com'])
|
||||||
|
# test environment variables
|
||||||
|
- "'FOO=bar=1' in test.containers[0]['Config']['Env']"
|
||||||
|
- "'BAR=foo' in test.containers[0]['Config']['Env']"
|
||||||
|
- "'TEST=1' in test.containers[0]['Config']['Env']"
|
||||||
|
- "'BOOL=False' in test.containers[0]['Config']['Env']"
|
||||||
|
# test labels
|
||||||
|
- test.containers[0]['Config']['Labels'] | length == 2
|
||||||
|
- test.containers[0]['Config']['Labels']['somelabel'] == "labelvalue"
|
||||||
|
- test.containers[0]['Config']['Labels']['otheralbe'] == "othervalue"
|
||||||
|
# test mounts
|
||||||
|
- >-
|
||||||
|
(test.containers[0]['Mounts'][0]['Destination'] is defined and
|
||||||
|
'/data' in test.containers[0]['Mounts'] | map(attribute='Destination') | list) or
|
||||||
|
(test.containers[0]['Mounts'][0]['destination'] is defined and
|
||||||
|
'/data' in test.containers[0]['Mounts'] | map(attribute='destination') | list)
|
||||||
|
- >-
|
||||||
|
(test.containers[0]['Mounts'][0]['Source'] is defined and
|
||||||
|
'/tmp' in test.containers[0]['Mounts'] | map(attribute='Source') | list) or
|
||||||
|
(test.containers[0]['Mounts'][0]['source'] is defined and
|
||||||
|
'/tmp' in test.containers[0]['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_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
- name: testidem2
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 21m
|
||||||
|
- name: testidem3
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 22m
|
||||||
|
|
||||||
|
- name: Check basic idempotency of running container - run it again
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
- name: testidem2
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 21m
|
||||||
|
- name: testidem3
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 22m
|
||||||
|
register: idem
|
||||||
|
|
||||||
|
- name: Check that nothing was changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not idem.changed
|
||||||
|
|
||||||
|
- name: Run changed container (with tty enabled)
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
tty: true
|
||||||
|
- name: testidem2
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 21m
|
||||||
|
- name: testidem3
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 22m
|
||||||
|
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_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
- name: testidem2
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 21m
|
||||||
|
- name: testidem3
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 22m
|
||||||
|
register: idem2
|
||||||
|
|
||||||
|
- name: Check that container is recreated when changed to default value
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- idem2 is changed
|
||||||
|
|
||||||
|
- name: Remove container
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem
|
||||||
|
state: absent
|
||||||
|
register: remove
|
||||||
|
|
||||||
|
- name: Check podman_actions
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'podman rm -f testidem' in remove.podman_actions"
|
||||||
|
|
||||||
|
- name: Create a pod
|
||||||
|
containers.podman.podman_pod:
|
||||||
|
name: testidempod
|
||||||
|
|
||||||
|
- name: Check basic idempotency of pod container
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem-pod
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
pod: "testidempod"
|
||||||
|
- name: testidem-pod2
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
pod: testidempod
|
||||||
|
|
||||||
|
- name: Check basic idempotency of pod container - run it again
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem-pod
|
||||||
|
image: alpine:latest
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
pod: testidempod
|
||||||
|
- name: testidem-pod2
|
||||||
|
image: docker.io/alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
pod: testidempod
|
||||||
|
register: idem
|
||||||
|
|
||||||
|
- name: Check that nothing was changed in pod containers
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not idem.changed
|
||||||
|
|
||||||
|
- name: Run changed pod container (with tty enabled)
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem-pod
|
||||||
|
image: alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
tty: true
|
||||||
|
pod: testidempod
|
||||||
|
- name: testidem-pod2
|
||||||
|
image: alpine
|
||||||
|
state: present
|
||||||
|
command: sleep 20m
|
||||||
|
pod: testidempod
|
||||||
|
register: idem1
|
||||||
|
|
||||||
|
- name: Check that container is recreated when changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- idem1 is changed
|
||||||
|
|
||||||
|
- name: Remove container
|
||||||
|
containers.podman.podman_containers:
|
||||||
|
containers:
|
||||||
|
- name: testidem-pod
|
||||||
|
state: absent
|
||||||
|
- name: testidem-pod2
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Delete all container leftovers from tests
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- "alpine:3.7"
|
||||||
|
- "container"
|
||||||
|
- "container1"
|
||||||
|
- "container2"
|
||||||
|
- "container3"
|
||||||
|
- "container4"
|
||||||
|
- "testidem"
|
||||||
|
- "testidem1"
|
||||||
|
- "testidem2"
|
||||||
|
- "testidem3"
|
||||||
|
- "testidem-pod"
|
||||||
|
- "testidem-pod2"
|
||||||
|
|
||||||
|
- name: Remove pod
|
||||||
|
containers.podman.podman_pod:
|
||||||
|
name: testidempod
|
||||||
|
state: absent
|
||||||
Loading…
Add table
Add a link
Reference in a new issue