confctl 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +11 -0
  3. data/.gitignore +8 -0
  4. data/.overcommit.yml +6 -0
  5. data/.rubocop.yml +67 -0
  6. data/.rubocop_todo.yml +5 -0
  7. data/.ruby-version +1 -0
  8. data/CHANGELOG.md +2 -0
  9. data/Gemfile +2 -0
  10. data/LICENSE.txt +674 -0
  11. data/README.md +522 -0
  12. data/Rakefile +40 -0
  13. data/bin/confctl +4 -0
  14. data/confctl.gemspec +33 -0
  15. data/example/.gitignore +2 -0
  16. data/example/README.md +38 -0
  17. data/example/cluster/cluster.nix +7 -0
  18. data/example/cluster/module-list.nix +3 -0
  19. data/example/cluster/nixos-machine/config.nix +15 -0
  20. data/example/cluster/nixos-machine/hardware.nix +4 -0
  21. data/example/cluster/nixos-machine/module.nix +8 -0
  22. data/example/cluster/vpsadminos-container/config.nix +22 -0
  23. data/example/cluster/vpsadminos-container/module.nix +8 -0
  24. data/example/cluster/vpsadminos-machine/config.nix +22 -0
  25. data/example/cluster/vpsadminos-machine/hardware.nix +4 -0
  26. data/example/cluster/vpsadminos-machine/module.nix +8 -0
  27. data/example/cluster/vpsfreecz-vps/config.nix +25 -0
  28. data/example/cluster/vpsfreecz-vps/module.nix +8 -0
  29. data/example/configs/confctl.nix +10 -0
  30. data/example/configs/swpins.nix +28 -0
  31. data/example/data/default.nix +5 -0
  32. data/example/data/ssh-keys.nix +7 -0
  33. data/example/environments/base.nix +13 -0
  34. data/example/modules/module-list.nix +13 -0
  35. data/example/shell.nix +11 -0
  36. data/example/swpins/channels/nixos-unstable.json +35 -0
  37. data/example/swpins/channels/vpsadminos-staging.json +35 -0
  38. data/lib/confctl/cli/app.rb +551 -0
  39. data/lib/confctl/cli/attr_filters.rb +51 -0
  40. data/lib/confctl/cli/cluster.rb +1248 -0
  41. data/lib/confctl/cli/command.rb +206 -0
  42. data/lib/confctl/cli/configuration.rb +296 -0
  43. data/lib/confctl/cli/gen_data.rb +97 -0
  44. data/lib/confctl/cli/generation.rb +335 -0
  45. data/lib/confctl/cli/log_view.rb +267 -0
  46. data/lib/confctl/cli/output_formatter.rb +288 -0
  47. data/lib/confctl/cli/swpins/base.rb +40 -0
  48. data/lib/confctl/cli/swpins/channel.rb +73 -0
  49. data/lib/confctl/cli/swpins/cluster.rb +80 -0
  50. data/lib/confctl/cli/swpins/core.rb +86 -0
  51. data/lib/confctl/cli/swpins/utils.rb +55 -0
  52. data/lib/confctl/cli/swpins.rb +5 -0
  53. data/lib/confctl/cli/tag_filters.rb +30 -0
  54. data/lib/confctl/cli.rb +5 -0
  55. data/lib/confctl/conf_cache.rb +105 -0
  56. data/lib/confctl/conf_dir.rb +88 -0
  57. data/lib/confctl/erb_template.rb +37 -0
  58. data/lib/confctl/exceptions.rb +3 -0
  59. data/lib/confctl/gcroot.rb +30 -0
  60. data/lib/confctl/generation/build.rb +145 -0
  61. data/lib/confctl/generation/build_list.rb +106 -0
  62. data/lib/confctl/generation/host.rb +35 -0
  63. data/lib/confctl/generation/host_list.rb +81 -0
  64. data/lib/confctl/generation/unified.rb +117 -0
  65. data/lib/confctl/generation/unified_list.rb +63 -0
  66. data/lib/confctl/git_repo_mirror.rb +79 -0
  67. data/lib/confctl/health_checks/base.rb +66 -0
  68. data/lib/confctl/health_checks/run_command.rb +179 -0
  69. data/lib/confctl/health_checks/systemd/properties.rb +84 -0
  70. data/lib/confctl/health_checks/systemd/property_check.rb +31 -0
  71. data/lib/confctl/health_checks/systemd/property_list.rb +20 -0
  72. data/lib/confctl/health_checks.rb +5 -0
  73. data/lib/confctl/hook.rb +35 -0
  74. data/lib/confctl/line_buffer.rb +53 -0
  75. data/lib/confctl/logger.rb +151 -0
  76. data/lib/confctl/machine.rb +107 -0
  77. data/lib/confctl/machine_control.rb +172 -0
  78. data/lib/confctl/machine_list.rb +108 -0
  79. data/lib/confctl/machine_status.rb +135 -0
  80. data/lib/confctl/module_options.rb +95 -0
  81. data/lib/confctl/nix.rb +382 -0
  82. data/lib/confctl/nix_build.rb +108 -0
  83. data/lib/confctl/nix_collect_garbage.rb +64 -0
  84. data/lib/confctl/nix_copy.rb +49 -0
  85. data/lib/confctl/nix_format.rb +124 -0
  86. data/lib/confctl/nix_literal_expression.rb +15 -0
  87. data/lib/confctl/parallel_executor.rb +43 -0
  88. data/lib/confctl/pattern.rb +9 -0
  89. data/lib/confctl/settings.rb +50 -0
  90. data/lib/confctl/std_line_buffer.rb +40 -0
  91. data/lib/confctl/swpins/change_set.rb +151 -0
  92. data/lib/confctl/swpins/channel.rb +62 -0
  93. data/lib/confctl/swpins/channel_list.rb +47 -0
  94. data/lib/confctl/swpins/cluster_name.rb +94 -0
  95. data/lib/confctl/swpins/cluster_name_list.rb +15 -0
  96. data/lib/confctl/swpins/core.rb +137 -0
  97. data/lib/confctl/swpins/deployed_info.rb +23 -0
  98. data/lib/confctl/swpins/spec.rb +20 -0
  99. data/lib/confctl/swpins/specs/base.rb +184 -0
  100. data/lib/confctl/swpins/specs/directory.rb +51 -0
  101. data/lib/confctl/swpins/specs/git.rb +135 -0
  102. data/lib/confctl/swpins/specs/git_rev.rb +24 -0
  103. data/lib/confctl/swpins.rb +17 -0
  104. data/lib/confctl/system_command.rb +10 -0
  105. data/lib/confctl/user_script.rb +13 -0
  106. data/lib/confctl/user_scripts.rb +41 -0
  107. data/lib/confctl/utils/file.rb +21 -0
  108. data/lib/confctl/version.rb +3 -0
  109. data/lib/confctl.rb +43 -0
  110. data/man/man8/confctl-options.nix.8 +1334 -0
  111. data/man/man8/confctl-options.nix.8.md +1340 -0
  112. data/man/man8/confctl.8 +660 -0
  113. data/man/man8/confctl.8.md +654 -0
  114. data/nix/evaluator.nix +160 -0
  115. data/nix/lib/default.nix +83 -0
  116. data/nix/lib/machine/default.nix +74 -0
  117. data/nix/lib/machine/info.nix +5 -0
  118. data/nix/lib/swpins/eval.nix +71 -0
  119. data/nix/lib/swpins/options.nix +94 -0
  120. data/nix/machines.nix +31 -0
  121. data/nix/modules/cluster/default.nix +459 -0
  122. data/nix/modules/confctl/cli.nix +21 -0
  123. data/nix/modules/confctl/generations.nix +84 -0
  124. data/nix/modules/confctl/nix.nix +28 -0
  125. data/nix/modules/confctl/swpins.nix +55 -0
  126. data/nix/modules/module-list.nix +19 -0
  127. data/shell.nix +42 -0
  128. data/template/confctl-options.nix/main.erb +45 -0
  129. data/template/confctl-options.nix/options.erb +15 -0
  130. metadata +353 -0
