#!/usr/bin/env gosh (use gauche.parseopt) (use gauche.process) (use util.match) (define action #f) (define attribute (string-append "nixosConfigurations." (sys-gethostname))) (define keep #f) (define specialisation #f) (define verbose #f) (define extra-nix-args '()) (define config-path ".") (define (usage progname) (display #"~|progname|: Activate a nixos configuration. Usage: ~|progname| [OPTIONS] [PATH] ACTION where ACTION is one of the actions which can be passed to switch-to-configuration (i.e. dry-activate, switch, test, or boot). Options: -A --attr Attribute which evaluates to a (built) configuration. Defaults to nixosConfigurations. -k --keep Add a garbage collection root for the built configuration. -s --specialisation Specialisation to apply. -v --verbose Display commands before they are run. -h --help Print this help message. ")) (define (run-command cmd) (when verbose (display cmd (standard-error-port))) (do-process! cmd)) (define (log-msg msg) (display msg (standard-error-port))) (define (log-verbose msg) (when verbose (log-msg msg))) (define (main args) (let-args (cdr args) ((o-verbose "v|verbose") ; these are taken from nix-build (o-attribute "A|attr=s") (o-keep "k|keep") (o-specialisation "s|specialisation=s") (help "h|help" => (cut (begin (usage (car args)) (exit 0)))) (else (opt . _) (print "unknown option: " opt "\n") (usage (car args)) (exit 1)) . restargs) (when o-attribute (set! attribute o-attribute)) (set! keep o-keep) (set! specialisation o-specialisation) (set! verbose o-verbose) (match restargs [((or "dry-activate" "switch" "test" "boot")) (set! action (string->symbol (car restargs)))] [(path (or "dry-activate" "switch" "test" "boot")) (set! action (string->symbol (cadr restargs))) (set! config-path path)] [_ (begin (usage (car args)) (exit 1))]) (when (and specialisation (not (or (equal? action "test") (equal? action "switch")))) (log-msg "Error: --specialisation can only be used with `test' or `switch'") (exit 1)) (log-verbose (format "action: ~a" action)) (let ([built-config (build-config)]) (log-verbose (format "built config is ~a" built-config)) (install-in-env built-config) (switch-to-configuration built-config)))) (define (build-config) (define (optional b args) (if b args '())) (define nix-cmd (append ; use nix-build since it actually prints the outpath `(nix-build ,config-path --no-out-link --log-format bar-with-logs) (optional attribute (list '-A (string-append attribute ".config.system.build.toplevel"))) extra-nix-args)) (log-verbose nix-cmd) (process-output->string nix-cmd :on-abnormal-exit :error)) (define (install-in-env built-config) (define cmd '(nix-env -p /nix/var/nix/profiles/system --set ,built-config)) (if (or (equal? action 'switch) (equal? action 'boot)) (begin (log-verbose cmd) do-process! cmd) (log-verbose "skipping nix-env profile installation"))) (define (switch-to-configuration built-config) (define cmd `(systemd-run -E LOCALE_ARCHIVE -E NIXOS_INSTALL_BOOTLOADER --collect ;; --no-ask-password --pty --quiet --same-dir --service-type=exec --unit=nixos-rebuild-switch-to-configuration --wait ,(string-append built-config "/bin/switch-to-configuration") ,action)) (log-verbose cmd) (unless (do-process cmd) (log "warning: error(s) occurred while switching to the new configuration")))