summaryrefslogtreecommitdiffstats
path: root/ansible_collections/containers/podman/plugins/modules/podman_save.py
blob: e23f310213dadc9e681f9bd81124f881ce47ece7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/python
# coding: utf-8 -*-

# Copyright (c) 2020, Sagi Shnaidman <sshnaidm@redhat.com>
# 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_save
short_description: Saves podman image to tar file
author: Sagi Shnaidman (@sshnaidm)
description:
  - podman save saves an image to either docker-archive, oci-archive, oci-dir
    (directory with oci manifest type), or docker-dir (directory with v2s2 manifest type)
    on the local machine, default is docker-archive.

options:
  image:
    description:
    - Image to save.
    type: list
    elements: str
    required: true
  compress:
    description:
    - Compress tarball image layers when pushing to a directory using the 'dir' transport.
      (default is same compression type, compressed or uncompressed, as source)
    type: bool
  dest:
    description:
    - Destination file to write image to.
    type: str
    required: true
    aliases:
      - path
  format:
    description:
    - Save image to docker-archive, oci-archive (see containers-transports(5)), oci-dir
      (oci transport), or docker-dir (dir transport with v2s2 manifest type).
    type: str
    choices:
    - docker-archive
    - oci-archive
    - oci-dir
    - docker-dir
  multi_image_archive:
    description:
    - Allow for creating archives with more than one image. Additional names will be
      interpreted as images instead of tags. Only supported for docker-archive.
    type: bool
  force:
    description:
    - Force saving to file even if it exists.
    type: bool
    default: True
  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_save:
    image: nginx
    dest: /tmp/file123.tar
- containers.podman.podman_save:
    image:
      - nginx
      - fedora
    dest: /tmp/file456.tar
    multi_image_archive: true
'''

import os  # noqa: E402
from ansible.module_utils.basic import AnsibleModule  # noqa: E402
from ..module_utils.podman.common import remove_file_or_dir  # noqa: E402


def save(module, executable):
    changed = False
    command = [executable, 'save']
    cmd_args = {
        'compress': ['--compress'],
        'dest': ['-o=%s' % module.params['dest']],
        'format': ['--format=%s' % module.params['format']],
        'multi_image_archive': ['--multi-image-archive'],
    }
    for param in module.params:
        if module.params[param] is not None and param in cmd_args:
            command += cmd_args[param]
    for img in module.params['image']:
        command.append(img)
    if module.params['force']:
        dest = module.params['dest']
        if os.path.exists(dest):
            changed = True
            if module.check_mode:
                return changed, '', ''
            try:
                remove_file_or_dir(dest)
            except Exception as e:
                module.fail_json(msg="Error deleting %s path: %s" % (dest, e))
    else:
        changed = not os.path.exists(module.params['dest'])
    if module.check_mode:
        return changed, '', ''
    rc, out, err = module.run_command(command)
    if rc != 0:
        module.fail_json(msg="Error: %s" % (err))
    return changed, out, err


def main():
    module = AnsibleModule(
        argument_spec=dict(
            image=dict(type='list', elements='str', required=True),
            compress=dict(type='bool'),
            dest=dict(type='str', required=True, aliases=['path']),
            format=dict(type='str', choices=['docker-archive', 'oci-archive', 'oci-dir', 'docker-dir']),
            multi_image_archive=dict(type='bool'),
            force=dict(type='bool', default=True),
            executable=dict(type='str', default='podman')
        ),
        supports_check_mode=True,
    )
    if module.params['compress'] and module.params['format'] not in ['oci-dir', 'docker-dir']:
        module.fail_json(msg="Compression is only supported for oci-dir and docker-dir format")

    executable = module.get_bin_path(module.params['executable'], required=True)
    changed, out, err = save(module, executable)

    results = {
        "changed": changed,
        "stdout": out,
        "stderr": err,
    }

    module.exit_json(**results)


if __name__ == '__main__':
    main()