Skip to content

Commit

Permalink
GIVC Implementation
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mbssrc authored and brianmcgillion committed Aug 29, 2024
1 parent 1fb154f commit b7fe4a3
Show file tree
Hide file tree
Showing 31 changed files with 550 additions and 93 deletions.
60 changes: 59 additions & 1 deletion flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
4 changes: 4 additions & 0 deletions modules/common/development/debug-tools.nix
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ in
# to build ghaf on target

git

# Grpc testing

grpcurl
;
}
++
Expand Down
82 changes: 25 additions & 57 deletions modules/common/services/desktop.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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
Expand All @@ -35,86 +34,81 @@ 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
[
{
# The SPKI fingerprint is calculated like this:
# $ 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";
}

Expand All @@ -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 [
{
Expand Down
1 change: 1 addition & 0 deletions modules/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
./disko/flake-module.nix
./hardware/flake-module.nix
./microvm/flake-module.nix
./givc/flake-module.nix
];

flake.nixosModules = {
Expand Down
30 changes: 30 additions & 0 deletions modules/givc/adminvm.nix
Original file line number Diff line number Diff line change
@@ -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;
};
};
}
50 changes: 50 additions & 0 deletions modules/givc/appvm.nix
Original file line number Diff line number Diff line change
@@ -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}" ];
};
}
Loading

0 comments on commit b7fe4a3

Please sign in to comment.