diff --git a/modules/build/activation.nix b/modules/build/activation.nix index 1603602..1979736 100644 --- a/modules/build/activation.nix +++ b/modules/build/activation.nix @@ -8,6 +8,8 @@ with lib; let cfg = config.build; + profileDirectory = "/nix/var/nix/profiles/nix-on-droid"; + # Programs that always should be available on the activation # script's PATH. activationBinPaths = lib.makeBinPath [ @@ -108,13 +110,6 @@ in internal = true; description = "Package containing /etc files."; }; - - profileDirectory = mkOption { - type = types.path; - readOnly = true; - internal = true; - description = "Path to nix-on-droid profile."; - }; }; }; @@ -126,8 +121,13 @@ in build = { activationAfter.linkProfile = '' - generationDir="$(dirname "$(realpath $0)")" - $DRY_RUN_CMD nix-env --profile "${cfg.profileDirectory}" --set "$generationDir" + generationDir="$(dirname $0)" + + if [[ $generationDir =~ ^${profileDirectory}-([0-9]+)-link$ ]]; then + $DRY_RUN_CMD nix-env --profile "${profileDirectory}" --switch-generation "''${BASH_REMATCH[1]}" + else + $DRY_RUN_CMD nix-env --profile "${profileDirectory}" --set "$generationDir" + fi ''; activationPackage = @@ -151,8 +151,6 @@ in ln --symbolic ${config.environment.binSh} $out/filesystem/bin/sh ln --symbolic ${config.environment.usrBinEnv} $out/filesystem/usr/bin/env ''; - - profileDirectory = "/nix/var/nix/profiles/nix-on-droid"; }; }; diff --git a/nix-on-droid/nix-on-droid.sh b/nix-on-droid/nix-on-droid.sh index 9d57051..784ec6a 100644 --- a/nix-on-droid/nix-on-droid.sh +++ b/nix-on-droid/nix-on-droid.sh @@ -5,18 +5,24 @@ PATH=@coreutils@/bin:@nix@/bin:${PATH:+:}$PATH set -eu set -o pipefail +PROFILE_DIRECTORY="/nix/var/nix/profiles/nix-on-droid" + function errorEcho() { >&2 echo $@ } +function doGenerations() { + nix-env --profile $PROFILE_DIRECTORY --list-generations +} + function doHelp() { echo "Usage: $0 [OPTION] COMMAND" echo echo "Options" echo - echo " -v|--verbose Verbose output" - echo " -n|--dry-run Do a dry run, only prints what actions would be taken" echo " -h|--help Print this help" + echo " -n|--dry-run Do a dry run, only prints what actions would be taken" + echo " -v|--verbose Verbose output" echo echo "Options passed on to nix build" echo @@ -29,8 +35,16 @@ function doHelp() { echo echo "Commands" echo + echo " generations Show all generations" + echo echo " help Print this help" + echo + echo " rollback Rollback and activate configuration" + echo echo " switch Build and activate configuration" + echo + echo " switch-generation NUM" + echo " Switch generation and activate configuration" } function doSwitch() { @@ -55,15 +69,29 @@ function doSwitch() { "${generationDir}/activate" } +function doSwitchGeneration() { + local generationNum=$1 + + if [[ -x "${PROFILE_DIRECTORY}-${generationNum}-link/activate" ]]; then + echo "Run activation script..." + "${PROFILE_DIRECTORY}-${generationNum}-link/activate" + else + errorEcho "Activation was not successful, generation is either broken or already garbage collected." + errorEcho "See nix-on-droid generations for available generations." + exit 1 + fi +} + COMMAND= +COMMAND_ARGS=() PASSTHROUGH_OPTS=() while [[ $# -gt 0 ]]; do opt="$1" shift case $opt in - help|switch) + generations|help|rollback|switch|switch-generation) COMMAND="$opt" ;; -h|--help) @@ -87,10 +115,17 @@ while [[ $# -gt 0 ]]; do -v|--verbose) export VERBOSE=1 ;; - *) - errorEcho "$0: unknown option '$opt'" - errorEcho "Run '$0 --help' for usage help" - exit 1 + *) + case $COMMAND in + switch-generation) + COMMAND_ARGS+=("$opt") + ;; + *) + errorEcho "$0: unknown option '$opt'" + errorEcho "Run '$0 --help' for usage help" + exit 1 + ;; + esac ;; esac done @@ -101,12 +136,31 @@ if [[ -z $COMMAND ]]; then fi case $COMMAND in - switch) - doSwitch + generations) + doGenerations ;; help) doHelp ;; + rollback) + if [[ $(readlink $PROFILE_DIRECTORY) =~ ^nix-on-droid-([0-9]+)-link$ ]]; then + doSwitchGeneration $((${BASH_REMATCH[1]} - 1)) + else + errorEcho "nix-on-droid profile link is broken, please run nix-on-droid switch to fix it." + exit 1 + fi + ;; + switch) + doSwitch + ;; + switch-generation) + if [[ ${#COMMAND_ARGS[@]} -eq 1 ]]; then + doSwitchGeneration ${COMMAND_ARGS[0]} + else + errorEcho "switch-generation expects one argument, got ${#COMMAND_ARGS[@]}." + exit 1 + fi + ;; *) errorEcho "Unknown command: $COMMAND" doHelp >&2