confctl 1.0.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.
- checksums.yaml +7 -0
- data/.editorconfig +11 -0
- data/.gitignore +8 -0
- data/.overcommit.yml +6 -0
- data/.rubocop.yml +67 -0
- data/.rubocop_todo.yml +5 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +674 -0
- data/README.md +522 -0
- data/Rakefile +40 -0
- data/bin/confctl +4 -0
- data/confctl.gemspec +33 -0
- data/example/.gitignore +2 -0
- data/example/README.md +38 -0
- data/example/cluster/cluster.nix +7 -0
- data/example/cluster/module-list.nix +3 -0
- data/example/cluster/nixos-machine/config.nix +15 -0
- data/example/cluster/nixos-machine/hardware.nix +4 -0
- data/example/cluster/nixos-machine/module.nix +8 -0
- data/example/cluster/vpsadminos-container/config.nix +22 -0
- data/example/cluster/vpsadminos-container/module.nix +8 -0
- data/example/cluster/vpsadminos-machine/config.nix +22 -0
- data/example/cluster/vpsadminos-machine/hardware.nix +4 -0
- data/example/cluster/vpsadminos-machine/module.nix +8 -0
- data/example/cluster/vpsfreecz-vps/config.nix +25 -0
- data/example/cluster/vpsfreecz-vps/module.nix +8 -0
- data/example/configs/confctl.nix +10 -0
- data/example/configs/swpins.nix +28 -0
- data/example/data/default.nix +5 -0
- data/example/data/ssh-keys.nix +7 -0
- data/example/environments/base.nix +13 -0
- data/example/modules/module-list.nix +13 -0
- data/example/shell.nix +11 -0
- data/example/swpins/channels/nixos-unstable.json +35 -0
- data/example/swpins/channels/vpsadminos-staging.json +35 -0
- data/lib/confctl/cli/app.rb +551 -0
- data/lib/confctl/cli/attr_filters.rb +51 -0
- data/lib/confctl/cli/cluster.rb +1248 -0
- data/lib/confctl/cli/command.rb +206 -0
- data/lib/confctl/cli/configuration.rb +296 -0
- data/lib/confctl/cli/gen_data.rb +97 -0
- data/lib/confctl/cli/generation.rb +335 -0
- data/lib/confctl/cli/log_view.rb +267 -0
- data/lib/confctl/cli/output_formatter.rb +288 -0
- data/lib/confctl/cli/swpins/base.rb +40 -0
- data/lib/confctl/cli/swpins/channel.rb +73 -0
- data/lib/confctl/cli/swpins/cluster.rb +80 -0
- data/lib/confctl/cli/swpins/core.rb +86 -0
- data/lib/confctl/cli/swpins/utils.rb +55 -0
- data/lib/confctl/cli/swpins.rb +5 -0
- data/lib/confctl/cli/tag_filters.rb +30 -0
- data/lib/confctl/cli.rb +5 -0
- data/lib/confctl/conf_cache.rb +105 -0
- data/lib/confctl/conf_dir.rb +88 -0
- data/lib/confctl/erb_template.rb +37 -0
- data/lib/confctl/exceptions.rb +3 -0
- data/lib/confctl/gcroot.rb +30 -0
- data/lib/confctl/generation/build.rb +145 -0
- data/lib/confctl/generation/build_list.rb +106 -0
- data/lib/confctl/generation/host.rb +35 -0
- data/lib/confctl/generation/host_list.rb +81 -0
- data/lib/confctl/generation/unified.rb +117 -0
- data/lib/confctl/generation/unified_list.rb +63 -0
- data/lib/confctl/git_repo_mirror.rb +79 -0
- data/lib/confctl/health_checks/base.rb +66 -0
- data/lib/confctl/health_checks/run_command.rb +179 -0
- data/lib/confctl/health_checks/systemd/properties.rb +84 -0
- data/lib/confctl/health_checks/systemd/property_check.rb +31 -0
- data/lib/confctl/health_checks/systemd/property_list.rb +20 -0
- data/lib/confctl/health_checks.rb +5 -0
- data/lib/confctl/hook.rb +35 -0
- data/lib/confctl/line_buffer.rb +53 -0
- data/lib/confctl/logger.rb +151 -0
- data/lib/confctl/machine.rb +107 -0
- data/lib/confctl/machine_control.rb +172 -0
- data/lib/confctl/machine_list.rb +108 -0
- data/lib/confctl/machine_status.rb +135 -0
- data/lib/confctl/module_options.rb +95 -0
- data/lib/confctl/nix.rb +382 -0
- data/lib/confctl/nix_build.rb +108 -0
- data/lib/confctl/nix_collect_garbage.rb +64 -0
- data/lib/confctl/nix_copy.rb +49 -0
- data/lib/confctl/nix_format.rb +124 -0
- data/lib/confctl/nix_literal_expression.rb +15 -0
- data/lib/confctl/parallel_executor.rb +43 -0
- data/lib/confctl/pattern.rb +9 -0
- data/lib/confctl/settings.rb +50 -0
- data/lib/confctl/std_line_buffer.rb +40 -0
- data/lib/confctl/swpins/change_set.rb +151 -0
- data/lib/confctl/swpins/channel.rb +62 -0
- data/lib/confctl/swpins/channel_list.rb +47 -0
- data/lib/confctl/swpins/cluster_name.rb +94 -0
- data/lib/confctl/swpins/cluster_name_list.rb +15 -0
- data/lib/confctl/swpins/core.rb +137 -0
- data/lib/confctl/swpins/deployed_info.rb +23 -0
- data/lib/confctl/swpins/spec.rb +20 -0
- data/lib/confctl/swpins/specs/base.rb +184 -0
- data/lib/confctl/swpins/specs/directory.rb +51 -0
- data/lib/confctl/swpins/specs/git.rb +135 -0
- data/lib/confctl/swpins/specs/git_rev.rb +24 -0
- data/lib/confctl/swpins.rb +17 -0
- data/lib/confctl/system_command.rb +10 -0
- data/lib/confctl/user_script.rb +13 -0
- data/lib/confctl/user_scripts.rb +41 -0
- data/lib/confctl/utils/file.rb +21 -0
- data/lib/confctl/version.rb +3 -0
- data/lib/confctl.rb +43 -0
- data/man/man8/confctl-options.nix.8 +1334 -0
- data/man/man8/confctl-options.nix.8.md +1340 -0
- data/man/man8/confctl.8 +660 -0
- data/man/man8/confctl.8.md +654 -0
- data/nix/evaluator.nix +160 -0
- data/nix/lib/default.nix +83 -0
- data/nix/lib/machine/default.nix +74 -0
- data/nix/lib/machine/info.nix +5 -0
- data/nix/lib/swpins/eval.nix +71 -0
- data/nix/lib/swpins/options.nix +94 -0
- data/nix/machines.nix +31 -0
- data/nix/modules/cluster/default.nix +459 -0
- data/nix/modules/confctl/cli.nix +21 -0
- data/nix/modules/confctl/generations.nix +84 -0
- data/nix/modules/confctl/nix.nix +28 -0
- data/nix/modules/confctl/swpins.nix +55 -0
- data/nix/modules/module-list.nix +19 -0
- data/shell.nix +42 -0
- data/template/confctl-options.nix/main.erb +45 -0
- data/template/confctl-options.nix/options.erb +15 -0
- 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
|