From 9996cca17aeb63ed0d51d59d4572dced0b050aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sun, 4 Dec 2022 21:39:25 +0100 Subject: install.sh: add ability to install non-native architecture The result is that it now requires to be run only on NixOS but that should be fine. --- common.sh | 16 +++++----- install.sh | 79 +++++++++++++++++++++++++++++++++-------------- nixos/modules/compile.nix | 20 +++++++++++- 3 files changed, 83 insertions(+), 32 deletions(-) diff --git a/common.sh b/common.sh index 9b6f48c..d3ddbc3 100644 --- a/common.sh +++ b/common.sh @@ -80,6 +80,10 @@ device_system() { nix eval --raw ".#nixosConfigurations.$1.config.nixpkgs.system" } +build_system() { + nix eval --raw --impure --expr 'builtins.currentSystem' +} + # Validates if link is valid. build_validate() { local device="$1" @@ -93,12 +97,10 @@ build() { local device="$1" shift - local toplevel=".config.system.build.toplevel" - if [ "$(device_system "$device")" = "armv7l-linux" ]; then - toplevel=".config.system.build.cross.x86_64-linux${toplevel}" - fi - if [ "$(device_system "$device")" = "aarch64-linux" ]; then - toplevel=".config.system.build.cross.x86_64-linux${toplevel}" + local toplevel="config.system.build.toplevel" + local bsystem="$(build_system)" + if [ "$bsystem" != "$(device_system "$device")" ]; then + toplevel="config.system.build.cross.$bsystem.$toplevel" fi stage "Building system for device: $device" @@ -106,7 +108,7 @@ build() { -o "$(result "${device}")" \ --keep-going \ "$@" \ - "${0%/*}#nixosConfigurations.${device}${toplevel}" + "${0%/*}#nixosConfigurations.${device}.${toplevel}" } ## Copy NixOS system ########################################################### diff --git a/install.sh b/install.sh index a0ec3b7..823a9f5 100755 --- a/install.sh +++ b/install.sh @@ -1,37 +1,68 @@ #!/bin/sh set -eu -hostname="${1:-$(hostname)}" -root="${2:-}" - -_sudo() { - if [ "$(id -u)" -ne 0 ]; then - "$@" - else - sudo -p 'Sudo password: ' -- "$@" - fi -} - -if [ "$hostname" = "nixos" ]; then - echo "The hostname is the default one, that is not right for sure." >&2 - echo "Please specify the correct hostname as the first argument!" >&2 +hostname="$1" +root="${2:-$(pwd)}" +src="$(readlink -f "${0%/*}")" + +if [ "$(id -u)" -ne 0 ]; then + echo "Run this as root!" >&2 exit 1 fi +if ! command -v git >/dev/null; then + exec nix shell 'nixpkgs#git' -c "$0" "$@" +fi + if [ ! -s "$root/.personal-secrets.key" ]; then echo "Please paste the personal secret key (terminate using ^D)" >&2 sudo tee "$root/.personal-secrets.key" >/dev/null fi -eval "$(ssh-agent)" -echo "Please paste the SSH access key now (terminate using ^D):" >&2 -ssh-add - -trap 'kill "$SSH_AGENT_PID"' EXIT +if [ -f "$src/flake.nix" ]; then + flake="$src" +else + flake="git+https://git.cynerd.cz/nixos-personal" + eval "$(ssh-agent)" + echo "Please paste the SSH access key now (terminate using ^D):" >&2 + ssh-add - + trap 'kill "$SSH_AGENT_PID"' EXIT +fi + +buildSystem="$(nix eval --raw --impure --expr 'builtins.currentSystem')" +targetSystem="$(nix eval --raw "$flake#nixosConfigurations.$hostname.pkgs.system")" -flake="git+https://git.cynerd.cz/nixos-personal#$hostname" -if [ -z "$root" ]; then - nix shell nixpkgs\#git --command \ - "_sudo \"\$(command -v nixos-rebuild)\" switch --flake '$flake' --fast" +toplevel="config.system.build.toplevel" +if [ "$buildSystem" != "$targetSystem" ]; then + toplevel="config.system.build.cross.$buildSystem.$toplevel" +fi + +if [ -f "$src/flake.nix" ]; then + # Build in system when running from sources + result="$(nix build --no-link --print-out-paths \ + "$flake#nixosConfigurations.$hostname.$toplevel")" + nix copy --to "$root" "$result" else - nix shell nixpkgs\#git nixpkgs\#nixos-install-tools --command \ - "_sudo \"\$(command -v nixos-install)\" --flake '$flake' --root '$root'" + result="$(nix build --no-link --print-out-paths \ + "$flake#nixosConfigurations.$hostname.$toplevel" \ + --store "$root" --extra-substituters 'auto?trusted=1')" +fi + +nix-env --store "$root" --extra-substituters 'auto?trusted=1' \ + -p "$root/nix/var/nix/profiles/system" --set "$result" + +# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out. +mkdir -m 0755 -p "$root/etc" +touch "$root/etc/NIXOS" + +# Copy over binfmt runners if required +if [ "$buildSystem" != "$targetSystem" ]; then + mkdir -p "$root/run/binfmt" + for binfmt in /run/binfmt/*; do + nix copy --to "$root" "$(readlink -f "$binfmt")" + ln -sf "$(readlink -f "$binfmt")" "$root/$binfmt" + done fi + +ln -sfn /proc/mounts "$root/etc/mtab" # Grub needs an mtab. +NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root "$root" -- \ + /nix/var/nix/profiles/system/bin/switch-to-configuration boot diff --git a/nixos/modules/compile.nix b/nixos/modules/compile.nix index 6c42951..ffa339f 100644 --- a/nixos/modules/compile.nix +++ b/nixos/modules/compile.nix @@ -17,7 +17,25 @@ with lib; max-jobs = 32; cores = 0; }; - boot.binfmt.emulatedSystems = [ "armv7l-linux" "aarch64-linux" ]; + boot.binfmt.registrations = { + aarch64-linux = { + fixBinary = true; + wrapInterpreterInShell = false; + interpreter = (lib.systems.elaborate { system = "aarch64-linux"; }).emulator pkgs; + magicOrExtension = "\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7\\x00"; + mask = "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xfe\\xff\\xff\\xff"; + }; + armv7l-linux = { + fixBinary = true; + wrapInterpreterInShell = false; + interpreter = (lib.systems.elaborate { system = "armv7l-linux"; }).emulator pkgs; + magicOrExtension = "\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00"; + mask = "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xfe\\xff\\xff\\xff"; + }; + }; + nix.settings.extra-platforms = [ + "aarch64-linux" "armv7l-linux" + ]; environment.systemPackages = with pkgs; [ # Tools -- cgit v1.2.3