@@ -0,0 +1,551 @@
1
+ require 'gli'
2
+
3
+ module ConfCtl::Cli
4
+ class App
5
+ include GLI::App
6
+
7
+ def self.get
8
+ cli = new
9
+ cli.setup
10
+ cli
11
+ end
12
+
13
+ def self.run
14
+ cli = get
15
+ exit(cli.run(ARGV))
16
+ end
17
+
18
+ def setup
19
+ Thread.abort_on_exception = true
20
+
21
+ program_desc 'Nix deployment configuration management tool'
22
+ subcommand_option_handling :normal
23
+ preserve_argv true
24
+ arguments :strict
25
+ hide_commands_without_desc true
26
+
27
+ desc 'Toggle color mode'
28
+ flag %i[c color], must_match: %w[always never auto], default_value: 'auto'
29
+
30
+ desc 'Create a new configuration'
31
+ command :init do |c|
32
+ c.action(&Command.run(c, Configuration, :init))
33
+ end
34
+
35
+ desc 'Add a new machine'
36
+ arg_name '<name>'
37
+ command :add do |c|
38
+ c.action(&Command.run(c, Configuration, :add))
39
+ end
40
+
41
+ desc 'Rename an existing machine'
42
+ arg_name '<old-name> <new-name>'
43
+ command :rename do |c|
44
+ c.action(&Command.run(c, Configuration, :rename))
45
+ end
46
+
47
+ desc 'Update cluster machine list with contents of cluster/'
48
+ command :rediscover do |c|
49
+ c.action(&Command.run(c, Configuration, :rediscover))
50
+ end
51
+
52
+ desc 'Manage software pins'
53
+ command :swpins do |pins|
54
+ pins.desc 'Manage software pins channels'
55
+ pins.command :channel do |ch|
56
+ ch.desc 'List configured sw pins'
57
+ ch.arg_name '[channel [sw]]'
58
+ ch.command :ls do |c|
59
+ c.action(&Command.run(c, Swpins::Channel, :list))
60
+ end
61
+
62
+ swpins_commands(ch, Swpins::Channel, 'channel')
63
+ end
64
+
65
+ pins.desc 'Manage cluster software pins'
66
+ pins.command :cluster do |cl|
67
+ cl.desc 'List configured sw pins'
68
+ cl.arg_name '[cluster-name [sw]]'
69
+ cl.command :ls do |c|
70
+ c.action(&Command.run(c, Swpins::Cluster, :list))
71
+ end
72
+
73
+ swpins_commands(cl, Swpins::Cluster, 'name')
74
+ end
75
+
76
+ pins.desc 'Manage core software pins'
77
+ pins.command :core do |core|
78
+ core.desc 'List configured sw pins'
79
+ core.arg_name '[sw]'
80
+ core.command :ls do |c|
81
+ c.action(&Command.run(c, Swpins::Core, :list))
82
+ end
83
+
84
+ core.desc 'Set to specific version'
85
+ core.arg_name '<sw> <ref>'
86
+ core.command :set do |c|
87
+ c.desc 'Commit changes to git'
88
+ c.switch :commit, default_value: false
89
+
90
+ c.desc 'Include changelog in the commit message'
91
+ c.switch :changelog, default_value: true
92
+
93
+ c.desc 'Generate changelog for downgrade'
94
+ c.switch %i[d downgrade], default_value: false
95
+
96
+ c.action(&Command.run(c, Swpins::Core, :set))
97
+ end
98
+
99
+ core.desc 'Update to newest version'
100
+ core.arg_name '[<sw> [<version...>]]]'
101
+ core.command :update do |c|
102
+ c.desc 'Commit changes to git'
103
+ c.switch :commit, default_value: false
104
+
105
+ c.desc 'Include changelog in the commit message'
106
+ c.switch :changelog, default_value: true
107
+
108
+ c.desc 'Generate changelog for downgrade'
109
+ c.switch %i[d downgrade], default_value: false
110
+
111
+ c.action(&Command.run(c, Swpins::Core, :update))
112
+ end
113
+ end
114
+
115
+ pins.desc 'Update all swpins'
116
+ pins.command :update do |c|
117
+ c.desc 'Commit changes to git'
118
+ c.switch :commit, default_value: false
119
+
120
+ c.desc 'Include changelog in the commit message'
121
+ c.switch :changelog, default_value: true
122
+
123
+ c.desc 'Generate changelog for downgrade'
124
+ c.switch %i[d downgrade], default_value: false
125
+
126
+ c.action(&Command.run(c, Swpins::Base, :update))
127
+ end
128
+
129
+ pins.desc 'Generate confctl-managed JSON files for configured swpins'
130
+ pins.command :reconfigure do |c|
131
+ c.action(&Command.run(c, Swpins::Base, :reconfigure))
132
+ end
133
+ end
134
+
135
+ desc 'List configured machines'
136
+ arg_name '[machine-pattern]'
137
+ command :ls do |c|
138
+ c.desc 'Enable traces in Nix'
139
+ c.switch 'show-trace'
140
+
141
+ c.desc 'Filter (un)managed machines'
142
+ c.flag :managed, must_match: %w[y yes n no a all]
143
+
144
+ c.desc 'List possible attributes to output'
145
+ c.switch %i[L list], negatable: false
146
+
147
+ c.desc 'Select attributes to output'
148
+ c.flag %i[o output]
149
+
150
+ c.desc 'Do not show the header'
151
+ c.switch %i[H hide-header]
152
+
153
+ c.desc 'Filter by attribute'
154
+ c.flag %i[a attr], multiple: true
155
+
156
+ c.desc 'Filter by tag'
157
+ c.flag %i[t tag], multiple: true
158
+
159
+ c.action(&Command.run(c, Cluster, :list))
160
+ end
161
+
162
+ desc 'Build target systems'
163
+ arg_name '[machine-pattern]'
164
+ command :build do |c|
165
+ c.desc 'Enable traces in Nix'
166
+ c.switch 'show-trace'
167
+
168
+ c.desc 'Filter by attribute'
169
+ c.flag %i[a attr], multiple: true
170
+
171
+ c.desc 'Filter by tag'
172
+ c.flag %i[t tag], multiple: true
173
+
174
+ c.desc 'Assume the answer to confirmations is yes'
175
+ c.switch %w[y yes]
176
+
177
+ nix_build_options(c)
178
+
179
+ c.action(&Command.run(c, Cluster, :build))
180
+ end
181
+
182
+ desc 'Deploy target systems'
183
+ arg_name '[machine-pattern [switch-action]]'
184
+ command :deploy do |c|
185
+ c.desc 'Enable traces in Nix'
186
+ c.switch 'show-trace'
187
+
188
+ c.desc 'Filter by attribute'
189
+ c.flag %i[a attr], multiple: true
190
+
191
+ c.desc 'Filter by tag'
192
+ c.flag %i[t tag], multiple: true
193
+
194
+ c.desc 'Assume the answer to confirmations is yes'
195
+ c.switch %w[y yes]
196
+
197
+ c.desc 'Deploy selected generation'
198
+ c.flag %i[g generation]
199
+
200
+ c.desc 'Ask for confirmation before activation'
201
+ c.switch %w[i interactive]
202
+
203
+ c.desc 'Try to dry-activate before the real switch'
204
+ c.switch 'dry-activate-first'
205
+
206
+ c.desc 'Copy and deploy machines one by one'
207
+ c.switch 'one-by-one'
208
+
209
+ c.desc 'Max number of concurrent nix-copy-closure processes'
210
+ c.flag 'max-concurrent-copy', arg_name: 'n', type: Integer,
211
+ default_value: 5
212
+
213
+ c.desc 'Do not activate copied closures'
214
+ c.switch 'copy-only', negatable: false
215
+
216
+ c.desc 'Reboot target systems after deployment'
217
+ c.switch :reboot
218
+
219
+ c.desc 'Wait for the machine to boot'
220
+ c.flag 'wait-online', default_value: '600'
221
+
222
+ nix_build_options(c)
223
+
224
+ c.desc 'Toggle health checks'
225
+ c.switch 'health-checks', default_value: true
226
+
227
+ c.desc 'Do not abourt on failed health checks'
228
+ c.switch 'keep-going', default_value: false
229
+
230
+ c.action(&Command.run(c, Cluster, :deploy))
231
+ end
232
+
233
+ desc 'Run machine health-checks'
234
+ arg_name '[machine-pattern]'
235
+ command :'health-check' do |c|
236
+ c.desc 'Filter by attribute'
237
+ c.flag %i[a attr], multiple: true
238
+
239
+ c.desc 'Filter by tag'
240
+ c.flag %i[t tag], multiple: true
241
+
242
+ c.desc 'Assume the answer to confirmations is yes'
243
+ c.switch %w[y yes]
244
+
245
+ c.desc 'Maximum number of health-check jobs'
246
+ c.flag %w[j max-jobs], arg_name: 'number', type: Integer, default_value: 5
247
+
248
+ c.action(&Command.run(c, Cluster, :health_check))
249
+ end
250
+
251
+ desc 'Check machine status'
252
+ arg_name '[machine-pattern]'
253
+ command :status do |c|
254
+ c.desc 'Filter by attribute'
255
+ c.flag %i[a attr], multiple: true
256
+
257
+ c.desc 'Filter by tag'
258
+ c.flag %i[t tag], multiple: true
259
+
260
+ c.desc 'Assume the answer to confirmations is yes'
261
+ c.switch %w[y yes]
262
+
263
+ c.desc 'Check status against selected generation'
264
+ c.flag %i[g generation]
265
+
266
+ c.action(&Command.run(c, Cluster, :status))
267
+ end
268
+
269
+ desc 'Changelog between deployed and configured swpins'
270
+ arg_name '[machine-pattern [sw-pattern]]'
271
+ command :changelog do |c|
272
+ c.desc 'Filter by attribute'
273
+ c.flag %i[a attr], multiple: true
274
+
275
+ c.desc 'Filter by tag'
276
+ c.flag %i[t tag], multiple: true
277
+
278
+ c.desc 'Assume the answer to confirmations is yes'
279
+ c.switch %w[y yes]
280
+
281
+ c.desc 'Show changelog against swpins from selected generation'
282
+ c.flag %i[g generation]
283
+
284
+ c.desc 'Show a changelog for downgrade'
285
+ c.switch %i[d downgrade]
286
+
287
+ c.desc 'Show full-length changelog descriptions'
288
+ c.switch %i[v verbose]
289
+
290
+ c.desc 'Show patches'
291
+ c.switch %i[p patch]
292
+
293
+ nix_build_options(c)
294
+
295
+ c.action(&Command.run(c, Cluster, :changelog))
296
+ end
297
+
298
+ desc 'Diff between deployed and configured swpins'
299
+ arg_name '[machine-pattern [sw-pattern]]'
300
+ command :diff do |c|
301
+ c.desc 'Filter by attribute'
302
+ c.flag %i[a attr], multiple: true
303
+
304
+ c.desc 'Filter by tag'
305
+ c.flag %i[t tag], multiple: true
306
+
307
+ c.desc 'Assume the answer to confirmations is yes'
308
+ c.switch %w[y yes]
309
+
310
+ c.desc 'Show diff against swpins from selected generation'
311
+ c.flag %i[g generation]
312
+
313
+ c.desc 'Show a changelog for downgrade'
314
+ c.switch %i[d downgrade]
315
+
316
+ nix_build_options(c)
317
+
318
+ c.action(&Command.run(c, Cluster, :diff))
319
+ end
320
+
321
+ desc 'Test SSH connection'
322
+ arg_name '[machine-pattern]'
323
+ command :'test-connection' do |c|
324
+ c.desc 'Filter (un)managed machines'
325
+ c.flag :managed, must_match: %w[y yes n no a all]
326
+
327
+ c.desc 'Filter by attribute'
328
+ c.flag %i[a attr], multiple: true
329
+
330
+ c.desc 'Filter by tag'
331
+ c.flag %i[t tag], multiple: true
332
+
333
+ c.desc 'Assume the answer to confirmations is yes'
334
+ c.switch %w[y yes]
335
+
336
+ c.action(&Command.run(c, Cluster, :test_connection))
337
+ end
338
+
339
+ desc 'Run command over SSH'
340
+ arg_name '[machine-pattern [command [arguments...]]]'
341
+ command :ssh do |c|
342
+ c.desc 'Filter (un)managed machines'
343
+ c.flag :managed, must_match: %w[y yes n no a all]
344
+
345
+ c.desc 'Filter by attribute'
346
+ c.flag %i[a attr], multiple: true
347
+
348
+ c.desc 'Filter by tag'
349
+ c.flag %i[t tag], multiple: true
350
+
351
+ c.desc 'Assume the answer to confirmations is yes'
352
+ c.switch %w[y yes]
353
+
354
+ c.desc 'Run command in parallel on all machines at once'
355
+ c.switch %i[p parallel]
356
+
357
+ c.desc 'Aggregate identical command output'
358
+ c.switch %i[g aggregate]
359
+
360
+ c.desc 'Data passed to standard input'
361
+ c.flag %i[i input-string]
362
+
363
+ c.desc 'File passed to standard input'
364
+ c.flag %i[f input-file]
365
+
366
+ c.action(&Command.run(c, Cluster, :ssh))
367
+ end
368
+
369
+ desc 'Open ClusterSSH'
370
+ arg_name '[machine-pattern]'
371
+ command :cssh do |c|
372
+ c.desc 'Filter (un)managed machines'
373
+ c.flag :managed, must_match: %w[y yes n no a all]
374
+
375
+ c.desc 'Filter by attribute'
376
+ c.flag %i[a attr], multiple: true
377
+
378
+ c.desc 'Filter by tag'
379
+ c.flag %i[t tag], multiple: true
380
+
381
+ c.desc 'Assume the answer to confirmations is yes'
382
+ c.switch %w[y yes]
383
+
384
+ c.action(&Command.run(c, Cluster, :cssh))
385
+ end
386
+
387
+ desc 'Manage built machine generations'
388
+ command :generation do |gen|
389
+ gen.desc 'List machine generations'
390
+ gen.arg_name '[machine-pattern [generation-pattern]]'
391
+ gen.command :ls do |c|
392
+ c.desc 'Filter by attribute'
393
+ c.flag %i[a attr], multiple: true
394
+
395
+ c.desc 'Filter by tag'
396
+ c.flag %i[t tag], multiple: true
397
+
398
+ c.desc 'List local build generations'
399
+ c.switch %i[l local]
400
+
401
+ c.desc 'List remote machine generations'
402
+ c.switch %i[r remote]
403
+
404
+ c.action(&Command.run(c, Generation, :list))
405
+ end
406
+
407
+ gen.desc 'Remove machine generations'
408
+ gen.arg_name '[machine-pattern [generation-pattern|old]]'
409
+ gen.command :rm do |c|
410
+ c.desc 'Filter by attribute'
411
+ c.flag %i[a attr], multiple: true
412
+
413
+ c.desc 'Filter by tag'
414
+ c.flag %i[t tag], multiple: true
415
+
416
+ c.desc 'List local build generations'
417
+ c.switch %i[l local]
418
+
419
+ c.desc 'List remote machine generations'
420
+ c.switch %i[r remote]
421
+
422
+ c.desc 'Run nix-collect-garbage to delete unreachable store paths'
423
+ c.switch %i[gc collect-garbage], default_value: true
424
+
425
+ c.desc 'Max number of concurrent nix-collect-garbage processes'
426
+ c.flag 'max-concurrent-gc', arg_name: 'n', type: Integer,
427
+ default_value: 5
428
+
429
+ c.desc 'Assume the answer to confirmations is yes'
430
+ c.switch %w[y yes]
431
+
432
+ c.action(&Command.run(c, Generation, :remove))
433
+ end
434
+
435
+ gen.desc 'Auto-remove old machine generations'
436
+ gen.arg_name '[machine-pattern]'
437
+ gen.command :rotate do |c|
438
+ c.desc 'Filter by attribute'
439
+ c.flag %i[a attr], multiple: true
440
+
441
+ c.desc 'Filter by tag'
442
+ c.flag %i[t tag], multiple: true
443
+
444
+ c.desc 'List local build generations'
445
+ c.switch %i[l local]
446
+
447
+ c.desc 'List remote machine generations'
448
+ c.switch %i[r remote]
449
+
450
+ c.desc 'Max number of concurrent nix-collect-garbage processes'
451
+ c.flag 'max-concurrent-gc', arg_name: 'n', type: Integer,
452
+ default_value: 5
453
+
454
+ c.desc 'Assume the answer to confirmations is yes'
455
+ c.switch %w[y yes]
456
+
457
+ c.action(&Command.run(c, Generation, :rotate))
458
+ end
459
+ end
460
+
461
+ desc 'Run nix-collect-garbage to deleted unreachable store paths'
462
+ arg_name '[machine-pattern]'
463
+ command 'collect-garbage' do |c|
464
+ c.desc 'Filter by attribute'
465
+ c.flag %i[a attr], multiple: true
466
+
467
+ c.desc 'Filter by tag'
468
+ c.flag %i[t tag], multiple: true
469
+
470
+ c.desc 'Max number of concurrent nix-collect-garbage processes'
471
+ c.flag 'max-concurrent-gc', arg_name: 'n', type: Integer,
472
+ default_value: 5
473
+
474
+ c.desc 'Assume the answer to confirmations is yes'
475
+ c.switch %w[y yes]
476
+
477
+ c.action(&Command.run(c, Generation, :collect_garbage))
478
+ end
479
+
480
+ desc 'Generate data files'
481
+ command 'gen-data' do |gen|
482
+ gen.desc 'Fetch data from vpsAdmin'
483
+ gen.command :vpsadmin do |vpsa|
484
+ vpsa.desc 'Generate all data files'
485
+ vpsa.command :all do |c|
486
+ c.action(&Command.run(c, GenData, :vpsadmin_all))
487
+ end
488
+
489
+ vpsa.desc 'Generate container data files'
490
+ vpsa.command :containers do |c|
491
+ c.action(&Command.run(c, GenData, :vpsadmin_containers))
492
+ end
493
+
494
+ vpsa.desc 'Generate network data files'
495
+ vpsa.command :network do |c|
496
+ c.action(&Command.run(c, GenData, :vpsadmin_network))
497
+ end
498
+ end
499
+ end
500
+
501
+ ConfCtl::UserScripts.each do |script|
502
+ script.setup_cli(self)
503
+ end
504
+
505
+ on_error do |_exception|
506
+ log = ConfCtl::Logger.instance
507
+ warn "\nLog file: #{log.path}" if log.open?
508
+ true
509
+ end
510
+ end
511
+
512
+ protected
513
+
514
+ def swpins_commands(cmd, klass, arg_name)
515
+ cmd.desc 'Set to specific version'
516
+ cmd.arg_name "<#{arg_name}> <sw> <ref>"
517
+ cmd.command :set do |c|
518
+ c.desc 'Commit changes to git'
519
+ c.switch :commit, default_value: false
520
+
521
+ c.desc 'Include changelog in the commit message'
522
+ c.switch :changelog, default_value: true
523
+
524
+ c.desc 'Generate changelog for downgrade'
525
+ c.switch %i[d downgrade], default_value: false
526
+
527
+ c.action(&Command.run(c, klass, :set))
528
+ end
529
+
530
+ cmd.desc 'Update to newest version'
531
+ cmd.arg_name "[<#{arg_name}> [<sw> [<version...>]]]"
532
+ cmd.command :update do |c|
533
+ c.desc 'Commit changes to git'
534
+ c.switch :commit, default_value: false
535
+
536
+ c.desc 'Include changelog in the commit message'
537
+ c.switch :changelog, default_value: true
538
+
539
+ c.desc 'Generate changelog for downgrade'
540
+ c.switch %i[d downgrade], default_value: false
541
+
542
+ c.action(&Command.run(c, klass, :update))
543
+ end
544
+ end
545
+
546
+ def nix_build_options(cmd)
547
+ cmd.desc 'Maximum number of build jobs (see nix-build)'
548
+ cmd.flag %w[j max-jobs], arg_name: 'number'
549
+ end
550
+ end
551
+ end
@@ -0,0 +1,51 @@
1
+ module ConfCtl::Cli
2
+ class AttrFilters
3
+ # @param str_filters [Array<String>]
4
+ def initialize(str_filters)
5
+ @filters = parse_all(str_filters)
6
+ end
7
+
8
+ # @param machine [ConfCtl::Machine]
9
+ def pass?(machine)
10
+ filters.all? { |f| f.call(machine) }
11
+ end
12
+
13
+ protected
14
+
15
+ attr_reader :filters
16
+
17
+ def parse_all(str_filters)
18
+ ret = []
19
+
20
+ str_filters.each do |s|
21
+ k, v = parse_one(s, '!=')
22
+ if k
23
+ ret << proc do |machine|
24
+ machine[k].to_s != v
25
+ end
26
+ next
27
+ end
28
+
29
+ k, v = parse_one(s, '=')
30
+ if k
31
+ ret << proc do |machine|
32
+ machine[k].to_s == v
33
+ end
34
+ next
35
+ end
36
+
37
+ raise GLI::BadCommandLine, "Invalid filter '#{v}'"
38
+ end
39
+
40
+ ret
41
+ end
42
+
43
+ def parse_one(v, sep)
44
+ i = v.index(sep)
45
+ return false unless i
46
+
47
+ len = sep.length
48
+ [v[0..i - 1], v[i + len..]]
49
+ end
50
+ end
51
+ end