confctl 2.2.2 → 3.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.
Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/.git-hooks/pre_commit/nixfmt.rb +13 -0
  3. data/.github/workflows/rspec.yml +64 -0
  4. data/.github/workflows/rubocop.yml +27 -0
  5. data/.github/workflows/tests.yml +139 -0
  6. data/.gitignore +12 -7
  7. data/.overcommit.yml +2 -0
  8. data/.rspec +1 -0
  9. data/.rubocop.yml +8 -1
  10. data/AGENTS.md +42 -0
  11. data/CHANGELOG.md +57 -0
  12. data/Gemfile +3 -2
  13. data/Gemfile.lock +198 -0
  14. data/README.md +166 -58
  15. data/Rakefile +5 -0
  16. data/confctl.gemspec +20 -2
  17. data/docs/carrier.md +3 -3
  18. data/docs/flake-inputs.md +159 -0
  19. data/docs/swpins-to-flakes.md +325 -0
  20. data/example/cluster/module-list.nix +2 -1
  21. data/example/cluster/nixos-machine/config.nix +12 -2
  22. data/example/cluster/nixos-machine/hardware.nix +6 -1
  23. data/example/cluster/vpsadminos-container/config.nix +6 -1
  24. data/example/cluster/vpsadminos-container/module.nix +4 -1
  25. data/example/cluster/vpsadminos-machine/config.nix +6 -1
  26. data/example/cluster/vpsadminos-machine/hardware.nix +6 -1
  27. data/example/cluster/vpsadminos-machine/module.nix +5 -2
  28. data/example/cluster/vpsfreecz-vps/config.nix +6 -1
  29. data/example/cluster/vpsfreecz-vps/module.nix +4 -1
  30. data/example/configs/swpins.nix +8 -3
  31. data/example/environments/base.nix +6 -1
  32. data/example/swpins/core.json +35 -0
  33. data/example-flake/.gitignore +2 -0
  34. data/example-flake/README.md +38 -0
  35. data/example-flake/cluster/cluster.nix +5 -0
  36. data/example-flake/cluster/module-list.nix +4 -0
  37. data/example-flake/cluster/nested/nixos-machine/config.nix +25 -0
  38. data/example-flake/cluster/nested/nixos-machine/hardware.nix +9 -0
  39. data/example-flake/cluster/nested/nixos-machine/module.nix +8 -0
  40. data/example-flake/cluster/nixos-machine/config.nix +25 -0
  41. data/example-flake/cluster/nixos-machine/hardware.nix +9 -0
  42. data/example-flake/cluster/nixos-machine/module.nix +8 -0
  43. data/example-flake/cluster/vpsadminos-container/config.nix +28 -0
  44. data/example-flake/cluster/vpsadminos-container/module.nix +8 -0
  45. data/example-flake/cluster/vpsadminos-machine/config.nix +27 -0
  46. data/example-flake/cluster/vpsadminos-machine/hardware.nix +9 -0
  47. data/example-flake/cluster/vpsadminos-machine/module.nix +8 -0
  48. data/example-flake/cluster/vpsfreecz-vps/config.nix +31 -0
  49. data/example-flake/cluster/vpsfreecz-vps/module.nix +8 -0
  50. data/example-flake/configs/confctl.nix +10 -0
  51. data/example-flake/data/default.nix +5 -0
  52. data/example-flake/data/ssh-keys.nix +7 -0
  53. data/example-flake/environments/base.nix +18 -0
  54. data/example-flake/flake.lock +75 -0
  55. data/example-flake/flake.nix +36 -0
  56. data/example-flake/modules/module-list.nix +13 -0
  57. data/example-flake/shell.nix +11 -0
  58. data/flake.lock +159 -0
  59. data/flake.nix +189 -0
  60. data/gemset.nix +1022 -0
  61. data/lib/confctl/cli/app.rb +145 -0
  62. data/lib/confctl/cli/attr_filters.rb +1 -1
  63. data/lib/confctl/cli/cluster.rb +681 -108
  64. data/lib/confctl/cli/command.rb +24 -2
  65. data/lib/confctl/cli/configuration.rb +171 -106
  66. data/lib/confctl/cli/generation.rb +65 -1
  67. data/lib/confctl/cli/inputs/channels.rb +190 -0
  68. data/lib/confctl/cli/inputs/machines.rb +83 -0
  69. data/lib/confctl/cli/inputs/root.rb +101 -0
  70. data/lib/confctl/cli/inputs.rb +5 -0
  71. data/lib/confctl/cli/log_view.rb +21 -10
  72. data/lib/confctl/cli/migrate/swpins_to_flakes.rb +866 -0
  73. data/lib/confctl/cli/migrate.rb +5 -0
  74. data/lib/confctl/cli/output_formatter.rb +5 -7
  75. data/lib/confctl/cli/swpins/base.rb +9 -0
  76. data/lib/confctl/cli/swpins/channel.rb +2 -5
  77. data/lib/confctl/cli/swpins/cluster.rb +2 -5
  78. data/lib/confctl/cli/swpins/core.rb +2 -5
  79. data/lib/confctl/config_type.rb +7 -0
  80. data/lib/confctl/flake_lock.rb +78 -0
  81. data/lib/confctl/flake_lock_diff.rb +36 -0
  82. data/lib/confctl/generation/build.rb +131 -24
  83. data/lib/confctl/generation/build_list.rb +4 -3
  84. data/lib/confctl/generation/unified.rb +14 -1
  85. data/lib/confctl/git_repo_mirror.rb +2 -2
  86. data/lib/confctl/health_checks/run_command.rb +3 -2
  87. data/lib/confctl/health_checks/systemd/properties.rb +1 -1
  88. data/lib/confctl/health_checks/systemd/property_list.rb +2 -2
  89. data/lib/confctl/inputs/commit_message.rb +125 -0
  90. data/lib/confctl/inputs/git_commit.rb +17 -0
  91. data/lib/confctl/inputs/nix_output_guard.rb +37 -0
  92. data/lib/confctl/inputs/setter.rb +179 -0
  93. data/lib/confctl/inputs/updater.rb +76 -0
  94. data/lib/confctl/inputs.rb +5 -0
  95. data/lib/confctl/inputs_info.rb +50 -0
  96. data/lib/confctl/line_buffer.rb +1 -1
  97. data/lib/confctl/machine.rb +18 -3
  98. data/lib/confctl/machine_control.rb +8 -2
  99. data/lib/confctl/machine_list.rb +2 -2
  100. data/lib/confctl/machine_status.rb +63 -20
  101. data/lib/confctl/nix/args.rb +48 -0
  102. data/lib/confctl/nix.rb +30 -437
  103. data/lib/confctl/nix_build_flake.rb +95 -0
  104. data/lib/confctl/nix_copy.rb +14 -2
  105. data/lib/confctl/nix_flake.rb +449 -0
  106. data/lib/confctl/nix_format.rb +3 -3
  107. data/lib/confctl/nix_legacy.rb +467 -0
  108. data/lib/confctl/swpins/change_set.rb +29 -3
  109. data/lib/confctl/swpins/specs/base.rb +2 -2
  110. data/lib/confctl/ui.rb +19 -0
  111. data/lib/confctl/version.rb +1 -1
  112. data/man/index.html +11 -0
  113. data/man/man8/confctl-options.nix.8.html +113 -0
  114. data/man/man8/confctl.8 +152 -21
  115. data/man/man8/confctl.8.html +355 -0
  116. data/man/man8/confctl.8.md +148 -17
  117. data/man/style.css +301 -0
  118. data/nix/evaluator.nix +94 -69
  119. data/nix/flake/mk-confctl-devshell.nix +85 -0
  120. data/nix/flake/mk-confctl-outputs.nix +522 -0
  121. data/nix/flake/mk-config-devshell.nix +168 -0
  122. data/nix/lib/default.nix +118 -65
  123. data/nix/lib/machine/default.nix +65 -45
  124. data/nix/lib/machine/info.nix +16 -5
  125. data/nix/lib/swpins/eval.nix +42 -29
  126. data/nix/lib/swpins/options.nix +6 -2
  127. data/nix/machines.nix +23 -15
  128. data/nix/modules/cluster/default.nix +104 -41
  129. data/nix/modules/confctl/carrier/base.nix +11 -4
  130. data/nix/modules/confctl/carrier/carrier-env.rb +2 -2
  131. data/nix/modules/confctl/carrier/netboot/build-netboot-server.rb +50 -16
  132. data/nix/modules/confctl/carrier/netboot/nixos.nix +56 -24
  133. data/nix/modules/confctl/configuration-info.nix +17 -0
  134. data/nix/modules/confctl/generations.nix +2 -2
  135. data/nix/modules/confctl/host.nix +13 -0
  136. data/nix/modules/confctl/inputs-info.nix +21 -0
  137. data/nix/modules/confctl/kexec-netboot/default.nix +13 -6
  138. data/nix/modules/confctl/kexec-netboot/kexec-netboot.8.adoc +3 -0
  139. data/nix/modules/confctl/kexec-netboot/kexec-netboot.rb +25 -16
  140. data/nix/modules/confctl/nix.nix +31 -1
  141. data/nix/modules/confctl/swpins.nix +13 -6
  142. data/nix/modules/module-list.nix +4 -2
  143. data/nix/modules/system-list.nix +4 -1
  144. data/nix/package.nix +37 -0
  145. data/shell.nix +39 -8
  146. data/skills/confctl-configuration-update/SKILL.md +228 -0
  147. data/skills/confctl-configuration-update/agents/openai.yaml +4 -0
  148. data/skills/confctl-release/SKILL.md +102 -0
  149. data/skills/confctl-release/agents/openai.yaml +4 -0
  150. data/spec/confctl/cli/cluster_health_check_spec.rb +43 -0
  151. data/spec/confctl/cli/cluster_skip_current_deploy_spec.rb +157 -0
  152. data/spec/confctl/cli/cluster_status_flake_spec.rb +83 -0
  153. data/spec/confctl/cli/inputs_set_output_spec.rb +70 -0
  154. data/spec/confctl/configuration_spec.rb +45 -0
  155. data/spec/confctl/inputs_spec.rb +104 -0
  156. data/spec/confctl/machine_control_spec.rb +112 -0
  157. data/spec/confctl/machine_list_spec.rb +47 -0
  158. data/spec/confctl/nix_flake_spec.rb +41 -0
  159. data/spec/confctl/swpins_spec.rb +106 -0
  160. data/spec/generation/build_modes_spec.rb +132 -0
  161. data/spec/inputs/commit_message_spec.rb +205 -0
  162. data/spec/inputs/nix_cached_fallback_spec.rb +50 -0
  163. data/spec/inputs/nix_output_guard_spec.rb +45 -0
  164. data/spec/spec_helper.rb +12 -0
  165. data/spec/support/cli_helper.rb +57 -0
  166. data/test-runner.sh +7 -0
  167. data/tests/all-tests.nix +30 -0
  168. data/tests/make-test.nix +15 -0
  169. data/tests/runner/extensions/confctl_helpers.rb +238 -0
  170. data/tests/runner/extensions/hostfwd_ports.rb +41 -0
  171. data/tests/suite/auto_rollback.nix +344 -0
  172. data/tests/suite/carrier/deploy.nix +751 -0
  173. data/tests/suite/carrier/netboot.nix +849 -0
  174. data/tests/suite/deploy/base.nix +806 -0
  175. data/tests/suite/deploy/flakes.nix +1 -0
  176. data/tests/suite/deploy/swpins.nix +1 -0
  177. metadata +104 -4
  178. data/nix/modules/confctl/overlays.nix +0 -15
