Merge "Use podman collection instead of podman* modules"

This commit is contained in:
Zuul 2021-06-02 18:50:53 +00:00 committed by Gerrit Code Review
commit 7a2a75267c
36 changed files with 41 additions and 4094 deletions

View File

@ -29,9 +29,6 @@ mock_modules:
- os_baremetal_provide_node
- os_tripleo_baremetal_configure
- os_tripleo_baremetal_node_introspection
- podman_container
- podman_container_info
- podman_volume_info
- tripleo_baremetal_check_existing
- tripleo_baremetal_expand_roles
- tripleo_baremetal_populate_environment

View File

@ -1,14 +0,0 @@
=========================
Module - podman_container
=========================
This module provides for the following ansible plugin:
* podman_container
.. ansibleautoplugin::
:module: tripleo_ansible/ansible_plugins/modules/podman_container.py
:documentation: true
:examples: true

View File

@ -226,4 +226,4 @@ TripleO Heat Templates. Note that it doesn't write down the overrides in the
JSON file so if an update / upgrade is executed, the container will be
re-configured with the configuration that is in the JSON file.
.. _podman_container: https://docs.openstack.org/tripleo-ansible/latest/modules/modules-podman_container.html
.. _podman_container: https://github.com/containers/ansible-podman-collections

View File

@ -105,10 +105,3 @@ commands =
echo -e '\n\nNo molecule tests have been executed\nSee https://docs.openstack.org/tripleo-ansible/latest/contributing.html#local-testing-of-new-roles\n\n'; \
fi"
{[testenv:linters]commands}
[testenv:modules]
deps=
{[testenv:linters]deps}
commands =
bash -c "cd {toxinidir}/tripleo_ansible/ansible_plugins/tests; molecule test --all;"
{[testenv:linters]commands}

View File

