From b7fe4a3bd7c4a0ebce49857e06e99914337b35cf Mon Sep 17 00:00:00 2001 From: Manuel Bluhm Date: Wed, 28 Aug 2024 18:53:46 +0400 Subject: [PATCH] GIVC Implementation Changes: - introduce givc for laptop-x86: rust admin service and client, go agent - add and configure givc modules for Ghaf - replace ssh commands for application and power start Notes: - TLS is turned off, will be added later Signed-off-by: Manuel Bluhm --- flake.lock | 60 +++++++++++++- flake.nix | 12 +++ modules/common/development/debug-tools.nix | 4 + modules/common/services/desktop.nix | 82 ++++++------------- modules/flake-module.nix | 1 + modules/givc/adminvm.nix | 30 +++++++ modules/givc/appvm.nix | 50 +++++++++++ modules/givc/audiovm.nix | 30 +++++++ modules/givc/common.nix | 73 +++++++++++++++++ modules/givc/flake-module.nix | 41 ++++++++++ modules/givc/guivm.nix | 30 +++++++ modules/givc/host.nix | 41 ++++++++++ modules/givc/netvm.nix | 37 +++++++++ modules/microvm/flake-module.nix | 12 +-- .../virtualization/microvm/adminvm.nix | 4 + .../microvm/virtualization/microvm/appvm.nix | 6 +- .../virtualization/microvm/audiovm.nix | 3 + .../microvm/common/storagevm.nix | 3 - .../microvm/virtualization/microvm/guivm.nix | 7 +- .../virtualization/microvm/microvm-host.nix | 6 ++ .../virtualization/microvm/modules.nix | 10 +++ .../microvm/virtualization/microvm/netvm.nix | 7 +- modules/reference/appvms/appflowy.nix | 12 ++- modules/reference/appvms/business.nix | 13 +++ modules/reference/appvms/chromium.nix | 9 ++ modules/reference/appvms/default.nix | 4 +- modules/reference/appvms/element.nix | 8 +- modules/reference/appvms/gala.nix | 18 +++- modules/reference/appvms/zathura.nix | 12 ++- modules/reference/profiles/laptop-x86.nix | 17 ++-- targets/laptop/flake-module.nix | 1 - 31 files changed, 550 insertions(+), 93 deletions(-) create mode 100644 modules/givc/adminvm.nix create mode 100644 modules/givc/appvm.nix create mode 100644 modules/givc/audiovm.nix create mode 100644 modules/givc/common.nix create mode 100644 modules/givc/flake-module.nix create mode 100644 modules/givc/guivm.nix create mode 100644 modules/givc/host.nix create mode 100644 modules/givc/netvm.nix diff --git a/flake.lock b/flake.lock index 47c37f5d3..5dbcd3305 100644 --- a/flake.lock +++ b/flake.lock @@ -1,6 +1,27 @@ { "nodes": { "crane": { + "inputs": { + "nixpkgs": [ + "givc", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1720975002, + "narHash": "sha256-1i521ecK2MFg+lxSk9oRx/C0SsdlI6GS6eYT79nA6TA=", + "owner": "ipetkov", + "repo": "crane", + "rev": "1791a5b98d2c1bf143ad85469abcfa2426f3f087", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "crane_2": { "inputs": { "nixpkgs": [ "lanzaboote", @@ -223,6 +244,42 @@ "type": "github" } }, + "givc": { + "inputs": { + "crane": "crane", + "devshell": [ + "devshell" + ], + "flake-parts": [ + "flake-parts" + ], + "flake-root": [ + "flake-root" + ], + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks-nix": [ + "pre-commit-hooks-nix" + ], + "treefmt-nix": [ + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1724752104, + "narHash": "sha256-wNYN6dSsLPGLWkrb27/YswsE0kqkw29m6UCbMBDR600=", + "owner": "tiiuae", + "repo": "ghaf-givc", + "rev": "ff9f60e3059f940fad610c27393b4d101bf6693d", + "type": "github" + }, + "original": { + "owner": "tiiuae", + "repo": "ghaf-givc", + "type": "github" + } + }, "impermanence": { "locked": { "lastModified": 1717932370, @@ -261,7 +318,7 @@ }, "lanzaboote": { "inputs": { - "crane": "crane", + "crane": "crane_2", "flake-compat": [ "flake-compat" ], @@ -448,6 +505,7 @@ "flake-root": "flake-root", "flake-utils": "flake-utils", "ghafpkgs": "ghafpkgs", + "givc": "givc", "impermanence": "impermanence", "jetpack-nixos": "jetpack-nixos", "lanzaboote": "lanzaboote", diff --git a/flake.nix b/flake.nix index 7ff4f62bc..8d005ef24 100644 --- a/flake.nix +++ b/flake.nix @@ -143,6 +143,18 @@ impermanence = { url = "github:nix-community/impermanence"; }; + + givc = { + url = "github:tiiuae/ghaf-givc"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-parts.follows = "flake-parts"; + flake-root.follows = "flake-root"; + treefmt-nix.follows = "treefmt-nix"; + devshell.follows = "devshell"; + pre-commit-hooks-nix.follows = "pre-commit-hooks-nix"; + }; + }; }; outputs = diff --git a/modules/common/development/debug-tools.nix b/modules/common/development/debug-tools.nix index 7c7613384..61152eb25 100644 --- a/modules/common/development/debug-tools.nix +++ b/modules/common/development/debug-tools.nix @@ -58,6 +58,10 @@ in # to build ghaf on target git + + # Grpc testing + + grpcurl ; } ++ diff --git a/modules/common/services/desktop.nix b/modules/common/services/desktop.nix index dbf10b6d3..be6d4f07b 100644 --- a/modules/common/services/desktop.nix +++ b/modules/common/services/desktop.nix @@ -7,15 +7,15 @@ ... }: let - inherit (builtins) filter map hasAttr; + inherit (builtins) hasAttr replaceStrings; inherit (lib) mkIf mkEnableOption - head - any optionals optionalAttrs + optionalString ; + cfg = config.ghaf.services.desktop; winConfig = @@ -26,7 +26,6 @@ let { } else { }; - isIdsvmEnabled = any (vm: vm == "ids-vm") config.ghaf.namespaces.vms; in # TODO: The desktop configuration needs to be re-worked. # TODO it needs to be moved out of common and the launchers have to be set bu the reference programs NOT here @@ -35,18 +34,21 @@ in enable = mkEnableOption "Enable the desktop configuration"; }; - config = mkIf cfg.enable { + config = mkIf (cfg.enable && config.ghaf.givc.enable) { ghaf = optionalAttrs (hasAttr "graphics" config.ghaf) { profiles.graphics.compositor = "labwc"; graphics = { launchers = let - hostEntry = filter ( - x: x.name == "ghaf-host" + lib.optionalString config.ghaf.profiles.debug.enable "-debug" - ) config.ghaf.networking.hosts.entries; - hostAddress = head (map (x: x.ip) hostEntry); - powerControl = pkgs.callPackage ../../../packages/powercontrol { }; - privateSshKeyPath = config.ghaf.security.sshKeys.sshKeyPath; + cliArgs = replaceStrings [ "\n" ] [ " " ] '' + --name ${config.ghaf.givc.adminConfig.name} + --addr ${config.ghaf.givc.adminConfig.addr} + --port ${config.ghaf.givc.adminConfig.port} + ${optionalString config.ghaf.givc.enableTls "--cacert /run/givc/ca-cert.pem"} + ${optionalString config.ghaf.givc.enableTls "--cert /run/givc/gui-vm-cert.pem"} + ${optionalString config.ghaf.givc.enableTls "--key /run/givc/gui-vm-key.pem"} + ${optionalString (!config.ghaf.givc.enableTls) "--notls"} + ''; in [ { @@ -54,67 +56,59 @@ in # $ openssl x509 -noout -in mitmproxy-ca-cert.pem -pubkey | openssl asn1parse -noout -inform pem -out public.key # $ openssl dgst -sha256 -binary public.key | openssl enc -base64 name = "Chromium"; - path = - if isIdsvmEnabled then - "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no chromium-vm run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --user-data-dir=/home/${config.ghaf.users.accounts.user}/.config/chromium/Default --ignore-certificate-errors-spki-list=Bq49YmAq1CG6FuBzp8nsyRXumW7Dmkp7QQ/F82azxGU=" - else - "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no chromium-vm run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start chromium"; icon = "${pkgs.icon-pack}/chromium.svg"; } { name = "Trusted Browser"; - path = - if isIdsvmEnabled then - "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no business-vm run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --user-data-dir=/home/${config.ghaf.users.accounts.user}/.config/chromium/Default --ignore-certificate-errors-spki-list=Bq49YmAq1CG6FuBzp8nsyRXumW7Dmkp7QQ/F82azxGU=" - else - "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no business-vm run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm chromium"; icon = "${pkgs.icon-pack}/thorium-browser.svg"; } # TODO must enable the waypipe to support more than one app in a VM { name = "VPN"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no business-vm run-waypipe gpclient -platform wayland"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm gpclient"; icon = "${pkgs.icon-pack}/yast-vpn.svg"; } { name = "Microsoft Outlook"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no business-vm run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --app=https://outlook.office.com/mail/"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm outlook"; icon = "${pkgs.icon-pack}/ms-outlook.svg"; } { name = "Microsoft 365"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no business-vm run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --app=https://microsoft365.com"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm office"; icon = "${pkgs.icon-pack}/microsoft-365.svg"; } { name = "Teams"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no business-vm run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --app=https://teams.microsoft.com"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm teams"; icon = "${pkgs.icon-pack}/teams-for-linux.svg"; } { name = "GALA"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no gala-vm run-waypipe gala --enable-features=UseOzonePlatform --ozone-platform=wayland"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start gala"; icon = "${pkgs.icon-pack}/distributor-logo-android.svg"; } { name = "PDF Viewer"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no zathura-vm run-waypipe zathura"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start zathura"; icon = "${pkgs.icon-pack}/document-viewer.svg"; } { name = "Element"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no element-vm run-waypipe element-desktop --enable-features=UseOzonePlatform --ozone-platform=wayland"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start element"; icon = "${pkgs.icon-pack}/element-desktop.svg"; } { name = "AppFlowy"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no appflowy-vm run-waypipe appflowy"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start appflowy"; icon = "${pkgs.appflowy}/opt/data/flutter_assets/assets/images/flowy_logo.svg"; } @@ -126,41 +120,15 @@ in { name = "Shutdown"; - path = "${powerControl.makePowerOffCommand { - inherit hostAddress; - inherit privateSshKeyPath; - }}"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} poweroff"; icon = "${pkgs.icon-pack}/system-shutdown.svg"; } { name = "Reboot"; - path = "${powerControl.makeRebootCommand { - inherit hostAddress; - inherit privateSshKeyPath; - }}"; + path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} reboot"; icon = "${pkgs.icon-pack}/system-reboot.svg"; } - - # Temporarly disabled as it fails to turn off display when suspended - # { - # name = "Suspend"; - # path = "${powerControl.makeSuspendCommand { - # inherit hostAddress; - # inherit privateSshKeyPath; - # }}"; - # icon = "${pkgs.icon-pack}/system-suspend.svg"; - # } - - # Temporarly disabled as it doesn't work at all - # { - # name = "Hibernate"; - # path = "${powerControl.makeHibernateCommand { - # inherit hostAddress; - # inherit privateSshKeyPath; - # }}"; - # icon = "${pkgs.icon-pack}/system-suspend-hibernate.svg"; - # } ] ++ optionals config.ghaf.reference.programs.windows-launcher.enable [ { diff --git a/modules/flake-module.nix b/modules/flake-module.nix index 4d5d0249a..fe22ac7e8 100644 --- a/modules/flake-module.nix +++ b/modules/flake-module.nix @@ -9,6 +9,7 @@ ./disko/flake-module.nix ./hardware/flake-module.nix ./microvm/flake-module.nix + ./givc/flake-module.nix ]; flake.nixosModules = { diff --git a/modules/givc/adminvm.nix b/modules/givc/adminvm.nix new file mode 100644 index 000000000..e501ea145 --- /dev/null +++ b/modules/givc/adminvm.nix @@ -0,0 +1,30 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ config, lib, ... }: +let + cfg = config.ghaf.givc.adminvm; + inherit (lib) mkEnableOption mkIf; +in +{ + options.ghaf.givc.adminvm = { + enable = mkEnableOption "Enable adminvm givc module."; + }; + + config = mkIf (cfg.enable && config.ghaf.givc.enable) { + # Configure admin service + givc.admin = { + enable = true; + inherit (config.ghaf.givc.adminConfig) name; + inherit (config.ghaf.givc.adminConfig) addr; + inherit (config.ghaf.givc.adminConfig) port; + inherit (config.ghaf.givc.adminConfig) protocol; + services = [ + "givc-ghaf-host-debug.service" + "givc-net-vm.service" + "givc-gui-vm.service" + "givc-audio-vm.service" + ]; + tls.enable = config.ghaf.givc.enableTls; + }; + }; +} diff --git a/modules/givc/appvm.nix b/modules/givc/appvm.nix new file mode 100644 index 000000000..6fe698785 --- /dev/null +++ b/modules/givc/appvm.nix @@ -0,0 +1,50 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + config, + lib, + givc, + ... +}: +let + cfg = config.ghaf.givc.appvm; + inherit (lib) + mkOption + mkEnableOption + mkIf + types + ; + vmEntry = vm: builtins.filter (x: x.name == vm) config.ghaf.networking.hosts.entries; + address = vm: lib.head (builtins.map (x: x.ip) (vmEntry vm)); +in +{ + options.ghaf.givc.appvm = { + enable = mkEnableOption "Enable appvm givc module."; + name = mkOption { + type = types.str; + default = "appvm"; + description = "Name of the appvm."; + }; + applications = mkOption { + type = types.str; + default = "{}"; + description = "Applications to run in the appvm."; + }; + }; + + config = mkIf (cfg.enable && config.ghaf.givc.enable) { + # Configure appvm service + givc.appvm = { + enable = true; + inherit (cfg) name; + inherit (cfg) applications; + addr = address cfg.name; + port = "9000"; + tls.enable = config.ghaf.givc.enableTls; + admin = config.ghaf.givc.adminConfig; + }; + + # Quick fix to allow linger (linger option in user def. currently doesn't work, e.g., bc mutable) + systemd.tmpfiles.rules = [ "f /var/lib/systemd/linger/${config.ghaf.users.accounts.user}" ]; + }; +} diff --git a/modules/givc/audiovm.nix b/modules/givc/audiovm.nix new file mode 100644 index 000000000..1ef30a751 --- /dev/null +++ b/modules/givc/audiovm.nix @@ -0,0 +1,30 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ config, lib, ... }: +let + cfg = config.ghaf.givc.audiovm; + inherit (lib) mkEnableOption mkIf; + hostName = "audio-vm"; +in +{ + options.ghaf.givc.audiovm = { + enable = mkEnableOption "Enable audiovm givc module."; + }; + + config = mkIf (cfg.enable && config.ghaf.givc.enable) { + # Configure audiovm service + givc.sysvm = + let + audiovmEntry = builtins.filter (x: x.name == hostName) config.ghaf.networking.hosts.entries; + addr = lib.head (builtins.map (x: x.ip) audiovmEntry); + in + { + enable = true; + name = hostName; + inherit addr; + port = "9000"; + tls.enable = config.ghaf.givc.enableTls; + admin = config.ghaf.givc.adminConfig; + }; + }; +} diff --git a/modules/givc/common.nix b/modules/givc/common.nix new file mode 100644 index 000000000..6306376ec --- /dev/null +++ b/modules/givc/common.nix @@ -0,0 +1,73 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ config, lib, ... }: +let + cfg = config.ghaf.givc; + inherit (lib) + mkOption + mkEnableOption + mkIf + types + ; + mitmEnabled = + config.ghaf.virtualization.microvm.idsvm.enable + && config.ghaf.virtualization.microvm.idsvm.mitmproxy.enable; + mitmExtraArgs = lib.optionalString mitmEnabled "--user-data-dir=/home/${config.ghaf.users.accounts.user}/.config/chromium/Default --test-type --ignore-certificate-errors-spki-list=Bq49YmAq1CG6FuBzp8nsyRXumW7Dmkp7QQ/F82azxGU="; +in +{ + options.ghaf.givc = { + enable = mkEnableOption "Enable gRPC inter-vm communication"; + enableTls = mkOption { + description = "Enable TLS for gRPC communication globally, or disable for debugging."; + type = types.bool; + default = false; + }; + idsExtraArgs = mkOption { + description = "Extra arguments for applications when IDS/MITM is enabled."; + type = types.str; + default = mitmExtraArgs; + }; + appPrefix = mkOption { + description = "Common application path prefix."; + type = types.str; + default = "/run/current-system/sw/bin"; + }; + adminConfig = mkOption { + description = "Admin server configuration."; + type = types.submodule { + options = { + name = mkOption { + description = "Host name of admin server"; + type = types.str; + }; + addr = mkOption { + description = "Address of admin server"; + type = types.str; + }; + port = mkOption { + description = "Port of admin server"; + type = types.str; + }; + protocol = mkOption { + description = "Protocol of admin server"; + type = types.str; + }; + }; + }; + }; + }; + config = mkIf cfg.enable { + # Givc admin server configuration + ghaf.givc.adminConfig = + let + adminvmEntry = builtins.filter (x: x.name == "admin-vm-debug") config.ghaf.networking.hosts.entries; + addr = lib.head (builtins.map (x: x.ip) adminvmEntry); + in + { + name = "admin-vm-debug"; + inherit addr; + port = "9001"; + protocol = "tcp"; + }; + }; +} diff --git a/modules/givc/flake-module.nix b/modules/givc/flake-module.nix new file mode 100644 index 000000000..33bce39b2 --- /dev/null +++ b/modules/givc/flake-module.nix @@ -0,0 +1,41 @@ +# Copyright 2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ inputs, ... }: +{ + flake.nixosModules = { + givc-adminvm.imports = [ + inputs.givc.nixosModules.admin + ./common.nix + ./adminvm.nix + ]; + givc-host.imports = [ + inputs.givc.nixosModules.host + ./common.nix + ./host.nix + ]; + givc-guivm.imports = [ + inputs.givc.nixosModules.sysvm + ./common.nix + ./guivm.nix + { + # Include givc overlay to import app + nixpkgs.overlays = [ inputs.givc.overlays.default ]; + } + ]; + givc-netvm.imports = [ + inputs.givc.nixosModules.sysvm + ./common.nix + ./netvm.nix + ]; + givc-audiovm.imports = [ + inputs.givc.nixosModules.sysvm + ./common.nix + ./audiovm.nix + ]; + givc-appvm.imports = [ + inputs.givc.nixosModules.appvm + ./common.nix + ./appvm.nix + ]; + }; +} diff --git a/modules/givc/guivm.nix b/modules/givc/guivm.nix new file mode 100644 index 000000000..4a7e8d737 --- /dev/null +++ b/modules/givc/guivm.nix @@ -0,0 +1,30 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ config, lib, ... }: +let + cfg = config.ghaf.givc.guivm; + inherit (lib) mkEnableOption mkIf; + hostName = "gui-vm"; +in +{ + options.ghaf.givc.guivm = { + enable = mkEnableOption "Enable guivm givc module."; + }; + + config = mkIf (cfg.enable && config.ghaf.givc.enable) { + # Configure guivm service + givc.sysvm = + let + guivmEntry = builtins.filter (x: x.name == hostName) config.ghaf.networking.hosts.entries; + addr = lib.head (builtins.map (x: x.ip) guivmEntry); + in + { + enable = true; + name = hostName; + inherit addr; + port = "9000"; + tls.enable = config.ghaf.givc.enableTls; + admin = config.ghaf.givc.adminConfig; + }; + }; +} diff --git a/modules/givc/host.nix b/modules/givc/host.nix new file mode 100644 index 000000000..6849accc9 --- /dev/null +++ b/modules/givc/host.nix @@ -0,0 +1,41 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + config, + lib, + givc, + ... +}: +let + cfg = config.ghaf.givc.host; + inherit (builtins) map filter attrNames; + inherit (lib) mkEnableOption mkIf head; + hostName = "ghaf-host-debug"; +in +{ + options.ghaf.givc.host = { + enable = mkEnableOption "Enable host givc module."; + }; + + config = mkIf (cfg.enable && config.ghaf.givc.enable) { + # Configure host service + givc.host = + let + getIp = + name: head (map (x: x.ip) (filter (x: x.name == name) config.ghaf.networking.hosts.entries)); + addr = getIp hostName; + in + { + enable = true; + name = hostName; + inherit addr; + port = "9000"; + services = [ + "reboot.target" + "poweroff.target" + ] ++ map (vmName: "microvm@${vmName}.service") (attrNames config.microvm.vms); + tls.enable = config.ghaf.givc.enableTls; + admin = config.ghaf.givc.adminConfig; + }; + }; +} diff --git a/modules/givc/netvm.nix b/modules/givc/netvm.nix new file mode 100644 index 000000000..aa22d3b0f --- /dev/null +++ b/modules/givc/netvm.nix @@ -0,0 +1,37 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + config, + lib, + givc, + ... +}: +let + cfg = config.ghaf.givc.netvm; + inherit (lib) mkEnableOption mkIf; + hostName = "net-vm"; +in +{ + options.ghaf.givc.netvm = { + enable = mkEnableOption "Enable netvm givc module."; + }; + + config = mkIf (cfg.enable && config.ghaf.givc.enable) { + # Configure netvm service + givc.sysvm = + let + netvmEntry = builtins.filter (x: x.name == hostName) config.ghaf.networking.hosts.entries; + addr = lib.head (builtins.map (x: x.ip) netvmEntry); + in + { + enable = true; + name = hostName; + inherit addr; + port = "9000"; + wifiManager = true; + hwidService = true; + tls.enable = config.ghaf.givc.enableTls; + admin = config.ghaf.givc.adminConfig; + }; + }; +} diff --git a/modules/microvm/flake-module.nix b/modules/microvm/flake-module.nix index 83738c8ad..9d0f4ff70 100644 --- a/modules/microvm/flake-module.nix +++ b/modules/microvm/flake-module.nix @@ -5,14 +5,14 @@ flake.nixosModules = { microvm.imports = [ inputs.microvm.nixosModules.host - ./virtualization/microvm/microvm-host.nix - (import ./virtualization/microvm/netvm.nix { inherit (inputs) impermanence; }) - ./virtualization/microvm/adminvm.nix + (import ./virtualization/microvm/microvm-host.nix { inherit inputs; }) + (import ./virtualization/microvm/netvm.nix { inherit inputs; }) + (import ./virtualization/microvm/adminvm.nix { inherit inputs; }) + (import ./virtualization/microvm/appvm.nix { inherit inputs; }) + (import ./virtualization/microvm/guivm.nix { inherit inputs; }) + (import ./virtualization/microvm/audiovm.nix { inherit inputs; }) ./virtualization/microvm/idsvm/idsvm.nix ./virtualization/microvm/idsvm/mitmproxy - (import ./virtualization/microvm/appvm.nix { inherit (inputs) impermanence; }) - (import ./virtualization/microvm/guivm.nix { inherit (inputs) impermanence; }) - ./virtualization/microvm/audiovm.nix ./virtualization/microvm/modules.nix ./networking.nix ./power-control.nix diff --git a/modules/microvm/virtualization/microvm/adminvm.nix b/modules/microvm/virtualization/microvm/adminvm.nix index dd6147825..0395c1d04 100644 --- a/modules/microvm/virtualization/microvm/adminvm.nix +++ b/modules/microvm/virtualization/microvm/adminvm.nix @@ -1,5 +1,6 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 +{ inputs }: { config, lib, ... }: let configHost = config; @@ -9,6 +10,7 @@ let adminvmBaseConfiguration = { imports = [ + inputs.self.nixosModules.givc-adminvm (import ./common/vm-networking.nix { inherit config @@ -46,6 +48,8 @@ let withHardenedConfigs = true; }; + givc.adminvm.enable = true; + # Log aggregation configuration logging.client.enable = isLoggingEnabled; logging.listener.address = configHost.ghaf.logging.listener.address; diff --git a/modules/microvm/virtualization/microvm/appvm.nix b/modules/microvm/virtualization/microvm/appvm.nix index 18acb68e7..fb6659a8a 100644 --- a/modules/microvm/virtualization/microvm/appvm.nix +++ b/modules/microvm/virtualization/microvm/appvm.nix @@ -1,6 +1,6 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 -{ impermanence }: +{ inputs }: { config, lib, @@ -25,13 +25,15 @@ let cid = if vm.cid > 0 then vm.cid else cfg.vsockBaseCID + index; appvmConfiguration = { imports = [ + inputs.impermanence.nixosModules.impermanence + inputs.self.nixosModules.givc-appvm (import ./common/vm-networking.nix { inherit config lib vmName; inherit (vm) macAddress; internalIP = index + 100; }) - (import ./common/storagevm.nix { inherit impermanence; }) + ./common/storagevm.nix # To push logs to central location ../../../common/logging/client.nix diff --git a/modules/microvm/virtualization/microvm/audiovm.nix b/modules/microvm/virtualization/microvm/audiovm.nix index ca224d18f..7d90ee030 100644 --- a/modules/microvm/virtualization/microvm/audiovm.nix +++ b/modules/microvm/virtualization/microvm/audiovm.nix @@ -1,5 +1,6 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 +{ inputs }: { config, lib, @@ -19,6 +20,7 @@ let audiovmBaseConfiguration = { imports = [ + inputs.self.nixosModules.givc-audiovm (import ./common/vm-networking.nix { inherit config @@ -51,6 +53,7 @@ let withTimesyncd = true; withDebug = configHost.ghaf.profiles.debug.enable; }; + givc.audiovm.enable = true; services.audio.enable = true; }; diff --git a/modules/microvm/virtualization/microvm/common/storagevm.nix b/modules/microvm/virtualization/microvm/common/storagevm.nix index 16d0cb732..6f86423b0 100644 --- a/modules/microvm/virtualization/microvm/common/storagevm.nix +++ b/modules/microvm/virtualization/microvm/common/storagevm.nix @@ -1,14 +1,11 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 -{ impermanence }: { lib, config, ... }: let cfg = config.ghaf.storagevm; mountPath = "/tmp/storagevm"; in { - imports = [ impermanence.nixosModules.impermanence ]; - options.ghaf.storagevm = with lib; { enable = mkEnableOption "StorageVM support"; diff --git a/modules/microvm/virtualization/microvm/guivm.nix b/modules/microvm/virtualization/microvm/guivm.nix index f910bcd13..c86ff6222 100644 --- a/modules/microvm/virtualization/microvm/guivm.nix +++ b/modules/microvm/virtualization/microvm/guivm.nix @@ -1,6 +1,6 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 -{ impermanence }: +{ inputs }: { config, lib, @@ -13,6 +13,8 @@ let inherit (import ../../../../lib/launcher.nix { inherit pkgs lib; }) rmDesktopEntries; guivmBaseConfiguration = { imports = [ + inputs.impermanence.nixosModules.impermanence + inputs.self.nixosModules.givc-guivm (import ./common/vm-networking.nix { inherit config @@ -23,7 +25,7 @@ let internalIP = 3; }) - (import ./common/storagevm.nix { inherit impermanence; }) + ./common/storagevm.nix # To push logs to central location ../../../common/logging/client.nix @@ -54,6 +56,7 @@ let withDebug = config.ghaf.profiles.debug.enable; withHardenedConfigs = true; }; + givc.guivm.enable = true; # Logging client configuration logging.client.enable = config.ghaf.logging.client.enable; logging.client.endpoint = config.ghaf.logging.client.endpoint; diff --git a/modules/microvm/virtualization/microvm/microvm-host.nix b/modules/microvm/virtualization/microvm/microvm-host.nix index a65e3d4d2..53f5c275e 100644 --- a/modules/microvm/virtualization/microvm/microvm-host.nix +++ b/modules/microvm/virtualization/microvm/microvm-host.nix @@ -1,5 +1,6 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 +{ inputs }: { config, lib, @@ -10,6 +11,10 @@ let cfg = config.ghaf.virtualization.microvm-host; in { + imports = [ + inputs.impermanence.nixosModules.impermanence + inputs.self.nixosModules.givc-host + ]; options.ghaf.virtualization.microvm-host = { enable = lib.mkEnableOption "MicroVM Host"; networkSupport = lib.mkEnableOption "Network support services to run host applications."; @@ -34,6 +39,7 @@ in withDebug = config.ghaf.profiles.debug.enable; withHardenedConfigs = true; }; + ghaf.givc.host.enable = true; # TODO: remove hardcoded paths systemd.services."microvm@audio-vm".serviceConfig = diff --git a/modules/microvm/virtualization/microvm/modules.nix b/modules/microvm/virtualization/microvm/modules.nix index 4cfaeb453..f61200817 100644 --- a/modules/microvm/virtualization/microvm/modules.nix +++ b/modules/microvm/virtualization/microvm/modules.nix @@ -47,6 +47,11 @@ let # Service modules serviceModules = { + # Givc module + givc = { + config.ghaf.givc.enable = config.ghaf.givc.enable; + }; + # Audio module audio = optionalAttrs cfg.audiovm.audio { config.ghaf.services.audio.enable = true; }; @@ -133,6 +138,7 @@ in deviceModules.netvmPCIPassthroughModule firmwareModule serviceModules.wifi + serviceModules.givc referenceServiceModule ]; # Audiovm modules @@ -140,6 +146,7 @@ in deviceModules.audiovmPCIPassthroughModule kernelConfigs.audiovm serviceModules.audio + serviceModules.givc ]; # Guivm modules guivm.extraModules = optionals cfg.guivm.enable [ @@ -153,8 +160,11 @@ in serviceModules.yubikey serviceModules.pdfOpener serviceModules.commonNamespace + serviceModules.givc referenceProgramsModule ]; + adminvm.extraModules = optionals cfg.adminvm.enable [ serviceModules.givc ]; + appvm.extraModules = optionals cfg.appvm.enable [ serviceModules.givc ]; }; }; } diff --git a/modules/microvm/virtualization/microvm/netvm.nix b/modules/microvm/virtualization/microvm/netvm.nix index 758c18891..b22ace700 100644 --- a/modules/microvm/virtualization/microvm/netvm.nix +++ b/modules/microvm/virtualization/microvm/netvm.nix @@ -1,6 +1,6 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 -{ impermanence }: +{ inputs }: { config, lib, @@ -20,6 +20,8 @@ let netvmBaseConfiguration = { imports = [ + inputs.impermanence.nixosModules.impermanence + inputs.self.nixosModules.givc-netvm (import ./common/vm-networking.nix { inherit config @@ -31,7 +33,7 @@ let isGateway = true; }) - (import ./common/storagevm.nix { inherit impermanence; }) + ./common/storagevm.nix # To push logs to central location ../../../common/logging/client.nix @@ -60,6 +62,7 @@ let withDebug = config.ghaf.profiles.debug.enable; withHardenedConfigs = true; }; + givc.netvm.enable = true; # Logging client configuration logging.client.enable = config.ghaf.logging.client.enable; logging.client.endpoint = config.ghaf.logging.client.endpoint; diff --git a/modules/reference/appvms/appflowy.nix b/modules/reference/appvms/appflowy.nix index f89512b4c..584b08852 100644 --- a/modules/reference/appvms/appflowy.nix +++ b/modules/reference/appvms/appflowy.nix @@ -1,7 +1,12 @@ # Copyright 2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 # -{ pkgs, config, ... }: +{ + lib, + pkgs, + config, + ... +}: { name = "appflowy"; packages = [ pkgs.appflowy ]; @@ -12,6 +17,11 @@ { hardware.graphics.enable = true; time.timeZone = config.time.timeZone; + ghaf.givc.appvm = { + enable = true; + name = lib.mkForce "appflowy-vm"; + applications = lib.mkForce ''{"appflowy": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/appflowy"}''; + }; } ]; borderColor = "#4c3f7a"; diff --git a/modules/reference/appvms/business.nix b/modules/reference/appvms/business.nix index 4acf441e9..2fe8908bb 100644 --- a/modules/reference/appvms/business.nix +++ b/modules/reference/appvms/business.nix @@ -76,6 +76,19 @@ in devices = [ ]; }; + ghaf.givc.appvm = { + enable = true; + name = lib.mkForce "business-vm"; + applications = lib.mkForce '' + { + "chromium": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland ${config.ghaf.givc.idsExtraArgs}", + "outlook": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --app=https://outlook.office.com/mail/ ${config.ghaf.givc.idsExtraArgs}", + "office": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --app=https://microsoft365.com ${config.ghaf.givc.idsExtraArgs}", + "teams": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --app=https://teams.microsoft.com ${config.ghaf.givc.idsExtraArgs}", + "gpclient": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/gpclient -platform wayland" + }''; + }; + ghaf.reference.programs.chromium.enable = true; ghaf.storagevm = { enable = true; diff --git a/modules/reference/appvms/chromium.nix b/modules/reference/appvms/chromium.nix index f432a555f..2b7094720 100644 --- a/modules/reference/appvms/chromium.nix +++ b/modules/reference/appvms/chromium.nix @@ -71,6 +71,15 @@ in ) config.ghaf.hardware.usb.internal.qemuExtraArgs.cam0; microvm.devices = [ ]; + ghaf.givc.appvm = { + enable = true; + name = lib.mkForce "chromium-vm"; + applications = lib.mkForce '' + { + "chromium": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland ${config.ghaf.givc.idsExtraArgs}" + }''; + }; + ghaf.reference.programs.chromium.enable = true; ghaf.storagevm = { enable = true; diff --git a/modules/reference/appvms/default.nix b/modules/reference/appvms/default.nix index 47c14b8f3..731df72d5 100644 --- a/modules/reference/appvms/default.nix +++ b/modules/reference/appvms/default.nix @@ -34,9 +34,9 @@ in enabled-app-vms = (lib.optionals cfg.chromium-vm [ (import ./chromium.nix { inherit pkgs lib config; }) ]) ++ (lib.optionals cfg.gala-vm [ (import ./gala.nix { inherit pkgs lib config; }) ]) - ++ (lib.optionals cfg.zathura-vm [ (import ./zathura.nix { inherit pkgs config; }) ]) + ++ (lib.optionals cfg.zathura-vm [ (import ./zathura.nix { inherit pkgs lib config; }) ]) ++ (lib.optionals cfg.element-vm [ (import ./element.nix { inherit pkgs lib config; }) ]) - ++ (lib.optionals cfg.appflowy-vm [ (import ./appflowy.nix { inherit pkgs config; }) ]) + ++ (lib.optionals cfg.appflowy-vm [ (import ./appflowy.nix { inherit pkgs lib config; }) ]) ++ (lib.optionals cfg.business-vm [ (import ./business.nix { inherit pkgs lib config; }) ]); }; }; diff --git a/modules/reference/appvms/element.nix b/modules/reference/appvms/element.nix index db6a8f6ee..246d2cedd 100644 --- a/modules/reference/appvms/element.nix +++ b/modules/reference/appvms/element.nix @@ -2,8 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 # { - pkgs, lib, + pkgs, config, ... }: @@ -98,6 +98,12 @@ in config.ghaf.hardware.usb.external.enable && (hasAttr "gps0" config.ghaf.hardware.usb.external.qemuExtraArgs) ) config.ghaf.hardware.usb.external.qemuExtraArgs.gps0; + + ghaf.givc.appvm = { + enable = true; + name = lib.mkForce "element-vm"; + applications = lib.mkForce ''{"element": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/element-desktop --enable-features=UseOzonePlatform --ozone-platform=wayland"}''; + }; } ]; borderColor = "#337aff"; diff --git a/modules/reference/appvms/gala.nix b/modules/reference/appvms/gala.nix index 28b5c69d9..b895b7ae1 100644 --- a/modules/reference/appvms/gala.nix +++ b/modules/reference/appvms/gala.nix @@ -1,13 +1,27 @@ # Copyright 2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 # -{ pkgs, config, ... }: +{ + lib, + pkgs, + config, + ... +}: { name = "gala"; packages = [ pkgs.gala-app ]; macAddress = "02:00:00:03:06:01"; ramMb = 1536; cores = 2; - extraModules = [ { time.timeZone = config.time.timeZone; } ]; + extraModules = [ + { + time.timeZone = config.time.timeZone; + ghaf.givc.appvm = { + enable = true; + name = lib.mkForce "gala-vm"; + applications = lib.mkForce ''{"gala": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/gala --enable-features=UseOzonePlatform --ozone-platform=wayland"}''; + }; + } + ]; borderColor = "#027d7b"; } diff --git a/modules/reference/appvms/zathura.nix b/modules/reference/appvms/zathura.nix index 635caebb7..d8f7a7d52 100644 --- a/modules/reference/appvms/zathura.nix +++ b/modules/reference/appvms/zathura.nix @@ -1,7 +1,12 @@ # Copyright 2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 # -{ pkgs, config, ... }: +{ + lib, + pkgs, + config, + ... +}: { name = "zathura"; packages = [ pkgs.zathura ]; @@ -13,6 +18,11 @@ imports = [ ../programs/zathura.nix ]; time.timeZone = config.time.timeZone; ghaf.reference.programs.zathura.enable = true; + ghaf.givc.appvm = { + enable = true; + name = lib.mkForce "zathura-vm"; + applications = lib.mkForce ''{"zathura": "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/zathura"}''; + }; } ]; borderColor = "#122263"; diff --git a/modules/reference/profiles/laptop-x86.nix b/modules/reference/profiles/laptop-x86.nix index a835d72fa..5d838b9ed 100644 --- a/modules/reference/profiles/laptop-x86.nix +++ b/modules/reference/profiles/laptop-x86.nix @@ -1,13 +1,7 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, ... }: let - powerControl = pkgs.callPackage ../../../packages/powercontrol { }; cfg = config.ghaf.reference.profiles.laptop-x86; listenerAddress = config.ghaf.logging.listener.address; listenerPort = toString config.ghaf.logging.listener.port; @@ -53,10 +47,6 @@ in }; config = lib.mkIf cfg.enable { - security.polkit = { - enable = true; - extraConfig = powerControl.polkitExtraConfig; - }; ghaf = { # Hardware definitions @@ -108,9 +98,12 @@ in }; }; + # Enable givc + # @TODO change this flag to enable givc in release + givc.enable = config.ghaf.profiles.debug.enable; + host = { networking.enable = true; - powercontrol.enable = true; }; # UI applications diff --git a/targets/laptop/flake-module.nix b/targets/laptop/flake-module.nix index 98c94e49e..2b022cf91 100644 --- a/targets/laptop/flake-module.nix +++ b/targets/laptop/flake-module.nix @@ -26,7 +26,6 @@ let ]) (laptop-configuration "lenovo-x1-carbon-gen11" "debug" [ self.nixosModules.disko-ab-partitions-v1 - inputs.impermanence.nixosModules.impermanence { ghaf = { hardware.definition.configFile = "/lenovo-x1/definitions/x1-gen11.nix";