nixos-notes

nixos notes
git clone https://logand.com/git/nixos-notes.git/
Log | Files | Refs | README

commit 8a7123f890bd08d69078fe864c457af103ca80c2
parent 20038216792e3dce8e72fa4c95a574142f76ac13
Author: Tomas Hlavaty <tom@logand.com>
Date:   Tue, 10 Sep 2019 23:39:58 +0200

more notes

Diffstat:
MREADME | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 138 insertions(+), 0 deletions(-)

diff --git a/README b/README @@ -54,3 +54,141 @@ Install NixOS $ sudo cryptsetup luksAddKey /dev/sdX $ sudo cryptsetup luksRemoveKey /dev/sdX + +## Deployment + +There are several deployment tools for nixos each with pros and cons. + +- nixops: tried it, didn't like it. too stateful and fragile. + +- hail: did not try. looks abandoned. pulls updates from hydra. + +- morph: did not try. looks complex. + +- krops: did not try. actively used. builds remotely, which I don't + want. A production server should serve specific purpose and things + which don't serve that purpose should not be there, i.e. I don't + want to build there anything and I don't want the build artefacts to + be stored there. + +- nixos-rebuild: nixos native command. supports deploying to other + machines but doesn't do substitutes, which is a major flaw on + asymetric connections with bad upload speed. + +nixos-rebuid is actually closest to what I want. + +Here is an example of a deployment scripts for several machines, each +with different nixpkgs. Deployment scripts are first built for all +machines (can be built and cached by hydra, for example). Running a +deployment script handles local and remote deployments accordingly. +Remote deployments immitate "nixos-rebuild switch" but allow +substitutes by copying the closure first. + +Have hw directory with subdir with configuration.nix for each machine. +hw/default.nix can look something like this: + + # nix-build && ./result/bin/deploy-all + # nix-build && ./result/bin/deploy-hostname1 + # nix-build && ./result/bin/deploy-hostname2 + let + pkgs = import <nixpkgs> {}; + nixpkgs1809 = fetchTarball { + url = https://nixos.org/channels/nixos-18.09/nixexprs.tar.xz; + }; + nixpkgs1903 = fetchTarball { + url = https://nixos.org/channels/nixos-19.03/nixexprs.tar.xz; + }; + local = name: nixpkgs: + pkgs.writeScript "deploy-local-${name}" '' + sudo nixos-rebuild switch \ + -I nixos-config=./${name}/configuration.nix \ + -I nixpkgs=${nixpkgs} + ''; + buildSystem = name: nixpkgs: + let + # https://stackoverflow.com/questions/47655567/how-to-build-a-nixops-deployment-on-hydra + pkgs2 = import nixpkgs {}; + nixosSystem = import (pkgs2.path + "/nixos/lib/eval-config.nix") { + inherit (pkgs2) system; + modules = [(./. + "/${name}/configuration.nix")]; + }; + in nixosSystem.config.system.build.toplevel; + remote = name: nixpkgs: + let + sshName = "${name}.tincnet"; + system = buildSystem name nixpkgs; + pkgs2 = import nixpkgs {}; + switch = pkgs.writeScript "switch-${name}" '' + #!${pkgs2.bash}/bin/bash + set -euo pipefail + cd /tmp + ls -al /nix/var/nix/profiles + echo register ${system} + sudo nix-env -p /nix/var/nix/profiles/system --set ${system} + echo switch + sudo nohup ${system}/bin/switch-to-configuration switch + ls -al /nix/var/nix/profiles + ''; + in + pkgs.writeScript "deploy-remote-${name}" '' + #!${pkgs.bash}/bin/bash + set -euo pipefail + echo starting ${name} to ${sshName} + #nix-copy-closure --sign --use-substitutes --to ${sshName} ${switch} + nix-copy-closure --gzip --use-substitutes --to ${sshName} ${switch} + #nix copy --to ssh://${sshName} ${switch} + ssh -t ${sshName} ${switch} + echo ok ${name} to ${sshName} + ''; + deploy1 = name: nixpkgs: + pkgs.writeScriptBin "deploy-${name}" '' + #!${pkgs.bash}/bin/bash + set -euo pipefail + if test ${name} -eq $(hostname -s); then + exec ${local name nixpkgs} + else + exec ${remote name nixpkgs} + fi + ''; + all = [ + (deploy1 "hostname1" nixpkgs1809) + (deploy1 "hostname2" nixpkgs1903) + ]; + in + pkgs.buildEnv { + name = "deploy"; + paths = all ++ [ + (pkgs.writeScriptBin "deploy-all" ('' + #!${pkgs.bash}/bin/bash + set -euo pipefail + '' + + (pkgs.stdenv.lib.concatMapStrings (x: "${x}\n") all))) + ]; + } + +If the closure is not signed, your user needs to be trusted by nix in +the target machine configuration.nix: + + nix.trustedUsers = ["root" "myuser"]; + +## Secrets + +Nix does not address management of secrets. + +What I do, for example, for tinc: + +- define the tinc service with empty fields for unknown public keys + +- deploy the the tinc service, let it generate the keys on the target + machine + +- read the public key from the target machine and update the tinc + service with the newly acquired public key + +- deploy the tinc service for the second time, this time with the + public key already filled in + +Some NixOS deployment tools try to handle it by creating the secret +keys somewhere and then pushing them to the target machines. I am not +convinced that this is the right approach. Secrets should not be +pushed around unnecessarily.