@procedures/docker 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +40 -3
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/index.d.ts +3 -3
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/module.d.ts +4 -1
  9. package/dist/module.d.ts.map +1 -1
  10. package/dist/module.js +252 -1
  11. package/dist/module.js.map +1 -1
  12. package/dist/procedures/docker/compose/build.d.ts +12 -0
  13. package/dist/procedures/docker/compose/build.d.ts.map +1 -0
  14. package/dist/procedures/docker/compose/build.js +22 -0
  15. package/dist/procedures/docker/compose/build.js.map +1 -0
  16. package/dist/procedures/docker/compose/logs.d.ts +13 -0
  17. package/dist/procedures/docker/compose/logs.d.ts.map +1 -0
  18. package/dist/procedures/docker/compose/logs.js +23 -0
  19. package/dist/procedures/docker/compose/logs.js.map +1 -0
  20. package/dist/procedures/docker/compose/ps.d.ts +12 -0
  21. package/dist/procedures/docker/compose/ps.d.ts.map +1 -0
  22. package/dist/procedures/docker/compose/ps.js +19 -0
  23. package/dist/procedures/docker/compose/ps.js.map +1 -0
  24. package/dist/procedures/docker/compose/restart.d.ts +12 -0
  25. package/dist/procedures/docker/compose/restart.d.ts.map +1 -0
  26. package/dist/procedures/docker/compose/restart.js +17 -0
  27. package/dist/procedures/docker/compose/restart.js.map +1 -0
  28. package/dist/procedures/docker/exec.d.ts.map +1 -1
  29. package/dist/procedures/docker/exec.js +7 -2
  30. package/dist/procedures/docker/exec.js.map +1 -1
  31. package/dist/procedures/docker/images.d.ts +12 -0
  32. package/dist/procedures/docker/images.d.ts.map +1 -0
  33. package/dist/procedures/docker/images.js +22 -0
  34. package/dist/procedures/docker/images.js.map +1 -0
  35. package/dist/procedures/docker/index.d.ts +15 -0
  36. package/dist/procedures/docker/index.d.ts.map +1 -1
  37. package/dist/procedures/docker/index.js +15 -0
  38. package/dist/procedures/docker/index.js.map +1 -1
  39. package/dist/procedures/docker/inspect.d.ts +13 -0
  40. package/dist/procedures/docker/inspect.d.ts.map +1 -0
  41. package/dist/procedures/docker/inspect.js +30 -0
  42. package/dist/procedures/docker/inspect.js.map +1 -0
  43. package/dist/procedures/docker/network/create.d.ts +13 -0
  44. package/dist/procedures/docker/network/create.d.ts.map +1 -0
  45. package/dist/procedures/docker/network/create.js +21 -0
  46. package/dist/procedures/docker/network/create.js.map +1 -0
  47. package/dist/procedures/docker/network/list.d.ts +12 -0
  48. package/dist/procedures/docker/network/list.d.ts.map +1 -0
  49. package/dist/procedures/docker/network/list.js +18 -0
  50. package/dist/procedures/docker/network/list.js.map +1 -0
  51. package/dist/procedures/docker/network/remove.d.ts +12 -0
  52. package/dist/procedures/docker/network/remove.d.ts.map +1 -0
  53. package/dist/procedures/docker/network/remove.js +14 -0
  54. package/dist/procedures/docker/network/remove.js.map +1 -0
  55. package/dist/procedures/docker/prune.d.ts +14 -0
  56. package/dist/procedures/docker/prune.d.ts.map +1 -0
  57. package/dist/procedures/docker/prune.js +30 -0
  58. package/dist/procedures/docker/prune.js.map +1 -0
  59. package/dist/procedures/docker/push.d.ts +13 -0
  60. package/dist/procedures/docker/push.d.ts.map +1 -0
  61. package/dist/procedures/docker/push.js +18 -0
  62. package/dist/procedures/docker/push.js.map +1 -0
  63. package/dist/procedures/docker/run.d.ts.map +1 -1
  64. package/dist/procedures/docker/run.js +3 -5
  65. package/dist/procedures/docker/run.js.map +1 -1
  66. package/dist/procedures/docker/shared.d.ts +16 -0
  67. package/dist/procedures/docker/shared.d.ts.map +1 -1
  68. package/dist/procedures/docker/shared.js +24 -0
  69. package/dist/procedures/docker/shared.js.map +1 -1
  70. package/dist/procedures/docker/tag.d.ts +12 -0
  71. package/dist/procedures/docker/tag.d.ts.map +1 -0
  72. package/dist/procedures/docker/tag.js +14 -0
  73. package/dist/procedures/docker/tag.js.map +1 -0
  74. package/dist/procedures/docker/volume/create.d.ts +13 -0
  75. package/dist/procedures/docker/volume/create.d.ts.map +1 -0
  76. package/dist/procedures/docker/volume/create.js +20 -0
  77. package/dist/procedures/docker/volume/create.js.map +1 -0
  78. package/dist/procedures/docker/volume/list.d.ts +12 -0
  79. package/dist/procedures/docker/volume/list.d.ts.map +1 -0
  80. package/dist/procedures/docker/volume/list.js +18 -0
  81. package/dist/procedures/docker/volume/list.js.map +1 -0
  82. package/dist/procedures/docker/volume/remove.d.ts +13 -0
  83. package/dist/procedures/docker/volume/remove.d.ts.map +1 -0
  84. package/dist/procedures/docker/volume/remove.js +18 -0
  85. package/dist/procedures/docker/volume/remove.js.map +1 -0
  86. package/dist/types.d.ts +170 -1
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js +180 -4
  89. package/dist/types.js.map +1 -1
  90. package/package.json +4 -4
  91. package/src/index.ts +46 -0
  92. package/src/module.ts +329 -1
  93. package/src/procedures/docker/compose/build.ts +23 -0
  94. package/src/procedures/docker/compose/logs.ts +23 -0
  95. package/src/procedures/docker/compose/ps.ts +20 -0
  96. package/src/procedures/docker/compose/restart.ts +19 -0
  97. package/src/procedures/docker/exec.ts +7 -2
  98. package/src/procedures/docker/images.ts +21 -0
  99. package/src/procedures/docker/index.ts +15 -0
  100. package/src/procedures/docker/inspect.ts +31 -0
  101. package/src/procedures/docker/network/create.ts +22 -0
  102. package/src/procedures/docker/network/list.ts +19 -0
  103. package/src/procedures/docker/network/remove.ts +17 -0
  104. package/src/procedures/docker/prune.ts +30 -0
  105. package/src/procedures/docker/push.ts +20 -0
  106. package/src/procedures/docker/run.ts +3 -5
  107. package/src/procedures/docker/shared.ts +28 -0
  108. package/src/procedures/docker/tag.ts +17 -0
  109. package/src/procedures/docker/volume/create.ts +21 -0
  110. package/src/procedures/docker/volume/list.ts +19 -0
  111. package/src/procedures/docker/volume/remove.ts +20 -0
  112. package/src/types.ts +360 -5
