From eeb1dffd02a19b35e0f3877166c3b05a23aa823e Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Tue, 9 Jul 2024 13:21:49 +0200 Subject: [PATCH] nixos/nixos-install: add support for --file and --attr flags --- .../installer/tools/manpages/nixos-install.8 | 28 ++++++++ .../modules/installer/tools/nixos-install.sh | 68 ++++++++++++++++--- 2 files changed, 86 insertions(+), 10 deletions(-) diff --git a/nixos/modules/installer/tools/manpages/nixos-install.8 b/nixos/modules/installer/tools/manpages/nixos-install.8 index c6c8ed15224d..e1af90a37d76 100644 --- a/nixos/modules/installer/tools/manpages/nixos-install.8 +++ b/nixos/modules/installer/tools/manpages/nixos-install.8 @@ -14,6 +14,8 @@ .Op Fl -root Ar root .Op Fl -system Ar path .Op Fl -flake Ar flake-uri +.Op Fl -file | f Ar path +.Op Fl -attr | A Ar attrPath .Op Fl -impure .Op Fl -channel Ar channel .Op Fl -no-channel-copy @@ -111,6 +113,32 @@ output named .Ql nixosConfigurations. Ns Ar name Ns \&. . +.It Fl -file Ar path , Fl f Ar path +Enable and build the NixOS system from the specified file. The file must +evaluate to an attribute set, and it must contain a valid NixOS configuration +at attribute +.Va attrPath Ns +\&. This is useful for building a NixOS system from a nix file that is not +a flake or a NixOS configuration module. Attribute set a with valid NixOS +configuration can be made using +.Va nixos +function in nixpkgs or importing and calling +.Pa nixos/lib/eval-config.nix +from nixpkgs. If specified without +.Fl -attr +option, builds the configuration from the top-level +attribute of the file. +. +.It Fl -attr Ar attrPath , Fl A Ar attrPath +Enable and build the NixOS system from nix file and use the specified attribute +path from file specified by the +.Fl -file +option. If specified without +.Fl -file +option, uses +.Va [root] Ns Pa /etc/nixos/default.nix Ns +\&. +. .It Fl -channel Ar channel If this option is provided, do not copy the current .Dq nixos diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 4e42875c0365..a76b4ffb4444 100755 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -17,6 +17,9 @@ mountPoint=/mnt channelPath= system= verbosity=() +attr= +buildFile= +buildingAttribute=1 while [ "$#" -gt 0 ]; do i="$1"; shift 1 @@ -41,6 +44,24 @@ while [ "$#" -gt 0 ]; do flakeFlags=(--experimental-features 'nix-command flakes') shift 1 ;; + --file|-f) + if [ -z "$1" ]; then + log "$0: '$i' requires an argument" + exit 1 + fi + buildFile="$1" + buildingAttribute= + shift 1 + ;; + --attr|-A) + if [ -z "$1" ]; then + log "$0: '$i' requires an argument" + exit 1 + fi + attr="$1" + buildingAttribute= + shift 1 + ;; --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file) lockFlags+=("$i") ;; @@ -101,17 +122,30 @@ while [[ "$checkPath" != "/" ]]; do checkPath="$(dirname "$checkPath")" done -# Get the path of the NixOS configuration file. -if [[ -z $NIXOS_CONFIG ]]; then - NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix -fi - -if [[ ${NIXOS_CONFIG:0:1} != / ]]; then - echo "$0: \$NIXOS_CONFIG is not an absolute path" +# Verify that user is not trying to use attribute building and flake +# at the same time +if [[ -z $buildingAttribute && -n $flake ]]; then + echo "$0: '--flake' cannot be used with '--file' or '--attr'" exit 1 fi -if [[ -n $flake ]]; then +# Get the path of the NixOS configuration file. +if [[ -z $flake && -n $buildingAttribute ]]; then + if [[ -z $NIXOS_CONFIG ]]; then + NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix + fi + + if [[ ${NIXOS_CONFIG:0:1} != / ]]; then + echo "$0: \$NIXOS_CONFIG is not an absolute path" + exit 1 + fi +elif [[ -z $buildingAttribute ]]; then + if [[ -z $buildFile ]]; then + buildFile="$mountPoint/etc/nixos/default.nix" + elif [[ -d $buildFile ]]; then + buildFile="$buildFile/default.nix" + fi +elif [[ -n $flake ]]; then if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then flake="${BASH_REMATCH[1]}" flakeAttr="${BASH_REMATCH[2]}" @@ -129,11 +163,16 @@ if [[ -n $flake ]]; then flake=$(nix "${flakeFlags[@]}" flake metadata --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url) fi -if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake ]]; then +if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake && -n $buildingAttribute ]]; then echo "configuration file $NIXOS_CONFIG doesn't exist" exit 1 fi +if [[ ! -z $buildingAttribute && -e $buildFile && -z $system ]]; then + echo "configuration file $buildFile doesn't exist" + exit 1 +fi + # A place to drop temporary stuff. tmpdir="$(mktemp -d -p "$mountPoint")" trap 'rm -rf $tmpdir' EXIT @@ -163,11 +202,20 @@ fi # Build the system configuration in the target filesystem. if [[ -z $system ]]; then outLink="$tmpdir/system" - if [[ -z $flake ]]; then + if [[ -z $flake && -n $buildingAttribute ]]; then echo "building the configuration in $NIXOS_CONFIG..." nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \ --extra-substituters "$sub" \ '' -A system -I "nixos-config=$NIXOS_CONFIG" "${verbosity[@]}" + elif [[ -z $buildingAttribute ]]; then + if [[ -n $attr ]]; then + echo "building the configuration in $buildFile and attribute $attr..." + else + echo "building the configuration in $buildFile..." + fi + nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \ + --extra-substituters "$sub" \ + "$buildFile" -A "${attr:+$attr.}config.system.build.toplevel" "${verbosity[@]}" else echo "building the flake in $flake..." nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" \