mirror of
https://github.com/containers/ansible-podman-collections.git
synced 2026-02-04 07:11:49 +00:00
Add podman_container_copy module
Signed-off-by: kubealex <al.rossi87@gmail.com>
This commit is contained in:
parent
202a0fb6da
commit
25c409a80c
4 changed files with 342 additions and 0 deletions
99
.github/workflows/podman_container_copy.yml
vendored
Normal file
99
.github/workflows/podman_container_copy.yml
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
name: Podman Container Copy module
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/podman_container_copy.yml'
|
||||
- 'ci/*.yml'
|
||||
- 'ci/run_containers_tests.sh'
|
||||
- 'ci/playbooks/containers/podman_container_copy.yml'
|
||||
- 'plugins/modules/podman_container_copy.py'
|
||||
- 'tests/integration/targets/podman_container_copy/**'
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/podman_container_copy.yml'
|
||||
- 'ci/*.yml'
|
||||
- 'ci/run_containers_tests.sh'
|
||||
- 'ci/playbooks/containers/podman_container_copy.yml'
|
||||
- 'plugins/modules/podman_container_copy.py'
|
||||
- 'tests/integration/targets/podman_container_copy/**'
|
||||
schedule:
|
||||
- cron: 4 0 * * * # Run daily at 0:03 UTC
|
||||
|
||||
jobs:
|
||||
|
||||
test_podman_container_copy:
|
||||
name: Podman Container Copy ${{ matrix.ansible-version }}-${{ matrix.os || 'ubuntu-22.04' }}
|
||||
runs-on: ${{ matrix.os || 'ubuntu-22.04' }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ansible-version:
|
||||
- ansible<2.10
|
||||
# - git+https://github.com/ansible/ansible.git@stable-2.11
|
||||
- git+https://github.com/ansible/ansible.git@devel
|
||||
os:
|
||||
- ubuntu-22.04
|
||||
python-version:
|
||||
- 3.11
|
||||
|
||||
steps:
|
||||
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Upgrade pip and display Python and PIP versions
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y python*-wheel python*-yaml
|
||||
python -m pip install --upgrade pip
|
||||
python -V
|
||||
pip --version
|
||||
- name: Set up pip cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ github.ref }}-units-VMs
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
${{ runner.os }}-
|
||||
- name: Install Ansible ${{ matrix.ansible-version }}
|
||||
run: python3 -m pip install --user --force-reinstall --upgrade '${{ matrix.ansible-version }}'
|
||||
|
||||
- name: Build and install the collection tarball
|
||||
run: |
|
||||
rm -rf /tmp/just_new_collection
|
||||
~/.local/bin/ansible-galaxy collection build --output-path /tmp/just_new_collection --force
|
||||
~/.local/bin/ansible-galaxy collection install -vvv --force /tmp/just_new_collection/*.tar.gz
|
||||
- name: Run collection tests for Podman Container Copy module
|
||||
run: |
|
||||
export PATH=~/.local/bin:$PATH
|
||||
echo "Run ansible version"
|
||||
command -v ansible
|
||||
ansible --version
|
||||
export ANSIBLE_CONFIG=$(pwd)/ci/ansible-dev.cfg
|
||||
if [[ '${{ matrix.ansible-version }}' == 'ansible<2.10' ]]; then
|
||||
export ANSIBLE_CONFIG=$(pwd)/ci/ansible-2.9.cfg
|
||||
fi
|
||||
echo $ANSIBLE_CONFIG
|
||||
command -v ansible-playbook
|
||||
pip --version
|
||||
python --version
|
||||
ansible-playbook --version
|
||||
ansible-playbook -vv ci/playbooks/pre.yml \
|
||||
-e host=localhost \
|
||||
-i localhost, \
|
||||
-e ansible_connection=local \
|
||||
-e setup_python=false
|
||||
TEST2RUN=podman_container_copy ./ci/run_containers_tests.sh
|
||||
shell: bash
|
||||
8
ci/playbooks/containers/podman_container_copy.yml
Normal file
8
ci/playbooks/containers/podman_container_copy.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
- hosts: all
|
||||
gather_facts: true
|
||||
tasks:
|
||||
- include_role:
|
||||
name: podman_container_copy
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ _ansible_python_interpreter }}"
|
||||
131
plugins/modules/podman_container_copy.py
Normal file
131
plugins/modules/podman_container_copy.py
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2024 Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
module: podman_container_copy
|
||||
author:
|
||||
- Alessandro Rossi (@kubealex)
|
||||
short_description: Copy file to/from a container
|
||||
notes:
|
||||
- Podman may required elevated privileges in order to run properly.
|
||||
description:
|
||||
- Copy file or folder from the host to a container and vice-versa.
|
||||
options:
|
||||
executable:
|
||||
description:
|
||||
- Path to C(podman) executable if it is not in the C($PATH) on the machine running C(podman)
|
||||
default: 'podman'
|
||||
type: str
|
||||
src:
|
||||
description:
|
||||
- Path of the file/folder to copy from/to the container
|
||||
type: str
|
||||
required: True
|
||||
dest:
|
||||
description:
|
||||
- Path of the destination file/folder to copy from/to the container
|
||||
required: True
|
||||
type: str
|
||||
container:
|
||||
description:
|
||||
- Name/ID of the container to copy from/to
|
||||
required: True
|
||||
type: str
|
||||
from_container:
|
||||
description:
|
||||
- Specify whether or not the file must be copied from the container to the host
|
||||
required: False
|
||||
default: False
|
||||
type: bool
|
||||
archive:
|
||||
description:
|
||||
- Chown copied files to the primary uid/gid of the destination container.
|
||||
required: False
|
||||
default: True
|
||||
type: bool
|
||||
overwrite:
|
||||
description:
|
||||
- Allow to overwrite directories with non-directories and vice versa
|
||||
required: False
|
||||
default: False
|
||||
type: bool
|
||||
'''
|
||||
|
||||
EXAMPLES = r"""
|
||||
- name: Copy file "test.yml" on the host to the "apache" container's root folder
|
||||
containers.podman.podman_search:
|
||||
src: test.yml
|
||||
dest: /
|
||||
container: apache
|
||||
- name: Copy file "test.yml" in the "apache" container's root folder to the playbook's folder
|
||||
containers.podman.podman_search:
|
||||
src: /test.yml
|
||||
dest: ./
|
||||
container: apache
|
||||
from_container: True
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
def copy_file(module, executable, src, dest, container, from_container, archive, overwrite):
|
||||
if from_container:
|
||||
command = [executable, 'cp', '{0}:{1}'.format(container, src), dest]
|
||||
else:
|
||||
command = [executable, 'cp', src, '{0}:{1}'.format(container, dest)]
|
||||
|
||||
if not archive:
|
||||
command.append('--archive=False')
|
||||
|
||||
if overwrite:
|
||||
command.append('--overwrite')
|
||||
|
||||
rc, out, err = module.run_command(command)
|
||||
|
||||
if rc != 0:
|
||||
module.fail_json(msg='Unable to copy file to/from container - {out}'.format(out=err))
|
||||
else:
|
||||
changed = True
|
||||
return changed, out, err
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
executable=dict(type='str', default='podman'),
|
||||
src=dict(type='str', required=True),
|
||||
dest=dict(type='str', required=True),
|
||||
container=dict(type='str', required=True),
|
||||
from_container=dict(type='bool', required=False, default=False),
|
||||
archive=dict(type='bool', required=False, default=True),
|
||||
overwrite=dict(type='bool', required=False, default=False)
|
||||
),
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
executable = module.params['executable']
|
||||
src = module.params['src']
|
||||
dest = module.params['dest']
|
||||
container = module.params['container']
|
||||
from_container = module.params['from_container']
|
||||
archive = module.params['archive']
|
||||
overwrite = module.params['overwrite']
|
||||
|
||||
executable = module.get_bin_path(executable, required=True)
|
||||
|
||||
changed, out, err = copy_file(module, executable, src, dest, container, from_container, archive, overwrite)
|
||||
|
||||
results = dict(
|
||||
changed=changed
|
||||
)
|
||||
|
||||
module.exit_json(**results)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
104
tests/integration/targets/podman_container_copy/tasks/main.yml
Normal file
104
tests/integration/targets/podman_container_copy/tasks/main.yml
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
- name: Test podman container copy host-container
|
||||
block:
|
||||
- name: Generate random value for container name
|
||||
ansible.builtin.set_fact:
|
||||
container_name: "{{ 'ansible-test-podman-%0x' % ((2**32) | random) }}"
|
||||
file_name: sample_file
|
||||
|
||||
- name: Start container
|
||||
containers.podman.podman_container:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
name: "{{ container_name }}"
|
||||
image: alpine:3.7
|
||||
state: started
|
||||
command: sleep 1d
|
||||
|
||||
- name: Create local file to copy
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
This file tests if host -> container copy is working
|
||||
dest: "{{ playbook_dir }}/{{ file_name }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Copy local file to containers root folder
|
||||
containers.podman.podman_container_copy:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
src: "{{ playbook_dir }}/{{ file_name }}"
|
||||
dest: "/{{ file_name }}"
|
||||
container: "{{ container_name }}"
|
||||
|
||||
- name: Verify that the file exists in the container
|
||||
containers.podman.podman_container_exec:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
name: "{{ container_name }}"
|
||||
command: "cat /{{ file_name }}"
|
||||
|
||||
always:
|
||||
- name: Remove container
|
||||
containers.podman.podman_container:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
name: "{{ container_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove local file
|
||||
ansible.builtin.file:
|
||||
path: "{{ playbook_dir }}/{{ file_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Test podman container copy container-host
|
||||
block:
|
||||
- name: Generate random value for container name
|
||||
ansible.builtin.set_fact:
|
||||
container_name: "{{ 'ansible-test-podman-%0x' % ((2**32) | random) }}"
|
||||
file_name: sample_file
|
||||
|
||||
- name: Start container
|
||||
containers.podman.podman_container:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
name: "{{ container_name }}"
|
||||
image: alpine:3.7
|
||||
state: started
|
||||
command: sleep 1d
|
||||
|
||||
- name: Create file in the container for further copy
|
||||
containers.podman.podman_container_exec:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
name: "{{ container_name }}"
|
||||
command: sh -c 'echo "This file tests if container -> host copy is working" > /{{ file_name }}'
|
||||
|
||||
- name: Verify that the file exists in the container
|
||||
containers.podman.podman_container_exec:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
name: "{{ container_name }}"
|
||||
command: "cat /{{ file_name }}"
|
||||
|
||||
- name: Copy local file to containers root folder
|
||||
containers.podman.podman_container_copy:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
src: "/{{ file_name }}"
|
||||
dest: "{{ playbook_dir }}/{{ file_name }}"
|
||||
container: "{{ container_name }}"
|
||||
from_container: true
|
||||
|
||||
- name: Check file
|
||||
ansible.builtin.stat:
|
||||
path: "{{ playbook_dir }}/{{ file_name }}"
|
||||
register: copied_file
|
||||
|
||||
- name: Check it's present
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- copied_file.stat.exists
|
||||
|
||||
always:
|
||||
- name: Remove container
|
||||
containers.podman.podman_container:
|
||||
executable: "{{ test_executable | default('podman') }}"
|
||||
name: "{{ container_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove local file
|
||||
ansible.builtin.file:
|
||||
path: "{{ playbook_dir }}/{{ file_name }}"
|
||||
state: absent
|
||||
Loading…
Add table
Add a link
Reference in a new issue