Skip to content

Commit

Permalink
Merge pull request #175 from benjixx/feature/support-ansible26-and-py…
Browse files Browse the repository at this point in the history
…thon37

add support for Ansible 2.6 and Python 3.7
  • Loading branch information
benjixx committed Jul 31, 2018
2 parents f809892 + eb5d0d5 commit 874f918
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 80 deletions.
20 changes: 16 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
sudo: required
dist: trusty
dist: xenial

language: python

cache:
directories:
- $HOME/.cache/pip
before_cache:
- rm -rf $HOME/.cache/pip/log/

services:
- docker

env:
matrix:
- TOXENV=py27-ansible23
- TOXENV=py27-ansible24
- TOXENV=py27-ansible25
- TOXENV=py27-ansible26
- TOXENV=py27-ansibledevel
- TOXENV=py36-ansible23
- TOXENV=py36-ansible24
- TOXENV=py36-ansible25
- TOXENV=py36-ansible26
- TOXENV=py36-ansibledevel
- TOXENV=py37-ansible25
- TOXENV=py37-ansible26
- TOXENV=py37-ansibledevel
- TOXENV=docs

before_install:
Expand All @@ -26,7 +35,10 @@ before_install:
- sudo apt-get -qq update

# install python 3.6
- sudo apt-get -qq -y install python3.6 python3.6-dev
- if [ ${TOXENV:0:4} = py36 ]; then sudo apt-get -qq -y install python3.6 python3.6-dev; fi

# install python 3.7
- if [ ${TOXENV:0:4} = py37 ]; then sudo apt-get -qq -y install python3.7 python3.7-dev; fi

# list available docker-ce versions
- apt-cache madison docker-ce
Expand Down
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ History
0.12.0 (TBD - ACTIVE DEVELOPMENT)
---------------------------------

Major Changes
~~~~~~~~~~~~~

* add support for Ansible 2.6, drop support for Ansible 2.3
* add support for Python 3.7


0.11.0 (2018-06-20)
-------------------
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ and playbooks as well as running full integration tests for your software.
:scale: 100%
:target: https://github.com/goodplay/goodplay/blob/master/LICENSE

.. |supported-ansible-versions| image:: https://img.shields.io/badge/ansible-2.3,2.4,2.5-blue.svg
.. |supported-ansible-versions| image:: https://img.shields.io/badge/ansible-2.4,%202.5,%202.6-blue.svg
:alt: Supported Ansible Versions
:scale: 100%
:target: https://docs.ansible.com/
Expand Down
6 changes: 5 additions & 1 deletion goodplay/ansible_support/callback_plugin/goodplay.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def __init__(self):
self._supports_check_mode_re = re.compile(b'\\bsupports_check_mode\\s*=\\s*True\\b')
self._cache = {}

def should_run_in_check_mode(self, action):
return action not in ('command', 'shell') \
and self.supports_check_mode(action)

def supports_check_mode(self, action):
is_supported = self._cache.get(action, None)
not_found_in_cache = is_supported is None
Expand Down Expand Up @@ -50,7 +54,7 @@ def goodplay_set_task_and_variable_override(self, task, *args, **kwargs):

if 'test' in task.tags:
# enable check mode if supported
if ActionInfo.supports_check_mode(task.action):
if ActionInfo.should_run_in_check_mode(task.action):
new_info.check_mode = True

# special task action handling
Expand Down
27 changes: 0 additions & 27 deletions goodplay/ansible_support/connection_plugin/goodplaydocker.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)

import re

from ansible import __version__ as ansible_version
import ansible.constants as C
from ansible.errors import AnsibleError
from ansible.playbook.play_context import PlayContext
import ansible.plugins.connection.docker

Expand Down Expand Up @@ -58,26 +54,3 @@ def _build_exec_cmd(self, cmd):
local_cmd += ['-i', self._play_context.remote_addr] + cmd

return local_cmd


# Ansible 2.2 specific fixes
if ansible_version.startswith('2.2.'):
@staticmethod
def _sanitize_version(version):
return re.sub(b'[^0-9a-zA-Z\.]', b'', version)

def _get_docker_version(self):
cmd, cmd_output, err, returncode = self._old_docker_version()
if returncode == 0:
for line in cmd_output.split(b'\n'):
if line.startswith(b'Server version:'): # old docker versions
return self._sanitize_version(line.split()[2]).decode('utf-8')

cmd, cmd_output, err, returncode = self._new_docker_version()
if returncode:
raise AnsibleError('Docker version check (%s) failed: %s' % (cmd, err))

return self._sanitize_version(cmd_output).decode('utf-8')

Connection._sanitize_version = _sanitize_version
Connection._get_docker_version = _get_docker_version
47 changes: 9 additions & 38 deletions goodplay/ansible_support/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,11 @@
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)

from ansible import __version__ as ansible_version

try:
from ansible.inventory.manager import InventoryManager
except ImportError:
import ansible.inventory

from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.utils.vars import load_extra_vars

try:
from ansible.vars.manager import VariableManager
except ImportError:
from ansible.vars import VariableManager
import ansible.vars
from ansible.vars.manager import VariableManager