package/src/module.ts CHANGED
@@ -4,7 +4,10 @@
4
4
  * Procedure Registration for Docker operations
5
5
  *
6
6
  * Provides docker.run, docker.build, docker.pull, docker.exec, docker.stop,
7
- * docker.rm, docker.ps, docker.logs, docker.compose.up, docker.compose.down procedures.
7
+ * docker.rm, docker.ps, docker.logs, docker.compose.up, docker.compose.down procedures, and since
8
+ * roadmap R41 docker.compose.ps/logs/build/restart, docker.images, docker.inspect,
9
+ * docker.volume.list/create/remove, docker.network.list/create/remove, docker.tag, docker.push
10
+ * and docker.prune.
8
11
  */
9
12
 
10
13
 
@@ -49,6 +52,83 @@ import {
49
52
  DockerLogsOutputSchema,
50
53
  } from "./types.js";
51
54
  import type { ProcedureContext } from "@procedures/client";
55
+ import { dockerComposePs } from "./procedures/docker/compose/ps.js";
56
+ import { dockerComposeLogs } from "./procedures/docker/compose/logs.js";
57
+ import { dockerComposeBuild } from "./procedures/docker/compose/build.js";
58
+ import { dockerComposeRestart } from "./procedures/docker/compose/restart.js";
59
+ import { dockerImages } from "./procedures/docker/images.js";
60
+ import { dockerInspect } from "./procedures/docker/inspect.js";
61
+ import { dockerVolumeList } from "./procedures/docker/volume/list.js";
62
+ import { dockerVolumeCreate } from "./procedures/docker/volume/create.js";
63
+ import { dockerVolumeRemove } from "./procedures/docker/volume/remove.js";
64
+ import { dockerNetworkList } from "./procedures/docker/network/list.js";
65
+ import { dockerNetworkCreate } from "./procedures/docker/network/create.js";
66
+ import { dockerNetworkRemove } from "./procedures/docker/network/remove.js";
67
+ import { dockerTag } from "./procedures/docker/tag.js";
68
+ import { dockerPush } from "./procedures/docker/push.js";
69
+ import { dockerPrune } from "./procedures/docker/prune.js";
70
+ import {
71
+ DockerComposePsInputSchema,
72
+ DockerComposePsOutputSchema,
73
+ type DockerComposePsInput,
74
+ type DockerComposePsOutput,
75
+ DockerComposeLogsInputSchema,
76
+ DockerComposeLogsOutputSchema,
77
+ type DockerComposeLogsInput,
78
+ type DockerComposeLogsOutput,
79
+ DockerComposeBuildInputSchema,
80
+ DockerComposeBuildOutputSchema,
81
+ type DockerComposeBuildInput,
82
+ type DockerComposeBuildOutput,
83
+ DockerComposeRestartInputSchema,
84
+ DockerComposeRestartOutputSchema,
85
+ type DockerComposeRestartInput,
86
+ type DockerComposeRestartOutput,
87
+ DockerImagesInputSchema,
88
+ DockerImagesOutputSchema,
89
+ type DockerImagesInput,
90
+ type DockerImagesOutput,
91
+ DockerInspectInputSchema,
92
+ DockerInspectOutputSchema,
93
+ type DockerInspectInput,
94
+ type DockerInspectOutput,
95
+ DockerVolumeListInputSchema,
96
+ DockerVolumeListOutputSchema,
97
+ type DockerVolumeListInput,
98
+ type DockerVolumeListOutput,
99
+ DockerVolumeCreateInputSchema,
100
+ DockerVolumeCreateOutputSchema,
101
+ type DockerVolumeCreateInput,
102
+ type DockerVolumeCreateOutput,
103
+ DockerVolumeRemoveInputSchema,
104
+ DockerVolumeRemoveOutputSchema,
105
+ type DockerVolumeRemoveInput,
106
+ type DockerVolumeRemoveOutput,
107
+ DockerNetworkListInputSchema,
108
+ DockerNetworkListOutputSchema,
109
+ type DockerNetworkListInput,
110
+ type DockerNetworkListOutput,
111
+ DockerNetworkCreateInputSchema,
112
+ DockerNetworkCreateOutputSchema,
113
+ type DockerNetworkCreateInput,
114
+ type DockerNetworkCreateOutput,
115
+ DockerNetworkRemoveInputSchema,
116
+ DockerNetworkRemoveOutputSchema,
117
+ type DockerNetworkRemoveInput,
118
+ type DockerNetworkRemoveOutput,
119
+ DockerTagInputSchema,
120
+ DockerTagOutputSchema,
121
+ type DockerTagInput,
122
+ type DockerTagOutput,
123
+ DockerPushInputSchema,
124
+ DockerPushOutputSchema,
125
+ type DockerPushInput,
126
+ type DockerPushOutput,
127
+ DockerPruneInputSchema,
128
+ DockerPruneOutputSchema,
129
+ type DockerPruneInput,
130
+ type DockerPruneOutput,
131
+ } from "./types.js";
52
132
 
