-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocker.sh
137 lines (121 loc) · 5.37 KB
/
docker.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/bin/bash
#
# Copyright (c) Ontic. (http://www.ontic.com.au). All rights reserved.
# See the COPYING file bundled with this package for license details.
#
# Ansible role test runner.
#
# Usage: [OPTIONS] ./tests/docker.sh [ action = ( build | test | verify ) ]
# - distribution: a supported Docker distribution name (default = "debian")
# - version: a associated Docker distribution version (default = "stretch")
# - playbook: a playbook in the tests directory (default = "test.yml")
# - cleanup: whether to remove the Docker container (default = true)
# - container_id: the --name to set for the container (default = timestamp)
# - test_idempotence: whether to test a playbook idempotence (default = true)
# - base_url: the base url for downloading Docker files (default = https://raw.githubusercontent.com/ontic/ansible-role-test/master/docker)
# Exit on any individual command failure.
set -e
# Terminal colors.
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
purple='\033[1;35m'
heading='\033[1;32m'
neutral='\033[0m'
if [ "${1}" != "build" ] && [ "${1}" != "test" ] && [ "${1}" != "verify" ]; then
printf "${red}Expected a supplied action of 'build', 'test' or 'verify'${neutral}\n"
exit 1
fi
# First argument used to execute an action.
action="${1}_action"
# Timestamp used as the default container ID.
timestamp=$(date +%s)
# Override default values with environment variables.
distribution=${distribution:-"debian"}
version=${version:-"stretch"}
playbook=${playbook:-"test.yml"}
inventory=${inventory:-"hosts"}
requirements=${requirements:-"requirements.yml"}
cleanup=${cleanup:-"true"}
container_id=${container_id:-$timestamp}
test_idempotence=${test_idempotence:-"true"}
base_url=${base_url:-"https://raw.githubusercontent.com/ontic/ansible-role-test/master/docker"}
# Set variables for each operating system which configure the container.
if [ "${distribution}/${version}" = "debian/9" ]; then
init="/lib/systemd/systemd"
opts="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
elif [ "${distribution}/${version}" = "ubuntu/16.04" ]; then
init="/lib/systemd/systemd"
opts="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
elif [ "${distribution}/${version}" = "ubuntu/18.04" ]; then
init="/lib/systemd/systemd"
opts="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
elif [ "${distribution}/${version}" = "ubuntu/20.04" ]; then
init="/lib/systemd/systemd"
opts="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
elif [ "${distribution}/${version}" = "centos/7" ]; then
init="/usr/lib/systemd/systemd"
opts="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
fi
# Build the container
build_action()
{
# Download Docker file for the supplied distribution and version.
wget -O "${PWD}/tests/Dockerfile" "${base_url}/Dockerfile.${distribution}-${version}"
# Build and run the container using the supplied distribution and version.
printf "${heading}Starting Docker container: ${distribution}/${version}${neutral}\n"
docker pull "${distribution}:${version}"
docker build --rm=true --file=tests/Dockerfile --tag="${distribution}-${version}:ansible" tests
docker run --detach --volume="${PWD}:/etc/ansible/roles/role_under_test:rw" --name="${container_id}" ${opts} "${distribution}-${version}:ansible" ${init}
# If the distribution is either Debian or Ubuntu.
if [ "${distribution}" = "debian" ] || [ "${distribution}" = "ubuntu" ]; then
# Update the repository cache so not required by playbooks.
docker exec --tty ${container_id} env TERM=xterm apt-get update
fi
}
# Test the role
test_action()
{
# If a requirements file exists.
if [ -f "${PWD}/tests/${requirements}" ]; then
# Install roles dependencies using Ansible Galaxy.
printf "\n${heading}Installing Ansible role dependencies.${neutral}\n"
docker exec --tty ${container_id} env TERM=xterm ansible-galaxy install -r tests/${requirements}
fi
# Test playbook syntax.
printf "\n${heading}Checking Ansible playbook syntax.${neutral}\n"
docker exec --tty ${container_id} env TERM=xterm ansible-playbook tests/${playbook} --syntax-check
# Run the playbook.
printf "\n${heading}Running Ansible playbook.${neutral}\n"
docker exec ${container_id} env TERM=xterm env ANSIBLE_FORCE_COLOR=1 ansible-playbook tests/${playbook}
# If testing for idempotence is configured.
if [ "${test_idempotence}" = true ]; then
# Create a temporary file for storing output.
idempotence=$(mktemp)
# Run the playbook again and record the output.
printf "\n${heading}Testing Ansible playbook idempotence.${neutral}\n"
docker exec ${container_id} ansible-playbook tests/${playbook} | tee -a ${idempotence}
tail ${idempotence} | grep -q 'changed=0.*failed=0' \
&& (printf ${green}"Idempotence test: [pass]"${neutral}) \
|| (printf ${red}"Idempotence test: [fail]"${neutral} && exit 1)
fi
# If removing the container is configured.
if [ "${cleanup}" = true ]; then
# Remove the container.
printf "\n${heading}Removing Docker container.${neutral}\n"
docker rm -f ${container_id}
fi
}
# Verify the system
verify_action()
{
# If a test-verify.sh file exists.
if [ -f "${PWD}/tests/test-verify.sh" ]; then
# Ensure the file is executable then execute it.
printf "\n${purple}Verifying system details.${neutral}\n\n"
chmod +x ${PWD}/tests/test-verify.sh
${PWD}/tests/test-verify.sh
fi
}
# Invoke the supplied action.
eval ${action}