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
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
|
+
}
|