Skip to content

Commit e4cd2c4

Browse files
authored
Adding volume import and export option (#617)
* Adding volume import and export option adding volume import and volume export to podman_import and podman_export Updating integration tests Signed-off-by: DilasserT <[email protected]> * Fixes and linting Signed-off-by: DilasserT <[email protected]> --------- Signed-off-by: DilasserT <[email protected]>
1 parent aeec6b9 commit e4cd2c4

File tree

4 files changed

+224
-9
lines changed

4 files changed

+224
-9
lines changed

plugins/modules/podman_export.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
description:
2525
- Container to export.
2626
type: str
27-
required: true
27+
volume:
28+
description:
29+
- Volume to export.
30+
type: str
2831
force:
2932
description:
3033
- Force saving to file even if it exists.
@@ -48,6 +51,9 @@
4851
- containers.podman.podman_export:
4952
dest: /path/to/tar/file
5053
container: container-name
54+
- containers.podman.podman_export:
55+
dest: /path/to/tar/file
56+
volume: volume-name
5157
'''
5258

5359
import os # noqa: E402
@@ -57,8 +63,16 @@
5763

5864
def export(module, executable):
5965
changed = False
60-
command = [executable, 'export']
61-
command += ['-o=%s' % module.params['dest'], module.params['container']]
66+
export_type = ''
67+
command = []
68+
if module.params['container']:
69+
export_type = 'container'
70+
command = [executable, 'export']
71+
else:
72+
export_type = 'volume'
73+
command = [executable, 'volume', 'export']
74+
75+
command += ['-o=%s' % module.params['dest'], module.params[export_type]]
6276
if module.params['force']:
6377
dest = module.params['dest']
6478
if os.path.exists(dest):
@@ -75,20 +89,27 @@ def export(module, executable):
7589
return changed, '', ''
7690
rc, out, err = module.run_command(command)
7791
if rc != 0:
78-
module.fail_json(msg="Error exporting container %s: %s" % (
79-
module.params['container'], err))
92+
module.fail_json(msg="Error exporting %s %s: %s" % (export_type,
93+
module.params['container'], err))
8094
return changed, out, err
8195

8296

8397
def main():
8498
module = AnsibleModule(
8599
argument_spec=dict(
86100
dest=dict(type='str', required=True),
87-
container=dict(type='str', required=True),
101+
container=dict(type='str'),
102+
volume=dict(type='str'),
88103
force=dict(type='bool', default=True),
89104
executable=dict(type='str', default='podman')
90105
),
91106
supports_check_mode=True,
107+
mutually_exclusive=[
108+
('container', 'volume'),
109+
],
110+
required_one_of=[
111+
('container', 'volume'),
112+
],
92113
)
93114

94115
executable = module.get_bin_path(module.params['executable'], required=True)

plugins/modules/podman_import.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
- Set changes as list of key-value pairs, see example.
3030
type: list
3131
elements: dict
32+
volume:
33+
description:
34+
- Volume to import, cannot be used with change and commit_message
35+
type: str
3236
executable:
3337
description:
3438
- Path to C(podman) executable if it is not in the C($PATH) on the
@@ -95,6 +99,9 @@
9599
- "CMD": /bin/bash
96100
- "User": root
97101
commit_message: "Importing image"
102+
- containers.podman.podman_import:
103+
src: /path/to/tar/file
104+
volume: myvolume
98105
'''
99106

100107
import json # noqa: E402
@@ -128,25 +135,55 @@ def load(module, executable):
128135
return changed, out, err, info, command
129136

130137

138+
def volume_load(module, executable):
139+
changed = True
140+
command = [executable, 'volume', 'import', module.params['volume'], module.params['src']]
141+
src = module.params['src']
142+
if module.check_mode:
143+
return changed, '', '', '', command
144+
rc, out, err = module.run_command(command)
145+
if rc != 0:
146+
module.fail_json(msg="Error importing volume %s: %s" % (src, err))
147+
rc, out2, err2 = module.run_command([executable, 'volume', 'inspect', module.params['volume']])
148+
if rc != 0:
149+
module.fail_json(msg="Volume %s inspection failed: %s" % (module.params['volume'], err2))
150+
try:
151+
info = json.loads(out2)[0]
152+
except Exception as e:
153+
module.fail_json(msg="Could not parse JSON from volume %s: %s" % (module.params['volume'], e))
154+
return changed, out, err, info, command
155+
156+
131157
def main():
132158
module = AnsibleModule(
133159
argument_spec=dict(
134160
src=dict(type='str', required=True),
135161
commit_message=dict(type='str'),
136162
change=dict(type='list', elements='dict'),
137-
executable=dict(type='str', default='podman')
163+
executable=dict(type='str', default='podman'),
164+
volume=dict(type='str', required=False),
138165
),
166+
mutually_exclusive=[
167+
('volume', 'commit_message'),
168+
('volume', 'change'),
169+
],
139170
supports_check_mode=True,
140171
)
141172

142173
executable = module.get_bin_path(module.params['executable'], required=True)
143-
changed, out, err, image_info, command = load(module, executable)
174+
volume_info = ''
175+
image_info = ''
176+
if module.params['volume']:
177+
changed, out, err, volume_info, command = volume_load(module, executable)
178+
else:
179+
changed, out, err, image_info, command = load(module, executable)
144180

145181
results = {
146182
"changed": changed,
147183
"stdout": out,
148184
"stderr": err,
149185
"image": image_info,
186+
"volume": volume_info,
150187
"podman_command": " ".join(command)
151188
}
152189

tests/integration/targets/podman_export/tasks/main.yml

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
- name: Test podman export
2+
- name: Test podman container export
33
block:
44
- name: Start container
55
containers.podman.podman_container:
@@ -69,3 +69,83 @@
6969
executable: "{{ test_executable | default('podman') }}"
7070
name: container
7171
state: absent
72+
73+
- name: Test podman volume export
74+
block:
75+
- name: Start container
76+
containers.podman.podman_container:
77+
executable: "{{ test_executable | default('podman') }}"
78+
name: container
79+
image: alpine:3.7
80+
state: started
81+
volume:
82+
- "volume:/test"
83+
command: sleep 1d
84+
85+
- name: Export volume
86+
containers.podman.podman_export:
87+
executable: "{{ test_executable | default('podman') }}"
88+
volume: volume
89+
dest: /tmp/volume
90+
91+
- name: Check file
92+
stat:
93+
path: /tmp/volume
94+
register: vlm
95+
96+
- name: Check it's exported
97+
assert:
98+
that:
99+
- vlm.stat.exists
100+
101+
- name: Import volume
102+
containers.podman.podman_import:
103+
executable: "{{ test_executable | default('podman') }}"
104+
src: /tmp/volume
105+
volume: "volume"
106+
register: volume
107+
108+
- name: Check it's imported
109+
assert:
110+
that:
111+
- volume is success
112+
113+
- name: Export volume without force
114+
containers.podman.podman_export:
115+
executable: "{{ test_executable | default('podman') }}"
116+
volume: volume
117+
dest: /tmp/volume
118+
force: false
119+
register: volume2
120+
121+
- name: Check it's exported
122+
assert:
123+
that:
124+
- volume2 is success
125+
- volume2 is not changed
126+
127+
- name: Export volume with force
128+
containers.podman.podman_export:
129+
executable: "{{ test_executable | default('podman') }}"
130+
volume: volume
131+
dest: /tmp/volume
132+
force: true
133+
register: volume3
134+
135+
- name: Check it's not exported
136+
assert:
137+
that:
138+
- volume3 is changed
139+
140+
always:
141+
- name: Remove container
142+
containers.podman.podman_container:
143+
executable: "{{ test_executable | default('podman') }}"
144+
name: container
145+
state: absent
146+
147+
- name: Remove volume
148+
containers.podman.podman_volume:
149+
executable: "{{ test_executable | default('podman') }}"
150+
name: test_volume
151+
state: absent

tests/integration/targets/podman_import/tasks/main.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,86 @@
6464
- test2.image.User == 'someuser'
6565
- test2.image["Config"]["Cmd"][2] == "/bin/nonsh"
6666

67+
- name: Test podman volume import
68+
block:
69+
- name: Start container
70+
containers.podman.podman_container:
71+
executable: "{{ test_executable | default('podman') }}"
72+
name: container
73+
image: alpine:3.7
74+
state: started
75+
volume:
76+
- "volume:/test"
77+
command: touch /test/test_file
78+
79+
- name: Export volume
80+
containers.podman.podman_export:
81+
executable: "{{ test_executable | default('podman') }}"
82+
volume: volume
83+
dest: /tmp/volume
84+
85+
- name: Check file
86+
stat:
87+
path: /tmp/volume
88+
register: vlm
89+
90+
- name: Check it's exported
91+
assert:
92+
that:
93+
- vlm.stat.exists
94+
95+
- name: delete container
96+
containers.podman.podman_container:
97+
state: absent
98+
name: container
99+
100+
- name: delete volume
101+
containers.podman.podman_volume:
102+
state: absent
103+
name: volume
104+
105+
# podman needs a volume to exist before import
106+
- name: creating volume before importing
107+
containers.podman.podman_volume:
108+
name: volume
109+
state: present
110+
111+
- name: Import volume
112+
containers.podman.podman_import:
113+
executable: "{{ test_executable | default('podman') }}"
114+
src: /tmp/volume
115+
volume: "volume"
116+
register: volume
117+
118+
- name: Check it's imported
119+
assert:
120+
that:
121+
- volume is success
122+
123+
- name: Check file is there
124+
containers.podman.podman_container:
125+
executable: "{{ test_executable | default('podman') }}"
126+
name: container
127+
image: alpine:3.7
128+
state: started
129+
volume:
130+
- "volume:/test"
131+
command: ls /test/test_file
132+
register: ls
133+
134+
- name: Check it's imported
135+
assert:
136+
that:
137+
- ls is success
138+
67139
always:
68140
- name: Remove container
69141
containers.podman.podman_container:
70142
executable: "{{ test_executable | default('podman') }}"
71143
name: container
72144
state: absent
145+
- name: Remove volume
146+
containers.podman.podman_volume:
147+
executable: "{{ test_executable | default('podman') }}"
148+
name: volume
149+
state: absent

0 commit comments

Comments
 (0)