From 0587aedc018ce50a2236586389f71e127739579f Mon Sep 17 00:00:00 2001 From: Tomas Tomecek Date: Mon, 8 Jan 2018 20:51:49 +0100 Subject: [PATCH] synchronize: add support for buildah (#33823) Fixes #33533 Signed-off-by: Tomas Tomecek --- lib/ansible/plugins/action/synchronize.py | 34 ++++++---- .../targets/synchronize-buildah/aliases | 2 + .../targets/synchronize-buildah/inventory | 1 + .../files/normal_file.txt | 1 + .../test_buildah_synchronize/tasks/main.yml | 66 +++++++++++++++++++ .../targets/synchronize-buildah/runme.sh | 15 +++++ .../test_synchronize_buildah.yml | 8 +++ 7 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 test/integration/targets/synchronize-buildah/aliases create mode 100644 test/integration/targets/synchronize-buildah/inventory create mode 100644 test/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/files/normal_file.txt create mode 100644 test/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/tasks/main.yml create mode 100755 test/integration/targets/synchronize-buildah/runme.sh create mode 100644 test/integration/targets/synchronize-buildah/test_synchronize_buildah.yml diff --git a/lib/ansible/plugins/action/synchronize.py b/lib/ansible/plugins/action/synchronize.py index 6c6613cd7a..cac7f59c93 100644 --- a/lib/ansible/plugins/action/synchronize.py +++ b/lib/ansible/plugins/action/synchronize.py @@ -59,8 +59,8 @@ class ActionModule(ActionBase): if path.startswith('rsync://'): return path - # If using docker, do not add user information - if self._remote_transport not in ['docker'] and user: + # If using docker or buildah, do not add user information + if self._remote_transport not in ['docker', 'buildah'] and user: user_prefix = '%s@' % (user, ) if self._host_is_ipv6_address(host): @@ -188,12 +188,16 @@ class ActionModule(ActionBase): except (AttributeError, KeyError): delegate_to = None - # ssh paramiko docker and local are fully supported transports. Anything + # ssh paramiko docker buildah and local are fully supported transports. Anything # else only works with delegate_to - if delegate_to is None and self._connection.transport not in ('ssh', 'paramiko', 'local', 'docker'): + if delegate_to is None and self._connection.transport not in \ + ('ssh', 'paramiko', 'local', 'docker', 'buildah'): result['failed'] = True - result['msg'] = ("synchronize uses rsync to function. rsync needs to connect to the remote host via ssh, docker client or a direct filesystem " - "copy. This remote host is being accessed via %s instead so it cannot work." % self._connection.transport) + result['msg'] = ( + "synchronize uses rsync to function. rsync needs to connect to the remote " + "host via ssh, docker client or a direct filesystem " + "copy. This remote host is being accessed via %s instead " + "so it cannot work." % self._connection.transport) return result use_ssh_args = _tmp_args.pop('use_ssh_args', None) @@ -382,7 +386,7 @@ class ActionModule(ActionBase): # If launching synchronize against docker container # use rsync_opts to support container to override rsh options - if self._remote_transport in ['docker']: + if self._remote_transport in ['docker', 'buildah']: # Replicate what we do in the module argumentspec handling for lists if not isinstance(_tmp_args.get('rsync_opts'), MutableSequence): tmp_rsync_opts = _tmp_args.get('rsync_opts', []) @@ -394,12 +398,16 @@ class ActionModule(ActionBase): if '--blocking-io' not in _tmp_args['rsync_opts']: _tmp_args['rsync_opts'].append('--blocking-io') - if become and self._play_context.become_user: - _tmp_args['rsync_opts'].append("--rsh=%s exec -u %s -i" % (self._docker_cmd, self._play_context.become_user)) - elif user is not None: - _tmp_args['rsync_opts'].append("--rsh=%s exec -u %s -i" % (self._docker_cmd, user)) - else: - _tmp_args['rsync_opts'].append("--rsh=%s exec -i" % self._docker_cmd) + + if self._remote_transport in ['docker']: + if become and self._play_context.become_user: + _tmp_args['rsync_opts'].append("--rsh=%s exec -u %s -i" % (self._docker_cmd, self._play_context.become_user)) + elif user is not None: + _tmp_args['rsync_opts'].append("--rsh=%s exec -u %s -i" % (self._docker_cmd, user)) + else: + _tmp_args['rsync_opts'].append("--rsh=%s exec -i" % self._docker_cmd) + elif self._remote_transport in ['buildah']: + _tmp_args['rsync_opts'].append("--rsh=buildah run --") # run the module and store the result result.update(self._execute_module('synchronize', module_args=_tmp_args, task_vars=task_vars)) diff --git a/test/integration/targets/synchronize-buildah/aliases b/test/integration/targets/synchronize-buildah/aliases new file mode 100644 index 0000000000..0d34d72346 --- /dev/null +++ b/test/integration/targets/synchronize-buildah/aliases @@ -0,0 +1,2 @@ +non_local +needs/root diff --git a/test/integration/targets/synchronize-buildah/inventory b/test/integration/targets/synchronize-buildah/inventory new file mode 100644 index 0000000000..2eeaf31350 --- /dev/null +++ b/test/integration/targets/synchronize-buildah/inventory @@ -0,0 +1 @@ +buildah-container ansible_host=buildah-container ansible_connection=buildah diff --git a/test/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/files/normal_file.txt b/test/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/files/normal_file.txt new file mode 100644 index 0000000000..33257a92c0 --- /dev/null +++ b/test/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/files/normal_file.txt @@ -0,0 +1 @@ +abnormal content diff --git a/test/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/tasks/main.yml b/test/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/tasks/main.yml new file mode 100644 index 0000000000..251c81768c --- /dev/null +++ b/test/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/tasks/main.yml @@ -0,0 +1,66 @@ +# test code for the synchronize module +# (c) 2014, James Tanner + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +- name: cleanup old files + file: + path: '{{ output_dir }}' + state: absent + +- name: ensure the target directory exists + file: + path: '{{ output_dir }}' + state: directory + +- name: synchronize file to new filename + synchronize: + src: normal_file.txt + dest: '{{ output_dir }}/remote_file.txt' + register: sync_result + +- assert: + that: + - "'changed' in sync_result" + - "sync_result.changed == true" + - "'cmd' in sync_result" + - "'rsync' in sync_result.cmd" + - "'msg' in sync_result" + - "sync_result.msg.startswith('/dev/null 2>/dev/null + +set -e + +buildah from --name $CONTAINER_NAME docker.io/library/centos:7 +trap '{ buildah rm $CONTAINER_NAME; }' EXIT +buildah run $CONTAINER_NAME -- yum install -y rsync + +ansible-playbook test_synchronize_buildah.yml -c buildah -i inventory -vv diff --git a/test/integration/targets/synchronize-buildah/test_synchronize_buildah.yml b/test/integration/targets/synchronize-buildah/test_synchronize_buildah.yml new file mode 100644 index 0000000000..e1cc96657e --- /dev/null +++ b/test/integration/targets/synchronize-buildah/test_synchronize_buildah.yml @@ -0,0 +1,8 @@ +--- +- hosts: buildah-container + connection: buildah + gather_facts: no + vars: + output_dir: /tmp/ansible_test_synchronize_buildah + roles: + - test_buildah_synchronize