confctl 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +1 -1
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +18 -1
- data/README.md +3 -9
- data/confctl.gemspec +14 -14
- data/docs/carrier.md +138 -0
- data/lib/confctl/cli/app.rb +3 -0
- data/lib/confctl/cli/cluster.rb +73 -44
- data/lib/confctl/cli/configuration.rb +7 -2
- data/lib/confctl/cli/gen_data.rb +19 -1
- data/lib/confctl/cli/generation.rb +5 -3
- data/lib/confctl/generation/host_list.rb +3 -3
- data/lib/confctl/git_repo_mirror.rb +2 -2
- data/lib/confctl/machine.rb +101 -11
- data/lib/confctl/machine_control.rb +7 -0
- data/lib/confctl/machine_list.rb +14 -1
- data/lib/confctl/machine_status.rb +51 -4
- data/lib/confctl/nix.rb +28 -5
- data/lib/confctl/swpins/specs/git.rb +1 -1
- data/lib/confctl/version.rb +1 -1
- data/man/man8/confctl-options.nix.8 +165 -1
- data/man/man8/confctl-options.nix.8.md +165 -1
- data/man/man8/confctl.8 +21 -1
- data/man/man8/confctl.8.md +16 -1
- data/nix/evaluator.nix +18 -7
- data/nix/lib/default.nix +64 -17
- data/nix/lib/machine/default.nix +14 -11
- data/nix/lib/machine/info.nix +3 -3
- data/nix/modules/cluster/default.nix +142 -3
- data/nix/modules/confctl/carrier/base.nix +35 -0
- data/nix/modules/confctl/carrier/carrier-env.rb +81 -0
- data/nix/modules/confctl/carrier/netboot/build-netboot-server.rb +803 -0
- data/nix/modules/confctl/carrier/netboot/nixos.nix +185 -0
- data/nix/modules/system-list.nix +8 -0
- metadata +12 -7
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 602260a8486eef31801f7fcf2221f09164e4443e66ea94d6fe534f8f68c56fc2
|
4
|
+
data.tar.gz: 24b4b5dabe240f2e93e0a9784f9eda90bbf52cec2a82fab8e5c5644e323be8da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87f22fe62a9354b20e711fff429f0a34f6961f9c08489bd42f97ff1d8f9f350bc281e7eca069aecc25081ae71f2ea73f803aa06a0dc4c3d244adbfe10dbbaa86
|
7
|
+
data.tar.gz: 8f44626b3b0e9a97b37171cbc58e94a15b04d87f448110ff211bfa5bc34477d1ce9a0d9f344b19cab93ed8d23f657e44fab3d14c8bad71e62b5d65ea2d3d3d26
|
data/.editorconfig
CHANGED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,2 +1,19 @@
|
|
1
|
-
#
|
1
|
+
# Sun Nov 17 2024 -- version 2.0.0
|
2
|
+
- Distinguish machine `config` and `metaConfig` (breaking change)
|
3
|
+
- Support for machine carriers and netboot servers
|
4
|
+
- Optimized git fetch calls when updating software pins
|
5
|
+
- Added option `--cores` that is passed to nix-build
|
6
|
+
- Added RuboCop
|
7
|
+
- Bug fixes
|
8
|
+
|
9
|
+
## Transition to `metaConfig`
|
10
|
+
The use of `config` has been ambiguous, it could either mean machine
|
11
|
+
configuration, i.e. the result of all configured NixOS/vpsAdminOS options,
|
12
|
+
or it could mean machine metadata from `module.nix`. Machine metadata
|
13
|
+
is now accessible as `metaConfig`.
|
14
|
+
|
15
|
+
- `confLib.findConfig` has been renamed to `confLib.findMetaConfig`
|
16
|
+
- `confLib.confLib.getClusterMachines` returns a list of machines with `metaConfig` attribute
|
17
|
+
|
18
|
+
# Sat Feb 17 2024 -- version 1.0.0
|
2
19
|
- Initial release
|
data/README.md
CHANGED
@@ -13,6 +13,7 @@ machines.
|
|
13
13
|
configurations)
|
14
14
|
* Query machine state, view changelogs and diffs
|
15
15
|
* Run health checks
|
16
|
+
* Support for creating netboot servers, see [docs/carrier.md](docs/carrier.md)
|
16
17
|
|
17
18
|
## Requirements
|
18
19
|
|
@@ -40,19 +41,12 @@ stored:
|
|
40
41
|
```
|
41
42
|
mkdir cluster-configuration
|
42
43
|
```
|
43
|
-
3.
|
44
|
-
- Create a `shell.nix` and import the same file from confctl:
|
44
|
+
3. Create `shell.nix` and import the same file from confctl:
|
45
45
|
```
|
46
46
|
cd cluster-configuration
|
47
47
|
cat > shell.nix <<EOF
|
48
48
|
import ../confctl/shell.nix
|
49
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
50
|
```
|
57
51
|
|
58
52
|
4. Enter the `nix-shell`. This will make confctl available and install its
|
@@ -489,7 +483,7 @@ Then you can use it in machine module as:
|
|
489
483
|
Note that these modules are self-contained. They are not evaluated with the full
|
490
484
|
set of NixOS modules. You have to import modules that you need.
|
491
485
|
|
492
|
-
## User-defined confctl commands
|
486
|
+
## User-defined confctl commands
|
493
487
|
User-defined Ruby scripts can be placed in directory `scripts`. Each script
|
494
488
|
should create a subclass of `ConfCtl::UserScript` and call class-method `register`.
|
495
489
|
Scripts can define their own `confctl` subcommands.
|
data/confctl.gemspec
CHANGED
@@ -15,19 +15,19 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
16
|
s.license = 'GPL-3.0-only'
|
17
17
|
|
18
|
-
s.required_ruby_version =
|
18
|
+
s.required_ruby_version = '>= 3.1.0'
|
19
19
|
|
20
|
-
s.
|
21
|
-
s.
|
22
|
-
s.
|
23
|
-
s.
|
24
|
-
s.
|
25
|
-
s.
|
26
|
-
s.
|
27
|
-
s.
|
28
|
-
s.
|
29
|
-
s.
|
30
|
-
s.
|
31
|
-
s.
|
32
|
-
s.
|
20
|
+
s.add_dependency 'curses'
|
21
|
+
s.add_dependency 'gli', '~> 2.22.0'
|
22
|
+
s.add_dependency 'json'
|
23
|
+
s.add_dependency 'md2man'
|
24
|
+
s.add_dependency 'rainbow', '~> 3.1.1'
|
25
|
+
s.add_dependency 'rake'
|
26
|
+
s.add_dependency 'require_all', '~> 2.0.0'
|
27
|
+
s.add_dependency 'tty-command', '~> 0.10.1'
|
28
|
+
s.add_dependency 'tty-cursor', '~> 0.7.1'
|
29
|
+
s.add_dependency 'tty-pager', '~> 0.14.0'
|
30
|
+
s.add_dependency 'tty-progressbar', '~> 0.18.2'
|
31
|
+
s.add_dependency 'tty-spinner', '~> 0.9.3'
|
32
|
+
s.add_dependency 'vpsfree-client', '~> 0.19.0'
|
33
33
|
end
|
data/docs/carrier.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
# confctl carriers
|
2
|
+
Carrier is a machine that can carry other machines. The concept was created
|
3
|
+
for the purpose of building netboot servers, but can be used in other settings
|
4
|
+
as well.
|
5
|
+
|
6
|
+
All machines must be defined within the cluster as usual. We can then designate
|
7
|
+
a machine that will serve as a carrier and provide a list of machines that it
|
8
|
+
will carry, e.g.:
|
9
|
+
|
10
|
+
```nix
|
11
|
+
# File cluster/pxe-server/module.nix
|
12
|
+
cluster.pxe-server = {
|
13
|
+
# ...
|
14
|
+
carrier = {
|
15
|
+
enable = true;
|
16
|
+
|
17
|
+
# A list of machines found in the cluster/ directory that will be
|
18
|
+
# available on the netboot server. Note that you will have to create
|
19
|
+
# your own buildAttribute, so that the resulting path contains bzImage,
|
20
|
+
# initrd and possibly a machine.json file.
|
21
|
+
machines = [
|
22
|
+
{
|
23
|
+
machine = "node1";
|
24
|
+
buildAttribute = [ "system" "build" "dist" ];
|
25
|
+
}
|
26
|
+
];
|
27
|
+
};
|
28
|
+
};
|
29
|
+
```
|
30
|
+
|
31
|
+
Now the `node1` machine is available as two machines within the cluster:
|
32
|
+
`node1` and `pxe-server#node1`. We can build and deploy both:
|
33
|
+
|
34
|
+
* `confctl deploy node1` will deploy the target machine as defined by the configuration
|
35
|
+
* `confctl deploy pxe-server#node1` will build the machine and copy the result to `pxe-server`, its carrier
|
36
|
+
|
37
|
+
We need both commands to build a slightly different output, but based on the same
|
38
|
+
configuration. When deploying `node1`, confctl will build attribute
|
39
|
+
`config.system.build.toplevel`, where as deploying `pxe-server#node1` will build
|
40
|
+
attribute `config.system.build.dist`. This attribute is configured in `buildAttribute`
|
41
|
+
option in the example above. `config.system.build.dist` is defined within vpsAdminOS,
|
42
|
+
its output is a directory with kernel bzImage, initrd and the root filesystem
|
43
|
+
in a squashfs image, i.e. what we need for booting from network.
|
44
|
+
|
45
|
+
Custom build attributes can be created by the user. For example, this is how
|
46
|
+
`config.system.build.dist` would be defined for NixOS:
|
47
|
+
|
48
|
+
```nix
|
49
|
+
# File cluster/nixos/config.nix
|
50
|
+
{ config, pkgs, lib, confMachine, swpinsInfo, ... }:
|
51
|
+
let
|
52
|
+
# machine.json contains metadata about the machine that the carrier uses
|
53
|
+
# to assemble the netboot server
|
54
|
+
machineJson = pkgs.writeText "machine-${config.networking.hostName}.json" (builtins.toJSON {
|
55
|
+
# machine spin, nixos/vpsadminos
|
56
|
+
spin = "nixos";
|
57
|
+
|
58
|
+
# fully qualified domain name
|
59
|
+
fqdn = confMachine.host.fqdn;
|
60
|
+
|
61
|
+
# label used e.g. in user menus
|
62
|
+
label = confMachine.host.fqdn;
|
63
|
+
|
64
|
+
# path to the top-level derivation, needed for system boot
|
65
|
+
toplevel = builtins.unsafeDiscardStringContext config.system.build.toplevel;
|
66
|
+
|
67
|
+
# NixOS version and git revision
|
68
|
+
version = config.system.nixos.version;
|
69
|
+
revision = config.system.nixos.revision;
|
70
|
+
|
71
|
+
# MAC addresses for auto-detection
|
72
|
+
macs = confMachine.netboot.macs;
|
73
|
+
|
74
|
+
# Information used by confctl status
|
75
|
+
swpins-info = swpinsInfo;
|
76
|
+
});
|
77
|
+
in {
|
78
|
+
imports = [
|
79
|
+
<nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix>
|
80
|
+
];
|
81
|
+
|
82
|
+
# Define custom build attribute
|
83
|
+
system.build.dist = pkgs.symlinkJoin {
|
84
|
+
name = "nixos-netboot";
|
85
|
+
paths = [
|
86
|
+
config.system.build.netbootRamdisk
|
87
|
+
config.system.build.kernel
|
88
|
+
config.system.build.netbootIpxeScript
|
89
|
+
];
|
90
|
+
|
91
|
+
# Install machine.json
|
92
|
+
postBuild = ''
|
93
|
+
ln -s ${machineJson} $out/machine.json
|
94
|
+
'';
|
95
|
+
};
|
96
|
+
|
97
|
+
# other NixOS configuration
|
98
|
+
}
|
99
|
+
```
|
100
|
+
|
101
|
+
The carrier must be configured to handle the carried machines. Netboot server
|
102
|
+
support is integrated within confctl and it only has to be enabled.
|
103
|
+
|
104
|
+
```nix
|
105
|
+
# File cluster/pxe-server/config.nix
|
106
|
+
{ config, ... }:
|
107
|
+
{
|
108
|
+
confctl.carrier.netboot = {
|
109
|
+
enable = true;
|
110
|
+
|
111
|
+
# IP address or hostname the netboot server will be available on
|
112
|
+
host = "192.168.100.5";
|
113
|
+
|
114
|
+
# IP ranges that will have access to the server
|
115
|
+
allowedIPv4Ranges = [
|
116
|
+
"192.168.100.0/24"
|
117
|
+
];
|
118
|
+
};
|
119
|
+
}
|
120
|
+
```
|
121
|
+
|
122
|
+
The netboot server is rebuilt whenever a machine is deployed to it.
|
123
|
+
The rebuild can be also run manually using command `build-netboot-server`.
|
124
|
+
|
125
|
+
## Other uses
|
126
|
+
You can define your own commands to be run on the carrier machine when
|
127
|
+
images are deployed to it:
|
128
|
+
|
129
|
+
```nix
|
130
|
+
# File cluster/pxe-server/config.nix
|
131
|
+
{ config, ... }:
|
132
|
+
{
|
133
|
+
confctl.carrier.onChangeCommands = ''
|
134
|
+
# List profiles of carried machines
|
135
|
+
ls -l /nix/var/nix/profiles/confctl-*
|
136
|
+
'';
|
137
|
+
}
|
138
|
+
```
|
data/lib/confctl/cli/app.rb
CHANGED
@@ -546,6 +546,9 @@ module ConfCtl::Cli
|
|
546
546
|
def nix_build_options(cmd)
|
547
547
|
cmd.desc 'Maximum number of build jobs (see nix-build)'
|
548
548
|
cmd.flag %w[j max-jobs], arg_name: 'number'
|
549
|
+
|
550
|
+
cmd.desc 'Number of CPU cores to be used (see nix-build)'
|
551
|
+
cmd.flag :cores, arg_name: 'number'
|
549
552
|
end
|
550
553
|
end
|
551
554
|
end
|
data/lib/confctl/cli/cluster.rb
CHANGED
@@ -110,7 +110,10 @@ module ConfCtl::Cli
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def status
|
113
|
-
machines = select_machines(args[0]).managed
|
113
|
+
machines = select_machines(args[0]).managed.select do |_host, machine|
|
114
|
+
machine.target_host || machine.carried?
|
115
|
+
end
|
116
|
+
|
114
117
|
raise 'No machines to check' if machines.empty?
|
115
118
|
|
116
119
|
ask_confirmation! do
|
@@ -244,7 +247,7 @@ module ConfCtl::Cli
|
|
244
247
|
end
|
245
248
|
|
246
249
|
def test_connection
|
247
|
-
machines = select_machines_with_managed(args[0])
|
250
|
+
machines = select_machines_with_managed(args[0]).runnable
|
248
251
|
raise 'No machines to test' if machines.empty?
|
249
252
|
|
250
253
|
ask_confirmation! do
|
@@ -276,7 +279,7 @@ module ConfCtl::Cli
|
|
276
279
|
end
|
277
280
|
|
278
281
|
def ssh
|
279
|
-
machines = select_machines_with_managed(args[0])
|
282
|
+
machines = select_machines_with_managed(args[0]).runnable
|
280
283
|
raise 'No machines to ssh to' if machines.empty?
|
281
284
|
|
282
285
|
if opts['input-string'] && opts['input-file']
|
@@ -295,7 +298,7 @@ module ConfCtl::Cli
|
|
295
298
|
end
|
296
299
|
|
297
300
|
def cssh
|
298
|
-
machines = select_machines_with_managed(args[0])
|
301
|
+
machines = select_machines_with_managed(args[0]).runnable
|
299
302
|
raise 'No machines to open cssh to' if machines.empty?
|
300
303
|
|
301
304
|
ask_confirmation! do
|
@@ -508,38 +511,67 @@ module ConfCtl::Cli
|
|
508
511
|
size: :auto,
|
509
512
|
reserved_lines: 10
|
510
513
|
) do |lw|
|
511
|
-
if
|
512
|
-
lw
|
513
|
-
|
514
|
-
|
515
|
-
"(#{machine.target_host})"
|
516
|
-
).yellow
|
517
|
-
end
|
518
|
-
|
519
|
-
raise "Error while activating configuration on #{host}" unless nix.activate(machine, toplevel, 'dry-activate')
|
514
|
+
if machine.carried?
|
515
|
+
deploy_carried_to_host(lw, nix, host, machine, toplevel, action)
|
516
|
+
else
|
517
|
+
deploy_standalone_to_host(lw, nix, host, machine, toplevel, action)
|
520
518
|
end
|
521
519
|
|
520
|
+
lw.flush
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
def deploy_standalone_to_host(lw, nix, host, machine, toplevel, action)
|
525
|
+
if opts['dry-activate-first']
|
522
526
|
lw.sync_console do
|
523
527
|
puts Rainbow(
|
524
|
-
"
|
525
|
-
"#{
|
528
|
+
"Trying to activate configuration on #{host} " \
|
529
|
+
"(#{machine.target_host})"
|
526
530
|
).yellow
|
527
531
|
end
|
528
532
|
|
529
|
-
|
533
|
+
raise "Error while activating configuration on #{host}" unless nix.activate(machine, toplevel, 'dry-activate')
|
534
|
+
end
|
530
535
|
|
531
|
-
|
536
|
+
lw.sync_console do
|
537
|
+
puts Rainbow(
|
538
|
+
"Activating configuration on #{host} (#{machine.target_host}): " \
|
539
|
+
"#{action}"
|
540
|
+
).yellow
|
541
|
+
end
|
532
542
|
|
533
|
-
|
534
|
-
|
535
|
-
|
543
|
+
return :skip if opts[:interactive] && !ask_confirmation(always: true)
|
544
|
+
|
545
|
+
# rubocop:disable Style/GuardClause
|
546
|
+
|
547
|
+
unless nix.activate(machine, toplevel, action)
|
548
|
+
raise "Error while activating configuration on #{host}"
|
549
|
+
end
|
550
|
+
|
551
|
+
if %w[boot switch].include?(action) && !nix.set_profile(machine, toplevel)
|
552
|
+
raise "Error while setting profile on #{host}"
|
536
553
|
end
|
554
|
+
|
555
|
+
# rubocop:enable Style/GuardClause
|
556
|
+
end
|
557
|
+
|
558
|
+
def deploy_carried_to_host(lw, nix, host, machine, toplevel, action)
|
559
|
+
return if action != 'switch'
|
560
|
+
|
561
|
+
# rubocop:disable Style/GuardClause
|
562
|
+
unless nix.set_carried_profile(machine, toplevel)
|
563
|
+
raise "Error while setting carried profile for #{host} on #{machine.carrier_machine}"
|
564
|
+
end
|
565
|
+
# rubocop:enable Style/GuardClause
|
537
566
|
end
|
538
567
|
|
539
568
|
def reboot_host(host, machine)
|
540
569
|
if machine.localhost?
|
541
570
|
puts Rainbow("Skipping reboot of #{host} as it is localhost").yellow
|
542
571
|
return :skip
|
572
|
+
elsif machine.carried?
|
573
|
+
puts Rainbow("Skipping reboot of carried machine #{host}").yellow
|
574
|
+
return :skip
|
543
575
|
end
|
544
576
|
|
545
577
|
puts Rainbow("Rebooting #{host} (#{machine.target_host})").yellow
|
@@ -761,22 +793,16 @@ module ConfCtl::Cli
|
|
761
793
|
machines.each do |host, machine|
|
762
794
|
mc = ConfCtl::MachineControl.new(machine)
|
763
795
|
|
764
|
-
|
765
|
-
puts "#{host}:" unless aggregate
|
796
|
+
puts "#{host}:" unless aggregate
|
766
797
|
|
767
|
-
|
798
|
+
result = run_ssh_command_on_machine(mc, cmd)
|
768
799
|
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
if aggregate
|
776
|
-
results[host] = e
|
777
|
-
else
|
778
|
-
puts e.message
|
779
|
-
end
|
800
|
+
if aggregate
|
801
|
+
results[host] = result
|
802
|
+
elsif result.success?
|
803
|
+
puts result.out
|
804
|
+
else
|
805
|
+
puts result.err
|
780
806
|
end
|
781
807
|
|
782
808
|
puts unless aggregate
|
@@ -808,12 +834,8 @@ module ConfCtl::Cli
|
|
808
834
|
tw.add do
|
809
835
|
mc = ConfCtl::MachineControl.new(machine)
|
810
836
|
|
811
|
-
|
812
|
-
|
813
|
-
results[host] = result
|
814
|
-
rescue TTY::Command::ExitError => e
|
815
|
-
results[host] = e
|
816
|
-
end
|
837
|
+
result = run_ssh_command_on_machine(mc, cmd)
|
838
|
+
results[host] = result
|
817
839
|
|
818
840
|
lw.sync_console { pb.advance }
|
819
841
|
end
|
@@ -830,7 +852,13 @@ module ConfCtl::Cli
|
|
830
852
|
|
831
853
|
results.each do |host, result|
|
832
854
|
puts "#{host}:"
|
833
|
-
|
855
|
+
|
856
|
+
if result.success?
|
857
|
+
puts result.out
|
858
|
+
else
|
859
|
+
puts result.err
|
860
|
+
end
|
861
|
+
|
834
862
|
puts
|
835
863
|
end
|
836
864
|
end
|
@@ -844,7 +872,7 @@ module ConfCtl::Cli
|
|
844
872
|
cmd_opts[:in] = opts['input-file']
|
845
873
|
end
|
846
874
|
|
847
|
-
mc.execute(*cmd, **cmd_opts)
|
875
|
+
mc.execute!(*cmd, **cmd_opts)
|
848
876
|
end
|
849
877
|
|
850
878
|
def process_aggregated_results(results)
|
@@ -903,7 +931,8 @@ module ConfCtl::Cli
|
|
903
931
|
def do_build(machines)
|
904
932
|
nix = ConfCtl::Nix.new(
|
905
933
|
show_trace: opts['show-trace'],
|
906
|
-
max_jobs: opts['max-jobs']
|
934
|
+
max_jobs: opts['max-jobs'],
|
935
|
+
cores: opts['cores']
|
907
936
|
)
|
908
937
|
hosts_swpin_paths = {}
|
909
938
|
|
@@ -996,7 +1025,7 @@ module ConfCtl::Cli
|
|
996
1025
|
'Fetching [:bar] :current/:total (:percent)'
|
997
1026
|
)
|
998
1027
|
|
999
|
-
built_generations = nix.
|
1028
|
+
built_generations = nix.build_attributes(
|
1000
1029
|
hosts:,
|
1001
1030
|
swpin_paths:,
|
1002
1031
|
time:,
|
@@ -1,8 +1,11 @@
|
|
1
|
+
require_relative '../hook'
|
1
2
|
require 'fileutils'
|
2
3
|
require 'securerandom'
|
3
4
|
|
4
5
|
module ConfCtl::Cli
|
5
6
|
class Configuration < Command
|
7
|
+
ConfCtl::Hook.register :configuration_rediscover
|
8
|
+
|
6
9
|
DIR_MODE = 0o755
|
7
10
|
FILE_MODE = 0o644
|
8
11
|
|
@@ -238,6 +241,8 @@ module ConfCtl::Cli
|
|
238
241
|
|
239
242
|
f.puts(']')
|
240
243
|
end
|
244
|
+
|
245
|
+
ConfCtl::Hook.call(:configuration_rediscover)
|
241
246
|
end
|
242
247
|
|
243
248
|
protected
|
@@ -251,8 +256,8 @@ module ConfCtl::Cli
|
|
251
256
|
|
252
257
|
entry_rel_path = File.join(*[rel_path, v].compact)
|
253
258
|
|
254
|
-
if File.exist?(File.join(entry_abs_path, 'module.nix'))
|
255
|
-
|
259
|
+
if File.exist?(File.join(entry_abs_path, 'module.nix')) &&
|
260
|
+
File.exist?(File.join(entry_abs_path, 'config.nix'))
|
256
261
|
ret << entry_rel_path
|
257
262
|
end
|
258
263
|
|
data/lib/confctl/cli/gen_data.rb
CHANGED
@@ -78,10 +78,28 @@ module ConfCtl::Cli
|
|
78
78
|
q.echo = false
|
79
79
|
end.to_s
|
80
80
|
|
81
|
-
@vpsadmin_client.authenticate(:
|
81
|
+
@vpsadmin_client.authenticate(:token, user:, password:, lifetime: 'fixed', interval: 60) do |_action, params|
|
82
|
+
ret = {}
|
83
|
+
|
84
|
+
params.each do |name, desc|
|
85
|
+
ret[name] = read_auth_param(name, desc)
|
86
|
+
end
|
87
|
+
|
88
|
+
ret
|
89
|
+
end
|
90
|
+
|
82
91
|
@vpsadmin_client
|
83
92
|
end
|
84
93
|
|
94
|
+
def read_auth_param(name, p)
|
95
|
+
prompt = "#{p[:label] || name}: "
|
96
|
+
|
97
|
+
ask(prompt) do |q|
|
98
|
+
q.default = nil
|
99
|
+
q.echo = !p[:protected]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
85
103
|
def update_file(relpath, &)
|
86
104
|
abs = File.join(data_dir, relpath)
|
87
105
|
tmp = "#{abs}.new"
|
@@ -31,7 +31,7 @@ module ConfCtl::Cli
|
|
31
31
|
|
32
32
|
return unless opts[:remote] && opts[:gc]
|
33
33
|
|
34
|
-
machines_gc = machines.select do |host, _machine|
|
34
|
+
machines_gc = machines.runnable.select do |host, _machine|
|
35
35
|
gens.detect { |gen| gen.host == host }
|
36
36
|
end
|
37
37
|
|
@@ -68,7 +68,7 @@ module ConfCtl::Cli
|
|
68
68
|
|
69
69
|
global = ConfCtl::Settings.instance.host_generations
|
70
70
|
|
71
|
-
machines_gc = machines.select do |_host, machine|
|
71
|
+
machines_gc = machines.runnable.select do |_host, machine|
|
72
72
|
gc = machine['buildGenerations']['collectGarbage']
|
73
73
|
|
74
74
|
if gc.nil?
|
@@ -82,7 +82,7 @@ module ConfCtl::Cli
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def collect_garbage
|
85
|
-
machines = select_machines(args[0])
|
85
|
+
machines = select_machines(args[0]).runnable
|
86
86
|
|
87
87
|
raise 'No machines to collect garbage on' if machines.empty?
|
88
88
|
|
@@ -295,6 +295,8 @@ module ConfCtl::Cli
|
|
295
295
|
retvals = executor.run
|
296
296
|
failed = retvals.compact
|
297
297
|
|
298
|
+
lw.flush
|
299
|
+
|
298
300
|
raise "Gargabe collection failed on: #{failed.join(', ')}" if failed.any?
|
299
301
|
end
|
300
302
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module ConfCtl
|
2
2
|
class Generation::HostList
|
3
3
|
# @param mc [MachineControl]
|
4
|
+
# @param profile [String]
|
4
5
|
# @return [Generation::HostList]
|
5
|
-
def self.fetch(mc, profile:
|
6
|
-
out, = mc.bash_script(
|
6
|
+
def self.fetch(mc, profile:)
|
7
|
+
out, = mc.bash_script(<<~END)
|
7
8
|
realpath #{profile}
|
8
9
|
|
9
10
|
for generation in `ls -d -1 #{profile}-*-link` ; do
|
10
11
|
echo "$generation;$(readlink $generation);$(stat --format=%Y $generation)"
|
11
12
|
done
|
12
13
|
END
|
13
|
-
)
|
14
14
|
|
15
15
|
list = new(mc.machine.name)
|
16
16
|
lines = out.strip.split("\n")
|
@@ -14,13 +14,13 @@ module ConfCtl
|
|
14
14
|
@cmd = SystemCommand.new
|
15
15
|
end
|
16
16
|
|
17
|
-
def setup
|
17
|
+
def setup(ref: nil)
|
18
18
|
File.stat(mirror_path)
|
19
19
|
rescue Errno::ENOENT
|
20
20
|
FileUtils.mkdir_p(mirror_path)
|
21
21
|
git('clone', args: ['--mirror', url, mirror_path])
|
22
22
|
else
|
23
|
-
git_repo('fetch')
|
23
|
+
git_repo('fetch', opts: ['--no-show-forced-updates'], args: (ref ? ['origin', ref] : []))
|
24
24
|
end
|
25
25
|
|
26
26
|
def revision_parse(str)
|