Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vm-check: init #150

Draft
wants to merge 8 commits into
base: central
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ result
system.raw
*.log
tmp

# QEMU Files
*.fd
Binary file added ignucius-efi-vars.fd
Binary file not shown.
56 changes: 28 additions & 28 deletions src/nixos/machines/ignucius/config/disks.nix
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ in mkMerge [
system = {
device = diskoDevice;
type = "disk";
imageSize = "50G"; # Size of the generated image
imageSize = "30G"; # Size of the generated image
content = {
type = "gpt";
partitions = {
Expand Down Expand Up @@ -76,7 +76,7 @@ in mkMerge [
type = "luks";
settings.allowDiscards = true;

passwordFile = config.age.secrets.ignucius-disks-password.path;
# passwordFile = config.age.secrets.ignucius-disks-password.path;

initrdUnlock = true; # Add a boot.initrd.luks.devices entry for the specified disk

Expand Down Expand Up @@ -115,39 +115,39 @@ in mkMerge [
};
};

swap = {
priority = 2;
size = "30G";
content = {
name = "swap";
type = "luks";
# swap = {
# priority = 2;
# size = "30G";
# content = {
# name = "swap";
# type = "luks";

settings.allowDiscards = true;
# settings.allowDiscards = true;

passwordFile = config.age.secrets.ignucius-disks-password.path;
# # passwordFile = config.age.secrets.ignucius-disks-password.path;

initrdUnlock = true; # Add a boot.initrd.luks.devices entry for the specified disk
# initrdUnlock = true; # Add a boot.initrd.luks.devices entry for the specified disk

extraFormatArgs = [
"--use-random" # use true random data from /dev/random, will block until enough entropy is available
"--label=CRYPT_SWAP"
];
# extraFormatArgs = [
# "--use-random" # use true random data from /dev/random, will block until enough entropy is available
# "--label=CRYPT_SWAP"
# ];

extraOpenArgs = [
"--timeout 10"
];
# extraOpenArgs = [
# "--timeout 10"
# ];

content = {
# FIXME-QA(Krey): Add label 'SWAP'
type = "swap";
resumeDevice = true; # resume from hiberation from this device
# content = {
# # FIXME-QA(Krey): Add label 'SWAP'
# type = "swap";
# resumeDevice = true; # resume from hiberation from this device

extraArgs = [
"--label SWAP"
];
};
};
};
# extraArgs = [
# "--label SWAP"
# ];
# };
# };
# };
};
};
};
Expand Down
127 changes: 113 additions & 14 deletions src/nixos/machines/ignucius/config/vm-build.nix
Original file line number Diff line number Diff line change
@@ -1,24 +1,123 @@
{ ... }:
{ config, lib, pkgs, ... }:

# VM configuration of IGNUCIUS, used for testing prior to deployment

{
# FIXME(Krey): Neither of those are working right now, see https://github.com/nix-community/disko/issues/668
# Relevant: https://github.com/nix-community/disko/issues/668

# Thank you Maroka-chan for the Cryptkey reference! <3 : https://github.com/Maroka-chan/NixOS-config/blob/c97494c2d725bfb79c0776907a6d89e4724ee21f/modules/base/default.nix#L87

let
inherit (lib) mkForce;
in {
# The end Goal Of this configuration is to provide ideally 1:1 emulation of the system to be used as a part of Quality Assurance and to test various deployments
virtualisation = {
# build-vm
vmVariant = {
# nix run -L .#nixosConfigurations.nixos-ignucius-stable.config.system.build.vmWithDisko
# FIXME(Krey): ignucius-disko-images> hwclock: Cannot access the Hardware Clock via any known method.
vmVariantWithDisko = {
virtualisation = {
memorySize = 1024 * 2;
cores = 2;
};
};
# FIXME-QA(Krey): It's weird that this is needed when it's already set in disks.nix
fileSystems."/nix/persist/system".neededForBoot = true;

# build-vm-with-bootloader
vmVariantWithBootLoader = {
virtualisation = {
memorySize = 1024 * 2;
cores = 2;
restrictNetwork = false; # Whether to Enable Network Connection

# More efficient space management as it won't be re-creating store paths in VM
mountHostNixStore = true;

# This is enabled by default and it will set up small (~500MB) /nix/.rw-store mount that will cause most of the services to fail loading due to lack of space
writableStoreUseTmpfs = false;

# Set Virtual Resolution
resolution = {
x = 1280;
y = 720;
};

# Set up the bootloader
# FIXME-BUG(Krey): Can't be made to work rn as we can't modify `disko.*` to adjust the filesystems for it
# error: EFI variables can be used only with a partition table of type: hybrid, efi, efixbootldr, or legacy+gpt.
# useBootLoader = true;
# # Resolve configuration config
# fileSystems."/boot".device = mkForce "/dev/disk/by-partlabel/disk-system-boot";
# useEFIBoot = true;

# Secret Management
# FIXME(Krey): Replace the secrets with dummies so that this can be used by others as well
# Mount local .ssh directory, so the secrets can be decrypted.
sharedDirectories."secrets_decryption_key" = {
source = "/nix/persist/users/kreyren/.ssh";
target = dirOf (builtins.head config.age.identityPaths);
};
};

# Disable GUI
services.xserver.enable = mkForce false;
services.xserver.displayManager.gdm.enable = mkForce false;
services.xserver.desktopManager.gnome.enable = mkForce false;

# Do not perform distributed builds as it's not subject of this VM check
nix.distributedBuilds = mkForce false;

# Disable S.M.A.R.T. as QEMU VM doesn't provide the relevant endpoints
# FIXME(Krey): Figure out how to emulate the end-point
services.smartd.enable = mkForce false; # Disable S.M.A.R.T. Daemon

# Disable ThinkFan as it errors out as we don't have the /proc/acpi/ibm/thermal in QEMU
# FIXME(Krey): Figure out how to emulate the end-point
services.thinkfan.enable = mkForce false; # Disable thinkfan service

# Use a Dummy Cryptkey so that we don't have to input disk password
# FIXME(Krey): Any changes to `disko.*` appears to cause `no type option set in` error
# disko.devices.disk.cryptkey = {
# type = "disk";
# content.type = "gpt";

# content.partitions.cryptkey = {
# size = "4096";
# label = "CRYPTKEY";

# content = {
# type = "filesystem";
# format = "vfat";
# };
# };
# };

# disko.devices.disk.system.content.preCreateHook = ''
# mkdir -p /dev/disk/by-partlabel/
# dd bs=1024 count=4 if=/dev/zero of=/dev/disk/by-partlabel/CRYPTKEY iflag=fullblock
# chmod 0400 /dev/disk/by-partlabel/CRYPTKEY
# '';

# # Configure the system to use the CRYPTKEY
# disko.devices.disk.system.content.partitions.store.content.settings = {
# keyFileSize = 4096;
# keyFile = "/dev/disk/by-partlabel/CRYPTKEY";

# # passwordFile = mkForce ""; # Unset Disk Password for the store
# fallbackToPassword = false;
# };

# FIXME(Krey): For some reason this results in no option type even when the same configuration works outside of vmVariantWithDisko?
# error: No type option set in
# disko.devices.disk.system.content.partitions.store.content.passwordFile = mkForce (pkgs.writeText "ignucius-disks-password" "000000").outPath;

# disko.devices.disk.system.content.partitions.swap.content.passsssswordFile = mkForce (pkgs.writeText "ignucius-disks-password" "000000").outPath;

# Also doesn't work:
# disko.devices.disk.system.content.preCreateHook = ''
# mkdir -p /run/agenix/
# echo 000000 > /run/agenix/ignucius-disks-password
# '';

# Doesn't seem to deploy the files
# system.activationScripts.set-dummy-secrets = ''
# mkdir -p /run/agenix
# echo 000000 > /run/agenix/ignucius-disks-password
# ''; # Set Permission Of the Persistent Users Directory

# Disable Swap as it's not needed during VM and only takes space
# FIXME(Krey): Fails with **No Type option set in**, apparently we can't change disko.* in here?
# disko.devices.disk.system.content.partitions.swap.size = mkForce null; # Unset swap partition
};
};
}
24 changes: 11 additions & 13 deletions src/nixos/modules/system/impermenance/impermenance.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ config, lib, ...}:
{ config, lib, pkgs, ...}:

# Global Management of Impermanence

Expand Down Expand Up @@ -36,18 +36,16 @@ in mkIf config.boot.impermanence.enable {
boot.initrd.systemd.suppressedUnits = [ "systemd-machine-id-commit.service" ];
systemd.suppressedSystemUnits = [ "systemd-machine-id-commit.service" ];


# The configuration will deploy the user directories owned by root:root which will cause the user's home manager to fail deployment due to permission denied error, so we need to change the ownership before home-manager setup
# Plan A
# system.activationScripts.change-ownership-persist-users = ''chown root:users /nix/persist/users''; # Set Permission Of the Persistent Users Directory

# Plan B
# systemd.tmpfiles.rules = [
# "d /persist/home/${username} 0700 ${username} users"
# # We need to explicitly set ownership on the home directory when using impermanence.
# # Otherwise, it will be owned as root, and home-manager will fail.
# "d /home/${username} 0700 ${username} users"
# ];
# Set permission for the users directory
systemd.services.setUserPersistPermissions = {
description = "Set ownership and permissions for /nix/persist/users";
wantedBy = [ "multi-user.target" ];
after = [ "local-fs.target" ]; # Ensure this runs after the filesystem is mounted
script = builtins.concatStringsSep "\n" [
"${pkgs.coreutils}/bin/chown root:users /nix/persist/users"
"${pkgs.coreutils}/bin/chmod 770 /nix/persist/users"
];
};

age.identityPaths = [ "/nix/persist/system/etc/ssh/ssh_host_ed25519_key" ]; # Add impermenant path for keys

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,5 @@ in {
allowOther = true; # FIXME-DOCS(Krey): What is this used for?
};

home.stateVersion = nixosConfig.system.nixos.release; # Impermanence does not have state
home.stateVersion = nixosConfig.system.nixos.release; # Impermanence enables declarative state management so we don't need to set any
}
11 changes: 6 additions & 5 deletions src/nixos/users/users/kreyren/kreyren.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ in {
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOzh6FRxWUemwVeIDsr681fgJ2Q2qCnwJbvFe4xD15ve kreyren@fsfe.org" ];
};

# system.activationScripts.make-homedir-kreyren = builtins.concatStringsSep "\n" [
# "mkdir /nix/persist/users/kreyren"
# "chown kreyren:users /nix/persist/users/kreyren" # Set Permission Of the Persistent Users Directory
# ];

users.users.root.openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOzh6FRxWUemwVeIDsr681fgJ2Q2qCnwJbvFe4xD15ve kreyren@fsfe.org" ]; # Allow root access for all systems for kreyren

nix.settings.trusted-users = [ "kreyren" ]; # Add Kreyren in Trusted-Users

# Set Password for Virtual Machine Checks
virtualisation.vmVariantWithDisko.users.users.kreyren = {
hashedPasswordFile = mkForce null;
password = "a"; # Fastest to brute force password
};
}
35 changes: 29 additions & 6 deletions tasks/administration/build/tasks-build.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
# shellcheck shell=sh # POSIX
set +u # Do not fail on nounset as we use command-line arguments for logic
#@ This POSIX Shell Script is executed in an isolated reproducible environment managed by Nix <https://github.com/NixOS/nix>, which handles dependencies, ensures deterministic function imports, sets any needed variables and performs strict linting prior to script execution to capture common issues for quality assurance.

hostname="$(hostname --short)" # Capture the hostname of the current system
### [START] Export this outside [START] ###

# FIXME-QA(Krey): This should be a runtimeInput
die() { printf "FATAL: %s\n" "$2"; exit ;} # Termination Helper

# FIXME-QA(Krey): This should be a runtimeInput
status() { printf "STATUS: %s\n" "$1" ;} # Status Helper

# FIXME-QA(Krey): This should be a runtimeInput
warn() { printf "WARNING: %s\n" "$1" ;} # Warning Helper

# Termination Helper
command -v success 1>/dev/null || success() {
case "$1" in
"") : ;;
*) printf "SUCCESS: %s\n" "$1"
esac

