diff --git a/.gitignore b/.gitignore
index 43e46a19..b3710ea2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@ build/
dist/
extra/
tests/ansible/.*.pid
+tests/image_prep/logs
docs/_build/
htmlcov/
*.egg-info
diff --git a/tests/ansible/hosts/group_vars/debian9.yml b/tests/ansible/hosts/group_vars/debian9.yml
index e08b1ed2..5be6ee80 100644
--- a/tests/ansible/hosts/group_vars/debian9.yml
+++ b/tests/ansible/hosts/group_vars/debian9.yml
@@ -1,4 +1,6 @@
package_manager_repos:
- dest: /etc/apt/sources.list
content: |
- deb http://archive.debian.org/debian stretch main contrib non-free
+ deb http://archive.debian.org/debian/ stretch main contrib non-free
+ deb http://archive.debian.org/debian/ stretch-proposed-updates main contrib non-free
+ deb http://archive.debian.org/debian-security stretch/updates main contrib non-free
diff --git a/tests/data/docker/doas-debian.tar.gz b/tests/data/docker/doas-debian.tar.gz
deleted file mode 100644
index 2deb72ff..00000000
Binary files a/tests/data/docker/doas-debian.tar.gz and /dev/null differ
diff --git a/tests/image_prep/_container_create.yml b/tests/image_prep/_container_create.yml
index b07c46eb..ab52b73b 100644
--- a/tests/image_prep/_container_create.yml
+++ b/tests/image_prep/_container_create.yml
@@ -3,18 +3,30 @@
strategy: mitogen_free
gather_facts: false
tasks:
- - name: Fetch container images
- docker_image:
- name: "{{ docker_base }}"
- delegate_to: localhost
-
- name: Start containers
docker_container:
name: "{{ inventory_hostname }}"
image: "{{ docker_base }}"
command: /bin/bash
hostname: "mitogen-{{ inventory_hostname }}"
+ etc_hosts:
+ centos-vault-proxy: host-gateway
detach: true
interactive: true
tty: true
delegate_to: localhost
+
+ - name: Wait for containers
+ # Can't use wait_for_connection yet, not all base images have a python
+ command: >-
+ docker inspect
+ --format "{% raw %}{{.State.Running}}{% endraw %}"
+ "{{ inventory_hostname }}"
+ register: container_inspect_result
+ retries: 5
+ delay: 10
+ until:
+ - container_inspect_result is succeeded
+ - container_inspect_result.stdout == "true"
+ changed_when: false
+ delegate_to: localhost
diff --git a/tests/image_prep/_container_finalize.yml b/tests/image_prep/_container_finalize.yml
index 5329fefa..7e090870 100644
--- a/tests/image_prep/_container_finalize.yml
+++ b/tests/image_prep/_container_finalize.yml
@@ -1,7 +1,7 @@
- name: Prepare images
hosts: all
strategy: mitogen_free
- gather_facts: true
+ gather_facts: false
tasks:
- name: Commit containers
command: >
@@ -10,9 +10,11 @@
--change 'CMD ["/usr/sbin/sshd", "-D"]'
{{ inventory_hostname }}
{{ container_image_name }}
+ changed_when: true
delegate_to: localhost
- name: Stop containers
command: >
docker rm -f {{ inventory_hostname }}
+ changed_when: true
delegate_to: localhost
diff --git a/tests/image_prep/_container_host.yml b/tests/image_prep/_container_host.yml
new file mode 100644
index 00000000..d3c2aca8
--- /dev/null
+++ b/tests/image_prep/_container_host.yml
@@ -0,0 +1,5 @@
+- name: Setup container host
+ hosts: localhost
+ become: true
+ roles:
+ - role: container_host
diff --git a/tests/image_prep/_container_setup.yml b/tests/image_prep/_container_setup.yml
index b95d67a9..276004f1 100644
--- a/tests/image_prep/_container_setup.yml
+++ b/tests/image_prep/_container_setup.yml
@@ -2,113 +2,44 @@
hosts: all
strategy: linear
gather_facts: false
- tasks:
- - name: Install bootstrap packages
- raw: |
- set -o errexit
- set -o nounset
- if type -p yum; then
- yum -y install {{ bootstrap_packages | join(' ') }}
- else
- apt-get -y update
- apt-get -y --no-install-recommends install {{ bootstrap_packages | join(' ') }}
- fi
- when: bootstrap_packages | length
+ roles:
+ - role: bootstrap
- name: Setup containers
hosts: all
strategy: mitogen_free
- # Resource limitation, my laptop freezes doing every container concurrently
- serial: 4
# Can't gather facts before here.
gather_facts: true
vars:
distro: "{{ansible_distribution}}"
- pre_tasks:
- - meta: end_play
- when:
- - ansible_facts.virtualization_type != "docker"
-
roles:
- role: package_manager
+ - role: packages
- role: sshd
- role: sshd_container
tasks:
- - name: Ensure requisite apt packages are installed
- apt:
- name: "{{ common_packages + packages }}"
- state: present
- install_recommends: false
- update_cache: true
- when: ansible_pkg_mgr == 'apt'
-
- - name: Ensure requisite yum packages are installed
- yum:
- name: "{{ common_packages + packages }}"
- state: present
- update_cache: true
- when: ansible_pkg_mgr == 'yum'
-
- - name: Ensure requisite dnf packages are installed
- dnf:
- name: "{{ common_packages + packages }}"
- state: present
- update_cache: true
- when: ansible_pkg_mgr == 'dnf'
-
- - name: Clean up package cache
- vars:
- clean_command:
- apt: apt-get clean
- yum: yum clean all
- dnf: dnf clean all
- command: "{{ clean_command[ansible_pkg_mgr] }}"
- args:
- warn: "{{ False if ansible_version_major_minor is version('2.10', '<=', strict=True) else omit }}"
-
- - name: Clean up apt package lists
- shell: rm -rf {{item}}/*
- with_items:
- - /var/cache/apt
- - /var/lib/apt/lists
- when: ansible_pkg_mgr == 'apt'
-
- - name: Configure /usr/bin/python
- command: alternatives --set python /usr/bin/python3.8
- args:
- creates: /usr/bin/python
- when: inventory_hostname in ["centos8"]
-
- name: Enable UTF-8 locale on Debian
copy:
dest: /etc/locale.gen
content: |
en_US.UTF-8 UTF-8
fr_FR.UTF-8 UTF-8
+ mode: u=rw,go=r
when: ansible_pkg_mgr == 'apt'
- name: Generate UTF-8 locale on Debian
- shell: locale-gen
+ command:
+ cmd: locale-gen
+ changed_when: true
when: ansible_pkg_mgr == 'apt'
- name: Write Unicode into /etc/environment
copy:
dest: /etc/environment
content: "UNICODE_SNOWMAN=\u2603\n"
-
- - name: Install prebuilt 'doas' binary
- unarchive:
- dest: /
- src: ../data/docker/doas-debian.tar.gz
-
- - name: Make prebuilt 'doas' binary executable
- file:
- path: /usr/local/bin/doas
- mode: 'u=rwxs,go=rx'
- owner: root
- group: root
+ mode: u=rw,go=r
- name: Install doas.conf
copy:
@@ -116,6 +47,7 @@
content: |
permit :mitogen__group
permit :root
+ mode: u=rw,go=
- name: Set root user password and shell
user:
@@ -127,6 +59,7 @@
file:
path: /var/run/sshd
state: directory
+ mode: u=rwx,go=rx
- name: Generate SSH host key
command: ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
@@ -142,6 +75,7 @@
dest: /etc/sentinel
content: |
i-am-mitogen-test-docker-image
+ mode: u=rw,go=r
- name: Ensure /etc/sudoers.d exists
file:
diff --git a/tests/image_prep/_user_accounts.yml b/tests/image_prep/_user_accounts.yml
index a1701e55..0f167e7a 100644
--- a/tests/image_prep/_user_accounts.yml
+++ b/tests/image_prep/_user_accounts.yml
@@ -181,6 +181,6 @@
{% endfor %}
validate: '/usr/sbin/visudo -cf %s'
when:
- - ansible_virtualization_type != "docker"
+ - ansible_connection == "local"
roles:
- role: user_policies
diff --git a/tests/image_prep/ansible.cfg b/tests/image_prep/ansible.cfg
index f698ed89..cc63c3a3 100644
--- a/tests/image_prep/ansible.cfg
+++ b/tests/image_prep/ansible.cfg
@@ -1,13 +1,17 @@
[defaults]
+any_errors_fatal = true
# Ansible >= 6 (ansible-core >= 2.13)
callback_result_format = yaml
deprecation_warnings = false
+duplicate_dict_key = error
+inventory = hosts.ini
strategy_plugins = ../../ansible_mitogen/plugins/strategy
retry_files_enabled = false
-display_args_to_stdout = True
no_target_syslog = True
host_key_checking = False
[inventory]
-unparsed_is_fatal = true
+any_unparsed_is_failed = true
+host_pattern_mismatch = error
+unparsed_is_failed = true
diff --git a/tests/image_prep/apache_proxy.conf b/tests/image_prep/apache_proxy.conf
new file mode 100644
index 00000000..79022df7
--- /dev/null
+++ b/tests/image_prep/apache_proxy.conf
@@ -0,0 +1,33 @@
+DefaultRuntimeDir ${XDG_RUNTIME_DIR}
+PidFile ${XDG_RUNTIME_DIR}/apache2.pid
+
+LoadModule alias_module /usr/lib/apache2/modules/mod_alias.so
+LoadModule authz_core_module /usr/lib/apache2/modules/mod_authz_core.so
+LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
+LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
+LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
+LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
+LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so
+
+LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
+
+KeepAlive On
+Listen 8090
+
+
+ Require all denied
+ AllowOverride None
+
+
+
+ ServerName centos-vault-proxy
+ SSLProxyEngine On
+ CustomLog logs/access.log vhost_combined
+ ProxyPass "/" "https://vault.centos.org/"
+ ProxyPassReverse "https://vault.centos.org/" "/"
+ RedirectMatch "^/(.*)" "http://centos-vault-proxy:8090/$1"
+
+
+# /usr/sbin/apache2 -d . -f apache_proxy.conf -D FOREGROUND
+
+# vim: syntax=apache
diff --git a/tests/image_prep/group_vars/all.yml b/tests/image_prep/group_vars/all.yml
index 6545e432..fc9ffddf 100644
--- a/tests/image_prep/group_vars/all.yml
+++ b/tests/image_prep/group_vars/all.yml
@@ -1,16 +1,18 @@
ansible_version_major_minor: "{{ ansible_version.major }}.{{ ansible_version.minor }}"
common_packages:
+ - acl
- openssh-server
- rsync
- strace
- sudo
container_image_name: "{{ container_registry }}/{{ inventory_hostname }}-test"
-container_registry: public.ecr.aws/n5z0e8q9
+container_registry: ghcr.io/mitogen-hq
sudo_group:
MacOSX: admin
Debian: sudo
Ubuntu: sudo
CentOS: wheel
+ AlmaLinux: wheel
diff --git a/tests/image_prep/host_vars/alma9.yml b/tests/image_prep/host_vars/alma9.yml
new file mode 100644
index 00000000..63279e0c
--- /dev/null
+++ b/tests/image_prep/host_vars/alma9.yml
@@ -0,0 +1,5 @@
+bootstrap_packages: [python3]
+docker_base: almalinux:9
+
+packages:
+ - perl-JSON
diff --git a/tests/image_prep/host_vars/centos5.yml b/tests/image_prep/host_vars/centos5.yml
index 1828c29e..19397096 100644
--- a/tests/image_prep/host_vars/centos5.yml
+++ b/tests/image_prep/host_vars/centos5.yml
@@ -1,6 +1,36 @@
bootstrap_packages: [python-simplejson]
-docker_base: astj/centos5-vault
+docker_base: centos:5
packages:
- perl
+package_manager_repos:
+ - dest: /etc/yum.repos.d/CentOS-Base.repo
+ content: |
+ [base]
+ name=CentOS-$releasever - Base
+ baseurl=http://centos-vault-proxy:8090/5.11/os/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
+
+ [updates]
+ name=CentOS-$releasever - Updates
+ baseurl=http://centos-vault-proxy:8090/5.11/updates/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
+
+ [extras]
+ name=CentOS-$releasever - Extras
+ baseurl=http://centos-vault-proxy:8090/5.11/extras/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
+
+ - dest: /etc/yum.repos.d/libselinux.repo
+ content: |
+ [libselinux]
+ name=CentOS-$releasever - libselinux
+ baseurl=http://centos-vault-proxy:8090/5.11/centosplus/$basearch/
+ gpgcheck=1
+ enabled=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
+ includepkgs=libselinux*
diff --git a/tests/image_prep/host_vars/centos6.yml b/tests/image_prep/host_vars/centos6.yml
index aae7965f..2eb20f48 100644
--- a/tests/image_prep/host_vars/centos6.yml
+++ b/tests/image_prep/host_vars/centos6.yml
@@ -1,6 +1,27 @@
bootstrap_packages: [python]
-docker_base: moreati/centos6-vault
+docker_base: centos:6
packages:
- perl-JSON
+
+package_manager_repos:
+ - dest: /etc/yum.repos.d/CentOS-Base.repo
+ content: |
+ [base]
+ name=CentOS-$releasever - Base
+ baseurl=http://vault.centos.org/6.10/os/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
+
+ [updates]
+ name=CentOS-$releasever - Updates
+ baseurl=http://vault.centos.org/6.10/updates/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
+
+ [extras]
+ name=CentOS-$releasever - Extras
+ baseurl=http://vault.centos.org/6.10/extras/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
diff --git a/tests/image_prep/host_vars/centos7.yml b/tests/image_prep/host_vars/centos7.yml
index fec83471..513e4bb9 100644
--- a/tests/image_prep/host_vars/centos7.yml
+++ b/tests/image_prep/host_vars/centos7.yml
@@ -6,3 +6,24 @@ packages:
- perl-JSON
- python-virtualenv
- python3
+
+package_manager_repos:
+ - dest: /etc/yum.repos.d/CentOS-Base.repo
+ content: |
+ [base]
+ name=CentOS-$releasever - Base
+ baseurl=http://vault.centos.org/$contentdir/$releasever/os/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
+
+ [updates]
+ name=CentOS-$releasever - Updates
+ baseurl=http://vault.centos.org/$contentdir/$releasever/updates/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
+
+ [extras]
+ name=CentOS-$releasever - Extras
+ baseurl=http://vault.centos.org/$contentdir/$releasever/extras/$basearch/
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
diff --git a/tests/image_prep/host_vars/centos8.yml b/tests/image_prep/host_vars/centos8.yml
index 17eccd01..baccafea 100644
--- a/tests/image_prep/host_vars/centos8.yml
+++ b/tests/image_prep/host_vars/centos8.yml
@@ -6,5 +6,29 @@ packages:
- perl-JSON
- python2-virtualenv
- python3-virtualenv
- - python36
- - python38
+
+package_manager_repos:
+ - dest: /etc/yum.repos.d/CentOS-Linux-AppStream.repo
+ content: |
+ [appstream]
+ name=CentOS Linux $releasever - AppStream
+ baseurl=http://vault.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
+ enabled=1
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
+ - dest: /etc/yum.repos.d/CentOS-Linux-BaseOS.repo
+ content: |
+ [baseos]
+ name=CentOS Linux $releasever - BaseOS
+ baseurl=http://vault.centos.org/$contentdir/$releasever/BaseOS/$basearch/os/
+ enabled=1
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
+ - dest: /etc/yum.repos.d/CentOS-Linux-Extras.repo
+ content: |
+ [extras]
+ name=CentOS Linux $releasever - Extras
+ baseurl=http://vault.centos.org/$contentdir/$releasever/extras/$basearch/os/
+ enabled=1
+ gpgcheck=1
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
diff --git a/tests/image_prep/host_vars/debian10.yml b/tests/image_prep/host_vars/debian10.yml
index 1b03d6a2..3e3c000f 100644
--- a/tests/image_prep/host_vars/debian10.yml
+++ b/tests/image_prep/host_vars/debian10.yml
@@ -1,4 +1,4 @@
-bootstrap_packages: [python]
+bootstrap_packages: [python, python-apt]
docker_base: debian:10
@@ -9,3 +9,11 @@ packages:
- python3
- python3-virtualenv
- virtualenv
+
+package_manager_repos:
+ - dest: /etc/apt/sources.list
+ content: |
+ deb http://archive.debian.org/debian/ buster main non-free contrib
+ deb http://archive.debian.org/debian/ buster-updates main non-free contrib
+ deb http://archive.debian.org/debian/ buster-proposed-updates main non-free contrib
+ deb http://security.debian.org/ buster/updates main non-free contrib
diff --git a/tests/image_prep/host_vars/debian11.yml b/tests/image_prep/host_vars/debian11.yml
index 5ab2d761..55d34ae4 100644
--- a/tests/image_prep/host_vars/debian11.yml
+++ b/tests/image_prep/host_vars/debian11.yml
@@ -1,11 +1,18 @@
bootstrap_packages: [python3, python3-apt]
-docker_base: debian:bullseye
+docker_base: debian:11
packages:
+ - doas
- libjson-perl
- locales
- python-is-python3
- python2
- python3-virtualenv
- virtualenv
+
+package_manager_keys:
+ - src: debian-archive-bullseye-automatic.gpg # Debian 11
+ dest: /etc/apt/trusted.gpg.d/
+ - src: debian-archive-bookworm-automatic.gpg # Debian 12
+ dest: /etc/apt/trusted.gpg.d/
diff --git a/tests/image_prep/host_vars/debian12.yml b/tests/image_prep/host_vars/debian12.yml
new file mode 100644
index 00000000..8c4afc66
--- /dev/null
+++ b/tests/image_prep/host_vars/debian12.yml
@@ -0,0 +1,8 @@
+bootstrap_packages: [python3, python3-apt]
+docker_base: debian:12
+
+packages:
+ - libjson-perl
+ - locales
+ - opendoas
+ - virtualenv
diff --git a/tests/image_prep/host_vars/debian9.yml b/tests/image_prep/host_vars/debian9.yml
index cbd22e0f..6676d7ce 100644
--- a/tests/image_prep/host_vars/debian9.yml
+++ b/tests/image_prep/host_vars/debian9.yml
@@ -1,4 +1,4 @@
-bootstrap_packages: [python]
+bootstrap_packages: [python, python-apt]
docker_base: debian:9
@@ -9,3 +9,10 @@ packages:
- python3
- python3-virtualenv
- virtualenv
+
+package_manager_repos:
+ - dest: /etc/apt/sources.list
+ content: |
+ deb http://archive.debian.org/debian/ stretch main contrib non-free
+ deb http://archive.debian.org/debian/ stretch-proposed-updates main contrib non-free
+ deb http://archive.debian.org/debian-security stretch/updates main contrib non-free
diff --git a/tests/image_prep/host_vars/ubuntu1604.yml b/tests/image_prep/host_vars/ubuntu1604.yml
index 461e522d..6afe326f 100644
--- a/tests/image_prep/host_vars/ubuntu1604.yml
+++ b/tests/image_prep/host_vars/ubuntu1604.yml
@@ -1,4 +1,4 @@
-bootstrap_packages: [python]
+bootstrap_packages: [python, python-apt]
docker_base: ubuntu:16.04
diff --git a/tests/image_prep/host_vars/ubuntu1804.yml b/tests/image_prep/host_vars/ubuntu1804.yml
index 4c913e2d..e174cbb8 100644
--- a/tests/image_prep/host_vars/ubuntu1804.yml
+++ b/tests/image_prep/host_vars/ubuntu1804.yml
@@ -1,4 +1,4 @@
-bootstrap_packages: [python]
+bootstrap_packages: [python, python-apt]
docker_base: ubuntu:18.04
diff --git a/tests/image_prep/host_vars/ubuntu2004.yml b/tests/image_prep/host_vars/ubuntu2004.yml
index 4ee5b331..f8179f1d 100644
--- a/tests/image_prep/host_vars/ubuntu2004.yml
+++ b/tests/image_prep/host_vars/ubuntu2004.yml
@@ -1,4 +1,4 @@
-bootstrap_packages: [python3]
+bootstrap_packages: [python3, python3-apt]
docker_base: ubuntu:20.04
diff --git a/tests/image_prep/host_vars/ubuntu2204.yml b/tests/image_prep/host_vars/ubuntu2204.yml
new file mode 100644
index 00000000..e8a21c65
--- /dev/null
+++ b/tests/image_prep/host_vars/ubuntu2204.yml
@@ -0,0 +1,10 @@
+bootstrap_packages: [python3, python3-apt]
+docker_base: ubuntu:22.04
+
+packages:
+ - doas
+ - libjson-perl
+ - locales
+ - python2
+ - python3-virtualenv
+ - virtualenv
diff --git a/tests/image_prep/host_vars/ubuntu2404.yml b/tests/image_prep/host_vars/ubuntu2404.yml
new file mode 100644
index 00000000..76eefc5f
--- /dev/null
+++ b/tests/image_prep/host_vars/ubuntu2404.yml
@@ -0,0 +1,9 @@
+bootstrap_packages: [python3, python3-apt]
+docker_base: ubuntu:24.04
+
+packages:
+ - libjson-perl
+ - locales
+ - opendoas
+ - python3-virtualenv
+ - virtualenv
diff --git a/tests/image_prep/hosts.ini b/tests/image_prep/hosts.ini
index 68f8be62..254643a7 100644
--- a/tests/image_prep/hosts.ini
+++ b/tests/image_prep/hosts.ini
@@ -1,4 +1,5 @@
[all:children]
+alma
centos
debian
ubuntu
@@ -6,6 +7,9 @@ ubuntu
[all:vars]
ansible_connection = docker
+[alma]
+alma9
+
[centos]
centos5
centos6
@@ -16,8 +20,36 @@ centos8
debian9
debian10
debian11
+debian12
[ubuntu]
ubuntu1604
ubuntu1804
ubuntu2004
+ubuntu2204
+ubuntu2404
+
+[ansible_2_3]
+# Python 2.4 on targets
+centos5
+
+[ansible_5]
+# Python 2.6 on targets
+centos6
+
+[ansible_9]
+# Python 2.7 and/or 3.6 on targets
+centos7
+centos8
+debian9
+debian10
+ubuntu1804
+
+[ansible_11]
+# Python >= 3.8 on targets
+alma9
+debian11
+debian12
+ubuntu2004
+ubuntu2204
+ubuntu2404
diff --git a/tests/image_prep/roles/bootstrap/defaults/main.yml b/tests/image_prep/roles/bootstrap/defaults/main.yml
new file mode 100644
index 00000000..198a6135
--- /dev/null
+++ b/tests/image_prep/roles/bootstrap/defaults/main.yml
@@ -0,0 +1,2 @@
+bootstrap_packages: []
+package_manager_repos: []
diff --git a/tests/image_prep/roles/bootstrap/tasks/main.yml b/tests/image_prep/roles/bootstrap/tasks/main.yml
new file mode 100644
index 00000000..5ecaa49d
--- /dev/null
+++ b/tests/image_prep/roles/bootstrap/tasks/main.yml
@@ -0,0 +1,3 @@
+- name: Bootstrap
+ raw: "{{ lookup('template', 'bootstrap.sh.j2') }}"
+ changed_when: true
diff --git a/tests/image_prep/roles/bootstrap/templates/bootstrap.sh.j2 b/tests/image_prep/roles/bootstrap/templates/bootstrap.sh.j2
new file mode 100644
index 00000000..0d25a95b
--- /dev/null
+++ b/tests/image_prep/roles/bootstrap/templates/bootstrap.sh.j2
@@ -0,0 +1,21 @@
+set -o errexit
+set -o nounset
+
+{% for item in package_manager_repos %}
+cat << "EOF" > "{{ item.dest }}"
+{{ item.content }}
+EOF
+{% endfor %}
+
+{% if bootstrap_packages %}
+if command -v apt-get; then
+ apt-get -y update
+ apt-get -y --no-install-recommends install {{ bootstrap_packages | join(' ') }}
+elif command -v dnf; then
+ dnf -y install {{ bootstrap_packages | join(' ') }}
+elif command -v yum; then
+ yum -y install {{ bootstrap_packages | join(' ') }}
+else
+ exit 42
+fi
+{% endif %}
diff --git a/tests/image_prep/roles/container_host/handlers/main.yml b/tests/image_prep/roles/container_host/handlers/main.yml
new file mode 100644
index 00000000..60c76cee
--- /dev/null
+++ b/tests/image_prep/roles/container_host/handlers/main.yml
@@ -0,0 +1,6 @@
+- name: Update GRUB
+ command: update-grub
+ changed_when: true
+
+- name: Reboot
+ reboot:
diff --git a/tests/image_prep/roles/container_host/tasks/main.yml b/tests/image_prep/roles/container_host/tasks/main.yml
new file mode 100644
index 00000000..c7736790
--- /dev/null
+++ b/tests/image_prep/roles/container_host/tasks/main.yml
@@ -0,0 +1,27 @@
+# > If running `docker run --rm -it centos:centos6.7 bash` immediately exits
+# > with status code 139, check to see if your system has disabled vsyscall:
+# > ...
+# > If you do not see a vsyscall mapping, and you need to run a CentOS 6
+# > container, try adding vsyscall=emulated to the kernel options.
+# > -- https://hub.docker.com/_/centos
+
+- name: Check vsyscall enabled
+ command:
+ cmd: grep -c vsyscall /proc/self/maps
+ register: grep_self_maps_result
+ changed_when: false
+ check_mode: false
+ failed_when:
+ # 0 -> match, 1 -> no match, 2 -> error
+ - grep_self_maps_result.rc not in [0, 1]
+
+- name: Enable vsyscall
+ lineinfile:
+ path: /etc/default/grub
+ regexp: '^GRUB_CMDLINE_LINUX_DEFAULT.+'
+ line: GRUB_CMDLINE_LINUX_DEFAULT="quiet vsyscall=emulate"
+ when:
+ - grep_self_maps_result.rc != 0
+ notify:
+ - Update GRUB
+ - Reboot
diff --git a/tests/image_prep/roles/packages/defaults/main.yml b/tests/image_prep/roles/packages/defaults/main.yml
new file mode 100644
index 00000000..c6ee8cc4
--- /dev/null
+++ b/tests/image_prep/roles/packages/defaults/main.yml
@@ -0,0 +1,14 @@
+common_packages: []
+packages: []
+
+packages_clean_command:
+ apt: apt-get clean
+ dnf: dnf clean all
+ yum: yum clean all
+
+packages_cleanup_directories:
+ apt:
+ - /var/cache/apt
+ - /var/lib/apt/lists
+ dnf: []
+ yum: []
diff --git a/tests/image_prep/roles/packages/tasks/main.yml b/tests/image_prep/roles/packages/tasks/main.yml
new file mode 100644
index 00000000..30076690
--- /dev/null
+++ b/tests/image_prep/roles/packages/tasks/main.yml
@@ -0,0 +1,35 @@
+- name: Ensure requisite apt packages are installed
+ apt:
+ name: "{{ common_packages + packages }}"
+ state: present
+ install_recommends: false
+ update_cache: true
+ when:
+ - ansible_pkg_mgr == 'apt'
+
+- name: Ensure requisite yum packages are installed
+ yum:
+ name: "{{ common_packages + packages }}"
+ state: present
+ update_cache: true
+ when:
+ - ansible_pkg_mgr == 'yum'
+
+- name: Ensure requisite dnf packages are installed
+ dnf:
+ name: "{{ common_packages + packages }}"
+ state: present
+ update_cache: true
+ when:
+ - ansible_pkg_mgr == 'dnf'
+
+- name: Clean up package cache
+ command:
+ cmd: "{{ packages_clean_command[ansible_pkg_mgr] }}"
+ changed_when: true
+
+- name: Clean up package directories
+ shell:
+ rm -rf {{ item }}/*
+ with_items: "{{ packages_cleanup_directories }}"
+ changed_when: true
diff --git a/tests/image_prep/roles/sshd_container/handlers/main.yml b/tests/image_prep/roles/sshd_container/handlers/main.yml
index cc7b9166..79902ed6 100644
--- a/tests/image_prep/roles/sshd_container/handlers/main.yml
+++ b/tests/image_prep/roles/sshd_container/handlers/main.yml
@@ -1,2 +1,4 @@
- name: Restart sshd
- meta: noop
+ command: "true"
+ changed_when: false
+ check_mode: false
diff --git a/tests/image_prep/setup.yml b/tests/image_prep/setup.yml
index b820e1bc..afe189a5 100755
--- a/tests/image_prep/setup.yml
+++ b/tests/image_prep/setup.yml
@@ -1,6 +1,17 @@
#!/usr/bin/env ansible-playbook
-- include_playbook: _container_create.yml
-- include_playbook: _container_setup.yml
-- include_playbook: _user_accounts.yml
-- include_playbook: _container_finalize.yml
+- name: Get base images
+ hosts: all
+ # strategy: mitogen_free
+ gather_facts: false
+ tasks:
+ - name: Fetch container base images
+ docker_image:
+ name: "{{ docker_base }}"
+ source: pull # Added in Ansible 2.8, required circa 2.12
+ delegate_to: localhost
+
+- import_playbook: _container_create.yml
+- import_playbook: _container_setup.yml
+- import_playbook: _user_accounts.yml
+- import_playbook: _container_finalize.yml
diff --git a/tests/image_prep/setup_ansible2.3.yml b/tests/image_prep/setup_ansible2.3.yml
new file mode 100644
index 00000000..cc7025c8
--- /dev/null
+++ b/tests/image_prep/setup_ansible2.3.yml
@@ -0,0 +1,15 @@
+#!/usr/bin/env ansible-playbook
+
+- name: Get base images
+ hosts: all
+ gather_facts: false
+ tasks:
+ - name: Fetch container base images
+ docker_image:
+ name: "{{ docker_base }}"
+ delegate_to: localhost
+
+- include: _container_create.yml
+- include: _container_setup.yml
+- include: _user_accounts.yml
+- include: _container_finalize.yml
diff --git a/tests/image_prep/tox.ini b/tests/image_prep/tox.ini
index d28d1512..2e32cdce 100644
--- a/tests/image_prep/tox.ini
+++ b/tests/image_prep/tox.ini
@@ -1,7 +1,9 @@
[tox]
envlist =
ansible2.3,
- ansible2.10,
+ ansible5
+ ansible9
+ ansible11
skipsdist = true
[testenv]
@@ -13,17 +15,47 @@ basepython = python2
deps =
ansible>=2.3,<2.4
docker-py>=1.7.0
- mitogen>=0.2.10rc1,<0.3
+ mitogen~=0.2.0
install_command =
python -m pip --no-python-version-warning install {opts} {packages}
commands =
- ./setup.yml -i hosts.ini -l 'localhost,centos5' {posargs}
+ ansible-playbook -l 'localhost,ansible_2_3' setup_ansible2.3.yml
-[testenv:ansible2.10]
+[testenv:ansible5]
basepython = python3
deps =
- ansible>=2.10,<2.11
+ ansible~=5.0
docker>=1.8.0
- mitogen>=0.3.0rc1,<0.4
+ mitogen~=0.3.0
+ passlib
+setenv =
+ ANSIBLE_PYTHON_INTERPRETER=auto_silent
+ ANSIBLE_STDOUT_CALLBACK=yaml
+commands =
+ ansible-playbook -l 'localhost,ansible_5' setup.yml
+
+[testenv:ansible9]
+basepython = python3
+deps =
+ ansible~=9.0
+ docker>=1.8.0
+ mitogen~=0.3.0
+ passlib
+setenv =
+ ANSIBLE_PYTHON_INTERPRETER=auto_silent
+ ANSIBLE_STDOUT_CALLBACK=yaml
+commands =
+ ansible-playbook -l 'localhost,ansible_9' setup.yml
+
+[testenv:ansible11]
+basepython = python3
+deps =
+ ansible~=11.0
+ docker>=1.8.0
+ mitogen~=0.3.0
+ passlib
+setenv =
+ ANSIBLE_PYTHON_INTERPRETER=auto_silent
+ ANSIBLE_STDOUT_CALLBACK=yaml
commands =
- ./setup.yml -i hosts.ini -l '!centos5' {posargs}
+ ansible-playbook -l 'localhost,ansible_11' setup.yml
diff --git a/tox.ini b/tox.ini
index 08b2eb98..c2a51dda 100644
--- a/tox.ini
+++ b/tox.ini
@@ -6,8 +6,8 @@
# Py A cntrllr A target coverage Django Jinja2 pip psutil pytest tox virtualenv
# ==== ========== ========== ========== ========== ========== ========== ========== ========== ========== ==========
-# 2.4 2.3? <= 3.7.1 <= 1.3.7 <= 1.1 <= 2.1.3 <= 1.4 <= 1.8
-# 2.5 <= 3.7.1 <= 1.4.22 <= 1.3.1 <= 2.1.3 <= 2.8.7 <= 1.6.1 <= 1.9.1
+# 2.4 <= 2.3³ <= 3.7.1 <= 1.3.7 <= 1.1 <= 2.1.3 <= 1.4 <= 1.8
+# 2.5 <= 2.3³ <= 3.7.1 <= 1.4.22 <= 1.3.1 <= 2.1.3 <= 2.8.7 <= 1.6.1 <= 1.9.1
# 2.6 <= 2.6.20 <= 2.12 <= 4.5.4 <= 1.6.11 <= 2.10.3 <= 9.0.3 <= 5.9.0 <= 3.2.5 <= 2.9.1 <= 15.2.0
# 2.7 <= 2.11 <= 2.16 <= 5.5 <= 1.11.29 <= 2.11.3 <= 20 <= 4.6.11 <= 3.28 <= 20.15²
# 3.5 <= 2.11 <= 2.15 <= 5.5 <= 2.2.28 <= 2.11.3 <= 20 <= 5.9.5 <= 6.1.0 <= 3.28 <= 20.15²
@@ -35,6 +35,8 @@
# Virtualenv <= 20.21.1 supports creating virtualenvs with any *target* Python.
# Virtualenv >= 20.22 supports creating virtualenvs with target Python >= 3.7.
# https://virtualenv.pypa.io/en/latest/#compatibility
+#
+# 3. https://docs.ansible.com/ansible/2.7/dev_guide/developing_python_3.html#minimum-version-of-python-3-x-and-python-2-x
# Ansible Dependency
# ================== ======================