aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2020-09-04 02:40:24 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2020-09-04 02:59:46 +0200
commit34abd6afa44c620a56416bd423a2438a09bd1ce4 (patch)
treeb7eef613348fcb9d8fabd19c0437430c30678152
parentf5cbc6f767ee234e9cdd53baa113d5ab26edb6d8 (diff)
downloadNix-34abd6afa44c620a56416bd423a2438a09bd1ce4.tar.gz
Nix-34abd6afa44c620a56416bd423a2438a09bd1ce4.tar.zst
Nix-34abd6afa44c620a56416bd423a2438a09bd1ce4.zip
Migrate to morph as a replacement to nixops
The deployment tasks are now independent of any state
-rw-r--r--.envrc2
-rw-r--r--.gitignore1
-rw-r--r--Makefile5
-rw-r--r--docs/migrate_hetzner.md20
-rw-r--r--modules/private/system.nix10
-rw-r--r--modules/private/system/backup-2.nix20
-rw-r--r--modules/private/system/dilion.nix91
-rw-r--r--modules/private/system/eldiron.nix85
-rw-r--r--modules/private/system/monitoring-1.nix19
-rw-r--r--modules/secrets.nix13
-rw-r--r--nixops/Makefile87
-rw-r--r--nixops/default.nix11
-rwxr-xr-xnixops/scripts/setup16
-rwxr-xr-xnixops/scripts/with_env6
m---------nixops/secrets0
-rw-r--r--nixops/state/.gitkeep0
-rw-r--r--overlays/default.nix1
-rw-r--r--overlays/morph/default.nix5
-rw-r--r--overlays/morph/verbose_nix.patch12
-rw-r--r--shell.nix2
20 files changed, 195 insertions, 211 deletions
diff --git a/.envrc b/.envrc
index 6eeaba9..8aa086a 100644
--- a/.envrc
+++ b/.envrc
@@ -1,7 +1,5 @@
1# vim: filetype=bash 1# vim: filetype=bash
2export PASSWORD_STORE_DIR=$(expand_path nixops/secrets) 2export PASSWORD_STORE_DIR=$(expand_path nixops/secrets)
3export NIXOPS_STATE=$(expand_path nixops/state/immaeEu.nixops)
4export NIXOPS_DEPLOYMENT=cef694f3-081d-11e9-b31f-0242ec186adf
5export NIX_PATH=nixpkgs=$(cat $(expand_path nix/sources.json) | jq -r '."nixpkgs-nixops".url') 3export NIX_PATH=nixpkgs=$(cat $(expand_path nix/sources.json) | jq -r '."nixpkgs-nixops".url')
6 4
7export NIXOPS_ENV_LOADED=1 5export NIXOPS_ENV_LOADED=1
diff --git a/.gitignore b/.gitignore
index 6786d42..ff9c9cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
1/result* 1/result*
2/versions_log 2/versions_log
3.direnv/ 3.direnv/
4/nixops/.gcroots
diff --git a/Makefile b/Makefile
index 6ba059c..9c12ff4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,7 @@
1subrecipes = setup nix-info edit_env 1subrecipes = setup nix-info edit_env
2subrecipes += nixops ssh-eldiron ssh-backup-2 ssh-monitoring-1 2subrecipes += ssh-eldiron ssh-backup-2 ssh-monitoring-1
3subrecipes += info debug dry-run build upload deploy deploy-reboot reboot 3subrecipes += debug build upload deploy deploy-reboot
4subrecipes += list-generations delete-generations cleanup 4subrecipes += list-generations delete-generations cleanup
5subrecipes += pull_deployment deployment_is_set push_deployment
6${subrecipes}: 5${subrecipes}:
7 @$(MAKE) --no-print-directory -C nixops/ $@ 6 @$(MAKE) --no-print-directory -C nixops/ $@
8.PHONY: ${subrecipes} 7.PHONY: ${subrecipes}
diff --git a/docs/migrate_hetzner.md b/docs/migrate_hetzner.md
deleted file mode 100644
index c7fbe20..0000000
--- a/docs/migrate_hetzner.md
+++ /dev/null
@@ -1,20 +0,0 @@
1nixops show a deprecation message at each deployment because hetzner
2info is outdated. To fix it:
3
4 cp -a ~/.nixops ~/.nixops.bak
5
6 nixops export --all > all.json
7
8 network=$(cat all.json| jq -r '."cef694f3-081d-11e9-b31f-0242ec186adf".resources.eldiron."hetzner.networkInfo"' | jq -r -c '.networking.interfaces.eth0 = { "ipv4": { "addresses": [ { "address": .networking.interfaces.eth0.ipAddress, "prefixLength": .networking.interfaces.eth0.prefixLength } ] } }')
9
10 cat all.json | jq --arg network "$network" '."cef694f3-081d-11e9-b31f-0242ec186adf".resources.eldiron."hetzner.networkInfo" = $network' > all_new.json
11
12 nixops delete --force -d eldiron
13
14 nixops import < all_new.json
15
16 rm all.json all_new.json
17
18*check that everything works*, then:
19
20 rm -rf ~/.nixops.bak
diff --git a/modules/private/system.nix b/modules/private/system.nix
index b667ee8..6b4ef6e 100644
--- a/modules/private/system.nix
+++ b/modules/private/system.nix
@@ -1,6 +1,12 @@
1{ pkgs, lib, config, name, ... }: 1{ pkgs, lib, config, name, nodes, ... }:
2{ 2{
3 config = { 3 config = {
4 networking.extraHosts = builtins.concatStringsSep "\n"
5 (lib.mapAttrsToList (n: v: "${v.config.hostEnv.ips.main.ip4} ${n}") nodes);
6
7 users.extraUsers.root.openssh.authorizedKeys.keyFiles = [ "${config.myEnv.privateFiles}/id_ed25519.pub" ];
8 services.openssh.enable = true;
9
4 services.duplyBackup.profiles.system = { 10 services.duplyBackup.profiles.system = {
5 rootDir = "/var/lib"; 11 rootDir = "/var/lib";
6 excludeFile = lib.mkAfter '' 12 excludeFile = lib.mkAfter ''
@@ -73,6 +79,8 @@
73 environment.systemPackages = [ 79 environment.systemPackages = [
74 pkgs.git 80 pkgs.git
75 pkgs.vim 81 pkgs.vim
82 pkgs.rsync
83 pkgs.strace
76 ] ++ 84 ] ++
77 (lib.optional (builtins.length (config.hostEnv.users pkgs) > 0) pkgs.home-manager); 85 (lib.optional (builtins.length (config.hostEnv.users pkgs) > 0) pkgs.home-manager);
78 86
diff --git a/modules/private/system/backup-2.nix b/modules/private/system/backup-2.nix
index a49c374..d1064c7 100644
--- a/modules/private/system/backup-2.nix
+++ b/modules/private/system/backup-2.nix
@@ -1,26 +1,22 @@
1{ privateFiles }: 1{ privateFiles }:
2{ config, pkgs, resources, name, ... }: 2{ config, pkgs, resources, name, ... }:
3{ 3{
4 deployment = {
5 targetUser = "root";
6 targetHost = config.hostEnv.ips.main.ip4;
7 substituteOnDestination = true;
8 };
4 boot.kernelPackages = pkgs.linuxPackages_latest; 9 boot.kernelPackages = pkgs.linuxPackages_latest;
5 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 10 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
6 11
7 imports = builtins.attrValues (import ../..); 12 imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ] ++ builtins.attrValues (import ../..);
8
9 deployment = {
10 targetEnv = "hetznerCloud";
11 hetznerCloud = {
12 authToken = config.myEnv.hetznerCloud.authToken;
13 datacenter = "hel1-dc2";
14 location ="hel1";
15 serverType = "cx11";
16 };
17 };
18 13
19 fileSystems = { 14 fileSystems = {
20 "/backup2" = { 15 "/backup2" = {
21 fsType = "ext4"; 16 fsType = "ext4";
22 device = "UUID=b9425333-f567-435d-94d8-b26c22d93426"; 17 device = "UUID=b9425333-f567-435d-94d8-b26c22d93426";
23 }; 18 };
19 "/" = { device = "/dev/sda1"; fsType = "ext4"; };
24 }; 20 };
25 21
26 networking = { 22 networking = {
@@ -34,6 +30,8 @@
34 defaultGateway6 = { address = "fe80::1"; interface = "ens3"; }; 30 defaultGateway6 = { address = "fe80::1"; interface = "ens3"; };
35 }; 31 };
36 32
33 boot.loader.grub.device = "nodev";
34
37 myServices.certificates.enable = true; 35 myServices.certificates.enable = true;
38 security.acme.certs."${name}" = { 36 security.acme.certs."${name}" = {
39 user = config.services.nginx.user; 37 user = config.services.nginx.user;
diff --git a/modules/private/system/dilion.nix b/modules/private/system/dilion.nix
index 5c24656..5abaac0 100644
--- a/modules/private/system/dilion.nix
+++ b/modules/private/system/dilion.nix
@@ -1,59 +1,81 @@
1{ privateFiles }: 1{ privateFiles }:
2{ config, pkgs, name, lib, ... }: 2{ config, pkgs, name, lib, ... }:
3{ 3{
4 boot.supportedFilesystems = [ "zfs" ]; 4 deployment = {
5 boot.kernelPackages = pkgs.linuxPackages_latest; 5 targetUser = "root";
6 targetHost = config.hostEnv.ips.main.ip4;
7 substituteOnDestination = true;
8 };
9 nixpkgs.system = lib.mkOverride 900 "x86_64-linux";
10 boot = {
11 loader = {
12 grub = {
13 version = 2;
14 devices = [ "/dev/sda" "/dev/sdb" "/dev/sdc" "/dev/sdd" ];
15 };
16 timeout = 1;
17 };
18 blacklistedKernelModules = [ "nvidiafb" ];
19 supportedFilesystems = [ "zfs" ];
20 kernelPackages = pkgs.linuxPackages_latest;
21 kernelModules = [ "kvm-intel" ];
22 initrd.availableKernelModules = [ "ahci" "sd_mod" ];
23 initrd.secrets = {
24 "/boot/pass.key" = "/boot/pass.key";
25 };
26 kernel.sysctl."vm.nr_hugepages" = 256; # for xmr-stak
27 };
28 nix.maxJobs = 8;
29 powerManagement.cpuFreqGovernor = "powersave";
30 hardware.enableRedistributableFirmware = true;
31
6 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 32 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
7 33
34 swapDevices = [ { label = "swap"; } ];
8 fileSystems = { 35 fileSystems = {
9 "/" = lib.mkForce { fsType = "zfs"; device = "zpool/root"; }; 36 "/" = { fsType = "zfs"; device = "zpool/root"; };
10 "/boot" = { fsType = "ext4"; device = "/dev/disk/by-uuid/fd1c511e-2bc0-49d5-b8bb-95e7e8c8c816"; }; 37 "/boot" = { fsType = "ext4"; device = "/dev/disk/by-uuid/fd1c511e-2bc0-49d5-b8bb-95e7e8c8c816"; };
11 "/etc" = { fsType = "zfs"; device = "zpool/root/etc"; }; 38 "/etc" = { fsType = "zfs"; device = "zpool/root/etc"; };
12 "/home" = { fsType = "zfs"; device = "zpool/root/home"; }; 39 "/home" = { fsType = "zfs"; device = "zpool/root/home"; };
13 "/home/immae" = { fsType = "zfs"; device = "zpool/root/home/immae"; }; 40 "/home/immae" = { fsType = "zfs"; device = "zpool/root/home/immae"; };
14 "/tmp" = { fsType = "zfs"; device = "zpool/root/tmp"; }; 41 "/tmp" = { fsType = "zfs"; device = "zpool/root/tmp"; };
15 "/var" = { fsType = "zfs"; device = "zpool/root/var"; }; 42 "/var" = { fsType = "zfs"; device = "zpool/root/var"; };
43 "/data" = { fsType = "ext4"; label = "data"; };
44 "/nix" = { fsType = "ext4"; label = "nix"; };
16 }; 45 };
17 boot.initrd.secrets = { 46
18 "/boot/pass.key" = "/boot/pass.key"; 47 services.udev.extraRules = ''
19 }; 48 ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="10:bf:48:7f:e6:3b", NAME="eth0"
49 '';
20 50
21 networking = { 51 networking = {
22 hostId = "27c3048d"; # generated with head -c4 /dev/urandom | od -A none -t x4 52 hostId = "27c3048d"; # generated with head -c4 /dev/urandom | od -A none -t x4
23 firewall.enable = false; 53 firewall.enable = false;
24 interfaces."eth0".ipv4.addresses = pkgs.lib.attrsets.mapAttrsToList 54 interfaces."eth0".ipv4.addresses =
25 (n: ips: { address = ips.ip4; prefixLength = 32; }) 55 [ { address = config.hostEnv.ips.main.ip4; prefixLength = 27; } ]
26 (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.hostEnv.ips); 56 ++ pkgs.lib.attrsets.mapAttrsToList
27 interfaces."eth0".ipv6.addresses = pkgs.lib.flatten (pkgs.lib.attrsets.mapAttrsToList 57 (n: ips: { address = ips.ip4; prefixLength = 32; })
28 (n: ips: map (ip: { address = ip; prefixLength = (if n == "main" && ip == pkgs.lib.head ips.ip6 then 64 else 128); }) (ips.ip6 or [])) 58 (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.hostEnv.ips);
29 config.hostEnv.ips); 59 interfaces."eth0".ipv6.addresses =
60 [ { address = "2a01:4f8:141:53e7::"; prefixLength = 64; } ]
61 ++ pkgs.lib.flatten (pkgs.lib.attrsets.mapAttrsToList
62 (n: ips: map (ip: { address = ip; prefixLength = (if n == "main" && ip == pkgs.lib.head ips.ip6 then 64 else 128); }) (ips.ip6 or []))
63 config.hostEnv.ips);
64 defaultGateway = { address = "176.9.10.225"; interface = "eth0"; };
65 defaultGateway6 = { address = "fe80::1"; interface = "eth0"; };
66 nameservers = [
67 "213.133.98.98"
68 "213.133.99.99"
69 "213.133.100.100"
70 "2a01:4f8:0:a0a1::add:1010"
71 "2a01:4f8:0:a102::add:9999"
72 "2a01:4f8:0:a111::add:9898"
73 ];
30 }; 74 };
31 75
32 myServices.ssh.modules = [ config.myServices.ssh.predefinedModules.regular ]; 76 myServices.ssh.modules = [ config.myServices.ssh.predefinedModules.regular ];
33 imports = builtins.attrValues (import ../..); 77 imports = builtins.attrValues (import ../..);
34 78
35 deployment = {
36 targetEnv = "hetzner";
37 hetzner = {
38 robotUser = config.myEnv.hetzner.user;
39 robotPass = config.myEnv.hetzner.pass;
40 mainIPv4 = config.hostEnv.ips.main.ip4;
41 partitions = ''
42 clearpart --all --initlabel --drives=sda,sdb,sdc,sdd
43
44 part swap --recommended --label=swap --fstype=swap --ondisk=sda
45
46 part raid.1 --grow --ondisk=sdc
47 part raid.2 --grow --ondisk=sdd
48
49 raid / --level=1 --device=md0 --fstype=ext4 --label=root raid.1 raid.2
50
51 part /nix --grow --label=nix --ondisk=sda
52 part /data --grow --label=data --ondisk=sdb
53 '';
54 };
55 };
56
57 system.nssModules = [ pkgs.libvirt ]; 79 system.nssModules = [ pkgs.libvirt ];
58 system.nssDatabases.hosts = lib.mkForce [ "files" "libvirt_guest" "mymachines" "dns" "myhostname" ]; 80 system.nssDatabases.hosts = lib.mkForce [ "files" "libvirt_guest" "mymachines" "dns" "myhostname" ];
59 programs.zsh.enable = true; 81 programs.zsh.enable = true;
@@ -78,7 +100,6 @@
78 } 100 }
79 ]; 101 ];
80 102
81 boot.kernel.sysctl."vm.nr_hugepages" = 256; # for xmr-stak
82 system.activationScripts.libvirtd_exports = '' 103 system.activationScripts.libvirtd_exports = ''
83 install -m 0755 -o root -g root -d /var/lib/caldance 104 install -m 0755 -o root -g root -d /var/lib/caldance
84 ''; 105 '';
diff --git a/modules/private/system/eldiron.nix b/modules/private/system/eldiron.nix
index 83e52b8..bb8bbfc 100644
--- a/modules/private/system/eldiron.nix
+++ b/modules/private/system/eldiron.nix
@@ -1,22 +1,45 @@
1{ privateFiles }: 1{ privateFiles }:
2{ config, pkgs, lib, ... }: 2{ config, pkgs, lib, ... }:
3{ 3{
4 boot.supportedFilesystems = [ "zfs" ]; 4 deployment = {
5 boot.kernelParams = ["zfs.zfs_arc_max=6442450944"]; 5 targetUser = "root";
6 boot.kernelPackages = pkgs.linuxPackages_latest; 6 targetHost = config.hostEnv.ips.main.ip4;
7 substituteOnDestination = true;
8 };
9 boot = {
10 kernelModules = [ "kvm-intel" ];
11 blacklistedKernelModules = [ "nvidiafb" ];
12 loader.timeout = 1;
13 loader.grub.devices = [ "/dev/sda" "/dev/sdb" ];
14 kernel.sysctl = {
15 # https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001.md
16 "net.ipv4.tcp_sack" = 0;
17 };
18 supportedFilesystems = [ "zfs" ];
19 kernelParams = ["zfs.zfs_arc_max=6442450944"];
20 kernelPackages = pkgs.linuxPackages_latest;
21 initrd.availableKernelModules = [ "ahci" "sd_mod" ];
22 initrd.secrets = {
23 "/boot/pass.key" = "/boot/pass.key";
24 };
25 };
26 services.udev.extraRules = ''
27 ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="c8:60:00:56:a0:88", NAME="eth0"
28 '';
29 nix.maxJobs = 8;
30 powerManagement.cpuFreqGovernor = "powersave";
7 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 31 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
8 32
9 fileSystems = { 33 fileSystems = {
10 "/" = lib.mkForce { fsType = "zfs"; device = "zpool/root"; }; 34 "/" = { fsType = "zfs"; device = "zpool/root"; };
11 "/boot" = { fsType = "ext4"; device = "/dev/disk/by-uuid/e6bb18fb-ff56-4b5f-ae9f-e60d40dc0622"; }; 35 "/boot" = { fsType = "ext4"; device = "/dev/disk/by-uuid/e6bb18fb-ff56-4b5f-ae9f-e60d40dc0622"; };
12 "/etc" = { fsType = "zfs"; device = "zpool/root/etc"; }; 36 "/etc" = { fsType = "zfs"; device = "zpool/root/etc"; };
13 "/nix" = { fsType = "zfs"; device = "zpool/root/nix"; }; 37 "/nix" = { fsType = "zfs"; device = "zpool/root/nix"; };
14 "/tmp" = { fsType = "zfs"; device = "zpool/root/tmp"; }; 38 "/tmp" = { fsType = "zfs"; device = "zpool/root/tmp"; };
15 "/var" = { fsType = "zfs"; device = "zpool/root/var"; }; 39 "/var" = { fsType = "zfs"; device = "zpool/root/var"; };
16 }; 40 };
17 boot.initrd.secrets = { 41 swapDevices = [ { label = "swap1"; } { label = "swap2"; } ];
18 "/boot/pass.key" = "/boot/pass.key"; 42 hardware.enableRedistributableFirmware = true;
19 };
20 43
21 services.zfs = { 44 services.zfs = {
22 autoScrub = { 45 autoScrub = {
@@ -27,20 +50,34 @@
27 hostId = "8262ca33"; # generated with head -c4 /dev/urandom | od -A none -t x4 50 hostId = "8262ca33"; # generated with head -c4 /dev/urandom | od -A none -t x4
28 firewall.enable = true; 51 firewall.enable = true;
29 # 176.9.151.89 declared in nixops -> infra / tools 52 # 176.9.151.89 declared in nixops -> infra / tools
30 interfaces."eth0".ipv4.addresses = pkgs.lib.attrsets.mapAttrsToList 53 interfaces."eth0".ipv4.addresses =
31 (n: ips: { address = ips.ip4; prefixLength = 32; }) 54 pkgs.lib.attrsets.mapAttrsToList
32 (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.hostEnv.ips); 55 (n: ips: { address = ips.ip4; prefixLength = 32; })
56 (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.hostEnv.ips)
57 ++ [ { address = config.hostEnv.ips.main.ip4; prefixLength = 27; } ];
33 interfaces."eth0".ipv6.addresses = pkgs.lib.flatten (pkgs.lib.attrsets.mapAttrsToList 58 interfaces."eth0".ipv6.addresses = pkgs.lib.flatten (pkgs.lib.attrsets.mapAttrsToList
34 (n: ips: map (ip: { address = ip; prefixLength = (if n == "main" && ip == pkgs.lib.head ips.ip6 then 64 else 128); }) (ips.ip6 or [])) 59 (n: ips: map (ip: { address = ip; prefixLength = (if n == "main" && ip == pkgs.lib.head ips.ip6 then 64 else 128); }) (ips.ip6 or []))
35 config.hostEnv.ips); 60 config.hostEnv.ips);
61 defaultGateway = "176.9.151.65";
62 localCommands = ''
63 # FIXME: Those commands were added by nixops and may not be
64 # actually needed
65 ip -6 addr add '2a01:4f8:160:3445::/64' dev 'eth0' || true
66 ip -4 route change '176.9.151.64/27' via '176.9.151.65' dev 'eth0' || true
67 ip -6 route add default via 'fe80::1' dev eth0 || true
68 '';
69 nameservers = [
70 "213.133.98.98"
71 "213.133.99.99"
72 "213.133.100.100"
73 "2a01:4f8:0:a0a1::add:1010"
74 "2a01:4f8:0:a102::add:9999"
75 "2a01:4f8:0:a111::add:9898"
76 ];
36 }; 77 };
37 78
38 imports = builtins.attrValues (import ../..); 79 imports = builtins.attrValues (import ../..);
39 80
40 boot.kernel.sysctl = {
41 # https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001.md
42 "net.ipv4.tcp_sack" = 0;
43 };
44 myServices.buildbot.enable = true; 81 myServices.buildbot.enable = true;
45 myServices.databases.enable = true; 82 myServices.databases.enable = true;
46 myServices.gitolite.enable = true; 83 myServices.gitolite.enable = true;
@@ -76,26 +113,6 @@
76 "${profile.host_key_type} ${profile.host_key}"; 113 "${profile.host_key_type} ${profile.host_key}";
77 }; 114 };
78 115
79 deployment = {
80 targetEnv = "hetzner";
81 hetzner = {
82 robotUser = config.myEnv.hetzner.user;
83 robotPass = config.myEnv.hetzner.pass;
84 mainIPv4 = config.hostEnv.ips.main.ip4;
85 partitions = ''
86 clearpart --all --initlabel --drives=sda,sdb
87
88 part swap1 --recommended --label=swap1 --fstype=swap --ondisk=sda
89 part swap2 --recommended --label=swap2 --fstype=swap --ondisk=sdb
90
91 part raid.1 --grow --ondisk=sda
92 part raid.2 --grow --ondisk=sdb
93
94 raid / --level=1 --device=md0 --fstype=ext4 --label=root raid.1 raid.2
95 '';
96 };
97 };
98
99 services.cron = { 116 services.cron = {
100 enable = true; 117 enable = true;
101 mailto = "cron@immae.eu"; 118 mailto = "cron@immae.eu";
diff --git a/modules/private/system/monitoring-1.nix b/modules/private/system/monitoring-1.nix
index c87c784..2241b2b 100644
--- a/modules/private/system/monitoring-1.nix
+++ b/modules/private/system/monitoring-1.nix
@@ -1,20 +1,15 @@
1{ privateFiles }: 1{ privateFiles }:
2{ config, pkgs, resources, ... }: 2{ config, pkgs, resources, ... }:
3{ 3{
4 deployment = {
5 targetUser = "root";
6 targetHost = config.hostEnv.ips.main.ip4;
7 substituteOnDestination = true;
8 };
4 boot.kernelPackages = pkgs.linuxPackages_latest; 9 boot.kernelPackages = pkgs.linuxPackages_latest;
5 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; 10 myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
6 11
7 imports = builtins.attrValues (import ../..); 12 imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ] ++ builtins.attrValues (import ../..);
8
9 deployment = {
10 targetEnv = "hetznerCloud";
11 hetznerCloud = {
12 authToken = config.myEnv.hetznerCloud.authToken;
13 datacenter = "hel1-dc2";
14 location ="hel1";
15 serverType = "cx11";
16 };
17 };
18 13
19 myServices.monitoring.enable = true; 14 myServices.monitoring.enable = true;
20 myServices.monitoring.master = true; 15 myServices.monitoring.master = true;
@@ -29,6 +24,8 @@
29 config.hostEnv.ips); 24 config.hostEnv.ips);
30 defaultGateway6 = { address = "fe80::1"; interface = "ens3"; }; 25 defaultGateway6 = { address = "fe80::1"; interface = "ens3"; };
31 }; 26 };
27 boot.loader.grub.device = "nodev";
28 fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
32 myServices.mailRelay.enable = true; 29 myServices.mailRelay.enable = true;
33 30
34 security.pki.certificateFiles = [ 31 security.pki.certificateFiles = [
diff --git a/modules/secrets.nix b/modules/secrets.nix
index a2424e9..a149f02 100644
--- a/modules/secrets.nix
+++ b/modules/secrets.nix
@@ -61,14 +61,13 @@
61 fi 61 fi
62 ''; 62 '';
63 }; 63 };
64 deployment.keys."secrets.tar" = { 64 system.extraDependencies = [ secrets ];
65 deployment.secrets."secrets.tar" = {
66 source = "${secrets}";
67 destination = "/run/keys/secrets.tar";
68 owner.user = "root";
69 owner.group = "root";
65 permissions = "0400"; 70 permissions = "0400";
66 # keyFile below is not evaluated at build time by nixops, so the
67 # `secrets` path doesn’t necessarily exist when uploading the
68 # keys, and nixops is unhappy.
69 user = "root${builtins.substring 10000 1 secrets}";
70 group = "root";
71 keyFile = "${secrets}";
72 }; 71 };
73 }; 72 };
74} 73}
diff --git a/nixops/Makefile b/nixops/Makefile
index 18d48eb..0bebaf8 100644
--- a/nixops/Makefile
+++ b/nixops/Makefile
@@ -2,8 +2,6 @@ ifndef NIXOPS_ENV_LOADED
2 $(error "Please load environment with direnv") 2 $(error "Please load environment with direnv")
3endif 3endif
4 4
5NIXOPS_PRIV = ./scripts/with_env nixops
6
7###### Current channel information 5###### Current channel information
8nix-info: 6nix-info:
9 @version=$$(nix eval --raw nixpkgs.lib.version) && \ 7 @version=$$(nix eval --raw nixpkgs.lib.version) && \
@@ -17,100 +15,69 @@ setup:
17 ./scripts/setup 15 ./scripts/setup
18.PHONY: setup 16.PHONY: setup
19 17
20###### Nixops regular tasks 18###### Morph regular tasks
19PROFILE=/nix/var/nix/profiles/per-user/immae/morph/immaeEu
21TARGET ?= 20TARGET ?=
22NIXOPS_ARGS ?= 21MORPH_ARGS ?=
23ifdef TARGET 22ifdef TARGET
24 override NIXOPS_ARGS +=--include=$(TARGET) 23 # multiple targets: --on="{machine1,machine2}" (works with * glob too)
24 override MORPH_ARGS +=--on=$(TARGET)
25endif 25endif
26SSH_ARGS ?= 26SSH_ARGS ?=
27 27
28edit_env: 28edit_env:
29 pass edit Nixops/files/environment.nix || true 29 pass edit Nixops/files/environment.nix || true
30 30
31nixops:
32 $(NIXOPS_PRIV) $(NIXOPS_ARGS)
33
34ssh-eldiron: 31ssh-eldiron:
35 $(NIXOPS_PRIV) ssh eldiron -- $(SSH_ARGS) 32 ./scripts/with_env bash -c 'ssh -i $$SSH_IDENTITY_FILE root@eldiron $(SSH_ARGS)'
36 33
37ssh-dilion: 34ssh-dilion:
38 $(NIXOPS_PRIV) ssh dilion -- $(SSH_ARGS) 35 ./scripts/with_env bash -c 'ssh -i $$SSH_IDENTITY_FILE root@dilion $(SSH_ARGS)'
39 36
40ssh-backup-2: 37ssh-backup-2:
41 $(NIXOPS_PRIV) ssh backup-2 -- $(SSH_ARGS) 38 ./scripts/with_env bash -c 'ssh -i $$SSH_IDENTITY_FILE root@backup-2 $(SSH_ARGS)'
42 39
43ssh-monitoring-1: 40ssh-monitoring-1:
44 $(NIXOPS_PRIV) ssh monitoring-1 -- $(SSH_ARGS) 41 ./scripts/with_env bash -c 'ssh -i $$SSH_IDENTITY_FILE root@monitoring-1 $(SSH_ARGS)'
45
46info:
47 $(NIXOPS_PRIV) list
48 $(NIXOPS_PRIV) info
49 42
50debug: 43debug:
51 $(NIXOPS_PRIV) deploy --build-only --show-trace $(NIXOPS_ARGS) 44 ./scripts/with_env morph build --show-trace default.nix $(MORPH_ARGS)
52
53dry-run:
54 $(NIXOPS_PRIV) deploy --dry-run $(NIXOPS_ARGS)
55 45
56build: 46build:
57 $(NIXOPS_PRIV) deploy --build-only $(NIXOPS_ARGS) 47 ./scripts/with_env morph build default.nix $(MORPH_ARGS)
58 48
59upload: 49upload:
60 $(NIXOPS_PRIV) deploy --copy-only $(NIXOPS_ARGS) 50 ./scripts/with_env morph push default.nix $(MORPH_ARGS)
61 51
62deploy: 52deploy:
63 $(NIXOPS_PRIV) deploy $(NIXOPS_ARGS) 53 ./scripts/with_env morph deploy default.nix switch --keep-result --upload-secrets $(MORPH_ARGS)
54 nix-env -p $(PROFILE) --set .gcroots/default.nix
64 55
65deploy-reboot: 56deploy-reboot:
66 $(NIXOPS_PRIV) deploy --force-reboot $(NIXOPS_ARGS) 57 ./scripts/with_env morph deploy default.nix boot --reboot --upload-secrets $(MORPH_ARGS)
67 58
68reboot: 59.PHONY: ssh-eldiron ssh-dilion ssh-monitoring-1 ssh-backup-2 debug build upload deploy deploy-reboot
69 $(NIXOPS_PRIV) reboot --include=$(TARGET)
70.PHONY: nixops ssh-eldiron info debug dry-run build upload deploy deploy-reboot reboot
71 60
72###### Cleanup generations and garbage collection 61###### Cleanup generations and garbage collection
73profile := $$($(NIXOPS_PRIV) info | grep "^Nix profile: " | sed -e "s/^Nix profile: //")
74GEN ?= "+3" 62GEN ?= "+3"
75 63
76list-generations: 64list-generations:
77 nix-env -p $(profile) --list-generations 65 nix-env -p $(PROFILE) --list-generations
78 $(NIXOPS_PRIV) ssh eldiron -- nix-env -p /nix/var/nix/profiles/system --list-generations 66 $(MAKE) ssh-eldiron SSH_ARGS="nix-env -p /nix/var/nix/profiles/system --list-generations"
79.PHONY: list-generations 67.PHONY: list-generations
80 68
81delete-generations: 69delete-generations:
82 nix-env -p $(profile) --delete-generations $(GEN) 70 nix-env -p $(PROFILE) --delete-generations $(GEN)
83 $(NIXOPS_PRIV) ssh eldiron -- nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN) 71 $(MAKE) ssh-eldiron SSH_ARGS="nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN)"
84 $(NIXOPS_PRIV) ssh dilion -- nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN) 72 $(MAKE) ssh-dilion SSH_ARGS="nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN)"
85 $(NIXOPS_PRIV) ssh backup-2 -- nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN) 73 $(MAKE) ssh-backup-2 SSH_ARGS="nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN)"
86 $(NIXOPS_PRIV) ssh monitoring-1 -- nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN) 74 $(MAKE) ssh-monitoring-1 SSH_ARGS="nix-env -p /nix/var/nix/profiles/system --delete-generations $(GEN)"
87.PHONY: delete-generations 75.PHONY: delete-generations
88 76
89cleanup: delete-generations 77cleanup: delete-generations
90 nix-store --gc 78 nix-store --gc
91 $(NIXOPS_PRIV) ssh eldiron -- nix-store --gc 79 $(MAKE) ssh-eldiron SSH_ARGS="nix-store --gc"
92 $(NIXOPS_PRIV) ssh dilion -- nix-store --gc 80 $(MAKE) ssh-dilion SSH_ARGS="nix-store --gc"
93 $(NIXOPS_PRIV) ssh backup-2 -- nix-store --gc 81 $(MAKE) ssh-backup-2 SSH_ARGS="nix-store --gc"
94 $(NIXOPS_PRIV) ssh monitoring-1 -- nix-store --gc 82 $(MAKE) ssh-monitoring-1 SSH_ARGS="nix-store --gc"
95.PHONY: cleanup 83.PHONY: cleanup
96
97###### Pull environment and deployment from remote
98pull_deployment:
99 @if nixops info -d $(NIXOPS_DEPLOYMENT) 2>/dev/null >/dev/null ; then \
100 echo "This will remove your current deployment file and recreate it!. Continue? [y/N]" && \
101 read y && \
102 [ "$$y" = "y" -o "$$y" = "Y" ] && \
103 nixops delete --force -d $(NIXOPS_DEPLOYMENT); \
104 fi
105 pass show Nixops/Deployment | nixops import
106 nixops modify -d $(NIXOPS_DEPLOYMENT) "$$(pwd)/default.nix"
107.PHONY: pull_deployment
108
109deployment_is_set:
110 nixops info -d $(NIXOPS_DEPLOYMENT) 2>/dev/null >/dev/null
111.PHONY: deployment_is_set
112
113###### Push deployment information to password store
114push_deployment:
115 nixops export | pass insert -m Nixops/Deployment
116.PHONY: push
diff --git a/nixops/default.nix b/nixops/default.nix
index 56b86e8..7c6dd38 100644
--- a/nixops/default.nix
+++ b/nixops/default.nix
@@ -1,12 +1,7 @@
1{ privateFiles ? ./. }: 1let
2 privateFiles = <privateFiles>;
3in
2{ 4{
3 network = {
4 description = "Immae's network";
5 enableRollback = true;
6 };
7
8 # Used by hetzner cloud to provision machines
9 resources.sshKeyPairs.ssh-key = {};
10 dilion = import ../modules/private/system/dilion.nix { inherit privateFiles; }; 5 dilion = import ../modules/private/system/dilion.nix { inherit privateFiles; };
11 eldiron = import ../modules/private/system/eldiron.nix { inherit privateFiles; }; 6 eldiron = import ../modules/private/system/eldiron.nix { inherit privateFiles; };
12 backup-2 = import ../modules/private/system/backup-2.nix { inherit privateFiles; }; 7 backup-2 = import ../modules/private/system/backup-2.nix { inherit privateFiles; };
diff --git a/nixops/scripts/setup b/nixops/scripts/setup
index 22f43ce..e161e43 100755
--- a/nixops/scripts/setup
+++ b/nixops/scripts/setup
@@ -2,8 +2,6 @@
2 2
3set -euo pipefail 3set -euo pipefail
4 4
5MAKEFILE_DIR="$( cd "$( dirname $( dirname "${BASH_SOURCE[0]}" ))" >/dev/null 2>&1 && pwd )"
6
7if ! which nix 2>/dev/null >/dev/null; then 5if ! which nix 2>/dev/null >/dev/null; then
8 cat <<-EOF 6 cat <<-EOF
9 nix is needed, please install it: 7 nix is needed, please install it:
@@ -62,20 +60,6 @@ if nix show-config --json | jq -e '.sandbox.value == "true"' >/dev/null; then
62 read y 60 read y
63fi 61fi
64 62
65if ! make -C $MAKEFILE_DIR deployment_is_set 2>/dev/null >/dev/null; then
66 cat <<-EOF
67 Importing deployment file into nixops:
68 Continue? [y/N]
69 EOF
70 read y
71 if [ "$y" = "y" -o "$y" = "Y" ]; then
72 make -C $MAKEFILE_DIR pull_deployment
73 else
74 echo "Aborting"
75 exit 1
76 fi
77fi
78
79cat <<-EOF 63cat <<-EOF
80 All set up. 64 All set up.
81 Please make sure you’re using make commands when deploying 65 Please make sure you’re using make commands when deploying
diff --git a/nixops/scripts/with_env b/nixops/scripts/with_env
index 9882f78..f8e5537 100755
--- a/nixops/scripts/with_env
+++ b/nixops/scripts/with_env
@@ -5,12 +5,12 @@ if [ -z "$NIXOPS_ENV_LOADED" ]; then
5 exit 1; 5 exit 1;
6fi 6fi
7 7
8umask 0077
8TEMP=$(mktemp -d /tmp/XXXXXX-nixops-files) 9TEMP=$(mktemp -d /tmp/XXXXXX-nixops-files)
9chmod go-rwx $TEMP 10chmod go-rwx $TEMP
10 11
11finish() { 12finish() {
12 rm -rf "$TEMP" 13 rm -rf "$TEMP"
13 nixops set-args --unset privateFiles
14} 14}
15 15
16trap finish EXIT 16trap finish EXIT
@@ -21,6 +21,8 @@ files=$(pass ls Nixops/files | sed -e '1d' -e 's/^.* //')
21for file in $files; do 21for file in $files; do
22 pass show "Nixops/files/$file" > $TEMP/$file 22 pass show "Nixops/files/$file" > $TEMP/$file
23done 23done
24nixops set-args --argstr privateFiles "$TEMP" 24
25export NIX_PATH="privateFiles=$TEMP:$NIX_PATH"
26export SSH_IDENTITY_FILE="$TEMP/id_ed25519"
25 27
26"$@" 28"$@"
diff --git a/nixops/secrets b/nixops/secrets
Subproject 79b991028b09aa59f719059de8dc1fba7d6b04f Subproject def4146f0e703ca9a32735fbbc3820d6f9bb22e
diff --git a/nixops/state/.gitkeep b/nixops/state/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/nixops/state/.gitkeep
+++ /dev/null
diff --git a/overlays/default.nix b/overlays/default.nix
index 0c7c738..7444e15 100644
--- a/overlays/default.nix
+++ b/overlays/default.nix
@@ -32,5 +32,6 @@
32 doing = import ./doing; 32 doing = import ./doing;
33 khal = import ./khal; 33 khal = import ./khal;
34 nix-direnv = import ./nix-direnv; 34 nix-direnv = import ./nix-direnv;
35 morph = import ./morph;
35} 36}
36// import ./python-packages 37// import ./python-packages
diff --git a/overlays/morph/default.nix b/overlays/morph/default.nix
new file mode 100644
index 0000000..ee59e25
--- /dev/null
+++ b/overlays/morph/default.nix
@@ -0,0 +1,5 @@
1self: super: {
2 morph = super.morph.overrideAttrs(old: {
3 patches = (old.patches or []) ++ [ ./verbose_nix.patch ];
4 });
5}
diff --git a/overlays/morph/verbose_nix.patch b/overlays/morph/verbose_nix.patch
new file mode 100644
index 0000000..389a79c
--- /dev/null
+++ b/overlays/morph/verbose_nix.patch
@@ -0,0 +1,12 @@
1diff --git a/nix/nix.go b/nix/nix.go
2index bb63870..7fe04aa 100644
3--- a/nix/nix.go
4+++ b/nix/nix.go
5@@ -347,6 +347,7 @@ func Push(ctx *ssh.SSHContext, host Host, paths ...string) (err error) {
6 options := mkOptions(host)
7 for _, path := range paths {
8 args := []string{
9+ "-v",
10 "copy",
11 path,
12 "--to", "ssh://" + userArg + host.TargetHost + keyArg,
diff --git a/shell.nix b/shell.nix
index 70c7604..2a95658 100644
--- a/shell.nix
+++ b/shell.nix
@@ -1,4 +1,4 @@
1{ pkgs ? import <nixpkgs> { overlays = builtins.attrValues (import ./overlays); } }: 1{ pkgs ? import <nixpkgs> { overlays = builtins.attrValues (import ./overlays); } }:
2pkgs.mkShell { 2pkgs.mkShell {
3 buildInputs = [ pkgs.nixops pkgs.niv pkgs.pass pkgs.curl pkgs.shellcheck pkgs.jq pkgs.gnumake ]; 3 buildInputs = [ pkgs.morph pkgs.niv pkgs.pass pkgs.curl pkgs.shellcheck pkgs.jq pkgs.gnumake ];
4} 4}