data/man/style.css ADDED
@@ -0,0 +1,301 @@
1
+ @import url('https://maxcdn.bootstrapcdn.com/bootstrap/2.3.2/css/bootstrap.min.css');
2
+
3
+ @media all {
4
+ h1,
5
+ h2,
6
+ h3,
7
+ h4,
8
+ h5,
9
+ h6 {
10
+ margin-top: 1em;
11
+ }
12
+
13
+ /* deactivate external manual page cross-references */
14
+ a.md2man-reference:not([href]) {
15
+ color: inherit;
16
+ text-decoration: none;
17
+ }
18
+ }
19
+
20
+ @media screen {
21
+ body {
22
+ font-family: monospace;
23
+ text-align: justify;
24
+ max-width: 83ch; /* 80 chars, +3 for Bootstrap CSS */
25
+ margin: auto;
26
+ }
27
+
28
+ h1:first-child {
29
+ margin-top: -5em;
30
+ font-weight: normal;
31
+ font-size: smaller;
32
+ text-align: center;
33
+ }
34
+
35
+ h1:first-child > span.md2man-source {
36
+ float: right;
37
+ }
38
+
39
+ h1:first-child > span.md2man-title,
40
+ h1:first-child > span.md2man-section,
41
+ h1:first-child > span.md2man-manual,
42
+ h1:first-child > a.md2man-permalink {
43
+ display: none;
44
+ }
45
+
46
+ a.md2man-permalink {
47
+ float: left;
48
+ margin-left: -1em;
49
+ opacity: 0.25;
50
+ font-size: xx-large;
51
+ }
52
+
53
+ a.md2man-permalink:before {
54
+ content: '\2605'; /* ★ */
55
+ }
56
+
57
+ a.md2man-permalink:hover,
58
+ *:target > a.md2man-permalink {
59
+ opacity: inherit;
60
+ }
61
+
62
+ *:target > a.md2man-permalink {
63
+ color: red;
64
+ }
65
+ }
66
+
67
+ @media print {
68
+ .navbar:first-child {
69
+ display: none;
70
+ }
71
+
72
+ /* improve readability of revealed hyperlink URLs */
73
+ a:after {
74
+ font-family: monospace;
75
+ }
76
+
77
+ /* internal links and manual page cross-references */
78
+ a[href^='#'], a[href^='../man'] {
79
+ color: inherit;
80
+ font-weight: bolder;
81
+ text-decoration: none;
82
+ }
83
+
84
+ /* undo bootstrap's revealing of those hyperlinks */
85
+ a[href^='#']:after, a[href^='../man']:after {
86
+ content: none;
87
+ }
88
+ }
89
+ .highlight table td { padding: 5px; }
90
+ .highlight table pre { margin: 0; }
91
+ .highlight .cm {
92
+ color: #999988;
93
+ font-style: italic;
94
+ }
95
+ .highlight .cp {
96
+ color: #999999;
97
+ font-weight: bold;
98
+ }
99
+ .highlight .c1 {
100
+ color: #999988;
101
+ font-style: italic;
102
+ }
103
+ .highlight .cs {
104
+ color: #999999;
105
+ font-weight: bold;
106
+ font-style: italic;
107
+ }
108
+ .highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf {
109
+ color: #999988;
110
+ font-style: italic;
111
+ }
112
+ .highlight .err {
113
+ color: #a61717;
114
+ background-color: #e3d2d2;
115
+ }
116
+ .highlight .gd {
117
+ color: #000000;
118
+ background-color: #ffdddd;
119
+ }
120
+ .highlight .ge {
121
+ color: #000000;
122
+ font-style: italic;
123
+ }
124
+ .highlight .gr {
125
+ color: #aa0000;
126
+ }
127
+ .highlight .gh {
128
+ color: #999999;
129
+ }
130
+ .highlight .gi {
131
+ color: #000000;
132
+ background-color: #ddffdd;
133
+ }
134
+ .highlight .go {
135
+ color: #888888;
136
+ }
137
+ .highlight .gp {
138
+ color: #555555;
139
+ }
140
+ .highlight .gs {
141
+ font-weight: bold;
142
+ }
143
+ .highlight .gu {
144
+ color: #aaaaaa;
145
+ }
146
+ .highlight .gt {
147
+ color: #aa0000;
148
+ }
149
+ .highlight .kc {
150
+ color: #000000;
151
+ font-weight: bold;
152
+ }
153
+ .highlight .kd {
154
+ color: #000000;
155
+ font-weight: bold;
156
+ }
157
+ .highlight .kn {
158
+ color: #000000;
159
+ font-weight: bold;
160
+ }
161
+ .highlight .kp {
162
+ color: #000000;
163
+ font-weight: bold;
164
+ }
165
+ .highlight .kr {
166
+ color: #000000;
167
+ font-weight: bold;
168
+ }
169
+ .highlight .kt {
170
+ color: #445588;
171
+ font-weight: bold;
172
+ }
173
+ .highlight .k, .highlight .kv {
174
+ color: #000000;
175
+ font-weight: bold;
176
+ }
177
+ .highlight .mf {
178
+ color: #009999;
179
+ }
180
+ .highlight .mh {
181
+ color: #009999;
182
+ }
183
+ .highlight .il {
184
+ color: #009999;
185
+ }
186
+ .highlight .mi {
187
+ color: #009999;
188
+ }
189
+ .highlight .mo {
190
+ color: #009999;
191
+ }
192
+ .highlight .m, .highlight .mb, .highlight .mx {
193
+ color: #009999;
194
+ }
195
+ .highlight .sa {
196
+ color: #000000;
197
+ font-weight: bold;
198
+ }
199
+ .highlight .sb {
200
+ color: #d14;
201
+ }
202
+ .highlight .sc {
203
+ color: #d14;
204
+ }
205
+ .highlight .sd {
206
+ color: #d14;
207
+ }
208
+ .highlight .s2 {
209
+ color: #d14;
210
+ }
211
+ .highlight .se {
212
+ color: #d14;
213
+ }
214
+ .highlight .sh {
215
+ color: #d14;
216
+ }
217
+ .highlight .si {
218
+ color: #d14;
219
+ }
220
+ .highlight .sx {
221
+ color: #d14;
222
+ }
223
+ .highlight .sr {
224
+ color: #009926;
225
+ }
226
+ .highlight .s1 {
227
+ color: #d14;
228
+ }
229
+ .highlight .ss {
230
+ color: #990073;
231
+ }
232
+ .highlight .s, .highlight .dl {
233
+ color: #d14;
234
+ }
235
+ .highlight .na {
236
+ color: #008080;
237
+ }
238
+ .highlight .bp {
239
+ color: #999999;
240
+ }
241
+ .highlight .nb {
242
+ color: #0086B3;
243
+ }
244
+ .highlight .nc {
245
+ color: #445588;
246
+ font-weight: bold;
247
+ }
248
+ .highlight .no {
249
+ color: #008080;
250
+ }
251
+ .highlight .nd {
252
+ color: #3c5d5d;
253
+ font-weight: bold;
254
+ }
255
+ .highlight .ni {
256
+ color: #800080;
257
+ }
258
+ .highlight .ne {
259
+ color: #990000;
260
+ font-weight: bold;
261
+ }
262
+ .highlight .nf, .highlight .fm {
263
+ color: #990000;
264
+ font-weight: bold;
265
+ }
266
+ .highlight .nl {
267
+ color: #990000;
268
+ font-weight: bold;
269
+ }
270
+ .highlight .nn {
271
+ color: #555555;
272
+ }
273
+ .highlight .nt {
274
+ color: #000080;
275
+ }
276
+ .highlight .vc {
277
+ color: #008080;
278
+ }
279
+ .highlight .vg {
280
+ color: #008080;
281
+ }
282
+ .highlight .vi {
283
+ color: #008080;
284
+ }
285
+ .highlight .nv, .highlight .vm {
286
+ color: #008080;
287
+ }
288
+ .highlight .ow {
289
+ color: #000000;
290
+ font-weight: bold;
291
+ }
292
+ .highlight .o {
293
+ color: #000000;
294
+ font-weight: bold;
295
+ }
296
+ .highlight .w {
297
+ color: #bbbbbb;
298
+ }
299
+ .highlight {
300
+ background-color: #f8f8f8;
301
+ }
data/nix/evaluator.nix CHANGED
@@ -4,11 +4,7 @@ let
4
4
 