class EmptyOptions(object):
Expand All @@ -34,36 +24,17 @@ def build_inventory(self):
self.clear_caches()

loader = DataLoader()

# Ansible 2.2 and 2.3 specific fixes
if ansible_version.startswith('2.2.') or ansible_version.startswith('2.3.'):
variable_manager = ansible.vars.VariableManager()
variable_manager.extra_vars = load_extra_vars(
loader=loader, options=EmptyOptions())

inventory = ansible.inventory.Inventory(
loader=loader,
variable_manager=variable_manager,
host_list=self.inventory_path.strpath)
variable_manager.set_inventory(inventory)
# Ansible 2.4+
else:
inventory = InventoryManager(loader=loader, sources=self.inventory_path.strpath)
variable_manager = VariableManager(
loader=loader, inventory=inventory)
variable_manager.extra_vars = load_extra_vars(
loader=loader, options=EmptyOptions())
inventory = InventoryManager(
loader=loader, sources=self.inventory_path.strpath)
variable_manager = VariableManager(
loader=loader, inventory=inventory)
variable_manager.extra_vars = load_extra_vars(
loader=loader, options=EmptyOptions())

return inventory

def clear_caches(self):
# Ansible 2.2 and 2.3 specific fixes
if ansible_version.startswith('2.2.') or ansible_version.startswith('2.3.'):
# unfortunately we have to reset caches as these are kept as module state
ansible.inventory.HOSTS_PATTERNS_CACHE.clear()
ansible.vars.HOSTVARS_CACHE.clear()
# Ansible 2.4+
elif self.inventory is not None:
if self.inventory is not None:
self.inventory.clear_caches()

def hosts(self):
Expand Down
2 changes: 1 addition & 1 deletion goodplay/docker_support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def setup(self):
inventory_content = '\n'.join(inventory_lines)

# choose name 'inventory_goodplay' as it comes after 'inventory' when compared,
# alphanumerical, otherwise Ansible 2.3 does not merge in the ansible_connection
# alphanumerical, otherwise Ansible does not merge in the ansible_connection
# information correctly and thus tries to use an SSH connection
self.ctx.extended_inventory_path.join('inventory_goodplay').write(inventory_content)

Expand Down
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ansible==2.5.5
ansible==2.6.2
cached-property==1.4.3
docker-compose==1.21.2
docker-compose==1.22.0
idna==2.6
py==1.5.3
pytest==3.6.1
py==1.5.4
pytest==3.7.0
sarge==0.1.5
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


install_requires = [
'ansible>=2.3',
'ansible>=2.4',
'cached-property>=1.3.1',
'docker-compose>=1.18.0',
'idna==2.6', # pin temporary due to dep docker-py -> requests -> idna<2.7
Expand Down Expand Up @@ -51,6 +51,7 @@
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Topic :: Software Development :: Quality Assurance',
'Topic :: Software Development :: Testing',
],
Expand Down
23 changes: 22 additions & 1 deletion tests/test_ansible_check_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def test_lineinfile_task_tagged_with_test_runs_in_check_mode(testdir):
assert testdir.tmpdir.join('HELLO').read() == 'WORLD\n'


def test_task_tagged_with_test_that_does_not_support_check_mode_runs_in_normal_mode(testdir):
def test_command_task_tagged_with_test_runs_in_normal_mode(testdir):
smart_create(testdir.tmpdir, '''
## inventory
127.0.0.1 ansible_connection=local
Expand All @@ -80,6 +80,27 @@ def test_task_tagged_with_test_that_does_not_support_check_mode_runs_in_normal_m
assert testdir.tmpdir.join('HELLO').check(file=True)


def test_shell_task_tagged_with_test_runs_in_normal_mode(testdir):
smart_create(testdir.tmpdir, '''
## inventory
127.0.0.1 ansible_connection=local
## test_playbook.yml
- hosts: 127.0.0.1
gather_facts: no
tasks:
- name: intentional test with side effect
shell: touch "{{ playbook_dir }}/HELLO"
changed_when: False
tags: test
''')

result = testdir.inline_run('-s')
result.assertoutcome(passed=1)

assert testdir.tmpdir.join('HELLO').check(file=True)


def test_custom_module_runs_in_normal_mode_when_check_mode_not_supported(testdir):
smart_create(testdir.tmpdir, '''
## inventory
Expand Down
4 changes: 2 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = {py27,py36}-ansible{23,24,25,devel}
envlist = {py27,py36}-ansible{24,25,26,devel}, py37-ansible{25,26,devel}, docs, lint

[pytest]
log_format = %(asctime)s %(name)s:%(lineno)d %(levelname)s %(message)s
Expand All @@ -9,9 +9,9 @@ markers =
[testenv]
deps =
coverage
ansible23: ansible>=2.3,<2.4
ansible24: ansible>=2.4,<2.5
ansible25: ansible>=2.5,<2.6
ansible26: ansible>=2.6,<2.7
ansibledevel: git+https://github.com/ansible/ansible.git@devel#egg=ansible
passenv =
CI # required for pytest to detect CI environment and show full comparison
Expand Down

0 comments on commit 874f918

Please sign in to comment.