diff --git a/config-processor-hardware.nix b/config-processor-hardware.nix index 902a3b7..b167175 100644 --- a/config-processor-hardware.nix +++ b/config-processor-hardware.nix @@ -9,17 +9,9 @@ nixos-hardware, nixpkgs, microvm, -}: { - sysconf, -}: +}: sysconf: let - updateAttrs = (import ./utils/updateAttrs.nix).updateAttrs; - updateHostConfig = (import ./utils/updateHostConfig.nix).updateHostConfig; - - targetconf = if lib.hasAttr "extend" sysconf - then updateAttrs false (import (lib.path.append ./hardware sysconf.extend) ).sysconf sysconf - else sysconf; - + targetconf = sysconf; name = targetconf.name; system = "x86_64-linux"; vms = targetconf.vms; @@ -33,6 +25,7 @@ let }; addSystemPackages = {pkgs, ...}: {environment.systemPackages = map (app: pkgs.${app}) targetconf.systemPackages;}; addCustomLaunchers = { ghaf.graphics.app-launchers.enabled-launchers = targetconf.launchers; }; + updateHostConfig = (import ./utils/updateHostConfig.nix).updateHostConfig; formatModule = nixos-generators.nixosModules.raw-efi; target = variant: extraModules: let @@ -82,7 +75,8 @@ let ++ (import "${ghafOS}/modules/module-list.nix") ++ (import ./modules/fmo-module-list.nix) ++ extraModules - ++ (if lib.hasAttr "extraModules" targetconf then targetconf.extraModules else []); + ++ (if lib.hasAttr "extraModules" targetconf then targetconf.extraModules else []) + ++ (import ./modules/fmo-tools/fmo-hyper-module-list.nix {inherit targetconf;}); }; in { inherit hostConfiguration; diff --git a/config-processor-installers.nix b/config-processor-installers.nix index 1ec7a8e..28ff409 100644 --- a/config-processor-installers.nix +++ b/config-processor-installers.nix @@ -9,20 +9,14 @@ nixos-hardware, nixpkgs, microvm, -}: { - sysconf, -}: +}: sysconf: let - updateAttrs = (import ./utils/updateAttrs.nix).updateAttrs; oss = sysconf.oss; 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"]) // @@ -74,7 +68,7 @@ let addSystemPackages { - isoImage.squashfsCompression = "lz4"; + isoImage.squashfsCompression = "lz4"; } ] ++ (import ./modules/fmo-module-list.nix) diff --git a/flake.nix b/flake.nix index 8725008..c422df5 100644 --- a/flake.nix +++ b/flake.nix @@ -28,7 +28,6 @@ nixos-generators = ghafOS.inputs.nixos-generators; nixos-hardware = ghafOS.inputs.nixos-hardware; microvm = ghafOS.inputs.microvm; - systems = with flake-utils.lib.system; [ x86_64-linux ]; @@ -39,7 +38,21 @@ lib = final; }; }); - + + 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 nixpkgs ghafOS self nixos-hardware nixos-generators lib microvm;}; generateInstConfig = import ./config-processor-installers.nix {inherit nixpkgs ghafOS self nixos-hardware nixos-generators lib microvm;}; in @@ -63,15 +76,6 @@ formatter = pkgs.alejandra; })) - ] - ++ 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)); } diff --git a/hardware/fmo-os-rugged-laptop-7330.nix b/hardware/fmo-os-rugged-laptop-7330.nix index 278f6a6..eb76994 100644 --- a/hardware/fmo-os-rugged-laptop-7330.nix +++ b/hardware/fmo-os-rugged-laptop-7330.nix @@ -7,7 +7,11 @@ name = "fmo-os-rugged-laptop-7330"; ipaddr = "192.168.101.2"; defaultgw = "192.168.101.1"; + release = "v1.0.0a"; + fmo-system = { + RAversion = "v0.8.4"; + }; systemPackages = [ "vim" "tcpdump" @@ -36,8 +40,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; + }; # fmo-config registration-agent-laptop = { enable = true; }; # services.registration-agent-laptop @@ -100,12 +116,13 @@ fmo-psk-distribution-service-vm = { enable = true; - }; + }; # 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"; @@ -156,7 +173,7 @@ proto = "tcp"; } ]; - }; # services.portforwarding-service; + }; # services.dynamic-portforwarding-service }; # services microvm = { @@ -264,6 +281,16 @@ enable = true; hostname-path = "/var/lib/fogdata/hostname"; }; # services.fmo-hostnam-service + 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 fd3b2a7..4b9fcf2 100644 --- a/hardware/fmo-os-rugged-tablet-7230.nix +++ b/hardware/fmo-os-rugged-tablet-7230.nix @@ -7,7 +7,11 @@ name = "fmo-os-rugged-tablet-7230"; ipaddr = "192.168.101.2"; defaultgw = "192.168.101.1"; + release = "v1.0.0a"; + fmo-system = { + RAversion = "v0.8.4"; + }; systemPackages = [ "vim" "tcpdump" @@ -36,8 +40,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; + }; # fmo-config registration-agent-laptop = { enable = true; }; # services.registration-agent-laptop @@ -100,12 +116,13 @@ fmo-psk-distribution-service-vm = { enable = true; - }; + }; # 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"; @@ -156,7 +173,7 @@ proto = "tcp"; } ]; - }; # services.portforwarding-service; + }; # services.dynamic-portforwarding-service }; # services microvm = { @@ -244,6 +261,16 @@ enable = true; hostname-path = "/var/lib/fogdata/hostname"; }; # services.fmo-hostnam-service + 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/custom-packages/default.nix b/modules/custom-packages/default.nix index 9d61fd0..9f830b2 100644 --- a/modules/custom-packages/default.nix +++ b/modules/custom-packages/default.nix @@ -14,5 +14,7 @@ _: { (import ./squeekboard) (import ./sway-scripts) (import ./terminator) + (import ./fmo-tool) + (import ./vhotplug) ]; } diff --git a/modules/custom-packages/fmo-tool/default.nix b/modules/custom-packages/fmo-tool/default.nix new file mode 100644 index 0000000..8bde0f3 --- /dev/null +++ b/modules/custom-packages/fmo-tool/default.nix @@ -0,0 +1,6 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +(final: _prev: { + fmo-tool = _prev.callPackage ./fmo-tool.nix {}; + typer = _prev.callPackage ./typer.nix {}; +}) diff --git a/modules/custom-packages/fmo-tool/fmo-tool.nix b/modules/custom-packages/fmo-tool/fmo-tool.nix new file mode 100644 index 0000000..9522f55 --- /dev/null +++ b/modules/custom-packages/fmo-tool/fmo-tool.nix @@ -0,0 +1,49 @@ +{ pkgs }: +let + # WAR: This is because current typer and paramiko dependencies are old versions, + # Solve by manually build newer versions of the packages + # Will be remove in new version of nixpkgs (with pkgs.python3Packages) + typer = pkgs.callPackage ./typer.nix {}; + paramiko = pkgs.callPackage ./paramiko.nix {}; +in + +pkgs.python3Packages.buildPythonApplication { + pname = "fmo-tool"; + version = "0.0.1"; + + build-system = with pkgs.python3Packages; [ + setuptools + wheel + ]; + + dependencies = with pkgs.python3Packages; [ + typer + colorama + shellingham + pytest + typing-extensions + pyyaml + paramiko +# py3compat + rich + ]; + + propagatedBuildInputs = with pkgs.python3Packages; [ + (pkgs.python3.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 = "40ca851d4f51af7ecf48939394609c6520b5d549"; + ref = "refs/heads/integrate_ddp"; + }; +} diff --git a/modules/custom-packages/fmo-tool/paramiko.nix b/modules/custom-packages/fmo-tool/paramiko.nix new file mode 100644 index 0000000..292490c --- /dev/null +++ b/modules/custom-packages/fmo-tool/paramiko.nix @@ -0,0 +1,80 @@ +{ + lib, + python3Packages, + fetchpatch, + fetchPypi, +}: + +python3Packages.buildPythonPackage rec { + pname = "paramiko"; + version = "3.4.0"; + format = "setuptools"; + + src = fetchPypi { + inherit pname version; + hash = "sha256-qsCPJqMdxN/9koIVJ9FoLZnVL572hRloEUqHKPPCdNM="; + }; + + patches = [ + # Fix usage of dsa keys + # https://github.com/paramiko/paramiko/pull/1606/ + (fetchpatch { + url = "https://github.com/paramiko/paramiko/commit/18e38b99f515056071fb27b9c1a4f472005c324a.patch"; + hash = "sha256-bPDghPeLo3NiOg+JwD5CJRRLv2VEqmSx1rOF2Tf8ZDA="; + }) + (fetchpatch { + name = "paramiko-pytest8-compat.patch"; + url = "https://github.com/paramiko/paramiko/commit/d71046151d9904df467ff72709585cde39cdd4ca.patch"; + hash = "sha256-4CTIZ9BmzRdh+HOwxSzfM9wkUGJOnndctK5swqqsIvU="; + }) + ]; + + propagatedBuildInputs = with python3Packages;[ + bcrypt + cryptography + pyasn1 + six + ] ++ passthru.optional-dependencies.ed25519; # remove on 3.0 update + + passthru.optional-dependencies = { + gssapi = with python3Packages;[ + pyasn1 + gssapi + ]; + ed25519 = with python3Packages;[ + pynacl + bcrypt + ]; + invoke = with python3Packages;[ invoke ]; + }; + + nativeCheckInputs = with python3Packages;[ + icecream + mock + pytestCheckHook + ] ++ lib.flatten (builtins.attrValues passthru.optional-dependencies); + + disabledTestPaths = [ + # disable tests that require pytest-relaxed, which is broken + "tests/test_client.py" + "tests/test_ssh_gss.py" + ]; + + pythonImportsCheck = [ "paramiko" ]; + + __darwinAllowLocalNetworking = true; + + meta = with lib; { + homepage = "https://github.com/paramiko/paramiko/"; + changelog = "https://github.com/paramiko/paramiko/blob/${version}/sites/www/changelog.rst"; + description = "Native Python SSHv2 protocol library"; + license = licenses.lgpl21Plus; + longDescription = '' + Library for making SSH2 connections (client or server). Emphasis is + on using SSH2 as an alternative to SSL for making secure connections + between python scripts. All major ciphers and hash methods are + supported. SFTP client and server mode are both supported too. + ''; + maintainers = with maintainers; [ ]; + }; +} diff --git a/modules/custom-packages/fmo-tool/typer.nix b/modules/custom-packages/fmo-tool/typer.nix new file mode 100644 index 0000000..2590ff3 --- /dev/null +++ b/modules/custom-packages/fmo-tool/typer.nix @@ -0,0 +1,61 @@ +{ + lib, + stdenv, + python3Packages, + fetchPypi, +}: + +python3Packages.buildPythonPackage rec { + pname = "typer"; + version = "0.12.3"; + format = "pyproject"; + + src = fetchPypi { + inherit pname version; + hash = "sha256-SecxMUgdgEKI72JZjZehzu8wWJBapTahE0+QiRujVII="; + }; + + nativeBuildInputs = with python3Packages;[ pdm-backend ]; + + propagatedBuildInputs = with python3Packages;[ + click + typing-extensions + ]; + + passthru.optional-dependencies = { + all = with python3Packages;[ + colorama + shellingham + rich + ]; + }; + + nativeCheckInputs = with python3Packages;[ + coverage # execs coverage in tests + pytest-sugar + pytest-xdist + pytestCheckHook + ] ++ passthru.optional-dependencies.all; + + preCheck = '' + export HOME=$(mktemp -d); + ''; + + disabledTests = [ + "test_scripts" + # Likely related to https://github.com/sarugaku/shellingham/issues/35 + # fails also on Linux + "test_show_completion" + "test_install_completion" + ] ++ lib.optionals (stdenv.isLinux && stdenv.isAarch64) [ "test_install_completion" ]; + + pythonImportsCheck = [ "typer" ]; + + meta = with lib; { + description = "Library for building CLI applications"; + homepage = "https://typer.tiangolo.com/"; + changelog = "https://github.com/tiangolo/typer/releases/tag/${version}"; + license = licenses.mit; + maintainers = with maintainers; [ winpat ]; + }; +} diff --git a/modules/custom-packages/vhotplug/default.nix b/modules/custom-packages/vhotplug/default.nix new file mode 100644 index 0000000..473b12b --- /dev/null +++ b/modules/custom-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/custom-packages/vhotplug/qemuqmp.nix b/modules/custom-packages/vhotplug/qemuqmp.nix new file mode 100644 index 0000000..f8e6e13 --- /dev/null +++ b/modules/custom-packages/vhotplug/qemuqmp.nix @@ -0,0 +1,34 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + python3Packages, + fetchFromGitLab, + lib, +}: +python3Packages.buildPythonPackage rec { + pname = "qemu.qmp"; + version = "0.0.3"; + format = "pyproject"; + + src = fetchFromGitLab { + owner = "qemu-project"; + repo = "python-qemu-qmp"; + rev = "v${version}"; + hash = "sha256-NOtBea81hv+swJyx8Mv2MIqoK4/K5vyMiN12hhDEpJY="; + }; + + SETUPTOOLS_SCM_PRETEND_VERSION = version; + + nativeBuildInputs = with python3Packages;[ + setuptools + setuptools-scm + wheel + ]; + + pythonImportsCheck = [ "qemu.qmp" ]; + + meta = { + homepage = "https://www.qemu.org/"; + description = "QEMU Monitor Protocol library"; + }; +} diff --git a/modules/custom-packages/vhotplug/vhotplug.nix b/modules/custom-packages/vhotplug/vhotplug.nix new file mode 100644 index 0000000..ac34c1f --- /dev/null +++ b/modules/custom-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/dynamic-device-passthrough-services-host/default.nix b/modules/dynamic-device-passthrough-services-host/default.nix new file mode 100644 index 0000000..7349c5f --- /dev/null +++ b/modules/dynamic-device-passthrough-services-host/default.nix @@ -0,0 +1,34 @@ +# 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 = '' + if ! [ -f /var/host/vmddp.conf ]; then + ${pkgs.fmo-tool}/bin/fmo-tool ddp generate + fi + ${pkgs.vhotplug}/bin/vhotplug -a -c /var/host/vmddp.conf + ''; + serviceConfig = { + Type = "simple"; + RemainAfterExit = true; + }; + wantedBy = [ "multi-user.target" ]; + }; + }; +} diff --git a/modules/dynamic-device-passthrough-services/default.nix b/modules/dynamic-device-passthrough-services/default.nix new file mode 100644 index 0000000..debceed --- /dev/null +++ b/modules/dynamic-device-passthrough-services/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/dynamic-portforwarding-service-host/default.nix b/modules/dynamic-portforwarding-service-host/default.nix new file mode 100644 index 0000000..3b5bfc8 --- /dev/null +++ b/modules/dynamic-portforwarding-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-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/dynamic-portforwarding-service/default.nix b/modules/dynamic-portforwarding-service/default.nix new file mode 100644 index 0000000..ca3b508 --- /dev/null +++ b/modules/dynamic-portforwarding-service/default.nix @@ -0,0 +1,68 @@ +# 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 = '' + IP=$(${pkgs.gawk}/bin/gawk '{print $1}' ${cfg.ipaddress-path} || echo ${cfg.ipaddress}) + + 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 INPUT -p $PROTO --dport $SRC_PORT -j ACCEPT + ${pkgs.iptables}/bin/iptables -t nat -I PREROUTING -p $PROTO -d $SRC_IP --dport $SRC_PORT -j DNAT --to-destination $DST_IP:$DST_PORT + done < ${cfg.config-path} + ''; + + wantedBy = ["network.target"]; + }; + }; +} diff --git a/modules/fmo-module-list.nix b/modules/fmo-module-list.nix index 7d0796c..7f24386 100644 --- a/modules/fmo-module-list.nix +++ b/modules/fmo-module-list.nix @@ -18,4 +18,8 @@ ../utils/write-to-file ./fmo-psk-distribution-host ./fmo-psk-distribution-vm + ./dynamic-portforwarding-service + ./dynamic-portforwarding-service-host + ./dynamic-device-passthrough-services + ./dynamic-device-passthrough-services-host ] diff --git a/modules/fmo-tools/fmo-config/default.nix b/modules/fmo-tools/fmo-config/default.nix new file mode 100644 index 0000000..c1dd25a --- /dev/null +++ b/modules/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/modules/fmo-tools/fmo-hyper-module-list.nix b/modules/fmo-tools/fmo-hyper-module-list.nix new file mode 100644 index 0000000..55cb738 --- /dev/null +++ b/modules/fmo-tools/fmo-hyper-module-list.nix @@ -0,0 +1,12 @@ +# 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 diff --git a/modules/virtualization/microvm/vm.nix b/modules/virtualization/microvm/vm.nix index 7b4c7b7..cb10151 100644 --- a/modules/virtualization/microvm/vm.nix +++ b/modules/virtualization/microvm/vm.nix @@ -29,6 +29,7 @@ nixpkgs.hostPlatform.system = configHost.nixpkgs.hostPlatform.system; microvm.hypervisor = "qemu"; + #microvm.optimize.enable = false; networking = { enableIPv6 = false; @@ -47,6 +48,11 @@ } ]; + microvm.qemu.extraArgs = [ + "-device" + "qemu-xhci" + ]; + microvm.shares = [ # Use host's /nix/store to reduce size of the image # WAR: to enable -M q35 option need to share any fs or pcie devices