Skip to content

Commit

Permalink
New installation approach
Browse files Browse the repository at this point in the history
Signed-off-by: Valentin Kharin <[email protected]>
  • Loading branch information
remimimimimi authored and brianmcgillion committed Feb 16, 2024
1 parent 5668ed6 commit 0911ef7
Show file tree
Hide file tree
Showing 24 changed files with 358 additions and 305 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ See the documentation overview under [README-docs.md](./docs/README-docs.md).

Other repositories that are a part of the Ghaf project:

* [sbomnix](https://github.com/tiiuae/sbomnix): a utility that generates SBOM given Nix derivations or out paths
* [sbomnix](https://github.com/tiiuae/sbomnix): a utility that generates SBOMs given Nix derivations or out paths
* [ghaf-infra](https://github.com/tiiuae/ghaf-infra), [ci-public](https://github.com/tiiuae/ci-public), [ci-test-automation](https://github.com/tiiuae/ci-test-automation), [ghafscan](https://github.com/tiiuae/ghafscan): CI/CD related files
* [ghaf-installation-wizard](https://github.com/tiiuae/ghaf-installation-wizard): helps you install Ghaf for the first time


## Build System
Expand Down
2 changes: 1 addition & 1 deletion docs/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
nixosOptionsDoc,
mdbook,
revision ? "",
options ? {},
options,
}: let
optionsDocMd =
(nixosOptionsDoc {
Expand Down
103 changes: 53 additions & 50 deletions docs/src/ref_impl/installer.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,70 @@

# Installer

## Configuring and Building Installer for Ghaf

You can obtain the installation image for your Ghaf configuration. To check possible configuration options, see [Modules Options](../ref_impl/modules_options.md#ghafinstallerenable).

1. Set `ghaf.installer.enable` to `true`.
2. Add nixos-generators module to `ghaf.installer.imgModules` list to configure installer image type.
3. Choose installer modules from `ghaf.installer.installerModules` and set `ghaf.installer.enabledModules` to list of their names.
4. Write code for the installer in `ghaf.installer.installerCode`.

```nix
{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}} 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
'';
};
}
```
Ghaf has a NixOS-like non-interactive, declarative installer instead of a
conventional (imperative, non-declarative) installer as in most conventional
Linux distributions. This is possible with the [Ghaf as
Library](https://github.com/tiiuae/ghaf/pull/ghaf-based-project.md) approach:
rather than clicking similar options during installation, you can configure the
system once and deploy this configuration to the desired machines.


To implement the pre-configured setting up approach, we used the
[nixos-anywhere](https://github.com/nix-community/nixos-anywhere) tool.

There are two separate ways to use it:
* manually
* with the Ghaf installation wizard.
> NOTE: The Ghaf installation wizard is currently under development and cannot be used to create the required system configuration.
After that you can build an installer image using this command:
## Manual Installation

To install Ghaf manually:

1. Create your own flake using the Ghaf template:

```sh
nix build .#nixosConfigurations.<CONFIGURATION>.config.system.build.installer
nix flake init -t github:tiiuae/ghaf#target-x86_64-generic
```

## Adding Installer Modules
2. Edit it according to your preferences.

3. Set the value of `ghaf.installer.sshKeys` to get an installer image. If you don't have ssh keys follow substeps:

3.1. Generate an SSH keypair as follows:
```
$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519): /home/user/.ssh/id_ed25519_installer
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519_installer
Your public key has been saved in /home/user/.ssh/id_ed25519_installer.pub
...
```

To add an installer module, replace the corresponding placeholders with your code and add this to your configuraiton:
3.2. Copy public key from file (`id_ed25519_installer.pub` in an example above) in place of stub in `flake.nix` of your configuration.

```nix
ghaf.installer.installerModules.<MODULE_NAME> = {
requestCode = ''
# Your request code written in Bash
'';
providedVariables = {
# Notice the dollar sign before the actual variable name in Bash.
<VARIABLE_NAME> = "$<VARIABLE_NAME>";
};
};
4. Build the installer image:

```sh
nix build .#nixosConfigurations.PROJ_NAME-ghaf-debug.config.system.build.installer
```

## Built-in Installer Modules
5. Flash the installer image to your device (temporary storage which will be used to establish connection with the host machine):

Provided variables show variable names in Nix. For actual names of variables in Bash, see the sources of the module.
```sh
sudo dd if=./result/iso/nixos-...-linux.iso of=/dev/YOUR_DEVICE conv=sync && sync
```

### flushImage
6. Run the image on the device.

Provided variables:
7. Connect the device to the network using `wifi-connector`.

- deviceName: name of the device on which image should be flushed (e.g. "sda", "nvme0n1")
8. Check the target block device name using the lsblk command and put it in the disk configuration option in `flake.nix`.

8. Install the NixOS configuration to the target device using the command:

```sh
nix run github:nix-community/nixos-anywhere -- --flake .#CONFIGURATION_NAME root@IP_ADDRESS
```
2 changes: 2 additions & 0 deletions lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ in
#
inherit ghaf-version;

ghaf = import ./lib {inherit lib inputs;};

flattenTree =
/*
*
Expand Down
70 changes: 35 additions & 35 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,63 @@
#
# SPDX-License-Identifier: Apache-2.0
{
self,
lib,
nixpkgs,
inputs,
}: let
release = lib.strings.fileContents ../.version;
versionSuffix = ".${lib.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}";
version = release + versionSuffix;
inherit (inputs) nixpkgs;
inherit (inputs) nixos-generators;
in {
inherit release versionSuffix version;
modules = import ./ghaf-modules.nix {inherit lib;};

# NOTE: Currently supports configuration that generates raw-efi image using nixos-generators
installer = {
systemImgCfg,
system,
sshKeys,
modules ? [],
userCode ? "",
}: let
inherit (systemImgCfg.nixpkgs.hostPlatform) system;

pkgs = import nixpkgs {inherit system;};

installerScript = import ../modules/installer/installer.nix {
inherit pkgs;
inherit (pkgs) runtimeShell;
inherit userCode;
};

installerImgCfg = lib.nixosSystem {
inherit system;
specialArgs = {inherit lib;};
modules =
[
../modules/host

({modulesPath, ...}: {
({
pkgs,
lib,
modulesPath,
...
}: {
imports = [(modulesPath + "/profiles/all-hardware.nix")];

environment.systemPackages = [(pkgs.callPackage ../packages/wifi-connector {useNmcli = true;})];

nixpkgs.hostPlatform.system = system;
nixpkgs.config.allowUnfree = true;

hardware.enableAllFirmware = true;

ghaf.profiles.installer.enable = true;
})
networking = {
# wireless is disabled because we use NetworkManager for wireless
wireless.enable = lib.mkForce false;
networkmanager.enable = true;
};

{
environment.systemPackages = [installerScript];
environment.loginShellInit = ''
installer.sh
'';
}
ghaf = {
profiles = {
installer.enable = true;
debug.enable = true;
};
development.ssh.daemon = {
enable = true;
authorizedKeys = sshKeys;
};
};
})
]
++ (import ../modules/module-list.nix)
++ modules;
++ modules
# NOTE: Stick with install-iso as nixos-anywhere requires VARIANT=installer
# https://nix-community.github.io/nixos-anywhere/howtos/no-os.html#installing-on-a-machine-with-no-operating-system
++ [nixos-generators.nixosModules.install-iso];
};
in {
inherit installerImgCfg system;
installerImgDrv = installerImgCfg.config.system.build.${installerImgCfg.config.formatAttr};
};
in
installerImgCfg.config.system.build.${installerImgCfg.config.formatAttr};
}
12 changes: 0 additions & 12 deletions lib/ghaf-modules.nix

This file was deleted.

19 changes: 17 additions & 2 deletions modules/development/ssh.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,26 @@ in
with lib; {
options.ghaf.development.ssh.daemon = {
enable = mkEnableOption "ssh daemon";
authorizedKeys = mkOption {
type = with types; listOf singleLineStr;
default = [];
description = mdDoc ''
Add your SSH Public Keys here.
NOTE: adding your pub ssh key here will make accessing and "nixos-rebuild switching" development mode
builds easy but still secure. Given that you protect your private keys. Do not share your keypairs across hosts.
Shared authorized keys access poses a minor risk for developers in the same network (e.g. office) cross-accessing
each others development devices if:
- the ip addresses from dhcp change between the developers without the noticing AND
- you ignore the server fingerprint checks
You have been helped and you have been warned.
'';
};
};

config = mkIf cfg.enable {
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = authorizedKeys;
users.users.${config.ghaf.users.accounts.user}.openssh.authorizedKeys.keys = authorizedKeys;
users.users.root.openssh.authorizedKeys.keys = cfg.authorizedKeys;
users.users.${config.ghaf.users.accounts.user}.openssh.authorizedKeys.keys = cfg.authorizedKeys;
};
}
70 changes: 68 additions & 2 deletions modules/hardware/x86_64-linux.nix
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,74 @@ in
# Enable normal Linux console on the display
kernelParams = ["console=tty0"];

# To enable installation of ghaf into NVMe drives
initrd.availableKernelModules = ["nvme"];
# The initrd has to contain any module that might be necessary for
# supporting the most important parts of HW like drives.
initrd.availableKernelModules = [
# SATA/PATA support.
"ahci"

"ata_piix"

"sata_inic162x"
"sata_nv"
"sata_promise"
"sata_qstor"
"sata_sil"
"sata_sil24"
"sata_sis"
"sata_svw"
"sata_sx4"
"sata_uli"
"sata_via"
"sata_vsc"

"pata_ali"
"pata_amd"
"pata_artop"
"pata_atiixp"
"pata_efar"
"pata_hpt366"
"pata_hpt37x"
"pata_hpt3x2n"
"pata_hpt3x3"
"pata_it8213"
"pata_it821x"
"pata_jmicron"
"pata_marvell"
"pata_mpiix"
"pata_netcell"
"pata_ns87410"
"pata_oldpiix"
"pata_pcmcia"
"pata_pdc2027x"
"pata_qdi"
"pata_rz1000"
"pata_serverworks"
"pata_sil680"
"pata_sis"
"pata_sl82c105"
"pata_triflex"
"pata_via"
"pata_winbond"

# SCSI support (incomplete).
"3w-9xxx"
"3w-xxxx"
"aic79xx"
"aic7xxx"
"arcmsr"
"hpsa"

# USB support, especially for booting from USB CD-ROM
# drives.
"uas"

# SD cards.
"sdhci_pci"

# NVMe drives
"nvme"
];
loader = {
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
Expand Down
14 changes: 0 additions & 14 deletions modules/installer/builtin/flush.nix

This file was deleted.

Loading

0 comments on commit 0911ef7

Please sign in to comment.