confctl 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
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
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
|
data/example/.gitignore
ADDED
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,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
|
+
}
|