# SPDX-License-Identifier: CC0-1.0 { self }: { config, pkgs, lib, ... }: { options.genodeGuests = with lib; with lib.types; let genodeOpts = { ... }: { options = { name = mkOption { example = "webserver"; type = str; description = "Name of the Genode subsystem."; }; config = mkOption { type = oneOf [ str path ]; example = '' let Genode = env:DHALL_GENODE in Genode.Init::{=} ''; description = '' Configuration of the Genode subsystem in Dhall. The type of the expression must be Genode.Init.Type, where the Genode is library available at env:DHALL_GENODE. ''; }; rom = mkOption { default = pkgs: { }; description = '' Function taking a package set and returning an attrset of name to store path mappings. Note that this set is the Nixpkgs collection, the native Genode packages are found within this set at "genodePackages". ''; example = literalExample '' pkgs: { nic_drv = "${pkgs.genodePackages.linux_nic_drv}/bin/linux_nic_drv"; } ''; }; nics = mkOption { type = with types; listOf str; default = [ ]; example = [ "tap0" "tap1" ]; description = '' TAP interfaces to pass from NixOS into the Genode guest. ''; }; }; }; in mkOption { type = loaOf (submodule genodeOpts); default = { }; example = { foobar = { config = "…"; rom = pkgs: { }; }; }; description = "Configurations of Genode subsystems."; }; config = let crossSystem = config.nixpkgs.localSystem.system + "-" + pkgs.targetPlatform.platform.kernelArch + "-genode"; crossPkgs = builtins.trace crossSystem self.legacyPackages.${crossSystem}; in { systemd.services = let inherit (crossPkgs.genodePackages) base-linux; toService = name: cfg: { description = "Genode subsystem"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; preStart = let config' = self.lib.${crossSystem}.runDhallCommand "${name}.config" { } '' set -e exec ${self.apps.${crossSystem}.render-init.program} > $out << EOF ${./root-config.dhall} { guest = ${cfg.config} , nics = [ "${builtins.concatStringsSep ''", "'' cfg.nics}" ] } EOF ''; rom' = with crossPkgs.genodePackages; { init = "${init}/init"; "ld.lib.so" = "${base-linux}/lib/ld.lib.so"; timer_drv = "${base-linux}/timer_drv"; config = config'; linux_nic_drv = "${ crossPkgs.genodeSources.depot "linux_nic_drv" }/linux_nic_drv"; } // (cfg.rom crossPkgs); in builtins.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "ln -sv ${value} ${name}") rom'); serviceConfig = { DynamicUser = true; RuntimeDirectory = "genode/" + name; WorkingDirectory = "/run/genode/" + name; ExecStart = "${base-linux}/core-linux"; }; }; in lib.mapAttrs toService config.genodeGuests; }; }