v2
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
# See template for more information:
|
||||
# https://github.com/ansible/ansible/blob/devel/test/lib/ansible_test/config/config.yml
|
||||
modules:
|
||||
python_requires: default
|
||||
@@ -0,0 +1,15 @@
|
||||
- hosts: localhost
|
||||
vars:
|
||||
docker_test_image_alpine: quay.io/ansible/docker-test-containers:alpine3.8
|
||||
tasks:
|
||||
- name: Find all roles
|
||||
find:
|
||||
paths:
|
||||
- "{{ (playbook_dir | default('.')) ~ '/roles' }}"
|
||||
file_type: directory
|
||||
depth: 1
|
||||
register: result
|
||||
- name: Include all roles
|
||||
include_role:
|
||||
name: "{{ item }}"
|
||||
loop: "{{ result.files | map(attribute='path') | map('regex_replace', '.*/', '') | sort }}"
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
- name: Retrieve information on current container
|
||||
community.docker.current_container_facts:
|
||||
register: result
|
||||
|
||||
# The following two tasks are useful if we ever have to debug why this fails.
|
||||
|
||||
- name: Print all Ansible facts
|
||||
debug:
|
||||
var: ansible_facts
|
||||
|
||||
- name: Read some files
|
||||
slurp:
|
||||
src: "{{ item }}"
|
||||
loop:
|
||||
- /proc/self/cpuset
|
||||
- /proc/1/cgroup
|
||||
- /proc/1/environ
|
||||
|
||||
- name: Print facts returned by module
|
||||
debug:
|
||||
var: result.ansible_facts
|
||||
|
||||
- name: Validate results
|
||||
assert:
|
||||
that:
|
||||
- ansible_module_running_in_container
|
||||
- ansible_module_container_type != ''
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# Create random name prefix (for containers, networks, ...)
|
||||
- name: Create random container name prefix
|
||||
set_fact:
|
||||
cname_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
|
||||
- name: Create project and container names
|
||||
set_fact:
|
||||
pname: "{{ cname_prefix }}"
|
||||
cname: "{{ cname_prefix }}-hi"
|
||||
|
||||
- name: Define service
|
||||
set_fact:
|
||||
test_service: |
|
||||
version: '3'
|
||||
services:
|
||||
{{ cname }}:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
stop_grace_period: 1s
|
||||
|
||||
- name: Present
|
||||
community.docker.docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
remove_orphans: true
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
|
||||
- name: Absent
|
||||
community.docker.docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: absent
|
||||
remove_orphans: true
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# Create random name prefix (for containers, networks, ...)
|
||||
- name: Create random container name prefix
|
||||
set_fact:
|
||||
cname_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
|
||||
- name: Make sure image is absent
|
||||
community.docker.docker_image:
|
||||
name: "{{ docker_test_image_alpine }}"
|
||||
state: absent
|
||||
|
||||
- name: Make sure image is pulled
|
||||
community.docker.docker_image:
|
||||
name: "{{ docker_test_image_alpine }}"
|
||||
source: pull
|
||||
|
||||
- name: Start container
|
||||
community.docker.docker_container:
|
||||
name: "{{ cname_prefix }}-1"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
state: started
|
||||
|
||||
- name: Remove container
|
||||
community.docker.docker_container:
|
||||
name: "{{ cname_prefix }}-1"
|
||||
state: absent
|
||||
stop_timeout: 1
|
||||
force_kill: yes
|
||||
@@ -0,0 +1,2 @@
|
||||
---
|
||||
# Currently the docker_stack* modules are not supported in the EE since we'd need to install the Docker CLI client
|
||||
@@ -0,0 +1 @@
|
||||
hidden
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eux
|
||||
|
||||
[ -f "${INVENTORY}" ]
|
||||
|
||||
# Run connection tests with both the default and C locale.
|
||||
|
||||
ansible-playbook test_connection.yml -i "${INVENTORY}" "$@"
|
||||
LC_ALL=C LANG=C ansible-playbook test_connection.yml -i "${INVENTORY}" "$@"
|
||||
@@ -0,0 +1,43 @@
|
||||
- hosts: "{{ target_hosts }}"
|
||||
gather_facts: no
|
||||
serial: 1
|
||||
tasks:
|
||||
|
||||
### raw with unicode arg and output
|
||||
|
||||
- name: raw with unicode arg and output
|
||||
raw: echo 汉语
|
||||
register: command
|
||||
- name: check output of raw with unicode arg and output
|
||||
assert:
|
||||
that:
|
||||
- "'汉语' in command.stdout"
|
||||
- command is changed # as of 2.2, raw should default to changed: true for consistency w/ shell/command/script modules
|
||||
|
||||
### copy local file with unicode filename and content
|
||||
|
||||
- name: create local file with unicode filename and content
|
||||
local_action: lineinfile dest={{ local_tmp }}-汉语/汉语.txt create=true line=汉语
|
||||
- name: remove remote file with unicode filename and content
|
||||
action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语/汉语.txt state=absent"
|
||||
- name: create remote directory with unicode name
|
||||
action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语 state=directory"
|
||||
- name: copy local file with unicode filename and content
|
||||
action: "{{ action_prefix }}copy src={{ local_tmp }}-汉语/汉语.txt dest={{ remote_tmp }}-汉语/汉语.txt"
|
||||
|
||||
### fetch remote file with unicode filename and content
|
||||
|
||||
- name: remove local file with unicode filename and content
|
||||
local_action: file path={{ local_tmp }}-汉语/汉语.txt state=absent
|
||||
- name: fetch remote file with unicode filename and content
|
||||
fetch: src={{ remote_tmp }}-汉语/汉语.txt dest={{ local_tmp }}-汉语/汉语.txt fail_on_missing=true validate_checksum=true flat=true
|
||||
|
||||
### remove local and remote temp files
|
||||
|
||||
- name: remove local temp file
|
||||
local_action: file path={{ local_tmp }}-汉语 state=absent
|
||||
- name: remove remote temp file
|
||||
action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语 state=absent"
|
||||
|
||||
### test wait_for_connection plugin
|
||||
- ansible.builtin.wait_for_connection:
|
||||
@@ -0,0 +1,3 @@
|
||||
shippable/posix/group4
|
||||
skip/docker # coverage does not work if we're inside a docker container, since we cannot access this container's /tmp dir from the new container
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eux
|
||||
|
||||
# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
|
||||
# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
|
||||
|
||||
PYTHON="$(command -v python3 python | head -n1)"
|
||||
|
||||
group=$(${PYTHON} -c \
|
||||
"from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
|
||||
|
||||
cd ../connection
|
||||
|
||||
INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
|
||||
-e target_hosts="${group}" \
|
||||
-e action_prefix= \
|
||||
-e local_tmp=/tmp/ansible-local \
|
||||
-e remote_tmp=/tmp/ansible-remote \
|
||||
"$@"
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# If you use another image, you possibly also need to adjust
|
||||
# ansible_python_interpreter in test_connection.inventory.
|
||||
source ../setup_docker/vars/main.env
|
||||
IMAGE="${DOCKER_TEST_IMAGE_PYTHON3}"
|
||||
|
||||
# Setup phase
|
||||
|
||||
echo "Setup"
|
||||
ANSIBLE_ROLES_PATH=.. ansible-playbook setup.yml
|
||||
|
||||
# If docker wasn't installed, don't run the tests
|
||||
if [ "$(command -v docker)" == "" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
# Test phase
|
||||
|
||||
CONTAINER_SUFFIX=-${RANDOM}
|
||||
|
||||
DOCKER_CONTAINERS="docker-connection-test-container${CONTAINER_SUFFIX}"
|
||||
|
||||
[[ -n "$DEBUG" || -n "$ANSIBLE_DEBUG" ]] && set -x
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cleanup() {
|
||||
echo "Cleanup"
|
||||
docker rm -f ${DOCKER_CONTAINERS}
|
||||
echo "Shutdown"
|
||||
ANSIBLE_ROLES_PATH=.. ansible-playbook shutdown.yml
|
||||
echo "Done"
|
||||
}
|
||||
|
||||
trap cleanup INT TERM EXIT
|
||||
|
||||
echo "Start containers"
|
||||
for CONTAINER in ${DOCKER_CONTAINERS}; do
|
||||
if [ "${ANSIBLE_TEST_COVERAGE:-}" == "" ]; then
|
||||
docker run --rm --name ${CONTAINER} --detach "${IMAGE}" /bin/sh -c 'sleep 10m'
|
||||
else
|
||||
docker run --rm --name ${CONTAINER} --detach -v /tmp:/tmp "${IMAGE}" /bin/sh -c 'sleep 10m'
|
||||
docker exec ${CONTAINER} pip3 install coverage
|
||||
fi
|
||||
echo ${CONTAINER}
|
||||
done
|
||||
|
||||
cat > test_connection.inventory << EOF
|
||||
[docker]
|
||||
docker-no-pipelining ansible_pipelining=false
|
||||
docker-pipelining ansible_pipelining=true
|
||||
|
||||
[docker:vars]
|
||||
ansible_host=docker-connection-test-container${CONTAINER_SUFFIX}
|
||||
ansible_connection=community.docker.docker
|
||||
ansible_python_interpreter=/usr/local/bin/python3
|
||||
EOF
|
||||
|
||||
echo "Run tests"
|
||||
./runme-connection.sh "$@"
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
vars:
|
||||
docker_skip_cleanup: yes
|
||||
|
||||
tasks:
|
||||
- name: Setup docker
|
||||
import_role:
|
||||
name: setup_docker
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
vars:
|
||||
docker_skip_cleanup: yes
|
||||
|
||||
tasks:
|
||||
- name: Remove docker packages
|
||||
action: "{{ ansible_facts.pkg_mgr }}"
|
||||
args:
|
||||
name:
|
||||
- docker
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
state: absent
|
||||
@@ -0,0 +1,3 @@
|
||||
shippable/posix/group4
|
||||
skip/docker # coverage does not work if we're inside a docker container, since we cannot access this container's /tmp dir from the new container
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eux
|
||||
|
||||
# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
|
||||
# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
|
||||
|
||||
PYTHON="$(command -v python3 python | head -n1)"
|
||||
|
||||
group=$(${PYTHON} -c \
|
||||
"from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
|
||||
|
||||
cd ../connection
|
||||
|
||||
INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
|
||||
-e target_hosts="${group}" \
|
||||
-e action_prefix= \
|
||||
-e local_tmp=/tmp/ansible-local \
|
||||
-e remote_tmp=/tmp/ansible-remote \
|
||||
"$@"
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# If you use another image, you possibly also need to adjust
|
||||
# ansible_python_interpreter in test_connection.inventory.
|
||||
source ../setup_docker/vars/main.env
|
||||
IMAGE="${DOCKER_TEST_IMAGE_PYTHON3}"
|
||||
|
||||
# Setup phase
|
||||
|
||||
echo "Setup"
|
||||
ANSIBLE_ROLES_PATH=.. ansible-playbook setup.yml
|
||||
|
||||
# If docker wasn't installed, don't run the tests
|
||||
if [ "$(command -v docker)" == "" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
# Test phase
|
||||
|
||||
CONTAINER_SUFFIX=-${RANDOM}
|
||||
|
||||
DOCKER_CONTAINERS="docker-connection-test-container${CONTAINER_SUFFIX}"
|
||||
|
||||
[[ -n "$DEBUG" || -n "$ANSIBLE_DEBUG" ]] && set -x
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cleanup() {
|
||||
echo "Cleanup"
|
||||
docker rm -f ${DOCKER_CONTAINERS}
|
||||
echo "Shutdown"
|
||||
ANSIBLE_ROLES_PATH=.. ansible-playbook shutdown.yml
|
||||
echo "Done"
|
||||
}
|
||||
|
||||
trap cleanup INT TERM EXIT
|
||||
|
||||
echo "Start containers"
|
||||
for CONTAINER in ${DOCKER_CONTAINERS}; do
|
||||
if [ "${ANSIBLE_TEST_COVERAGE:-}" == "" ]; then
|
||||
docker run --rm --name ${CONTAINER} --detach "${IMAGE}" /bin/sh -c 'sleep 10m'
|
||||
else
|
||||
docker run --rm --name ${CONTAINER} --detach -v /tmp:/tmp "${IMAGE}" /bin/sh -c 'sleep 10m'
|
||||
docker exec ${CONTAINER} pip3 install coverage
|
||||
fi
|
||||
echo ${CONTAINER}
|
||||
done
|
||||
|
||||
cat > test_connection.inventory << EOF
|
||||
[docker_api]
|
||||
docker_api-no-pipelining ansible_pipelining=false
|
||||
docker_api-pipelining ansible_pipelining=true
|
||||
|
||||
[docker_api:vars]
|
||||
ansible_host=docker-connection-test-container${CONTAINER_SUFFIX}
|
||||
ansible_connection=community.docker.docker_api
|
||||
ansible_python_interpreter=/usr/local/bin/python3
|
||||
EOF
|
||||
|
||||
echo "Run tests"
|
||||
./runme-connection.sh "$@"
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
vars:
|
||||
docker_skip_cleanup: yes
|
||||
|
||||
tasks:
|
||||
- name: Setup docker
|
||||
import_role:
|
||||
name: setup_docker
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
vars:
|
||||
docker_skip_cleanup: yes
|
||||
|
||||
tasks:
|
||||
- name: Remove docker packages
|
||||
action: "{{ ansible_facts.pkg_mgr }}"
|
||||
args:
|
||||
name:
|
||||
- docker
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
state: absent
|
||||
@@ -0,0 +1,4 @@
|
||||
shippable/posix/group5
|
||||
skip/docker # this requires unfettered access to the container host
|
||||
skip/rhel7.9 # nsenter does not work out of the box
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eux
|
||||
|
||||
# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
|
||||
# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
|
||||
|
||||
PYTHON="$(command -v python3 python | head -n1)"
|
||||
|
||||
group=$(${PYTHON} -c \
|
||||
"from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
|
||||
|
||||
cd ../connection
|
||||
|
||||
INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
|
||||
-e target_hosts="${group}" \
|
||||
-e action_prefix= \
|
||||
-e local_tmp=/tmp/ansible-local \
|
||||
-e remote_tmp=/tmp/ansible-remote \
|
||||
"$@"
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
[[ -n "${DEBUG:-}" || -n "${ANSIBLE_DEBUG:-}" ]] && set -x
|
||||
|
||||
readonly IMAGE="quay.io/ansible/ansible-runner:devel"
|
||||
readonly PYTHON="$(command -v python3 python | head -n1)"
|
||||
|
||||
# Determine collection root
|
||||
COLLECTION_ROOT=./
|
||||
while true; do
|
||||
if [ -e ${COLLECTION_ROOT}galaxy.yml ] || [ -e ${COLLECTION_ROOT}MANIFEST.json ]; then
|
||||
break
|
||||
fi
|
||||
COLLECTION_ROOT="${COLLECTION_ROOT}../"
|
||||
done
|
||||
readonly COLLECTION_ROOT="$(cd ${COLLECTION_ROOT} ; pwd)"
|
||||
|
||||
# Setup phase
|
||||
echo "Setup"
|
||||
ANSIBLE_ROLES_PATH=.. ansible-playbook setup.yml
|
||||
|
||||
# If docker wasn't installed, don't run the tests
|
||||
if [ "$(command -v docker)" == "" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
echo "Cleanup"
|
||||
echo "Shutdown"
|
||||
ANSIBLE_ROLES_PATH=.. ansible-playbook shutdown.yml
|
||||
echo "Done"
|
||||
}
|
||||
|
||||
envs=(--env "HOME=${HOME:-}")
|
||||
while IFS=$'\0' read -d '' -r line; do
|
||||
key="$(echo "$line" | cut -d= -f1)"
|
||||
value="$(echo "$line" | cut -d= -f2-)"
|
||||
if [[ "${key}" =~ ^(ANSIBLE_|JUNIT_OUTPUT_DIR$|OUTPUT_DIR$|PYTHONPATH$) ]]; then
|
||||
envs+=(--env "${key}=${value}")
|
||||
fi
|
||||
done < <(printenv -0)
|
||||
|
||||
# Test phase
|
||||
cat > test_connection.inventory << EOF
|
||||
[nsenter]
|
||||
nsenter-no-pipelining ansible_pipelining=false
|
||||
nsenter-pipelining ansible_pipelining=true
|
||||
|
||||
[nsenter:vars]
|
||||
ansible_host=localhost
|
||||
ansible_connection=community.docker.nsenter
|
||||
ansible_host_volume_mount=/host
|
||||
ansible_nsenter_pid=1
|
||||
ansible_python_interpreter=${PYTHON}
|
||||
EOF
|
||||
|
||||
echo "Run tests"
|
||||
set -x
|
||||
docker run \
|
||||
-i \
|
||||
--rm \
|
||||
--privileged \
|
||||
--pid host \
|
||||
"${envs[@]}" \
|
||||
--volume "${COLLECTION_ROOT}:${COLLECTION_ROOT}" \
|
||||
--workdir "$(pwd)" \
|
||||
"${IMAGE}" \
|
||||
./runme-connection.sh "$@"
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
vars:
|
||||
docker_skip_cleanup: yes
|
||||
|
||||
tasks:
|
||||
- name: Setup docker
|
||||
import_role:
|
||||
name: setup_docker
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
vars:
|
||||
docker_skip_cleanup: yes
|
||||
|
||||
tasks:
|
||||
- name: Remove docker packages
|
||||
action: "{{ ansible_facts.pkg_mgr }}"
|
||||
args:
|
||||
name:
|
||||
- docker
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
state: absent
|
||||
@@ -0,0 +1,2 @@
|
||||
needs/target/connection
|
||||
hidden
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eux
|
||||
|
||||
# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
|
||||
# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
|
||||
|
||||
PYTHON="$(command -v python3 python | head -n1)"
|
||||
|
||||
group=$(${PYTHON} -c \
|
||||
"from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
|
||||
|
||||
cd ../connection
|
||||
|
||||
INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
|
||||
-e target_hosts="${group}" \
|
||||
-e action_prefix= \
|
||||
-e local_tmp=/tmp/ansible-local \
|
||||
-e remote_tmp=/tmp/ansible-remote \
|
||||
"$@"
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group4
|
||||
destructive
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker_compose
|
||||
- setup_remote_tmp_dir
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# Create random name prefix (for containers, networks, ...)
|
||||
- name: Create random container name prefix
|
||||
set_fact:
|
||||
cname_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
cnames: []
|
||||
dnetworks: []
|
||||
|
||||
- debug:
|
||||
msg: "Using container name prefix {{ cname_prefix }}"
|
||||
|
||||
# Run the tests
|
||||
- block:
|
||||
- include_tasks: run-test.yml
|
||||
with_fileglob:
|
||||
- "tests/*.yml"
|
||||
|
||||
always:
|
||||
- name: "Make sure all containers are removed"
|
||||
docker_container:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
with_items: "{{ cnames }}"
|
||||
diff: no
|
||||
- name: "Make sure all networks are removed"
|
||||
docker_network:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force: yes
|
||||
with_items: "{{ dnetworks }}"
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
diff: no
|
||||
|
||||
when: has_docker_compose and docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run all docker_container tests!"
|
||||
when: has_docker_compose and not(docker_py_version is version('3.5.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: "Loading tasks from {{ item }}"
|
||||
include_tasks: "{{ item }}"
|
||||
@@ -0,0 +1,239 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
pname: "{{ cname_prefix }}"
|
||||
cname_1: "{{ cname_prefix ~ '1' }}"
|
||||
cname_2: "{{ cname_prefix ~ '2' }}"
|
||||
|
||||
####################################################################
|
||||
## Profiles ########################################################
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: Define service
|
||||
set_fact:
|
||||
test_service: |
|
||||
version: '3'
|
||||
services:
|
||||
{{ cname_1 }}:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
profiles:
|
||||
- profile_1
|
||||
- profile_all
|
||||
stop_grace_period: 1s
|
||||
{{ cname_2 }}:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
profiles:
|
||||
- profile_2
|
||||
- profile_all
|
||||
stop_grace_period: 1s
|
||||
test_cases:
|
||||
- test_name: no services enabled
|
||||
- test_name: enable 1
|
||||
profiles_value:
|
||||
- profile_1
|
||||
- test_name: stop all services
|
||||
profiles_value:
|
||||
- profile_1
|
||||
stopped_value: true
|
||||
- test_name: enable 2
|
||||
profiles_value:
|
||||
- profile_2
|
||||
- test_name: stop all services
|
||||
profiles_value:
|
||||
- profile_2
|
||||
stopped_value: true
|
||||
- test_name: enable both
|
||||
profiles_value:
|
||||
- profile_1
|
||||
- profile_2
|
||||
- test_name: stop all services
|
||||
profiles_value:
|
||||
- profile_1
|
||||
- profile_2
|
||||
stopped_value: true
|
||||
- test_name: enable all
|
||||
profiles_value:
|
||||
- profile_all
|
||||
|
||||
- name: Profiles ({{ test_case.test_name }})
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
profiles: "{{ test_case.profiles_value | default(omit) }}"
|
||||
stopped: "{{ test_case.stopped_value | default(omit) }}"
|
||||
state: present
|
||||
register: profiles_outputs
|
||||
loop: "{{ test_cases }}"
|
||||
loop_control:
|
||||
loop_var: test_case
|
||||
|
||||
- name: Cleanup
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: absent
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- profiles_outputs.results[0] is not changed
|
||||
- profiles_outputs.results[1].services[cname_1][cname_1_name].state.running
|
||||
- profiles_outputs.results[1].services[cname_2] == {}
|
||||
- not profiles_outputs.results[2].services[cname_1][cname_1_name].state.running
|
||||
- profiles_outputs.results[2].services[cname_2] == {}
|
||||
- not profiles_outputs.results[3].services[cname_1][cname_1_name].state.running
|
||||
- profiles_outputs.results[3].services[cname_2][cname_2_name].state.running
|
||||
- not profiles_outputs.results[4].services[cname_1][cname_1_name].state.running
|
||||
- not profiles_outputs.results[4].services[cname_2][cname_2_name].state.running
|
||||
- profiles_outputs.results[5].services[cname_1][cname_1_name].state.running
|
||||
- profiles_outputs.results[5].services[cname_2][cname_2_name].state.running
|
||||
- not profiles_outputs.results[6].services[cname_1][cname_1_name].state.running
|
||||
- not profiles_outputs.results[6].services[cname_2][cname_2_name].state.running
|
||||
- profiles_outputs.results[7].services[cname_1][cname_1_name].state.running
|
||||
- profiles_outputs.results[7].services[cname_2][cname_2_name].state.running
|
||||
vars:
|
||||
cname_1_name: "{{ pname + '_' + cname_1 + '_1' }}"
|
||||
cname_2_name: "{{ pname + '_' + cname_2 + '_1' }}"
|
||||
when: docker_compose_version is version('1.28.0', '>=')
|
||||
|
||||
####################################################################
|
||||
## Env_file ########################################################
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: Define service and files
|
||||
set_fact:
|
||||
compose_file: "{{ remote_tmp_dir }}/docker-compose.yml"
|
||||
env_file: "{{ remote_tmp_dir }}/.env"
|
||||
env_sleep_cmd: sleep 10m
|
||||
new_env_file: "{{ remote_tmp_dir }}/new.env"
|
||||
new_env_sleep_cmd: sleep 20m
|
||||
test_service: |
|
||||
version: '3'
|
||||
services:
|
||||
{{ cname_1 }}:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "${SLEEP_CMD}"'
|
||||
stop_grace_period: 1s
|
||||
|
||||
- name: Define testcases
|
||||
set_fact:
|
||||
test_cases:
|
||||
- test_name: Without env_file option
|
||||
- test_name: With env_file option
|
||||
env_file: "{{ new_env_file }}"
|
||||
|
||||
- name: Generate compose file
|
||||
ansible.builtin.copy:
|
||||
content: "{{ test_service }}"
|
||||
dest: "{{ compose_file }}"
|
||||
|
||||
- name: Generate .env file
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
SLEEP_CMD="{{ env_sleep_cmd }}"
|
||||
dest: "{{ env_file }}"
|
||||
|
||||
- name: Generate new.env file
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
SLEEP_CMD="{{ new_env_sleep_cmd }}"
|
||||
dest: "{{ new_env_file }}"
|
||||
|
||||
- name: Env_file
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
project_src: "{{ remote_tmp_dir }}"
|
||||
env_file: "{{ test_case.env_file | default(omit) }}"
|
||||
register: env_file_outputs
|
||||
loop: "{{ test_cases }}"
|
||||
loop_control:
|
||||
loop_var: test_case
|
||||
|
||||
- name: Cleanup
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: absent
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "env_sleep_cmd is in (env_file_outputs.results[0].services[cname_1][cname_1_name].cmd | join(' '))"
|
||||
- "new_env_sleep_cmd is in (env_file_outputs.results[1].services[cname_1][cname_1_name].cmd | join(' '))"
|
||||
vars:
|
||||
cname_1_name: "{{ pname + '_' + cname_1 + '_1' }}"
|
||||
cname_2_name: "{{ pname + '_' + cname_2 + '_1' }}"
|
||||
|
||||
- name: Remove files
|
||||
ansible.builtin.file:
|
||||
path: "{{ file_path }}"
|
||||
state: absent
|
||||
loop_control:
|
||||
loop_var: file_path
|
||||
loop:
|
||||
- "{{ compose_file }}"
|
||||
- "{{ env_file }}"
|
||||
- "{{ new_env_file }}"
|
||||
when: docker_compose_version is version('1.25.0', '>=')
|
||||
|
||||
####################################################################
|
||||
## Project_src #####################################################
|
||||
####################################################################
|
||||
|
||||
- name: Define service and files
|
||||
set_fact:
|
||||
compose_file: "{{ remote_tmp_dir }}/docker-compose.yml"
|
||||
env_sleep_cmd: sleep 10m
|
||||
new_env_sleep_cmd: sleep 20m
|
||||
test_service: |
|
||||
version: '3'
|
||||
services:
|
||||
{{ cname_1 }}:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c 10m'
|
||||
stop_grace_period: 1s
|
||||
|
||||
- name: Generate compose file
|
||||
ansible.builtin.copy:
|
||||
content: "{{ test_service }}"
|
||||
dest: "{{ compose_file }}"
|
||||
|
||||
- name: Start with project_src
|
||||
docker_compose:
|
||||
project_src: "{{ remote_tmp_dir }}"
|
||||
register: project_src_1
|
||||
|
||||
- name: Start with project_src (idempotent)
|
||||
docker_compose:
|
||||
project_src: "{{ remote_tmp_dir }}"
|
||||
register: project_src_2
|
||||
|
||||
- name: Stop with project_src
|
||||
docker_compose:
|
||||
project_src: "{{ remote_tmp_dir }}"
|
||||
state: absent
|
||||
register: project_src_3
|
||||
|
||||
- name: Stop with project_src (idempotent)
|
||||
docker_compose:
|
||||
project_src: "{{ remote_tmp_dir }}"
|
||||
state: absent
|
||||
register: project_src_4
|
||||
|
||||
- name: Remove files
|
||||
ansible.builtin.file:
|
||||
path: "{{ file_path }}"
|
||||
state: absent
|
||||
loop_control:
|
||||
loop_var: file_path
|
||||
loop:
|
||||
- "{{ compose_file }}"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- project_src_1 is changed
|
||||
# - project_src_2 is not changed -- for some reason, this currently fails!
|
||||
- project_src_3 is changed
|
||||
- project_src_4 is not changed
|
||||
@@ -0,0 +1,229 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
pname: "{{ cname_prefix }}"
|
||||
cname: "{{ cname_prefix ~ '-hi' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [pname ~ '-' ~ cname] }}"
|
||||
dnetworks: "{{ dnetworks + [pname ~ '_default'] }}"
|
||||
|
||||
- name: Define service
|
||||
set_fact:
|
||||
test_service: |
|
||||
version: '3'
|
||||
services:
|
||||
{{ cname }}:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
stop_grace_period: 1s
|
||||
test_service_mod: |
|
||||
version: '3'
|
||||
services:
|
||||
{{ cname }}:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 15m"'
|
||||
stop_grace_period: 1s
|
||||
|
||||
####################################################################
|
||||
## Present #########################################################
|
||||
####################################################################
|
||||
|
||||
- name: Present (check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
check_mode: yes
|
||||
register: present_1
|
||||
|
||||
- name: Present
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
register: present_2
|
||||
|
||||
- name: Present (idempotent)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
register: present_3
|
||||
|
||||
- name: Present (idempotent check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
check_mode: yes
|
||||
register: present_4
|
||||
|
||||
- name: Present (changed check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service_mod | from_yaml }}"
|
||||
check_mode: yes
|
||||
register: present_5
|
||||
|
||||
- name: Present (changed)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service_mod | from_yaml }}"
|
||||
register: present_6
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- present_1 is changed
|
||||
- present_2 is changed
|
||||
- present_3 is not changed
|
||||
- present_4 is not changed
|
||||
- present_5 is changed
|
||||
- present_6 is changed
|
||||
|
||||
####################################################################
|
||||
## Absent ##########################################################
|
||||
####################################################################
|
||||
|
||||
- name: Absent (check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: absent
|
||||
definition: "{{ test_service_mod | from_yaml }}"
|
||||
check_mode: yes
|
||||
register: absent_1
|
||||
|
||||
- name: Absent
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: absent
|
||||
definition: "{{ test_service_mod | from_yaml }}"
|
||||
register: absent_2
|
||||
|
||||
- name: Absent (idempotent)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: absent
|
||||
definition: "{{ test_service_mod | from_yaml }}"
|
||||
register: absent_3
|
||||
|
||||
- name: Absent (idempotent check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: absent
|
||||
definition: "{{ test_service_mod | from_yaml }}"
|
||||
check_mode: yes
|
||||
register: absent_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- absent_1 is changed
|
||||
- absent_2 is changed
|
||||
- absent_3 is not changed
|
||||
- absent_4 is not changed
|
||||
|
||||
####################################################################
|
||||
## Stopping and starting ###########################################
|
||||
####################################################################
|
||||
|
||||
- name: Present stopped (check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
stopped: true
|
||||
check_mode: yes
|
||||
register: present_1
|
||||
|
||||
- name: Present stopped
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
stopped: true
|
||||
register: present_2
|
||||
|
||||
- name: Present stopped (idempotent)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
stopped: true
|
||||
register: present_3
|
||||
|
||||
- name: Present stopped (idempotent check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
stopped: true
|
||||
check_mode: yes
|
||||
register: present_4
|
||||
|
||||
- name: Started (check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
check_mode: yes
|
||||
register: started_1
|
||||
|
||||
- name: Started
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
register: started_2
|
||||
|
||||
- name: Started (idempotent)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
register: started_3
|
||||
|
||||
- name: Started (idempotent check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
check_mode: yes
|
||||
register: started_4
|
||||
|
||||
- name: Stopped (check)
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
stopped: true
|
||||
check_mode: yes
|
||||
register: stopped_1
|
||||
|
||||
- name: Stopped
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: present
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
stopped: true
|
||||
register: stopped_2
|
||||
|
||||
- name: Cleanup
|
||||
docker_compose:
|
||||
project_name: "{{ pname }}"
|
||||
state: absent
|
||||
definition: "{{ test_service | from_yaml }}"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- present_1 is changed
|
||||
- present_2 is changed
|
||||
- present_3 is not changed
|
||||
- present_4 is not changed
|
||||
- started_1 is changed
|
||||
- started_2 is changed
|
||||
- started_3 is not changed
|
||||
- started_4 is not changed
|
||||
- stopped_1 is changed
|
||||
- stopped_2 is changed
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group3
|
||||
destructive
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
- setup_remote_tmp_dir
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- include_tasks: test_docker_config.yml
|
||||
when: docker_py_version is version('2.6.0', '>=') and docker_api_version is version('1.30', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_config tests!"
|
||||
when: not(docker_py_version is version('2.6.0', '>=') and docker_api_version is version('1.30', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,330 @@
|
||||
---
|
||||
- block:
|
||||
- shell: "docker info --format '{% raw %}{{json .}}{% endraw %}' | python -m json.tool"
|
||||
|
||||
- name: Make sure we're not already using Docker swarm
|
||||
docker_swarm:
|
||||
state: absent
|
||||
force: true
|
||||
|
||||
- shell: "docker info --format '{% raw %}{{json .}}{% endraw %}' | python -m json.tool"
|
||||
|
||||
- name: Create a Swarm cluster
|
||||
docker_swarm:
|
||||
name: default
|
||||
state: present
|
||||
advertise_addr: "{{ansible_default_ipv4.address}}"
|
||||
|
||||
- name: Parameter name should be required
|
||||
docker_config:
|
||||
state: present
|
||||
ignore_errors: yes
|
||||
register: output
|
||||
|
||||
- name: Assert failure when called with no name
|
||||
assert:
|
||||
that:
|
||||
- 'output is failed'
|
||||
- 'output.msg == "missing required arguments: name"'
|
||||
|
||||
- name: Test parameters
|
||||
docker_config:
|
||||
name: foo
|
||||
state: present
|
||||
ignore_errors: yes
|
||||
register: output
|
||||
|
||||
- name: Assert failure when called with no data
|
||||
assert:
|
||||
that:
|
||||
- 'output is failed'
|
||||
- 'output.msg == "state is present but any of the following are missing: data, data_src"'
|
||||
|
||||
- name: Create config
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: opensesame!
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Create variable config_id
|
||||
set_fact:
|
||||
config_id: "{{ output.config_id }}"
|
||||
|
||||
- name: Inspect config
|
||||
command: "docker config inspect {{ config_id }}"
|
||||
register: inspect
|
||||
ignore_errors: yes
|
||||
|
||||
- debug:
|
||||
var: inspect
|
||||
|
||||
- name: Assert config creation succeeded
|
||||
assert:
|
||||
that:
|
||||
- "'db_password' in inspect.stdout"
|
||||
- "'ansible_key' in inspect.stdout"
|
||||
when: inspect is not failed
|
||||
- assert:
|
||||
that:
|
||||
- "'is too new. Maximum supported API version is' in inspect.stderr"
|
||||
when: inspect is failed
|
||||
|
||||
- name: Create config again
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: opensesame!
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Assert create config is idempotent
|
||||
assert:
|
||||
that:
|
||||
- output is not changed
|
||||
|
||||
- name: Write config into file
|
||||
copy:
|
||||
dest: "{{ remote_tmp_dir }}/data"
|
||||
content: |-
|
||||
opensesame!
|
||||
|
||||
- name: Create config again (from file)
|
||||
docker_config:
|
||||
name: db_password
|
||||
data_src: "{{ remote_tmp_dir }}/data"
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Assert create config is idempotent
|
||||
assert:
|
||||
that:
|
||||
- output is not changed
|
||||
|
||||
- name: Create config again (base64)
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: b3BlbnNlc2FtZSE=
|
||||
data_is_b64: true
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Assert create config (base64) is idempotent
|
||||
assert:
|
||||
that:
|
||||
- output is not changed
|
||||
|
||||
- name: Update config
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: newpassword!
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Assert config was updated
|
||||
assert:
|
||||
that:
|
||||
- output is changed
|
||||
- output.config_id != config_id
|
||||
|
||||
- name: Remove config
|
||||
docker_config:
|
||||
name: db_password
|
||||
state: absent
|
||||
|
||||
- name: Check that config is removed
|
||||
command: "docker config inspect {{ config_id }}"
|
||||
register: output
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Assert config was removed
|
||||
assert:
|
||||
that:
|
||||
- output is failed
|
||||
|
||||
- name: Remove config
|
||||
docker_config:
|
||||
name: db_password
|
||||
state: absent
|
||||
register: output
|
||||
|
||||
- name: Assert remove config is idempotent
|
||||
assert:
|
||||
that:
|
||||
- output is not changed
|
||||
|
||||
# Rolling update
|
||||
|
||||
- name: Create rolling config
|
||||
docker_config:
|
||||
name: rolling_password
|
||||
data: opensesame!
|
||||
rolling_versions: true
|
||||
state: present
|
||||
register: original_output
|
||||
|
||||
- name: Create variable config_id
|
||||
set_fact:
|
||||
config_id: "{{ original_output.config_id }}"
|
||||
|
||||
- name: Inspect config
|
||||
command: "docker config inspect {{ config_id }}"
|
||||
register: inspect
|
||||
ignore_errors: yes
|
||||
|
||||
- debug:
|
||||
var: inspect
|
||||
|
||||
- name: Assert config creation succeeded
|
||||
assert:
|
||||
that:
|
||||
- "'rolling_password' in inspect.stdout"
|
||||
- "'ansible_key' in inspect.stdout"
|
||||
- "'ansible_version' in inspect.stdout"
|
||||
- original_output.config_name == 'rolling_password_v1'
|
||||
when: inspect is not failed
|
||||
- assert:
|
||||
that:
|
||||
- "'is too new. Maximum supported API version is' in inspect.stderr"
|
||||
when: inspect is failed
|
||||
|
||||
- name: Create config again
|
||||
docker_config:
|
||||
name: rolling_password
|
||||
data: newpassword!
|
||||
rolling_versions: true
|
||||
state: present
|
||||
register: new_output
|
||||
|
||||
- name: Assert that new version is created
|
||||
assert:
|
||||
that:
|
||||
- new_output is changed
|
||||
- new_output.config_id != original_output.config_id
|
||||
- new_output.config_name != original_output.config_name
|
||||
- new_output.config_name == 'rolling_password_v2'
|
||||
|
||||
- name: Remove rolling configs
|
||||
docker_config:
|
||||
name: rolling_password
|
||||
rolling_versions: true
|
||||
state: absent
|
||||
|
||||
- name: Check that config is removed
|
||||
command: "docker config inspect {{ original_output.config_id }}"
|
||||
register: output
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Assert config was removed
|
||||
assert:
|
||||
that:
|
||||
- output is failed
|
||||
|
||||
- name: Check that config is removed
|
||||
command: "docker config inspect {{ new_output.config_id }}"
|
||||
register: output
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Assert config was removed
|
||||
assert:
|
||||
that:
|
||||
- output is failed
|
||||
|
||||
# template_driver tests
|
||||
|
||||
- when: docker_py_version is version('5.0.3', '>=') and docker_api_version is version('1.37', '>=')
|
||||
block:
|
||||
|
||||
- name: Create regular config
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: opensesame!
|
||||
state: present
|
||||
|
||||
- name: Update config with template_driver
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: opensesame!
|
||||
template_driver: golang
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Assert config was updated
|
||||
assert:
|
||||
that:
|
||||
- output is changed
|
||||
|
||||
- name: Invalid template_driver
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: opensesame!
|
||||
template_driver: "not a template driver"
|
||||
state: present
|
||||
ignore_errors: yes
|
||||
register: output
|
||||
|
||||
- name: Assert failure when called with invalid template_driver
|
||||
assert:
|
||||
that:
|
||||
- 'output is failed'
|
||||
- 'output.msg == "value of template_driver must be one of: golang, got: not a template driver"'
|
||||
|
||||
- name: Create config again
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: opensesame!
|
||||
template_driver: golang
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Assert create config is idempotent
|
||||
assert:
|
||||
that:
|
||||
- output is not changed
|
||||
|
||||
# data is the docker swarm's name
|
||||
- name: Update config with template data
|
||||
docker_config:
|
||||
name: db_password
|
||||
data: "{{ '{{' }} .Service.Name {{ '}}' }}"
|
||||
template_driver: golang
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Inspect config
|
||||
command: "docker config inspect {{ output.config_id }}"
|
||||
register: inspect
|
||||
|
||||
- name: Show inspection result
|
||||
debug:
|
||||
var: inspect
|
||||
|
||||
- name: Assert config creation succeeded
|
||||
assert:
|
||||
that:
|
||||
- "'db_password' in inspect.stdout"
|
||||
- "'ansible_key' in inspect.stdout"
|
||||
# According to the API docs, 'Data' is "Base64-url-safe-encoded (RFC 4648) config data."
|
||||
- "'\"Data\": \"e3sgLlNlcnZpY2UuTmFtZSB9fQ==\"' in inspect.stdout"
|
||||
- "'Templating' in inspect.stdout"
|
||||
- "'\"Name\": \"golang\"' in inspect.stdout"
|
||||
|
||||
- name: Remove config
|
||||
docker_config:
|
||||
name: db_password
|
||||
state: absent
|
||||
|
||||
- name: Check that config is removed
|
||||
command: "docker config inspect {{ output.config_id }}"
|
||||
register: output
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Assert config was removed
|
||||
assert:
|
||||
that:
|
||||
- output is failed
|
||||
|
||||
always:
|
||||
- name: Remove a Swarm cluster
|
||||
docker_swarm:
|
||||
state: absent
|
||||
force: true
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group5
|
||||
destructive
|
||||
@@ -0,0 +1,2 @@
|
||||
TEST3=val3
|
||||
TEST4=val4
|
||||
@@ -0,0 +1,34 @@
|
||||
# (c) 2020, Felix Fontein <felix@fontein.de>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
def _normalize_ipaddr(ipaddr):
|
||||
# Import when needed, to allow installation of that module in the test setup
|
||||
import ipaddress
|
||||
return ipaddress.ip_address(ipaddr).compressed
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
""" IP address and network manipulation filters """
|
||||
|
||||
def filters(self):
|
||||
return {
|
||||
'normalize_ipaddr': _normalize_ipaddr,
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- name: Gather facts on controller
|
||||
setup:
|
||||
gather_subset: '!all'
|
||||
delegate_to: localhost
|
||||
delegate_facts: true
|
||||
run_once: true
|
||||
|
||||
- name: Make sure ipaddress is available on controller
|
||||
pip:
|
||||
name: ipaddress
|
||||
delegate_to: localhost
|
||||
when: hostvars['localhost'].ansible_facts.python.version.major < 3
|
||||
|
||||
# Create random name prefix (for containers, networks, ...)
|
||||
- name: Create random container name prefix
|
||||
set_fact:
|
||||
cname_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
cnames: []
|
||||
inames: []
|
||||
dnetworks: []
|
||||
|
||||
- debug:
|
||||
msg: "Using container name prefix {{ cname_prefix }}"
|
||||
|
||||
# Run the tests
|
||||
- block:
|
||||
- include_tasks: run-test.yml
|
||||
with_fileglob:
|
||||
- "tests/*.yml"
|
||||
|
||||
always:
|
||||
- name: "Make sure all containers are removed"
|
||||
docker_container:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
with_items: "{{ cnames }}"
|
||||
diff: no
|
||||
- name: "Make sure all images are removed"
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
with_items: "{{ inames }}"
|
||||
- name: "Make sure all networks are removed"
|
||||
docker_network:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force: yes
|
||||
with_items: "{{ dnetworks }}"
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
diff: no
|
||||
|
||||
when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run all docker_container tests!"
|
||||
when: not(docker_py_version is version('3.5.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: "Loading tasks from {{ item }}"
|
||||
include_tasks: "{{ item }}"
|
||||
@@ -0,0 +1,463 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cname: "{{ cname_prefix ~ '-comparisons' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname] }}"
|
||||
|
||||
####################################################################
|
||||
## value ###########################################################
|
||||
####################################################################
|
||||
|
||||
- name: value
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
hostname: example.com
|
||||
register: value_1
|
||||
|
||||
- name: value (change, ignore)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
hostname: example.org
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
hostname: ignore
|
||||
register: value_2
|
||||
|
||||
- name: value (change, strict)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
hostname: example.org
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
hostname: strict
|
||||
register: value_3
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- value_1 is changed
|
||||
- value_2 is not changed
|
||||
- value_3 is changed
|
||||
|
||||
####################################################################
|
||||
## list ############################################################
|
||||
####################################################################
|
||||
|
||||
- name: list
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
dns_servers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
register: list_1
|
||||
|
||||
- name: list (change, ignore)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
dns_servers:
|
||||
- 9.9.9.9
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
dns_servers: ignore
|
||||
register: list_2
|
||||
|
||||
- name: list (change, strict)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
dns_servers:
|
||||
- 9.9.9.9
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
dns_servers: strict
|
||||
register: list_3
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- list_1 is changed
|
||||
- list_2 is not changed
|
||||
- list_3 is changed
|
||||
|
||||
####################################################################
|
||||
## set #############################################################
|
||||
####################################################################
|
||||
|
||||
- name: set
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
groups:
|
||||
- "1010"
|
||||
- "1011"
|
||||
register: set_1
|
||||
|
||||
- name: set (change, ignore)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
groups:
|
||||
- "1010"
|
||||
- "1011"
|
||||
- "1012"
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
groups: ignore
|
||||
register: set_2
|
||||
|
||||
- name: set (change, allow_more_present)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
groups:
|
||||
- "1010"
|
||||
- "1011"
|
||||
- "1012"
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
groups: allow_more_present
|
||||
register: set_3
|
||||
|
||||
- name: set (change, allow_more_present)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
groups:
|
||||
- "1010"
|
||||
- "1012"
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
groups: allow_more_present
|
||||
register: set_4
|
||||
|
||||
- name: set (change, strict)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
groups:
|
||||
- "1010"
|
||||
- "1012"
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
groups: strict
|
||||
register: set_5
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- set_1 is changed
|
||||
- set_2 is not changed
|
||||
- set_3 is changed
|
||||
- set_4 is not changed
|
||||
- set_5 is changed
|
||||
|
||||
####################################################################
|
||||
## set(dict) #######################################################
|
||||
####################################################################
|
||||
|
||||
- name: set(dict)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
devices:
|
||||
- "/dev/random:/dev/virt-random:rwm"
|
||||
- "/dev/urandom:/dev/virt-urandom:rwm"
|
||||
register: set_dict_1
|
||||
|
||||
- name: set(dict) (change, ignore)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
devices:
|
||||
- "/dev/random:/dev/virt-random:rwm"
|
||||
- "/dev/urandom:/dev/virt-urandom:rwm"
|
||||
- "/dev/null:/dev/virt-null:rwm"
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
devices: ignore
|
||||
register: set_dict_2
|
||||
|
||||
- name: set(dict) (change, allow_more_present)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
devices:
|
||||
- "/dev/random:/dev/virt-random:rwm"
|
||||
- "/dev/urandom:/dev/virt-urandom:rwm"
|
||||
- "/dev/null:/dev/virt-null:rwm"
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
devices: allow_more_present
|
||||
register: set_dict_3
|
||||
|
||||
- name: set(dict) (change, allow_more_present)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
devices:
|
||||
- "/dev/random:/dev/virt-random:rwm"
|
||||
- "/dev/null:/dev/virt-null:rwm"
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
devices: allow_more_present
|
||||
register: set_dict_4
|
||||
|
||||
- name: set(dict) (change, strict)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
devices:
|
||||
- "/dev/random:/dev/virt-random:rwm"
|
||||
- "/dev/null:/dev/virt-null:rwm"
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
devices: strict
|
||||
register: set_dict_5
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- set_dict_1 is changed
|
||||
- set_dict_2 is not changed
|
||||
- set_dict_3 is changed
|
||||
- set_dict_4 is not changed
|
||||
- set_dict_5 is changed
|
||||
|
||||
####################################################################
|
||||
## dict ############################################################
|
||||
####################################################################
|
||||
|
||||
- name: dict
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.2: world
|
||||
register: dict_1
|
||||
|
||||
- name: dict (change, ignore)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.2: world
|
||||
ansible.test.3: ansible
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
labels: ignore
|
||||
register: dict_2
|
||||
|
||||
- name: dict (change, allow_more_present)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.2: world
|
||||
ansible.test.3: ansible
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
labels: allow_more_present
|
||||
register: dict_3
|
||||
|
||||
- name: dict (change, allow_more_present)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.3: ansible
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
labels: allow_more_present
|
||||
register: dict_4
|
||||
|
||||
- name: dict (change, strict)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.3: ansible
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
labels: strict
|
||||
register: dict_5
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- dict_1 is changed
|
||||
- dict_2 is not changed
|
||||
- dict_3 is changed
|
||||
- dict_4 is not changed
|
||||
- dict_5 is changed
|
||||
|
||||
####################################################################
|
||||
## wildcard ########################################################
|
||||
####################################################################
|
||||
|
||||
- name: Pull {{ docker_test_image_hello_world }} image to make sure wildcard_2 test succeeds
|
||||
# If the image isn't there, it will pull it and return 'changed'.
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
source: pull
|
||||
|
||||
- name: wildcard
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
hostname: example.com
|
||||
stop_timeout: 1
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.2: world
|
||||
ansible.test.3: ansible
|
||||
register: wildcard_1
|
||||
|
||||
- name: wildcard (change, ignore)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_hello_world }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
hostname: example.org
|
||||
stop_timeout: 2
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.4: ignore
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
'*': ignore
|
||||
register: wildcard_2
|
||||
|
||||
- name: wildcard (change, strict)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
hostname: example.org
|
||||
stop_timeout: 1
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.2: world
|
||||
ansible.test.3: ansible
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
'*': strict
|
||||
register: wildcard_3
|
||||
|
||||
- name: wildcard (no change, strict)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
hostname: example.org
|
||||
stop_timeout: 1
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.2: world
|
||||
ansible.test.3: ansible
|
||||
force_kill: yes
|
||||
comparisons:
|
||||
'*': strict
|
||||
register: wildcard_4
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- wildcard_1 is changed
|
||||
- wildcard_2 is not changed
|
||||
- wildcard_3 is changed
|
||||
- wildcard_4 is not changed
|
||||
@@ -0,0 +1,118 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cname: "{{ cname_prefix ~ '-hi' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname] }}"
|
||||
|
||||
####################################################################
|
||||
## container_default_behavior: compatibility #######################
|
||||
####################################################################
|
||||
|
||||
- name: Start container (check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
container_default_behavior: compatibility
|
||||
check_mode: yes
|
||||
register: start_1
|
||||
|
||||
- name: Start container
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
container_default_behavior: compatibility
|
||||
register: start_2
|
||||
|
||||
- name: Start container (idempotent)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
container_default_behavior: compatibility
|
||||
register: start_3
|
||||
|
||||
- name: Start container (idempotent check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
state: started
|
||||
container_default_behavior: compatibility
|
||||
check_mode: yes
|
||||
register: start_4
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- start_1 is changed
|
||||
- start_2 is changed
|
||||
- start_3 is not changed
|
||||
- start_4 is not changed
|
||||
|
||||
####################################################################
|
||||
## container_default_behavior: no_defaults #########################
|
||||
####################################################################
|
||||
|
||||
- name: Start container (check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
container_default_behavior: no_defaults
|
||||
check_mode: yes
|
||||
register: start_1
|
||||
|
||||
- name: Start container
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
container_default_behavior: no_defaults
|
||||
register: start_2
|
||||
|
||||
- name: Start container (idempotent)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
container_default_behavior: no_defaults
|
||||
register: start_3
|
||||
|
||||
- name: Start container (idempotent check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
container_default_behavior: no_defaults
|
||||
check_mode: yes
|
||||
register: start_4
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- start_1 is changed
|
||||
- start_2 is changed
|
||||
- start_3 is not changed
|
||||
- start_4 is not changed
|
||||
@@ -0,0 +1,151 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cname: "{{ cname_prefix ~ '-iid' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname] }}"
|
||||
|
||||
- name: Pull images
|
||||
docker_image:
|
||||
name: "{{ image }}"
|
||||
source: pull
|
||||
loop:
|
||||
- "{{ docker_test_image_hello_world }}"
|
||||
- "{{ docker_test_image_alpine }}"
|
||||
loop_control:
|
||||
loop_var: image
|
||||
|
||||
- name: Get image ID of {{ docker_test_image_hello_world }} and {{ docker_test_image_alpine }} images
|
||||
docker_image_info:
|
||||
name:
|
||||
- "{{ docker_test_image_hello_world }}"
|
||||
- "{{ docker_test_image_alpine }}"
|
||||
register: image_info
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- image_info.images | length == 2
|
||||
|
||||
- name: Print image IDs
|
||||
debug:
|
||||
msg: "{{ docker_test_image_hello_world }}: {{ image_info.images[0].Id }}; {{ docker_test_image_alpine }}: {{ image_info.images[1].Id }}"
|
||||
|
||||
- name: Create container with {{ docker_test_image_hello_world }} image via ID
|
||||
docker_container:
|
||||
image: "{{ image_info.images[0].Id }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: create_1
|
||||
|
||||
- name: Create container with {{ docker_test_image_hello_world }} image via ID (idempotent)
|
||||
docker_container:
|
||||
image: "{{ image_info.images[0].Id }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: create_2
|
||||
|
||||
- name: Create container with {{ docker_test_image_alpine }} image via ID
|
||||
docker_container:
|
||||
image: "{{ image_info.images[1].Id }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: create_3
|
||||
|
||||
- name: Create container with {{ docker_test_image_alpine }} image via ID (idempotent)
|
||||
docker_container:
|
||||
image: "{{ image_info.images[1].Id }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: create_4
|
||||
|
||||
- name: Untag image
|
||||
# Image will not be deleted since the container still uses it
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_alpine }}"
|
||||
force_absent: yes
|
||||
state: absent
|
||||
|
||||
- name: Create container with {{ docker_test_image_alpine }} image via name (check mode, will pull, same image)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
register: create_5
|
||||
check_mode: yes
|
||||
|
||||
- name: Create container with {{ docker_test_image_alpine }} image via name (will pull, same image)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
register: create_6
|
||||
|
||||
- name: Cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- create_1 is changed
|
||||
- create_2 is not changed
|
||||
- create_3 is changed
|
||||
- create_4 is not changed
|
||||
- create_5 is changed
|
||||
- create_6 is changed
|
||||
- create_6.container.Image == image_info.images[1].Id
|
||||
- create_6.container.Id == create_4.container.Id # make sure container wasn't recreated
|
||||
|
||||
- name: Create container with {{ docker_test_image_digest_base }} image via old digest
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_digest_base }}@sha256:{{ docker_test_image_digest_v1 }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: digest_1
|
||||
|
||||
- name: Create container with {{ docker_test_image_digest_base }} image via old digest (idempotent)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_digest_base }}@sha256:{{ docker_test_image_digest_v1 }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: digest_2
|
||||
|
||||
- name: Create container with {{ docker_test_image_digest_base }} image via old digest (idempotent, pull)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_digest_base }}@sha256:{{ docker_test_image_digest_v1 }}"
|
||||
name: "{{ cname }}"
|
||||
pull: yes
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: digest_3
|
||||
|
||||
- name: Update container with {{ docker_test_image_digest_base }} image via new digest
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_digest_base }}@sha256:{{ docker_test_image_digest_v2 }}"
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: digest_4
|
||||
|
||||
- name: Cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- digest_1 is changed
|
||||
- digest_2 is not changed
|
||||
- digest_3 is not changed
|
||||
- digest_4 is changed
|
||||
@@ -0,0 +1,471 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cname: "{{ cname_prefix ~ '-mounts' }}"
|
||||
cname_h1: "{{ cname_prefix ~ '-mounts-h1' }}"
|
||||
cname_h2: "{{ cname_prefix ~ '-mounts-h2' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname, cname_h1, cname_h2] }}"
|
||||
|
||||
####################################################################
|
||||
## keep_volumes ####################################################
|
||||
####################################################################
|
||||
|
||||
# TODO: - keep_volumes
|
||||
|
||||
####################################################################
|
||||
## mounts ##########################################################
|
||||
####################################################################
|
||||
|
||||
- name: mounts
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /tmp
|
||||
target: /tmp
|
||||
type: bind
|
||||
- source: /
|
||||
target: /whatever
|
||||
type: bind
|
||||
read_only: no
|
||||
register: mounts_1
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /
|
||||
target: /whatever
|
||||
type: bind
|
||||
read_only: no
|
||||
- source: /tmp
|
||||
target: /tmp
|
||||
type: bind
|
||||
register: mounts_2
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts (less mounts)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /tmp
|
||||
target: /tmp
|
||||
type: bind
|
||||
register: mounts_3
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts (more mounts)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /tmp
|
||||
target: /tmp
|
||||
type: bind
|
||||
- source: /tmp
|
||||
target: /somewhereelse
|
||||
type: bind
|
||||
read_only: yes
|
||||
force_kill: yes
|
||||
register: mounts_4
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts (different modes)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /tmp
|
||||
target: /tmp
|
||||
type: bind
|
||||
- source: /tmp
|
||||
target: /somewhereelse
|
||||
type: bind
|
||||
read_only: no
|
||||
force_kill: yes
|
||||
register: mounts_5
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts (endpoint collision)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /home
|
||||
target: /x
|
||||
type: bind
|
||||
- source: /etc
|
||||
target: /x
|
||||
type: bind
|
||||
read_only: no
|
||||
force_kill: yes
|
||||
register: mounts_6
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts (anonymous volume)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- target: /tmp
|
||||
type: volume
|
||||
force_kill: true
|
||||
register: mounts_7
|
||||
|
||||
- name: mounts (anonymous volume idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- target: /tmp
|
||||
type: volume
|
||||
force_kill: true
|
||||
register: mounts_8
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- mounts_1 is changed
|
||||
- mounts_2 is not changed
|
||||
- mounts_3 is not changed
|
||||
- mounts_4 is changed
|
||||
- mounts_5 is changed
|
||||
- mounts_6 is failed
|
||||
- "'The mount point \"/x\" appears twice in the mounts option' == mounts_6.msg"
|
||||
- mounts_7 is changed
|
||||
- mounts_8 is not changed
|
||||
when: docker_py_version is version('2.6.0', '>=')
|
||||
- assert:
|
||||
that:
|
||||
- mounts_1 is failed
|
||||
- "('version is ' ~ docker_py_version ~ ' ') in mounts_1.msg"
|
||||
- "'Minimum version required is 2.6.0 ' in mounts_1.msg"
|
||||
when: docker_py_version is version('2.6.0', '<')
|
||||
|
||||
####################################################################
|
||||
## mounts + volumes ################################################
|
||||
####################################################################
|
||||
|
||||
- name: mounts + volumes
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /
|
||||
target: /whatever
|
||||
type: bind
|
||||
read_only: yes
|
||||
volumes:
|
||||
- /tmp:/tmp
|
||||
register: mounts_volumes_1
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts + volumes (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /
|
||||
target: /whatever
|
||||
type: bind
|
||||
read_only: yes
|
||||
volumes:
|
||||
- /tmp:/tmp
|
||||
register: mounts_volumes_2
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts + volumes (switching)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /tmp
|
||||
target: /tmp
|
||||
type: bind
|
||||
read_only: no
|
||||
volumes:
|
||||
- /:/whatever:ro
|
||||
force_kill: yes
|
||||
register: mounts_volumes_3
|
||||
ignore_errors: yes
|
||||
|
||||
- name: mounts + volumes (collision, should fail)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
mounts:
|
||||
- source: /tmp
|
||||
target: /tmp
|
||||
type: bind
|
||||
read_only: no
|
||||
volumes:
|
||||
- /tmp:/tmp
|
||||
force_kill: yes
|
||||
register: mounts_volumes_4
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- mounts_volumes_1 is changed
|
||||
- mounts_volumes_2 is not changed
|
||||
- mounts_volumes_3 is changed
|
||||
- mounts_volumes_4 is failed
|
||||
- "'The mount point \"/tmp\" appears both in the volumes and mounts option' in mounts_volumes_4.msg"
|
||||
when: docker_py_version is version('2.6.0', '>=')
|
||||
- assert:
|
||||
that:
|
||||
- mounts_volumes_1 is failed
|
||||
- "('version is ' ~ docker_py_version ~ ' ') in mounts_1.msg"
|
||||
- "'Minimum version required is 2.6.0 ' in mounts_1.msg"
|
||||
when: docker_py_version is version('2.6.0', '<')
|
||||
|
||||
####################################################################
|
||||
## volume_driver ###################################################
|
||||
####################################################################
|
||||
|
||||
- name: volume_driver
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
volume_driver: local
|
||||
state: started
|
||||
register: volume_driver_1
|
||||
|
||||
- name: volume_driver (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
volume_driver: local
|
||||
state: started
|
||||
register: volume_driver_2
|
||||
|
||||
- name: volume_driver (change)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
volume_driver: /
|
||||
state: started
|
||||
force_kill: yes
|
||||
register: volume_driver_3
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- volume_driver_1 is changed
|
||||
- volume_driver_2 is not changed
|
||||
- volume_driver_3 is changed
|
||||
|
||||
####################################################################
|
||||
## volumes #########################################################
|
||||
####################################################################
|
||||
|
||||
- name: volumes
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes:
|
||||
- "/tmp:/tmp"
|
||||
- "/:/whatever:rw,z"
|
||||
- "/anon:rw"
|
||||
register: volumes_1
|
||||
|
||||
- name: volumes (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes:
|
||||
- "/:/whatever:rw,z"
|
||||
- "/tmp:/tmp"
|
||||
- "/anon:rw"
|
||||
register: volumes_2
|
||||
|
||||
- name: volumes (less volumes)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes:
|
||||
- "/tmp:/tmp"
|
||||
register: volumes_3
|
||||
|
||||
- name: volumes (more volumes)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes:
|
||||
- "/tmp:/tmp"
|
||||
- "/tmp:/somewhereelse:ro,Z"
|
||||
force_kill: yes
|
||||
register: volumes_4
|
||||
|
||||
- name: volumes (different modes)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes:
|
||||
- "/tmp:/tmp"
|
||||
- "/tmp:/somewhereelse:ro"
|
||||
force_kill: yes
|
||||
register: volumes_5
|
||||
|
||||
- name: volumes (collision)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes:
|
||||
- "/etc:/tmp"
|
||||
- "/home:/tmp:ro"
|
||||
force_kill: yes
|
||||
register: volumes_6
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- volumes_1 is changed
|
||||
- volumes_1.container.Config.Volumes | length == 1
|
||||
- volumes_1.container.Config.Volumes['/anon:rw'] | length == 0
|
||||
- volumes_2 is not changed
|
||||
- volumes_3 is not changed
|
||||
- volumes_4 is changed
|
||||
- not volumes_4.container.Config.Volumes
|
||||
- volumes_5 is changed
|
||||
- volumes_6 is failed
|
||||
- "'The mount point \"/tmp\" appears twice in the volumes option' in volumes_6.msg"
|
||||
|
||||
####################################################################
|
||||
## volumes_from ####################################################
|
||||
####################################################################
|
||||
|
||||
- name: start helpers
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ container_name }}"
|
||||
state: started
|
||||
volumes:
|
||||
- "{{ '/tmp:/tmp' if container_name == cname_h1 else '/:/whatever:ro' }}"
|
||||
loop:
|
||||
- "{{ cname_h1 }}"
|
||||
- "{{ cname_h2 }}"
|
||||
loop_control:
|
||||
loop_var: container_name
|
||||
|
||||
- name: volumes_from
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes_from: "{{ cname_h1 }}"
|
||||
register: volumes_from_1
|
||||
|
||||
- name: volumes_from (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes_from: "{{ cname_h1 }}"
|
||||
register: volumes_from_2
|
||||
|
||||
- name: volumes_from (change)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
volumes_from: "{{ cname_h2 }}"
|
||||
force_kill: yes
|
||||
register: volumes_from_3
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ container_name }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
loop:
|
||||
- "{{ cname }}"
|
||||
- "{{ cname_h1 }}"
|
||||
- "{{ cname_h2 }}"
|
||||
loop_control:
|
||||
loop_var: container_name
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- volumes_from_1 is changed
|
||||
- volumes_from_2 is not changed
|
||||
- volumes_from_3 is changed
|
||||
|
||||
####################################################################
|
||||
####################################################################
|
||||
####################################################################
|
||||
@@ -0,0 +1,749 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cname: "{{ cname_prefix ~ '-network' }}"
|
||||
cname_h1: "{{ cname_prefix ~ '-network-h1' }}"
|
||||
nname_1: "{{ cname_prefix ~ '-network-1' }}"
|
||||
nname_2: "{{ cname_prefix ~ '-network-2' }}"
|
||||
nname_3: "{{ cname_prefix ~ '-network-3' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname, cname_h1] }}"
|
||||
dnetworks: "{{ dnetworks + [nname_1, nname_2, nname_3] }}"
|
||||
|
||||
- name: Create networks
|
||||
docker_network:
|
||||
name: "{{ network_name }}"
|
||||
state: present
|
||||
loop:
|
||||
- "{{ nname_1 }}"
|
||||
- "{{ nname_2 }}"
|
||||
loop_control:
|
||||
loop_var: network_name
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
|
||||
- set_fact:
|
||||
subnet_ipv4_base: 10.{{ 16 + (240 | random) }}.{{ 16 + (240 | random) }}
|
||||
subnet_ipv6_base: fdb6:feea:{{ '%0.4x:%0.4x' | format(65536 | random, 65536 | random) }}
|
||||
# If netaddr would be installed on the controller, one could do:
|
||||
# subnet_ipv4: "10.{{ 16 + (240 | random) }}.{{ 16 + (240 | random) }}.0/24"
|
||||
# subnet_ipv6: "fdb6:feea:{{ '%0.4x:%0.4x' | format(65536 | random, 65536 | random) }}::/64"
|
||||
|
||||
- set_fact:
|
||||
subnet_ipv4: "{{ subnet_ipv4_base }}.0/24"
|
||||
subnet_ipv6: "{{ subnet_ipv6_base }}::/64"
|
||||
nname_3_ipv4_2: "{{ subnet_ipv4_base }}.2"
|
||||
nname_3_ipv4_3: "{{ subnet_ipv4_base }}.3"
|
||||
nname_3_ipv4_4: "{{ subnet_ipv4_base }}.4"
|
||||
nname_3_ipv6_2: "{{ subnet_ipv6_base }}::2"
|
||||
nname_3_ipv6_3: "{{ subnet_ipv6_base }}::3"
|
||||
nname_3_ipv6_4: "{{ subnet_ipv6_base }}::4"
|
||||
# If netaddr would be installed on the controller, one could do:
|
||||
# nname_3_ipv4_2: "{{ subnet_ipv4 | ansible.netcommon.next_nth_usable(2) }}"
|
||||
# nname_3_ipv4_3: "{{ subnet_ipv4 | ansible.netcommon.next_nth_usable(3) }}"
|
||||
# nname_3_ipv4_4: "{{ subnet_ipv4 | ansible.netcommon.next_nth_usable(4) }}"
|
||||
# nname_3_ipv6_2: "{{ subnet_ipv6 | ansible.netcommon.next_nth_usable(2) }}"
|
||||
# nname_3_ipv6_3: "{{ subnet_ipv6 | ansible.netcommon.next_nth_usable(3) }}"
|
||||
# nname_3_ipv6_4: "{{ subnet_ipv6 | ansible.netcommon.next_nth_usable(4) }}"
|
||||
|
||||
- debug:
|
||||
msg: "Chose random IPv4 subnet {{ subnet_ipv4 }} and random IPv6 subnet {{ subnet_ipv6 }}"
|
||||
|
||||
- name: Create network with fixed IPv4 and IPv6 subnets
|
||||
docker_network:
|
||||
name: "{{ nname_3 }}"
|
||||
enable_ipv6: yes
|
||||
ipam_config:
|
||||
- subnet: "{{ subnet_ipv4 }}"
|
||||
- subnet: "{{ subnet_ipv6 }}"
|
||||
state: present
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
|
||||
####################################################################
|
||||
## network_mode ####################################################
|
||||
####################################################################
|
||||
|
||||
- name: network_mode
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
network_mode: host
|
||||
register: network_mode_1
|
||||
|
||||
- name: network_mode (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
network_mode: host
|
||||
register: network_mode_2
|
||||
|
||||
- name: network_mode (change)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
network_mode: none
|
||||
force_kill: yes
|
||||
register: network_mode_3
|
||||
|
||||
- name: network_mode (container mode setup)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname_h1 }}"
|
||||
state: started
|
||||
register: cname_h1_id
|
||||
|
||||
- name: network_mode (container mode)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
network_mode: "container:{{ cname_h1_id.container.Id }}"
|
||||
force_kill: yes
|
||||
register: network_mode_4
|
||||
|
||||
- name: network_mode (container mode idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
network_mode: "container:{{ cname_h1 }}"
|
||||
register: network_mode_5
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ container_name }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
loop:
|
||||
- "{{ cname }}"
|
||||
- "{{ cname_h1 }}"
|
||||
loop_control:
|
||||
loop_var: container_name
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network_mode_1 is changed
|
||||
- network_mode_1.container.HostConfig.NetworkMode == 'host'
|
||||
- network_mode_2 is not changed
|
||||
- network_mode_2.container.HostConfig.NetworkMode == 'host'
|
||||
- network_mode_3 is changed
|
||||
- network_mode_3.container.HostConfig.NetworkMode == 'none'
|
||||
- network_mode_4 is changed
|
||||
- network_mode_4.container.HostConfig.NetworkMode == 'container:' ~ cname_h1_id.container.Id
|
||||
- network_mode_5 is not changed
|
||||
- network_mode_5.container.HostConfig.NetworkMode == 'container:' ~ cname_h1_id.container.Id
|
||||
|
||||
####################################################################
|
||||
## networks, purge_networks for networks_cli_compatible=no #########
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: networks_cli_compatible=no, networks w/o purge_networks
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_1 }}"
|
||||
- name: "{{ nname_2 }}"
|
||||
networks_cli_compatible: no
|
||||
register: networks_1
|
||||
|
||||
- name: networks_cli_compatible=no, networks w/o purge_networks
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_1 }}"
|
||||
- name: "{{ nname_2 }}"
|
||||
networks_cli_compatible: no
|
||||
register: networks_2
|
||||
|
||||
- name: networks_cli_compatible=no, networks, purge_networks
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
purge_networks: yes
|
||||
networks:
|
||||
- name: bridge
|
||||
- name: "{{ nname_1 }}"
|
||||
networks_cli_compatible: no
|
||||
force_kill: yes
|
||||
register: networks_3
|
||||
|
||||
- name: networks_cli_compatible=no, networks, purge_networks (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
purge_networks: yes
|
||||
networks:
|
||||
- name: "{{ nname_1 }}"
|
||||
- name: bridge
|
||||
networks_cli_compatible: no
|
||||
register: networks_4
|
||||
|
||||
- name: networks_cli_compatible=no, networks (less networks)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: bridge
|
||||
networks_cli_compatible: no
|
||||
register: networks_5
|
||||
|
||||
- name: networks_cli_compatible=no, networks, purge_networks (less networks)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
purge_networks: yes
|
||||
networks:
|
||||
- name: bridge
|
||||
networks_cli_compatible: no
|
||||
force_kill: yes
|
||||
register: networks_6
|
||||
|
||||
- name: networks_cli_compatible=no, networks, purge_networks (more networks)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
purge_networks: yes
|
||||
networks:
|
||||
- name: bridge
|
||||
- name: "{{ nname_2 }}"
|
||||
networks_cli_compatible: no
|
||||
force_kill: yes
|
||||
register: networks_7
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
# networks_1 has networks default, 'bridge', nname_1
|
||||
- networks_1 is changed
|
||||
- networks_1.container.NetworkSettings.Networks | length == 3
|
||||
- nname_1 in networks_1.container.NetworkSettings.Networks
|
||||
- nname_2 in networks_1.container.NetworkSettings.Networks
|
||||
- "'default' in networks_1.container.NetworkSettings.Networks or 'bridge' in networks_1.container.NetworkSettings.Networks"
|
||||
# networks_2 has networks default, 'bridge', nname_1
|
||||
- networks_2 is not changed
|
||||
- networks_2.container.NetworkSettings.Networks | length == 3
|
||||
- nname_1 in networks_2.container.NetworkSettings.Networks
|
||||
- nname_2 in networks_1.container.NetworkSettings.Networks
|
||||
- "'default' in networks_1.container.NetworkSettings.Networks or 'bridge' in networks_1.container.NetworkSettings.Networks"
|
||||
# networks_3 has networks 'bridge', nname_1
|
||||
- networks_3 is changed
|
||||
- networks_3.container.NetworkSettings.Networks | length == 2
|
||||
- nname_1 in networks_3.container.NetworkSettings.Networks
|
||||
- "'default' in networks_3.container.NetworkSettings.Networks or 'bridge' in networks_3.container.NetworkSettings.Networks"
|
||||
# networks_4 has networks 'bridge', nname_1
|
||||
- networks_4 is not changed
|
||||
- networks_4.container.NetworkSettings.Networks | length == 2
|
||||
- nname_1 in networks_4.container.NetworkSettings.Networks
|
||||
- "'default' in networks_4.container.NetworkSettings.Networks or 'bridge' in networks_4.container.NetworkSettings.Networks"
|
||||
# networks_5 has networks 'bridge', nname_1
|
||||
- networks_5 is not changed
|
||||
- networks_5.container.NetworkSettings.Networks | length == 2
|
||||
- nname_1 in networks_5.container.NetworkSettings.Networks
|
||||
- "'default' in networks_5.container.NetworkSettings.Networks or 'bridge' in networks_5.container.NetworkSettings.Networks"
|
||||
# networks_6 has networks 'bridge'
|
||||
- networks_6 is changed
|
||||
- networks_6.container.NetworkSettings.Networks | length == 1
|
||||
- "'default' in networks_6.container.NetworkSettings.Networks or 'bridge' in networks_6.container.NetworkSettings.Networks"
|
||||
# networks_7 has networks 'bridge', nname_2
|
||||
- networks_7 is changed
|
||||
- networks_7.container.NetworkSettings.Networks | length == 2
|
||||
- nname_2 in networks_7.container.NetworkSettings.Networks
|
||||
- "'default' in networks_7.container.NetworkSettings.Networks or 'bridge' in networks_7.container.NetworkSettings.Networks"
|
||||
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
|
||||
####################################################################
|
||||
## networks for networks_cli_compatible=yes ########################
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: networks_cli_compatible=yes, networks specified
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_1 }}"
|
||||
aliases:
|
||||
- alias1
|
||||
- alias2
|
||||
- name: "{{ nname_2 }}"
|
||||
networks_cli_compatible: yes
|
||||
register: networks_1
|
||||
|
||||
- name: networks_cli_compatible=yes, networks specified
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_1 }}"
|
||||
- name: "{{ nname_2 }}"
|
||||
networks_cli_compatible: yes
|
||||
register: networks_2
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- name: networks_cli_compatible=yes, empty networks list specified
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks: []
|
||||
networks_cli_compatible: yes
|
||||
register: networks_3
|
||||
|
||||
- name: networks_cli_compatible=yes, empty networks list specified
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks: []
|
||||
networks_cli_compatible: yes
|
||||
register: networks_4
|
||||
|
||||
- name: networks_cli_compatible=yes, empty networks list specified, purge_networks
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks: []
|
||||
networks_cli_compatible: yes
|
||||
purge_networks: yes
|
||||
force_kill: yes
|
||||
register: networks_5
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- name: networks_cli_compatible=yes, networks not specified
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks_cli_compatible: yes
|
||||
force_kill: yes
|
||||
register: networks_6
|
||||
|
||||
- name: networks_cli_compatible=yes, networks not specified
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks_cli_compatible: yes
|
||||
register: networks_7
|
||||
|
||||
- name: networks_cli_compatible=yes, networks not specified, purge_networks
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks_cli_compatible: yes
|
||||
purge_networks: yes
|
||||
force_kill: yes
|
||||
register: networks_8
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- debug: var=networks_3
|
||||
|
||||
- assert:
|
||||
that:
|
||||
# networks_1 has networks nname_1, nname_2
|
||||
- networks_1 is changed
|
||||
- networks_1.container.NetworkSettings.Networks | length == 2
|
||||
- nname_1 in networks_1.container.NetworkSettings.Networks
|
||||
- nname_2 in networks_1.container.NetworkSettings.Networks
|
||||
# networks_2 has networks nname_1, nname_2
|
||||
- networks_2 is not changed
|
||||
- networks_2.container.NetworkSettings.Networks | length == 2
|
||||
- nname_1 in networks_2.container.NetworkSettings.Networks
|
||||
- nname_2 in networks_1.container.NetworkSettings.Networks
|
||||
# networks_3 has networks 'bridge'
|
||||
- networks_3 is changed
|
||||
- networks_3.container.NetworkSettings.Networks | length == 1
|
||||
- "'default' in networks_3.container.NetworkSettings.Networks or 'bridge' in networks_3.container.NetworkSettings.Networks"
|
||||
# networks_4 has networks 'bridge'
|
||||
- networks_4 is not changed
|
||||
- networks_4.container.NetworkSettings.Networks | length == 1
|
||||
- "'default' in networks_4.container.NetworkSettings.Networks or 'bridge' in networks_4.container.NetworkSettings.Networks"
|
||||
# networks_5 has no networks
|
||||
- networks_5 is changed
|
||||
- networks_5.container.NetworkSettings.Networks | length == 0
|
||||
# networks_6 has networks 'bridge'
|
||||
- networks_6 is changed
|
||||
- networks_6.container.NetworkSettings.Networks | length == 1
|
||||
- "'default' in networks_6.container.NetworkSettings.Networks or 'bridge' in networks_6.container.NetworkSettings.Networks"
|
||||
# networks_7 has networks 'bridge'
|
||||
- networks_7 is not changed
|
||||
- networks_7.container.NetworkSettings.Networks | length == 1
|
||||
- "'default' in networks_7.container.NetworkSettings.Networks or 'bridge' in networks_7.container.NetworkSettings.Networks"
|
||||
# networks_8 has no networks
|
||||
- networks_8 is changed
|
||||
- networks_8.container.NetworkSettings.Networks | length == 0
|
||||
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
|
||||
####################################################################
|
||||
## networks with comparisons #######################################
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: create container with one network
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_1 }}"
|
||||
networks_cli_compatible: yes
|
||||
register: networks_1
|
||||
|
||||
- name: different networks, comparisons=ignore
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_2 }}"
|
||||
networks_cli_compatible: yes
|
||||
comparisons:
|
||||
network_mode: ignore # otherwise we'd have to set network_mode to nname_1
|
||||
networks: ignore
|
||||
register: networks_2
|
||||
|
||||
- name: less networks, comparisons=ignore
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks: []
|
||||
networks_cli_compatible: yes
|
||||
comparisons:
|
||||
networks: ignore
|
||||
register: networks_3
|
||||
|
||||
- name: less networks, comparisons=allow_more_present
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks: []
|
||||
networks_cli_compatible: yes
|
||||
comparisons:
|
||||
networks: allow_more_present
|
||||
register: networks_4
|
||||
|
||||
- name: different networks, comparisons=allow_more_present
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_2 }}"
|
||||
networks_cli_compatible: yes
|
||||
comparisons:
|
||||
network_mode: ignore # otherwise we'd have to set network_mode to nname_1
|
||||
networks: allow_more_present
|
||||
force_kill: yes
|
||||
register: networks_5
|
||||
|
||||
- name: different networks, comparisons=strict
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_2 }}"
|
||||
networks_cli_compatible: yes
|
||||
comparisons:
|
||||
networks: strict
|
||||
force_kill: yes
|
||||
register: networks_6
|
||||
|
||||
- name: less networks, comparisons=strict
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks: []
|
||||
networks_cli_compatible: yes
|
||||
comparisons:
|
||||
networks: strict
|
||||
force_kill: yes
|
||||
register: networks_7
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
# networks_1 has networks nname_1
|
||||
- networks_1 is changed
|
||||
- networks_1.container.NetworkSettings.Networks | length == 1
|
||||
- nname_1 in networks_1.container.NetworkSettings.Networks
|
||||
# networks_2 has networks nname_1
|
||||
- networks_2 is not changed
|
||||
- networks_2.container.NetworkSettings.Networks | length == 1
|
||||
- nname_1 in networks_2.container.NetworkSettings.Networks
|
||||
# networks_3 has networks nname_1
|
||||
- networks_3 is not changed
|
||||
- networks_3.container.NetworkSettings.Networks | length == 1
|
||||
- nname_1 in networks_3.container.NetworkSettings.Networks
|
||||
# networks_4 has networks nname_1
|
||||
- networks_4 is not changed
|
||||
- networks_4.container.NetworkSettings.Networks | length == 1
|
||||
- nname_1 in networks_4.container.NetworkSettings.Networks
|
||||
# networks_5 has networks nname_1, nname_2
|
||||
- networks_5 is changed
|
||||
- networks_5.container.NetworkSettings.Networks | length == 2
|
||||
- nname_1 in networks_5.container.NetworkSettings.Networks
|
||||
- nname_2 in networks_5.container.NetworkSettings.Networks
|
||||
# networks_6 has networks nname_2
|
||||
- networks_6 is changed
|
||||
- networks_6.container.NetworkSettings.Networks | length == 1
|
||||
- nname_2 in networks_6.container.NetworkSettings.Networks
|
||||
# networks_7 has no networks
|
||||
- networks_7 is changed
|
||||
- networks_7.container.NetworkSettings.Networks | length == 0
|
||||
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
|
||||
####################################################################
|
||||
## networks with IP address ########################################
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: create container (stopped) with one network and fixed IP
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: stopped
|
||||
networks:
|
||||
- name: "{{ nname_3 }}"
|
||||
ipv4_address: "{{ nname_3_ipv4_2 }}"
|
||||
ipv6_address: "{{ nname_3_ipv6_2 }}"
|
||||
networks_cli_compatible: yes
|
||||
register: networks_1
|
||||
|
||||
- name: create container (stopped) with one network and fixed IP (idempotent)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: stopped
|
||||
networks:
|
||||
- name: "{{ nname_3 }}"
|
||||
ipv4_address: "{{ nname_3_ipv4_2 }}"
|
||||
ipv6_address: "{{ nname_3_ipv6_2 }}"
|
||||
networks_cli_compatible: yes
|
||||
register: networks_2
|
||||
|
||||
- name: create container (stopped) with one network and fixed IP (different IPv4)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: stopped
|
||||
networks:
|
||||
- name: "{{ nname_3 }}"
|
||||
ipv4_address: "{{ nname_3_ipv4_3 }}"
|
||||
ipv6_address: "{{ nname_3_ipv6_2 }}"
|
||||
networks_cli_compatible: yes
|
||||
register: networks_3
|
||||
|
||||
- name: create container (stopped) with one network and fixed IP (different IPv6)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: stopped
|
||||
networks:
|
||||
- name: "{{ nname_3 }}"
|
||||
ipv4_address: "{{ nname_3_ipv4_3 }}"
|
||||
ipv6_address: "{{ nname_3_ipv6_3 }}"
|
||||
networks_cli_compatible: yes
|
||||
register: networks_4
|
||||
|
||||
- name: create container (started) with one network and fixed IP
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
register: networks_5
|
||||
|
||||
- name: create container (started) with one network and fixed IP (different IPv4)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_3 }}"
|
||||
ipv4_address: "{{ nname_3_ipv4_4 }}"
|
||||
ipv6_address: "{{ nname_3_ipv6_3 }}"
|
||||
networks_cli_compatible: yes
|
||||
force_kill: yes
|
||||
register: networks_6
|
||||
|
||||
- name: create container (started) with one network and fixed IP (different IPv6)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_3 }}"
|
||||
ipv4_address: "{{ nname_3_ipv4_4 }}"
|
||||
ipv6_address: "{{ nname_3_ipv6_4 }}"
|
||||
networks_cli_compatible: yes
|
||||
force_kill: yes
|
||||
register: networks_7
|
||||
|
||||
- name: create container (started) with one network and fixed IP (idempotent)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
networks:
|
||||
- name: "{{ nname_3 }}"
|
||||
ipv4_address: "{{ nname_3_ipv4_4 }}"
|
||||
ipv6_address: "{{ nname_3_ipv6_4 }}"
|
||||
networks_cli_compatible: yes
|
||||
register: networks_8
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_1 is changed
|
||||
- networks_1.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv4Address == nname_3_ipv4_2
|
||||
- networks_1.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv6Address | normalize_ipaddr == nname_3_ipv6_2 | normalize_ipaddr
|
||||
- networks_1.container.NetworkSettings.Networks[nname_3].IPAddress == ""
|
||||
- networks_1.container.NetworkSettings.Networks[nname_3].GlobalIPv6Address == ""
|
||||
- networks_2 is not changed
|
||||
- networks_2.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv4Address == nname_3_ipv4_2
|
||||
- networks_2.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv6Address | normalize_ipaddr == nname_3_ipv6_2 | normalize_ipaddr
|
||||
- networks_2.container.NetworkSettings.Networks[nname_3].IPAddress == ""
|
||||
- networks_2.container.NetworkSettings.Networks[nname_3].GlobalIPv6Address == ""
|
||||
- networks_3 is changed
|
||||
- networks_3.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv4Address == nname_3_ipv4_3
|
||||
- networks_3.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv6Address | normalize_ipaddr == nname_3_ipv6_2 | normalize_ipaddr
|
||||
- networks_3.container.NetworkSettings.Networks[nname_3].IPAddress == ""
|
||||
- networks_3.container.NetworkSettings.Networks[nname_3].GlobalIPv6Address == ""
|
||||
- networks_4 is changed
|
||||
- networks_4.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv4Address == nname_3_ipv4_3
|
||||
- networks_4.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv6Address | normalize_ipaddr == nname_3_ipv6_3 | normalize_ipaddr
|
||||
- networks_4.container.NetworkSettings.Networks[nname_3].IPAddress == ""
|
||||
- networks_4.container.NetworkSettings.Networks[nname_3].GlobalIPv6Address == ""
|
||||
- networks_5 is changed
|
||||
- networks_5.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv4Address == nname_3_ipv4_3
|
||||
- networks_5.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv6Address | normalize_ipaddr == nname_3_ipv6_3 | normalize_ipaddr
|
||||
- networks_5.container.NetworkSettings.Networks[nname_3].IPAddress == nname_3_ipv4_3
|
||||
- networks_5.container.NetworkSettings.Networks[nname_3].GlobalIPv6Address | normalize_ipaddr == nname_3_ipv6_3 | normalize_ipaddr
|
||||
- networks_6 is changed
|
||||
- networks_6.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv4Address == nname_3_ipv4_4
|
||||
- networks_6.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv6Address | normalize_ipaddr == nname_3_ipv6_3 | normalize_ipaddr
|
||||
- networks_6.container.NetworkSettings.Networks[nname_3].IPAddress == nname_3_ipv4_4
|
||||
- networks_6.container.NetworkSettings.Networks[nname_3].GlobalIPv6Address | normalize_ipaddr == nname_3_ipv6_3 | normalize_ipaddr
|
||||
- networks_7 is changed
|
||||
- networks_7.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv4Address == nname_3_ipv4_4
|
||||
- networks_7.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv6Address | normalize_ipaddr == nname_3_ipv6_4 | normalize_ipaddr
|
||||
- networks_7.container.NetworkSettings.Networks[nname_3].IPAddress == nname_3_ipv4_4
|
||||
- networks_7.container.NetworkSettings.Networks[nname_3].GlobalIPv6Address | normalize_ipaddr == nname_3_ipv6_4 | normalize_ipaddr
|
||||
- networks_8 is not changed
|
||||
- networks_8.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv4Address == nname_3_ipv4_4
|
||||
- networks_8.container.NetworkSettings.Networks[nname_3].IPAMConfig.IPv6Address | normalize_ipaddr == nname_3_ipv6_4 | normalize_ipaddr
|
||||
- networks_8.container.NetworkSettings.Networks[nname_3].IPAddress == nname_3_ipv4_4
|
||||
- networks_8.container.NetworkSettings.Networks[nname_3].GlobalIPv6Address | normalize_ipaddr == nname_3_ipv6_4 | normalize_ipaddr
|
||||
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
|
||||
####################################################################
|
||||
####################################################################
|
||||
####################################################################
|
||||
|
||||
- name: Delete networks
|
||||
docker_network:
|
||||
name: "{{ network_name }}"
|
||||
state: absent
|
||||
force: yes
|
||||
loop:
|
||||
- "{{ nname_1 }}"
|
||||
- "{{ nname_2 }}"
|
||||
- "{{ nname_3 }}"
|
||||
loop_control:
|
||||
loop_var: network_name
|
||||
when: docker_py_version is version('1.10.0', '>=')
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,427 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cname: "{{ cname_prefix ~ '-options' }}"
|
||||
cname2: "{{ cname_prefix ~ '-options-h1' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname, cname2] }}"
|
||||
|
||||
####################################################################
|
||||
## published_ports: error handling #################################
|
||||
####################################################################
|
||||
|
||||
- name: published_ports -- non-closing square bracket
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "[::1:2000:3000"
|
||||
register: published_ports_1
|
||||
ignore_errors: true
|
||||
|
||||
- name: published_ports -- forgot square brackets for IPv6
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "::1:2000:3000"
|
||||
register: published_ports_2
|
||||
ignore_errors: true
|
||||
|
||||
- name: published_ports -- disallow hostnames
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "foo:2000:3000"
|
||||
register: published_ports_3
|
||||
ignore_errors: true
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- published_ports_1 is failed
|
||||
- published_ports_1.msg == 'Cannot find closing "]" in input "[::1:2000:3000" for opening "[" at index 1!'
|
||||
- published_ports_2 is failed
|
||||
- published_ports_2.msg == 'Invalid port description "::1:2000:3000" - expected 1 to 3 colon-separated parts, but got 5. Maybe you forgot to use square brackets ([...]) around an IPv6 address?'
|
||||
- published_ports_3 is failed
|
||||
- "published_ports_3.msg == 'Bind addresses for published ports must be IPv4 or IPv6 addresses, not hostnames. Use the dig lookup to resolve hostnames. (Found hostname: foo)'"
|
||||
|
||||
####################################################################
|
||||
## published_ports: all ############################################
|
||||
####################################################################
|
||||
|
||||
- name: published_ports -- all
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9002"
|
||||
published_ports:
|
||||
- all
|
||||
force_kill: yes
|
||||
register: published_ports_1
|
||||
|
||||
- name: published_ports -- all (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9002"
|
||||
published_ports:
|
||||
- all
|
||||
force_kill: yes
|
||||
register: published_ports_2
|
||||
|
||||
- name: published_ports -- all (writing out 'all')
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9002"
|
||||
published_ports:
|
||||
- "9001"
|
||||
- "9002"
|
||||
force_kill: yes
|
||||
register: published_ports_3
|
||||
|
||||
- name: published_ports -- all (idempotency 2)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9002"
|
||||
published_ports:
|
||||
- "9002"
|
||||
- "9001"
|
||||
force_kill: yes
|
||||
register: published_ports_4
|
||||
|
||||
- name: published_ports -- all (switching back to 'all')
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9002"
|
||||
published_ports:
|
||||
- all
|
||||
force_kill: yes
|
||||
register: published_ports_5
|
||||
|
||||
- name: published_ports -- all equivalence with publish_all_ports
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9002"
|
||||
publish_all_ports: true
|
||||
force_kill: yes
|
||||
register: published_ports_6
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- published_ports_1 is changed
|
||||
- published_ports_2 is not changed
|
||||
- published_ports_3 is changed
|
||||
- published_ports_4 is not changed
|
||||
- published_ports_5 is changed
|
||||
- published_ports_6 is not changed
|
||||
|
||||
####################################################################
|
||||
## published_ports: port range #####################################
|
||||
####################################################################
|
||||
|
||||
- name: published_ports -- port range
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9010-9050"
|
||||
published_ports:
|
||||
- "9001:9001"
|
||||
- "9010-9050:9010-9050"
|
||||
force_kill: yes
|
||||
register: published_ports_1
|
||||
|
||||
- name: published_ports -- port range (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9010-9050"
|
||||
published_ports:
|
||||
- "9001:9001"
|
||||
- "9010-9050:9010-9050"
|
||||
force_kill: yes
|
||||
register: published_ports_2
|
||||
|
||||
- name: published_ports -- port range (different range)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
exposed_ports:
|
||||
- "9001"
|
||||
- "9010-9050"
|
||||
published_ports:
|
||||
- "9001:9001"
|
||||
- "9020-9060:9020-9060"
|
||||
force_kill: yes
|
||||
register: published_ports_3
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- published_ports_1 is changed
|
||||
- published_ports_2 is not changed
|
||||
- published_ports_3 is changed
|
||||
|
||||
####################################################################
|
||||
## published_ports: one-element container port range ###############
|
||||
####################################################################
|
||||
|
||||
- name: published_ports -- one-element container port range
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ item }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "9010-9050:9010"
|
||||
force_kill: yes
|
||||
loop:
|
||||
- '{{ cname }}'
|
||||
- '{{ cname2 }}'
|
||||
register: published_ports_1
|
||||
|
||||
- name: published_ports -- one-element container port range (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ item }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "9010-9050:9010"
|
||||
force_kill: yes
|
||||
loop:
|
||||
- '{{ cname }}'
|
||||
- '{{ cname2 }}'
|
||||
register: published_ports_2
|
||||
|
||||
- name: published_ports -- one-element container port range (different range)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ item }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "9010-9051:9010"
|
||||
force_kill: yes
|
||||
loop:
|
||||
- '{{ cname }}'
|
||||
- '{{ cname2 }}'
|
||||
register: published_ports_3
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
loop:
|
||||
- '{{ cname }}'
|
||||
- '{{ cname2 }}'
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- published_ports_1 is changed
|
||||
- published_ports_2 is not changed
|
||||
- published_ports_3 is changed
|
||||
|
||||
####################################################################
|
||||
## published_ports: IPv6 addresses #################################
|
||||
####################################################################
|
||||
|
||||
- name: published_ports -- IPv6
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "[::1]:9001:9001"
|
||||
force_kill: yes
|
||||
register: published_ports_1
|
||||
|
||||
- name: published_ports -- IPv6 (idempotency)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "[::1]:9001:9001"
|
||||
force_kill: yes
|
||||
register: published_ports_2
|
||||
|
||||
- name: published_ports -- IPv6 (different IP)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "127.0.0.1:9001:9001"
|
||||
force_kill: yes
|
||||
register: published_ports_3
|
||||
|
||||
- name: published_ports -- IPv6 (hostname)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
published_ports:
|
||||
- "localhost:9001:9001"
|
||||
force_kill: yes
|
||||
register: published_ports_4
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- published_ports_1 is changed
|
||||
- published_ports_2 is not changed
|
||||
- published_ports_3 is changed
|
||||
- published_ports_4 is failed
|
||||
|
||||
####################################################################
|
||||
## publish_all_ports ###############################################
|
||||
####################################################################
|
||||
|
||||
- set_fact:
|
||||
publish_all_ports_test_cases:
|
||||
- test_name: no_options
|
||||
changed: true
|
||||
- test_name: null_to_true
|
||||
publish_all_ports_value: true
|
||||
changed: true
|
||||
- test_name: true_idempotency
|
||||
publish_all_ports_value: true
|
||||
changed: false
|
||||
- test_name: true_to_null
|
||||
changed: false
|
||||
- test_name: null_to_true_2
|
||||
publish_all_ports_value: true
|
||||
changed: false
|
||||
- test_name: true_to_false
|
||||
publish_all_ports_value: false
|
||||
changed: true
|
||||
- test_name: false_idempotency
|
||||
publish_all_ports_value: false
|
||||
changed: false
|
||||
- test_name: false_to_null
|
||||
changed: false
|
||||
- test_name: null_with_published_ports
|
||||
published_ports_value: &ports
|
||||
- "9001:9001"
|
||||
- "9010-9050:9010-9050"
|
||||
changed: true
|
||||
- test_name: null_to_true_with_published_ports
|
||||
publish_all_ports_value: true
|
||||
published_ports_value: *ports
|
||||
changed: true
|
||||
- test_name: true_idempotency_with_published_ports
|
||||
publish_all_ports_value: true
|
||||
published_ports_value: *ports
|
||||
changed: false
|
||||
- test_name: true_to_null_with_published_ports
|
||||
published_ports_value: *ports
|
||||
changed: false
|
||||
- test_name: null_to_true_2_with_published_ports
|
||||
publish_all_ports_value: true
|
||||
published_ports_value: *ports
|
||||
changed: false
|
||||
- test_name: true_to_false_with_published_ports
|
||||
publish_all_ports_value: false
|
||||
published_ports_value: *ports
|
||||
changed: true
|
||||
- test_name: false_idempotency_with_published_ports
|
||||
publish_all_ports_value: false
|
||||
published_ports_value: *ports
|
||||
changed: false
|
||||
- test_name: false_to_null_with_published_ports
|
||||
published_ports_value: *ports
|
||||
changed: false
|
||||
|
||||
- name: publish_all_ports ({{ test_case.test_name }})
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
publish_all_ports: "{{ test_case.publish_all_ports_value | default(omit) }}"
|
||||
published_ports: "{{ test_case.published_ports_value | default(omit) }}"
|
||||
force_kill: yes
|
||||
register: publish_all_ports
|
||||
loop_control:
|
||||
loop_var: test_case
|
||||
loop: "{{ publish_all_ports_test_cases }}"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- publish_all_ports.results[index].changed == test_case.changed
|
||||
loop: "{{ publish_all_ports_test_cases }}"
|
||||
loop_control:
|
||||
index_var: index
|
||||
loop_var: test_case
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# Regression test for https://github.com/ansible/ansible/pull/45700
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cname: "{{ cname_prefix ~ '-45700' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname] }}"
|
||||
|
||||
- name: Start container
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
|
||||
- name: Stop container with a lot of invalid options
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
force_kill: yes
|
||||
# Some options with "invalid" values, which would
|
||||
# have to be parsed. The values are "invalid" because
|
||||
# the containers and networks listed here do not exist.
|
||||
# This can happen because the networks are removed
|
||||
# before the container is stopped (see
|
||||
# https://github.com/ansible/ansible/issues/45486).
|
||||
networks:
|
||||
- name: "nonexistant-network-{{ (2**32) | random }}"
|
||||
published_ports:
|
||||
- '1:2'
|
||||
- '3'
|
||||
links:
|
||||
- "nonexistant-container-{{ (2**32) | random }}:test"
|
||||
state: absent
|
||||
@@ -0,0 +1,455 @@
|
||||
---
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cname: "{{ cname_prefix ~ '-hi' }}"
|
||||
- name: Registering container name
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname] }}"
|
||||
|
||||
####################################################################
|
||||
## Creation ########################################################
|
||||
####################################################################
|
||||
|
||||
- name: Create container (check)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
check_mode: yes
|
||||
register: create_1
|
||||
|
||||
- name: Create container
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
register: create_2
|
||||
|
||||
- name: Create container (idempotent)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
register: create_3
|
||||
|
||||
- name: Create container (idempotent check)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
check_mode: yes
|
||||
register: create_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- create_1 is changed
|
||||
- create_2 is changed
|
||||
- create_3 is not changed
|
||||
- create_4 is not changed
|
||||
|
||||
####################################################################
|
||||
## Starting (after creation) #######################################
|
||||
####################################################################
|
||||
|
||||
- name: Start container (check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
check_mode: yes
|
||||
register: start_1
|
||||
|
||||
- name: Start container
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
register: start_2
|
||||
|
||||
- name: Start container (idempotent)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
register: start_3
|
||||
|
||||
- name: Start container (idempotent check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
check_mode: yes
|
||||
register: start_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- start_1 is changed
|
||||
- start_2 is changed
|
||||
- start_3 is not changed
|
||||
- start_4 is not changed
|
||||
|
||||
####################################################################
|
||||
## Present check for running container #############################
|
||||
####################################################################
|
||||
|
||||
- name: Present check for running container (check)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
check_mode: yes
|
||||
register: present_check_1
|
||||
|
||||
- name: Present check for running container
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
register: present_check_2
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- present_check_1 is not changed
|
||||
- present_check_2 is not changed
|
||||
|
||||
####################################################################
|
||||
## Starting (from scratch) #########################################
|
||||
####################################################################
|
||||
|
||||
- name: Remove container (setup for starting from scratch)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
|
||||
- name: Start container from scratch (check)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
stop_timeout: 1
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
check_mode: yes
|
||||
register: start_scratch_1
|
||||
|
||||
- name: Start container from scratch
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
stop_timeout: 1
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
register: start_scratch_2
|
||||
|
||||
- name: Start container from scratch (idempotent)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
stop_timeout: 1
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
register: start_scratch_3
|
||||
|
||||
- name: Start container from scratch (idempotent check)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
stop_timeout: 1
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
check_mode: yes
|
||||
register: start_scratch_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- start_scratch_1 is changed
|
||||
- start_scratch_2 is changed
|
||||
- start_scratch_3 is not changed
|
||||
- start_scratch_4 is not changed
|
||||
|
||||
####################################################################
|
||||
## Recreating ######################################################
|
||||
####################################################################
|
||||
|
||||
- name: Recreating container (created)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: recreate_1
|
||||
|
||||
- name: Recreating container (created, recreate, check mode)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
recreate: yes
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: recreate_2
|
||||
check_mode: yes
|
||||
|
||||
- name: Recreating container (created, recreate)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
recreate: yes
|
||||
state: present
|
||||
force_kill: yes
|
||||
register: recreate_3
|
||||
|
||||
- name: Recreating container (started)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
force_kill: yes
|
||||
register: recreate_4
|
||||
|
||||
- name: Recreating container (started, recreate, check mode)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
recreate: yes
|
||||
removal_wait_timeout: 10
|
||||
state: started
|
||||
force_kill: yes
|
||||
register: recreate_5
|
||||
check_mode: yes
|
||||
|
||||
- name: Recreating container (started, recreate)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
recreate: yes
|
||||
removal_wait_timeout: 10
|
||||
state: started
|
||||
force_kill: yes
|
||||
register: recreate_6
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- debug: var=recreate_1
|
||||
- debug: var=recreate_3
|
||||
- debug: var=recreate_4
|
||||
- debug: var=recreate_6
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- recreate_2 is changed
|
||||
- recreate_3 is changed
|
||||
- recreate_4 is changed
|
||||
- recreate_5 is changed
|
||||
- recreate_6 is changed
|
||||
- recreate_1.container.Id == recreate_2.container.Id
|
||||
- recreate_1.container.Id != recreate_3.container.Id
|
||||
- recreate_3.container.Id == recreate_4.container.Id
|
||||
- recreate_4.container.Id == recreate_5.container.Id
|
||||
- recreate_4.container.Id != recreate_6.container.Id
|
||||
|
||||
####################################################################
|
||||
## Restarting ######################################################
|
||||
####################################################################
|
||||
|
||||
- name: Restarting
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
stop_timeout: 1
|
||||
volumes:
|
||||
- /tmp/tmp
|
||||
register: restart_1
|
||||
|
||||
- name: Restarting (restart, check mode)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
restart: yes
|
||||
state: started
|
||||
stop_timeout: 1
|
||||
force_kill: yes
|
||||
register: restart_2
|
||||
check_mode: yes
|
||||
|
||||
- name: Restarting (restart)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
restart: yes
|
||||
state: started
|
||||
stop_timeout: 1
|
||||
force_kill: yes
|
||||
register: restart_3
|
||||
|
||||
- name: Restarting (verify volumes)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
stop_timeout: 1
|
||||
volumes:
|
||||
- /tmp/tmp
|
||||
register: restart_4
|
||||
|
||||
- name: cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- restart_1 is changed
|
||||
- restart_2 is changed
|
||||
- restart_3 is changed
|
||||
- restart_1.container.Id == restart_3.container.Id
|
||||
- restart_4 is not changed
|
||||
|
||||
####################################################################
|
||||
## Stopping ########################################################
|
||||
####################################################################
|
||||
|
||||
- name: Stop container (check)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
name: "{{ cname }}"
|
||||
state: stopped
|
||||
stop_timeout: 1
|
||||
check_mode: yes
|
||||
register: stop_1
|
||||
|
||||
- name: Stop container
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
name: "{{ cname }}"
|
||||
state: stopped
|
||||
stop_timeout: 1
|
||||
register: stop_2
|
||||
|
||||
- name: Stop container (idempotent)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
name: "{{ cname }}"
|
||||
state: stopped
|
||||
stop_timeout: 1
|
||||
register: stop_3
|
||||
|
||||
- name: Stop container (idempotent check)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
name: "{{ cname }}"
|
||||
state: stopped
|
||||
stop_timeout: 1
|
||||
check_mode: yes
|
||||
register: stop_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- stop_1 is changed
|
||||
- stop_2 is changed
|
||||
- stop_3 is not changed
|
||||
- stop_4 is not changed
|
||||
|
||||
####################################################################
|
||||
## Removing ########################################################
|
||||
####################################################################
|
||||
|
||||
- name: Remove container (check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
check_mode: yes
|
||||
register: remove_1
|
||||
|
||||
- name: Remove container
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
register: remove_2
|
||||
|
||||
- name: Remove container (idempotent)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
register: remove_3
|
||||
|
||||
- name: Remove container (idempotent check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
check_mode: yes
|
||||
register: remove_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- remove_1 is changed
|
||||
- remove_2 is changed
|
||||
- remove_3 is not changed
|
||||
- remove_4 is not changed
|
||||
|
||||
####################################################################
|
||||
## Removing (from running) #########################################
|
||||
####################################################################
|
||||
|
||||
- name: Start container (setup for removing from running)
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
state: started
|
||||
|
||||
- name: Remove container from running (check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
check_mode: yes
|
||||
register: remove_from_running_1
|
||||
|
||||
- name: Remove container from running
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
register: remove_from_running_2
|
||||
|
||||
- name: Remove container from running (idempotent)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
register: remove_from_running_3
|
||||
|
||||
- name: Remove container from running (idempotent check)
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
check_mode: yes
|
||||
register: remove_from_running_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- remove_from_running_1 is changed
|
||||
- remove_from_running_2 is changed
|
||||
- remove_from_running_3 is not changed
|
||||
- remove_from_running_4 is not changed
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group4
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,226 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: Create random container name
|
||||
set_fact:
|
||||
cname: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
|
||||
- name: Make sure container is not there
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
|
||||
- name: Execute in a non-present container
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
command: "/bin/bash -c 'ls -a'"
|
||||
register: result
|
||||
ignore_errors: true
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is failed
|
||||
- "'Could not find container' in result.msg"
|
||||
|
||||
- name: Make sure container exists
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
force_kill: yes
|
||||
|
||||
- name: Execute in a present container (command)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
command: "/bin/sh -c 'ls -a'"
|
||||
register: result_cmd
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result_cmd.rc == 0
|
||||
- "'stdout' in result_cmd"
|
||||
- "'stdout_lines' in result_cmd"
|
||||
- "'stderr' in result_cmd"
|
||||
- "'stderr_lines' in result_cmd"
|
||||
|
||||
- name: Execute in a present container (argv)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
argv:
|
||||
- /bin/sh
|
||||
- '-c'
|
||||
- ls -a
|
||||
register: result_argv
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result_argv.rc == 0
|
||||
- "'stdout' in result_argv"
|
||||
- "'stdout_lines' in result_argv"
|
||||
- "'stderr' in result_argv"
|
||||
- "'stderr_lines' in result_argv"
|
||||
- result_cmd.stdout == result_argv.stdout
|
||||
|
||||
- name: Execute in a present container (cat without stdin)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
argv:
|
||||
- /bin/sh
|
||||
- '-c'
|
||||
- cat
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result.rc == 0
|
||||
- result.stdout == ''
|
||||
- result.stdout_lines == []
|
||||
- result.stderr == ''
|
||||
- result.stderr_lines == []
|
||||
|
||||
- name: Execute in a present container (cat with stdin)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
argv:
|
||||
- /bin/sh
|
||||
- '-c'
|
||||
- cat
|
||||
stdin: Hello world!
|
||||
strip_empty_ends: false
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result.rc == 0
|
||||
- result.stdout == 'Hello world!\n'
|
||||
- result.stdout_lines == ['Hello world!']
|
||||
- result.stderr == ''
|
||||
- result.stderr_lines == []
|
||||
|
||||
- name: Execute in a present container (cat with stdin, no newline)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
argv:
|
||||
- /bin/sh
|
||||
- '-c'
|
||||
- cat
|
||||
stdin: Hello world!
|
||||
stdin_add_newline: false
|
||||
strip_empty_ends: false
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result.rc == 0
|
||||
- result.stdout == 'Hello world!'
|
||||
- result.stdout_lines == ['Hello world!']
|
||||
- result.stderr == ''
|
||||
- result.stderr_lines == []
|
||||
|
||||
- name: Execute in a present container (cat with stdin, newline but stripping)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
argv:
|
||||
- /bin/sh
|
||||
- '-c'
|
||||
- cat
|
||||
stdin: Hello world!
|
||||
stdin_add_newline: true
|
||||
strip_empty_ends: true
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result.rc == 0
|
||||
- result.stdout == 'Hello world!'
|
||||
- result.stdout_lines == ['Hello world!']
|
||||
- result.stderr == ''
|
||||
- result.stderr_lines == []
|
||||
|
||||
- name: Prepare long string
|
||||
set_fact:
|
||||
very_long_string: "{{ 'something long ' * 10000 }}"
|
||||
very_long_string2: "{{ 'something else ' * 5000 }}"
|
||||
|
||||
- name: Execute in a present container (long stdin)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
argv:
|
||||
- /bin/sh
|
||||
- '-c'
|
||||
- cat
|
||||
stdin: |-
|
||||
{{ very_long_string }}
|
||||
{{ very_long_string2 }}
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.rc == 0
|
||||
- result.stdout == very_long_string ~ '\n' ~ very_long_string2
|
||||
- result.stdout_lines == [very_long_string, very_long_string2]
|
||||
- result.stderr == ''
|
||||
- result.stderr_lines == []
|
||||
- "'exec_id' not in result"
|
||||
|
||||
- name: Execute in a present container (detached)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
argv:
|
||||
- /bin/sh
|
||||
- '-c'
|
||||
- sleep 1m
|
||||
detach: true
|
||||
register: result
|
||||
|
||||
- debug: var=result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is changed
|
||||
- "'rc' not in result"
|
||||
- "'stdout' not in result"
|
||||
- "'stderr' not in result"
|
||||
- result.exec_id is string
|
||||
|
||||
- when: docker_py_version is version('2.3.0', '>=') and docker_api_version is version('1.25', '>=')
|
||||
block:
|
||||
- name: Execute in a present container (environment variable)
|
||||
docker_container_exec:
|
||||
container: "{{ cname }}"
|
||||
argv:
|
||||
- /bin/sh
|
||||
- '-c'
|
||||
- 'echo "$FOO" ; echo $FOO > /dev/stderr'
|
||||
env:
|
||||
FOO: |-
|
||||
bar
|
||||
baz
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result.rc == 0
|
||||
- result.stdout == 'bar\nbaz'
|
||||
- result.stdout_lines == ['bar', 'baz']
|
||||
- result.stderr == 'bar baz'
|
||||
- result.stderr_lines == ['bar baz']
|
||||
|
||||
always:
|
||||
- name: Cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
|
||||
when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_container_exec tests!"
|
||||
when: not(docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group5
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: Create random container name
|
||||
set_fact:
|
||||
cname: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
|
||||
- name: Make sure container is not there
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
|
||||
- name: Inspect a non-present container
|
||||
docker_container_info:
|
||||
name: "{{ cname }}"
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "not result.exists"
|
||||
- "'container' in result"
|
||||
- "result.container is none"
|
||||
|
||||
- name: Make sure container exists
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
state: started
|
||||
force_kill: yes
|
||||
|
||||
- name: Inspect a present container
|
||||
docker_container_info:
|
||||
name: "{{ cname }}"
|
||||
register: result
|
||||
- name: Dump docker_container_info result
|
||||
debug: var=result
|
||||
|
||||
- name: "Comparison: use 'docker inspect'"
|
||||
command: docker inspect "{{ cname }}"
|
||||
register: docker_inspect
|
||||
ignore_errors: yes
|
||||
- block:
|
||||
- set_fact:
|
||||
docker_inspect_result: "{{ docker_inspect.stdout | from_json }}"
|
||||
- name: Dump docker inspect result
|
||||
debug: var=docker_inspect_result
|
||||
when: docker_inspect is not failed
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result.exists
|
||||
- "'container' in result"
|
||||
- "result.container"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result.container == docker_inspect_result[0]"
|
||||
when: docker_inspect is not failed
|
||||
- assert:
|
||||
that:
|
||||
- "'is too new. Maximum supported API version is' in docker_inspect.stderr"
|
||||
when: docker_inspect is failed
|
||||
|
||||
always:
|
||||
- name: Cleanup
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
|
||||
when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_container_info tests!"
|
||||
when: not(docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group4
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,10 @@
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- include_tasks: test_host_info.yml
|
||||
when: docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.21', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_host_info tests!"
|
||||
when: not(docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.21', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,337 @@
|
||||
---
|
||||
- name: Create random container/volume name
|
||||
set_fact:
|
||||
cname: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
vname: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
|
||||
- debug:
|
||||
msg: "Using container name '{{ cname }}' and volume name '{{ vname }}'"
|
||||
|
||||
- block:
|
||||
- name: Get info on Docker host
|
||||
docker_host_info:
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage is not defined'
|
||||
|
||||
# Container and volume are created so that all lists are non-empty:
|
||||
# * container and volume lists are non-emtpy because of the created objects;
|
||||
# * image list is non-empty because the image of the container is there;
|
||||
# * network list is always non-empty (default networks).
|
||||
- name: Create container
|
||||
docker_container:
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
name: "{{ cname }}"
|
||||
labels:
|
||||
key1: value1
|
||||
key2: value2
|
||||
state: started
|
||||
register: container_output
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- container_output is changed
|
||||
|
||||
- name: Create a volume
|
||||
docker_volume:
|
||||
name: "{{ vname }}"
|
||||
register: volume_output
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- volume_output is changed
|
||||
|
||||
- name: Get info on Docker host and list containers
|
||||
docker_host_info:
|
||||
containers: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and list containers
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage is not defined'
|
||||
- 'output.containers[0].Image is string'
|
||||
- 'output.containers[0].ImageID is not defined'
|
||||
|
||||
- name: Get info on Docker host and list containers matching filters (single label)
|
||||
docker_host_info:
|
||||
containers: yes
|
||||
containers_filters:
|
||||
label: key1=value1
|
||||
register: output
|
||||
|
||||
- name: assert container is returned when filters are matched (single label)
|
||||
assert:
|
||||
that: "{{ output.containers | length }} == 1"
|
||||
|
||||
- name: Get info on Docker host and list containers matching filters (multiple labels)
|
||||
docker_host_info:
|
||||
containers: yes
|
||||
containers_filters:
|
||||
label:
|
||||
- key1=value1
|
||||
- key2=value2
|
||||
register: output
|
||||
|
||||
- name: assert container is returned when filters are matched (multiple labels)
|
||||
assert:
|
||||
that: "{{ output.containers | length }} == 1"
|
||||
|
||||
- name: Get info on Docker host and do not list containers which do not match filters
|
||||
docker_host_info:
|
||||
containers: yes
|
||||
containers_filters:
|
||||
label:
|
||||
- key1=value1
|
||||
- key2=value2
|
||||
- key3=value3
|
||||
register: output
|
||||
|
||||
- name: assert no container is returned when filters are not matched
|
||||
assert:
|
||||
that: "{{ output.containers | length }} == 0"
|
||||
|
||||
- name: Get info on Docker host and list containers with verbose output
|
||||
docker_host_info:
|
||||
containers: yes
|
||||
verbose_output: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and list containers with verbose output
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage is not defined'
|
||||
- 'output.containers[0].Image is string'
|
||||
- 'output.containers[0].ImageID is string'
|
||||
|
||||
- name: Get info on Docker host and list images
|
||||
docker_host_info:
|
||||
images: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and list images
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images[0].Id is string'
|
||||
- 'output.images[0].ParentId is not defined'
|
||||
- 'output.disk_usage is not defined'
|
||||
|
||||
- name: Get info on Docker host and list images with verbose output
|
||||
docker_host_info:
|
||||
images: yes
|
||||
verbose_output: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and list images with verbose output
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images[0].Id is string'
|
||||
- 'output.images[0].ParentId is string'
|
||||
- 'output.disk_usage is not defined'
|
||||
|
||||
- name: Get info on Docker host and list networks
|
||||
docker_host_info:
|
||||
networks: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and list networks
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks[0].Id is string'
|
||||
- 'output.networks[0].Created is not defined'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage is not defined'
|
||||
|
||||
- name: Get info on Docker host and list networks with verbose output
|
||||
docker_host_info:
|
||||
networks: yes
|
||||
verbose_output: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and list networks with verbose output
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks[0].Id is string'
|
||||
- 'output.networks[0].Created is string'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage is not defined'
|
||||
|
||||
- name: Get info on Docker host and list volumes
|
||||
docker_host_info:
|
||||
volumes: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and list volumes
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes[0].Name is string'
|
||||
- 'output.volumes[0].Mountpoint is not defined'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage is not defined'
|
||||
|
||||
- name: Get info on Docker host and list volumes with verbose output
|
||||
docker_host_info:
|
||||
volumes: yes
|
||||
verbose_output: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and list volumes with verbose output
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes[0].Name is string'
|
||||
- 'output.volumes[0].Mountpoint is string'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage is not defined'
|
||||
|
||||
- name: Get info on Docker host and get disk usage
|
||||
docker_host_info:
|
||||
disk_usage: yes
|
||||
register: output
|
||||
ignore_errors: yes
|
||||
|
||||
- name: assert reading docker host facts when docker is running and get disk usage
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage.LayersSize is number'
|
||||
- 'output.disk_usage.BuilderSize is not defined'
|
||||
when: docker_py_version is version('2.2.0', '>=')
|
||||
- assert:
|
||||
that:
|
||||
- output is failed
|
||||
- "('version is ' ~ docker_py_version ~ ' ') in output.msg"
|
||||
- "'Minimum version required is 2.2.0 ' in output.msg"
|
||||
when: docker_py_version is version('2.2.0', '<')
|
||||
|
||||
- name: Get info on Docker host and get disk usage with verbose output
|
||||
docker_host_info:
|
||||
disk_usage: yes
|
||||
verbose_output: yes
|
||||
register: output
|
||||
ignore_errors: yes
|
||||
|
||||
- name: assert reading docker host facts when docker is running and get disk usage with verbose output
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers is not defined'
|
||||
- 'output.networks is not defined'
|
||||
- 'output.volumes is not defined'
|
||||
- 'output.images is not defined'
|
||||
- 'output.disk_usage.LayersSize is number'
|
||||
- 'output.disk_usage.BuilderSize is number'
|
||||
when: docker_py_version is version('2.2.0', '>=')
|
||||
- assert:
|
||||
that:
|
||||
- output is failed
|
||||
- "('version is ' ~ docker_py_version ~ ' ') in output.msg"
|
||||
- "'Minimum version required is 2.2.0 ' in output.msg"
|
||||
when: docker_py_version is version('2.2.0', '<')
|
||||
|
||||
- name: Get info on Docker host, disk usage and get all lists together
|
||||
docker_host_info:
|
||||
volumes: yes
|
||||
containers: yes
|
||||
networks: yes
|
||||
images: yes
|
||||
disk_usage: "{{ docker_py_version is version('2.2.0', '>=') }}"
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running, disk usage and get lists together
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers[0].Image is string'
|
||||
- 'output.containers[0].ImageID is not defined'
|
||||
- 'output.networks[0].Id is string'
|
||||
- 'output.networks[0].Created is not defined'
|
||||
- 'output.volumes[0].Name is string'
|
||||
- 'output.volumes[0].Mountpoint is not defined'
|
||||
- 'output.images[0].Id is string'
|
||||
- 'output.images[0].ParentId is not defined'
|
||||
- assert:
|
||||
that:
|
||||
- 'output.disk_usage.LayersSize is number'
|
||||
- 'output.disk_usage.BuilderSize is not defined'
|
||||
when: docker_py_version is version('2.2.0', '>=')
|
||||
|
||||
- name: Get info on Docker host, disk usage and get all lists together with verbose output
|
||||
docker_host_info:
|
||||
volumes: yes
|
||||
containers: yes
|
||||
networks: yes
|
||||
images: yes
|
||||
disk_usage: "{{ docker_py_version is version('2.2.0', '>=') }}"
|
||||
verbose_output: yes
|
||||
register: output
|
||||
|
||||
- name: assert reading docker host facts when docker is running and get disk usage with verbose output
|
||||
assert:
|
||||
that:
|
||||
- 'output.host_info.Name is string'
|
||||
- 'output.containers[0].Image is string'
|
||||
- 'output.containers[0].ImageID is string'
|
||||
- 'output.networks[0].Id is string'
|
||||
- 'output.networks[0].Created is string'
|
||||
- 'output.volumes[0].Name is string'
|
||||
- 'output.volumes[0].Mountpoint is string'
|
||||
- 'output.images[0].Id is string'
|
||||
- 'output.images[0].ParentId is string'
|
||||
- assert:
|
||||
that:
|
||||
- 'output.disk_usage.LayersSize is number'
|
||||
- 'output.disk_usage.BuilderSize is number'
|
||||
when: docker_py_version is version('2.2.0', '>=')
|
||||
|
||||
always:
|
||||
- name: Delete container
|
||||
docker_container:
|
||||
name: "{{ cname }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
|
||||
- name: Delete volume
|
||||
docker_volume:
|
||||
name: "{{ vname }}"
|
||||
state: absent
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group4
|
||||
destructive
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker_registry
|
||||
- setup_remote_tmp_dir
|
||||
@@ -0,0 +1,8 @@
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- when: ansible_facts.distribution ~ ansible_facts.distribution_major_version not in ['CentOS6', 'RedHat6']
|
||||
include_tasks:
|
||||
file: test.yml
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: "Loading tasks from {{ item }}"
|
||||
include_tasks: "{{ item }}"
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
- name: Create random name prefix
|
||||
set_fact:
|
||||
name_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
- name: Create image and container list
|
||||
set_fact:
|
||||
inames: []
|
||||
cnames: []
|
||||
|
||||
- debug:
|
||||
msg: "Using name prefix {{ name_prefix }}"
|
||||
|
||||
- name: Create files directory
|
||||
file:
|
||||
path: '{{ remote_tmp_dir }}/files'
|
||||
state: directory
|
||||
|
||||
- name: Template files
|
||||
template:
|
||||
src: '{{ item }}'
|
||||
dest: '{{ remote_tmp_dir }}/files/{{ item }}'
|
||||
loop:
|
||||
- Dockerfile
|
||||
- EtcHostsDockerfile
|
||||
- MyDockerfile
|
||||
- StagedDockerfile
|
||||
|
||||
- block:
|
||||
- include_tasks: run-test.yml
|
||||
with_fileglob:
|
||||
- "tests/*.yml"
|
||||
|
||||
always:
|
||||
- name: "Make sure all images are removed"
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
with_items: "{{ inames }}"
|
||||
- name: "Make sure all containers are removed"
|
||||
docker_container:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
with_items: "{{ cnames }}"
|
||||
|
||||
when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_image tests!"
|
||||
when: not(docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,135 @@
|
||||
---
|
||||
####################################################################
|
||||
## basic ###########################################################
|
||||
####################################################################
|
||||
|
||||
- name: Make sure image is not there
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
register: absent_1
|
||||
|
||||
- name: Make sure image is not there (idempotency)
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
state: absent
|
||||
register: absent_2
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- absent_2 is not changed
|
||||
|
||||
- name: Make sure image is there
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
state: present
|
||||
source: pull
|
||||
pull:
|
||||
platform: amd64
|
||||
register: present_1
|
||||
|
||||
- name: Make sure image is there (idempotent)
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
state: present
|
||||
source: pull
|
||||
pull:
|
||||
platform: amd64
|
||||
register: present_2
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- present_1 is changed
|
||||
- present_2 is not changed
|
||||
|
||||
- name: Make sure tag is not there
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world_base }}:alias"
|
||||
state: absent
|
||||
|
||||
- name: Tag image with alias
|
||||
docker_image:
|
||||
source: local
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
repository: "{{ docker_test_image_hello_world_base }}:alias"
|
||||
register: tag_1
|
||||
|
||||
- name: Tag image with alias (idempotent)
|
||||
docker_image:
|
||||
source: local
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
repository: "{{ docker_test_image_hello_world_base }}:alias"
|
||||
register: tag_2
|
||||
|
||||
- name: Tag image with alias (force, still idempotent)
|
||||
docker_image:
|
||||
source: local
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
repository: "{{ docker_test_image_hello_world_base }}:alias"
|
||||
force_tag: yes
|
||||
register: tag_3
|
||||
|
||||
- name: Tag image with ID instead of name
|
||||
docker_image:
|
||||
source: local
|
||||
name: "{{ present_1.image.Id }}"
|
||||
repository: "{{ docker_test_image_hello_world_base }}:alias"
|
||||
register: tag_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- tag_1 is changed
|
||||
- tag_2 is not changed
|
||||
- tag_3 is not changed
|
||||
- tag_4 is not changed
|
||||
|
||||
- name: Cleanup alias tag
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world_base }}:alias"
|
||||
state: absent
|
||||
|
||||
- name: Tag image with ID instead of name (use ID for repository, must fail)
|
||||
docker_image:
|
||||
source: local
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
repository: "{{ present_1.image.Id }}"
|
||||
register: fail_1
|
||||
ignore_errors: true
|
||||
|
||||
- name: Push image with ID (must fail)
|
||||
docker_image:
|
||||
source: local
|
||||
name: "{{ present_1.image.Id }}"
|
||||
push: true
|
||||
register: fail_2
|
||||
ignore_errors: true
|
||||
|
||||
- name: Pull image ID (must fail)
|
||||
docker_image:
|
||||
source: pull
|
||||
name: "{{ present_1.image.Id }}"
|
||||
force_source: true
|
||||
register: fail_3
|
||||
ignore_errors: true
|
||||
|
||||
- name: buildargs
|
||||
docker_image:
|
||||
source: build
|
||||
name: "{{ present_1.image.Id }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
force_source: true
|
||||
register: fail_4
|
||||
ignore_errors: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- fail_1 is failed
|
||||
- "'`repository` must not be an image ID' in fail_1.msg"
|
||||
- fail_2 is failed
|
||||
- "'Cannot push an image by ID' in fail_2.msg"
|
||||
- fail_3 is failed
|
||||
- "'Image name must not be an image ID for source=pull' in fail_3.msg"
|
||||
- fail_4 is failed
|
||||
- "'Image name must not be an image ID for source=build' in fail_4.msg"
|
||||
@@ -0,0 +1,255 @@
|
||||
---
|
||||
- name: Registering image name
|
||||
set_fact:
|
||||
iname: "{{ name_prefix ~ '-options' }}"
|
||||
|
||||
- name: Determining pushed image names
|
||||
set_fact:
|
||||
hello_world_image_base: "{{ registry_address }}/test/hello-world"
|
||||
test_image_base: "{{ registry_address }}/test/{{ iname }}"
|
||||
|
||||
- name: Registering image name
|
||||
set_fact:
|
||||
inames: "{{ inames + [iname, test_image_base ~ ':latest', test_image_base ~ ':other', hello_world_image_base ~ ':latest', hello_world_image_base ~ ':newtag', hello_world_image_base ~ ':newtag2'] }}"
|
||||
|
||||
####################################################################
|
||||
## interact with test registry #####################################
|
||||
####################################################################
|
||||
|
||||
- name: Make sure image is not there
|
||||
docker_image:
|
||||
name: "{{ hello_world_image_base }}:latest"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- name: Make sure we have {{ docker_test_image_hello_world }}
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
source: pull
|
||||
|
||||
- name: Push image to test registry
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
repository: "{{ hello_world_image_base }}:latest"
|
||||
push: yes
|
||||
source: local
|
||||
register: push_1
|
||||
|
||||
- name: Push image to test registry (idempotent)
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
repository: "{{ hello_world_image_base }}:latest"
|
||||
push: yes
|
||||
source: local
|
||||
register: push_2
|
||||
|
||||
- name: Push image to test registry (force, still idempotent)
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
repository: "{{ hello_world_image_base }}:latest"
|
||||
push: yes
|
||||
source: local
|
||||
force_tag: yes
|
||||
register: push_3
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- push_1 is changed
|
||||
- push_2 is not changed
|
||||
- push_3 is not changed
|
||||
|
||||
- name: Get facts of local image
|
||||
docker_image_info:
|
||||
name: "{{ hello_world_image_base }}:latest"
|
||||
register: facts_1
|
||||
|
||||
- name: Make sure image is not there
|
||||
docker_image:
|
||||
name: "{{ hello_world_image_base }}:latest"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- name: Get facts of local image (absent)
|
||||
docker_image_info:
|
||||
name: "{{ hello_world_image_base }}:latest"
|
||||
register: facts_2
|
||||
|
||||
- name: Pull image from test registry
|
||||
docker_image:
|
||||
name: "{{ hello_world_image_base }}:latest"
|
||||
state: present
|
||||
source: pull
|
||||
register: pull_1
|
||||
|
||||
- name: Pull image from test registry (idempotency)
|
||||
docker_image:
|
||||
name: "{{ hello_world_image_base }}:latest"
|
||||
state: present
|
||||
source: pull
|
||||
register: pull_2
|
||||
|
||||
- name: Get facts of local image (present)
|
||||
docker_image_info:
|
||||
name: "{{ hello_world_image_base }}:latest"
|
||||
register: facts_3
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- pull_1 is changed
|
||||
- pull_2 is not changed
|
||||
- facts_1.images | length == 1
|
||||
- facts_2.images | length == 0
|
||||
- facts_3.images | length == 1
|
||||
|
||||
- name: Pull image from test registry (with digest)
|
||||
docker_image:
|
||||
name: "{{ facts_3.images[0].RepoDigests[0] }}"
|
||||
state: present
|
||||
source: pull
|
||||
force_source: true
|
||||
register: pull_digest
|
||||
|
||||
- name: Make sure that changed is still false
|
||||
assert:
|
||||
that:
|
||||
- pull_digest is not changed
|
||||
|
||||
- name: Tag different image with new tag
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_alpine_different }}"
|
||||
repository: "{{ hello_world_image_base }}:newtag"
|
||||
push: no
|
||||
source: pull
|
||||
|
||||
- name: Push different image with new tag
|
||||
docker_image:
|
||||
name: "{{ hello_world_image_base }}"
|
||||
repository: "{{ hello_world_image_base }}"
|
||||
tag: newtag
|
||||
push: yes
|
||||
source: local
|
||||
register: push_1_different
|
||||
|
||||
- name: Push different image with new tag (idempotent)
|
||||
docker_image:
|
||||
name: "{{ hello_world_image_base }}"
|
||||
repository: "{{ hello_world_image_base }}"
|
||||
tag: newtag
|
||||
push: yes
|
||||
source: local
|
||||
register: push_2_different
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- push_1_different is changed
|
||||
- push_2_different is not changed
|
||||
|
||||
- name: Tag same image with new tag
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_alpine_different }}"
|
||||
repository: "{{ hello_world_image_base }}:newtag2"
|
||||
push: no
|
||||
source: pull
|
||||
|
||||
- name: Push same image with new tag
|
||||
docker_image:
|
||||
name: "{{ hello_world_image_base }}"
|
||||
repository: "{{ hello_world_image_base }}"
|
||||
tag: newtag2
|
||||
push: yes
|
||||
source: local
|
||||
register: push_1_same
|
||||
|
||||
- name: Push same image with new tag (idempotent)
|
||||
docker_image:
|
||||
name: "{{ hello_world_image_base }}"
|
||||
repository: "{{ hello_world_image_base }}"
|
||||
tag: newtag2
|
||||
push: yes
|
||||
source: local
|
||||
register: push_2_same
|
||||
|
||||
- assert:
|
||||
that:
|
||||
# NOTE: This should be:
|
||||
# - push_1_same is changed
|
||||
# Unfortunately docker does *NOT* report whether the tag already existed or not.
|
||||
# Here are the logs returned by client.push() for both tasks (which are exactly the same):
|
||||
# push_1_same:
|
||||
# {"status": "The push refers to repository [localhost:32796/test/hello-world]"},
|
||||
# {"id": "3fc64803ca2d", "progressDetail": {}, "status": "Preparing"},
|
||||
# {"id": "3fc64803ca2d", "progressDetail": {}, "status": "Layer already exists"},
|
||||
# {"status": "newtag2: digest: sha256:92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b size: 528"},
|
||||
# {"aux": {"Digest": "sha256:92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b", "Size": 528, "Tag": "newtag2"}, "progressDetail": {}}
|
||||
# push_2_same:
|
||||
# {"status": "The push refers to repository [localhost:32796/test/hello-world]"},
|
||||
# {"id": "3fc64803ca2d", "progressDetail": {}, "status": "Preparing"},
|
||||
# {"id": "3fc64803ca2d", "progressDetail": {}, "status": "Layer already exists"},
|
||||
# {"status": "newtag2: digest: sha256:92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b size: 528"},
|
||||
# {"aux": {"Digest": "sha256:92251458088c638061cda8fd8b403b76d661a4dc6b7ee71b6affcf1872557b2b", "Size": 528, "Tag": "newtag2"}, "progressDetail": {}}
|
||||
- push_1_same is not changed
|
||||
- push_2_same is not changed
|
||||
|
||||
####################################################################
|
||||
## repository ######################################################
|
||||
####################################################################
|
||||
|
||||
- name: Make sure image is not there
|
||||
docker_image:
|
||||
name: "{{ test_image_base }}:latest"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- name: repository
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
pull: no
|
||||
repository: "{{ test_image_base }}"
|
||||
source: build
|
||||
register: repository_1
|
||||
|
||||
- name: repository (idempotent)
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
repository: "{{ test_image_base }}"
|
||||
source: local
|
||||
register: repository_2
|
||||
|
||||
- name: repository, tag with ID
|
||||
docker_image:
|
||||
name: "{{ repository_1.image.Id }}"
|
||||
repository: "{{ test_image_base }}:other"
|
||||
source: local
|
||||
register: repository_3
|
||||
|
||||
- name: repository, tag with ID (idempotent)
|
||||
docker_image:
|
||||
name: "{{ repository_1.image.Id }}"
|
||||
repository: "{{ test_image_base }}:other"
|
||||
source: local
|
||||
force_tag: true
|
||||
register: repository_4
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- repository_1 is changed
|
||||
- repository_2 is not changed
|
||||
- repository_3 is changed
|
||||
- repository_4 is not changed
|
||||
|
||||
- name: Get facts of image
|
||||
docker_image_info:
|
||||
name: "{{ test_image_base }}:latest"
|
||||
register: facts_1
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ test_image_base }}:latest"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- facts_1.images | length == 1
|
||||
@@ -0,0 +1,404 @@
|
||||
---
|
||||
- name: Registering image name
|
||||
set_fact:
|
||||
iname: "{{ name_prefix ~ '-options' }}"
|
||||
iname_1: "{{ name_prefix ~ '-options-1' }}"
|
||||
|
||||
- name: Registering image name
|
||||
set_fact:
|
||||
inames: "{{ inames + [iname, iname_1] }}"
|
||||
|
||||
####################################################################
|
||||
## build.args ######################################################
|
||||
####################################################################
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- name: buildargs
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
args:
|
||||
TEST1: val1
|
||||
TEST2: val2
|
||||
TEST3: "True"
|
||||
pull: no
|
||||
source: build
|
||||
register: buildargs_1
|
||||
ignore_errors: yes
|
||||
|
||||
- name: buildargs (idempotency)
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
args:
|
||||
TEST1: val1
|
||||
TEST2: val2
|
||||
TEST3: "True"
|
||||
pull: no
|
||||
source: build
|
||||
register: buildargs_2
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- buildargs_1 is changed
|
||||
- buildargs_2 is not failed and buildargs_2 is not changed
|
||||
when: docker_py_version is version('1.6.0', '>=')
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- buildargs_1 is failed
|
||||
- buildargs_2 is failed
|
||||
when: docker_py_version is version('1.6.0', '<')
|
||||
|
||||
####################################################################
|
||||
## build.container_limits ##########################################
|
||||
####################################################################
|
||||
|
||||
- name: container_limits (Failed due to min memory limit)
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
container_limits:
|
||||
memory: 4000
|
||||
pull: no
|
||||
source: build
|
||||
ignore_errors: yes
|
||||
register: container_limits_1
|
||||
|
||||
- name: container_limits
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
container_limits:
|
||||
memory: 7000000
|
||||
memswap: 8000000
|
||||
pull: no
|
||||
source: build
|
||||
register: container_limits_2
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
# It *sometimes* happens that the first task does not fail.
|
||||
# For now, we work around this by
|
||||
# a) requiring that if it fails, the message must
|
||||
# contain 'Minimum memory limit allowed is (4|6)MB', and
|
||||
# b) requiring that either the first task, or the second
|
||||
# task is changed, but not both.
|
||||
- "not container_limits_1 is failed or ('Minimum memory limit allowed is ') in container_limits_1.msg"
|
||||
- "container_limits_1 is changed or container_limits_2 is changed and not (container_limits_1 is changed and container_limits_2 is changed)"
|
||||
|
||||
####################################################################
|
||||
## build.dockerfile ################################################
|
||||
####################################################################
|
||||
|
||||
- name: dockerfile
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
dockerfile: "MyDockerfile"
|
||||
pull: no
|
||||
source: build
|
||||
register: dockerfile_1
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- dockerfile_1 is changed
|
||||
- "('FROM ' ~ docker_test_image_alpine) in dockerfile_1.stdout"
|
||||
- dockerfile_1['image']['Config']['WorkingDir'] == '/newdata'
|
||||
|
||||
####################################################################
|
||||
## build.platform ##################################################
|
||||
####################################################################
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- name: build.platform
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
platform: linux
|
||||
pull: no
|
||||
source: build
|
||||
register: platform_1
|
||||
ignore_errors: yes
|
||||
|
||||
- name: build.platform (idempotency)
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
platform: linux
|
||||
pull: no
|
||||
source: build
|
||||
register: platform_2
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- platform_1 is changed
|
||||
- platform_2 is not failed and platform_2 is not changed
|
||||
when: docker_py_version is version('3.0.0', '>=')
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- platform_1 is failed
|
||||
- platform_2 is failed
|
||||
when: docker_py_version is version('3.0.0', '<')
|
||||
|
||||
####################################################################
|
||||
## force ###########################################################
|
||||
####################################################################
|
||||
|
||||
- name: Build an image
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
pull: no
|
||||
source: build
|
||||
|
||||
- name: force (changed)
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
dockerfile: "MyDockerfile"
|
||||
pull: no
|
||||
source: build
|
||||
force_source: yes
|
||||
register: force_1
|
||||
|
||||
- name: force (unchanged)
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
dockerfile: "MyDockerfile"
|
||||
pull: no
|
||||
source: build
|
||||
force_source: yes
|
||||
register: force_2
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- force_1 is changed
|
||||
- force_2 is not changed
|
||||
|
||||
####################################################################
|
||||
## load path #######################################################
|
||||
####################################################################
|
||||
|
||||
- name: Archive image
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
archive_path: "{{ remote_tmp_dir }}/image.tar"
|
||||
source: pull
|
||||
register: archive_image
|
||||
|
||||
- name: Archive image by ID
|
||||
docker_image:
|
||||
name: "{{ archive_image.image.Id }}"
|
||||
archive_path: "{{ remote_tmp_dir }}/image_id.tar"
|
||||
source: local
|
||||
register: archive_image_id
|
||||
|
||||
- name: Create invalid archive
|
||||
copy:
|
||||
dest: "{{ remote_tmp_dir }}/image-invalid.tar"
|
||||
content: "this is not a valid image"
|
||||
|
||||
- name: remove image
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- name: load image (changed)
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
load_path: "{{ remote_tmp_dir }}/image.tar"
|
||||
source: load
|
||||
register: load_image
|
||||
|
||||
- name: load image (idempotency)
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
load_path: "{{ remote_tmp_dir }}/image.tar"
|
||||
source: load
|
||||
register: load_image_1
|
||||
|
||||
- name: load image (wrong name)
|
||||
docker_image:
|
||||
name: foo:bar
|
||||
load_path: "{{ remote_tmp_dir }}/image.tar"
|
||||
source: load
|
||||
register: load_image_2
|
||||
ignore_errors: true
|
||||
|
||||
- name: load image (invalid image)
|
||||
docker_image:
|
||||
name: foo:bar
|
||||
load_path: "{{ remote_tmp_dir }}/image-invalid.tar"
|
||||
source: load
|
||||
register: load_image_3
|
||||
ignore_errors: true
|
||||
|
||||
- name: load image (invalid image, old API version)
|
||||
docker_image:
|
||||
name: foo:bar
|
||||
load_path: "{{ remote_tmp_dir }}/image-invalid.tar"
|
||||
source: load
|
||||
api_version: "1.22"
|
||||
register: load_image_4
|
||||
|
||||
- name: load image (ID, idempotency)
|
||||
docker_image:
|
||||
name: "{{ archive_image.image.Id }}"
|
||||
load_path: "{{ remote_tmp_dir }}/image_id.tar"
|
||||
source: load
|
||||
register: load_image_5
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- load_image is changed
|
||||
- archive_image['image']['Id'] == load_image['image']['Id']
|
||||
- load_image_1 is not changed
|
||||
- load_image_2 is failed
|
||||
- >-
|
||||
"The archive did not contain image 'foo:bar'. Instead, found '" ~ docker_test_image_hello_world ~ "'." == load_image_2.msg
|
||||
- load_image_3 is failed
|
||||
- '"Detected no loaded images. Archive potentially corrupt?" == load_image_3.msg'
|
||||
- load_image_4 is changed
|
||||
- "'The API version of your Docker daemon is < 1.23, which does not return the image loading result from the Docker daemon. Therefore, we cannot verify whether the expected image was loaded, whether multiple images where loaded, or whether the load actually succeeded. You should consider upgrading your Docker daemon.' in load_image_4.warnings"
|
||||
- load_image_5 is not changed
|
||||
|
||||
####################################################################
|
||||
## build.path ######################################################
|
||||
####################################################################
|
||||
|
||||
- name: Build image
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
pull: no
|
||||
source: build
|
||||
register: path_1
|
||||
|
||||
- name: Build image (idempotency)
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
pull: no
|
||||
source: build
|
||||
register: path_2
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- path_1 is changed
|
||||
- path_2 is not changed
|
||||
|
||||
####################################################################
|
||||
## build.target ####################################################
|
||||
####################################################################
|
||||
|
||||
- name: Build multi-stage image
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
dockerfile: "StagedDockerfile"
|
||||
target: first
|
||||
pull: no
|
||||
source: build
|
||||
register: dockerfile_2
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- dockerfile_2 is changed
|
||||
- dockerfile_2.image.Config.WorkingDir == '/first'
|
||||
|
||||
####################################################################
|
||||
## build.etc_hosts #################################################
|
||||
####################################################################
|
||||
|
||||
- name: Build image with custom etc_hosts
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
build:
|
||||
path: "{{ remote_tmp_dir }}/files"
|
||||
dockerfile: "EtcHostsDockerfile"
|
||||
pull: no
|
||||
etc_hosts:
|
||||
some-custom-host: "127.0.0.1"
|
||||
source: build
|
||||
register: path_1
|
||||
|
||||
- name: cleanup
|
||||
docker_image:
|
||||
name: "{{ iname }}"
|
||||
state: absent
|
||||
force_absent: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- path_1 is changed
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM {{ docker_test_image_busybox }}
|
||||
ENV foo /bar
|
||||
WORKDIR ${foo}
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM {{ docker_test_image_busybox }}
|
||||
# This should fail building if docker cannot resolve some-custom-host
|
||||
RUN ping -c1 some-custom-host
|
||||
@@ -0,0 +1,5 @@
|
||||
FROM {{ docker_test_image_alpine }}
|
||||
ENV INSTALL_PATH /newdata
|
||||
RUN mkdir -p $INSTALL_PATH
|
||||
|
||||
WORKDIR $INSTALL_PATH
|
||||
@@ -0,0 +1,7 @@
|
||||
FROM {{ docker_test_image_busybox }} AS first
|
||||
ENV dir /first
|
||||
WORKDIR ${dir}
|
||||
|
||||
FROM {{ docker_test_image_busybox }} AS second
|
||||
ENV dir /second
|
||||
WORKDIR ${dir}
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group4
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: Make sure image is not there
|
||||
docker_image:
|
||||
name: "{{ docker_test_image_alpine_different }}"
|
||||
state: absent
|
||||
|
||||
- name: Inspect a non-available image
|
||||
docker_image_info:
|
||||
name: "{{ docker_test_image_alpine_different }}"
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result.images|length == 0"
|
||||
|
||||
- name: Make sure images are there
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
source: pull
|
||||
state: present
|
||||
loop:
|
||||
- "{{ docker_test_image_hello_world }}"
|
||||
- "{{ docker_test_image_alpine }}"
|
||||
|
||||
- name: Inspect an available image
|
||||
docker_image_info:
|
||||
name: "{{ docker_test_image_hello_world }}"
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result.images|length == 1"
|
||||
- "docker_test_image_hello_world in result.images[0].RepoTags"
|
||||
|
||||
- name: Inspect multiple images
|
||||
docker_image_info:
|
||||
name:
|
||||
- "{{ docker_test_image_hello_world }}"
|
||||
- "{{ docker_test_image_alpine }}"
|
||||
register: result
|
||||
|
||||
- debug: var=result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result.images|length == 2"
|
||||
- "docker_test_image_hello_world in result.images[0].RepoTags"
|
||||
- "docker_test_image_alpine in result.images[1].RepoTags"
|
||||
|
||||
when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_image_info tests!"
|
||||
when: not(docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group4
|
||||
destructive
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
- setup_remote_tmp_dir
|
||||
@@ -0,0 +1,8 @@
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- when: ansible_facts.distribution ~ ansible_facts.distribution_major_version not in ['CentOS6', 'RedHat6']
|
||||
include_tasks:
|
||||
file: test.yml
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: "Loading tasks from {{ item }}"
|
||||
include_tasks: "{{ item }}"
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
- name: Create random name prefix
|
||||
set_fact:
|
||||
name_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
- name: Create image and container list
|
||||
set_fact:
|
||||
inames: []
|
||||
cnames: []
|
||||
|
||||
- debug:
|
||||
msg: "Using name prefix {{ name_prefix }}"
|
||||
|
||||
- block:
|
||||
- include_tasks: run-test.yml
|
||||
with_fileglob:
|
||||
- "tests/*.yml"
|
||||
|
||||
always:
|
||||
- name: "Make sure all images are removed"
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
with_items: "{{ inames }}"
|
||||
- name: "Make sure all containers are removed"
|
||||
docker_container:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
with_items: "{{ cnames }}"
|
||||
|
||||
when: docker_py_version is version('2.5.0', '>=') and docker_api_version is version('1.23', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_image tests!"
|
||||
when: not(docker_py_version is version('2.5.0', '>=') and docker_api_version is version('1.23', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,213 @@
|
||||
---
|
||||
- set_fact:
|
||||
image_names:
|
||||
- "{{ docker_test_image_hello_world }}"
|
||||
- "{{ docker_test_image_alpine_different }}"
|
||||
- "{{ docker_test_image_alpine }}"
|
||||
|
||||
- name: Make sure images are there
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
source: pull
|
||||
register: images
|
||||
loop: "{{ image_names }}"
|
||||
|
||||
- name: Compile list of all image names and IDs
|
||||
set_fact:
|
||||
image_ids: "{{ images.results | map(attribute='image') | map(attribute='Id') | list }}"
|
||||
all_images: "{{ image_names + (images.results | map(attribute='image') | map(attribute='Id') | list) }}"
|
||||
|
||||
- name: Create archives
|
||||
command: docker save {{ item.images | join(' ') }} -o {{ remote_tmp_dir }}/{{ item.file }}
|
||||
loop:
|
||||
- file: archive-1.tar
|
||||
images: "{{ image_names }}"
|
||||
- file: archive-2.tar
|
||||
images: "{{ image_ids }}"
|
||||
- file: archive-3.tar
|
||||
images:
|
||||
- "{{ image_names[0] }}"
|
||||
- "{{ image_ids[1] }}"
|
||||
- file: archive-4.tar
|
||||
images:
|
||||
- "{{ image_ids[0] }}"
|
||||
- "{{ image_names[0] }}"
|
||||
- file: archive-5.tar
|
||||
images:
|
||||
- "{{ image_ids[0] }}"
|
||||
|
||||
# All images by IDs
|
||||
|
||||
- name: Remove all images
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force_absent: true
|
||||
loop: "{{ all_images }}"
|
||||
ignore_errors: true
|
||||
register: remove_all_images
|
||||
|
||||
- name: Prune all containers (if removing failed)
|
||||
docker_prune:
|
||||
containers: true
|
||||
when: remove_all_images is failed
|
||||
|
||||
- name: Obtain all docker containers and images (if removing failed)
|
||||
shell: docker ps -a ; docker images -a
|
||||
when: remove_all_images is failed
|
||||
register: docker_container_image_list
|
||||
|
||||
- name: Show all docker containers and images (if removing failed)
|
||||
debug:
|
||||
var: docker_container_image_list.stdout_lines
|
||||
when: remove_all_images is failed
|
||||
|
||||
- name: Remove all images (after pruning)
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force_absent: true
|
||||
loop: "{{ all_images }}"
|
||||
when: remove_all_images is failed
|
||||
|
||||
- name: Load all images (IDs)
|
||||
docker_image_load:
|
||||
path: "{{ remote_tmp_dir }}/archive-2.tar"
|
||||
register: result
|
||||
|
||||
- name: Print loaded image names
|
||||
debug:
|
||||
var: result.image_names
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.image_names | sort == image_ids | sort
|
||||
- result.image_names | length == result.images | length
|
||||
|
||||
- name: Load all images (IDs, should be same result)
|
||||
docker_image_load:
|
||||
path: "{{ remote_tmp_dir }}/archive-2.tar"
|
||||
register: result_2
|
||||
|
||||
- name: Print loaded image names
|
||||
debug:
|
||||
var: result_2.image_names
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result_2 is changed
|
||||
- result_2.image_names | sort == image_ids | sort
|
||||
- result_2.image_names | length == result_2.images | length
|
||||
|
||||
# Mixed images and IDs
|
||||
|
||||
- name: Remove all images
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ all_images }}"
|
||||
|
||||
- name: Load all images (mixed images and IDs)
|
||||
docker_image_load:
|
||||
path: "{{ remote_tmp_dir }}/archive-3.tar"
|
||||
register: result
|
||||
|
||||
- name: Print loading log
|
||||
debug:
|
||||
var: result.stdout_lines
|
||||
|
||||
- name: Print loaded image names
|
||||
debug:
|
||||
var: result.image_names
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is changed
|
||||
# For some reason, *sometimes* only the named image is found; in fact, in that case, the log only mentions that image and nothing else
|
||||
- "result.images | length == 3 or ('Loaded image: ' ~ docker_test_image_hello_world) == result.stdout"
|
||||
- (result.image_names | sort) in [[image_names[0], image_ids[0], image_ids[1]] | sort, [image_names[0]]]
|
||||
- result.images | length in [1, 3]
|
||||
- (result.images | map(attribute='Id') | sort) in [[image_ids[0], image_ids[0], image_ids[1]] | sort, [image_ids[0]]]
|
||||
|
||||
# Same image twice
|
||||
|
||||
- name: Remove all images
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ all_images }}"
|
||||
|
||||
- name: Load all images (same image twice)
|
||||
docker_image_load:
|
||||
path: "{{ remote_tmp_dir }}/archive-4.tar"
|
||||
register: result
|
||||
|
||||
- name: Print loaded image names
|
||||
debug:
|
||||
var: result.image_names
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.image_names | length == 1
|
||||
- result.image_names[0] == image_names[0]
|
||||
- result.images | length == 1
|
||||
- result.images[0].Id == image_ids[0]
|
||||
|
||||
# Single image by ID
|
||||
|
||||
- name: Remove all images
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ all_images }}"
|
||||
|
||||
- name: Load all images (single image by ID)
|
||||
docker_image_load:
|
||||
path: "{{ remote_tmp_dir }}/archive-5.tar"
|
||||
register: result
|
||||
|
||||
- name: Print loaded image names
|
||||
debug:
|
||||
var: result.image_names
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.image_names | length == 1
|
||||
- result.image_names[0] == image_ids[0]
|
||||
- result.images | length == 1
|
||||
- result.images[0].Id == image_ids[0]
|
||||
|
||||
- name: Try to get image info by name
|
||||
docker_image_info:
|
||||
name: "{{ image_names[0] }}"
|
||||
register: result
|
||||
|
||||
- name: Make sure that image does not exist by name
|
||||
assert:
|
||||
that:
|
||||
- result.images | length == 0
|
||||
|
||||
# All images by names
|
||||
|
||||
- name: Remove all images
|
||||
docker_image:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ all_images }}"
|
||||
|
||||
- name: Load all images (names)
|
||||
docker_image_load:
|
||||
path: "{{ remote_tmp_dir }}/archive-1.tar"
|
||||
register: result
|
||||
|
||||
- name: Print loaded image names
|
||||
debug:
|
||||
var: result.image_names
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result.image_names | sort == image_names | sort
|
||||
- result.image_names | length == result.images | length
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group4
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker_registry
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- when: ansible_facts.distribution ~ ansible_facts.distribution_major_version not in ['CentOS6', 'RedHat6']
|
||||
include_tasks:
|
||||
file: test.yml
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: "Loading tasks from {{ item }}"
|
||||
include_tasks: "{{ item }}"
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
- block:
|
||||
- include_tasks: run-test.yml
|
||||
with_fileglob:
|
||||
- "tests/*.yml"
|
||||
when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_image tests!"
|
||||
when: not(docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,146 @@
|
||||
---
|
||||
- block:
|
||||
- name: Log out server
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: absent
|
||||
|
||||
- name: Log in with wrong password (check mode)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: "1234"
|
||||
state: present
|
||||
register: login_failed_check
|
||||
ignore_errors: yes
|
||||
check_mode: yes
|
||||
|
||||
- name: Log in with wrong password
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: "1234"
|
||||
state: present
|
||||
register: login_failed
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Make sure that login failed
|
||||
assert:
|
||||
that:
|
||||
- login_failed_check is failed
|
||||
- "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed_check.msg"
|
||||
- login_failed is failed
|
||||
- "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed.msg"
|
||||
|
||||
- name: Log in (check mode)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: present
|
||||
register: login_1
|
||||
check_mode: yes
|
||||
|
||||
- name: Log in
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: present
|
||||
register: login_2
|
||||
|
||||
- name: Get permissions of ~/.docker/config.json
|
||||
stat:
|
||||
path: ~/.docker/config.json
|
||||
register: login_2_stat
|
||||
|
||||
- name: Log in (idempotent)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: present
|
||||
register: login_3
|
||||
|
||||
- name: Log in (idempotent, check mode)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: present
|
||||
register: login_4
|
||||
check_mode: yes
|
||||
|
||||
- name: Make sure that login worked
|
||||
assert:
|
||||
that:
|
||||
- login_1 is changed
|
||||
- login_2 is changed
|
||||
- login_3 is not changed
|
||||
- login_4 is not changed
|
||||
- login_2_stat.stat.mode == '0600'
|
||||
|
||||
- name: Log in again with wrong password (check mode)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: "1234"
|
||||
state: present
|
||||
register: login_failed_check
|
||||
ignore_errors: yes
|
||||
check_mode: yes
|
||||
|
||||
- name: Log in again with wrong password
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: "1234"
|
||||
state: present
|
||||
register: login_failed
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Make sure that login failed again
|
||||
assert:
|
||||
that:
|
||||
- login_failed_check is failed
|
||||
- "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed_check.msg"
|
||||
- login_failed is failed
|
||||
- "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed.msg"
|
||||
|
||||
- name: Log out (check mode)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
state: absent
|
||||
register: logout_1
|
||||
check_mode: yes
|
||||
|
||||
- name: Log out
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
state: absent
|
||||
register: logout_2
|
||||
|
||||
- name: Log out (idempotent)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
state: absent
|
||||
register: logout_3
|
||||
|
||||
- name: Log out (idempotent, check mode)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
state: absent
|
||||
register: logout_4
|
||||
check_mode: yes
|
||||
|
||||
- name: Make sure that login worked
|
||||
assert:
|
||||
that:
|
||||
- logout_1 is changed
|
||||
- logout_2 is changed
|
||||
- logout_3 is not changed
|
||||
- logout_4 is not changed
|
||||
|
||||
when: registry_frontend_address != 'n/a'
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
- block:
|
||||
- name: Log out server 1
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: absent
|
||||
|
||||
- name: Log out server 2
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend2_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: absent
|
||||
|
||||
- name: Log in server 1
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: present
|
||||
register: login_1
|
||||
|
||||
- name: Log in server 2
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend2_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: present
|
||||
register: login_2
|
||||
|
||||
- name: Log in server 1 (idempotent)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: present
|
||||
register: login_1_2
|
||||
|
||||
- name: Log in server 2 (idempotent)
|
||||
docker_login:
|
||||
registry_url: "{{ registry_frontend2_address }}"
|
||||
username: testuser
|
||||
password: hunter2
|
||||
state: present
|
||||
register: login_2_2
|
||||
|
||||
- name: Make sure that login worked
|
||||
assert:
|
||||
that:
|
||||
- login_1 is changed
|
||||
- login_2 is changed
|
||||
- login_1_2 is not changed
|
||||
- login_2_2 is not changed
|
||||
|
||||
when: registry_frontend_address != 'n/a' and registry_frontend2_address != 'n/a'
|
||||
@@ -0,0 +1,2 @@
|
||||
shippable/posix/group4
|
||||
destructive
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- setup_docker
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
- name: List inspection results for all docker networks
|
||||
docker_host_info:
|
||||
networks: true
|
||||
verbose_output: true
|
||||
register: all_networks
|
||||
|
||||
- name: Show inspection results for all docker networks
|
||||
debug:
|
||||
var: all_networks.networks
|
||||
|
||||
- name: Create random name prefix
|
||||
set_fact:
|
||||
name_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
|
||||
cnames: []
|
||||
dnetworks: []
|
||||
|
||||
- debug:
|
||||
msg: "Using name prefix {{ name_prefix }}"
|
||||
|
||||
- block:
|
||||
- include_tasks: run-test.yml
|
||||
with_fileglob:
|
||||
- "tests/*.yml"
|
||||
|
||||
always:
|
||||
- name: "Make sure all containers are removed"
|
||||
docker_container:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
loop: "{{ cnames }}"
|
||||
- name: "Make sure all networks are removed"
|
||||
docker_network:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
force: yes
|
||||
loop: "{{ dnetworks }}"
|
||||
|
||||
when: docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.20', '>=') # FIXME: find out API version!
|
||||
|
||||
- fail: msg="Too old docker / docker-py version to run docker_network tests!"
|
||||
when: not(docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.20', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: "Loading tasks from {{ item }}"
|
||||
include_tasks: "{{ item }}"
|
||||
@@ -0,0 +1,134 @@
|
||||
---
|
||||
- name: Registering container and network names
|
||||
set_fact:
|
||||
cname_1: "{{ name_prefix ~ '-container-1' }}"
|
||||
cname_2: "{{ name_prefix ~ '-container-2' }}"
|
||||
cname_3: "{{ name_prefix ~ '-container-3' }}"
|
||||
nname_1: "{{ name_prefix ~ '-network-1' }}"
|
||||
nname_2: "{{ name_prefix ~ '-network-2' }}"
|
||||
- name: Registering container and network names
|
||||
set_fact:
|
||||
cnames: "{{ cnames + [cname_1, cname_2, cname_3] }}"
|
||||
dnetworks: "{{ dnetworks + [nname_1, nname_2] }}"
|
||||
|
||||
- name: Create containers
|
||||
docker_container:
|
||||
name: "{{ container_name }}"
|
||||
image: "{{ docker_test_image_alpine }}"
|
||||
command: /bin/sleep 10m
|
||||
state: started
|
||||
loop:
|
||||
- "{{ cname_1 }}"
|
||||
- "{{ cname_2 }}"
|
||||
- "{{ cname_3 }}"
|
||||
loop_control:
|
||||
loop_var: container_name
|
||||
|
||||
####################################################################
|
||||
|
||||
- name: Create network
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
register: networks_1
|
||||
|
||||
- name: Connect network to containers 1
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ cname_1 }}"
|
||||
register: networks_2
|
||||
|
||||
- name: Connect network to containers 1 (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ cname_1 }}"
|
||||
register: networks_2_idem
|
||||
|
||||
- name: Connect network to containers 1 and 2
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ cname_1 }}"
|
||||
- "{{ cname_2 }}"
|
||||
register: networks_3
|
||||
|
||||
- name: Connect network to containers 1 and 2 (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ cname_1 }}"
|
||||
- "{{ cname_2 }}"
|
||||
register: networks_3_idem
|
||||
|
||||
- name: Connect network to container 3
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ cname_3 }}"
|
||||
appends: yes
|
||||
register: networks_4
|
||||
|
||||
- name: Connect network to container 3 (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ cname_3 }}"
|
||||
appends: yes
|
||||
register: networks_4_idem
|
||||
|
||||
- name: Disconnect network from container 1
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ cname_2 }}"
|
||||
- "{{ cname_3 }}"
|
||||
register: networks_5
|
||||
|
||||
- name: Disconnect network from container 1 (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ cname_2 }}"
|
||||
- "{{ cname_3 }}"
|
||||
register: networks_5_idem
|
||||
|
||||
- name: Cleanup
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: absent
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_1 is changed
|
||||
- networks_2 is changed
|
||||
- networks_2_idem is not changed
|
||||
- networks_3 is changed
|
||||
- networks_3_idem is not changed
|
||||
- networks_4 is changed
|
||||
- networks_4_idem is not changed
|
||||
- networks_5 is changed
|
||||
- networks_5_idem is not changed
|
||||
|
||||
####################################################################
|
||||
|
||||
- name: Delete containers
|
||||
docker_container:
|
||||
name: "{{ container_name }}"
|
||||
state: absent
|
||||
force_kill: yes
|
||||
loop:
|
||||
- "{{ cname_1 }}"
|
||||
- "{{ cname_2 }}"
|
||||
- "{{ cname_3 }}"
|
||||
loop_control:
|
||||
loop_var: container_name
|
||||
@@ -0,0 +1,312 @@
|
||||
---
|
||||
- name: Registering network names
|
||||
set_fact:
|
||||
nname_ipam_0: "{{ name_prefix ~ '-network-ipam-0' }}"
|
||||
nname_ipam_1: "{{ name_prefix ~ '-network-ipam-1' }}"
|
||||
nname_ipam_2: "{{ name_prefix ~ '-network-ipam-2' }}"
|
||||
nname_ipam_3: "{{ name_prefix ~ '-network-ipam-3' }}"
|
||||
|
||||
- name: Registering network names
|
||||
set_fact:
|
||||
dnetworks: "{{ dnetworks + [nname_ipam_0, nname_ipam_1, nname_ipam_2, nname_ipam_3] }}"
|
||||
|
||||
|
||||
#################### IPv4 IPAM config ####################
|
||||
|
||||
- name: Create network with custom IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_1 }}"
|
||||
ipam_config:
|
||||
- subnet: 10.25.120.0/24
|
||||
gateway: 10.25.120.2
|
||||
iprange: 10.25.120.0/26
|
||||
aux_addresses:
|
||||
host1: 10.25.120.3
|
||||
host2: 10.25.120.4
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is changed
|
||||
|
||||
- name: Create network with custom IPAM config (idempotence)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_1 }}"
|
||||
ipam_config:
|
||||
- subnet: 10.25.120.0/24
|
||||
gateway: 10.25.120.2
|
||||
iprange: 10.25.120.0/26
|
||||
aux_addresses:
|
||||
host1: 10.25.120.3
|
||||
host2: 10.25.120.4
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is not changed
|
||||
|
||||
- name: Change of network created with custom IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_1 }}"
|
||||
ipam_config:
|
||||
- subnet: 10.25.121.0/24
|
||||
gateway: 10.25.121.2
|
||||
iprange: 10.25.121.0/26
|
||||
aux_addresses:
|
||||
host1: 10.25.121.3
|
||||
register: network
|
||||
diff: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is changed
|
||||
- network.diff.differences | length == 4
|
||||
- '"ipam_config[0].subnet" in network.diff.differences'
|
||||
- '"ipam_config[0].gateway" in network.diff.differences'
|
||||
- '"ipam_config[0].iprange" in network.diff.differences'
|
||||
- '"ipam_config[0].aux_addresses" in network.diff.differences'
|
||||
|
||||
- name: Remove gateway and iprange of network with custom IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_1 }}"
|
||||
ipam_config:
|
||||
- subnet: 10.25.121.0/24
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is not changed
|
||||
|
||||
- name: Cleanup network with custom IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_1 }}"
|
||||
state: absent
|
||||
|
||||
|
||||
#################### IPv6 IPAM config ####################
|
||||
|
||||
- name: Create network with IPv6 IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_2 }}"
|
||||
enable_ipv6: yes
|
||||
ipam_config:
|
||||
- subnet: fdd1:ac8c:0557:7ce0::/64
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is changed
|
||||
|
||||
- name: Create network with IPv6 IPAM config (idempotence)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_2 }}"
|
||||
enable_ipv6: yes
|
||||
ipam_config:
|
||||
- subnet: fdd1:ac8c:0557:7ce0::/64
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is not changed
|
||||
|
||||
- name: Change subnet of network with IPv6 IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_2 }}"
|
||||
enable_ipv6: yes
|
||||
ipam_config:
|
||||
- subnet: fdd1:ac8c:0557:7ce1::/64
|
||||
register: network
|
||||
diff: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is changed
|
||||
- network.diff.differences | length == 1
|
||||
- network.diff.differences[0] == "ipam_config[0].subnet"
|
||||
|
||||
- name: Change subnet of network with IPv6 IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_2 }}"
|
||||
enable_ipv6: yes
|
||||
ipam_config:
|
||||
- subnet: "fdd1:ac8c:0557:7ce1::"
|
||||
register: network
|
||||
ignore_errors: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is failed
|
||||
- "network.msg == '\"fdd1:ac8c:0557:7ce1::\" is not a valid CIDR'"
|
||||
|
||||
- name: Cleanup network with IPv6 IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_2 }}"
|
||||
state: absent
|
||||
|
||||
|
||||
#################### IPv4 and IPv6 network ####################
|
||||
|
||||
- name: Create network with IPv6 and custom IPv4 IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
enable_ipv6: yes
|
||||
ipam_config:
|
||||
- subnet: 10.26.120.0/24
|
||||
- subnet: fdd1:ac8c:0557:7ce2::/64
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is changed
|
||||
|
||||
- name: Change subnet order of network with IPv6 and custom IPv4 IPAM config (idempotence)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
enable_ipv6: yes
|
||||
ipam_config:
|
||||
- subnet: fdd1:ac8c:0557:7ce2::/64
|
||||
- subnet: 10.26.120.0/24
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is not changed
|
||||
|
||||
- name: Remove IPv6 from network with custom IPv4 and IPv6 IPAM config (change)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
enable_ipv6: no
|
||||
ipam_config:
|
||||
- subnet: 10.26.120.0/24
|
||||
register: network
|
||||
diff: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is changed
|
||||
- network.diff.differences | length == 1
|
||||
- network.diff.differences[0] == "enable_ipv6"
|
||||
|
||||
- name: Cleanup network with IPv6 and custom IPv4 IPAM config
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
state: absent
|
||||
|
||||
|
||||
#################### multiple IPv4 networks ####################
|
||||
|
||||
- block:
|
||||
- name: Create network with two IPv4 IPAM configs
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
driver: "macvlan"
|
||||
driver_options:
|
||||
parent: "{{ ansible_default_ipv4.alias }}"
|
||||
ipam_config:
|
||||
- subnet: 10.26.120.0/24
|
||||
- subnet: 10.26.121.0/24
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is changed
|
||||
|
||||
- name: Create network with two IPv4 IPAM configs (idempotence)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
driver: "macvlan"
|
||||
driver_options:
|
||||
parent: "{{ ansible_default_ipv4.alias }}"
|
||||
ipam_config:
|
||||
- subnet: 10.26.121.0/24
|
||||
- subnet: 10.26.120.0/24
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is not changed
|
||||
|
||||
- name: Create network with two IPv4 IPAM configs (change)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
driver: "macvlan"
|
||||
driver_options:
|
||||
parent: "{{ ansible_default_ipv4.alias }}"
|
||||
ipam_config:
|
||||
- subnet: 10.26.120.0/24
|
||||
- subnet: 10.26.122.0/24
|
||||
register: network
|
||||
diff: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is changed
|
||||
- network.diff.differences | length == 1
|
||||
|
||||
- name: Create network with one IPv4 IPAM config (no change)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
driver: "macvlan"
|
||||
driver_options:
|
||||
parent: "{{ ansible_default_ipv4.alias }}"
|
||||
ipam_config:
|
||||
- subnet: 10.26.122.0/24
|
||||
register: network
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network is not changed
|
||||
|
||||
- name: Cleanup network
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
state: absent
|
||||
|
||||
when: ansible_facts.virtualization_type != 'docker'
|
||||
|
||||
|
||||
#################### IPAM driver options ####################
|
||||
|
||||
- name: Create network with IPAM driver options
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
ipam_driver: default
|
||||
ipam_driver_options:
|
||||
a: b
|
||||
register: network_1
|
||||
ignore_errors: yes
|
||||
- name: Create network with IPAM driver options (idempotence)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
ipam_driver: default
|
||||
ipam_driver_options:
|
||||
a: b
|
||||
diff: yes
|
||||
register: network_2
|
||||
ignore_errors: yes
|
||||
- name: Create network with IPAM driver options (change)
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
ipam_driver: default
|
||||
ipam_driver_options:
|
||||
a: c
|
||||
diff: yes
|
||||
register: network_3
|
||||
ignore_errors: yes
|
||||
- name: Cleanup network
|
||||
docker_network:
|
||||
name: "{{ nname_ipam_3 }}"
|
||||
state: absent
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- network_1 is changed
|
||||
- network_2 is not changed
|
||||
- network_3 is changed
|
||||
when: docker_py_version is version('2.0.0', '>=')
|
||||
- assert:
|
||||
that:
|
||||
- network_1 is failed
|
||||
- "('version is ' ~ docker_py_version ~ ' ') in network_1.msg"
|
||||
- "'Minimum version required is 2.0.0 ' in network_1.msg"
|
||||
when: docker_py_version is version('2.0.0', '<')
|
||||
@@ -0,0 +1,240 @@
|
||||
---
|
||||
- name: Registering network name
|
||||
set_fact:
|
||||
nname_1: "{{ name_prefix ~ '-network-1' }}"
|
||||
- name: Registering network name
|
||||
set_fact:
|
||||
dnetworks: "{{ dnetworks + [nname_1] }}"
|
||||
|
||||
####################################################################
|
||||
## internal ########################################################
|
||||
####################################################################
|
||||
|
||||
- name: internal
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
internal: yes
|
||||
register: internal_1
|
||||
|
||||
- name: internal (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
internal: yes
|
||||
register: internal_2
|
||||
|
||||
- name: internal (change)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
internal: no
|
||||
register: internal_3
|
||||
|
||||
- name: cleanup
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: absent
|
||||
force: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- internal_1 is changed
|
||||
- internal_2 is not changed
|
||||
- internal_3 is changed
|
||||
|
||||
####################################################################
|
||||
## driver_options ##################################################
|
||||
####################################################################
|
||||
|
||||
- name: driver_options
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver_options:
|
||||
com.docker.network.bridge.enable_icc: 'false'
|
||||
register: driver_options_1
|
||||
|
||||
- name: driver_options (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver_options:
|
||||
com.docker.network.bridge.enable_icc: 'false'
|
||||
register: driver_options_2
|
||||
|
||||
- name: driver_options (idempotency with string translation)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver_options:
|
||||
com.docker.network.bridge.enable_icc: False
|
||||
register: driver_options_3
|
||||
|
||||
- name: driver_options (change)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver_options:
|
||||
com.docker.network.bridge.enable_icc: 'true'
|
||||
register: driver_options_4
|
||||
|
||||
- name: driver_options (idempotency with string translation)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver_options:
|
||||
com.docker.network.bridge.enable_icc: True
|
||||
register: driver_options_5
|
||||
|
||||
- name: cleanup
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: absent
|
||||
force: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- driver_options_1 is changed
|
||||
- driver_options_2 is not changed
|
||||
- driver_options_3 is not changed
|
||||
- driver_options_4 is changed
|
||||
- driver_options_5 is not changed
|
||||
|
||||
####################################################################
|
||||
## scope ###########################################################
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
- name: scope
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver: bridge
|
||||
scope: local
|
||||
register: scope_1
|
||||
|
||||
- name: scope (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver: bridge
|
||||
scope: local
|
||||
register: scope_2
|
||||
|
||||
- name: swarm
|
||||
docker_swarm:
|
||||
state: present
|
||||
advertise_addr: "{{ansible_default_ipv4.address}}"
|
||||
|
||||
# Driver change alongside scope is intentional - bridge doesn't appear to support anything but local, and overlay can't downgrade to local. Additionally, overlay reports as swarm for swarm OR global, so no change is reported in that case.
|
||||
# Test output indicates that the scope is altered, at least, so manual inspection will be required to verify this going forward, unless we come up with a test driver that supports multiple scopes.
|
||||
- name: scope (change)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver: overlay
|
||||
scope: swarm
|
||||
register: scope_3
|
||||
|
||||
- name: cleanup network
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: absent
|
||||
force: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- scope_1 is changed
|
||||
- scope_2 is not changed
|
||||
- scope_3 is changed
|
||||
|
||||
always:
|
||||
- name: cleanup swarm
|
||||
docker_swarm:
|
||||
state: absent
|
||||
force: yes
|
||||
|
||||
# Requirements for docker_swarm
|
||||
when: docker_py_version is version('2.6.0', '>=') and docker_api_version is version('1.25', '>=')
|
||||
|
||||
####################################################################
|
||||
## attachable ######################################################
|
||||
####################################################################
|
||||
|
||||
- name: attachable
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
attachable: true
|
||||
register: attachable_1
|
||||
ignore_errors: yes
|
||||
|
||||
- name: attachable (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
attachable: true
|
||||
register: attachable_2
|
||||
ignore_errors: yes
|
||||
|
||||
- name: attachable (change)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
attachable: false
|
||||
register: attachable_3
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: absent
|
||||
force: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- attachable_1 is changed
|
||||
- attachable_2 is not changed
|
||||
- attachable_3 is changed
|
||||
when: docker_py_version is version('2.0.0', '>=')
|
||||
- assert:
|
||||
that:
|
||||
- attachable_1 is failed
|
||||
- "('version is ' ~ docker_py_version ~ ' ') in attachable_1.msg"
|
||||
- "'Minimum version required is 2.0.0 ' in attachable_1.msg"
|
||||
when: docker_py_version is version('2.0.0', '<')
|
||||
|
||||
####################################################################
|
||||
## labels ##########################################################
|
||||
####################################################################
|
||||
|
||||
- name: labels
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.2: world
|
||||
register: labels_1
|
||||
|
||||
- name: labels (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
labels:
|
||||
ansible.test.2: world
|
||||
ansible.test.1: hello
|
||||
register: labels_2
|
||||
|
||||
- name: labels (less labels)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
register: labels_3
|
||||
|
||||
- name: labels (more labels)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
labels:
|
||||
ansible.test.1: hello
|
||||
ansible.test.3: ansible
|
||||
register: labels_4
|
||||
|
||||
- name: cleanup
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: absent
|
||||
force: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- labels_1 is changed
|
||||
- labels_2 is not changed
|
||||
- labels_3 is not changed
|
||||
- labels_4 is changed
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
- name: Registering network name
|
||||
set_fact:
|
||||
nname_1: "{{ name_prefix ~ '-network-1' }}"
|
||||
- name: Registering network name
|
||||
set_fact:
|
||||
dnetworks: "{{ dnetworks + [nname_1] }}"
|
||||
|
||||
####################################################################
|
||||
## overlay #########################################################
|
||||
####################################################################
|
||||
|
||||
- block:
|
||||
# Overlay networks require swarm initialization before they'll work
|
||||
- name: swarm
|
||||
docker_swarm:
|
||||
state: present
|
||||
advertise_addr: "{{ansible_default_ipv4.address}}"
|
||||
|
||||
- name: overlay
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver: overlay
|
||||
driver_options:
|
||||
com.docker.network.driver.overlay.vxlanid_list: "257"
|
||||
register: overlay_1
|
||||
|
||||
- name: overlay (idempotency)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver: overlay
|
||||
driver_options:
|
||||
com.docker.network.driver.overlay.vxlanid_list: "257"
|
||||
register: overlay_2
|
||||
|
||||
- name: overlay (change)
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
driver: bridge
|
||||
register: overlay_3
|
||||
|
||||
- name: cleanup network
|
||||
docker_network:
|
||||
name: "{{ nname_1 }}"
|
||||
state: absent
|
||||
force: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- overlay_1 is changed
|
||||
- overlay_2 is not changed
|
||||
- overlay_3 is changed
|
||||
|
||||
always:
|
||||
- name: cleanup swarm
|
||||
docker_swarm:
|
||||
state: absent
|
||||
force: yes
|
||||
|
||||
# Requirements for docker_swarm
|
||||
when: docker_py_version is version('2.6.0', '>=') and docker_api_version is version('1.25', '>=')
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user