# FIXME(Krey): Implement better management for this so that ideally `die` is always present by default
command -v die 1>/dev/null || die() { printf "FATAL: %s\n" "$2"; exit 1 ;} # Termination Helper
exit 0
}

# FIXME(Krey): This should be managed for all used scripts e.g. runtimeEnv
# Refer to https://github.com/srid/flake-root/discussions/5 for details tldr flake-root doesn't currently allow parsing the specific commit
#[ -n "$FLAKE_ROOT" ] || FLAKE_ROOT="github:NiXium-org/NiXium/$(curl -s -X GET "https://api.github.com/repos/NiXium-org/NiXium/commits" | jq -r '.[0].sha')"
[ -n "$FLAKE_ROOT" ] || FLAKE_ROOT="github:NiXium-org/NiXium/$(curl -s -X GET "https://api.github.com/repos/NiXium-org/NiXium/commits?sha=central" | jq -r '.[0].sha')"

# shellcheck disable=SC2034 # It's not expected to be always used
hostname="$(hostname --short)" # Capture the hostname of the current system

command -v success 1>/dev/null || success() { printf "SUCCESS: %s\n" "$1"; exit 0 ;} # Termination Helper
### [END] Export this outside [END] ###

# Check current system if no argument is provided
[ "$#" != 0 ] || {
Expand Down
33 changes: 29 additions & 4 deletions tasks/administration/deploy/tasks-deploy.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
# shellcheck shell=sh # POSIX
set +u # Do not fail on nounset as we use command-line arguments for logic
#@ This POSIX Shell Script is executed in an isolated reproducible environment managed by Nix <https://github.com/NixOS/nix>, which handles dependencies, ensures deterministic function imports, sets any needed variables and performs strict linting prior to script execution to capture common issues for quality assurance.

### [START] Export this outside [START] ###

# FIXME-QA(Krey): This should be a runtimeInput
die() { printf "FATAL: %s\n" "$2"; exit ;} # Termination Helper

# FIXME-QA(Krey): This should be a runtimeInput
status() { printf "STATUS: %s\n" "$1" ;} # Status Helper

# FIXME-QA(Krey): This should be a runtimeInput
warn() { printf "WARNING: %s\n" "$1" ;} # Warning Helper

# Termination Helper
command -v success 1>/dev/null || success() {
case "$1" in
"") : ;;
*) printf "SUCCESS: %s\n" "$1"
esac

exit 0
}

# FIXME(Krey): This should be managed for all used scripts e.g. runtimeEnv
# Refer to https://github.com/srid/flake-root/discussions/5 for details tldr flake-root doesn't currently allow parsing the specific commit
#[ -n "$FLAKE_ROOT" ] || FLAKE_ROOT="github:NiXium-org/NiXium/$(curl -s -X GET "https://api.github.com/repos/NiXium-org/NiXium/commits" | jq -r '.[0].sha')"
[ -n "$FLAKE_ROOT" ] || FLAKE_ROOT="github:NiXium-org/NiXium/$(curl -s -X GET "https://api.github.com/repos/NiXium-org/NiXium/commits?sha=central" | jq -r '.[0].sha')"

# shellcheck disable=SC2034 # It's not expected to be always used
hostname="$(hostname --short)" # Capture the hostname of the current system

# FIXME(Krey): Implement better management for this so that ideally `die` is always present by default
command -v die 1>/dev/null || die() { printf "FATAL: %s\n" "$2"; exit 1 ;} # Termination Helper
### [END] Export this outside [END] ###

# Check current system if no argument is provided
[ "$#" != 0 ] || {
Expand Down
Loading