@ -202,7 +202,7 @@ class ActionModule(ActionBase):
"""
tvars = copy.deepcopy(task_vars)
result = self._execute_module(
module_name='podman_container_info',
module_name='containers.podman.podman_container_info',
module_args=dict(name=containers),
task_vars=tvars
)

View File

@ -1,84 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.plugins.action import ActionBase
from ansible.utils.display import Display
DISPLAY = Display()
class ActionModule(ActionBase):
"""Action plugin for podman_container module"""
_VALID_ARGS = frozenset((
'containers',
))
def __init__(self, *args, **kwargs):
super(ActionModule, self).__init__(*args, **kwargs)
def run(self, tmp=None, task_vars=None):
self._supports_check_mode = True
self._supports_async = True
del tmp # tmp no longer has any effect
if task_vars is None:
task_vars = {}
if 'containers' not in self._task.args:
return {'failed': True,
'msg': 'Task must have "containers" argument!'}
containers = self._task.args.get('containers')
if not containers:
return {'failed': True,
'msg': 'Task must have non empty "containers" argument!'}
DISPLAY.vvvv('Running for containers: %s' % str(containers))
wrap_async = self._task.async_val and (
not self._connection.has_native_async)
results = [self._execute_module(
module_name='podman_container',
module_args=container,
task_vars=task_vars, wrap_async=wrap_async
) for container in containers]
changed = any([i.get('changed', False) for i in results])
skipped = all([i.get('skipped', False) for i in results])
failed = any([i.get('failed', False) for i in results])
try:
if not wrap_async:
# remove a temporary path we created
self._remove_tmp_path(self._connection._shell.tmpdir)
except Exception:
pass
finally:
if skipped:
return {'results': results,
'changed': False,
'skipped': skipped}
if failed:
msg = "\n".join([i.get('msg', '') for i in results])
return {'results': results,
'changed': changed,
'failed': failed,
'msg': msg}
return {'results': results,
'changed': changed,
'failed': False,
'msg': 'All items completed'}

View File

@ -1,28 +0,0 @@
#!/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
def run_podman_command(module, executable='podman', args=None, expected_rc=0, ignore_errors=False):
if not isinstance(executable, list):
command = [executable]
if args is not None:
command.extend(args)
rc, out, err = module.run_command(command)
if not ignore_errors and rc != expected_rc:
module.fail_json(
msg='Failed to run {command} {args}: {err}'.format(
command=command, args=args, err=err))
return rc, out, err
def lower_keys(x):
if isinstance(x, list):
return [lower_keys(v) for v in x]
elif isinstance(x, dict):
return dict((k.lower(), lower_keys(v)) for k, v in x.items())
else:
return x

View File

@ -1,940 +0,0 @@
#!/usr/bin/python
# Copyright (c) 2019 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# flake8: noqa: E501
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r"""
module: podman_container
author:
- "Sagi Shnaidman (@sshnaidm)"
version_added: '1.0.0'
short_description: Manage podman containers
notes: []
description:
- Start, stop, restart and manage Podman containers
requirements:
- podman
options:
name:
description:
- Name of the container
required: True
type: str
executable:
description:
- Path to C(podman) executable if it is not in the C($PATH) on the
machine running C(podman)
default: 'podman'
type: str
state:
description:
- I(absent) - A container matching the specified name will be stopped and
removed.
- I(present) - Asserts the existence of a container matching the name and
any provided configuration parameters. If no container matches the
name, a container will be created. If a container matches the name but
the provided configuration does not match, the container will be
updated, if it can be. If it cannot be updated, it will be removed and
re-created with the requested config. Image version will be taken into
account when comparing configuration. Use the recreate option to force
the re-creation of the matching container.
- I(started) - Asserts there is a running container matching the name and
any provided configuration. If no container matches the name, a
container will be created and started. Use recreate to always re-create
a matching container, even if it is running. Use force_restart to force
a matching container to be stopped and restarted.
- I(stopped) - Asserts that the container is first I(present), and then
if the container is running moves it to a stopped state.
- I(created) - Asserts that the container exists with given configuration.
If container doesn't exist, the module creates it and leaves it in
'created' state. If configuration doesn't match or 'recreate' option is
set, the container will be recreated
type: str
default: started
choices:
- absent
- present
- stopped
- started
- created
image:
description:
- Repository path (or image name) and tag used to create the container.
If an image is not found, the image will be pulled from the registry.
If no tag is included, C(latest) will be used.
- Can also be an image ID. If this is the case, the image is assumed to
be available locally.
type: str
annotation:
description:
- Add an annotation to the container. The format is key value, multiple
times.
type: dict
authfile:
description:
- Path of the authentication file. Default is
``${XDG_RUNTIME_DIR}/containers/auth.json``
(Not available for remote commands) You can also override the default
path of the authentication file by setting the ``REGISTRY_AUTH_FILE``
environment variable. ``export REGISTRY_AUTH_FILE=path``
type: path
blkio_weight:
description:
- Block IO weight (relative weight) accepts a weight value between 10 and
1000
type: int
blkio_weight_device:
description:
- Block IO weight (relative device weight, format DEVICE_NAME[:]WEIGHT).
type: dict
cap_add:
description:
- List of capabilities to add to the container.
type: list
elements: str
aliases:
- capabilities
cap_drop:
description:
- List of capabilities to drop from the container.
type: list
elements: str
cgroup_parent:
description:
- Path to cgroups under which the cgroup for the container will be
created.
If the path is not absolute, the path is considered to be relative to
the cgroups path of the init process. Cgroups will be created if they
do not already exist.
type: path
cgroupns:
description:
- Path to cgroups under which the cgroup for the container will be
created.
type: str
cgroups:
description:
- Determines whether the container will create CGroups.
Valid values are enabled and disabled, which the default being enabled.
The disabled option will force the container to not create CGroups,
and thus conflicts with CGroup options cgroupns and cgroup-parent.
type: str
choices:
- default
- disabled
cidfile:
description:
- Write the container ID to the file
type: path
cmd_args:
description:
- Any additional command options you want to pass to podman command,
cmd_args - ['--other-param', 'value']
Be aware module doesn't support idempotency if this is set.
type: list
elements: str
conmon_pidfile:
description:
- Write the pid of the conmon process to a file.
conmon runs in a separate process than Podman,
so this is necessary when using systemd to restart Podman containers.
type: path
command:
description:
- Override command of container. Can be a string or a list.
type: raw
cpu_period:
description:
- Limit the CPU real-time period in microseconds
type: int
cpu_rt_period:
description:
- Limit the CPU real-time period in microseconds.
Limit the container's Real Time CPU usage. This flag tell the kernel to
restrict the container's Real Time CPU usage to the period you specify.
type: int
cpu_rt_runtime:
description:
- Limit the CPU real-time runtime in microseconds.
This flag tells the kernel to limit the amount of time in a given CPU
period Real Time tasks may consume.
type: int
cpu_shares:
description:
- CPU shares (relative weight)
type: int
cpus:
description:
- Number of CPUs. The default is 0.0 which means no limit.
type: str
cpuset_cpus:
description:
- CPUs in which to allow execution (0-3, 0,1)
type: str
cpuset_mems:
description:
- Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only
effective on NUMA systems.
type: str
detach:
description:
- Run container in detach mode
type: bool
default: True
debug:
description:
- Return additional information which can be helpful for investigations.
type: bool
default: False
detach_keys:
description:
- Override the key sequence for detaching a container. Format is a single
character or ctrl-value
type: str
device:
description:
- Add a host device to the container.
The format is <device-on-host>[:<device-on-container>][:<permissions>]
(e.g. device /dev/sdc:/dev/xvdc:rwm)
type: list
elements: str
device_read_bps:
description:
- Limit read rate (bytes per second) from a device
(e.g. device-read-bps /dev/sda:1mb)
type: list
device_read_iops:
description:
- Limit read rate (IO per second) from a device
(e.g. device-read-iops /dev/sda:1000)
type: list
device_write_bps:
description:
- Limit write rate (bytes per second) to a device
(e.g. device-write-bps /dev/sda:1mb)
type: list
device_write_iops:
description:
- Limit write rate (IO per second) to a device
(e.g. device-write-iops /dev/sda:1000)
type: list
dns:
description:
- Set custom DNS servers
type: list
elements: str
aliases:
- dns_servers
dns_option:
description:
- Set custom DNS options
type: str
aliases:
- dns_opts
dns_search:
description:
- Set custom DNS search domains (Use dns_search with '' if you don't wish
to set the search domain)
type: str
aliases:
- dns_search_domains
entrypoint:
description:
- Overwrite the default ENTRYPOINT of the image
type: str
env:
description:
- Set environment variables.
This option allows you to specify arbitrary environment variables that
are available for the process that will be launched inside of the
container.
type: dict
env_file:
description:
- Read in a line delimited file of environment variables. Doesn't support
idempotency. If users changes the file with environment variables it's
on them to recreate the container.
type: path
env_host:
description:
- Use all current host environment variables in container.
Defaults to false.
type: bool
etc_hosts:
description:
- Dict of host-to-IP mappings, where each host name is a key in the
dictionary. Each host name will be added to the container's
``/etc/hosts`` file.
type: dict
aliases:
- add_hosts
expose:
description:
- Expose a port, or a range of ports (e.g. expose "3300-3310") to set up
port redirection on the host system.
type: list
elements: str
aliases:
- exposed
- exposed_ports
force_restart:
description:
- Force restart of container.
type: bool
default: False
aliases:
- restart
gidmap:
description:
- Run the container in a new user namespace using the supplied mapping.
type: list
elements: str
group_add:
description:
- Add additional groups to run as
type: list
aliases:
- groups
healthcheck:
description:
- Set or alter a healthcheck command for a container.
type: str
healthcheck_interval:
description:
- Set an interval for the healthchecks
(a value of disable results in no automatic timer setup)
(default "30s")
type: str
healthcheck_retries:
description:
- The number of retries allowed before a healthcheck is considered to be
unhealthy. The default value is 3.
type: int
healthcheck_start_period:
description:
- The initialization time needed for a container to bootstrap.
The value can be expressed in time format like 2m3s. The default value
is 0s
type: str
healthcheck_timeout:
description:
- The maximum time allowed to complete the healthcheck before an interval
is considered failed. Like start-period, the value can be expressed in
a time format such as 1m22s. The default value is 30s
type: str
hostname:
description:
- Container host name. Sets the container host name that is available
inside the container.
type: str
http_proxy:
description:
- By default proxy environment variables are passed into the container if
set for the podman process. This can be disabled by setting the
http_proxy option to false. The environment variables passed in
include http_proxy, https_proxy, ftp_proxy, no_proxy, and also the
upper case versions of those.
Defaults to true
type: bool
image_volume:
description:
- Tells podman how to handle the builtin image volumes.
The options are bind, tmpfs, or ignore (default bind)
type: str
choices:
- 'bind'
- 'tmpfs'
- 'ignore'
image_strict:
description:
- Whether to compare images in idempotency by taking into account a full
name with registry and namespaces.
type: bool
default: False
init:
description:
- Run an init inside the container that forwards signals and reaps
processes. The default is false.
type: bool
init_path:
description:
- Path to the container-init binary.
type: str
interactive:
description:
- Keep STDIN open even if not attached. The default is false.
When set to true, keep stdin open even if not attached.
The default is false.
type: bool
ip:
description:
- Specify a static IP address for the container, for example
'10.88.64.128'.
Can only be used if no additional CNI networks to join were specified
via 'network:', and if the container is not joining another container's
network namespace via 'network container:<name|id>'.
The address must be within the default CNI network's pool
(default 10.88.0.0/16).
type: str
ipc:
description:
- Default is to create a private IPC namespace (POSIX SysV IPC) for the
container
type: str
aliases:
- ipc_mode
kernel_memory:
description:
- Kernel memory limit
(format <number>[<unit>], where unit = b, k, m or g)
Note - idempotency is supported for integers only.
type: str
label:
description:
- Add metadata to a container, pass dictionary of label names and values
aliases:
- labels
type: dict
label_file:
description:
- Read in a line delimited file of labels
type: str
log_driver:
description:
- Logging driver. Used to set the log driver for the container.
For example log_driver "k8s-file".
type: str
choices:
- k8s-file
- journald
- json-file
log_level:
description:
- Logging level for Podman. Log messages above specified level
("debug"|"info"|"warn"|"error"|"fatal"|"panic") (default "error")
type: str
choices:
- debug
- info
- warn
- error
- fatal
- panic
log_opt:
description:
- Logging driver specific options. Used to set the path to the container
log file.
type: dict
aliases:
- log_options
suboptions:
path:
description:
- Specify a path to the log file (e.g. /var/log/container/mycontainer.json).
type: str
required: false
max_size:
description:
- Specify a max size of the log file (e.g 10mb).
type: str
required: false
tag:
description:
- Specify a custom log tag for the container.
type: str
required: false
mac_address:
description:
- Specify a MAC address for the container, for example
'92:d0:c6:0a:29:33'.
Don't forget that it must be unique within one Ethernet network.
type: str
memory:
description:
- Memory limit (format 10k, where unit = b, k, m or g)
Note - idempotency is supported for integers only.
type: str
memory_reservation:
description:
- Memory soft limit (format 100m, where unit = b, k, m or g)
Note - idempotency is supported for integers only.
type: str
memory_swap:
description:
- A limit value equal to memory plus swap. Must be used with the -m
(--memory) flag.
The swap LIMIT should always be larger than -m (--memory) value.
By default, the swap LIMIT will be set to double the value of --memory
Note - idempotency is supported for integers only.
type: str
memory_swappiness:
description:
- Tune a container's memory swappiness behavior. Accepts an integer
between 0 and 100.
type: int
mount:
description:
- Attach a filesystem mount to the container. bind or tmpfs
For example mount
"type=bind,source=/path/on/host,destination=/path/in/container"
type: str
network:
description:
- Set the Network mode for the container
* bridge create a network stack on the default bridge
* none no networking
* container:<name|id> reuse another container's network stack
* host use the podman host network stack.
* <network-name>|<network-id> connect to a user-defined network
* ns:<path> path to a network namespace to join
* slirp4netns use slirp4netns to create a user network stack.
This is the default for rootless containers
type: list
elements: str
aliases:
- net
- network_mode
no_hosts:
description:
- Do not create /etc/hosts for the container
Default is false.
type: bool
oom_kill_disable:
description:
- Whether to disable OOM Killer for the container or not.
Default is false.
type: bool
oom_score_adj:
description:
- Tune the host's OOM preferences for containers (accepts -1000 to 1000)
type: int
pid:
description:
- Set the PID mode for the container
type: str
aliases:
- pid_mode
pids_limit:
description:
- Tune the container's PIDs limit. Set -1 to have unlimited PIDs for the
container.
type: str
pod:
description:
- Run container in an existing pod.
If you want podman to make the pod for you, preference the pod name
with "new:"
type: str
privileged:
description:
- Give extended privileges to this container. The default is false.
type: bool
publish:
description:
- Publish a container's port, or range of ports, to the host.
Format - ip:hostPort:containerPort | ip::containerPort |
hostPort:containerPort | containerPort
In case of only containerPort is set, the hostPort will chosen
randomly by Podman.
type: list
elements: str
aliases:
- ports
- published
- published_ports
publish_all:
description:
- Publish all exposed ports to random ports on the host interfaces. The
default is false.
type: bool
read_only:
description:
- Mount the container's root filesystem as read only. Default is false
type: bool
read_only_tmpfs:
description:
- If container is running in --read-only mode, then mount a read-write
tmpfs on /run, /tmp, and /var/tmp. The default is true
type: bool
recreate:
description:
- Use with present and started states to force the re-creation of an
existing container.
type: bool
default: False
restart_policy:
description:
- Restart policy to follow when containers exit.
Restart policy will not take effect if a container is stopped via the
podman kill or podman stop commands. Valid values are
* no - Do not restart containers on exit
* on-failure[:max_retries] - Restart containers when they exit with a
non-0 exit code, retrying indefinitely
or until the optional max_retries count is hit
* always - Restart containers when they exit, regardless of status,
retrying indefinitely
type: str
rm:
description:
- Automatically remove the container when it exits. The default is false.
type: bool
aliases:
- remove
- auto_remove
rootfs:
description:
- If true, the first argument refers to an exploded container on the file
system. The default is false.
type: bool
security_opt:
description:
- Security Options. For example security_opt "seccomp=unconfined"
type: list
elements: str
shm_size:
description:
- Size of /dev/shm. The format is <number><unit>. number must be greater
than 0.
Unit is optional and can be b (bytes), k (kilobytes), m(megabytes), or
g (gigabytes).
If you omit the unit, the system uses bytes. If you omit the size
entirely, the system uses 64m
type: str
sig_proxy:
description:
- Proxy signals sent to the podman run command to the container process.
SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is true.
type: bool
stop_signal:
description:
- Signal to stop a container. Default is SIGTERM.
type: int
stop_timeout:
description:
- Timeout (in seconds) to stop a container. Default is 10.
type: int
subgidname:
description:
- Run the container in a new user namespace using the map with 'name' in
the /etc/subgid file.
type: str
subuidname:
description:
- Run the container in a new user namespace using the map with 'name' in
the /etc/subuid file.
type: str
sysctl:
description:
- Configure namespaced kernel parameters at runtime
type: dict
systemd:
description:
- Run container in systemd mode. The default is true.
type: str
tmpfs:
description:
- Create a tmpfs mount. For example tmpfs
"/tmp" "rw,size=787448k,mode=1777"
type: dict
tty:
description:
- Allocate a pseudo-TTY. The default is false.
type: bool
uidmap:
description:
- Run the container in a new user namespace using the supplied mapping.
type: list
elements: str
ulimit:
description:
- Ulimit options
type: list
aliases:
- ulimits
user:
description:
- Sets the username or UID used and optionally the groupname or GID for
the specified command.
type: str
userns:
description:
- Set the user namespace mode for the container.
It defaults to the PODMAN_USERNS environment variable.
An empty value means user namespaces are disabled.
type: str
aliases:
- userns_mode
uts:
description:
- Set the UTS mode for the container
type: str
volume:
description:
- Create a bind mount. If you specify, volume /HOST-DIR:/CONTAINER-DIR,
podman bind mounts /HOST-DIR in the host to /CONTAINER-DIR in the
podman container.
type: list
elements: str
aliases:
- volumes
volumes_from:
description:
- Mount volumes from the specified container(s).
type: list
elements: str
workdir:
description:
- Working directory inside the container.
The default working directory for running binaries within a container
is the root directory (/).
type: str
aliases:
- working_dir
"""
EXAMPLES = r"""
- name: Run container
podman_container:
name: container
image: quay.io/bitnami/wildfly
state: started
- name: Create a data container
podman_container:
name: mydata
image: busybox
volume:
- /tmp/data
- name: Re-create a redis container
podman_container:
name: myredis
image: redis
command: redis-server --appendonly yes
state: present
recreate: yes
expose:
- 6379
volumes_from:
- mydata
- name: Restart a container
podman_container:
name: myapplication
image: redis
state: started
restart: yes
etc_hosts:
other: "127.0.0.1"
restart_policy: "no"
device: "/dev/sda:/dev/xvda:rwm"
ports:
- "8080:9000"
- "127.0.0.1:8081:9001/udp"
env:
SECRET_KEY: "ssssh"
BOOLEAN_KEY: "yes"
- name: Container present
podman_container:
name: mycontainer
state: present
image: ubuntu:14.04
command: "sleep 1d"
- name: Stop a container
podman_container:
name: mycontainer
state: stopped
- name: Start 4 load-balanced containers
podman_container:
name: "container{{ item }}"
recreate: yes
image: someuser/anotherappimage
command: sleep 1d
with_sequence: count=4
- name: remove container
podman_container:
name: ohno
state: absent
- name: Writing output
podman_container:
name: myservice
image: busybox
log_options: path=/var/log/container/mycontainer.json
log_driver: k8s-file
"""
RETURN = r"""
container:
description:
- Facts representing the current state of the container. Matches the
podman inspection output.
- Note that facts are part of the registered vars since Ansible 2.8. For
compatibility reasons, the facts
are also accessible directly as C(podman_container). Note that the
returned fact will be removed in Ansible 2.12.
- Empty if C(state) is I(absent).
returned: always
type: dict
sample: '{
"AppArmorProfile": "",
"Args": [
"sh"
],
"BoundingCaps": [
"CAP_CHOWN",
...
],
"Config": {
"Annotations": {
"io.kubernetes.cri-o.ContainerType": "sandbox",
"io.kubernetes.cri-o.TTY": "false"
},
"AttachStderr": false,
"AttachStdin": false,
"AttachStdout": false,
"Cmd": [
"sh"
],
"Domainname": "",
"Entrypoint": "",
"Env": [
"PATH=/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm",
"HOSTNAME=",
"container=podman"
],
"Hostname": "",
"Image": "docker.io/library/busybox:latest",
"Labels": null,
"OpenStdin": false,
"StdinOnce": false,
"StopSignal": 15,
"Tty": false,
"User": {
"gid": 0,
"uid": 0
},
"Volumes": null,
"WorkingDir": "/"
},
"ConmonPidFile": "...",
"Created": "2019-06-17T19:13:09.873858307+03:00",
"Dependencies": [],
"Driver": "overlay",
"EffectiveCaps": [
"CAP_CHOWN",
...
],
"ExecIDs": [],
"ExitCommand": [
"/usr/bin/podman",
"--root",
...
],
"GraphDriver": {
...
},
"HostConfig": {
...
},
"HostnamePath": "...",
"HostsPath": "...",
"ID": "...",
"Image": "...",
"ImageName": "docker.io/library/busybox:latest",
"IsInfra": false,
"LogPath": "/tmp/container/mycontainer.json",
"MountLabel": "system_u:object_r:container_file_t:s0:c282,c782",
"Mounts": [
...
],
"Name": "myservice",
"Namespace": "",
"NetworkSettings": {
"Bridge": "",
...
},
"Path": "sh",
"ProcessLabel": "system_u:system_r:container_t:s0:c282,c782",
"ResolvConfPath": "...",
"RestartCount": 0,
"Rootfs": "",
"State": {
"Dead": false,
"Error": "",
"ExitCode": 0,
"FinishedAt": "2019-06-17T19:13:10.157518963+03:00",
"Healthcheck": {
"FailingStreak": 0,
"Log": null,
"Status": ""
},
"OOMKilled": false,
"OciVersion": "1.0.1-dev",
"Paused": false,
"Pid": 4083,
"Restarting": false,
"Running": false,
"StartedAt": "2019-06-17T19:13:10.152479729+03:00",
"Status": "exited"
},
"StaticDir": "..."
...
}'
"""
from ansible.module_utils.basic import AnsibleModule # noqa: F402
try:
from ansible.module_utils.podman.podman_container_lib import PodmanManager
from ansible.module_utils.podman.podman_container_lib import ARGUMENTS_SPEC_CONTAINER # noqa: F402
except ImportError:
from tripleo_ansible.ansible_plugins.module_utils.podman.podman_container_lib import PodmanManager # noqa: F402
from tripleo_ansible.ansible_plugins.module_utils.podman.podman_container_lib import ARGUMENTS_SPEC_CONTAINER # noqa: F402
def main():
module = AnsibleModule(
argument_spec=ARGUMENTS_SPEC_CONTAINER,
mutually_exclusive=(
['no_hosts', 'etc_hosts'],
),
supports_check_mode=True,
)
# work on input vars
if (module.params['state'] in ['started', 'present', 'created']
and not module.params['force_restart']
and not module.params['image']):
module.fail_json(msg="State '%s' required image to be configured!" %
module.params['state'])
results = PodmanManager(module, module.params).execute()
module.exit_json(**results)
if __name__ == '__main__':
main()

View File

@ -1,426 +0,0 @@
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''
module: podman_container_info
author:
- Sagi Shnaidman (@sshnaidm)
- Emilien Macchi (@EmilienM)
short_description: Gather facts about containers using podman
notes:
- Podman may require elevated privileges in order to run properly.
description:
- Gather facts about containers using C(podman)
requirements:
- "Podman installed on host"
options:
name:
description:
- List of container names to gather facts about. If no name is given
return facts about all containers.
type: list
elements: str
executable:
description:
- Path to C(podman) executable if it is not in the C($PATH) on the
machine running C(podman)
default: 'podman'
type: str
'''
EXAMPLES = r"""
- name: Gather facts for all containers
podman_container_info:
- name: Gather facts on a specific container
podman_container_info:
name: web1
- name: Gather facts on several containers
podman_container_info:
name:
- redis
- web1
"""
RETURN = r"""
containers:
description: Facts from all or specificed containers
returned: always
type: list
elements: dict
sample: [
{
"Id": "c5c39f9b80a6ea2ad665aa9946435934e478a0c5322da835f3883872f",
"Created": "2019-10-01T12:51:00.233106443Z",
"Path": "dumb-init",
"Args": [
"--single-child",
"--",
"kolla_start"
],
"State": {
"OciVersion": "1.0.1-dev",
"Status": "configured",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 0,
"Error": "",
"StartedAt": "0001-01-01T00:00:00Z",
"FinishedAt": "0001-01-01T00:00:00Z",
"Healthcheck": {
"Status": "",
"FailingStreak": 0,
"Log": null
}
},
"Image": "0e267acda67d0ebd643e900d820a91b961d859743039e620191ca1",
"ImageName": "docker.io/tripleomaster/centos-haproxy:latest",
"Rootfs": "",
"Pod": "",
"ResolvConfPath": "",
"HostnamePath": "",
"HostsPath": "",
"OCIRuntime": "runc",
"Name": "haproxy",
"RestartCount": 0,
"Driver": "overlay",
"MountLabel": "system_u:object_r:svirt_sandbox_file_t:s0:c78,c866",
"ProcessLabel": "system_u:system_r:svirt_lxc_net_t:s0:c785,c866",
"AppArmorProfile": "",
"EffectiveCaps": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"BoundingCaps": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"ExecIDs": [],
"GraphDriver": {
"Name": "overlay"
},
"Mounts": [],
"Dependencies": [],
"NetworkSettings": {
"Bridge": "",
"SandboxID": "",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": [],
"SandboxKey": "",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": ""
},
"ExitCommand": [
"/usr/bin/podman",
"--root",
"/var/lib/containers/storage",
"--runroot",
"/var/run/containers/storage",
"--log-level",
"error",
"--cgroup-manager",
"systemd",
"--tmpdir",
"/var/run/libpod",
"--runtime",
"runc",
"--storage-driver",
"overlay",
"--events-backend",
"journald",
"container",
"cleanup",
"c9e813703f9b80a6ea2ad665aa9946435934e478a0c5322da835f3883872f"
],
"Namespace": "",
"IsInfra": false,
"Config": {
"Hostname": "c5c39e813703",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm",
"HOSTNAME=",
"container=oci",
"KOLLA_INSTALL_METATYPE=rdo",
"KOLLA_BASE_DISTRO=centos",
"KOLLA_INSTALL_TYPE=binary",
"KOLLA_DISTRO_PYTHON_VERSION=2.7",
"KOLLA_BASE_ARCH=x86_64"
],
"Cmd": [
"kolla_start"
],
"Image": "docker.io/tripleomaster/centos-haproxy:latest",
"Volumes": null,
"WorkingDir": "/",
"Entrypoint": "dumb-init --single-child --",
"OnBuild": null,
"Labels": {
"build-date": "20190919",
"kolla_version": "8.1.0",
"name": "haproxy",
"org.label-schema.build-date": "20190801",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
},
"Annotations": {
"io.kubernetes.cri-o.ContainerType": "sandbox",
"io.kubernetes.cri-o.TTY": "false",
"io.podman.annotations.autoremove": "FALSE",
"io.podman.annotations.init": "FALSE",
"io.podman.annotations.privileged": "FALSE",
"io.podman.annotations.publish-all": "FALSE"
},
"StopSignal": 15
},
"HostConfig": {
"Binds": [],
"ContainerIDFile": "",
"LogConfig": {
"Type": "k8s-file",
"Config": null
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": [],
"CapDrop": [],
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": [],
"GroupAdd": [],
"IpcMode": "",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": [],
"Tmpfs": {},
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 65536000,
"Runtime": "oci",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": -1,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": [
{
"Name": "RLIMIT_NOFILE",
"Soft": 1048576,
"Hard": 1048576
},
{
"Name": "RLIMIT_NPROC",
"Soft": 1048576,
"Hard": 1048576
}
],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0
}
}
]
"""
import json # noqa: F402
import time
from ansible.module_utils.basic import AnsibleModule # noqa: F402
def get_containers_facts(module, executable, name):
"""Collect containers facts for all containers or for specified in 'name'.
Arguments:
module {AnsibleModule} -- instance of AnsibleModule
executable {string} -- binary to execute when inspecting containers
name {list} -- list of names or None in case of all containers
Returns:
list of containers info, stdout, stderr
"""
retry = 0
retry_limit = 4
if not name:
all_names = [executable, 'container', 'ls', '-q', '-a']
rc, out, err = module.run_command(all_names)
# This should not fail in regular circumstances, so retry again
# https://github.com/containers/podman/issues/10225
while rc != 0 and retry <= retry_limit:
module.log(msg="Unable to get list of containers: %s" % err)
time.sleep(1)
retry += 1
rc, out, err = module.run_command(all_names)
if rc != 0:
module.fail_json(msg="Unable to get list of containers during"
" %s retries" % retry_limit)
name = out.split()
if not name:
return [], out, err
command = [executable, 'container', 'inspect']
command.extend(name)
rc, out, err = module.run_command(command)
if rc == 0:
json_out = json.loads(out) if out else None
if json_out is None:
return [], out, err
return json_out, out, err
if rc != 0 and 'no such ' in err:
if len(name) < 2:
return [], out, err
return cycle_over(module, executable, name)
module.fail_json(msg="Unable to gather info for %s: %s" % (",".join(name), err))
def cycle_over(module, executable, name):
"""Inspect each container in a cycle in case some of them don't exist.
Arguments:
module {AnsibleModule} -- instance of AnsibleModule
executable {string} -- binary to execute when inspecting containers
name {list} -- list of containers names to inspect
Returns:
list of containers info, stdout as empty, stderr
"""
inspection = []
stderrs = []
for container in name:
command = [executable, 'container', 'inspect', container]
rc, out, err = module.run_command(command)
if rc != 0 and 'no such ' not in err:
module.fail_json(msg="Unable to gather info for %s: %s" % (container, err))
if rc == 0 and out:
json_out = json.loads(out)
if json_out:
inspection += json_out
stderrs.append(err)
return inspection, "", "\n".join(stderrs)
def main():
module = AnsibleModule(
argument_spec=dict(
executable=dict(type='str', default='podman'),
name=dict(type='list', elements='str')
),
supports_check_mode=True,
)
name = module.params['name']
executable = module.get_bin_path(module.params['executable'], required=True)
# pylint: disable=unused-variable
inspect_results, out, err = get_containers_facts(module, executable, name)
results = {
"changed": False,
"containers": inspect_results,
"stderr": err
}
module.exit_json(**results)
if __name__ == '__main__':
main()

View File

@ -1,61 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
'metadata_version': '1.0',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = '''
---
module: podman_containers
author:
- "Sagi Shnaidman (@sshnaidm)"
version_added: '2.9'
short_description: Manage podman containers in a batch
notes: []
description:
- Manage groups of podman containers
requirements:
- "Podman installed on host"
options:
containers:
description:
- List of dictionaries with data for running containers
for podman_container module.
required: True
type: list
elements: dict
'''
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
'''

View File

@ -1,115 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
__metaclass__ = type
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = """
module: podman_volume_info
author:
- "Sagi Shnaidman (@sshnaidm)"
version_added: '2.10'
short_description: Gather info about podman volumes
notes: []
description:
- Gather info about podman volumes with podman inspect command.
requirements:
- "Podman installed on host"
options:
name:
description:
- Name of the volume
type: str
executable:
description:
- Path to C(podman) executable if it is not in the C($PATH) on the
machine running C(podman)
default: 'podman'
type: str
"""
EXAMPLES = """
- name: Gather info about all present volumes
podman_volume_info:
- name: Gather info about specific volume
podman_volume_info:
name: specific_volume
"""
RETURN = """
volumes:
description: Facts from all or specified volumes
returned: always
type: list
sample: [
{
"name": "testvolume",
"labels": {},
"mountPoint": "/home/ansible/.local/share/testvolume/_data",
"driver": "local",
"options": {},
"scope": "local"
}
]
"""
import json
from ansible.module_utils.basic import AnsibleModule
def get_volume_info(module, executable, name):
command = [executable, 'volume', 'inspect']
if name:
command.append(name)
else:
command.append("--all")
rc, out, err = module.run_command(command)
if rc != 0 or 'no such volume' in err:
module.fail_json(msg="Unable to gather info for %s: %s" % (name or 'all volumes', err))
if not out or json.loads(out) is None:
return [], out, err
return json.loads(out), out, err
def main():
module = AnsibleModule(
argument_spec=dict(
executable=dict(type='str', default='podman'),
name=dict(type='str')
),
supports_check_mode=True,
)
name = module.params['name']
executable = module.get_bin_path(module.params['executable'], required=True)
inspect_results, out, err = get_volume_info(module, executable, name)
results = {
"changed": False,
"volumes": inspect_results,
"stderr": err
}
module.exit_json(**results)
if __name__ == '__main__':
main()

View File

@ -1,438 +0,0 @@
---
- name: Converge
hosts: all
tasks:
- name: Test podman_container
become: true
block:
- name: Delete all container leftovers from tests
podman_container:
name: "{{ item }}"
state: absent
loop:
- "ubi-minimal"
- "container"
- "container2"
- name: Test no image with default action
podman_container:
name: container
ignore_errors: true
register: no_image
- name: Test no image with state 'started'
podman_container:
name: container
state: started
ignore_errors: true
register: no_image1
- name: Test no image with state 'present'
podman_container:
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 == "State 'started' required image to be configured!"
- no_image1.msg == "State 'started' 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
podman_image:
name: registry.access.redhat.com/ubi8/ubi-minimal
state: absent
- name: Check pulling image
podman_container:
name: container
image: registry.access.redhat.com/ubi8/ubi-minimal
state: present
command: sleep 1d
register: image
- name: Check using already pulled image
podman_container:
name: container2
image: registry.access.redhat.com/ubi8/ubi-minimal
state: present
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 registry.access.redhat.com/ubi8/ubi-minimal' in image.actions"
- "'started container' in image.actions"
- image2 is changed
- image2.container is defined
- image2.container['State']['Running']
- "'pulled image registry.access.redhat.com/ubi8/ubi-minimal' not in image2.actions"
- "'started container2' in image2.actions"
fail_msg: Pulling image test failed!
success_msg: Pulling image test passed!
- name: Check failed image pull
podman_container:
name: container
image: quay.io/ineverneverneverexist
state: present
command: sleep 1d
register: imagefail
ignore_errors: true
- name: Check output is correct
assert:
that:
- imagefail is failed
- name: Force container recreate
podman_container:
name: container
image: registry.access.redhat.com/ubi8/ubi-minimal
state: present
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']
- "'recreated container' in recreated.actions"
fail_msg: Force recreate test failed!
success_msg: Force recreate test passed!
- name: Stop container
podman_container:
name: container
state: stopped
register: stopped
- name: Stop the same container again (idempotency)
podman_container:
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
podman_container:
name: container
state: absent
register: deleted
- name: Delete again container (idempotency)
podman_container:
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, but don't run
podman_container:
name: container
image: registry.access.redhat.com/ubi8/ubi-minimal
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: Delete created container
podman_container:
name: container
state: absent
- name: Start container that was deleted
podman_container:
name: container
image: registry.access.redhat.com/ubi8/ubi-minimal
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 registry.access.redhat.com/ubi8/ubi-minimal' not in started.actions"
- name: Delete started container
podman_container:
name: container
state: absent
register: deleted
- name: Delete again container (idempotency)
podman_container:
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: Recreate container with parameters
podman_container:
name: container
image: registry.access.redhat.com/ubi8/ubi-minimal
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
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.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' 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]['Destination'] is defined and
'/data' in test.container['Mounts'] | map(attribute='Destination') | list) or
(test.container['Mounts'][0]['destination'] is defined and
'/data' in test.container['Mounts'] | map(attribute='destination') | list)
- >-
(test.container['Mounts'][0]['Source'] is defined and
'/tmp' in test.container['Mounts'] | map(attribute='Source') | list) or
(test.container['Mounts'][0]['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
podman_container:
name: testidem
image: registry.access.redhat.com/ubi8/ubi-minimal
state: present
command: sleep 20m
- name: Check basic idempotency of running container - run it again
podman_container:
name: testidem
image: ubi-minimal:latest
state: present
command: sleep 20m
register: idem
- name: Check that nothing was changed
assert:
that:
- not idem.changed
- name: Run changed container (with tty enabled)
podman_container:
name: testidem
image: ubi-minimal
state: present
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
podman_container:
name: testidem
image: ubi-minimal
state: present
command: sleep 20m
register: idem2
- name: Check that container is recreated when changed to default value
assert:
that:
- idem2 is changed
- name: Remove container
podman_container:
name: testidem
state: absent
register: remove
- name: Check podman_actions
assert:
that:
- "'podman rm -f testidem' in remove.podman_actions"
- name: Check basic idempotency of pod container
podman_container:
name: testidem-pod
image: registry.access.redhat.com/ubi8/ubi-minimal
state: present
command: sleep 20m
pod: "new:testidempod"
- name: Check basic idempotency of pod container - run it again
podman_container:
name: testidem-pod
image: ubi-minimal:latest
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)
podman_container:
name: testidem-pod
image: ubi-minimal
state: present
command: sleep 20m
tty: true
pod: testidempod
register: idem1
- name: Check that container is recreated when changed
assert:
that:
- idem1 is changed
- name: Remove container
podman_container:
name: testidem-pod
state: absent
always:
- name: Delete all container leftovers from tests
podman_container:
name: "{{ item }}"
state: absent
loop:
- "container"
- "container2"
- "ubi-minimal"
- "web"
- "test"
- "testidem"
- name: Remove pod
shell: podman pod rm -f testidempod

View File

@ -1,50 +0,0 @@
---
driver:
name: delegated
options:
managed: false
login_cmd_template: >-
ssh
-o UserKnownHostsFile=/dev/null
-o StrictHostKeyChecking=no
-o Compression=no
-o TCPKeepAlive=yes
-o VerifyHostKeyDNS=no
-o ForwardX11=no
-o ForwardAgent=no
{instance}
ansible_connection_options:
ansible_connection: ssh
log: true
platforms:
- name: instance
provisioner:
name: ansible
config_options:
defaults:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule/facts
inventory:
hosts:
all:
hosts:
instance:
ansible_host: localhost
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles"
ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}"
ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}"
scenario:
test_sequence:
- prepare
- converge
- verify
verifier:
name: testinfra

View File

@ -1,39 +0,0 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: Prepare
hosts: all
gather_facts: true
roles:
- role: test_deps
test_deps_extra_packages:
- podman
post_tasks:
- name: Check podman version
command: podman version
register: p_ver
changed_when: false
- name: Print podman version
debug:
msg: |
podman version:
{{ p_ver.stdout }}
Testing with ansible {{ ansible_version.full }}
with python {{ ansible_python_version }}
on host {{ ansible_distribution }} {{ ansible_distribution_version }}

View File

@ -1,60 +0,0 @@
---
- name: Converge
hosts: all
tasks:
- name: Test podman_container_info
become: true
block:
- name: Generate random value for container name
set_fact:
container_name: "{{ 'ansible-test-podman-%0x' % ((2**32) | random) }}"
- name: Make sure container doesn't exist
command: podman container rm -f {{ container_name }}
ignore_errors: true
- name: Get missing container info
podman_container_info:
name: "{{ container_name }}"
register: nonexist
ignore_errors: true
- name: Check results
assert:
that:
- nonexist.containers == []
- nonexist is not failed
- name: Make sure container exists
command: podman container run -d --name {{ container_name }} alpine sleep 15m
- name: Get existing container info
podman_container_info:
name: "{{ container_name }}"
register: existing_container
- name: Get all containers info
podman_container_info:
register: all_containers
- name: Dump podman container inspect result
debug: var=existing_container
- name: Cleanup
command: podman container rm -f {{ container_name }}
- name: Make checks
assert:
that:
- "'containers' in existing_container"
- existing_container.containers
always:
- name: Delete all container leftovers from tests
podman_container:
name: "{{ item }}"
state: absent
loop:
- "alpine:3.7"
- "container"
- "container2"

View File

@ -1,50 +0,0 @@
---
driver:
name: delegated
options:
managed: false
login_cmd_template: >-
ssh
-o UserKnownHostsFile=/dev/null
-o StrictHostKeyChecking=no
-o Compression=no
-o TCPKeepAlive=yes
-o VerifyHostKeyDNS=no
-o ForwardX11=no
-o ForwardAgent=no
{instance}
ansible_connection_options:
ansible_connection: ssh
log: true
platforms:
- name: instance
provisioner:
name: ansible
config_options:
defaults:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule/facts
inventory:
hosts:
all:
hosts:
instance:
ansible_host: localhost
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles"
ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}"
ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}"
scenario:
test_sequence:
- prepare
- converge
- verify
verifier:
name: testinfra

View File

@ -1,22 +0,0 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: Prepare
hosts: all
roles:
- role: test_deps
test_deps_extra_packages:
- podman

View File

@ -1,63 +0,0 @@
---
- name: Converge
hosts: all
tasks:
- name: Test podman_volume_info
become: true
block:
- name: Print podman version
command: podman version
- name: Generate random value for volume name
set_fact:
volume_name: "{{ 'ansible-test-podman-%0x' % ((2**32) | random) }}"
- name: Make sure volume doesn't exist
command: podman volume rm {{ volume_name }}
ignore_errors: true
- name: Get missing volume info
podman_volume_info:
name: "{{ volume_name }}"
register: nonexist
ignore_errors: true
- name: Check results
assert:
that:
- "'volumes' not in nonexist"
- nonexist is failed
- name: Make sure volume exists
command: podman volume create {{ volume_name }}
- name: Get existing volume info
podman_volume_info:
name: "{{ volume_name }}"
register: existing_volume
- name: Dump podman volume inspect result
debug: var=existing_volume
- name: Comparison with 'podman volume inspect'
command: podman volume inspect "{{ volume_name }}"
register: podman_inspect
- name: Convert podman inspect output to JSON
set_fact:
podman_inspect_result: "{{ podman_inspect.stdout | from_json }}"
- name: Cleanup
command: podman volume rm {{ volume_name }}
- name: Make checks
assert:
that:
- "'volumes' in existing_volume"
- existing_volume.volumes
- "existing_volume.volumes == podman_inspect_result"
always:
- name: Cleanup
command: podman volume rm {{ volume_name }}
ignore_errors: true

View File

@ -1,51 +0,0 @@
---
driver:
name: delegated
options:
managed: false
login_cmd_template: >-
ssh
-o UserKnownHostsFile=/dev/null
-o StrictHostKeyChecking=no
-o Compression=no
-o TCPKeepAlive=yes
-o VerifyHostKeyDNS=no
-o ForwardX11=no
-o ForwardAgent=no
{instance}
ansible_connection_options:
ansible_connection: ssh
log: true
platforms:
- name: instance
provisioner:
name: ansible
config_options:
defaults:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule/facts
inventory:
hosts:
all:
hosts:
instance:
ansible_host: localhost
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles"
ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}"
ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}"
scenario:
name: podman_volume_info
test_sequence:
- prepare
- converge
- verify
verifier:
name: testinfra

View File

@ -1,22 +0,0 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: Prepare
hosts: all
roles:
- role: test_deps
test_deps_extra_packages:
- podman

View File

@ -80,14 +80,14 @@
}
- name: pull some images
podman_image:
containers.podman.podman_image:
name: "{{ item }}"
with_items:
- registry.access.redhat.com/ubi8/ubi-minimal
- mysql
- name: Create a data container
podman_container:
containers.podman.podman_container:
name: "{{ item }}"
image: ubi-minimal
state: started
@ -97,7 +97,7 @@
- test-container2
- name: Start myql container
podman_container:
containers.podman.podman_container:
name: mysql
image: mysql
state: started

View File

@ -76,7 +76,7 @@
- name: Check for fedora container
command: podman container exists fedora
- name: Gather facts about fedora container
podman_container_info:
containers.podman.podman_container_info:
name: fedora
register: fedora_infos
- name: Assert that fedora container has the right image
@ -110,7 +110,7 @@
- name: Check for fedora_bis container
command: podman container exists fedora_bis
- name: Gather facts about fedora_bis container
podman_container_info:
containers.podman.podman_container_info:
name: fedora_bis
register: fedora_bis_infos
- name: Assert that fedora_bis container has the right image
@ -124,7 +124,7 @@
- name: Check for fedora_three container
command: podman container exists fedora_three
- name: Gather facts about fedora_three container
podman_container_info:
containers.podman.podman_container_info:
name: fedora_three
register: fedora_three_infos
- name: Assert that fedora_three container has the right image
@ -145,7 +145,7 @@
tripleo_container_manage_systemd_order: true
tasks:
- name: Gather facts about fedora container before new run
podman_container_info:
containers.podman.podman_container_info:
name: fedora
register: fedora_infos_old
when:
@ -153,7 +153,7 @@
- include_role:
name: tripleo_container_manage
- name: Gather facts about fedora container after new run
podman_container_info:
containers.podman.podman_container_info:
name: fedora
register: fedora_infos_new
when:
@ -222,7 +222,7 @@
- name: Check for fedora container
command: podman container exists fedora
- name: Gather facts about fedora container
podman_container_info:
containers.podman.podman_container_info:
name: fedora
register: fedora_infos
- name: Assert that fedora container has the right image
@ -271,7 +271,7 @@
- name: Check for fedora container
command: podman container exists fedora
- name: Gather facts about fedora container
podman_container_info:
containers.podman.podman_container_info:
name: fedora
register: fedora_infos
- name: Check if tripleo_fedora systemd service is active
@ -357,7 +357,7 @@
- name: Check for fedora_bis container
command: podman container exists fedora_bis
- name: Gather facts about fedora_bis container
podman_container_info:
containers.podman.podman_container_info:
name: fedora_bis
register: fedora_bis_infos
- name: Assert that fedora_bis container has the right image
@ -394,7 +394,7 @@
- name: Check for fedora_bis container
command: podman container exists fedora_bis
- name: Gather facts about fedora_bis container
podman_container_info:
containers.podman.podman_container_info:
name: fedora_bis
register: fedora_bis_infos
- name: Assert that fedora_bis container has the right image

View File

@ -15,7 +15,7 @@
# under the License.
- name: Gather podman infos
podman_container_info: {}
containers.podman.podman_container_info: {}
register: podman_containers
no_log: "{{ not (tripleo_container_manage_debug | bool) }}"
when:

View File

@ -34,7 +34,7 @@
loop_control:
label: "{{ lookup('dict', container_data).key }}"
loop_var: container_data
podman_container:
containers.podman.podman_container:
annotation: "{{ lookup('dict', container_data).value.annotation | default(omit) }}"
cap_add: "{{ lookup('dict', container_data).value.cap_add | default(omit) }}"
cap_drop: "{{ lookup('dict', container_data).value.cap_drop | default(omit) }}"

View File

@ -15,7 +15,7 @@
# under the License.
- name: Gather podman infos
podman_container_info: {}
containers.podman.podman_container_info: {}
register: podman_containers
no_log: "{{ tripleo_container_manage_hide_sensitive_logs | bool }}"
when:

View File

@ -32,11 +32,11 @@
state: latest
- name: Pull container image
podman_image:
containers.podman.podman_image:
name: fedora
- name: Create test containers
podman_container:
containers.podman.podman_container:
name: "{{ item }}"
interactive: true
tty: true

View File

@ -32,11 +32,11 @@
state: latest
- name: Pull container image
podman_image:
containers.podman.podman_image:
name: fedora
- name: Create test containers
podman_container:
containers.podman.podman_container:
name: "{{ item }}"
interactive: true
tty: true

View File

@ -32,11 +32,11 @@
state: latest
- name: Pull container image
podman_image:
containers.podman.podman_image:
name: fedora
- name: Create test containers
podman_container:
containers.podman.podman_container:
name: "{{ item }}"
interactive: true
tty: true
@ -48,7 +48,7 @@
- podman-container2
- name: Stop test containers
podman_container:
containers.podman.podman_container:
name: "{{ item }}"
state: stopped
with_items:

View File

@ -79,7 +79,7 @@
daemon_reload: true
- name: Stop and remove container if exists
podman_container:
containers.podman.podman_container:
name: "{{ container }}"
state: absent
register: result

View File

@ -32,11 +32,11 @@
state: latest
- name: Pull container image
podman_image:
containers.podman.podman_image:
name: fedora
- name: Create test containers
podman_container:
containers.podman.podman_container:
name: "{{ item }}"
interactive: true
tty: true

View File

@ -40,7 +40,7 @@
become: false
- name: Create test containers
podman_container:
containers.podman.podman_container:
name: keystone-podman
image: keystone-img
detach: true

View File

@ -35,11 +35,11 @@
- role: test_deps
post_tasks:
- name: pull an image
podman_image:
containers.podman.podman_image:
name: "ubi8:latest"
- name: Create a data container
podman_container:
containers.podman.podman_container:
name: "{{ item }}"
image: "ubi8:latest"
detach: true

View File

@ -41,12 +41,12 @@
state: disabled
- name: Ensure registry doesn't exist
podman_container:
containers.podman.podman_container:
name: registry
state: absent
- name: Pull ubuntu image
podman_image:
containers.podman.podman_image:
name: ubuntu
tag: 16.04
@ -63,7 +63,7 @@
executable: /bin/bash
- name: Create registry
podman_container:
containers.podman.podman_container:
name: registry
image: "registry:2.7.0"
restart_policy: always

View File

@ -10,7 +10,6 @@
- tripleo-ansible-centos-8-molecule-login_defs
- tripleo-ansible-centos-8-molecule-test_deps
- tripleo-ansible-centos-8-molecule-test_package_action
- tripleo-ansible-centos-8-molecule-tripleo-modules
- tripleo-ansible-centos-8-molecule-tripleo_bootstrap
- tripleo-ansible-centos-8-molecule-tripleo_cellv2
- tripleo-ansible-centos-8-molecule-tripleo_ceph_client
@ -72,7 +71,6 @@
- tripleo-ansible-centos-8-molecule-login_defs
- tripleo-ansible-centos-8-molecule-test_deps
- tripleo-ansible-centos-8-molecule-test_package_action
# - tripleo-ansible-centos-8-molecule-tripleo-modules
- tripleo-ansible-centos-8-molecule-tripleo_bootstrap
- tripleo-ansible-centos-8-molecule-tripleo_cellv2
- tripleo-ansible-centos-8-molecule-tripleo_ceph_client
@ -135,7 +133,6 @@
- tripleo-ansible-centos-8-molecule-login_defs
- tripleo-ansible-centos-8-molecule-test_deps
- tripleo-ansible-centos-8-molecule-test_package_action
- tripleo-ansible-centos-8-molecule-tripleo-modules
- tripleo-ansible-centos-8-molecule-tripleo_bootstrap
- tripleo-ansible-centos-8-molecule-tripleo_cellv2
- tripleo-ansible-centos-8-molecule-tripleo_ceph_client
@ -229,12 +226,6 @@
parent: tripleo-ansible-centos-8-base
vars:
tripleo_role_name: test_package_action
- job:
files:
- ^tripleo_ansible/ansible_plugins/.*$
name: tripleo-ansible-centos-8-molecule-tripleo-modules
parent: tripleo-ansible-centos-8-base
voting: false
- job:
files:
- ^tripleo_ansible/roles/tripleo_bootstrap/.*
@ -320,8 +311,6 @@
- ^tripleo_ansible/ansible_plugins/modules/container_config_data.py$
- ^tripleo_ansible/ansible_plugins/modules/container_puppet_config.py$
- ^tripleo_ansible/ansible_plugins/modules/container_startup_config.py$
- ^tripleo_ansible/ansible_plugins/modules/podman_container.py$
- ^tripleo_ansible/ansible_plugins/modules/podman_container_info.py$
name: tripleo-ansible-centos-8-molecule-tripleo_container_manage
parent: tripleo-ansible-centos-8-base
vars:

View File

@ -109,3 +109,11 @@
{{ tripleo_ansible_project_path }}/tripleo_ansible/ansible-role-requirements.yml
environment:
ANSIBLE_ROLES_PATH: "{{ tripleo_ansible_project_path }}/tripleo_ansible/roles.galaxy"
- name: Get Ansible Galaxy collections
command: >-
{{ ansible_user_dir }}/test-python/bin/ansible-galaxy collection install
-fr
{{ tripleo_ansible_project_path }}/tripleo_ansible/requirements.yml
environment:
ANSIBLE_ROLES_PATH: "{{ tripleo_ansible_project_path }}/tripleo_ansible/roles.galaxy"