NixOS Modules
Import GIVC
Section titled “Import GIVC”GIVC exposes NixOS modules, which are primarily aimed to be used with the Ghaf Framework.
If you are using the Ghaf Framework as a library, the default functionality should be available without further modification. However, to include it into your project, define your flake input as follows
givc = { url = "github:tiiuae/ghaf-givc"; inputs = { nixpkgs.follows = "nixpkgs"; # optional flake-utils.follows = "flake-utils"; # optional devshell.follows = "devshell"; # optional treefmt-nix.follows = "treefmt-nix"; # optional };};
To use the givc flake overlay, overlay your nixpkgs with the givc overlay:
nixpkgs.overlays = [ inputs.givc.overlays.default ];
Import Modules
Section titled “Import Modules”You can import the givc modules individually, or create an internal module importing all givc modules at once and enable the respective module where needed.
Option 1: Individual Import
Section titled “Option 1: Individual Import”To import a givc module, simply add the respective module to your imports statement in the relevant VM or host.
Example: Import admin module to admin-vm
imports = [ inputs.givc.nixosModules.admin];
This allows you to import a modules where needed, and applies analogously to all VMs and host.
Option 2: Internal Module
Section titled “Option 2: Internal Module”You can alternatively create an internal module, and import this module anywhere a givc module is needed. It can then be enabled and configured in the config section. Here an example how to create such a module with flake-parts:
{ inputs, ... }:{ flake.nixosModules = { givc.imports = [ inputs.givc.nixosModules.admin inputs.givc.nixosModules.host inputs.givc.nixosModules.tls inputs.givc.nixosModules.dbus inputs.givc.nixosModules.sysvm inputs.givc.nixosModules.appvm ]; };}
The givc module of your project is then exported, and can typically be referenced internally as
inputs.self.nixosModules.givc
Module Configuration
Section titled “Module Configuration”IMPORTANT Please refer to the developer documentation for detailed documentation of the NixOS modules; and examine the configurations of the automated tests or the Ghaf project as reference.
Once you have imported a givc module, you need to configure it. Module configuration should be straightforward; generally, all modules requires at least:
- enabling the module
- configuring its network paramters
- configuring TLS paths (if different from defaults)
In addition, agents typically require:
- configuring the admin service network parameters (where to reach it)
- configuring systemd units, services, and/or applications that it administers
- enabling additional agent modules (such as dbus or locale services)
Example: Host Module
Section titled “Example: Host Module”As an example, we configure the systems host
module. Compared to the sysvm
module, it has additional functionality to control VM services (microvm@<vm-name>.service
), and TLS credential generation. Only one host module should be present at a time.
A sample host module configuration could look like this:
# Configure givc host modulegivc.host = { # Enable module enable = true;
# Define modules' server configuration transport = { name = "my-host"; addr = "192.168.1.2"; port = "9000"; };
# Provide list of services to whitelist for the module services = [ "a-host-service.service" "poweroff.target" "reboot.target" ];
# Provide a list of system and app VMs systemVms = map (vmName: "microvm@${vmName}.service") [ "admin-vm" "net-vm" ]; appVms = map (vmName: "microvm@${vmName}.service") [ "app-vm" ];
# Provide TLS configuration files tls = { caCertPath = "/etc/ssl/certs/ca-certificates.crt"; certPath = "/etc/givc/ghaf-host-cert.pem"; keyPath = "/etc/givc/ghaf-host-key.pem"; };
# Provide admin service information admin = { name = "admin-vm"; addr = "192.168.1.3"; port = "9001"; };
# Provide a TLS generator configuration givc.tls = { enable = true; agents = lib.attrsets.mapAttrsToList (n: v: { name = n; addr = v; }) { net-vm = "192.168.1.1"; my-host = "192.168.1.2"; admin-vm = "192.168.1.3"; app-vm = "192.168.1.4"; }; generatorHostName = "my-host"; storagePath = "/vm-storage/givc"; };};
The system VM module (sysvm
) is used and configured the similar as the host module, and only differs by type and subsequent parent process (VM) information.
The admin
module is configured similar to the host
module. Services defined with the admin
module are expected to be givc agent modules that report to the admin VM as part of the system startup.
Example: Appvm Module
Section titled “Example: Appvm Module”The appvm
module runs as user service in an active user session, not as a system service. The implementation allows to specify and run multiple applications.
To use the agent as application controller, include the appvm
module as follows:
# Configure appvm modulegivc.appvm = { # Enable module enable = true;
# UID of user to determine session bus uid = 1000;
# Define modules' server configuration transport = { name = "app-vm"; addr = "192.168.1.123"; port = "9000"; };
# Specify applications by name, command, and argument types accepted applications = [ { name = "foot"; command = "${pkgs.foot}/bin/foot"; args = [ "flag" ]; } ];
# Provide TLS configuration files tls = { caCertPath = "/etc/ssl/certs/ca-certificates.crt"; certPath = "/etc/givc/ghaf-host-cert.pem"; keyPath = "/etc/givc/ghaf-host-key.pem"; };
# Provide admin service information admin = { name = "admin-vm"; addr = "192.168.1.3"; port = "9001"; };};
Note that a user session must be active for the systemd service to run. Depending on your system’s user configuration, you can use loginctl enable-linger $USER
, the users.users.<name>.linger
NixOS option, or
systemd.tmpfiles.rules = [ "f /var/lib/systemd/linger/${my-user}"];
to keep the user session running without requiring additional login and keep the user service agent running.