Skip to content

Commit 0bc5e04

Browse files
committed
added podman-prune module
1 parent 877581e commit 0bc5e04

File tree

1 file changed

+293
-0
lines changed

1 file changed

+293
-0
lines changed

plugins/modules/podman_prune.py

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
4+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5+
# Copyright (c) 2023, Roberto Alfieri <[email protected]>
6+
7+
from __future__ import absolute_import, division, print_function
8+
__metaclass__ = type
9+
10+
DOCUMENTATION = r"""
11+
module: podman_prune
12+
author:
13+
- "Roberto Alfieri (@rebtoor)"
14+
version_added: '1.10.0'
15+
short_description: Allows to prune various podman objects
16+
notes: []
17+
description:
18+
- Allows to run C(podman container prune), C(podman image prune), C(podman network prune), C(podman volume prune) and C(podman system prune)
19+
requirements:
20+
- "Podman installed on host"
21+
options:
22+
executable:
23+
description:
24+
- Podman binary.
25+
type: str
26+
default: podman
27+
container:
28+
description:
29+
- Whether to prune containers.
30+
type: bool
31+
default: false
32+
container_filters:
33+
description:
34+
- A dictionary of filter values used for selecting containers to delete.
35+
- "For example, C(until: 24h)."
36+
- See L(the podman documentation, https://docs.podman.io/en/latest/markdown/podman-container-prune.1.html#filter-filters)
37+
for more information on possible filters.
38+
type: dict
39+
image:
40+
description:
41+
- Whether to prune images.
42+
type: bool
43+
default: false
44+
image_filters:
45+
description:
46+
- A dictionary of filter values used for selecting images to delete.
47+
- "For example, C(dangling: true)."
48+
- See L(the podman documentation,https://docs.podman.io/en/latest/markdown/podman-image-prune.1.html#filter-filters)
49+
for more information on possible filters.
50+
type: dict
51+
network:
52+
description:
53+
- Whether to prune networks.
54+
type: bool
55+
default: false
56+
network_filters:
57+
description:
58+
- A dictionary of filter values used for selecting networks to delete.
59+
- See L(the podman documentation,https://docs.podman.io/en/latest/markdown/podman-network-prune.1.html#filter)
60+
for more information on possible filters.
61+
type: dict
62+
system:
63+
description:
64+
- Wheter to prune unused pods, containers, image, networks and volume data
65+
type: bool
66+
default: false
67+
system_all:
68+
description:
69+
- Wheter to prune all unused images, not only dangling images.
70+
type: bool
71+
default: false
72+
system_volumes:
73+
description:
74+
- Wheter to prune volumes currently unused by any container.
75+
type: bool
76+
default: false
77+
volume:
78+
description:
79+
- Whether to prune volumes.
80+
type: bool
81+
default: false
82+
volume_filters:
83+
description:
84+
- A dictionary of filter values used for selecting volumes to delete.
85+
- See L(the podman documentation,https://docs.podman.io/en/latest/markdown/podman-volume-prune.1.html#filter)
86+
for more information on possible filters.
87+
type: dict
88+
"""
89+
90+
EXAMPLES = r"""
91+
- name: Prune containers older than 24h
92+
containers.podman.podman_prune:
93+
containers: true
94+
containers_filters:
95+
# only consider containers created more than 24 hours ago
96+
until: 24h
97+
98+
- name: Prune everything
99+
containers.podman.podman_prune:
100+
system: true
101+
102+
- name: Prune everything (including non-dangling images)
103+
containers.podman.podman_prune:
104+
system: true
105+
system_all: true
106+
system_volumes: true
107+
"""
108+
109+
RETURN = r"""
110+
# containers
111+
containers:
112+
description:
113+
- List of IDs of deleted containers.
114+
returned: I(containers) is C(true)
115+
type: list
116+
elements: str
117+
sample: []
118+
119+
# images
120+
images:
121+
description:
122+
- List of IDs of deleted images.
123+
returned: I(images) is C(true)
124+
type: list
125+
elements: str
126+
sample: []
127+
128+
# networks
129+
networks:
130+
description:
131+
- List of IDs of deleted networks.
132+
returned: I(networks) is C(true)
133+
type: list
134+
elements: str
135+
sample: []
136+
137+
# volumes
138+
volumes:
139+
description:
140+
- List of IDs of deleted volumes.
141+
returned: I(volumes) is C(true)
142+
type: list
143+
elements: str
144+
sample: []
145+
146+
# system
147+
system:
148+
description:
149+
- List of ID of deleted containers, volumes, images, network and total reclaimed space
150+
returned: I(system) is C(true)
151+
type: list
152+
elements: str
153+
sample: []
154+
"""
155+
156+
157+
from ansible.module_utils.basic import AnsibleModule
158+
159+
160+
def podmanExec(module, target, filters, executable):
161+
changed = False
162+
command = [executable, target, 'prune', '--force']
163+
if filters != "" and target != "system":
164+
command.append("--filter=")
165+
command.append(filters)
166+
if filters != "" and target == "system":
167+
split_filters = filters.strip().split(" ")
168+
for filter in split_filters:
169+
if filter:
170+
command.append(filter)
171+
rc, out, err = module.run_command(command)
172+
if out:
173+
changed = True
174+
if rc != 0:
175+
module.fail_json(
176+
msg="Error executing prune on {}: {}".format(target, err))
177+
return changed, out, err
178+
179+
180+
def run_module():
181+
module_args = dict(
182+
container=dict(type='bool', default=False),
183+
container_filters=dict(type='dict'),
184+
image=dict(type='bool', default=False),
185+
image_filters=dict(type='dict'),
186+
network=dict(type='bool', default=False),
187+
network_filters=dict(type='dict'),
188+
volume=dict(type='bool', default=False),
189+
volume_filters=dict(type='dict'),
190+
system=dict(type='bool', default=False),
191+
system_all=dict(type='bool', default=False),
192+
system_volumes=dict(type='bool', default=False),
193+
executable=dict(type='str', default='podman')
194+
)
195+
196+
module = AnsibleModule(
197+
argument_spec=module_args
198+
)
199+
200+
executable = module.get_bin_path(
201+
module.params['executable'], required=True)
202+
203+
if module.params["container"]:
204+
target = "container"
205+
if not module.params["container_filters"]:
206+
filters = ""
207+
else:
208+
filters = module.params["container_filters"]
209+
changed, out, err = podmanExec(module, target, filters, executable)
210+
if not out:
211+
containers = []
212+
else:
213+
containers = out.rstrip().split("\n")
214+
results = dict(
215+
changed=changed,
216+
containers=containers,
217+
stderr=err
218+
)
219+
220+
if module.params["network"]:
221+
target = "network"
222+
if not module.params["network_filters"]:
223+
filters = ""
224+
else:
225+
filters = module.params["network_filters"]
226+
changed, out, err = podmanExec(module, target, filters, executable)
227+
if not out:
228+
networks = []
229+
else:
230+
networks = out.rstrip().split("\n")
231+
results = dict(
232+
changed=changed,
233+
networks=networks,
234+
stderr=err
235+
)
236+
237+
if module.params["image"]:
238+
target = "image"
239+
if not module.params["image_filters"]:
240+
filters = ""
241+
else:
242+
filters = module.params["image_filters"]
243+
changed, out, err = podmanExec(module, target, filters, executable)
244+
results = dict(
245+
changed=changed,
246+
stdout=out,
247+
stderr=err
248+
)
249+
250+
if module.params["volume"]:
251+
target = "volume"
252+
if not module.params["volume_filters"]:
253+
filters = ""
254+
else:
255+
filters = module.params["volume_filters"]
256+
changed, out, err = podmanExec(module, target, filters, executable)
257+
if not out:
258+
volumes = []
259+
else:
260+
volumes = out.rstrip().split("\n")
261+
results = dict(
262+
changed=changed,
263+
volumes=volumes,
264+
stderr=err
265+
)
266+
267+
if module.params["system"]:
268+
target = "system"
269+
filters = str()
270+
271+
if module.params["system_all"]:
272+
filters = " ".join([filters, "--all"])
273+
274+
if module.params["system_volumes"]:
275+
filters = " ".join([filters, "--volumes"])
276+
277+
changed, out, err = podmanExec(module, target, filters, executable)
278+
279+
results = dict(
280+
changed=changed,
281+
stdout=out,
282+
stderr=err
283+
)
284+
285+
module.exit_json(**results)
286+
287+
288+
def main():
289+
run_module()
290+
291+
292+
if __name__ == '__main__':
293+
main()

0 commit comments

Comments
 (0)