4
4
as inventory directly.
5
5
"""
6
6
7
+ from __future__ import annotations
8
+
7
9
from pyinfra import host
8
10
from pyinfra .api import operation
9
- from pyinfra .facts .docker import DockerContainer , DockerNetwork , DockerVolume
11
+ from pyinfra .facts .docker import DockerContainer , DockerNetwork , DockerPlugin , DockerVolume
10
12
11
13
from .util .docker import ContainerSpec , handle_docker
12
14
13
15
14
16
@operation ()
15
17
def container (
16
- container ,
17
- image = "" ,
18
- ports = None ,
19
- networks = None ,
20
- volumes = None ,
21
- env_vars = None ,
22
- pull_always = False ,
23
- present = True ,
24
- force = False ,
25
- start = True ,
18
+ container : str ,
19
+ image : str = "" ,
20
+ ports : list [ str ] | None = None ,
21
+ networks : list [ str ] | None = None ,
22
+ volumes : list [ str ] | None = None ,
23
+ env_vars : list [ str ] | None = None ,
24
+ pull_always : bool = False ,
25
+ present : bool = True ,
26
+ force : bool = False ,
27
+ start : bool = True ,
26
28
):
27
29
"""
28
30
Manage Docker containers
@@ -168,7 +170,7 @@ def image(image, present=True):
168
170
169
171
170
172
@operation ()
171
- def volume (volume , driver = "" , labels = None , present = True ):
173
+ def volume (volume : str , driver : str = "" , labels : list [ str ] | None = None , present : bool = True ):
172
174
"""
173
175
Manage Docker volumes
174
176
@@ -220,20 +222,20 @@ def volume(volume, driver="", labels=None, present=True):
220
222
221
223
@operation ()
222
224
def network (
223
- network ,
224
- driver = "" ,
225
- gateway = "" ,
226
- ip_range = "" ,
227
- ipam_driver = "" ,
228
- subnet = "" ,
229
- scope = "" ,
230
- aux_addresses = None ,
231
- opts = None ,
232
- ipam_opts = None ,
233
- labels = None ,
234
- ingress = False ,
235
- attachable = False ,
236
- present = True ,
225
+ network : str ,
226
+ driver : str = "" ,
227
+ gateway : str = "" ,
228
+ ip_range : str = "" ,
229
+ ipam_driver : str = "" ,
230
+ subnet : str = "" ,
231
+ scope : str = "" ,
232
+ aux_addresses : dict [ str , str ] | None = None ,
233
+ opts : list [ str ] | None = None ,
234
+ ipam_opts : list [ str ] | None = None ,
235
+ labels : list [ str ] | None = None ,
236
+ ingress : bool = False ,
237
+ attachable : bool = False ,
238
+ present : bool = True ,
237
239
):
238
240
"""
239
241
Manage docker networks
@@ -245,6 +247,7 @@ def network(
245
247
+ ipam_driver: IP Address Management Driver
246
248
+ subnet: Subnet in CIDR format that represents a network segment
247
249
+ scope: Control the network's scope
250
+ + aux_addresses: named aux addresses for the network
248
251
+ opts: Set driver specific options
249
252
+ ipam_opts: Set IPAM driver specific options
250
253
+ labels: Label list to attach in the network
@@ -303,9 +306,9 @@ def network(
303
306
304
307
@operation (is_idempotent = False )
305
308
def prune (
306
- all = False ,
307
- volumes = False ,
308
- filter = "" ,
309
+ all : bool = False ,
310
+ volumes : bool = False ,
311
+ filter : str = "" ,
309
312
):
310
313
"""
311
314
Execute a docker system prune.
@@ -344,3 +347,101 @@ def prune(
344
347
volumes = volumes ,
345
348
filter = filter ,
346
349
)
350
+
351
+
352
+ @operation ()
353
+ def plugin (
354
+ plugin : str ,
355
+ alias : str | None = None ,
356
+ present : bool = True ,
357
+ enabled : bool = True ,
358
+ plugin_options : dict [str , str ] | None = None ,
359
+ ):
360
+ """
361
+ Manage Docker plugins
362
+
363
+ + plugin: Plugin name
364
+ + alias: Alias for the plugin (optional)
365
+ + present: Whether the plugin should be installed
366
+ + enabled: Whether the plugin should be enabled
367
+ + plugin_options: Options to pass to the plugin
368
+
369
+ **Examples:**
370
+
371
+ .. code:: python
372
+
373
+ # Install and enable a Docker plugin
374
+ docker.plugin(
375
+ name="Install and enable a Docker plugin",
376
+ plugin="username/my-awesome-plugin:latest",
377
+ alias="my-plugin",
378
+ present=True,
379
+ enabled=True,
380
+ plugin_options={"option1": "value1", "option2": "value2"},
381
+ )
382
+ """
383
+ plugin_name = alias if alias else plugin
384
+ existent_plugin = host .get_fact (DockerPlugin , object_id = plugin_name )
385
+ if existent_plugin :
386
+ existent_plugin = existent_plugin [0 ]
387
+
388
+ if present :
389
+ if existent_plugin :
390
+ plugin_options_different = (
391
+ plugin_options and existent_plugin ["Settings" ]["Env" ] != plugin_options
392
+ )
393
+ if plugin_options_different :
394
+ # Update options on existing plugin
395
+ if existent_plugin ["Enabled" ]:
396
+ yield handle_docker (
397
+ resource = "plugin" ,
398
+ command = "disable" ,
399
+ plugin = plugin_name ,
400
+ )
401
+ yield handle_docker (
402
+ resource = "plugin" ,
403
+ command = "set" ,
404
+ plugin = plugin_name ,
405
+ enabled = enabled ,
406
+ existent_options = existent_plugin ["Settings" ]["Env" ],
407
+ required_options = plugin_options ,
408
+ )
409
+ if enabled :
410
+ yield handle_docker (
411
+ resource = "plugin" ,
412
+ command = "enable" ,
413
+ plugin = plugin_name ,
414
+ )
415
+ else :
416
+ # Options are the same, check if enabled state is different
417
+ if existent_plugin ["Enabled" ] == enabled :
418
+ host .noop (
419
+ f"Plugin '{ plugin_name } ' is already installed with the same options "
420
+ f"and { 'enabled' if enabled else 'disabled' } ."
421
+ )
422
+ return
423
+ else :
424
+ command = "enable" if enabled else "disable"
425
+ yield handle_docker (
426
+ resource = "plugin" ,
427
+ command = command ,
428
+ plugin = plugin_name ,
429
+ )
430
+ else :
431
+ yield handle_docker (
432
+ resource = "plugin" ,
433
+ command = "install" ,
434
+ plugin = plugin ,
435
+ alias = alias ,
436
+ enabled = enabled ,
437
+ plugin_options = plugin_options ,
438
+ )
439
+ else :
440
+ if not existent_plugin :
441
+ host .noop (f"Plugin '{ plugin_name } ' is not installed." )
442
+ return
443
+ yield handle_docker (
444
+ resource = "plugin" ,
445
+ command = "remove" ,
446
+ plugin = plugin_name ,
447
+ )
0 commit comments