Extending Targets
Extending Targets
Section titled “Extending Targets”This guide covers how to customize existing Ghaf hardware targets, from simple configuration changes to creating entirely new variants.
Target Architecture
Section titled “Target Architecture”Targets in Ghaf combine:
- Hardware Definition - Device-specific settings (
modules/hardware/) - Profile - Platform capabilities (
modules/profiles/) - Variant - Debug/release configuration (
lib/ghaf.profiles.*) - Custom Modules - Target-specific additions
Simple Configuration Changes
Section titled “Simple Configuration Changes”Modifying Global Settings
Section titled “Modifying Global Settings”Override global config settings via extraConfig:
# In targets/laptop/flake-module.nixmkGhafConfiguration { name = "my-target"; system = "x86_64-linux"; profile = "laptop-x86"; hardwareModule = inputs.self.nixosModules.hardware-my-target; variant = "debug";
# Override specific global config values extraConfig = { global-config.features.bluetooth.enable = false; global-config.logging.listener.port = 10000; };
extraModules = [ # Additional modules ];};Adding Packages
Section titled “Adding Packages”Add packages to a target:
extraModules = [ ({ pkgs, ... }: { environment.systemPackages = with pkgs; [ vim htop tmux ]; })];Enabling Services
Section titled “Enabling Services”Enable host services:
extraModules = [ { services.tailscale.enable = true; networking.firewall.allowedUDPPorts = [ 41641 ]; }];Customizing VMs
Section titled “Customizing VMs”Extending VM Configuration
Section titled “Extending VM Configuration”Use extendModules to customize VMs:
# In a target or custom profile{ config, lib, ... }:let baseGuivm = config.ghaf.profiles.laptop-x86.guivmBase;
customGuivm = baseGuivm.extendModules { modules = [ ({ pkgs, ... }: { # Add applications environment.systemPackages = [ pkgs.chromium ];
# Configure desktop services.xserver.desktopManager.gnome.enable = true; }) ]; };in{ ghaf.virtualization.microvm.guivm.evaluatedConfig = customGuivm;}Adding Application VMs
Section titled “Adding Application VMs”Add custom application VMs:
{ config, ... }:let mkAppVm = config.ghaf.profiles.laptop-x86.mkAppVm;in{ ghaf.virtualization.microvm.appvm.vms.my-custom-app = mkAppVm { name = "my-custom-app"; applications = [{ name = "My Application"; description = "Custom application for this target"; packages = [ pkgs.my-app ]; icon = "my-app"; command = "my-app"; }]; };}Reassigning Features
Section titled “Reassigning Features”Move hardware features to different VMs:
{ ghaf.global-config.features = { # Move fingerprint to admin VM fprint.targetVms = [ "admin-vm" ];
# Enable YubiKey in multiple VMs yubikey.targetVms = [ "gui-vm" "admin-vm" ];
# Disable Bluetooth entirely bluetooth.enable = false; };}Creating New Variants
Section titled “Creating New Variants”Debug vs Release
Section titled “Debug vs Release”Create both debug and release variants:
# In flake-module.nixlet mkGhafConfiguration = inputs.self.lib.ghaf.builders.mkGhafConfiguration;in{ flake.nixosConfigurations = { # Debug variant "my-target-debug" = mkGhafConfiguration { name = "my-target"; system = "x86_64-linux"; profile = "laptop-x86"; hardwareModule = inputs.self.nixosModules.hardware-my-target; variant = "debug"; };
# Release variant "my-target-release" = mkGhafConfiguration { name = "my-target"; system = "x86_64-linux"; profile = "laptop-x86"; hardwareModule = inputs.self.nixosModules.hardware-my-target; variant = "release"; }; };}Custom Profile Variants
Section titled “Custom Profile Variants”Create custom profile combinations by overriding global config:
{ # Minimal debug - debug tools but reduced features "my-target-minimal-debug" = mkGhafConfiguration { name = "my-target-minimal"; system = "x86_64-linux"; profile = "laptop-x86"; hardwareModule = inputs.self.nixosModules.hardware-my-target; variant = "debug"; extraConfig = { global-config = { givc.enable = false; features.audio.enable = false; features.bluetooth.enable = false; }; }; };}Creating New Hardware Targets
Section titled “Creating New Hardware Targets”Step 1: Hardware Definition
Section titled “Step 1: Hardware Definition”Create modules/hardware/my-device/definition.nix:
# SPDX-FileCopyrightText: 2022-2026 TII (SSRC) and the Ghaf contributors{ config, lib, ... }:{ _file = ./definition.nix;
hardware.definition = { name = "My Device"; skuName = "my-device"; host.kernelConfig.kernelParams = [ "quiet" ];
network.pciDevices = [{ path = "0000:00:14.3"; vendorId = "8086"; productId = "a0f0"; name = "wlp0s20f3"; }];
gpu.pciDevices = [{ path = "0000:00:02.0"; vendorId = "8086"; productId = "9a49"; name = "Intel Graphics"; }];
# VM-specific hardware guivm = { extraModules = []; };
netvm = { extraModules = []; }; };}Step 2: Hardware Module
Section titled “Step 2: Hardware Module”Create modules/hardware/my-device/default.nix:
# SPDX-FileCopyrightText: 2022-2026 TII (SSRC) and the Ghaf contributors{ config, lib, pkgs, ... }:{ _file = ./default.nix;
imports = [ ./definition.nix ];
# Device-specific kernel boot.kernelPackages = pkgs.linuxPackages_latest;
# Firmware hardware.firmware = [ pkgs.linux-firmware ];
# Device-specific settings hardware.enableRedistributableFirmware = true;}Step 3: Target Configuration
Section titled “Step 3: Target Configuration”Create targets/my-device/flake-module.nix:
# SPDX-FileCopyrightText: 2022-2026 TII (SSRC) and the Ghaf contributors{ inputs, lib, ...}:let mkGhafConfiguration = inputs.self.lib.ghaf.builders.mkGhafConfiguration;in{ flake.nixosConfigurations = { my-device-debug = mkGhafConfiguration { name = "my-device"; system = "x86_64-linux"; profile = "laptop-x86"; hardwareModule = inputs.self.nixosModules.hardware-my-device; variant = "debug"; extraModules = [ # Target-specific additions ]; };
my-device-release = mkGhafConfiguration { name = "my-device"; system = "x86_64-linux"; profile = "laptop-x86"; hardwareModule = inputs.self.nixosModules.hardware-my-device; variant = "release"; }; };}Step 4: Export Hardware Module
Section titled “Step 4: Export Hardware Module”Add to modules/hardware/flake-module.nix:
{ flake.nixosModules = { hardware-my-device = ./my-device; };}Target Customization Patterns
Section titled “Target Customization Patterns”Pattern 1: Override VM Resources
Section titled “Pattern 1: Override VM Resources”mkGhafConfiguration { # ... other params ... vmConfig = { guivm = { mem = 8192; vcpu = 8; }; netvm = { mem = 1024; vcpu = 2; }; audiovm = { mem = 512; vcpu = 1; }; };}Pattern 2: Custom Networking
Section titled “Pattern 2: Custom Networking”{ ghaf.common.extraNetworking = { hosts = { gui-vm = { ipv4 = "10.0.0.2"; mac = "02:00:00:00:00:02"; }; net-vm = { ipv4 = "10.0.0.3"; mac = "02:00:00:00:00:03"; }; }; hostAddress = "10.0.0.1"; networkPrefix = "10.0.0.0/24"; };}Pattern 3: Hardware-Specific Modules
Section titled “Pattern 3: Hardware-Specific Modules”extraModules = [ ({ config, pkgs, ... }: { # Touchpad configuration services.libinput.enable = true; services.libinput.touchpad = { tapping = true; naturalScrolling = true; };
# Power management services.tlp.enable = true; services.thermald.enable = true; })];Pattern 4: Conditional Configuration
Section titled “Pattern 4: Conditional Configuration”extraModules = [ ({ config, lib, ... }: { # Only apply if debug profile config = lib.mkIf config.ghaf.global-config.debug.enable { services.getty.autologinUser = "ghaf"; }; })];Testing Targets
Section titled “Testing Targets”Build Target
Section titled “Build Target”# Debug variantnix build .#my-device-debug
# Release variantnix build .#my-device-releaseDry-Run Evaluation
Section titled “Dry-Run Evaluation”nix build .#my-device-debug --dry-runCheck Specific Configuration
Section titled “Check Specific Configuration”# Check VM configurationnix eval .#nixosConfigurations.my-device-debug.config.microvm.vms.gui-vm.config.config.networking.hostName
# Check global confignix eval .#nixosConfigurations.my-device-debug.config.ghaf.global-config --json | jqChecklist for New Targets
Section titled “Checklist for New Targets”- Create hardware definition with
_filedeclaration - Create hardware module with device-specific settings
- Export hardware module in
flake-module.nix - Create target configuration in
targets/ - Configure both debug and release variants
- Add installer configuration if needed
- Test build succeeds
- Test on actual hardware
- Document hardware requirements
See Also
Section titled “See Also”- Creating VMs - New VM types
- Writing Modules - Module conventions
- Downstream Setup - Downstream projects
- Profiles API - Profile configuration