From 6de67fc2040a8ab74a2225376869b024175c2f0b Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Sun, 20 Dec 2020 03:28:30 +0100 Subject: [PATCH] Use nix flake support to build and deploy machines --- bin/deploy | 32 ++++---- channels/nixos-19.09/default.nix | 1 - channels/nixos-unstable/default.nix | 1 - configuration.nix | 42 ++++++---- flake.lock | 6 +- layers/workstation.nix | 1 + layers/zsh.nix | 4 +- machine-manager.nix | 122 +++++++++++++++++----------- 8 files changed, 119 insertions(+), 90 deletions(-) diff --git a/bin/deploy b/bin/deploy index a78c412..051fccc 100755 --- a/bin/deploy +++ b/bin/deploy @@ -8,7 +8,7 @@ set -o pipefail readonly cmdname=$(basename $0) -readonly machines_repo_entry_point=$MACHINES_PATH/default.nix +readonly machines_repo_entry_point=$MACHINES_PATH/flake.nix # This script cannot run without the nixos configuration entry point if [[ ! -f "$machines_repo_entry_point" ]] @@ -17,7 +17,6 @@ then exit 2 fi - source $DOTFILES_PATH/bin/lib/util.zsh usage() { @@ -101,7 +100,7 @@ trap "rm -rf $local_temp_dir" EXIT INT HUP TERM if [[ "$operation" = "iso" ]] then print_info "Building iso image" - nix build --file "$MACHINES_PATH" --out-link "$local_temp_dir/nixos-iso-$hostname" "nixosIsoDerivations.$hostname" + nix build "path:$MACHINES_PATH#nixosConfigurations.$hostname.config.system.build.iso" --out-link "$local_temp_dir/nixos-iso-$hostname" readonly nixos_iso_path=$(realpath "$local_temp_dir/nixos-iso-$hostname") print_info "Iso generated" @@ -110,22 +109,22 @@ then fi -print_info "Building target system configuration" -nix build --file "$MACHINES_PATH" --out-link "$local_temp_dir/nixos-config-$hostname" "nixosSystemDerivations.$hostname" -readonly nixos_config_path=$(realpath "$local_temp_dir/nixos-config-$hostname") - -if [[ "$operation" = "build" ]] -then - print_info "Build completed" - print $nixos_config_path - exit 0 -fi - print_info "Deploying target system configuration" -if [[ "$is_target_host" ]] +if [[ "$is_target_host" || "$operation" = "build" ]] then # local deploy + print_info "Building target system configuration" + nix build "path:$MACHINES_PATH#nixosConfigurations.$hostname.config.system.build.toplevel" --out-link "$local_temp_dir/nixos-config-$hostname" + readonly nixos_config_path=$(realpath "$local_temp_dir/nixos-config-$hostname") + + if [[ "$operation" = "build" ]] + then + print_info "Build completed" + print $nixos_config_path + exit 0 + fi + if [[ -n "$set_profile" ]] then sudo nix-env --profile /nix/var/nix/profiles/system --set $nixos_config_path @@ -140,8 +139,7 @@ then else # remote deploy - nix copy --file "$MACHINES_PATH" "nixosSystemDerivations.$hostname" --to "ssh://root@$via_hostname" - #nix copy --substitute-on-destination --file "$MACHINES_PATH" "nixosSystemDerivations.$hostname" --to "ssh://root@$via_hostname" + nix copy --substitute-on-destination --to "ssh://root@$via_hostname" "path:$MACHINES_PATH#nixosConfigurations.$hostname.config.system.build.toplevel" # The manual way to do it (this is in theory also supported by nixos-rebuild by using '-I') diff --git a/channels/nixos-19.09/default.nix b/channels/nixos-19.09/default.nix index 000e694..9637fd5 100644 --- a/channels/nixos-19.09/default.nix +++ b/channels/nixos-19.09/default.nix @@ -7,6 +7,5 @@ let channelDef = fromJSON ( readFile ./channel.json ); in fetchGit { - inherit name; inherit (channelDef) url rev ref; } diff --git a/channels/nixos-unstable/default.nix b/channels/nixos-unstable/default.nix index 000e694..9637fd5 100644 --- a/channels/nixos-unstable/default.nix +++ b/channels/nixos-unstable/default.nix @@ -7,6 +7,5 @@ let channelDef = fromJSON ( readFile ./channel.json ); in fetchGit { - inherit name; inherit (channelDef) url rev ref; } diff --git a/configuration.nix b/configuration.nix index 7537d37..01cbd10 100644 --- a/configuration.nix +++ b/configuration.nix @@ -22,12 +22,31 @@ let else builtins.throw "Cannot find layer `${layerName}`"; layerImports = map layerPath dotfilesConfig.layers; + + normalSystemConfiguration = (lib.attrsets.optionalAttrs (!isIso) { + imports = [ (path + "/hardware-configuration.nix") ]; + # Bootloader + boot.loader.systemd-boot.enable = (installResult.bootloader == "efi"); + boot.loader.efi.canTouchEfiVariables = (installResult.bootloader == "efi"); + boot.loader.grub.enable = (installResult.bootloader == "bios"); + boot.loader.grub.device = installResult.installedBlockDevice; + + boot.initrd.luks.devices = if installResult.luks then { + cryptvol = { + device = "/dev/disk/by-uuid/" + installResult.luksPartitionUuid; + allowDiscards = true; + }; + } else {}; + }); in -({ +{ imports = [ ./modules (path + "/configuration.nix") - ] ++ layerImports ++ (lib.lists.optional (!isIso) (path + "/hardware-configuration.nix")); + normalSystemConfiguration + ] ++ layerImports; + + _module.args.isIso = lib.mkDefault false; nixpkgs.config = { packageOverrides = import ./pkgs; @@ -35,8 +54,9 @@ in # Pin channel in nix path nix.nixPath = [ "nixpkgs=${channel}" ]; + nix.registry.nixpkgs.flake = channel; # Make nixpkgs path available inside of the configuration - _module.args.nixpkgsPath = channel; + #_module.args.nixpkgsPath = channel; environment.shellAliases = { # nixos-option won't run without a configuration. With an empty config it does not show configured values, but can at least be used to search options and show default values. @@ -45,18 +65,4 @@ in # Default hostname ist machine directory name networking.hostName = lib.mkDefault name; - -} // (lib.attrsets.optionalAttrs (!isIso) { - # Bootloader - boot.loader.systemd-boot.enable = (installResult.bootloader == "efi"); - boot.loader.efi.canTouchEfiVariables = (installResult.bootloader == "efi"); - boot.loader.grub.enable = (installResult.bootloader == "bios"); - boot.loader.grub.device = installResult.installedBlockDevice; - - boot.initrd.luks.devices = if installResult.luks then { - cryptvol = { - device = "/dev/disk/by-uuid/" + installResult.luksPartitionUuid; - allowDiscards = true; - }; - } else {}; -})) +} diff --git a/flake.lock b/flake.lock index 93caa22..7c9851b 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1605988311, - "narHash": "sha256-PA+kgq46NApOAJlmBNJHs5DwsIrY+jodM0e4g7VtXyY=", + "lastModified": 1607690238, + "narHash": "sha256-9QFXxj6pjmHr+950E3/gXo9cz50l0AbFCHZR5eixkXw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2247d824fe07f16325596acc7faa286502faffd1", + "rev": "8006772a054ce57ca18c5955dcd6ec9a62577473", "type": "github" }, "original": { diff --git a/layers/workstation.nix b/layers/workstation.nix index 3a3654a..377ec82 100644 --- a/layers/workstation.nix +++ b/layers/workstation.nix @@ -6,6 +6,7 @@ ./vscode.nix ]; + nix.package = pkgs.nixUnstable; nix.extraOptions = '' experimental-features = nix-command flakes ''; diff --git a/layers/zsh.nix b/layers/zsh.nix index 4cb9a09..cb9ddec 100644 --- a/layers/zsh.nix +++ b/layers/zsh.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ pkgs, config, ... }: let promptPath = ../zsh/prompt; @@ -112,6 +112,8 @@ in alias icat="kitty +kitten icat" fi + source ${config.nix.package.src}/misc/zsh/completion.zsh + if (( $+commands[direnv] )) then eval "$(direnv hook zsh)" diff --git a/machine-manager.nix b/machine-manager.nix index a92a702..db81003 100644 --- a/machine-manager.nix +++ b/machine-manager.nix @@ -1,85 +1,109 @@ # entry point for machine configurations: # (import <repo-path> { machinesDir=./machines }).<netname>.configurations.<hostname> -{ machinesDir, extraLayersDir }: +{ flakeInputs, flakeOutputs, machinesDir, extraLayersDir }: with builtins; let # defaultChannel :: path (channel) - defaultChannel = loadChannel "nixos-unstable"; + #defaultChannel = loadChannel "nixos-unstable"; # helpers :: { *: ? } helpers = import ./helpers.nix; # channelsDir :: path - channelsDir = ./channels; + #channelsDir = ./channels; # loadChannel :: string -> path (channel) - loadChannel = name: import (channelsDir + "/${name}") name; + #loadChannel = name: import (channelsDir + "/${name}") name; # allChannels :: { *: path (channel) } - allChannels = with helpers; keysToAttrs loadChannel (readFilterDir (filterAnd [(not filterDirHidden) filterDirDirs]) channelsDir); + #allChannels = with helpers; keysToAttrs loadChannel (readFilterDir (filterAnd [(not filterDirHidden) filterDirDirs]) channelsDir); # getMachineChannel :: string -> path - getMachineChannel = { name, path }: - let - channelFile = path + "/channel.nix"; - in - if (pathExists channelFile) - then (import channelFile) allChannels - else defaultChannel; + getMachineChannel = _: flakeInputs.nixpkgs-unstable; + #getMachineChannel = { name, path }: + # let + # channelFile = path + "/channel.nix"; + # in + # if (pathExists channelFile) + # then (import channelFile) allChannels + # else defaultChannel; # machineChannels :: { *: path } machineChannels = withMachines getMachineChannel; machinesDirContents = readDir machinesDir; machineNames = filter (p: machinesDirContents.${p} == "directory") (attrNames machinesDirContents); withMachines = lambda: listToAttrs (map (m: {name = m; value = lambda { name = m; path = (machinesDir + "/${m}"); }; }) machineNames); - mkMachineConfig = { name, path, isIso ? false }: ( + mkMachineConfig = { name, path, isIso }: ( import ./configuration.nix { inherit name path isIso extraLayersDir; channel = machineChannels.${name}; } ); + evaluateConfig = pkgs: args: (import "${pkgs}/nixos/lib/eval-config.nix" args).config; mkNixosSystemDerivation = { name, path }: let - channel = machineChannels.${name}; - configuration = mkMachineConfig { inherit name path; }; - # Importing <nixpkgs/nixos> results in a nixos system closure - nixos = import "${channel}/nixos" { - system = "x86_64-linux"; - inherit configuration; - }; - in - nixos.system; - mkNixosIsoDerivation = { name, path }: - let - channel = machineChannels.${name}; - configuration = { config, ... }: - { - imports = [ - (mkMachineConfig { inherit name path; isIso = true; }) - <nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix> - <nixpkgs/nixos/modules/profiles/all-hardware.nix> - <nixpkgs/nixos/modules/profiles/base.nix> + channel = flakeInputs.nixpkgs-unstable; + configuration = mkMachineConfig { inherit name path; isIso = false; }; + isoConfiguration = mkMachineConfig { inherit name path; isIso = true; }; + system = "x86_64-linux"; + iso = (evaluateConfig channel { + inherit system; + modules = [ + isoConfiguration + (mkAdditionalIsoConfig name) ]; - isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixos.label}-isohost-${name}.iso"; - isoImage.volumeID = substring 0 11 "NIXOS_ISO"; - - isoImage.makeEfiBootable = true; - isoImage.makeUsbBootable = true; - boot.loader.grub.memtest86.enable = true; - - }; - # Importing <nixpkgs/nixos> results in a nixos system closure - nixos = import "${channel}/nixos" { - system = "x86_64-linux"; - inherit configuration; - }; + }).system.build.isoImage; + sdImage = (evaluateConfig channel { + inherit system; + modules = [ + isoConfiguration + (mkAdditionalSdCardConfig name) + ]; + }).system.build.sdImage; in - nixos.config.system.build.isoImage; + channel.lib.nixosSystem { + inherit system; + modules = [ + configuration + { + system.build = { + inherit iso sdImage; + }; + } + ]; + }; + mkAdditionalIsoConfig = name: { config, modulesPath, ... }: { + imports = [ + "${modulesPath}/installer/cd-dvd/iso-image.nix" + "${modulesPath}/profiles/all-hardware.nix" + "${modulesPath}/profiles/base.nix" + ]; + isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixos.label}-isohost-${name}.iso"; + isoImage.volumeID = substring 0 11 "NIXOS_ISO"; + isoImage.makeEfiBootable = true; + isoImage.makeUsbBootable = true; + boot.loader.grub.memtest86.enable = true; + _module.args.isIso = true; + }; + mkAdditionalSdCardConfig = name: { config, modulesPath, ... }: { + imports = [ + "${modulesPath}/installer/cd-dvd/sd-image.nix" + "${modulesPath}/profiles/all-hardware.nix" + "${modulesPath}/profiles/base.nix" + ]; + sdImage.populateRootCommands = ""; + sdImage.populateFirmwareCommands = ""; + boot.loader.grub.enable = false; + boot.loader.generic-extlinux-compatible.enable = true; + _module.args.isIso = true; + }; in { - configurations = withMachines mkMachineConfig; + # TODO remove + # configurations = withMachines mkMachineConfig; + # nixosIsoDerivations = withMachines mkNixosIsoDerivation; + # channels = machineChannels; + nixosSystemDerivations = withMachines mkNixosSystemDerivation; - nixosIsoDerivations = withMachines mkNixosIsoDerivation; machineTemplates = withMachines ({name, path}: import (path + /template.nix)); - channels = machineChannels; } -- GitLab