Skip to content
This repository was archived by the owner on Jun 12, 2020. It is now read-only.

Commit 3b673ac

Browse files
authored
Merge pull request #17 from paulfantom/molecule2
[minor] molecule 2.x tests and support for ubuntu bionic and debian stretch
2 parents ff639e8 + 6a4e466 commit 3b673ac

16 files changed

+275
-53
lines changed

.gitlab-ci.yml

-6
This file was deleted.

.travis.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ cache: pip
44
services:
55
- docker
66
env:
7-
- ANSIBLE=2.2.3
8-
- ANSIBLE=2.3.2
9-
- ANSIBLE=2.4.2
7+
- ANSIBLE='ansible>=2.3.0,<2.4.0'
8+
- ANSIBLE='ansible>=2.4.0,<2.5.0'
9+
- ANSIBLE='ansible>=2.5.0,<2.6.0'
1010
install:
11-
- pip install ansible==${ANSIBLE} ansible-lint>=3.4.15 molecule==1.25.0 docker git-semver testinfra>=1.7.0
11+
- pip install ${ANSIBLE} 'ansible-lint>=3.4.15' 'molecule>=2.13.0' docker git-semver 'testinfra>=1.7.0'
1212
script:
1313
- molecule test
1414
deploy:
1515
provider: script
1616
skip_cleanup: true
17-
script: ./.travis/generatetag.sh
17+
script: ./.travis/releaser.sh
1818
on:
1919
branch: master
2020
branches:

.travis/generatetag.sh

-16
This file was deleted.

.travis/releaser.sh

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/bin/bash
2+
#
3+
# Copyright (C) 2018 Pawel Krupa (@paulfantom) - All Rights Reserved
4+
# Permission to copy and modify is granted under the MIT license
5+
#
6+
# Script to automatically do a couple of things:
7+
# - generate a new tag according to semver (https://semver.org/)
8+
# - generate CHANGELOG.md by using https://github.com/skywinder/github-changelog-generator
9+
# - sync CHANGELOG with GitHub releases by using https://github.com/mattbrictson/chandler
10+
#
11+
# Tags are generated by searching for a keyword in last commit message. Keywords are:
12+
# - [patch] or [fix] to bump patch number
13+
# - [minor], [feature] or [feat] to bump minor number
14+
# - [major] or [breaking change] to bump major number
15+
# All keywords MUST be surrounded with square braces.
16+
#
17+
# Script uses git mechanisms for locking, so it can be used in parallel builds
18+
#
19+
# Requirements:
20+
# - GH_TOKEN variable set with GitHub token. Access level: repo.public_repo
21+
# - docker
22+
# - git-semver python package (pip install git-semver)
23+
24+
# Exit when latest commit is tagged
25+
[[ $(git tag --points-at) ]] && exit 0
26+
27+
# Some basic variables
28+
GIT_MAIL="paulfantom@gmail.com"
29+
GIT_USER="paulfantom"
30+
ORGANIZATION=$(echo "$TRAVIS_REPO_SLUG" | awk -F '/' '{print $1}')
31+
PROJECT=$(echo "$TRAVIS_REPO_SLUG" | awk -F '/' '{print $2}')
32+
GALAXY_URL="https://galaxy.ansible.com/${ORGANIZATION}/${PROJECT#ansible-}"
33+
34+
# Git config
35+
git config --global user.email "${GIT_MAIL}"
36+
git config --global user.name "${GIT_USER}"
37+
GIT_URL=$(git config --get remote.origin.url)
38+
GIT_URL=${GIT_URL#*//}
39+
40+
# Generate TAG
41+
GIT_TAG=none
42+
echo "Last commit message: $TRAVIS_COMMIT_MESSAGE"
43+
case "${TRAVIS_COMMIT_MESSAGE}" in
44+
*"[patch]"*|*"[fix]"* ) GIT_TAG=$(git semver --next-patch) ;;
45+
*"[minor]"*|*"[feat]"*|*"[feature]"* ) GIT_TAG=$(git semver --next-minor) ;;
46+
*"[major]"*|*"[breaking change]"* ) GIT_TAG=$(git semver --next-major) ;;
47+
*) echo "Keyword not detected. Doing nothing" ;;
48+
esac
49+
if [ "$GIT_TAG" != "none" ]; then
50+
echo "Assigning new tag: $GIT_TAG"
51+
git tag "$GIT_TAG" -a -m "Automatic tag generation for travis build no. $TRAVIS_BUILD_NUMBER"
52+
git push "https://${GH_TOKEN}:@${GIT_URL}" --tags || exit 0
53+
fi
54+
55+
# Generate CHANGELOG.md
56+
git checkout master
57+
git pull
58+
docker run -it --rm -v "$(pwd)":/usr/local/src/your-app ferrarimarco/github-changelog-generator \
59+
-u "${ORGANIZATION}" -p "${PROJECT}" --token "${GH_TOKEN}" \
60+
--release-url "${GALAXY_URL}" \
61+
--unreleased-label "**Next release**" --no-compare-link
62+
63+
git add CHANGELOG.md
64+
git commit -m '[ci skip] Automatic changelog update'
65+
66+
git push "https://${GH_TOKEN}:@${GIT_URL}" || exit 0
67+
68+
# Sync changelog to github releases
69+
if [ "$GIT_TAG" != "none" ]; then
70+
docker run -e CHANDLER_GITHUB_API_TOKEN="${GH_TOKEN}" -v "$(pwd)":/chandler -ti whizark/chandler push "${GIT_TAG}"
71+
fi

