From 6803b62ffd2ff5ed4eab8387f566ae5043f415cd Mon Sep 17 00:00:00 2001 From: buianhhuy96 Date: Mon, 28 Oct 2024 15:48:19 +0200 Subject: [PATCH] FMO-69: Update fmo-tool with DDP and DPF fixes - Create fmo-tool service for default config - Add dynamic-device-passthrough and dynamic-portforwarding services - Add fmo-tool package - Add vhotplug package for dynamic-device-passthrough - Add psk distribution service to dockervm Signed-off-by: Anh Huy Bui --- config-processor-hardware.nix | 21 ++-- config-processor-installers.nix | 9 +- flake.nix | 31 ++--- hardware/fmo-os-rugged-laptop-7330.nix | 59 ++++++++- hardware/fmo-os-rugged-tablet-7230.nix | 55 ++++++++- modules/flake-module.nix | 24 ++-- .../default.nix | 32 +++++ .../default.nix | 23 ++++ .../default.nix | 33 +++++ .../default.nix | 92 ++++++++++++++ .../{default.nix => host-services.nix} | 8 +- modules/fmo-services/vm-services.nix | 15 +++ modules/packages/default.nix | 2 + modules/packages/fmo-tool/default.nix | 5 + modules/packages/fmo-tool/fmo-tool.nix | 42 +++++++ modules/packages/vhotplug/default.nix | 5 + modules/packages/vhotplug/qemuqmp.nix | 28 +++++ modules/packages/vhotplug/vhotplug.nix | 28 +++++ modules/virtualization/microvm/vm.nix | 6 + utils/default.nix | 2 + utils/fmo-tools/fmo-config/default.nix | 113 ++++++++++++++++++ utils/fmo-tools/fmo-hyper-module-list.nix | 13 ++ 22 files changed, 593 insertions(+), 53 deletions(-) create mode 100644 modules/fmo-services/dynamic-device-passthrough-service-host/default.nix create mode 100644 modules/fmo-services/dynamic-device-passthrough-service/default.nix create mode 100644 modules/fmo-services/dynamic-portforwarding-service-host/default.nix create mode 100644 modules/fmo-services/dynamic-portforwarding-service/default.nix rename modules/fmo-services/{default.nix => host-services.nix} (65%) create mode 100644 modules/fmo-services/vm-services.nix create mode 100644 modules/packages/fmo-tool/default.nix create mode 100644 modules/packages/fmo-tool/fmo-tool.nix create mode 100644 modules/packages/vhotplug/default.nix create mode 100644 modules/packages/vhotplug/qemuqmp.nix create mode 100644 modules/packages/vhotplug/vhotplug.nix create mode 100644 utils/fmo-tools/fmo-config/default.nix create mode 100644 utils/fmo-tools/fmo-hyper-module-list.nix diff --git a/config-processor-hardware.nix b/config-processor-hardware.nix index a4fb5e9..7f45f3f 100644 --- a/config-processor-hardware.nix +++ b/config-processor-hardware.nix @@ -5,16 +5,12 @@ self, lib, ghafOS, -}: { - sysconf, -}: +}: sysconf: let - inherit (import ./utils {inherit lib self ghafOS;}) updateAttrs updateHostConfig addCustomLaunchers addSystemPackages importvm; - - targetconf = if lib.hasAttr "extend" sysconf - then updateAttrs false (import (lib.path.append ./hardware sysconf.extend) ).sysconf sysconf - else sysconf; + inherit (import ./utils {inherit lib self ghafOS;}) + updateAttrs updateHostConfig addCustomLaunchers addSystemPackages importvm generateFMOToolConfig; + targetconf = sysconf; name = targetconf.name; system = "x86_64-linux"; @@ -47,10 +43,11 @@ let ]; } ] - ++ (addCustomLaunchers targetconf.launchers) - ++ (addSystemPackages targetconf.systemPackages) - ++ (importvm targetconf.vms) - ++ (updateHostConfig targetconf) + ++ (addCustomLaunchers targetconf.launchers) + ++ (addSystemPackages targetconf.systemPackages) + ++ (importvm targetconf.vms) + ++ (updateHostConfig targetconf) + ++ (generateFMOToolConfig targetconf) ++ (if lib.hasAttr "extraModules" targetconf then targetconf.extraModules else []); }; in { diff --git a/config-processor-installers.nix b/config-processor-installers.nix index 04f79ad..d1d2d32 100644 --- a/config-processor-installers.nix +++ b/config-processor-installers.nix @@ -5,9 +5,7 @@ self, lib, ghafOS, -}: { - sysconf, -}: +}: sysconf: let inherit (import ./utils {inherit lib self ghafOS;}) updateAttrs addSystemPackages; @@ -15,10 +13,7 @@ let oss_list_name = "installer_os_list"; oss_list_path = "/etc/${oss_list_name}"; - installerconf = if lib.hasAttr "extend" sysconf - then updateAttrs false (import (lib.path.append ./installers sysconf.extend) ).sysconf sysconf - else sysconf; - + installerconf = sysconf; installerApp = inst_app: let installers = (builtins.removeAttrs inst_app ["name"]) // diff --git a/flake.nix b/flake.nix index 110bee2..6673936 100644 --- a/flake.nix +++ b/flake.nix @@ -21,11 +21,7 @@ outputs = inputs @ {ghafOS, self, ...}: let # Retrieve inputs from Ghaf nixpkgs = ghafOS.inputs.nixpkgs; - flake-utils = ghafOS.inputs.flake-utils; flake-parts = ghafOS.inputs.flake-parts; - systems = with flake-utils.lib.system; [ - x86_64-linux - ]; lib = nixpkgs.lib.extend (final: _prev: { ghaf = import "${ghafOS}/lib" { @@ -34,10 +30,24 @@ }; }); + hwConfigs = [ + (import ./hardware/fmo-os-rugged-laptop-7330.nix) + (import ./hardware/fmo-os-rugged-laptop-7330-public.nix) + (import ./hardware/fmo-os-rugged-tablet-7230.nix) + (import ./hardware/fmo-os-rugged-tablet-7230-public.nix) + ]; + instConfigs = [ + (import ./installers/fmo-os-installer.nix) + (import ./installers/fmo-os-installer-public.nix) + ]; + updateAttrs = (import ./utils/updateAttrs.nix).updateAttrs; + inheritConfig = confPath: { sysconf }: if lib.hasAttr "extend" sysconf + then updateAttrs false (import (lib.path.append confPath sysconf.extend) ).sysconf sysconf + else sysconf; generateHwConfig = import ./config-processor-hardware.nix {inherit ghafOS self lib;}; generateInstConfig = import ./config-processor-installers.nix {inherit ghafOS self lib;}; + in - flake-parts.lib.mkFlake { inherit inputs; @@ -53,15 +63,8 @@ imports = [ ./hydrajobs/flake-module.nix ./modules/flake-module.nix - ] ++ map generateHwConfig [ - (import ./hardware/fmo-os-rugged-laptop-7330.nix) - (import ./hardware/fmo-os-rugged-laptop-7330-public.nix) - (import ./hardware/fmo-os-rugged-tablet-7230.nix) - (import ./hardware/fmo-os-rugged-tablet-7230-public.nix) - ] ++ map generateInstConfig [ - (import ./installers/fmo-os-installer.nix) - (import ./installers/fmo-os-installer-public.nix) - ]; + ] ++ map generateHwConfig (map (conf: inheritConfig ./hardware conf) hwConfigs) + ++ map generateInstConfig (map (conf: inheritConfig ./installers conf) instConfigs); flake.lib = lib; }; diff --git a/hardware/fmo-os-rugged-laptop-7330.nix b/hardware/fmo-os-rugged-laptop-7330.nix index 6327e9d..a677f6e 100644 --- a/hardware/fmo-os-rugged-laptop-7330.nix +++ b/hardware/fmo-os-rugged-laptop-7330.nix @@ -7,6 +7,11 @@ name = "fmo-os-rugged-laptop-7330"; ipaddr = "192.168.101.2"; defaultgw = "192.168.101.1"; + release = "v1.1.0a"; + + fmo-system = { + RAversion = "v0.8.4"; + }; systemPackages = [ "vim" @@ -36,8 +41,20 @@ services = { fmo-psk-distribution-service-host = { - enable = true; - }; + enable = true; + }; # fmo-psk-distribution-service-host + fmo-dynamic-portforwarding-service-host = { + enable = true; + config-paths = { + netvm = "/var/netvm/netconf/dpf.config"; + }; + }; # services.dynamic-portforwarding-service + fmo-dynamic-device-passthrough-service-host = { + enable = true; + }; # services.dynamic-device-passthrough-service-host + fmo-config = { + enable = true; + }; # services.fmo-config registration-agent-laptop = { enable = true; }; # services.registration-agent-laptop @@ -100,12 +117,13 @@ fmo-psk-distribution-service-vm = { enable = true; - }; + }; # services.fmo-psk-distribution-service-vm - portforwarding-service = { + dynamic-portforwarding-service = { enable = true; ipaddress = "192.168.100.12"; ipaddress-path = "/etc/NetworkManager/system-connections/ip-address"; + config-path = "/etc/NetworkManager/system-connections/dpf.config"; configuration = [ { dip = "192.168.101.11"; @@ -143,8 +161,20 @@ sport = "7423"; proto = "tcp"; } + { + dip = "192.168.101.11"; + dport = "123"; + sport = "123"; + proto = "udp"; + } + { + dip = "192.168.101.11"; + dport = "123"; + sport = "123"; + proto = "tcp"; + } ]; - }; # services.portforwarding-service; + }; # services.dynamic-portforwarding-service }; # services microvm = { @@ -287,13 +317,32 @@ proto = "virtiofs"; socket = "fogdata.sock"; } + { + tag = "ssh-public-key"; + source = "/run/ssh-public-key"; + mountPoint = "/run/ssh-public-key"; + } ]; # microvm.shares };# microvm + fileSystems."/run/ssh-public-key".options = ["ro"]; services = { fmo-hostname-service = { enable = true; hostname-path = "/var/lib/fogdata/hostname"; }; # services.fmo-hostnam-service + fmo-psk-distribution-service-vm = { + enable = true; + }; # services.fmo-psk-distribution-service-vm + fmo-dynamic-device-passthrough = { + enable = true; + devices = [ + { + bus = "usb"; + vendorid = "1546"; + productid = "01a9"; + } + ]; + }; # services.fmo-dynamic-device-passthrough fmo-dci = { enable = true; compose-path = "/var/lib/fogdata/docker-compose.yml"; diff --git a/hardware/fmo-os-rugged-tablet-7230.nix b/hardware/fmo-os-rugged-tablet-7230.nix index f8431b7..e6b27d6 100644 --- a/hardware/fmo-os-rugged-tablet-7230.nix +++ b/hardware/fmo-os-rugged-tablet-7230.nix @@ -7,6 +7,11 @@ name = "fmo-os-rugged-tablet-7230"; ipaddr = "192.168.101.2"; defaultgw = "192.168.101.1"; + release = "v1.1.0a"; + + fmo-system = { + RAversion = "v0.8.4"; + }; systemPackages = [ "vim" @@ -36,8 +41,20 @@ services = { fmo-psk-distribution-service-host = { - enable = true; + enable = true; }; # services.fmo-psk-distribution-service-host + fmo-dynamic-portforwarding-service-host = { + enable = true; + config-paths = { + netvm = "/var/netvm/netconf/dpf.config"; + }; + }; # services.dynamic-portforwarding-service + fmo-dynamic-device-passthrough-service-host = { + enable = true; + }; # services.dynamic-device-passthrough-service-host + fmo-config = { + enable = true; + }; # services.fmo-config registration-agent-laptop = { enable = true; }; # services.registration-agent-laptop @@ -100,12 +117,13 @@ fmo-psk-distribution-service-vm = { enable = true; - }; + }; # services.fmo-psk-distribution-service-vm - portforwarding-service = { + dynamic-portforwarding-service = { enable = true; ipaddress = "192.168.100.12"; ipaddress-path = "/etc/NetworkManager/system-connections/ip-address"; + config-path = "/etc/NetworkManager/system-connections/dpf.config"; configuration = [ { dip = "192.168.101.11"; @@ -143,6 +161,18 @@ sport = "7423"; proto = "tcp"; } + { + dip = "192.168.101.11"; + dport = "123"; + sport = "123"; + proto = "udp"; + } + { + dip = "192.168.101.11"; + dport = "123"; + sport = "123"; + proto = "tcp"; + } ]; }; # services.portforwarding-service; }; # services @@ -268,13 +298,32 @@ proto = "virtiofs"; socket = "fogdata.sock"; } + { + tag = "ssh-public-key"; + source = "/run/ssh-public-key"; + mountPoint = "/run/ssh-public-key"; + } ]; # microvm.shares };# microvm + fileSystems."/run/ssh-public-key".options = ["ro"]; services = { fmo-hostname-service = { enable = true; hostname-path = "/var/lib/fogdata/hostname"; }; # services.fmo-hostnam-service + fmo-psk-distribution-service-vm = { + enable = true; + }; # services.fmo-psk-distribution-service-vm + fmo-dynamic-device-passthrough = { + enable = true; + devices = [ + { + bus = "usb"; + vendorid = "1546"; + productid = "01a9"; + } + ]; + }; # services.fmo-dynamic-device-passthrough fmo-dci = { enable = true; compose-path = "/var/lib/fogdata/docker-compose.yml"; diff --git a/modules/flake-module.nix b/modules/flake-module.nix index 15bab70..fa511d8 100644 --- a/modules/flake-module.nix +++ b/modules/flake-module.nix @@ -4,13 +4,28 @@ # {inputs, ...}: { flake.nixosModules = { + # Common fmo services/ultilities + fmo-common.imports = [ + inputs.ghafOS.nixosModules.common + ./packages + ../utils/write-to-file + ]; + + # fmo services/ultilities that runs only on host fmo-host.imports = [ inputs.ghafOS.nixosModules.hw-x86_64-generic inputs.ghafOS.nixosModules.host inputs.ghafOS.nixosModules.desktop + ./fmo-services/host-services.nix ./profiles/x86.nix ./desktop ]; + + # fmo services/ultilities that runs only on VMs + fmo-vm.imports = [ + ./fmo-services/vm-services.nix + ]; + microvm.imports = [ inputs.ghafOS.inputs.microvm.nixosModules.host (import "${inputs.ghafOS}/modules/microvm/networking.nix") @@ -20,14 +35,9 @@ # JIRA: FMO-43 for monitoring this issue. (import "${inputs.ghafOS}/modules/microvm/virtualization/microvm/audiovm.nix") ]; - fmo-common.imports = [ - inputs.ghafOS.nixosModules.common - ./packages - ./fmo-services - ../utils/write-to-file - ]; installer.imports = [ ./installers + ./fmo-services/registration-agent-laptop ]; }; -} \ No newline at end of file +} diff --git a/modules/fmo-services/dynamic-device-passthrough-service-host/default.nix b/modules/fmo-services/dynamic-device-passthrough-service-host/default.nix new file mode 100644 index 0000000..1a9cb31 --- /dev/null +++ b/modules/fmo-services/dynamic-device-passthrough-service-host/default.nix @@ -0,0 +1,32 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ lib, pkgs, config, ... }: +with lib; +let + cfg = config.services.fmo-dynamic-device-passthrough-service-host; +in { + options.services.fmo-dynamic-device-passthrough-service-host = { + enable = mkEnableOption "FMO dynamic device passthrough service"; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.vhotplug ]; + + services.udev.extraRules = '' + SUBSYSTEM=="usb", GROUP="kvm" + KERNEL=="event*", GROUP="kvm" + ''; + + systemd.services."fmo-dynamic-device-passthrough-service" = { + script = '' + ${pkgs.fmo-tool}/bin/fmo-tool ddp generate + ${pkgs.vhotplug}/bin/vhotplug -a -c /var/host/vmddp.conf + ''; + serviceConfig = { + Type = "simple"; + RemainAfterExit = true; + }; + wantedBy = [ "multi-user.target" ]; + }; + }; +} diff --git a/modules/fmo-services/dynamic-device-passthrough-service/default.nix b/modules/fmo-services/dynamic-device-passthrough-service/default.nix new file mode 100644 index 0000000..debceed --- /dev/null +++ b/modules/fmo-services/dynamic-device-passthrough-service/default.nix @@ -0,0 +1,23 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ lib, pkgs, config, ... }: +with lib; +let + cfg = config.services.fmo-dynamic-device-passthrough; +in { + options.services.fmo-dynamic-device-passthrough = { + enable = mkEnableOption "FMO dynamic device passthrough devices"; + + devices = mkOption { + type = types.listOf types.attrs; + description = '' + Device list to passthrough + { + bus = bus type "usb | pci", only usb is valid for now, + vendorid = vendorid for device, + productid = productid for device, + } + ''; + }; + }; +} diff --git a/modules/fmo-services/dynamic-portforwarding-service-host/default.nix b/modules/fmo-services/dynamic-portforwarding-service-host/default.nix new file mode 100644 index 0000000..e029b86 --- /dev/null +++ b/modules/fmo-services/dynamic-portforwarding-service-host/default.nix @@ -0,0 +1,33 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ lib, pkgs, config, ... }: +with lib; +let + cfg = config.services.fmo-dynamic-portforwarding-service-host; + + mkPortForwardingRules = vmname: path: '' + ${pkgs.fmo-tool}/bin/fmo-tool dpf rules -r ${vmname} > ${path} + + ''; +in { + options.services.fmo-dynamic-portforwarding-service-host = { + enable = mkEnableOption "fmo-dynamic-portforwarding-service-host"; + + config-paths = mkOption { + type = types.attrsOf types.str; + description = ""; + default = {}; + }; + }; + + config = mkIf cfg.enable { + ### host part ### + systemd.services.fmo-generate-dynamic-portforwarding-rules = { + script = '' + ${ lib.concatStrings (lib.attrsets.attrValues (lib.attrsets.mapAttrs (name: value: mkPortForwardingRules name value) cfg.config-paths)) } + ''; + + wantedBy = ["network.target"]; + }; + }; +} diff --git a/modules/fmo-services/dynamic-portforwarding-service/default.nix b/modules/fmo-services/dynamic-portforwarding-service/default.nix new file mode 100644 index 0000000..ae7ac11 --- /dev/null +++ b/modules/fmo-services/dynamic-portforwarding-service/default.nix @@ -0,0 +1,92 @@ +# Copyright 2022-2023 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ lib, pkgs, config, ... }: +with lib; +let + cfg = config.services.dynamic-portforwarding-service; + +in { + options.services.dynamic-portforwarding-service = { + enable = mkEnableOption "dynamic-portforwarding-service"; + + ipaddress-path = mkOption { + type = types.str; + description = "Path to ipaddress file for dynamic use"; + default = ""; + }; + + config-path = mkOption { + type = types.str; + description = "Path to dynamic configuraiton config"; + default = ""; + }; + + ipaddress = mkOption { + type = types.str; + description = "Static IP address to use instead for dynamic from file"; + default = ""; + }; + + configuration = mkOption { + type = types.listOf types.attrs; + description = '' + List of + { + dip = destanation IP address, + sport = source port, + dport = destanation port, + proto = protocol (udp, tcp) + } + ''; + }; + + }; + + config = mkIf cfg.enable { + systemd.services.fmo-dynamic-portforwarding-service = { + script = '' + CHAIN_N="fmo-os-fw" + IP=$(${pkgs.gawk}/bin/gawk '{print $1}' ${cfg.ipaddress-path} || echo ${cfg.ipaddress}) + sync + lines=$(cat ${cfg.config-path}) + + # Delete old rules if exist + while ${pkgs.iptables}/bin/iptables -L $CHAIN_N -n --line-numbers | grep -q -E '^[0-9]+'; do + ${pkgs.iptables}/bin/iptables -D $CHAIN_N 1 || echo "$CHAIN_N rule 1 does not exist. skip.." + done + + while ${pkgs.iptables}/bin/iptables -t nat -L $CHAIN_N -n --line-numbers | grep -q -E '^[0-9]+'; do + ${pkgs.iptables}/bin/iptables -t nat -D $CHAIN_N 1 || echo "$CHAIN_N -t nat rule 1 does not exist. skip.." + done + + # Delete old chains + ${pkgs.iptables}/bin/iptables -D INPUT -j $CHAIN_N || echo "chain does not exist. skip.." + ${pkgs.iptables}/bin/iptables -t nat -D PREROUTING -j $CHAIN_N || echo "chain does not exist. skip.." + ${pkgs.iptables}/bin/iptables -X $CHAIN_N || echo "chain does not exist. skip.." + ${pkgs.iptables}/bin/iptables -t nat -X $CHAIN_N || echo "chain does not exist. skip.." + + # Create new chains + ${pkgs.iptables}/bin/iptables -N $CHAIN_N + ${pkgs.iptables}/bin/iptables -t nat -N $CHAIN_N + ${pkgs.iptables}/bin/iptables -I INPUT -j $CHAIN_N + ${pkgs.iptables}/bin/iptables -t nat -I PREROUTING -j $CHAIN_N + + # Add new rules + while IFS= read -r line; do + SRC_IP=$(echo $line | ${pkgs.gawk}/bin/gawk '{print $1}') + SRC_PORT=$(echo $line | ${pkgs.gawk}/bin/gawk '{print $2}') + DST_PORT=$(echo $line | ${pkgs.gawk}/bin/gawk '{print $3}') + DST_IP=$(echo $line | ${pkgs.gawk}/bin/gawk '{print $4}') + PROTO=$(echo $line | ${pkgs.gawk}/bin/gawk '{print $5}') + SRC_IP=$([[ "$SRC_IP" = "NA" ]] && echo $IP || echo $SRC_IP) + + echo "Apply a new port forwarding: $SRC_IP:$SRC_PORT to $DST_IP:$DST_PORT proto: $PROTO" + ${pkgs.iptables}/bin/iptables -I $CHAIN_N -p $PROTO --dport $SRC_PORT -j ACCEPT + ${pkgs.iptables}/bin/iptables -t nat -I $CHAIN_N -p $PROTO -d $SRC_IP --dport $SRC_PORT -j DNAT --to-destination $DST_IP:$DST_PORT + done <<< "$lines" + ''; + + wantedBy = ["network.target"]; + }; + }; +} diff --git a/modules/fmo-services/default.nix b/modules/fmo-services/host-services.nix similarity index 65% rename from modules/fmo-services/default.nix rename to modules/fmo-services/host-services.nix index fa9694f..c47d757 100644 --- a/modules/fmo-services/default.nix +++ b/modules/fmo-services/host-services.nix @@ -5,11 +5,9 @@ # { imports = [ - ./dci-service - ./hostname-service - ./portforwarding-service ./psk-distribution-host - ./psk-distribution-vm + ./dynamic-portforwarding-service-host + ./dynamic-device-passthrough-service-host ./registration-agent-laptop - ]; + ]; } diff --git a/modules/fmo-services/vm-services.nix b/modules/fmo-services/vm-services.nix new file mode 100644 index 0000000..20e7d3e --- /dev/null +++ b/modules/fmo-services/vm-services.nix @@ -0,0 +1,15 @@ +# Copyright 2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +# +# Services for FMO +# +{ + imports = [ + ./dci-service + ./hostname-service + ./dynamic-portforwarding-service + ./dynamic-device-passthrough-service + ./psk-distribution-vm + ./registration-agent-laptop + ]; +} diff --git a/modules/packages/default.nix b/modules/packages/default.nix index 087a86a..4471d7f 100644 --- a/modules/packages/default.nix +++ b/modules/packages/default.nix @@ -5,6 +5,7 @@ # _: { nixpkgs.overlays = [ + (import ./fmo-tool) (import ./lisgd) (import ./nmLauncher) (import ./nwg-panel) @@ -13,5 +14,6 @@ _: { (import ./squeekboard) (import ./sway-scripts) (import ./terminator) + (import ./vhotplug) ]; } diff --git a/modules/packages/fmo-tool/default.nix b/modules/packages/fmo-tool/default.nix new file mode 100644 index 0000000..24f1f33 --- /dev/null +++ b/modules/packages/fmo-tool/default.nix @@ -0,0 +1,5 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +(final: _prev: { + fmo-tool = _prev.callPackage ./fmo-tool.nix {}; +}) diff --git a/modules/packages/fmo-tool/fmo-tool.nix b/modules/packages/fmo-tool/fmo-tool.nix new file mode 100644 index 0000000..15f9255 --- /dev/null +++ b/modules/packages/fmo-tool/fmo-tool.nix @@ -0,0 +1,42 @@ +{ pkgs }: + +pkgs.python310Packages.buildPythonApplication { + pname = "fmo-tool"; + version = "0.0.1"; + + build-system = with pkgs.python310Packages; [ + setuptools + wheel + ]; + + dependencies = with pkgs.python310Packages; [ + typer + colorama + shellingham + pytest +# typing_extensions + pyyaml + paramiko +# py3compat + rich + ]; + + propagatedBuildInputs = with pkgs.python310Packages; [ + (pkgs.python310.withPackages (ps: with ps; [ pip ])) + typer + colorama + shellingham + pytest + # typing_extensions + pyyaml + paramiko + # py3compat + rich + ]; + + src = builtins.fetchGit { + url = "git@github.com:tiiuae/fmo-tool.git"; + rev = "4cdb772a104893ecf2d15333bad0f335040c3be9"; + ref = "refs/heads/integrate_ddp"; + }; +} diff --git a/modules/packages/vhotplug/default.nix b/modules/packages/vhotplug/default.nix new file mode 100644 index 0000000..473b12b --- /dev/null +++ b/modules/packages/vhotplug/default.nix @@ -0,0 +1,5 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +(final: _prev: { + vhotplug = final.callPackage ./vhotplug.nix {}; +}) diff --git a/modules/packages/vhotplug/qemuqmp.nix b/modules/packages/vhotplug/qemuqmp.nix new file mode 100644 index 0000000..55da9cd --- /dev/null +++ b/modules/packages/vhotplug/qemuqmp.nix @@ -0,0 +1,28 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + python3Packages, + fetchPypi, + lib, +}: +python3Packages.buildPythonPackage rec { + pname = "qemu.qmp"; + version = "0.0.3"; + + src = fetchPypi { + inherit pname version; + sha256 = "sha256-y8iPvMEV7pQ9hER9FyxkLaEgIgRRQWwvYhrPM98eEBA="; + }; + + pyproject = true; + + nativeBuildInputs = [ + python3Packages.setuptools-scm + ]; + + meta = { + homepage = "https://www.qemu.org/"; + description = "QEMU Monitor Protocol library"; + license = lib.licenses.lgpl2Plus; + }; +} diff --git a/modules/packages/vhotplug/vhotplug.nix b/modules/packages/vhotplug/vhotplug.nix new file mode 100644 index 0000000..ac34c1f --- /dev/null +++ b/modules/packages/vhotplug/vhotplug.nix @@ -0,0 +1,28 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + python3Packages, + pkgs, + fetchFromGitHub, +}: let + qemuqmp = pkgs.callPackage ./qemuqmp.nix {}; +in + python3Packages.buildPythonApplication rec { + pname = "vhotplug"; + version = "0.1"; + + propagatedBuildInputs = [ + python3Packages.pyudev + python3Packages.psutil + qemuqmp + ]; + + doCheck = false; + + src = fetchFromGitHub { + owner = "tiiuae"; + repo = "vhotplug"; + rev = "fd05361ed893d06cdb5ac4a538c171e4a86b6f5a"; + hash = "sha256-6fl5xeSpcIIBKn3dZUAEHiNRRpn9LbYC4Imap5KBH2M="; + }; + } diff --git a/modules/virtualization/microvm/vm.nix b/modules/virtualization/microvm/vm.nix index df2ba4e..66a1704 100644 --- a/modules/virtualization/microvm/vm.nix +++ b/modules/virtualization/microvm/vm.nix @@ -33,6 +33,7 @@ nixpkgs.hostPlatform.system = configHost.nixpkgs.hostPlatform.system; microvm.hypervisor = "qemu"; + microvm.optimize.enable = false; networking = { enableIPv6 = false; @@ -61,6 +62,10 @@ mountPoint = "/nix/.ro-store"; } ]; # microvm.shares + microvm.qemu.extraArgs = [ + "-device" + "qemu-xhci" + ]; microvm.writableStoreOverlay = lib.mkIf config.ghaf.development.debug.tools.enable "/nix/.rw-store"; networking.nat = { @@ -98,6 +103,7 @@ }) addSystemPackages self.nixosModules.fmo-common + self.nixosModules.fmo-vm ]; }; cfg = config.ghaf.virtualization.microvm.${vmconf.name}; diff --git a/utils/default.nix b/utils/default.nix index c5cbec1..b609e93 100644 --- a/utils/default.nix +++ b/utils/default.nix @@ -10,4 +10,6 @@ addCustomLaunchers = (launchers: [{ghaf.graphics.app-launchers.enabled-launchers = launchers;}]); importvm = (vms: (map (vm: (import ../modules/virtualization/microvm/vm.nix {inherit ghafOS self; vmconf=vms.${vm};}) ) (builtins.attrNames vms))); + + generateFMOToolConfig = (import ./fmo-tools/fmo-hyper-module-list.nix); } diff --git a/utils/fmo-tools/fmo-config/default.nix b/utils/fmo-tools/fmo-config/default.nix new file mode 100644 index 0000000..c1dd25a --- /dev/null +++ b/utils/fmo-tools/fmo-config/default.nix @@ -0,0 +1,113 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ targetconf }: +{ lib, pkgs, config, ... }: +with lib; +let + cfg = config.services.fmo-config; + + hyperConfigServices = { + dynamic-portforwarding-service = {}; + monitoring-service = {}; + fmo-dynamic-device-passthrough = {}; + fmo-dci = {}; + }; + + hyperConfigExtraModules = { + services = getConfig hyperConfigServices {}; + }; + + hyperConfigVM = { + name = "Unknown"; + ipaddr = "Unknow"; + extraModules = getConfigMerged hyperConfigExtraModules {}; + }; + + hyperConfigFMOSystem = { + alias = "NA"; + ipaddr = "NA"; + defaultGW = "NA"; + dockerCR = "NA"; + RAversion = "NA"; + }; + + hyperConfigSystem = { + name = "Unknown"; + release = "Unknown"; + vms = getConfigTarget hyperConfigVM {}; + fmo-system = getConfig hyperConfigFMOSystem hyperConfigFMOSystem; + }; + + getConfigTarget = config: default: target: field: ( + if lib.hasAttr "${field}" target + then + let + newtarget = target.${field}; + in + listToAttrs ( + map ( + attr: + { + name = "${attr}"; + value = getConfig config default newtarget attr; + } + ) (builtins.attrNames newtarget) + ) + else + default + ); + + getConfigMerged = config: default: target: field: ( + if lib.hasAttr "${field}" target + then + let + newtarget = target.${field}; + merged = builtins.foldl' (acc: elem: acc // elem) {} target.${field}; + in + getConfig config default { "${field}" = merged; } field + else + default + ); + + + getConfig = config: default: target: field: ( + if lib.hasAttr "${field}" target + then + let + newtarget = target.${field}; + in + listToAttrs ( + map ( + attr: + { + name = "${attr}"; + value = if builtins.typeOf config.${attr} == "lambda" + then + config.${attr} newtarget attr + else + ifHasAttr newtarget "${attr}" config.${attr}; + } + ) (builtins.attrNames config) + ) + else + default + ); + + hyperSystemConfig = getConfig hyperConfigSystem {} { inherit targetconf; } "targetconf"; + + ifHasAttr = set: attr: default: if lib.hasAttr "${attr}" set then set.${attr} else default; +in { + options.services.fmo-config = { + enable = mkEnableOption "FMO configuration store"; + + conf-path = mkOption { + type = types.str; + description = "Path to store config"; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.fmo-tool]; + environment.etc."fmo-config.yaml".source = (pkgs.formats.yaml { }).generate "fmo-config.yaml" hyperSystemConfig; + }; +} diff --git a/utils/fmo-tools/fmo-hyper-module-list.nix b/utils/fmo-tools/fmo-hyper-module-list.nix new file mode 100644 index 0000000..6e87ffb --- /dev/null +++ b/utils/fmo-tools/fmo-hyper-module-list.nix @@ -0,0 +1,13 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +# +# +(targetconf : +let + fmo-tools-list = + [ + ./fmo-config + ]; +in + map (module: (import module {inherit targetconf;})) fmo-tools-list +)