@@ 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::{=}
@@ 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;
+
+}