~ehmry/sigil

12501f291dda4d4c556f9b9c9b6abe60171c3452 — Emery Hemingway 3 years ago 2f89f52 shells
nixos: add genode.shells option
2 files changed, 249 insertions(+), 0 deletions(-)

A nixos-modules/shell.dhall
A nixos-modules/shell.nix
A nixos-modules/shell.dhall => nixos-modules/shell.dhall +182 -0
@@ 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::{=}

A nixos-modules/shell.nix => nixos-modules/shell.nix +67 -0
@@ 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;

}