5
5
  hasCorePkgs = (builtins.hasAttr "coreSwpins" arg) && (builtins.hasAttr "nixpkgs" arg.coreSwpins);
6
6
 
7
- nixpkgs =
8
- if hasCorePkgs then
9
- import arg.coreSwpins.nixpkgs {}
10
- else
11
- import <nixpkgs> {};
7
+ nixpkgs = if hasCorePkgs then import arg.coreSwpins.nixpkgs { } else import <nixpkgs> { };
12
8
 
13
9
  machines = import ./machines.nix {
14
10
  inherit (arg) confDir;
@@ -18,38 +14,46 @@ let
18
14
  nameValuePairs = builtins.map (m: {
19
15
  name = m.name;
20
16
  value = {
21
- inherit (m) name alias clusterName carrier metaConfig;
17
+ inherit (m)
18
+ name
19
+ alias
20
+ clusterName
21
+ carrier
22
+ metaConfig
23
+ ;
22
24
  };
23
25
  }) machines;
24
26
 
25
27
  machinesAttrs = builtins.listToAttrs nameValuePairs;
26
28
 
27
- fullMachinesAttrs = builtins.listToAttrs (builtins.map (m: {
28
- name = m.name;
29
- value = m;
30
- }) machines);
29
+ fullMachinesAttrs = builtins.listToAttrs (
30
+ builtins.map (m: {
31
+ name = m.name;
32
+ value = m;
33
+ }) machines
34
+ );
31
35
 
32
- coreSwpins =
33
- import ./lib/swpins/eval.nix {
34
- inherit (arg) confDir;
35
- name = "core";
36
- dir = "";
37
- channels = evalConfctl.config.confctl.swpins.core.channels;
38
- pkgs = nixpkgs.pkgs;
39
- lib = nixpkgs.lib;
40
- };
36
+ coreSwpins = import ./lib/swpins/eval.nix {
37
+ inherit (arg) confDir;
38
+ name = "core";
39
+ dir = "";
40
+ channels = evalConfctl.config.confctl.swpins.core.channels;
41
+ pkgs = nixpkgs.pkgs;
42
+ lib = nixpkgs.lib;
43
+ };
41
44
 
42
45
  corePkgs =
43
46
  if hasCorePkgs then
44
47
  nixpkgs
45
48
  else if builtins.hasAttr "nixpkgs" coreSwpins.evaluated then
46
- import coreSwpins.evaluated.nixpkgs {}
49
+ import coreSwpins.evaluated.nixpkgs { }
47
50
  else
48
51
  abort "Core swpins not set, run `confctl swpins core update`";
49
52
 
50
53
  coreLib = corePkgs.lib;
51
54
 
52
- machineSwpins = m:
55
+ machineSwpins =
56
+ m:
53
57
  import ./lib/swpins/eval.nix {
54
58
  inherit (arg) confDir;
55
59
  name = m.name;
@@ -60,17 +64,22 @@ let
60
64
 
61
65
  coreSwpinsAttrs = coreSwpins.evaluated;
62
66
 
63
- selectedSwpinsAttrs = builtins.listToAttrs (builtins.map (host: {
64
- name = host;
65
- value = (machineSwpins fullMachinesAttrs.${host}).evaluated;
66
- }) arg.machines);
67
-
68
- selectedToplevels = builtins.listToAttrs (builtins.map (host: {
69
- name = host;
70
- value = buildToplevel fullMachinesAttrs.${host};
71
- }) arg.machines);
72
-
73
- buildToplevel = machine:
67
+ selectedSwpinsAttrs = builtins.listToAttrs (
68
+ builtins.map (host: {
69
+ name = host;
70
+ value = (machineSwpins fullMachinesAttrs.${host}).evaluated;
71
+ }) arg.machines
72
+ );
73
+
74
+ selectedToplevels = builtins.listToAttrs (
75
+ builtins.map (host: {
76
+ name = host;
77
+ value = buildToplevel fullMachinesAttrs.${host};
78
+ }) arg.machines
79
+ );
80
+
81
+ buildToplevel =
82
+ machine:
74
83
  let
75
84
  machineConfig = (evalMachine machine).config;
76
85
 
@@ -81,7 +90,8 @@ let
81
90
  abort "Attribute 'config.${coreLib.concatStringsSep "." machine.build.attribute}' not found on machine ${machine.name}"
82
91
  else
83
92
  buildAttr;
84
- in {
93
+ in
94
+ {
85
95
  attribute = result;
86
96
 
87
97
  autoRollback =
@@ -97,18 +107,22 @@ let
97
107
  ruby = nixpkgs.ruby;
98
108
  };
99
109
  in
100
- if builtins.hasAttr "replaceVarsWith" corePkgs then
101
- corePkgs.replaceVarsWith {
110
+ if builtins.hasAttr "replaceVarsWith" corePkgs then
111
+ corePkgs.replaceVarsWith {
112
+ inherit (args) src isExecutable;
113
+ inherit replacements;
114
+ }
115
+ else
116
+ corePkgs.substituteAll (
117
+ {
102
118
  inherit (args) src isExecutable;
103
- inherit replacements;
104
119
  }
105
- else
106
- corePkgs.substituteAll ({
107
- inherit (args) src isExecutable;
108
- } // replacements);
120
+ // replacements
121
+ );
109
122
  };
110
123
 
111
- evalMachine = machine:
124
+ evalMachine =
125
+ machine:
112
126
  let
113
127
  importPath = {
114
128
  nixos = <nixpkgs/nixos/lib/eval-config.nix>;
@@ -118,64 +132,74 @@ let
118
132
  evalConfig = import importPath.${machine.metaConfig.spin} {
119
133
  modules = machine.extraModules ++ [ machine.build.toplevel ];
120
134
  };
121
- in evalConfig;
135
+ in
136
+ evalConfig;
122
137
 
123
138
  evalConfctl =
124
139
  let
125
140
  cfg = "${toString arg.confDir}/configs/confctl.nix";
126
- in evalNixosModules ([
127
- ./modules/confctl/generations.nix
128
- ./modules/confctl/cli.nix
129
- ./modules/confctl/nix.nix
130
- ./modules/confctl/swpins.nix
131
- "${toString arg.confDir}/configs/swpins.nix"
132
- ] ++ nixpkgs.lib.optional (builtins.pathExists cfg) cfg);
141
+ in
142
+ evalNixosModules (
143
+ [
144
+ ./modules/confctl/generations.nix
145
+ ./modules/confctl/cli.nix
146
+ ./modules/confctl/nix.nix
147
+ ./modules/confctl/swpins.nix
148
+ "${toString arg.confDir}/configs/swpins.nix"
149
+ ]
150
+ ++ nixpkgs.lib.optional (builtins.pathExists cfg) cfg
151
+ );
133
152
 
134
153
  docToplevels = [
135
154
  "cluster."
136
155
  "confctl."
137
156
  ];
138
157
 
139
- filterOption = o:
140
- !o.internal && builtins.any (top: nixpkgs.lib.hasPrefix top o.name) docToplevels;
158
+ filterOption = o: !o.internal && builtins.any (top: nixpkgs.lib.hasPrefix top o.name) docToplevels;
141
159
 
142
160
  docModules =
143
161
  let
144
162
  userModules = "${toString arg.confDir}/modules/cluster/default.nix";
145
- in evalNixosModules (
163
+ in
164
+ evalNixosModules (
146
165
  (import ./modules/module-list.nix).all
147
- ++
148
- (nixpkgs.lib.optional (builtins.pathExists userModules) userModules)
166
+ ++ (nixpkgs.lib.optional (builtins.pathExists userModules) userModules)
149
167
  );
150
168
 
151
- docOptions =
152
- builtins.filter filterOption (nixpkgs.lib.optionAttrSetToDocList docModules.options);
169
+ docOptions = builtins.filter filterOption (nixpkgs.lib.optionAttrSetToDocList docModules.options);
153
170
 
154
- evalNixosModules = modules:
171
+ evalNixosModules =
172
+ modules:
155
173
  import <nixpkgs/nixos/lib/eval-config.nix> {
156
174
  modules = modules ++ [
157
- ({ ... }:
158
- {
159
- _module.args = {
160
- confLib = import ./lib {
161
- confDir = "${toString arg.confDir}";
162
- coreLib = nixpkgs.lib;
163
- corePkgs = nixpkgs.pkgs;
175
+ (
176
+ { ... }:
177
+ {
178
+ _module.args = {
179
+ confLib = import ./lib {
180
+ confDir = "${toString arg.confDir}";
181
+ coreLib = nixpkgs.lib;
182
+ corePkgs = nixpkgs.pkgs;
183
+ };
164
184
  };
165
- };
166
- })
185
+ }
186
+ )
167
187
  ];
168
188
  };
169
189
 
170
190
  build = {
171
191
  # confctl settings
172
- confctl = nixpkgs.writeText "confctl-settings.json" (builtins.toJSON { confctl = evalConfctl.config.confctl; });
192
+ confctl = nixpkgs.writeText "confctl-settings.json" (
193
+ builtins.toJSON { confctl = evalConfctl.config.confctl; }
194
+ );
173
195
 
174
196
  # List available nixos module options for documentation purposes
175
197
  moduleOptions = docOptions;
176
198
 
177
199
  # List of machines
178
- list = { machines = builtins.map (m: m.name) machines; };
200
+ list = {
201
+ machines = builtins.map (m: m.name) machines;
202
+ };
179
203
 
180
204
  # List of machines in an attrset: host => config
181
205
  info = corePkgs.writeText "machine-list.json" (builtins.toJSON machinesAttrs);
@@ -193,4 +217,5 @@ let
193
217
  # be run with proper NIX_PATH with swpins
194
218
  toplevel = corePkgs.writeText "toplevels.json" (builtins.toJSON selectedToplevels);
195
219
  };
196
- in build.${arg.build}
220
+ in
221
+ build.${arg.build}
@@ -0,0 +1,85 @@
1
+ { nixpkgs }:
2
+
3
+ {
4
+ system,
5
+ pkgs ? nixpkgs.legacyPackages.${system},
6
+ extraPackages ? [ ],
7
+ }:
8
+ let
9
+ ruby = if pkgs ? ruby_3_4 then pkgs.ruby_3_4 else pkgs.ruby;
10
+ in
11
+ pkgs.mkShell {
12
+ packages = [
13
+ pkgs.git
14
+ pkgs.ncurses
15
+ pkgs.openssl
16
+ ruby
17
+ pkgs.man-db
18
+ pkgs.groff
19
+ pkgs.less
20
+ pkgs.nix-prefetch-git
21
+ pkgs.nixfmt
22
+ pkgs.nixfmt-tree
23
+ ]
24
+ ++ extraPackages;
25
+
26
+ shellHook = ''
27
+ export CONFCTL="$PWD"
28
+ export GEM_ROOT="$PWD/.gems"
29
+ export GEM_HOME="$GEM_ROOT/ruby/$(ruby -e 'require "rbconfig"; print RbConfig::CONFIG["ruby_version"]')"
30
+ export GEM_PATH="$GEM_HOME"
31
+ export BUNDLE_PATH="$GEM_ROOT"
32
+ export BUNDLE_APP_CONFIG="$PWD/.bundle"
33
+ export RUBOCOP_CACHE_ROOT="$PWD/.rubocop_cache"
34
+
35
+ mkdir -p "$GEM_ROOT" "$GEM_HOME" "$PWD/.bin"
36
+ rm -f "$PWD/.bin/bundle" "$PWD/.bin/bundler"
37
+
38
+ export PATH="$PWD/.bin:$GEM_HOME/bin:$PATH"
39
+ export RUBYLIB="$CONFCTL/lib"
40
+ export MANPATH="$CONFCTL/man:$(man --path)"
41
+
42
+ bundler_version=""
43
+ if [ -f "$CONFCTL/Gemfile.lock" ]; then
44
+ bundler_version="$(awk '/^BUNDLED WITH$/{getline; sub(/^[[:space:]]+/, "", $0); print; exit}' "$CONFCTL/Gemfile.lock")"
45
+ fi
46
+
47
+ if [ -n "$bundler_version" ]; then
48
+ export BUNDLER_VERSION="$bundler_version"
49
+ if [ ! -x "$GEM_HOME/bin/bundle" ] \
50
+ || ! gem list -i bundler -v "$bundler_version" >/dev/null 2>&1; then
51
+ gem install --no-document bundler -v "$bundler_version" >/dev/null
52
+ fi
53
+ elif [ ! -x "$GEM_HOME/bin/bundle" ]; then
54
+ gem install --no-document bundler >/dev/null
55
+ fi
56
+ bundle_bin="$GEM_HOME/bin/bundle"
57
+
58
+ pushd "$CONFCTL" >/dev/null
59
+
60
+ "$bundle_bin" config set --local path "$BUNDLE_PATH" >/dev/null
61
+ "$bundle_bin" config set --local bin "$PWD/.bin" >/dev/null
62
+
63
+ # Purity disabled because of prism gem, which has a native extension.
64
+ NIX_ENFORCE_PURITY=0 "$bundle_bin" install >/dev/null
65
+
66
+ if "$bundle_bin" info rubocop >/dev/null 2>&1; then
67
+ "$bundle_bin" binstubs rubocop --force >/dev/null
68
+ fi
69
+
70
+ popd >/dev/null
71
+
72
+ cat > "$PWD/.bin/confctl" <<EOF
73
+ #!/usr/bin/env bash
74
+ export BUNDLE_GEMFILE="$CONFCTL/Gemfile"
75
+ bundle_bin="$GEM_HOME/bin/bundle"
76
+ exec "$bundle_bin" exec confctl "$@"
77
+ EOF
78
+ chmod +x "$PWD/.bin/confctl"
79
+
80
+ export PS1="(confctl) $PS1"
81
+
82
+ echo
83
+ echo "confctl development shell ready"
84
+ '';
85
+ }