Version: 0.7.0-rc.109
An Ansible collection for my opinionated development workstation configuration and prototyping Ansible (and non-Ansible) features for other Python packages and Ansible collections.
This collection houses roles, playbooks, and other Ansible content suitable for setting up standardized tooling and settings on development workstations. It also facilitates automated configuration of other systems, like Raspberry Pi servers and cloud instances for training labs or "capture the flag" contests.
The original design was influenced by the blog posts listed below in the See also section by Jonas Hecht and Jeff Geerling.
Development of this collection is supported by a test-driven design that uses
molecule to test any or all
roles, both locally and driven by GitHub Actions workflows on push actions.
The operating system distributions supported at this time by the full set of
roles in this collection for molecule testing are:
- Debian 11 (default distribution)
- Ubuntu 22.04 LTS
The development environment and test infrastructure that invokes molecule
for testing has been tested on the following (in order of most-frequently
to least-frequently used):
- Mac OS X (Darwin) 10.15.7
- Ubuntu 20.04 LTS on Windows Subsystem for Linux v2 (WSL2)
- Kali Linux (Debian 11 experimental, 2022-07-07 release)
- HypriotOS v1.12.3 (Debian 10, w/o
kali_likerole))
To help reduce the amount of time taken by all this testing, some optimization techniques are employed:
-
Local testing during development is done against only Debian 11. Once all tests are passing, the remaining OS distributions can then be selected for further compatibility testing.
-
Testing of all roles except
kali_like(which requires Debian 11) are done using Raspberry Pi 3 and 4 systems using Hypriot's custom Debian 10 images flashed with a modified version of Hypriot'sflashprogram (found in thehypriotdirectory. -
GitHub Action testing for release candidates on the
developbranch and releases on themainbranch are the only ones that test all roles against multiple distributions. When youpushto a feature branch with a name related to the role you are developing (e.g.,feature/brandingfor thedavedittrich.utils.brandingrole), only that role is tested against the distribution matrix. This reduces test time by only testing role-specific changes.
All of this comes at a cost, however. There is a lot of
non-DRY repetition of logic,
code, and molecule configuration settings. Some of the non-DRY aspects of GitHub
Actions workflows could be reduced by refactoring so as to
share workflows.
Some repetition in molecule configuration and tests has been reduced by
modularity and cross-inclusion of testing code.
https://github.com/davedittrich/utils
Before using this collection, you need to install it with the Ansible Galaxy command-line tool:
ansible-galaxy collection install davedittrich.utilsYou can also include it in a requirements.yml file and install it with
ansible-galaxy collection install -r requirements.yml, using the format:
---
collections:
- name: davedittrich.utilsNote that if you install the collection from Ansible Galaxy, it will not be upgraded automatically
when you upgrade the ansible package. To upgrade the collection to the latest available version,
run the following command:
ansible-galaxy collection install davedittrich.utils --upgradeYou can also install a specific version of the collection, for example if you need to downgrade
when something is broken in the latest version (please report an issue in this repository). Use
the following syntax to install version 0.1.0:
ansible-galaxy collection install davedittrich.utils:==0.1.0See Using Ansible collections for more details.
Following is a high-level breakdown of tasks performed by role. This is not an exhaustive list of all tasks, but rather a summary of the general topics:
- Install base OS packages necessary for Kali tooling.
- Set up for installing packages from Kali repo.
- Install a specific subset of Kali packages.
- Hush the Kali developer login message.
- Install templated helper scripts for user convenience.
- Set up
~/.local/bindirectories in accounts for local add-on programs. - Pre-configure Kali menus and desktop.
- Set host name based on system serial number.
- Install and configure system for Apache Guacamole (RDP in browser).
- Set custom timezone.
- Make LXDE/
lightdmdefault X11 session manager. - Customize LXDE and
lightdmsettings and menus. - Customize display wallpaper, login greeter background, and boot splash images.
- Disable boot logo (e.g., on Raspberry Pi devices.)
- Disable
clipithistory.
- Ensure SSH host key fingerprints are visible on console login screen.
- Ensure Ethernet device and IP addressing information is visible on console login screen.
davedittrich.utils.kdmt role.
- Swaps Left keyboard CapsLock key with CTRL.
- Disables bell sound for keyboard,
bash,csh,exfamily editors,vimeditor and instead sets visible bell. - Enables "natural scrolling" on mouse and trackpad.
- Configures
hid_applekeyboard devices to use function keys without needingFnkey.
- Ensures
update-dotdeeis installed viapipx. - Create initial dropin directories with original files appearing at top.
- By default, enabled use of
update-dotdeeto control users'~/.bash_aliases,~/.bashrc,~/.gitconfig, and~/.ssh/configfiles.
To reduce redundancy in code across multiple scenarios representing individual
roles in a larger collection, tests, variables, and functions are located in
the molecule/shared directory.
$ tree molecule/shared
molecule/shared
├── cleanup.yml
├── Dockerfile-debian_bullseye.j2
├── files
│  ├── cmdline.txt
│  ├── config.txt
│  └── Hello_World.jpg
├── __init__.py
├── prepare.yml
├── pytest.ini
├── tasks
│  └── fix_systemctl.yml
└── tests
├── conftest.py
├── helpers
│  └── __init__.py
├── __init__.py
├── test_branding.py
├── test_dropins.py
├── test_ip_in_issue.py
├── test_kali_like.py
├── test_kdmt.py
└── test_shared.py
4 directories, 18 files
The directory molecule/shared/tests/helpers/ contains shared variables and
functions used by the tests (as opposed to using conftest.py) as seen here:
from helpers import (
ansible_vars,
get_homedir,
skip_unless_role,
)The verifier section in files like molecule/default/molecule.yml are
configured as follows to allow the import to work:
verifier:
name: testinfra
directory: ../shared/tests
env:
PYTHONPATH: "${PWD}/molecule/shared/tests"
#PYTEST_ADDOPTS: "--debug -v -ra --trace-config"
PYTEST_ADDOPTS: "-v -ra"When debugging exceptions during the verify stage, you may want to swap the
PYTEST_ADDOPTS settings.
To further reduce redundancy and hard-coding values in tests, all Ansible
variables that were defined during the converge phase are dumped to a YAML
file in the molecule scenario's ephemeral directory so they are available to
tests in the verify stage. The path to the file for the default scenario
would be ${HOME}/.config/molecule/utils/default/ansible-vars.yml.
It is possible to conditionally call pytest.xfail() based on these variables.
Tests can also be skipped by use of the @skip_unless_role() decorator, which
checks to see if the role for which they apply is in the ansible_roles_names
variable (meaning that role was applied and thus needs testing).
. . .
ansible_role_names: [davedittrich.utils.ip_in_issue]
. . .Here is an example with a simple test.
@skip_unless_role('davedittrich.utils.branding')
def test_boot_config(host):
f = host.file('/boot/config.txt')
assert f.exists
assert f.user == 'root'
assert f.group == 'root'
assert r'disable_splash=1' in f.content_stringIf the ip_in_issue scenario was being tested, which only includes the
davedittrich.utils.ip_in_issue role (as seen in the ansible_role_names
variable above), this particular test would be skipped.
$ make SCENARIO=ip_in_issue test
[+] using 'conda' environment 'utils' and 'psec' environment 'utils'
molecule test --destroy=never -s ip_in_issue
INFO ip_in_issue scenario test matrix: dependency, lint, create, prepare, converge, idempotence, verify
INFO Performing prerun with role_name_check=0...
INFO Set ANSIBLE_LIBRARY=/home/dittrich/.cache/ansible-compat/6fd897/modules:/home/dittrich/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO Set ANSIBLE_COLLECTIONS_PATH=/home/dittrich/.cache/ansible-compat/6fd897/collections:/home/dittrich/.ansible/collections:/usr/share/ansible/collections
INFO Set ANSIBLE_ROLES_PATH=/home/dittrich/.cache/ansible-compat/6fd897/roles:roles:/home/dittrich/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO Running ansible-galaxy collection install -v --force -p /home/dittrich/.cache/ansible-compat/6fd897/collections .
INFO Running ip_in_issue > dependency
. . .
INFO Idempotence completed successfully.
INFO Running ip_in_issue > verify
INFO Executing Testinfra tests found in /home/dittrich/code/davedittrich/utils/molecule/ip_in_issue/../shared/tests/...
/home/dittrich/miniconda3/envs/utils/lib/python3.9/site-packages/molecule/config.py:51: DeprecationWarning: molecule.config.ansible_version is deprecated, will be removed in the future.
warnings.warn(
============================= test session starts ==============================
platform linux -- Python 3.9.13, pytest-7.1.3, pluggy-1.0.0 -- /home/dittrich/miniconda3/envs/utils/bin/python
metadata: {'Python': '3.9.13', 'Platform': 'Linux-5.18.0-kali7-amd64-x86_64-with-glibc2.34', 'Packages': {'pytest': '7.1.3', 'py': '1.11.0', 'pluggy': '1.0.0', 'molecule': '4.0.2.dev19'}, 'Plugins': {'ansible': '2.3.0', 'metadata':
'2.0.2', 'testinfra': '6.8.1.dev4+gd423e29', 'html': '3.1.1', 'molecule': '2.0.1.dev8+g236ac70'}, 'Tools': {'ansible': '2.13.3'}, 'env': 'ANSIBLE_COLLECTIONS_PATH=/home/dittrich/.cache/ansible-compat/6fd897/collections:/home/dittr
ich/.cache/molecule/utils/ip_in_issue/collections:/home/dittrich/.ansible/collections:/usr/share/ansible/collections:/etc/ansible/collections ANSIBLE_CONFIG=/home/dittrich/.cache/molecule/utils/ip_in_issue/ansible.cfg ANSIBLE_FILTE
R_PLUGINS=/home/dittrich/miniconda3/envs/utils/lib/python3.9/site-packages/molecule/provisioner/ansible/plugins/filter:/home/dittrich/.cache/molecule/utils/ip_in_issue/plugins/filter:/home/dittrich/code/davedittrich/utils/plugins/f
ilter:/home/dittrich/.ansible/plugins/filter:/usr/share/ansible/plugins/filter ANSIBLE_FORCE_COLOR=True ANSIBLE_LIBRARY=/home/dittrich/miniconda3/envs/utils/lib/python3.9/site-packages/molecule/provisioner/ansible/plugins/modules:/
home/dittrich/.cache/molecule/utils/ip_in_issue/library:/home/dittrich/code/davedittrich/utils/library:/home/dittrich/.ansible/plugins/modules:/usr/share/ansible/plugins/modules ANSIBLE_ROLES_PATH=/home/dittrich/.cache/ansible-comp
at/6fd897/roles:/home/dittrich/.cache/molecule/utils/ip_in_issue/roles:/home/dittrich/code/davedittrich:/home/dittrich/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles ANSIBLE_VERBOSITY=1 MOLECULE_DEBUG=False MOLECULE_DEP
ENDENCY_NAME=galaxy MOLECULE_DISTRO=debian11 MOLECULE_DRIVER_NAME=docker MOLECULE_ENV_FILE=/home/dittrich/code/davedittrich/utils/.env.yml MOLECULE_EPHEMERAL_DIRECTORY=/home/dittrich/.cache/molecule/utils/ip_in_issue MOLECULE_FILE=
/home/dittrich/.cache/molecule/utils/ip_in_issue/molecule.yml MOLECULE_INSTANCE_CONFIG=/home/dittrich/.cache/molecule/utils/ip_in_issue/instance_config.yml MOLECULE_INVENTORY_FILE=/home/dittrich/.cache/molecule/utils/ip_in_issue/in
ventory/ansible_inventory.yml MOLECULE_PROJECT_DIRECTORY=/home/dittrich/code/davedittrich/utils MOLECULE_PROVISIONER_NAME=ansible MOLECULE_SCENARIO_DIRECTORY=/home/dittrich/code/davedittrich/utils/molecule/ip_in_issue MOLECULE_SCEN
ARIO_NAME=ip_in_issue MOLECULE_STATE_FILE=/home/dittrich/.cache/molecule/utils/ip_in_issue/state.yml MOLECULE_VERIFIER_NAME=testinfra MOLECULE_VERIFIER_TEST_DIRECTORY=/home/dittrich/code/davedittrich/utils/molecule/ip_in_issue/../s
hared/tests '}
ansible: 2.13.3
rootdir: /home/dittrich/code/davedittrich/utils/molecule/shared, configfile: pytest.ini
plugins: ansible-2.3.0, metadata-2.0.2, testinfra-6.8.1.dev4+gd423e29, html-3.1.1, molecule-2.0.1.dev8+g236ac70
collecting ... collected 43 items
molecule/shared/tests/test_branding.py::test_boot_config[ansible:/debian_bullseye] SKIPPED [ 2%]
molecule/shared/tests/test_branding.py::test_boot_cmdline[ansible:/debian_bullseye] SKIPPED [ 4%]
molecule/shared/tests/test_branding.py::test_fbi_package[ansible:/debian_bullseye] SKIPPED [ 6%]
molecule/shared/tests/test_branding.py::test_splashscreen_service[ansible:/debian_bullseye] SKIPPED [ 9%]
molecule/shared/tests/test_branding.py::test_wallpaper_image[ansible:/debian_bullseye] SKIPPED [ 11%]
molecule/shared/tests/test_branding.py::test_x11_session_manager_is_lxde[ansible:/debian_bullseye] SKIPPED [ 13%]
molecule/shared/tests/test_branding.py::test_lightdm_login_background[ansible:/debian_bullseye] SKIPPED [ 16%]
molecule/shared/tests/test_branding.py::test_user_homedir[ansible:/debian_bullseye-user0] SKIPPED [ 18%]
molecule/shared/tests/test_branding.py::test_user_wallpaper_setting[ansible:/debian_bullseye-user0] SKIPPED [ 20%]
molecule/shared/tests/test_branding.py::test_user_LXDE_autostart_xset[ansible:/debian_bullseye-user0] SKIPPED [ 23%]
molecule/shared/tests/test_branding.py::test_config_files[fixture_users0-fixture_config_files0-ansible:/debian_bullseye] SKIPPED [ 25%]
molecule/shared/tests/test_dropins.py::test_etc_profile_d_dotlocal[ansible:/debian_bullseye] SKIPPED [ 27%]
molecule/shared/tests/test_dropins.py::test_bashrc_sources_aliases[fixture_users0-ansible:/debian_bullseye] SKIPPED [ 30%]
molecule/shared/tests/test_dropins.py::test_dropin_files[fixture_users0-fixture_dropin_files0-ansible:/debian_bullseye] SKIPPED [ 32%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[fixture_users0-fixture_dropin_files0-ansible:/debian_bullseye] SKIPPED [ 34%]
molecule/shared/tests/test_dropins.py::test_pipx[fixture_users0-pipx-ansible:/debian_bullseye] SKIPPED [ 37%]
molecule/shared/tests/test_dropins.py::test_pipx[fixture_users0-update-dotdee-ansible:/debian_bullseye] SKIPPED [ 39%]
molecule/shared/tests/test_dropins.py::test_update_dotdee_write_bash_profile[fixture_users0-ansible:/debian_bullseye] SKIPPED [ 41%]
molecule/shared/tests/test_ip_in_issue.py::test_issue_file[ansible:/debian_bullseye] PASSED [ 44%]
molecule/shared/tests/test_ip_in_issue.py::test_issue_d[ansible:/debian_bullseye] PASSED [ 46%]
molecule/shared/tests/test_ip_in_issue.py::test_issue_d_interfaces[ansible:/debian_bullseye] PASSED [ 48%]
molecule/shared/tests/test_ip_in_issue.py::test_issue_d_fingerprints[ansible:/debian_bullseye] PASSED [ 51%]
molecule/shared/tests/test_kali_like.py::test_kali_apt_list[ansible:/debian_bullseye] SKIPPED [ 53%]
molecule/shared/tests/test_kali_like.py::test_script_files[fixture_users0-fixture_helper_script_files0-ansible:/debian_bullseye] SKIPPED [ 55%]
molecule/shared/tests/test_kali_like.py::test_kali_like_packages[fixture_kali_like_packages0-ansible:/debian_bullseye] SKIPPED [ 58%]
molecule/shared/tests/test_kali_like.py::test_gawk[ansible:/debian_bullseye] SKIPPED [ 60%]
molecule/shared/tests/test_kali_like.py::test_kali_application_menu[ansible:/debian_bullseye] SKIPPED [ 62%]
molecule/shared/tests/test_kali_like.py::test_guacamole_guacd[ansible:/debian_bullseye] SKIPPED [ 65%]
molecule/shared/tests/test_kali_like.py::test_guacamole_services[fixture_guac_services0-ansible:/debian_bullseye] SKIPPED [ 67%]
molecule/shared/tests/test_kdmt.py::test_keyboard_config_packages[ansible:/debian_bullseye] SKIPPED [ 69%]
molecule/shared/tests/test_kdmt.py::test_custom_load_xmodmap[ansible:/debian_bullseye] SKIPPED [ 72%]
molecule/shared/tests/test_kdmt.py::test_udev_hwdb_file[ansible:/debian_bullseye] SKIPPED [ 74%]
molecule/shared/tests/test_kdmt.py::test_xkboptions[ansible:/debian_bullseye] SKIPPED [ 76%]
molecule/shared/tests/test_kdmt.py::test_keyboard_configuration[ansible:/debian_bullseye] SKIPPED [ 79%]
molecule/shared/tests/test_kdmt.py::test_hid_apple_conf[ansible:/debian_bullseye] SKIPPED [ 81%]
molecule/shared/tests/test_kdmt.py::test_hid_apple_fnmode[ansible:/debian_bullseye] SKIPPED [ 83%]
molecule/shared/tests/test_kdmt.py::test_hid_apple_iso_layout[ansible:/debian_bullseye] SKIPPED [ 86%]
molecule/shared/tests/test_kdmt.py::test_user_inputrc[ansible:/debian_bullseye-user0] SKIPPED [ 88%]
molecule/shared/tests/test_kdmt.py::test_user_cshrc[ansible:/debian_bullseye-user0] SKIPPED [ 90%]
molecule/shared/tests/test_kdmt.py::test_user_exrc[ansible:/debian_bullseye-user0] SKIPPED [ 93%]
molecule/shared/tests/test_kdmt.py::test_user_vimrc[ansible:/debian_bullseye-user0] SKIPPED [ 95%]
molecule/shared/tests/test_kdmt.py::test_user_xmodmap[ansible:/debian_bullseye-user0] SKIPPED [ 97%]
molecule/shared/tests/test_shared.py::test_shared_skip SKIPPED (forc...) [100%]
=========================== short test summary info ============================
SKIPPED [1] molecule/shared/tests/test_branding.py:16: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:24: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:32: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:37: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:43: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:52: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:60: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:74: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:83: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:106: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_branding.py:148: role davedittrich.utils.branding only
SKIPPED [1] molecule/shared/tests/test_dropins.py:33: role davedittrich.utils.dropins only
SKIPPED [1] molecule/shared/tests/test_dropins.py:41: role davedittrich.utils.dropins only
SKIPPED [1] molecule/shared/tests/test_dropins.py:52: role davedittrich.utils.dropins only
SKIPPED [1] molecule/shared/tests/test_dropins.py:63: role davedittrich.utils.dropins only
SKIPPED [2] molecule/shared/tests/test_dropins.py:75: role davedittrich.utils.dropins only
SKIPPED [1] molecule/shared/tests/test_dropins.py:87: role davedittrich.utils.dropins only
SKIPPED [1] molecule/shared/tests/test_kali_like.py:52: role davedittrich.utils.kali_like only
SKIPPED [1] molecule/shared/tests/test_kali_like.py:61: role davedittrich.utils.kali_like only
SKIPPED [1] molecule/shared/tests/test_kali_like.py:72: role davedittrich.utils.kali_like only
SKIPPED [1] molecule/shared/tests/test_kali_like.py:78: role davedittrich.utils.kali_like only
SKIPPED [1] molecule/shared/tests/test_kali_like.py:85: role davedittrich.utils.kali_like only
SKIPPED [1] molecule/shared/tests/test_kali_like.py:94: role davedittrich.utils.kali_like only
SKIPPED [1] molecule/shared/tests/test_kali_like.py:103: role davedittrich.utils.kali_like only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:16: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:22: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:30: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:39: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:47: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:54: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:64: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:76: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:91: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:118: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:132: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:146: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_kdmt.py:160: role davedittrich.utils.kdmt only
SKIPPED [1] molecule/shared/tests/test_shared.py:6: force skip
======================== 4 passed, 39 skipped in 1.70s =========================
INFO Verifier completed successfully.
[+] all tests succeeded
[+] instance(s) were not destroyed: use 'molecule destroy' or 'molecule reset' manually
. . .
Using the pytest option -rP instead, the output from the verify stage is much
shorter:
$ PYTEST_ADDOPTS="-rP" molecule verify -s ip_in_issue
INFO ip_in_issue scenario test matrix: verify
INFO Performing prerun with role_name_check=0...
INFO Set ANSIBLE_LIBRARY=/home/dittrich/.cache/ansible-compat/6fd897/modules:/home/dittrich/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO Set ANSIBLE_COLLECTIONS_PATH=/home/dittrich/.cache/ansible-compat/6fd897/collections:/home/dittrich/.ansible/collections:/usr/share/ansible/collections
INFO Set ANSIBLE_ROLES_PATH=/home/dittrich/.cache/ansible-compat/6fd897/roles:roles:/home/dittrich/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO Running ansible-galaxy collection install -v --force -p /home/dittrich/.cache/ansible-compat/6fd897/collections .
INFO Running ip_in_issue > verify
INFO Executing Testinfra tests found in /home/dittrich/code/davedittrich/utils/molecule/ip_in_issue/../shared/tests/...
/home/dittrich/miniconda3/envs/utils/lib/python3.9/site-packages/molecule/config.py:51: DeprecationWarning: molecule.config.ansible_version is deprecated, will be removed in the future.
warnings.warn(
============================= test session starts ==============================
platform linux -- Python 3.9.13, pytest-7.1.3, pluggy-1.0.0
ansible: 2.13.3
rootdir: /home/dittrich/code/davedittrich/utils/molecule/shared, configfile: pytest.ini
plugins: ansible-2.3.0, metadata-2.0.2, testinfra-6.8.1.dev4+gd423e29, html-3.1.1, molecule-2.0.1.dev8+g236ac70
collected 43 items
molecule/shared/tests/test_branding.py sssssssssss [ 25%]
molecule/shared/tests/test_dropins.py sssssss [ 41%]
molecule/shared/tests/test_ip_in_issue.py .... [ 51%]
molecule/shared/tests/test_kali_like.py sssssss [ 67%]
molecule/shared/tests/test_kdmt.py sssssssssssss [ 97%]
molecule/shared/tests/test_shared.py s [100%]
==================================== PASSES ====================================
======================== 4 passed, 39 skipped in 1.76s =========================
INFO Verifier completed successfully.
The file containing the Ansible variables from the converge phase also help
in debugging playbooks. They provide "ground truth" of the Ansible runtime state
and help you identify variables to use in playbooks and tests, or to watch
while running tests in a debugger. (There is a pytest launch rule for
VSCode defined in the .vscode/launch.json file.)
To continue on to testing in molecule, you can manually run molecule verify. The variables are loaded from the cached file and are available to
tests. This allows you to redefine some variables during development, re-run
molecule converge to have them take effect, and your tests can then
automatically adjust.
Only when molecule destroy is run will the file be deleted.
$ molecule destroy -s ip_in_issue
INFO ip_in_issue scenario test matrix: dependency, destroy
INFO Performing prerun with role_name_check=0...
INFO Set ANSIBLE_LIBRARY=/home/dittrich/.cache/ansible-compat/6fd897/modules:/home/dittrich/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO Set ANSIBLE_COLLECTIONS_PATH=/home/dittrich/.cache/ansible-compat/6fd897/collections:/home/dittrich/.ansible/collections:/usr/share/ansible/collections
INFO Set ANSIBLE_ROLES_PATH=/home/dittrich/.cache/ansible-compat/6fd897/roles:roles:/home/dittrich/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO Running ansible-galaxy collection install -v --force -p /home/dittrich/.cache/ansible-compat/6fd897/collections .
INFO Running ip_in_issue > dependency
WARNING Skipping, missing the requirements file.
WARNING Skipping, missing the requirements file.
INFO Running ip_in_issue > destroy
INFO Sanity checks: 'docker'
Using /home/dittrich/.cache/molecule/utils/ip_in_issue/ansible.cfg as config file
PLAY [Destroy] *****************************************************************
TASK [Destroy molecule instance(s)] ********************************************
changed: [localhost] => (item=debian_bullseye) => {"ansible_job_id": "151811718162.2756561", "ansible_loop_var": "item", "changed": true, "finished": 0, "item": {"capabilities": ["SYS_ADMIN"], "dockerfile": "../shared/Dockerfile-debian_bullseye.j2", "image": "debian:bullseye", "name": "debian_bullseye", "override_command": false, "privileged": true, "security_opts": ["seccomp=unconfined"], "tmpfs": ["/run", "/run/lock", "/tmp"]}, "results_file": "/home/dittrich/.ansible_async/151811718162.2756561", "started": 1}
TASK [Wait for instance(s) deletion to complete] *******************************
FAILED - RETRYING: [localhost]: Wait for instance(s) deletion to complete (300 retries left).
changed: [localhost] => (item=debian_bullseye) => {"ansible_job_id": "151811718162.2756561", "ansible_loop_var": "item", "attempts": 2, "changed": true, "finished": 1, "item": {"ansible_job_id": "151811718162.2756561", "ansible_loop_var": "item", "changed": true, "failed": 0, "finished": 0, "item": {"capabilities": ["SYS_ADMIN"], "dockerfile": "../shared/Dockerfile-debian_bullseye.j2", "image": "debian:bullseye", "name": "debian_bullseye", "override_command": false, "privileged": true, "security_opts": ["seccomp=unconfined"], "tmpfs": ["/run", "/run/lock", "/tmp"]}, "results_file": "/home/dittrich/.ansible_async/151811718162.2756561", "started": 1}, "results_file": "/home/dittrich/.ansible_async/151811718162.2756561", "started": 1, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
TASK [Delete docker networks(s)] ***********************************************
PLAY RECAP *********************************************************************
localhost : ok=2 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
INFO Pruning extra files from scenario ephemeral directory
You can see the defined scenarios and state information about related instances
with molecule list:
$ molecule list
INFO Running branding > list
INFO Running default > list
INFO Running delegated > list
INFO Running dropins > list
INFO Running ip_in_issue > list
INFO Running kali_like > list
INFO Running kdmt > list
â•· â•· â•· â•· â•·
Instance Name │ Driver Name │ Provisioner Name │ Scenario Name │ Created │ Converged
╶─────────────────┼─────────────┼──────────────────┼───────────────┼─────────┼───────────╴
debian_bullseye │ docker │ ansible │ branding │ false │ false
debian_bullseye │ docker │ ansible │ default │ true │ false
delegated-host │ delegated │ ansible │ delegated │ unknown │ false
debian_bullseye │ docker │ ansible │ dropins │ false │ false
debian_bullseye │ docker │ ansible │ ip_in_issue │ false │ false
debian_bullseye │ docker │ ansible │ kali_like │ false │ false
debian_bullseye │ docker │ ansible │ kdmt │ false │ false
╵ ╵ ╵ ╵ ╵
When using the delegated scenario--in this case against a Raspberry Pi with users
root and pirate--all of the roles and their associated tests for all users
will be applied:
$ make SCENARIO=delegated verify
molecule verify -s delegated
INFO delegated scenario test matrix: verify
INFO Performing prerun...
INFO Guessed /Users/dittrich/git/davedittrich/utils as project root directory
INFO Added ANSIBLE_LIBRARY=plugins/modules
INFO Added ANSIBLE_COLLECTIONS_PATH=/Users/dittrich/.cache/ansible-lint/6dd05e/collections
INFO Added ANSIBLE_ROLES_PATH=~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:roles
INFO Running delegated > verify
INFO Executing Testinfra tests found in /Users/dittrich/git/davedittrich/utils/molecule/delegated/../shared/tests/...
============================= test session starts ==============================
platform darwin -- Python 3.9.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- /usr/local/Caskroom/miniconda/base/envs/ansible/bin/python
metadata: {'Python': '3.9.5', 'Platform': 'macOS-10.14.6-x86_64-i386-64bit', 'Packages': {'pytest': '6.2.4', 'py': '1.10.0', 'pluggy':
'0.13.1'}, 'Plugins': {'cov': '2.12.1', 'metadata': '1.11.0', 'helpers-namespace': '0.0.0', 'xdist': '2.3.0', 'html': '3.1.1', 'mock':
'3.6.1', 'plus': '0.2', 'verbose-parametrize': '1.7.0', 'forked': '1.3.0', 'testinfra': '6.4.0'}}
rootdir: /Users/dittrich
plugins: cov-2.12.1, metadata-1.11.0, helpers-namespace-0.0.0, xdist-2.3.0, html-3.1.1, mock-3.6.1, plus-0.2, verbose-parametrize-1.7.0,
forked-1.3.0, testinfra-6.4.0
collecting ... collected 106 items
molecule/shared/tests/test_branding.py::test_boot_config[ansible:/delegated-host] PASSED [ 0%]
molecule/shared/tests/test_branding.py::test_boot_cmdline[ansible:/delegated-host] PASSED [ 1%]
molecule/shared/tests/test_branding.py::test_fbi_package[ansible:/delegated-host] PASSED [ 2%]
molecule/shared/tests/test_branding.py::test_splashscreen_service[ansible:/delegated-host] PASSED [ 3%]
molecule/shared/tests/test_branding.py::test_user_homedir[ansible:/delegated-host-root] PASSED [ 4%]
molecule/shared/tests/test_branding.py::test_user_homedir[ansible:/delegated-host-pirate] PASSED [ 5%]
molecule/shared/tests/test_branding.py::test_x11_session_manager_is_lxde[ansible:/delegated-host] PASSED [ 6%]
molecule/shared/tests/test_branding.py::test_wallpaper_image[ansible:/delegated-host] PASSED [ 7%]
molecule/shared/tests/test_branding.py::test_user_wallpaper_setting[ansible:/delegated-host-root] XFAIL [ 8%]
molecule/shared/tests/test_branding.py::test_user_wallpaper_setting[ansible:/delegated-host-pirate] XFAIL [ 9%]
molecule/shared/tests/test_branding.py::test_lightdm_login_background[ansible:/delegated-host] PASSED [ 10%]
molecule/shared/tests/test_branding.py::test_config_files[root-user-dirs.dirs.j20-ansible:/delegated-host] PASSED [ 11%]
molecule/shared/tests/test_branding.py::test_config_files[root-user-dirs.locale.j20-ansible:/delegated-host] PASSED [ 12%]
molecule/shared/tests/test_branding.py::test_config_files[root-gtk-3.0/bookmarks.j20-ansible:/delegated-host] PASSED [ 13%]
molecule/shared/tests/test_branding.py::test_config_files[root-qt5ct/qt5ct.conf.j20-ansible:/delegated-host] PASSED [ 14%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxterminal/lxterminal.conf.j20-ansible:/delegated-host] PASSED [ 15%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxsession/LXDE/desktop.conf.j20-ansible:/delegated-host] PASSED [ 16%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxsession/LXDE/autostart.j20-ansible:/delegated-host] PASSED [ 16%]
molecule/shared/tests/test_branding.py::test_config_files[root-pcmanfm/LXDE/desktop-items-0.conf.j20-ansible:/delegated-host] PASSED [ 17%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxpanel/launchtaskbar.cfg.j20-ansible:/delegated-host] PASSED [ 18%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxpanel/LXDE/panels/panel.j20-ansible:/delegated-host] PASSED [ 19%]
molecule/shared/tests/test_branding.py::test_config_files[root-openbox/lxde-rc.xml.j20-ansible:/delegated-host] PASSED [ 20%]
molecule/shared/tests/test_branding.py::test_config_files[root-clipit/disabled.j20-ansible:/delegated-host] PASSED [ 21%]
molecule/shared/tests/test_branding.py::test_config_files[root-libfm/libfm.conf.j20-ansible:/delegated-host] PASSED [ 22%]
molecule/shared/tests/test_branding.py::test_config_files[root-user-dirs.dirs.j21-ansible:/delegated-host] PASSED [ 23%]
molecule/shared/tests/test_branding.py::test_config_files[root-user-dirs.locale.j21-ansible:/delegated-host] PASSED [ 24%]
molecule/shared/tests/test_branding.py::test_config_files[root-gtk-3.0/bookmarks.j21-ansible:/delegated-host] PASSED [ 25%]
molecule/shared/tests/test_branding.py::test_config_files[root-qt5ct/qt5ct.conf.j21-ansible:/delegated-host] PASSED [ 26%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxterminal/lxterminal.conf.j21-ansible:/delegated-host] PASSED [ 27%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxsession/LXDE/desktop.conf.j21-ansible:/delegated-host] PASSED [ 28%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxsession/LXDE/autostart.j21-ansible:/delegated-host] PASSED [ 29%]
molecule/shared/tests/test_branding.py::test_config_files[root-pcmanfm/LXDE/desktop-items-0.conf.j21-ansible:/delegated-host] PASSED [ 30%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxpanel/launchtaskbar.cfg.j21-ansible:/delegated-host] PASSED [ 31%]
molecule/shared/tests/test_branding.py::test_config_files[root-lxpanel/LXDE/panels/panel.j21-ansible:/delegated-host] PASSED [ 32%]
molecule/shared/tests/test_branding.py::test_config_files[root-openbox/lxde-rc.xml.j21-ansible:/delegated-host] PASSED [ 33%]
molecule/shared/tests/test_branding.py::test_config_files[root-clipit/disabled.j21-ansible:/delegated-host] PASSED [ 33%]
molecule/shared/tests/test_branding.py::test_config_files[root-libfm/libfm.conf.j21-ansible:/delegated-host] PASSED [ 34%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-user-dirs.dirs.j20-ansible:/delegated-host] PASSED [ 35%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-user-dirs.locale.j20-ansible:/delegated-host] PASSED [ 36%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-gtk-3.0/bookmarks.j20-ansible:/delegated-host] PASSED [ 37%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-qt5ct/qt5ct.conf.j20-ansible:/delegated-host] PASSED [ 38%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxterminal/lxterminal.conf.j20-ansible:/delegated-host] PASSED [ 39%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxsession/LXDE/desktop.conf.j20-ansible:/delegated-host] PASSED [ 40%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxsession/LXDE/autostart.j20-ansible:/delegated-host] PASSED [ 41%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-pcmanfm/LXDE/desktop-items-0.conf.j20-ansible:/delegated-host] PASSED [ 42%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxpanel/launchtaskbar.cfg.j20-ansible:/delegated-host] PASSED [ 43%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxpanel/LXDE/panels/panel.j20-ansible:/delegated-host] PASSED [ 44%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-openbox/lxde-rc.xml.j20-ansible:/delegated-host] PASSED [ 45%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-clipit/disabled.j20-ansible:/delegated-host] PASSED [ 46%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-libfm/libfm.conf.j20-ansible:/delegated-host] PASSED [ 47%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-user-dirs.dirs.j21-ansible:/delegated-host] PASSED [ 48%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-user-dirs.locale.j21-ansible:/delegated-host] PASSED [ 49%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-gtk-3.0/bookmarks.j21-ansible:/delegated-host] PASSED [ 50%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-qt5ct/qt5ct.conf.j21-ansible:/delegated-host] PASSED [ 50%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxterminal/lxterminal.conf.j21-ansible:/delegated-host] PASSED [ 51%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxsession/LXDE/desktop.conf.j21-ansible:/delegated-host] PASSED [ 52%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxsession/LXDE/autostart.j21-ansible:/delegated-host] PASSED [ 53%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-pcmanfm/LXDE/desktop-items-0.conf.j21-ansible:/delegated-host] PASSED [ 54%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxpanel/launchtaskbar.cfg.j21-ansible:/delegated-host] PASSED [ 55%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-lxpanel/LXDE/panels/panel.j21-ansible:/delegated-host] PASSED [ 56%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-openbox/lxde-rc.xml.j21-ansible:/delegated-host] PASSED [ 57%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-clipit/disabled.j21-ansible:/delegated-host] PASSED [ 58%]
molecule/shared/tests/test_branding.py::test_config_files[pirate-libfm/libfm.conf.j21-ansible:/delegated-host] PASSED [ 59%]
molecule/shared/tests/test_dropins.py::test_bashrc_sources_aliases[root-ansible:/delegated-host] PASSED [ 60%]
molecule/shared/tests/test_dropins.py::test_bashrc_sources_aliases[pirate-ansible:/delegated-host] PASSED [ 61%]
molecule/shared/tests/test_dropins.py::test_dropin_files[root-.bash_profile-ansible:/delegated-host] PASSED [ 62%]
molecule/shared/tests/test_dropins.py::test_dropin_files[root-.bash_aliases-ansible:/delegated-host] PASSED [ 63%]
molecule/shared/tests/test_dropins.py::test_dropin_files[root-.gitconfig-ansible:/delegated-host] PASSED [ 64%]
molecule/shared/tests/test_dropins.py::test_dropin_files[root-.ssh/config-ansible:/delegated-host] PASSED [ 65%]
molecule/shared/tests/test_dropins.py::test_dropin_files[pirate-.bash_profile-ansible:/delegated-host] PASSED [ 66%]
molecule/shared/tests/test_dropins.py::test_dropin_files[pirate-.bash_aliases-ansible:/delegated-host] PASSED [ 66%]
molecule/shared/tests/test_dropins.py::test_dropin_files[pirate-.gitconfig-ansible:/delegated-host] PASSED [ 67%]
molecule/shared/tests/test_dropins.py::test_dropin_files[pirate-.ssh/config-ansible:/delegated-host] PASSED [ 68%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[root-.bash_profile-ansible:/delegated-host] PASSED [ 69%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[root-.bash_aliases-ansible:/delegated-host] PASSED [ 70%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[root-.gitconfig-ansible:/delegated-host] PASSED [ 71%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[root-.ssh/config-ansible:/delegated-host] PASSED [ 72%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[pirate-.bash_profile-ansible:/delegated-host] PASSED [ 73%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[pirate-.bash_aliases-ansible:/delegated-host] PASSED [ 74%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[pirate-.gitconfig-ansible:/delegated-host] PASSED [ 75%]
molecule/shared/tests/test_dropins.py::test_dropin_directories[pirate-.ssh/config-ansible:/delegated-host] PASSED [ 76%]
molecule/shared/tests/test_dropins.py::test_pipx[root-pipx-ansible:/delegated-host] PASSED [ 77%]
molecule/shared/tests/test_dropins.py::test_pipx[root-update-dotdee-ansible:/delegated-host] PASSED [ 78%]
molecule/shared/tests/test_dropins.py::test_pipx[pirate-pipx-ansible:/delegated-host] PASSED [ 79%]
molecule/shared/tests/test_dropins.py::test_pipx[pirate-update-dotdee-ansible:/delegated-host] PASSED [ 80%]
molecule/shared/tests/test_dropins.py::test_update_dotdee_write_bash_profile[root-ansible:/delegated-host] PASSED [ 81%]
molecule/shared/tests/test_dropins.py::test_update_dotdee_write_bash_profile[pirate-ansible:/delegated-host] PASSED [ 82%]
molecule/shared/tests/test_ip_in_issue.py::test_issue_file[ansible:/delegated-host] PASSED [ 83%]
molecule/shared/tests/test_ip_in_issue.py::test_issue_d[ansible:/delegated-host] PASSED [ 83%]
molecule/shared/tests/test_ip_in_issue.py::test_issue_d_interfaces[ansible:/delegated-host] PASSED [ 84%]
molecule/shared/tests/test_ip_in_issue.py::test_issue_d_fingerprints[ansible:/delegated-host] PASSED [ 85%]
molecule/shared/tests/test_shared.py::test_shared_skip SKIPPED (forc...) [ 86%]
molecule/shared/tests/test_swapcapslockctrl.py::test_udev_package[ansible:/delegated-host] PASSED [ 87%]
molecule/shared/tests/test_swapcapslockctrl.py::test_udev_hwdb_file[ansible:/delegated-host] PASSED [ 88%]
molecule/shared/tests/test_swapcapslockctrl.py::test_xkboptions[ansible:/delegated-host] PASSED [ 89%]
molecule/shared/tests/test_swapcapslockctrl.py::test_keyboard_configuration[ansible:/delegated-host] PASSED [ 90%]
molecule/shared/tests/test_swapcapslockctrl.py::test_inputrc[ansible:/delegated-host-root] PASSED [ 91%]
molecule/shared/tests/test_swapcapslockctrl.py::test_inputrc[ansible:/delegated-host-pirate] PASSED [ 92%]
molecule/shared/tests/test_swapcapslockctrl.py::test_bashrc[ansible:/delegated-host-root] PASSED [ 93%]
molecule/shared/tests/test_swapcapslockctrl.py::test_bashrc[ansible:/delegated-host-pirate] PASSED [ 94%]
molecule/shared/tests/test_swapcapslockctrl.py::test_cshrc[ansible:/delegated-host-root] PASSED [ 95%]
molecule/shared/tests/test_swapcapslockctrl.py::test_cshrc[ansible:/delegated-host-pirate] PASSED [ 96%]
molecule/shared/tests/test_swapcapslockctrl.py::test_exrc[ansible:/delegated-host-root] PASSED [ 97%]
molecule/shared/tests/test_swapcapslockctrl.py::test_exrc[ansible:/delegated-host-pirate] PASSED [ 98%]
molecule/shared/tests/test_swapcapslockctrl.py::test_vimrc[ansible:/delegated-host-root] PASSED [ 99%]
molecule/shared/tests/test_swapcapslockctrl.py::test_vimrc[ansible:/delegated-host-pirate] PASSED [100%]
============ 103 passed, 1 skipped, 2 xfailed in 116.30s (0:01:56) =============
INFO Verifier completed successfully.
Several environment variables in the molecule.yml files that allow you to control the amount
of output that is produced. These are:
ANSIBLE_VERBOSITY- Controls verbosity ofansible-playbook,ansible-lint, andpipdeptreeoutput. Set to a numeric value corresponding to output level (default0).ANSIBLE_FORCE_COLOR- Set tofalseto disable color output fromansible-playbook.
If you are producing collection artifacts for testing on delegated hosts, such as a Raspberry Pi or cloud instance, you will want to bump the version number when building artifacts.
Doing a make build will first do bumpversion build so each new
artifact will have a unique build version number component for the
artifact and its constituent files.
$ cat VERSION
0.6.0
$ bumpversion build
$ git diff VERSION
diff --git a/VERSION b/VERSION
index a918a2a..758efdb 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.6.0
+0.6.0.1
These artifacts will work for testing by manually loading them, but
they will not be published when you push to GitHub. The GitHub Actions
workflows will only run molecule tests, which is necessary before
any artifacts can be published via the GitHub Actions workflows.
Of course you can always manually publish the last built artifact
using make publish if need be.
When you are preparing to publish a release candidate, specify the current
version number and manually set a new version number with the -rc pre-release
identifier like this:
$ bumpversion --current-version 0.6.0.1 --new-version 0.6.1-rc.1 build
$ git diff VERSION
diff --git a/VERSION b/VERSION
index a918a2a..2f12cd4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.6.0
+0.6.1-rc.1
When you push to the develop branch with a tag containing the 0.6.1-rc.1
identifier, it will be published to the Ansible Galaxy development server.
As long as you are continuing to iterate, just keep doing make build and
the release candidate number will increment:
$ bumpversion build
$ git diff VERSION
diff --git a/VERSION b/VERSION
index a918a2a..2f12cd4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.6.0
+0.6.1-rc.2
When you are satisfied that all tests work on your development servers and GitHub, you are ready to publish a full "production" release artifact.
To do that, you need to do two things:
-
Manually remove the
-rc.Ncomponents from the version number by doing the opposite of what was done above, and -
Tag the commit with the new version number (in this case,
0.6.1) on themainbranch and the GitHub Actions workflow will publish it to the main Ansible Galaxy server.
Again, do frequent make test runs whenever making significant changes beyond
bumping version numbers and updating release history. Each push to GitHub
before pushing the tags will run tests as well, reassuring you that the
published artifacts will work.
This repo is set up assuming miniconda is installed for two reasons:
-
It allows you to avoid conflicts with your system's
pythoninstallation by using virtual environments for managing yourpythonexecutable and manage packages in itssite-packagesdirectory, and -
It sets environment variables automatically when activating virtual environments. This allows you to associate the
python-secretsenvironment you will be using for storing configuration variables, secrets like API keys and passwords, and storing temporary files that contain secrets (e.g., a Raspberry Picloud-configfile).
Create your virtual environment. For this example, the name utils is used.
$ conda create -n utils python=3.9
Set environment variables for python-secrets to use for finding where your
secrets will be stored and which environment identifier to use.
$ conda env config vars set D2_SECRETS_BASEDIR=~/.secrets D2_ENVIRONMENT=utils CLIFF_FIT_WIDTH=1
To make your changes take effect please reactivate your environment
Follow the guidance the first time you do this to get these environment variables set. When the values change, you will be notified of this fact.
To see what variables are set by conda on activation, do:
$ conda env config vars list
D2_SECRETS_BASEDIR = /home/dittrich/.secrets
D2_ENVIRONMENT = utils
CLIFF_FIT_WIDTH = 1
When developing and testing your new roles, you may find that some Ansible plays cause idempotence tests to fail. Here are some of the causes and solutions.
-
More than one role may attempt to manage the same file in the file system. This can cause problems when one play copies or templates an entire file, while another uses
ansible.builtin.blockinfileoransible.builtin.lineinfile. This can cause the file contents to change back and forth. Closely examine the plays that fail idempotence tests to see what file the change and how. You may need to change the order of the roles, change the way the file contents are modified, change the markers inblockinfileplays to be more unique. -
Idempotence failures can also be caused by changes in file metadata rather than contents. The most common reason for this is different
modevalues in two or more plays that manage the same file. This can result in the mode changing back and forth between the different values, even when the content remains exactly the same. Pay attention tomodeandgroupsettings. You may get warnings fromansible-lintthat a newly created file may end up with insecure settings. Usemolecule convergeto get all the plays to run, followed bymolecule loginto log into the instance to check file contents and/or file system metadata. Runningmolecule verifywill run the tests again to debug your plays. -
"FOSS-rot". Yes, I said it. Like most popular open source projects, anything you write for or with Ansible will, after a few months, simply fail because of breaking changes in Ansible, community collections and roles, and related software like
molecule,testinfra, and Docker is also part of this particular problem.I hadn't touched this collection in many months and when I came back to it to continue developing I got several failures in what previously was working fine. By pinning some packages to attempt to maintain stability, deprecations and non-backward compatible changes and newly set minimum versions above those being pinned resulted in breakages. This included operating system distributions reaching "end-of-life" status.
I rat-holed for days trying to get Debian 10 to run
systemdprocesses in Docker to install Kali Linux packages, which failed duringapt-get installbecause of a change inperl-baseandlibc6that resulted in a dynamic library that was refactored out of a dependent package toperl-base(whichdpkguses to complete installation of packages, breaking the installation entirely in a way that requires manually re-inserting the missing dynamic library and using APT's--fix-brokenflag to recover!After giving up on that and just moving to Debian 11 (which Kali Linux now uses), I ran into a cluster of issues with incompatible versions of
ansible,ansible-core,ansible-lint,ansible-compat, andpytestplugins fortestinfraandansible. They interact in very complex ways that are extremely difficult to debug.-
moleculeusesansible-compat(behind the scenes, mind you) to runansible-playbook,ansible-galaxy,ansible, linters, andpytest. -
pytest, in turn, also runsansibleas well astestinfra(in my case) for testing. But wait, there's more! -
testinfrarunsdocker, in which the Ansible collection is installed and tested.
I ended up having to get
pytesttesting working under VSCode, single-step through process execution to see data structures at runtime, and forking 5 repositories in which I fixed bugs in order to achieve enough stability to finally get everything working and the collection testable on a Raspberry Pi.Sigh. (At least everything seems to be stable again. For now...)
-
- Test-driven infrastructure development with Ansible & Molecule, by Jonas Hecht, December 4, 2018
- Continuous Infrastructure with Ansible, Molecule & TravisCI, by Jonas Hecht, December 11, 2018
- Make your Ansible Playbooks flexible, maintainable, and scalable, by Jeff Geerling, September 28, 2018
- Testing Ansible automation with molecule, by Peter Gustafsson, March 4, 2019
- Question: accessing values of variables as they are being used for provisioning an instance inside Testinfra tests #151, April 5, 2016
- Using Ansible Molecule to test roles in monorepo, by Maria Kotlyarevskaya, Mar 13, 2021
test inframodules- Advanced
bumpversionexamples - Five Ansible Techniques I Wish I'd Known Sooner, by zwischenzugs, August 27, 2021
- Mastering Molecule, by Sorin Sbarnea, January 1, 2019
See the changelog.
We follow the Ansible Code of Conduct in all our interactions within this project.
If you encounter abusive behavior, please refer to the policy violations section of the Code for information on how to raise a complaint.
Apache 2.0 License
See LICENSE to see the full text.
Dave Dittrich < [email protected] > (https://github.com/davedittrich/utils)