53
133
  // =============================================================================
54
134
  // Procedures
@@ -186,6 +266,8 @@ const dockerLogsProcedure = createProcedure()
186
266
  description: "Get container logs",
187
267
  calls: ["shell.run", "shell.stream"],
188
268
  effects: { reads: ["docker"], writes: [] },
269
+ // With follow, the stream runs as long as the container (roadmap R15)
270
+ stream: { unbounded: true },
189
271
  args: ["container"],
190
272
  shorts: { follow: "f", tail: "n", timestamps: "t" },
191
273
  output: "json",
@@ -233,6 +315,237 @@ const dockerComposeDownProcedure = createProcedure()
233
315
  })
234
316
  .build();
235
317
 
318
+ // =============================================================================
319
+ // Roadmap R41: compose ps, logs, build, restart, images, inspect, volumes, networks, tag, push, prune
320
+ // =============================================================================
321
+
322
+ const dockerComposePsProcedure = createProcedure()
323
+ .path(["docker", "compose", "ps"])
324
+ .input(zodAdapter<DockerComposePsInput>(DockerComposePsInputSchema))
325
+ .output(zodAdapter<DockerComposePsOutput>(DockerComposePsOutputSchema))
326
+ .meta({
327
+ description: "List the containers of a compose project",
328
+ calls: ["shell.run"],
329
+ // Docker reads the compose file
330
+ effects: { reads: ["docker", "fs"], writes: [] },
331
+ args: ["services"],
332
+ shorts: { file: "f", all: "a", format: "F" },
333
+ output: "json",
334
+ })
335
+ .handler(async (input: DockerComposePsInput, ctx: ProcedureContext): Promise<DockerComposePsOutput> => dockerComposePs(input, ctx))
336
+ .build();
337
+
338
+ const dockerComposeLogsProcedure = createProcedure()
339
+ .path(["docker", "compose", "logs"])
340
+ .input(zodAdapter<DockerComposeLogsInput>(DockerComposeLogsInputSchema))
341
+ .output(zodAdapter<DockerComposeLogsOutput>(DockerComposeLogsOutputSchema))
342
+ .meta({
343
+ description: "Get the logs of the services of a compose project (without follow)",
344
+ calls: ["shell.run"],
345
+ effects: { reads: ["docker", "fs"], writes: [] },
346
+ args: ["services"],
347
+ shorts: { file: "f", tail: "n", timestamps: "t" },
348
+ output: "json",
349
+ })
350
+ .handler(async (input: DockerComposeLogsInput, ctx: ProcedureContext): Promise<DockerComposeLogsOutput> => dockerComposeLogs(input, ctx))
351
+ .build();
352
+
353
+ const dockerComposeBuildProcedure = createProcedure()
354
+ .path(["docker", "compose", "build"])
355
+ .input(zodAdapter<DockerComposeBuildInput>(DockerComposeBuildInputSchema))
356
+ .output(zodAdapter<DockerComposeBuildOutput>(DockerComposeBuildOutputSchema))
357
+ .meta({
358
+ description: "Build the images of the services of a compose project",
359
+ calls: ["shell.run"],
360
+ // As docker.build: the RUN steps are code of the project, and docker pulls the base images.
361
+ // The tags go to the new images, and the earlier images stay.
362
+ effects: { reads: ["docker", "fs", "network"], writes: ["docker", "process"], destructive: false },
363
+ args: ["services"],
364
+ shorts: { file: "f" },
365
+ output: "json",
366
+ })
367
+ .handler(async (input: DockerComposeBuildInput, ctx: ProcedureContext): Promise<DockerComposeBuildOutput> => dockerComposeBuild(input, ctx))
368
+ .build();
369
+
370
+ const dockerComposeRestartProcedure = createProcedure()
371
+ .path(["docker", "compose", "restart"])
372
+ .input(zodAdapter<DockerComposeRestartInput>(DockerComposeRestartInputSchema))
373
+ .output(zodAdapter<DockerComposeRestartOutput>(DockerComposeRestartOutputSchema))
374
+ .meta({
375
+ description: "Restart the services of a compose project",
376
+ calls: ["shell.run"],
377
+ // A restart stops the processes of the services. Each call restarts them again.
378
+ effects: { reads: ["docker", "fs"], writes: ["docker"] },
379
+ args: ["services"],
380
+ shorts: { file: "f", time: "t" },
381
+ output: "json",
382
+ })
383
+ .handler(async (input: DockerComposeRestartInput, ctx: ProcedureContext): Promise<DockerComposeRestartOutput> => dockerComposeRestart(input, ctx))
384
+ .build();
385
+
386
+ const dockerImagesProcedure = createProcedure()
387
+ .path(["docker", "images"])
388
+ .input(zodAdapter<DockerImagesInput>(DockerImagesInputSchema))
389
+ .output(zodAdapter<DockerImagesOutput>(DockerImagesOutputSchema))
390
+ .meta({
391
+ description: "List images",
392
+ calls: ["shell.run"],
393
+ effects: { reads: ["docker"], writes: [] },
394
+ args: ["repository"],
395
+ shorts: { all: "a", filter: "f", format: "F" },
396
+ output: "json",
397
+ })
398
+ .handler(async (input: DockerImagesInput, ctx: ProcedureContext): Promise<DockerImagesOutput> => dockerImages(input, ctx))
399
+ .build();
400
+
401
+ const dockerInspectProcedure = createProcedure()
402
+ .path(["docker", "inspect"])
403
+ .input(zodAdapter<DockerInspectInput>(DockerInspectInputSchema))
404
+ .output(zodAdapter<DockerInspectOutput>(DockerInspectOutputSchema))
405
+ .meta({
406
+ description: "Give the details of containers, images, volumes or networks: data has the JSON of docker",
407
+ calls: ["shell.run"],
408
+ effects: { reads: ["docker"], writes: [] },
409
+ args: ["targets"],
410
+ shorts: { type: "T", format: "F" },
411
+ output: "json",
412
+ })
413
+ .handler(async (input: DockerInspectInput, ctx: ProcedureContext): Promise<DockerInspectOutput> => dockerInspect(input, ctx))
414
+ .build();
415
+
416
+ const dockerVolumeListProcedure = createProcedure()
417
+ .path(["docker", "volume", "list"])
418
+ .input(zodAdapter<DockerVolumeListInput>(DockerVolumeListInputSchema))
419
+ .output(zodAdapter<DockerVolumeListOutput>(DockerVolumeListOutputSchema))
420
+ .meta({
421
+ description: "List volumes",
422
+ calls: ["shell.run"],
423
+ effects: { reads: ["docker"], writes: [] },
424
+ shorts: { filter: "f", format: "F" },
425
+ output: "json",
426
+ })
427
+ .handler(async (input: DockerVolumeListInput, ctx: ProcedureContext): Promise<DockerVolumeListOutput> => dockerVolumeList(input, ctx))
428
+ .build();
429
+
430
+ const dockerVolumeCreateProcedure = createProcedure()
431
+ .path(["docker", "volume", "create"])
432
+ .input(zodAdapter<DockerVolumeCreateInput>(DockerVolumeCreateInputSchema))
433
+ .output(zodAdapter<DockerVolumeCreateOutput>(DockerVolumeCreateOutputSchema))
434
+ .meta({
435
+ description: "Create a volume. A volume that exists stays as it is",
436
+ calls: ["shell.run"],
437
+ effects: { reads: ["docker"], writes: ["docker"], destructive: false, idempotent: true },
438
+ args: ["name"],
439
+ shorts: { driver: "d" },
440
+ output: "json",
441
+ })
442
+ .handler(async (input: DockerVolumeCreateInput, ctx: ProcedureContext): Promise<DockerVolumeCreateOutput> => dockerVolumeCreate(input, ctx))
443
+ .build();
444
+
445
+ const dockerVolumeRemoveProcedure = createProcedure()
446
+ .path(["docker", "volume", "remove"])
447
+ .input(zodAdapter<DockerVolumeRemoveInput>(DockerVolumeRemoveInputSchema))
448
+ .output(zodAdapter<DockerVolumeRemoveOutput>(DockerVolumeRemoveOutputSchema))
449
+ .meta({
450
+ description: "Remove volumes. Their data is lost",
451
+ calls: ["shell.run"],
452
+ effects: { reads: ["docker"], writes: ["docker"], destructive: true, idempotent: true },
453
+ args: ["volumes"],
454
+ shorts: { force: "f" },
455
+ output: "json",
456
+ })
457
+ .handler(async (input: DockerVolumeRemoveInput, ctx: ProcedureContext): Promise<DockerVolumeRemoveOutput> => dockerVolumeRemove(input, ctx))
458
+ .build();
459
+
460
+ const dockerNetworkListProcedure = createProcedure()
461
+ .path(["docker", "network", "list"])
462
+ .input(zodAdapter<DockerNetworkListInput>(DockerNetworkListInputSchema))
463
+ .output(zodAdapter<DockerNetworkListOutput>(DockerNetworkListOutputSchema))
464
+ .meta({
465
+ description: "List networks",
466
+ calls: ["shell.run"],
467
+ effects: { reads: ["docker"], writes: [] },
468
+ shorts: { filter: "f", format: "F" },
469
+ output: "json",
470
+ })
471
+ .handler(async (input: DockerNetworkListInput, ctx: ProcedureContext): Promise<DockerNetworkListOutput> => dockerNetworkList(input, ctx))
472
+ .build();
473
+
474
+ const dockerNetworkCreateProcedure = createProcedure()
475
+ .path(["docker", "network", "create"])
476
+ .input(zodAdapter<DockerNetworkCreateInput>(DockerNetworkCreateInputSchema))
477
+ .output(zodAdapter<DockerNetworkCreateOutput>(DockerNetworkCreateOutputSchema))
478
+ .meta({
479
+ description: "Create a network. A name that exists is an error",
480
+ calls: ["shell.run"],
481
+ effects: { reads: ["docker"], writes: ["docker"], destructive: false, idempotent: true },
482
+ args: ["name"],
483
+ shorts: { driver: "d" },
484
+ output: "json",
485
+ })
486
+ .handler(async (input: DockerNetworkCreateInput, ctx: ProcedureContext): Promise<DockerNetworkCreateOutput> => dockerNetworkCreate(input, ctx))
487
+ .build();
488
+
489
+ const dockerNetworkRemoveProcedure = createProcedure()
490
+ .path(["docker", "network", "remove"])
491
+ .input(zodAdapter<DockerNetworkRemoveInput>(DockerNetworkRemoveInputSchema))
492
+ .output(zodAdapter<DockerNetworkRemoveOutput>(DockerNetworkRemoveOutputSchema))
493
+ .meta({
494
+ description: "Remove networks",
495
+ calls: ["shell.run"],
496
+ effects: { reads: ["docker"], writes: ["docker"], destructive: true, idempotent: true },
497
+ args: ["networks"],
498
+ output: "json",
499
+ })
500
+ .handler(async (input: DockerNetworkRemoveInput, ctx: ProcedureContext): Promise<DockerNetworkRemoveOutput> => dockerNetworkRemove(input, ctx))
501
+ .build();
502
+
503
+ const dockerTagProcedure = createProcedure()
504
+ .path(["docker", "tag"])
505
+ .input(zodAdapter<DockerTagInput>(DockerTagInputSchema))
506
+ .output(zodAdapter<DockerTagOutput>(DockerTagOutputSchema))
507
+ .meta({
508
+ description: "Give an image another name. An image that had the name loses it",
509
+ calls: ["shell.run"],
510
+ // The name moves from another image, so it is destructive
511
+ effects: { reads: ["docker"], writes: ["docker"], idempotent: true },
512
+ args: ["source", "target"],
513
+ output: "json",
514
+ })
515
+ .handler(async (input: DockerTagInput, ctx: ProcedureContext): Promise<DockerTagOutput> => dockerTag(input, ctx))
516
+ .build();
517
+
518
+ const dockerPushProcedure = createProcedure()
519
+ .path(["docker", "push"])
520
+ .input(zodAdapter<DockerPushInput>(DockerPushInputSchema))
521
+ .output(zodAdapter<DockerPushOutput>(DockerPushOutputSchema))
522
+ .meta({
523
+ description: "Push an image to a registry. The registry replaces an image with the same tag",
524
+ calls: ["shell.run"],
525
+ // A write to the registry: it replaces the image of the tag there
526
+ effects: { reads: ["docker", "network"], writes: ["network"], idempotent: true },
527
+ args: ["image"],
528
+ shorts: { allTags: "a" },
529
+ output: "json",
530
+ })
531
+ .handler(async (input: DockerPushInput, ctx: ProcedureContext): Promise<DockerPushOutput> => dockerPush(input, ctx))
532
+ .build();
533
+
534
+ const dockerPruneProcedure = createProcedure()
535
+ .path(["docker", "prune"])
536
+ .input(zodAdapter<DockerPruneInput>(DockerPruneInputSchema))
537
+ .output(zodAdapter<DockerPruneOutput>(DockerPruneOutputSchema))
538
+ .meta({
539
+ description: "Remove unused containers, images, volumes, networks or build cache. It needs confirm: true",
540
+ calls: ["shell.run"],
541
+ // The removed objects and their data are lost. A second call finds less to remove.
542
+ effects: { reads: ["docker"], writes: ["docker"], destructive: true, idempotent: true },
543
+ shorts: { kind: "k", all: "a", filter: "f" },
544
+ output: "json",
545
+ })
546
+ .handler(async (input: DockerPruneInput, ctx: ProcedureContext): Promise<DockerPruneOutput> => dockerPrune(input, ctx))
547
+ .build();
548
+
236
549
  // =============================================================================