.yamllint

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
extends: default
2+
ignore: |
3+
.travis/
4+
.travis.yml
5+
meta/
6+
7+
rules:
8+
braces:
9+
max-spaces-inside: 1
10+
level: error
11+
brackets:
12+
max-spaces-inside: 1
13+
level: error
14+
line-length: disable

CONTRIBUTING.md

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# Contributor Guideline
22

3-
This document provides an overview of how you can participate in improving this project or extending it. We are grateful for all your help: bug reports and fixes, code contributions, documentation or ideas. Feel free to join, I appreciate your support!!
3+
This document provides an overview of how you can participate in improving this project or extending it. We are grateful for all your help: bug reports and fixes, code contributions, documentation or ideas. Feel free to join, we appreciate your support!!
44

55
## Communication
66

7+
### IRC
8+
9+
You can talk with us on #cloudalchemy channel on freenode.
10+
711
### GitHub repositories
812

9-
Much of the issues, goals and ideas are tracked in the respective projects in GitHub. Please use this channel to report bugs and post ideas.
13+
Much of the issues, goals and ideas are tracked in the respective projects in GitHub. Please use this channel to report bugs.
1014

1115
## git and GitHub
1216

@@ -28,7 +32,15 @@ Some great guidelines can be found [here](https://wiki.openstack.org/wiki/GitCom
2832

2933
## Releases
3034

31-
Generally I try to stick to semantic versioning, where every accepted PR is treated as patch or minor feature and version is released accordingly by CI pipeline.
35+
We try to stick to semantic versioning and our releases are made by CI pipeline. It is done by assigning a keyword (in a way similar to travis [`[ci skip]`](https://docs.travis-ci.com/user/customizing-the-build#Skipping-a-build)) to a commit with merge request. Available keywords are (square brackets are important!):
36+
37+
* `[patch]`, `[fix]` - for PATCH version release
38+
* `[minor]`, `[feature]`, `[feat]` - for MINOR version release
39+
* `[major]`, `[breaking change]` - for MAJOR version release
40+
41+
## Changelog
42+
43+
Changelog is generateg automatically on every merged Pull Request and all information is taken from github issues, PRs and labels.
3244

3345
## Expectations
3446

@@ -45,13 +57,16 @@ We try to provide production ready ansible roles which should be as much zero-co
4557

4658
### Add tests
4759

48-
We try to have as much tests written in testinfra framework as possible, so when you copy file, some template or starting some server just add couple of lines in [/tests/test)default.py](test_default.py) file. If you want to know how to write tests in testinfra, go to their [docs](http://testinfra.readthedocs.io/en/latest/index.html).
60+
Currently we are using two test scenarios located in [/molecule](molecule) directory. First ([default](molecule/default/molecule.yml)) one is testing default configuration without any additional variables, second one ([alternative](molecule/alternative/molecule.yml)) is testing what happens when many variables from [/defaults/main.yml](defaults/main.yml) are changed. When adding new functionalities please add tests to proper scenarios. Tests are written in testinfra framework and are located in `/tests` subdirectory of scenario directory (for example default tests are in [/molecule/default/tests](molecule/default/tests)).
61+
More information about:
62+
- [testinfra](http://testinfra.readthedocs.io/en/latest/index.html)
63+
- [molecule](https://molecule.readthedocs.io/en/latest/index.html)
4964

5065
### Follow best practices
5166

5267
Please follow [ansible best practices](http://docs.ansible.com/ansible/latest/playbooks_best_practices.html) and especially provide meaningful names to tasks and even comments where needed.
5368

54-
Our test framework automatically lints code with [`ansible-lint`](https://github.com/willthames/ansible-lint) command so be sure to follow it's rules.
69+
Our test framework automatically lints code with [`yamllint`](https://yamllint.readthedocs.io) and [`ansible-lint`](https://github.com/willthames/ansible-lint) programs so be sure to follow their rules.
5570

5671
Remember: Code is generally read much more often than written.
5772

README.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,21 @@ Use it in a playbook as follows:
4646
4747
## Local Testing
4848
49-
The preferred way of locally testing the role is to use Docker and [molecule](https://github.com/metacloud/molecule) (v1.25). You will have to install Docker on your system. See Get started for a Docker package suitable to for your system.
49+
The preferred way of locally testing the role is to use Docker and [molecule](https://github.com/metacloud/molecule) (v2.x). You will have to install Docker on your system. See Get started for a Docker package suitable to for your system.
5050
All packages you need to can be specified in one line:
5151
```sh
52-
pip install ansible ansible-lint>=3.4.15 molecule==1.25.0 docker testinfra>=1.7.0
52+
pip install ansible 'ansible-lint>=3.4.15' 'molecule>2.13.0' docker 'testinfra>=1.7.0' jmespath
5353
```
54-
This should be similiar to one listed in `.travis.yml` file in `install` section.
54+
This should be similar to one listed in `.travis.yml` file in `install` section.
5555
After installing test suit you can run test by running
5656
```sh
57-
molecule test
57+
molecule test --all
5858
```
59-
For more information about molecule go to their [docs](http://molecule.readthedocs.io/en/stable-1.25/).
59+
For more information about molecule go to their [docs](http://molecule.readthedocs.io/en/latest/).
60+
61+
## Travis CI
62+
63+
Combining molecule and travis CI allows to test how new PRs will behave when used with multiple ansible versions and multiple operating systems. This also allows to create test scenarios for different role configurations. As a result test matrix is quite large and takes more time than local testing, so please be patient.
6064

6165
## Contributing
6266

meta/main.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
---
22
galaxy_info:
3-
author: Pawel Krupa (paulfantom), donat-b
3+
author: donat-b, Pawel Krupa (paulfantom)
44
description: Fast, secure, efficient backup program
55
license: MIT
66
min_ansible_version: 2.2
77
platforms:
88
- name: Ubuntu
99
versions:
10+
- bionic
1011
- xenial
1112
- name: EL
1213
versions:
1314
- 7
1415
- name: Debian
1516
versions:
17+
- stretch
1618
- jessie
1719
galaxy_tags:
1820
- system

molecule/default/create.yml

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
- name: Create
3+
hosts: localhost
4+
connection: local
5+
gather_facts: false
6+
no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}"
7+
tasks:
8+
- name: Create molecule instance(s)
9+
docker_container:
10+
name: "{{ item.name }}"
11+
docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}"
12+
hostname: "{{ item.name }}"
13+
image: "{{ item.image }}"
14+
state: started
15+
recreate: false
16+
log_driver: json-file
17+
command: "{{ item.command | default(omit) }}"
18+
privileged: "{{ item.privileged | default(omit) }}"
19+
volumes: "{{ item.volumes | default(omit) }}"
20+
capabilities: "{{ item.capabilities | default(omit) }}"
21+
exposed_ports: "{{ item.exposed_ports | default(omit) }}"
22+
published_ports: "{{ item.published_ports | default(omit) }}"
23+
ulimits: "{{ item.ulimits | default(omit) }}"
24+
networks: "{{ item.networks | default(omit) }}"
25+
dns_servers: "{{ item.dns_servers | default(omit) }}"
26+
register: server
27+
with_items: "{{ molecule_yml.platforms }}"
28+
async: 7200
29+
poll: 0
30+
31+
- name: Wait for instance(s) creation to complete
32+
async_status:
33+
jid: "{{ item.ansible_job_id }}"
34+
register: docker_jobs
35+
until: docker_jobs.finished
36+
retries: 300
37+
with_items: "{{ server.results }}"

molecule/default/destroy.yml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
- name: Destroy
3+
hosts: localhost
4+
connection: local
5+
gather_facts: false
6+
no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}"
7+
tasks:
8+
- name: Destroy molecule instance(s)
9+
docker_container:
10+
name: "{{ item.name }}"
11+
docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}"
12+
state: absent
13+
force_kill: "{{ item.force_kill | default(true) }}"
14+
register: server
15+
with_items: "{{ molecule_yml.platforms }}"
16+
async: 7200
17+
poll: 0
18+
19+
- name: Wait for instance(s) deletion to complete
20+
async_status:
21+
jid: "{{ item.ansible_job_id }}"
22+
register: docker_jobs
23+
until: docker_jobs.finished
24+
retries: 300
25+
with_items: "{{ server.results }}"
26+
27+
- name: Delete docker network(s)
28+
docker_network:
29+
name: "{{ item }}"
30+
docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}"
31+
state: absent
32+
with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}"

molecule/default/molecule.yml

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
dependency:
3+
name: galaxy
4+
driver:
5+
name: docker
6+
lint:
7+
name: yamllint
8+
platforms:
9+
- name: bionic
10+
image: paulfantom/ubuntu-molecule:18.04
11+
privileged: true
12+
volumes:
13+
- /sys/fs/cgroup:/sys/fs/cgroup:ro
14+
- name: xenial
15+
image: paulfantom/ubuntu-molecule:16.04
16+
privileged: true
17+
volumes:
18+
- /sys/fs/cgroup:/sys/fs/cgroup:ro
19+
- name: stretch
20+
image: paulfantom/debian-molecule:9
21+
privileged: true
22+
volumes:
23+
- /sys/fs/cgroup:/sys/fs/cgroup:ro
24+
- name: jessie
25+
image: paulfantom/debian-molecule:8
26+
privileged: true
27+
volumes:
28+
- /sys/fs/cgroup:/sys/fs/cgroup:ro
29+
- name: centos7
30+
image: paulfantom/centos-molecule:7
31+
privileged: true
32+
volumes:
33+
- /sys/fs/cgroup:/sys/fs/cgroup:ro
34+
- name: fedora
35+
image: paulfantom/fedora-molecule:27
36+
privileged: true
37+
volumes:
38+
- /sys/fs/cgroup:/sys/fs/cgroup:ro
39+
provisioner:
40+
name: ansible
41+
lint:
42+
name: ansible-lint
43+
playbooks:
44+
create: create.yml
45+
prepare: prepare.yml
46+
converge: playbook.yml
47+
destroy: destroy.yml
48+
scenario:
49+
name: default
50+
verifier:
51+
name: testinfra
52+
lint:
53+
name: flake8
54+
enabled: true

tests/playbook.yml molecule/default/playbook.yml

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
---
2-
- hosts: all
3-
any_errors_fatal: yes
4-
pre_tasks:
5-
- name: Ensure cron.d exists in docker containers
6-
file:
7-
state: 'directory'
8-
path: '/etc/cron.d'
2+
- name: Default use-case scenario
3+
hosts: all
4+
any_errors_fatal: true
95
roles:
106
- ansible-restic
117
vars:

molecule/default/prepare.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
- name: Prepare
3+
hosts: all
4+
gather_facts: false
5+
tasks:
6+
- name: Ensure cron.d exists in docker containers
7+
file:
8+
state: 'directory'
9+
path: '/etc/cron.d'

tests/test_default.py molecule/default/tests/test_default.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
from testinfra.utils.ansible_runner import AnsibleRunner
1+
import os
2+
import testinfra.utils.ansible_runner
23

3-
testinfra_hosts = AnsibleRunner('.molecule/ansible_inventory').get_hosts('all')
4+
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
5+
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
46

57

68
def test_binary(host):

0 commit comments

Comments
 (0)