From 12501f291dda4d4c556f9b9c9b6abe60171c3452 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Fri, 13 Nov 2020 14:28:42 +0100 Subject: [PATCH] nixos: add genode.shells option --- nixos-modules/shell.dhall | 182 ++++++++++++++++++++++++++++++++++++++ nixos-modules/shell.nix | 67 ++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 nixos-modules/shell.dhall create mode 100644 nixos-modules/shell.nix diff --git a/nixos-modules/shell.dhall b/nixos-modules/shell.dhall new file mode 100644 index 0000000..01d78c1 --- /dev/null +++ b/nixos-modules/shell.dhall @@ -0,0 +1,182 @@ +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let XML = Prelude.XML + +let VFS = Genode.VFS + +let Init = Genode.Init + +let Child = Init.Child + +let parentRoutes = + Prelude.List.map Text Init.ServiceRoute.Type Init.ServiceRoute.parent + +let EnvVar = Prelude.Map.Entry Text Text + +in λ ( params + : { name : Text + , coreutils : Text + , env : List EnvVar + , nic : Optional Text + , script : Text + } + ) → + let socketsVfs = + merge + { Some = + λ(interface : Text) → + [ VFS.dir + "sockets" + [ VFS.fs VFS.FS::{ label = "${interface}.sockets" } ] + ] + , None = [] : List XML.Type + } + params.nic + + let init = + Init::{ + , routes = parentRoutes [ "Timer", "Rtc", "File_system" ] + , children = toMap + { vfs = + Child.flat + Child.Attributes::{ + , binary = "vfs" + , exitPropagate = True + , provides = [ "File_system" ] + , resources = Genode.Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + , config = Init.Config::{ + , content = + [ VFS.vfs + [ VFS.dir + "dev" + ( [ VFS.dir "pipes" [ VFS.leaf "pipe" ] + , VFS.leaf "log" + , VFS.leaf "null" + , VFS.leaf "rtc" + , VFS.leaf "zero" + ] + # socketsVfs + ) + , VFS.dir + "usr" + [ VFS.dir + "bin" + [ VFS.symlink + "env" + "${params.coreutils}/bin/env" + ] + ] + , VFS.dir "tmp" [ VFS.leaf "ram" ] + , VFS.dir + "nix" + [ VFS.dir + "store" + [ VFS.fs VFS.FS::{ label = "nix-store" } ] + ] + ] + ] + , policies = + [ Init.Config.Policy::{ + , service = "File_system" + , label = Init.LabelSelector.prefix "shell" + , attributes = toMap + { root = "/", writeable = "yes" } + } + , Init.Config.Policy::{ + , service = "File_system" + , label = Init.LabelSelector.prefix "vfs_rom" + , attributes = toMap + { root = "/", writeable = "yes" } + } + ] + } + } + , vfs_rom = + Child.flat + Child.Attributes::{ + , binary = "cached_fs_rom" + , provides = [ "ROM" ] + , resources = Genode.Init.Resources::{ + , ram = Genode.units.MiB 16 + } + , config = Init.Config::{ + , policies = + [ Init.Config.Policy::{ + , service = "ROM" + , diag = Some True + , label = Init.LabelSelector.prefix "shell" + } + ] + } + } + , shell = + Child.flat + Child.Attributes::{ + , binary = "bash" + , exitPropagate = True + , resources = Genode.Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + , config = Init.Config::{ + , content = + [ XML.leaf + { name = "libc" + , attributes = toMap + { stdin = "/dev/null" + , stdout = "/dev/log" + , stderr = "/dev/log" + , pipe = "/dev/pipes" + , rtc = "/dev/rtc" + , socket = "/dev/sockets" + } + } + , VFS.vfs [ VFS.leaf "fs" ] + ] + # Prelude.List.map + Text + XML.Type + ( λ(x : Text) → + XML.leaf + { name = "arg" + , attributes = toMap { value = x } + } + ) + [ "bash", params.script ] + # Prelude.List.map + EnvVar + XML.Type + ( λ(e : EnvVar) → + XML.leaf + { name = "env" + , attributes = toMap + { key = e.mapKey, value = e.mapValue } + } + ) + params.env + } + , routes = + Prelude.List.map + Text + Init.ServiceRoute.Type + ( λ(label : Text) → + Init.ServiceRoute.parentLabel + "ROM" + (Some label) + (Some label) + ) + [ "libc.lib.so" + , "libm.lib.so" + , "posix.lib.so" + , "vfs.lib.so" + ] + } + } + } + + in Init.toChild init Init.Attributes::{=} diff --git a/nixos-modules/shell.nix b/nixos-modules/shell.nix new file mode 100644 index 0000000..fb54995 --- /dev/null +++ b/nixos-modules/shell.nix @@ -0,0 +1,67 @@ +{ config, pkgs, lib, ... }: +with lib; + +{ + options.genode.shells = mkOption { + default = { }; + type = with types; + attrsOf (submodule { + options = { + + environmentVariables = mkOption { + type = with types; attrsOf (either str (listOf str)); + apply = + mapAttrs (n: v: if isList v then concatStringsSep ":" v else v); + }; + + inputs = mkOption { + description = "List of packages to add to the shell environment"; + default = [ ]; + type = types.listOf types.package; + }; + + nic = 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. + ''; + }; + + script = mkOption { + type = types.lines; + description = "Shell script to execute"; + }; + }; + + }); + }; + + config.genode.init.children = mapAttrs' (name: shell: { + name = name + ".shell"; + value = { + inputs = with pkgs; + with genodePackages; + [ bash cached_fs_rom libc posix vfs vfs_pipe ] ++ shell.inputs; + configFile = let + nic = + if shell.nic == null then "None Text" else ''Some "${shell.nic}"''; + env = mapAttrsToList (mapKey: mapValue: + '', { mapKey = "${mapKey}", mapValue = "${mapValue}" }'') + shell.environmentVariables; + in pkgs.writeText "${name}.shell.dhall" '' + let Genode = env:DHALL_GENODE in + ${./shell.dhall} + { name = "${name}" + , coreutils = "${pkgs.coreutils}" + , env = [${toString env} ] : Genode.Prelude.Map.Type Text Text + , nic = ${nic} + , script = "${pkgs.writeText "${name}.shell.script" shell.script}" + } + ''; + }; + }) config.genode.shells; + +}