237
550
  // Registration
238
551
  // =============================================================================
@@ -252,6 +565,21 @@ export const dockerModule: ProcedureModule = defineModule("@procedures/docker",
252
565
  dockerLogsProcedure,
253
566
  dockerComposeUpProcedure,
254
567
  dockerComposeDownProcedure,
568
+ dockerComposePsProcedure,
569
+ dockerComposeLogsProcedure,
570
+ dockerComposeBuildProcedure,
571
+ dockerComposeRestartProcedure,
572
+ dockerImagesProcedure,
573
+ dockerInspectProcedure,
574
+ dockerVolumeListProcedure,
575
+ dockerVolumeCreateProcedure,
576
+ dockerVolumeRemoveProcedure,
577
+ dockerNetworkListProcedure,
578
+ dockerNetworkCreateProcedure,
579
+ dockerNetworkRemoveProcedure,
580
+ dockerTagProcedure,
581
+ dockerPushProcedure,
582
+ dockerPruneProcedure,
255
583
  ], [shellModule]);
256
584
 
257
585
  export default dockerModule;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * docker.compose.build procedure
3
+ *
4
+ * Build the images of the services of a compose project (roadmap R41).
5
+ */
6
+
7
+ import type { ProcedureContext } from "@procedures/client";
8
+ import { composeArgs, runDocker, serviceArgs } from "../shared.js";
9
+ import type { DockerComposeBuildInput, DockerComposeBuildOutput } from "../../../types.js";
10
+
11
+ /**
12
+ * Build the images of the services of a compose project
13
+ */
14
+ export async function dockerComposeBuild(input: DockerComposeBuildInput, ctx: ProcedureContext): Promise<DockerComposeBuildOutput> {
15
+ const args = composeArgs(input.file, "build");
16
+ if (input.noCache) args.push("--no-cache");
17
+ if (input.pull) args.push("--pull");
18
+ for (const [key, value] of Object.entries(input.buildArgs ?? {})) {
19
+ args.push("--build-arg", `${key}=${value}`);
20
+ }
21
+ args.push(...serviceArgs(input.services));
22
+ return runDocker(args, input, ctx);
23
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * docker.compose.logs procedure
3
+ *
4
+ * Get the logs of the services of a compose project (roadmap R41). The procedure does not follow
5
+ * the logs: it gives the lines that exist, without colors.
6
+ */
7
+
8
+ import type { ProcedureContext } from "@procedures/client";
9
+ import { composeArgs, runDocker, serviceArgs } from "../shared.js";
10
+ import type { DockerComposeLogsInput, DockerComposeLogsOutput } from "../../../types.js";
11
+
12
+ /**
13
+ * Get the logs of the services of a compose project
14
+ */
15
+ export async function dockerComposeLogs(input: DockerComposeLogsInput, ctx: ProcedureContext): Promise<DockerComposeLogsOutput> {
16
+ const args = composeArgs(input.file, "logs");
17
+ args.push("--no-color");
18
+ if (input.tail !== undefined) args.push("--tail", String(input.tail));
19
+ if (input.since) args.push("--since", input.since);
20
+ if (input.timestamps) args.push("--timestamps");
21
+ args.push(...serviceArgs(input.services));
22
+ return runDocker(args, input, ctx);
23
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * docker.compose.ps procedure
3
+ *
4
+ * List the containers of a compose project (roadmap R41).
5
+ */
6
+
7
+ import type { ProcedureContext } from "@procedures/client";
8
+ import { composeArgs, runDocker, serviceArgs } from "../shared.js";
9
+ import type { DockerComposePsInput, DockerComposePsOutput } from "../../../types.js";
10
+
11
+ /**
12
+ * List the containers of a compose project
13
+ */
14
+ export async function dockerComposePs(input: DockerComposePsInput, ctx: ProcedureContext): Promise<DockerComposePsOutput> {
15
+ const args = composeArgs(input.file, "ps");
16
+ if (input.all) args.push("--all");
17
+ if (input.format) args.push("--format", input.format);
18
+ args.push(...serviceArgs(input.services));
19
+ return runDocker(args, input, ctx);
20
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * docker.compose.restart procedure
3
+ *
4
+ * Restart the services of a compose project (roadmap R41).
5
+ */
6
+
7
+ import type { ProcedureContext } from "@procedures/client";
8
+ import { composeArgs, runDocker, serviceArgs } from "../shared.js";
9
+ import type { DockerComposeRestartInput, DockerComposeRestartOutput } from "../../../types.js";
10
+
11
+ /**
12
+ * Restart the services of a compose project
13
+ */
14
+ export async function dockerComposeRestart(input: DockerComposeRestartInput, ctx: ProcedureContext): Promise<DockerComposeRestartOutput> {
15
+ const args = composeArgs(input.file, "restart");
16
+ if (input.time !== undefined) args.push("--timeout", String(input.time));
17
+ args.push(...serviceArgs(input.services));
18
+ return runDocker(args, input, ctx);
19
+ }
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import type { ProcedureContext } from "@procedures/client";
8
- import { dockerArg, runDocker, words } from "./shared.js";
8
+ import { commandWords, dockerArg, runDocker } from "./shared.js";
9
9
  import type { DockerExecInput, DockerCommandOutput } from "../../types.js";
10
10
 
11
11
  /**
@@ -30,7 +30,12 @@ export async function dockerExec(
30
30
  }
31
31
 
32
32
  args.push(dockerArg("container", input.container));
33
- args.push(...words(input.command));
33
+ // The command: args as they are, or command split at whitespace
34
+ const command = commandWords(input);
35
+ if (command.length === 0) {
36
+ throw new Error("docker.exec needs command or args");
37
+ }
38
+ args.push(...command);
34
39
 
35
40
  return runDocker(args, input, ctx);
36
41
  }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * docker.images procedure
3
+ *
4
+ * List images (roadmap R41).
5
+ */
6
+
7
+ import type { ProcedureContext } from "@procedures/client";
8
+ import { dockerArg, runDocker } from "./shared.js";
9
+ import type { DockerImagesInput, DockerImagesOutput } from "../../types.js";
10
+
11
+ /**
12
+ * List images
13
+ */
14
+ export async function dockerImages(input: DockerImagesInput, ctx: ProcedureContext): Promise<DockerImagesOutput> {
15
+ const args = ["images"];
16
+ if (input.all) args.push("--all");
17
+ if (input.filter) args.push("--filter", input.filter);
18
+ if (input.format) args.push("--format", input.format);
19
+ if (input.repository) args.push(dockerArg("repository", input.repository));
20
+ return runDocker(args, input, ctx);
21
+ }
@@ -8,3 +8,18 @@ export { dockerPs } from "./ps.js";
8
8
  export { dockerLogs, type DockerLogItem } from "./logs.js";
9
9
  export { dockerComposeUp } from "./up.js";
10
10
  export { dockerComposeDown } from "./down.js";
11
+ export { dockerComposePs } from "./compose/ps.js";
12
+ export { dockerComposeLogs } from "./compose/logs.js";
13
+ export { dockerComposeBuild } from "./compose/build.js";
14
+ export { dockerComposeRestart } from "./compose/restart.js";
15
+ export { dockerImages } from "./images.js";
16
+ export { dockerInspect } from "./inspect.js";
17
+ export { dockerVolumeList } from "./volume/list.js";
18
+ export { dockerVolumeCreate } from "./volume/create.js";
19
+ export { dockerVolumeRemove } from "./volume/remove.js";
20
+ export { dockerNetworkList } from "./network/list.js";
21
+ export { dockerNetworkCreate } from "./network/create.js";
22
+ export { dockerNetworkRemove } from "./network/remove.js";
23
+ export { dockerTag } from "./tag.js";
24
+ export { dockerPush } from "./push.js";
25
+ export { dockerPrune } from "./prune.js";
@@ -0,0 +1,31 @@
1
+ /**
2
+ * docker.inspect procedure
3
+ *
4
+ * Give the details of containers, images, volumes or networks as JSON (roadmap R41). Without
5
+ * `format`, docker writes a JSON array, and `data` has it parsed.
6
+ */
7
+
8
+ import type { ProcedureContext } from "@procedures/client";
9
+ import { dockerArg, runDocker } from "./shared.js";
10
+ import type { DockerInspectInput, DockerInspectOutput } from "../../types.js";
11
+
12
+ /**
13
+ * Give the details of containers, images, volumes or networks as JSON
14
+ */
15
+ export async function dockerInspect(input: DockerInspectInput, ctx: ProcedureContext): Promise<DockerInspectOutput> {
16
+ const args = ["inspect"];
17
+ if (input.type) args.push("--type", input.type);
18
+ if (input.format) args.push("--format", input.format);
19
+ args.push(...input.targets.map((target) => dockerArg("target", target)));
20
+
21
+ const result: DockerInspectOutput = await runDocker(args, input, ctx);
22
+ // Docker writes the array also when a target is missing (exit 1): the found ones are in it
23
+ if (!input.format && result.stdout.trim().startsWith("[")) {
24
+ try {
25
+ result.data = JSON.parse(result.stdout);
26
+ } catch {
27
+ // Not JSON: stdout has the text
28
+ }
29
+ }
30
+ return result;
31
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * docker.network.create procedure
3
+ *
4
+ * Create a network (roadmap R41). Docker refuses a name that exists, so a second call changes
5
+ * nothing. The output is the ID of the network.
6
+ */
7
+
8
+ import type { ProcedureContext } from "@procedures/client";
9
+ import { dockerArg, labelArgs, runDocker } from "../shared.js";
10
+ import type { DockerNetworkCreateInput, DockerNetworkCreateOutput } from "../../../types.js";
11
+
12
+ /**
13
+ * Create a network
14
+ */
15
+ export async function dockerNetworkCreate(input: DockerNetworkCreateInput, ctx: ProcedureContext): Promise<DockerNetworkCreateOutput> {
16
+ const args = ["network", "create"];
17
+ if (input.driver) args.push("--driver", input.driver);
18
+ if (input.internal) args.push("--internal");
19
+ args.push(...labelArgs(input.labels));
20
+ args.push(dockerArg("network", input.name));
21
+ return runDocker(args, input, ctx);
22
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * docker.network.list procedure
3
+ *
4
+ * List networks (roadmap R41).
5
+ */
6
+
7
+ import type { ProcedureContext } from "@procedures/client";
8
+ import { runDocker } from "../shared.js";
9
+ import type { DockerNetworkListInput, DockerNetworkListOutput } from "../../../types.js";
10
+
11
+ /**
12
+ * List networks
13
+ */
14
+ export async function dockerNetworkList(input: DockerNetworkListInput, ctx: ProcedureContext): Promise<DockerNetworkListOutput> {
15
+ const args = ["network", "ls"];
16
+ if (input.filter) args.push("--filter", input.filter);
17
+ if (input.format) args.push("--format", input.format);
18
+ return runDocker(args, input, ctx);
19
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * docker.network.remove procedure
3
+ *
4
+ * Remove networks (roadmap R41). Docker refuses a network that a container uses.
5
+ */
6
+
7
+ import type { ProcedureContext } from "@procedures/client";
8
+ import { dockerArg, runDocker } from "../shared.js";
9
+ import type { DockerNetworkRemoveInput, DockerNetworkRemoveOutput } from "../../../types.js";
10
+
11
+ /**
12
+ * Remove networks
13
+ */
14
+ export async function dockerNetworkRemove(input: DockerNetworkRemoveInput, ctx: ProcedureContext): Promise<DockerNetworkRemoveOutput> {
15
+ const args = ["network", "rm", ...input.networks.map((network) => dockerArg("network", network))];
16
+ return runDocker(args, input, ctx);
17
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * docker.prune procedure
3
+ *
4
+ * Remove unused containers, images, volumes, networks or build cache (roadmap R41). The removed
5
+ * objects and their data are lost, so the input must have `confirm: true`. Docker does not ask:
6
+ * the procedure passes `--force`.
7
+ */
8
+
9
+ import type { ProcedureContext } from "@procedures/client";
10
+ import { runDocker } from "./shared.js";
11
+ import type { DockerPruneInput, DockerPruneOutput } from "../../types.js";
12
+
13
+ /**
14
+ * Remove unused containers, images, volumes, networks or build cache
15
+ */
16
+ export async function dockerPrune(input: DockerPruneInput, ctx: ProcedureContext): Promise<DockerPruneOutput> {
17
+ // The schema requires it. A direct call of this function gets the same check.
18
+ if (input.confirm !== true) {
19
+ throw new Error("docker.prune needs confirm: true. The removed objects and their data are lost");
20
+ }
21
+ const kind = input.kind ?? "system";
22
+ if (input.volumes && kind !== "system") {
23
+ throw new Error(`docker.prune: volumes needs the kind system, not ${kind}`);
24
+ }
25
+ const args = [kind, "prune", "--force"];
26
+ if (input.all) args.push("--all");
27
+ if (input.volumes) args.push("--volumes");
28
+ if (input.filter) args.push("--filter", input.filter);
29
+ return runDocker(args, input, ctx);
30
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * docker.push procedure
3
+ *
4
+ * Push an image to a registry (roadmap R41). The registry replaces an image with the same tag.
5
+ * Docker uses the credentials of `docker login`.
6
+ */
7
+
8
+ import type { ProcedureContext } from "@procedures/client";
9
+ import { dockerArg, runDocker } from "./shared.js";
10
+ import type { DockerPushInput, DockerPushOutput } from "../../types.js";
11
+
12
+ /**
13
+ * Push an image to a registry
14
+ */
15
+ export async function dockerPush(input: DockerPushInput, ctx: ProcedureContext): Promise<DockerPushOutput> {
16
+ const args = ["push"];
17
+ if (input.allTags) args.push("--all-tags");
18
+ args.push(dockerArg("image", input.image));
19
+ return runDocker(args, input, ctx);
20
+ }