forked from containers/ansible-podman-collections
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
- hosts: all | ||
gather_facts: true | ||
tasks: | ||
- include_role: | ||
name: podman_copy | ||
vars: | ||
ansible_python_interpreter: "{{ _ansible_python_interpreter }}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
#!/usr/bin/python | ||
# coding: utf-8 -*- | ||
|
||
# Copyright (c) 2021, Sagi Shnaidman <[email protected]> | ||
# 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_copy | ||
short_description: Copy from/to containers | ||
author: Thomas Dilasser (@DilasserT) | ||
description: | ||
- podman copies files from/to the container from/to the local machine. | ||
options: | ||
path: | ||
description: | ||
- Filesystem path. | ||
type: str | ||
required: true | ||
container_path: | ||
description: | ||
- Path inside the container | ||
type: str | ||
required: true | ||
into_container: | ||
description: | ||
- Copy in the container. | ||
type: bool | ||
from_container: | ||
description: | ||
- Copy from the container. | ||
type: bool | ||
container: | ||
description: | ||
- container name. | ||
type: str | ||
required: true | ||
force: | ||
description: | ||
- Overwrite file if it exists. | ||
type: bool | ||
default: false | ||
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 | ||
requirements: | ||
- "Podman installed on host" | ||
''' | ||
|
||
RETURN = ''' | ||
''' | ||
|
||
EXAMPLES = ''' | ||
# What modules does for example | ||
- containers.podman.podman_copy: | ||
path: /path/to/file | ||
container_path: /path/to/file/in/container | ||
container: container-name | ||
from_container: true | ||
- containers.podman.podman_copy: | ||
path: /path/to/file | ||
container_path: /path/to/file/in/container | ||
container: container-name | ||
into_container: true | ||
''' | ||
|
||
import os # noqa: E402 | ||
import json | ||
from ansible.module_utils.basic import AnsibleModule # noqa: E402 | ||
|
||
|
||
def copy(module, executable): | ||
changed = True | ||
command = [executable, 'cp'] | ||
container_name = module.params['container'] | ||
if module.params['into_container']: | ||
command += [module.params['path']] | ||
command += [module.params['container'] + ":" + module.params['container_path']] | ||
command_inspect = [executable, 'container', 'inspect'] | ||
command_inspect.extend([container_name]) | ||
rc, out, err = module.run_command(command_inspect) | ||
if rc != 0: | ||
module.fail_json(msg="Unable to gather info for %s: %s" % (",".join(module.params['container']), err)) | ||
else: | ||
json_out = json.loads(out) if out else None | ||
if json_out is None: | ||
module.fail_json(msg="Unable to gather info for %s: %s" % (",".join(module.params['container']), err)) | ||
|
||
full_path = json_out[0]['GraphDriver']['Data']['MergedDir'] | ||
if module.params['path'][0] == "/": | ||
full_path += module.params['container_path'] | ||
else: | ||
full_path += "/" | ||
full_path += module.params['container_path'] | ||
|
||
if os.path.exists(full_path) and not module.params['force']: | ||
changed = False | ||
return changed, '', '' | ||
|
||
else: | ||
command += [module.params['container'] + ":" + module.params['container_path']] | ||
command += [module.params['path']] | ||
if os.path.exists(module.params['path']) and not module.params['force']: | ||
changed = False | ||
return changed, '', '' | ||
|
||
rc, out, err = module.run_command(command) | ||
if rc != 0: | ||
module.fail_json(msg="Error during copy %s: %s" % ( | ||
module.params['container'], err)) | ||
return changed, out, err | ||
|
||
|
||
def main(): | ||
module = AnsibleModule( | ||
argument_spec=dict( | ||
path=dict(type='str', required=True), | ||
container_path=dict(type='str', required=True), | ||
container=dict(type='str', required=True), | ||
into_container=dict(type='bool'), | ||
from_container=dict(type='bool'), | ||
force=dict(type='bool', default=False), | ||
executable=dict(type='str', default='podman') | ||
), | ||
supports_check_mode=True, | ||
mutually_exclusive=[ | ||
('from_container', 'into_container'), | ||
], | ||
required_one_of=[ | ||
('from_container', 'into_container'), | ||
], | ||
) | ||
|
||
executable = module.get_bin_path(module.params['executable'], required=True) | ||
changed, out, err = copy(module, executable) | ||
|
||
results = { | ||
"changed": changed, | ||
"stdout": out, | ||
"stderr": err, | ||
} | ||
module.exit_json(**results) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
--- | ||
- name: Test podman copy | ||
block: | ||
- name: run container | ||
containers.podman.podman_container: | ||
name: container | ||
image: alpine:3.7 | ||
state: started | ||
command: sleep 1d | ||
|
||
- name: Create test file | ||
file: | ||
path: /tmp/podman_copy.txt | ||
state: touch | ||
|
||
- name: Get container info | ||
containers.podman.podman_container_info: | ||
name: container | ||
register: cntr_info | ||
|
||
- name: Copy into container | ||
containers.podman.podman_copy: | ||
path: '/tmp/podman_copy.txt' | ||
container_path: '/podman_copy.txt' | ||
container: container | ||
into_container: true | ||
register: copy1 | ||
|
||
- name: Check first copy | ||
assert: | ||
that: | ||
- copy1 is success | ||
- copy1 is changed | ||
|
||
- name: Stat file in container | ||
stat: | ||
path: "{{ cntr_info['containers'][0]['GraphDriver']['Data']['MergedDir'] }}/podman_copy.txt" | ||
register: file_check | ||
|
||
- name: Check file is in container | ||
assert: | ||
that: | ||
- file_check.stat.islnk is defined | ||
|
||
- name: Check file in container | ||
assert: | ||
that: | ||
- copy1 is success | ||
|
||
- name: Copy into container without force | ||
containers.podman.podman_copy: | ||
path: '/tmp/podman_copy.txt' | ||
container_path: '/podman_copy.txt' | ||
container: container | ||
into_container: true | ||
register: copy2 | ||
|
||
- name: Check second copy | ||
assert: | ||
that: | ||
- copy2 is success | ||
- copy2 is not changed | ||
|
||
- name: Copy into container (forced) | ||
containers.podman.podman_copy: | ||
path: '/tmp/podman_copy.txt' | ||
container_path: '/podman_copy.txt' | ||
container: container | ||
force: true | ||
into_container: true | ||
register: copy3 | ||
|
||
- name: Check third copy | ||
assert: | ||
that: | ||
- copy3 is success | ||
- copy3 is changed | ||
|
||
- name: Copy from container | ||
containers.podman.podman_copy: | ||
path: '/tmp/podman_copy_from.txt' | ||
container_path: '/podman_copy.txt' | ||
container: container | ||
from_container: true | ||
register: copy4 | ||
|
||
- name: Stat file in /tmp | ||
stat: | ||
path: "/tmp/podman_copy_from.txt" | ||
register: file_check | ||
|
||
- name: Check file is in container | ||
assert: | ||
that: | ||
- file_check.stat.islnk is defined | ||
|
||
- name: Check file in container | ||
assert: | ||
that: | ||
- copy1 is success | ||
|
||
- name: Check fourth copy | ||
assert: | ||
that: | ||
- copy4 is success | ||
- copy4 is changed | ||
|
||
- name: Copy from container without force | ||
containers.podman.podman_copy: | ||
path: '/tmp/podman_copy_from.txt' | ||
container_path: '/podman_copy.txt' | ||
container: container | ||
from_container: true | ||
register: copy5 | ||
|
||
- name: Check fifth copy | ||
assert: | ||
that: | ||
- copy5 is success | ||
- copy5 is not changed | ||
|
||
- name: Copy from container (forced) | ||
containers.podman.podman_copy: | ||
path: '/tmp/podman_copy_from.txt' | ||
container_path: '/podman_copy.txt' | ||
container: container | ||
force: true | ||
from_container: true | ||
register: copy6 | ||
|
||
- name: Check sixth copy | ||
assert: | ||
that: | ||
- copy6 is success | ||
- copy6 is changed | ||
|
||
always: | ||
- name: stop container | ||
containers.podman.podman_container: | ||
state: absent | ||
name: container | ||
- name: Clean up test file | ||
file: | ||
path: /tmp/podman_copy.txt | ||
state: absent | ||
- name: Clean up test file | ||
file: | ||
path: /tmp/podman_copy_from.txt | ||
state: absent |