{ config, pkgs, lib, ... }: with lib; { options.systemd.services = lib.mkOption { type = types.attrsOf (types.submodule ({ name, config, ... }: { options.genode = { enable = lib.mkEnableOption "systemd unit to a Genode subsystem translation"; interface = lib.mkOption { type = with types; nullOr str; default = null; example = "eth0"; description = '' Grant access to an IP stack for this interface. Only UDP and TCP are supported. No raw device access. ''; }; extraVfs = lib.mkOption { type = with types; nullOr path; default = null; description = '' Extra configuration to be appended to the VFS of the service. Dhall type is Prelude/XML/Type. ''; }; ramQuota = lib.mkOption { type = types.ints.unsigned; default = 16; description = "RAM quota in MiB"; }; }; })); }; config = { services.klogd.enable = false; # The default is determined by checking the Linux version # which cannot be evaluated here. genode.init.children = mapAttrs' (name: service: let name' = "services." + name; in { name = name'; value = { inputs = with pkgs; with genodePackages; [ bash cached_fs_rom libc posix vfs vfs_pipe ]; configFile = let args = lib.strings.splitString " " (toString service.serviceConfig.ExecStart); binary = builtins.head args; args' = ''[ "${concatStringsSep ''", "'' (builtins.tail args)}" ]''; # TODO: service.environment; interface = if service.genode.interface == null then "None Text" else ''Some "${service.genode.interface}"''; in pkgs.writeText "${name'}.dhall" '' ${./systemd-runner.dhall} { , args = ${args'} , binary = "${binary}" , coreutils = "${pkgs.coreutils}" , extraVfs = ${ if service.genode.extraVfs == null then "[] : List (env:DHALL_PRELUDE).XML.Type" else service.genode.extraVfs } , interface = ${interface} , ramQuotaMiB = ${toString service.genode.ramQuota} } ''; }; }) (filterAttrs (name: service: service.genode.enable) config.systemd.services); }; }