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
data/README.md ADDED
@@ -0,0 +1,522 @@
1
+ # confctl
2
+ confctl is a Nix deployment configuration management tool. It can be used to
3
+ build and deploy [NixOS](https://nixos.org) and [vpsAdminOS](https://vpsadminos.org)
4
+ machines.
5
+
6
+ ## Features
7
+
8
+ * Stateless
9
+ * Per-machine nixpkgs (both modules and packages)
10
+ * Build generations for easy rollback
11
+ * Rotation of old generations
12
+ * Support for configuration interconnections (declare and access other machines'
13
+ configurations)
14
+ * Query machine state, view changelogs and diffs
15
+ * Run health checks
16
+
17
+ ## Requirements
18
+
19
+ * [Nix](https://nixos.org)
20
+
21
+ ## Quick start
22
+ 1. Either install confctl as a gem:
23
+ ```
24
+ gem install confctl
25
+ ```
26
+
27
+ Or clone this repository:
28
+
29
+ ```
30
+ git clone https://github.com/vpsfreecz/confctl
31
+ ```
32
+
33
+ This guide assumes you have cloned the repository, because otherwise man will
34
+ not find confctl's manual pages. If you install confctl using gem, you can
35
+ ignore steps with `shell.nix`.
36
+
37
+ 2. Create a new directory, where your confctl-managed configuration will be
38
+ stored:
39
+
40
+ ```
41
+ mkdir cluster-configuration
42
+ ```
43
+ 3. Prepare `shell.nix` in the new directory:
44
+ - Create a `shell.nix` and import the same file from confctl:
45
+ ```
46
+ cd cluster-configuration
47
+ cat > shell.nix <<EOF
48
+ import ../confctl/shell.nix
49
+ EOF
50
+ ```
51
+
52
+ - Alternatively, you can symlink `shell.nix` from the confctl repository:
53
+ ```
54
+ cd cluster-configuration
55
+ ln -s ../confctl/shell.nix shell.nix
56
+ ```
57
+
58
+ 4. Enter the `nix-shell`. This will make confctl available and install its
59
+ dependencies into `.gems/`:
60
+ ```
61
+ nix-shell
62
+ ```
63
+
64
+ From within the shell, you can access the [manual](./man/man8/confctl.8.md)
65
+ and a list of [configuration options](./man/man8/confctl-options.nix.8.md):
66
+
67
+ ```
68
+ man confctl
69
+ man confctl-options.nix
70
+ ```
71
+
72
+ 5. Initialize the configuration directory with confctl:
73
+ ```
74
+ confctl init
75
+ ```
76
+
77
+ 6. Add a new machine to be deployed:
78
+ ```
79
+ confctl add my-machine
80
+ ```
81
+
82
+ You can now edit the machine's configuration in directory `cluster/my-machine`.
83
+
84
+ 7. Update pre-configured software pins to fetch current nixpkgs:
85
+ ```
86
+ confctl swpins update
87
+ ```
88
+
89
+ 8. Build the machine
90
+ ```
91
+ confctl build my-machine
92
+ ```
93
+
94
+ 9. Deploy the machine
95
+ ```
96
+ confctl deploy my-machine
97
+ ```
98
+
99
+ ## Example configuration
100
+ Example configuration, which can be used as a starting point, can be found in
101
+ directory [example/](example/).
102
+
103
+ See also existing configurations:
104
+
105
+ * [vpsfree-cz-configuration](https://github.com/vpsfreecz/vpsfree-cz-configuration)
106
+ * [vpsadminos-org-configuration](https://github.com/vpsfreecz/vpsadminos-org-configuration)
107
+
108
+ ## Configuration directory structure
109
+ `confctl` configurations should adhere to the following structure:
110
+
111
+ cluster-configuration/ # Configuration root
112
+ ├── cluster/ # Machine configurations
113
+ │ ├── <name>/ # Single machine, can be nested directories
114
+ │ │ ├── config.nix # Standard NixOS system configuration
115
+ │ │ └── module.nix # Config with machine metadata used by confctl
116
+ │ ├── cluster.nix # confctl-generated list of machines
117
+ │ └── module-list.nix # List of all machine modules (including those in cluster.nix)
118
+ ├── configs/ # confctl and other user-defined configs
119
+ │ ├── confctl.nix # Configuration for the confctl tool itself
120
+ │ └── swpins.nix # User-defined software pin channels
121
+ ├── data/ # User-defined datasets available in machine configurations as confData
122
+ ├── environments/ # Environment presets for various types of machines, optional
123
+ ├── modules/ # User-defined modules
124
+ │ └── cluster/default.nix # User-defined extensions of `cluster.` options used in `<machine>/module.nix` files
125
+ ├── scripts/ # User-defined scripts
126
+ ├── swpins/ # confctl-generated software pins configuration
127
+ └── shell.nix # Nix expression for nix-shell
128
+
129
+ ## Software pins
130
+ Software pins in confctl allow you to use specific revisions of
131
+ [nixpkgs](https://github.com/NixOS/nixpkgs) or any other software to build
132
+ and deploy target machines. It doesn't matter what nixpkgs version the build
133
+ machine uses, because each machine gets its own nixpkgs as configured by the
134
+ software pin.
135
+
136
+ Software pins can be grouped in channels, which can then be used by all
137
+ or selected machines in the configuration. Or, if needed, custom software pins
138
+ can be configured on selected machines. See below for usage examples.
139
+
140
+ ## Software pin channels
141
+ Software pin channels are defined in file `confctl/swpins.nix`:
142
+
143
+ ```nix
144
+ { config, ... }:
145
+ {
146
+ confctl.swpins.channels = {
147
+ # Channel for NixOS unstable
148
+ nixos-unstable = { # channel name
149
+ nixpkgs = { # swpin name
150
+ # git-rev fetches the contents of a git commit and adds information
151
+ # about the current git revision
152
+ type = "git-rev";
153
+
154
+ git-rev = { # swpin type-specific configuration
155
+ # Repository URL
156
+ url = "https://github.com/NixOS/nixpkgs";
157
+
158
+ # Fetch git submodules or not
159
+ fetchSubmodules = false;
160
+
161
+ # git reference to use for manual/automated update using
162
+ # `confctl swpins channel update`
163
+ update.ref = "refs/heads/nixos-unstable";
164
+
165
+ # Whether to enable automated updates triggered by `confctl build | deploy`
166
+ update.auto = true;
167
+
168
+ # If update.auto is true, this determines how frequently will confctl
169
+ # try to update the channel, in seconds
170
+ update.interval = 60*60;
171
+ };
172
+ };
173
+ };
174
+
175
+ # Channel for vpsAdminOS staging
176
+ vpsadminos-staging = {
177
+ vpsadminos = {
178
+ type = "git-rev";
179
+
180
+ git-rev = {
181
+ url = "https://github.com/vpsfreecz/vpsadminos";
182
+ update.ref = "refs/heads/staging";
183
+ update.auto = true;
184
+ };
185
+ };
186
+ };
187
+ };
188
+ }
189
+ ```
190
+
191
+ This configuration defines what channels exist, what packages they contain
192
+ and how to fetch them. Such configured channels can then be manipulated using
193
+ `confctl`. `confctl` prefetches selected software pins and saves their hashes
194
+ in JSON files in the `swpins/` directory.
195
+
196
+ ```
197
+ # List channels
198
+ $ confctl swpins channel ls
199
+ CHANNEL SW TYPE PIN
200
+ nixos-unstable nixpkgs git-rev 1f77a4c8
201
+ vpsadminos-staging vpsadminos git-rev 9c9a7bcb
202
+
203
+ # Update channels with update.auto = true to reference in update.ref
204
+ $ confctl swpins channel update
205
+
206
+ # You can update only selected channels or swpins
207
+ $ confctl swpins channel update nixos-unstable
208
+ $ confctl swpins channel update nixos-unstable nixpkgs
209
+
210
+ # Set swpin to a custom git reference
211
+ $ confctl swpins channel set nixos-unstable nixpkgs 1f77a4c8
212
+ ```
213
+
214
+ `confctl build` and `confctl deploy` will now use the prefetched software pins.
215
+
216
+ ## Machine metadata and software pins
217
+ Machine configuration directory usually contains at least two files:
218
+ `cluster/<machine name>/config.nix` and `cluster/<machine name>/module.nix`.
219
+
220
+ `config.nix` is evaluated only when that particular machine is being built. It is
221
+ a standard NixOS configuration module, similar to `/etc/nixos/configuration.nix`.
222
+
223
+ `module.nix` is specific to confctl configurations. `module.nix` files from
224
+ all machines are evaluated during every build, whether that particular machine
225
+ is being built or not. `module.nix` contains metadata about machines from which
226
+ confctl knows how to treat them. It is also used to declare which software pins
227
+ or channels the machine uses. Metadata about any machine can be read from
228
+ `config.nix` of any other machine.
229
+
230
+ For example, machine named `my-machine` would be described in
231
+ `cluster/my-machine/module.nix` as:
232
+
233
+ ```nix
234
+ { config, ... }:
235
+ {
236
+ cluster."my-machine" = {
237
+ # This tells confctl whether it is a NixOS or vpsAdminOS machine
238
+ spin = "nixos";
239
+
240
+ # Use NixOS unstable channel defined in configs/swpins.nix
241
+ swpins.channels = [ "nixos-unstable" ];
242
+
243
+ # If the machine name is not a hostname, configure the address to which
244
+ # should confctl deploy it
245
+ host.target = "<ip address>";
246
+ };
247
+ }
248
+ ```
249
+
250
+ See [man/man8/confctl-options.nix.8.md](./man/man8/confctl-options.nix.8.md)
251
+ for a list of all options.
252
+
253
+ ## Per-machine software pins
254
+ It is simpler to use software pins from channels, because they are usually
255
+ used by multiple machines, but it is possible to define per-machine software
256
+ pins, either to override pins from channels or add custom ones.
257
+
258
+ Per-machine software pins are configured in the machine's `module.nix` file:
259
+
260
+ ```nix
261
+ { config, ... }:
262
+ {
263
+ cluster."my-machine" = {
264
+ # List of channels
265
+ swpins.channels = [ "..." ];
266
+
267
+ # Per-machine swpins
268
+ swpins.pins = {
269
+ "pin-name" = {
270
+ type = "git-rev";
271
+ git-rev = {
272
+ # ...pin definition...
273
+ };
274
+ };
275
+ };
276
+ };
277
+ }
278
+ ```
279
+
280
+ The configuration is exactly the same as that of software pins in channels.
281
+ Instead of `confctl swpins channel` commands, use `confctl swpins cluster`
282
+ to manage configured pins.
283
+
284
+ ## Nix flakes
285
+ confctl's software pins are an alternative to flakes and flakes are not supported
286
+ by confctl at this time. Software pins are implemented by manipulating the `$NIX_PATH`
287
+ environment variable, which is in conflict with using flakes. confctl is likely
288
+ to be migrated to flakes when the interface will be stabilized. Since the transition
289
+ is going to require a significant effort, there are no plans for it currently.
290
+
291
+ ## Extra module arguments
292
+ Machine configs can use the following extra module arguments:
293
+
294
+ - `confDir` - path to the cluster configuration directory
295
+ - `confLib` - confctl functions, see [nix/lib/default.nix](nix/lib/default.nix)
296
+ - `confData` - access to user-defined datasets found in `data/default.nix`,
297
+ see [example/data/default.nix](example/data/default.nix)
298
+ - `confMachine` - attrset with information about the machine that is currently
299
+ being built, contains key `name` and all options from
300
+ [machine metadata module](##machine-metadata-and-software-pins)
301
+ - `swpins` - attrset of software pins of the machine that is currently being built
302
+
303
+ For example in `cluster/my-machine/config.nix`:
304
+
305
+ ```nix
306
+ { config, lib, pkgs, confLib, confData, confMachine, ... }:
307
+ {
308
+ # Set the hostname to the machine name from confctl
309
+ networking.hostName = confMachine.name;
310
+
311
+ # When used with the data defined at example/data/default.nix
312
+ users.users.root.openssh.authorizedKeys.keys = with confData.sshKeys; admins;
313
+ }
314
+ ```
315
+
316
+ ## confctl configuration
317
+ The `confctl` utility itself can be configured using `configs/confctl.nix`:
318
+
319
+ ```nix
320
+ { config, ... }:
321
+ {
322
+ confctl = {
323
+ # Columns that are shown by `confctl ls`. Any option from machine metadata
324
+ # can be used.
325
+ listColumns = {
326
+ "name"
327
+ "spin"
328
+ "host.fqdn"
329
+ };
330
+ };
331
+ }
332
+ ```
333
+
334
+ ## Health checks
335
+ Health checks can be used to verify that the deployed systems behave correctly,
336
+ all services are running, etc. Health checks are run automatically after deploy
337
+ and can also be run on demand using `confctl health-check`. Health checks are
338
+ configured in machine metadata module, i.e. in `cluster/<machine>/module.nix`
339
+ files.
340
+
341
+ ```nix
342
+ { config, ... }:
343
+ {
344
+ cluster."my-machine" = {
345
+ # [...]
346
+
347
+ healthChecks = {
348
+ # Check that there are no failed units (this is actually done automatically
349
+ # by confctl, you don't need to do this yourself)
350
+ systemd.systemProperties = [
351
+ { property = "SystemState"; value = "running"; }
352
+ ];
353
+
354
+ # Check that the firewall is active, we can check any property of any service
355
+ systemd.unitProperties."firewall.service" = [
356
+ { property = "ActiveState"; value = "active"; }
357
+ ];
358
+
359
+ # Run arbitrary commands from the builder
360
+ builderCommands = [
361
+ # Ping the deployed machine
362
+ { command = [ "ping" "-c1" "{host.fqdn}" ]; }
363
+ ];
364
+
365
+ # Run commands on the deployed machine
366
+ machineCommands = [
367
+ # Try to access a fictional internal web server
368
+ { command = [ "curl" "-s" "http://localhost:80" ]; }
369
+
370
+ # We can also check command output
371
+ { command = [ "hostname" ]; standardOutput.match = "my-machine\n"; }
372
+ ];
373
+ };
374
+ };
375
+ }
376
+ ```
377
+
378
+ ## Rotate build generations
379
+ confctl can be used to rotate old generations both on the build machine
380
+ and on the deployed machines.
381
+
382
+ Default rotation settings can be set in confctl settings at `configs/confctl.nix`:
383
+
384
+ ```nix
385
+ { config, lib, ... }:
386
+ with lib;
387
+ {
388
+ confctl = {
389
+ # Generations on the build machine
390
+ buildGenerations = {
391
+ # Keep at least 4 generations
392
+ min = mkDefault 4;
393
+
394
+ # Do not keep more than 10 generations
395
+ max = mkDefault 10;
396
+
397
+ # Delete generations older than 90 days
398
+ maxAge = mkDefault (90*24*60*60);
399
+ };
400
+
401
+ # The same settings can be configured for generations on the deployed machines
402
+ hostGenerations = {
403
+ min = mkDefault 40;
404
+ max = mkDefault 100;
405
+ maxAge = mkDefault (180*24*60*60);
406
+
407
+ # On the deployed machines, confctl can also run nix-collect-garbage to
408
+ # delete unreachable store paths
409
+ collectGarbage = mkDefault true;
410
+ };
411
+ };
412
+ }
413
+ ```
414
+
415
+ If these settings are not set, confctl uses its own defaults. Further, rotation
416
+ settings can be configured on per-machine basis in machine metadata module
417
+ at `cluster/<machine>/module.nix`:
418
+
419
+ ```nix
420
+ { config, ... }:
421
+ {
422
+ cluster."my-machine" = {
423
+ # [...]
424
+
425
+ buildGenerations = {
426
+ min = 8;
427
+ max = 16;
428
+ };
429
+
430
+ hostGenerations = {
431
+ min = 80;
432
+ };
433
+ };
434
+ }
435
+ ```
436
+
437
+ Settings from the machine metadata modules override default confctl settings
438
+ from `configs/confctl.nix`.
439
+
440
+ To rotate the generations both on the build and deployed machines, run:
441
+
442
+ ```
443
+ confctl generation rotate --local --remote
444
+ ```
445
+
446
+ Generations can also be deleted manually, e.g. to delete generations older than
447
+ 90 days, run:
448
+
449
+ ```
450
+ confctl generation rm --local --remote '*' 30d
451
+ ```
452
+
453
+ ## Extending machine metadata
454
+ To define your own options to be used within the `cluster.<name>` modules in
455
+ `cluster/<machine>/module.nix` files, create file `modules/cluster/default.nix`,
456
+ e.g.:
457
+
458
+ ```nix
459
+ { config, lib, ... }:
460
+ with lib;
461
+ let
462
+ myMachine =
463
+ { config, ... }:
464
+ {
465
+ options = {
466
+ myParameter = mkOption { ... };
467
+ };
468
+ };
469
+ in {
470
+ options = {
471
+ cluster = mkOption {
472
+ type = types.attrsOf (types.submodule myMachine);
473
+ };
474
+ };
475
+ }
476
+ ```
477
+
478
+ Then you can use it in machine module as:
479
+
480
+ ```nix
481
+ { config, ... }:
482
+ {
483
+ cluster."my-machine" = {
484
+ myParameter = "1234";
485
+ };
486
+ }
487
+ ```
488
+
489
+ Note that these modules are self-contained. They are not evaluated with the full
490
+ set of NixOS modules. You have to import modules that you need.
491
+
492
+ ## User-defined confctl commands
493
+ User-defined Ruby scripts can be placed in directory `scripts`. Each script
494
+ should create a subclass of `ConfCtl::UserScript` and call class-method `register`.
495
+ Scripts can define their own `confctl` subcommands.
496
+
497
+ ### Example user script
498
+
499
+ ```ruby
500
+ class MyScript < ConfCtl::UserScript
501
+ register
502
+
503
+ def setup_cli(app)
504
+ app.desc 'My CLI command'
505
+ app.command 'my-command' do |c|
506
+ c.action &ConfCtl::Cli::Command.run(c, MyCommand, :run)
507
+ end
508
+ end
509
+ end
510
+
511
+ class MyCommand < ConfCtl::Cli::Command
512
+ def run
513
+ puts 'Hello world'
514
+ end
515
+ end
516
+ ```
517
+
518
+ ## More information
519
+ See the [man pages](./man/man8) for more information:
520
+
521
+ * [confctl(8)](./man/man8/confctl.8.md)
522
+ * [confctl-options.nix(8)](./man/man8/confctl-options.nix.8.md)
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'confctl'
3
+ require 'md2man/rakefile'
4
+ require 'md2man/roff/engine'
5
+ require 'md2man/html/engine'
6
+
7
+ # Override markdown engine to add extra parameter
8
+ [Md2Man::Roff, Md2Man::HTML].each do |mod|
9
+ mod.send(:remove_const, :ENGINE)
10
+ mod.send(:const_set, :ENGINE, Redcarpet::Markdown.new(mod.const_get(:Engine),
11
+ tables: true,
12
+ autolink: true,
13
+ superscript: true,
14
+ strikethrough: true,
15
+ no_intra_emphasis: false,
16
+ fenced_code_blocks: true,
17
+
18
+ # This option is needed for command options to be rendered property
19
+ disable_indented_code_blocks: true))
20
+ end
21
+
22
+ desc 'Generate man/man8/confctl-options.nix.8.md'
23
+ task 'confctl-options' do
24
+ ConfCtl::Logger.open('rake', output: $stdout)
25
+
26
+ opts = ConfCtl::ModuleOptions.new(nix: ConfCtl::Nix.stateless)
27
+ opts.read
28
+
29
+ ConfCtl::ErbTemplate.render_to('confctl-options.nix/main', {
30
+ date: Time.now,
31
+ version: 'master',
32
+ opts:,
33
+ print_options: proc do |opt_list|
34
+ ConfCtl::ErbTemplate.render('confctl-options.nix/options', {
35
+ opts: opt_list,
36
+ indent: proc { |s, n| s.split("\n").join("\n#{' ' * n}") }
37
+ })
38
+ end
39
+ }, 'man/man8/confctl-options.nix.8.md')
40
+ end
data/bin/confctl ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'confctl'
3
+ require 'confctl/cli'
4
+ ConfCtl::Cli::App.run
data/confctl.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $:.unshift(lib) unless $:.include?(lib)
3
+ require 'confctl/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'confctl'
7
+
8
+ s.version = ConfCtl::VERSION
9
+ s.summary =
10
+ s.description = 'Nix deployment management tool'
11
+ s.authors = 'Jakub Skokan'
12
+ s.email = 'jakub.skokan@vpsfree.cz'
13
+ s.files = `git ls-files -z`.split("\x0")
14
+ s.files += Dir['man/man?/*.?']
15
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ s.license = 'GPL-3.0-only'
17
+
18
+ s.required_ruby_version = ">= #{File.read('.ruby-version').strip}"
19
+
20
+ s.add_runtime_dependency 'curses'
21
+ s.add_runtime_dependency 'gli', '~> 2.21.0'
22
+ s.add_runtime_dependency 'json'
23
+ s.add_runtime_dependency 'md2man'
24
+ s.add_runtime_dependency 'rainbow', '~> 3.1.1'
25
+ s.add_runtime_dependency 'rake'
26
+ s.add_runtime_dependency 'require_all', '~> 2.0.0'
27
+ s.add_runtime_dependency 'tty-command', '~> 0.10.1'
28
+ s.add_runtime_dependency 'tty-cursor', '~> 0.7.1'
29
+ s.add_runtime_dependency 'tty-pager', '~> 0.14.0'
30
+ s.add_runtime_dependency 'tty-progressbar', '~> 0.18.2'
31
+ s.add_runtime_dependency 'tty-spinner', '~> 0.9.3'
32
+ s.add_runtime_dependency 'vpsfree-client', '~> 0.18.0'
33
+ end
@@ -0,0 +1,2 @@
1
+ .confctl
2
+ .gems
data/example/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # confctl example configuration
2
+ There are four skeleton deployments:
3
+
4
+ * `nixos-machine` to deploy a standard NixOS machine
5
+ * `vpsadminos-machine` to deploy vpsAdminOS machine
6
+ * `vpsadminos-container` to deploy to a container running on vpsAdminOS
7
+ * `vpsfreecz-container` to deploy to a VPS at [vpsFree.cz](https://vpsfree.org),
8
+ which is the same as `vpsadminos-container`
9
+
10
+ ## Usage
11
+ 1. Enter `nix-shell`:
12
+ ```
13
+ nix-shell
14
+ ```
15
+
16
+ 2. Update software pins:
17
+ ```
18
+ confctl swpins update
19
+ ```
20
+
21
+ 3. Edit configurations in `cluster/` to your liking.
22
+
23
+ Note that to deploy physical machines, you have to supply `hardware.nix` file,
24
+ which is generated by `nixos-generate-config` when installing NixOS, you'll find
25
+ it at `/etc/nixos/hardware-configuration.nix`. confctl cannot actually install
26
+ or provision a machine, it has to already be installed and running. confctl will
27
+ deploy the new system over SSH and activate it.
28
+
29
+ Target IP addresses to which the systems will be deployed to can be set
30
+ in `cluster/*/module.nix`, option `target.host`.
31
+
32
+ Configure SSH keys in `data/ssh-keys.nix`.
33
+
34
+ 4. Build and deploy
35
+ ```
36
+ confctl build vpsfreecz-vps
37
+ confctl deploy vpsfreecz-vps
38
+ ```
@@ -0,0 +1,7 @@
1
+ # This file is generated by confctl, changes will be lost
2
+ [
3
+ ./nixos-machine/module.nix
4
+ ./vpsadminos-container/module.nix
5
+ ./vpsadminos-machine/module.nix
6
+ ./vpsfreecz-vps/module.nix
7
+ ]
@@ -0,0 +1,3 @@
1
+ (import ./cluster.nix) ++ [
2
+ # Place for custom modules
3
+ ]
@@ -0,0 +1,15 @@
1
+ { config, pkgs, lib, ... }:
2
+ {
3
+ imports = [
4
+ ../../environments/base.nix
5
+ ./hardware.nix
6
+ ];
7
+
8
+ networking.hostName = "nixos-machine";
9
+
10
+ boot.loader.grub.enable = true;
11
+ boot.loader.grub.version = 2;
12
+ # boot.loader.grub.device = "";
13
+
14
+ system.stateVersion = "20.09";
15
+ }
@@ -0,0 +1,4 @@
1
+ { config, pkgs, lib, ... }:
2
+ {
3
+ # Your hardware-configuration.nix
4
+ }
@@ -0,0 +1,8 @@
1
+ { config, ... }:
2
+ {
3
+ cluster."nixos-machine" = {
4
+ spin = "nixos";
5
+ swpins.channels = [ "nixos-unstable" ];
6
+ host.target = "<ip address>";
7
+ };
8
+ }