From 542ccb14fa41b6bf15d91723ff20fd2fdc70062d Mon Sep 17 00:00:00 2001 From: Valentin Kharin Date: Mon, 11 Sep 2023 17:30:53 +0300 Subject: [PATCH] Make module for installer Signed-off-by: Valentin Kharin --- lib/default.nix | 12 ++-- modules/installer/builtin/flush.nix | 11 +++ modules/installer/default.nix | 100 ++++++++++++++++++++++++++++ modules/installer/installer.nix | 6 +- modules/installer/installer.sh | 16 ++--- modules/module-list.nix | 1 + targets/default.nix | 1 - targets/generic-x86_64.nix | 21 ++++++ targets/installer.nix | 36 ---------- 9 files changed, 145 insertions(+), 59 deletions(-) create mode 100644 modules/installer/builtin/flush.nix create mode 100644 modules/installer/default.nix delete mode 100644 targets/installer.nix diff --git a/lib/default.nix b/lib/default.nix index 07a134d944..d001450360 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -12,19 +12,18 @@ in { # NOTE: Currently supports configuration that generates raw-efi image using nixos-generators installer = { - name, systemImgCfg, modules ? [], + userCode ? "", }: let - system = systemImgCfg.config.nixpkgs.hostPlatform.system; + system = systemImgCfg.nixpkgs.hostPlatform.system; pkgs = import nixpkgs {inherit system;}; - systemImgDrv = systemImgCfg.config.system.build.${systemImgCfg.config.formatAttr}; installerScript = import ../modules/installer/installer.nix { inherit pkgs; - systemImgDrv = "${systemImgDrv}/nixos.img"; inherit (pkgs) runtimeShell; + inherit userCode; }; installerImgCfg = lib.nixosSystem { @@ -46,9 +45,9 @@ in { }) { - # TODO + environment.systemPackages = [installerScript]; environment.loginShellInit = '' - ${installerScript}/bin/ghaf-installer + installer.sh ''; } ] @@ -56,7 +55,6 @@ in { ++ modules; }; in { - name = "${name}-installer"; inherit installerImgCfg system; installerImgDrv = installerImgCfg.config.system.build.${installerImgCfg.config.formatAttr}; }; diff --git a/modules/installer/builtin/flush.nix b/modules/installer/builtin/flush.nix new file mode 100644 index 0000000000..21f12514fc --- /dev/null +++ b/modules/installer/builtin/flush.nix @@ -0,0 +1,11 @@ +{...}: { + ghaf.installer.installerModules.flushImage = { + requestCode = '' + lsblk + read -p "Device name [e.g. sda]: " DEVICE_NAME + ''; + providedVariables = { + deviceName = "$DEVICE_NAME"; + }; + }; +} diff --git a/modules/installer/default.nix b/modules/installer/default.nix new file mode 100644 index 0000000000..4589ae0fa4 --- /dev/null +++ b/modules/installer/default.nix @@ -0,0 +1,100 @@ +# Copyright 2022-2023 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +inputs @ { + config, + lib, + pkgs, + ... +}: let + cfg = config.ghaf.installer; +in { + options.ghaf.installer = { + enable = lib.mkEnableOption "installer image"; + + imgModules = lib.mkOption { + description = lib.mdDoc '' + Modules that will be passed to the installer image. + ''; + type = with lib.types; listOf deferredModule; + default = []; + }; + + # NOTE: These options tries to resemble calamares module system so we'll be + # able to generate calamares installer from same (almost) code base. + # TODO: Add library of bash functions with unified way of asking user + # required information. + installerModules = lib.mkOption { + description = lib.mdDoc '' + Modules describe the information requested from the user + for the installer. + + All code must be written for the current pkgs.runtimeShell. + ''; + type = with lib.types; + attrsOf (submodule { + options = { + requestCode = lib.mkOption { + description = lib.mdDoc '' + Code that will ask user their preferences. + ''; + type = lines; + default = "echo \"Here's should be your installer\""; + }; + providedVariables = lib.mkOption { + description = lib.mdDoc '' + Variable that this modules provides. + Used to detect errors with non-existent variables. + ''; + type = attrsOf str; + default = {}; + }; + }; + }); + }; + + enabledModules = lib.mkOption { + description = lib.mdDoc '' + Sequence of enabled modules. + ''; + type = with lib.types; listOf str; + default = []; + }; + + installerCode = lib.mkOption { + description = lib.mdDoc '' + Code that will install image based on the information + collected from the installer modules. + + All code must be written for the current pkgs.runtimeShell. + ''; + type = lib.types.lines; + default = ""; + }; + }; + + config = lib.mkIf cfg.enable (let + builtinModulesPaths = map (name: "${./builtin}/${name}.nix") ["flush"]; + modulePath2Module = path: import path inputs; + builtinInstallerModules = map modulePath2Module builtinModulesPaths; + in + builtins.foldl' lib.recursiveUpdate { + system.build.installer = let + name2code = name: cfg.installerModules.${name}.requestCode; + enabledModulesCode = map name2code cfg.enabledModules; + enabledModulesCode' = builtins.concatStringsSep "\n" enabledModulesCode; + in + (lib.ghaf.installer { + systemImgCfg = config; + modules = cfg.imgModules; + userCode = '' + # Modules code + ${enabledModulesCode'} + + # Installer code + ${cfg.installerCode} + ''; + }) + .installerImgDrv; + } + builtinInstallerModules); +} diff --git a/modules/installer/installer.nix b/modules/installer/installer.nix index ba22086299..761be92f71 100644 --- a/modules/installer/installer.nix +++ b/modules/installer/installer.nix @@ -3,13 +3,13 @@ { pkgs, runtimeShell, - systemImgDrv, + userCode ? "", }: pkgs.substituteAll { dir = "bin"; isExecutable = true; - name = "ghaf-installer"; + pname = "ghaf-installer"; src = ./installer.sh; - inherit runtimeShell systemImgDrv; + inherit runtimeShell userCode; } diff --git a/modules/installer/installer.sh b/modules/installer/installer.sh index 6cc02f0830..73188ff5c3 100644 --- a/modules/installer/installer.sh +++ b/modules/installer/installer.sh @@ -20,19 +20,11 @@ cat <<"EOF" EOF echo "Welcome to Ghaf installer!" -echo "To install image choose path to the device on which image will be installed." -lsblk -read -p "Device name [e.g. sda]: " DEVICE_NAME -echo "Starting flushing..." +echo "To install image choose path to the device on which image will be installed." -if sudo dd if=@systemImgDrv@ of=/dev/$DEVICE_NAME conv=sync bs=4K status=progress; then - sync - echo "Flushing finished successfully!" - echo "Now you can detach installation device and reboot to ghaf." -else - echo "Some error occured during flushing process, exit code: $?." -fi +@userCode@ +echo "Rebooting..." sleep 1 -shutdown -r +sudo reboot -f diff --git a/modules/module-list.nix b/modules/module-list.nix index 6243531e48..ed4a2a6f2b 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -8,6 +8,7 @@ ./development/ssh.nix ./graphics ./hardware/x86_64-linux.nix + ./installer ./profiles/applications.nix ./profiles/debug.nix ./profiles/graphics.nix diff --git a/targets/default.nix b/targets/default.nix index 061ed79331..db0f7bd0b5 100644 --- a/targets/default.nix +++ b/targets/default.nix @@ -17,5 +17,4 @@ lib.foldr lib.recursiveUpdate {} [ (import ./generic-x86_64.nix {inherit self lib nixos-generators nixos-hardware microvm;}) (import ./imx8qm-mek.nix {inherit self lib nixos-generators nixos-hardware microvm;}) (import ./microchip-icicle-kit.nix {inherit self lib nixpkgs nixos-hardware;}) - (import ./installer.nix {inherit self nixpkgs lib nixos-generators;}) ] diff --git a/targets/generic-x86_64.nix b/targets/generic-x86_64.nix index 3036f1692d..1287017698 100644 --- a/targets/generic-x86_64.nix +++ b/targets/generic-x86_64.nix @@ -63,6 +63,27 @@ }; } + ({config, ...}: { + ghaf.installer = { + enable = true; + imgModules = [ + nixos-generators.nixosModules.raw-efi + ]; + enabledModules = ["flushImage"]; + installerCode = '' + echo "Starting flushing..." + if sudo dd if=${config.system.build.${config.formatAttr}}/nixos.img of=/dev/${config.ghaf.installer.installerModules.flushImage.providedVariables.deviceName} conv=sync bs=4K status=progress; then + sync + echo "Flushing finished successfully!" + echo "Now you can detach installation device and reboot to ghaf." + else + echo "Some error occured during flushing process, exit code: $?." + exit + fi + ''; + }; + }) + formatModule #TODO: how to handle the majority of laptops that need a little diff --git a/targets/installer.nix b/targets/installer.nix deleted file mode 100644 index c6d0c9cf4e..0000000000 --- a/targets/installer.nix +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2022-2023 TII (SSRC) and the Ghaf contributors -# SPDX-License-Identifier: Apache-2.0 -# -# Generic x86_64 (for now) computer installer -{ - self, - nixpkgs, - nixos-generators, - lib, -}: let - formatModule = nixos-generators.nixosModules.raw-efi; - inherit (lib.ghaf) installer; - targets = map installer [ - { - name = "generic-x86_64-release"; - systemImgCfg = self.nixosConfigurations.generic-x86_64-release; - modules = [formatModule]; - } - ]; -in { - nixosConfigurations.installer = - (installer { - name = "generic-x86_64-release"; - systemImgCfg = self.nixosConfigurations.generic-x86_64-release; - }) - .installerImgCfg; - packages = lib.foldr lib.recursiveUpdate {} (map ({ - name, - system, - installerImgDrv, - ... - }: { - ${system}.${name} = installerImgDrv; - }) - targets); -}