diff --git a/flake.nix b/flake.nix
index 95adcb6..5fbd6ca 100644
--- a/flake.nix
+++ b/flake.nix
@@ -131,10 +131,6 @@
packages = self.packages.${system};
});
- nixosModules =
- # Modules for composing Genode and NixOS
- import ./nixos-modules { inherit self; };
-
checks =
# Checks for continous testing
let tests = import ./tests;
diff --git a/nixos-modules/default.nix b/nixos-modules/default.nix
deleted file mode 100644
index ec1158b..0000000
--- a/nixos-modules/default.nix
+++ /dev/null
@@ -1,284 +0,0 @@
-{ self }: {
- genodeHost = { config, lib, pkgs, modulesPath, ... }:
- let
- apps' = self.apps.x86_64-linux-x86_64-genode;
- config' = config;
- lib' = self.lib.x86_64-linux-x86_64-genode;
- pkgs' = self.packages.x86_64-linux-x86_64-genode;
- legacyPackages' = self.legacyPackages.x86_64-linux-x86_64-genode;
-
- modulesPath' = "${self.inputs.nixpkgs}/nixos/modules";
-
- genodeConfig = config.genode;
-
- console = lib'.runDhallCommand "vbox.dhall" { } ''
- dhall > $out <<< '${
- ./dhall/console.dhall
- } { bash = "${legacyPackages'.bash}", coreutils = "${legacyPackages'.coreutils}", path = "${
- lib.makeSearchPathOutput "bin" "bin"
- (with legacyPackages'; [ bash coreutils ])
- }" }'
- '';
-
- guestChildren = lib'.runDhallCommand "vbox.dhall" { } (''
- dhall > $out << END
- let Genode = env:DHALL_GENODE
- in [
- '' + builtins.concatStringsSep "," (lib.mapAttrsToList (vmName: cfg:
- let
- inherit (cfg) config;
-
- boot = {
- iso = rec {
- filename = "nixos.iso";
- drv = pkgs.callPackage
- "${modulesPath'}/../lib/make-iso9660-image.nix"
- # call the ISO utility from our nixpkgs with the package set of the guest
- {
- isoName = filename;
- inherit (config.isoImage) volumeID contents;
- };
- format = "< ISO | VDI >.ISO";
- storeRoot = "${baseNameOf drv}/iso";
- uuid = "81763434-9a51-49e8-9444-528a5a28c4bc";
- };
- vdi = rec {
- filename = "nixos.vdi";
- drv = import "${modulesPath'}/../lib/make-disk-image.nix" {
- inherit config lib pkgs;
- diskSize = config.virtualbox.baseImageSize;
- partitionTableType = "legacy";
- name = "nixos-${pkgs.stdenv.hostPlatform.system}.vdi";
- format = "vdi";
- };
- format = "< ISO | VDI >.VDI";
- storeRoot = baseNameOf drv;
- uuid = ''
- $(${pkgs.virtualbox}/bin/VBoxManage showmediuminfo "${boot.drv}/${boot.filename}" | awk '/^UUID:/ {print $2}')'';
- };
- }.${cfg.bootFormat};
-
- in lib'.runDhallCommand "vbox.dhall" { } ''
- bootUuid=${boot.uuid}
- dhall > $out << END
- { mapKey = "vbox-${vmName}"
- , mapValue =
- ${./dhall/vbox-guest.dhall}
- { bootFilename = "${boot.filename}"
- , bootFormat = ${boot.format}
- , bootPkg = "${boot.storeRoot}"
- , bootUuid = "$bootUuid"
- , memorySize = ${toString cfg.memorySize}
- , vmName = "${vmName}"
- }
- }
- END
- '') config.genode.guests) + ''
- ] : Genode.Init.Children.Type
- END
- '');
-
- initConfig = let
- fbDriverConfig = {
- intel = ./dhall/intel_fb_drv.dhall;
- vesa = ./dhall/vesa_fb_drv.dhall;
- }.${genodeConfig.fbDriver};
- in ''
- ${
- ./dhall/root.dhall
- } { fbDriver = ${fbDriverConfig}, guests = toMap { console = ${console} } # ${guestChildren}, inputFilterChargens = ${genodeConfig.inputFilter.extraChargen}, partitionType = ${
- ./dhall/partition-type
- }, wm = ${./dhall/wm.dhall}, graphical-log = ${
- ./dhall/graphical-log.dhall
- }, fs-log = ${
- ./dhall/fs-log.dhall
- }, systemLabel = "${config.system.nixos.label}" }'';
-
- buildBootDescription = self.legacyPackages.x86_64-linux.callPackage
- ./buildBootDescription.nix { lib = lib'; };
-
- bootDescription = buildBootDescription {
- inherit initConfig;
- imageInputs = [ legacyPackages'.bash ] ++ map pkgs'.genodeSources.depot
- ([
- "acpi_drv"
- "ahci_drv"
- "cached_fs_rom"
- "chroot"
- "decorator"
- "event_filter"
- "fs_log"
- "gui_fb"
- "init"
- "ipxe_nic_drv"
- "libc"
- "libiconv"
- "log_core"
- "nic_router"
- "nitpicker"
- "part_block"
- "platform_drv"
- "posix"
- "ps2_drv"
- "report_rom"
- "rom_to_file"
- "rtc_drv"
- "rump"
- "stdcxx"
- "terminal"
- "terminal_log"
- "usb_drv"
- "vfs"
- "vfs_audit"
- "vfs_import"
- "vfs_pipe"
- "vfs_ttf"
- "window_layouter"
- "wm"
- ] ++ lib.optional (genodeConfig.guests != { }) "vbox5"
- ++ lib.optional (genodeConfig.fbDriver == "vesa") "vesa_drv"
- ++ lib.optional (genodeConfig.fbDriver == "intel") "intel_fb_drv")
- ++ (with pkgs'; [ base-nova block_router ]);
- extraBinaries = [
- "ld.lib.so"
- "libc.so"
- "libm.so"
- "libposix.so"
- "librump.so"
- "librump_fs.so"
- "libstdcxx.so"
- "libvfs.so"
- "libvfs_audit.so"
- "libvfs_import.so"
- "libvfs_pipe.so"
- "libvfs_rump.so"
- "libvfs_ttf.so"
- ] ++ lib.optionals (genodeConfig.guests != { }) [
- "libc_pipe.so"
- "libiconv.so"
- "libqemu-usb.so"
- ];
- extraRoms = {
- "Inconsolata.ttf" =
- "${pkgs.inconsolata}/share/fonts/truetype/inconsolata/Inconsolata-Regular.ttf";
- "focus" = builtins.toFile "nitpicker-is-too-complicated.xml" ''
-
- '';
- };
- };
-
- firmware = lib'.novaImage "stage0" { gzip = true; } bootDescription;
-
- in {
-
- options.genode = with lib; {
-
- fbDriver = mkOption {
- default = "vesa";
- type = types.enum [ "intel" "vesa" ];
- description = ''
- Set framebuffer driver.
- '';
- };
-
- guests = mkOption {
- type = types.attrsOf (types.submodule
- ({ config, options, name, ... }: {
- options = {
-
- bootFormat = mkOption {
- default = "vdi";
- type = types.enum [ "iso" "vdi" ];
- description = "Set boot media format.";
- };
- memorySize = mkOption {
- type = types.int;
- default = 1536;
- description = ''
- The amount of RAM in MiB allocated to the VirtualBox guest.
- '';
- };
-
- config = mkOption {
- description = ''
- A specification of the desired configuration of this
- guest VM, as a NixOS module.
- '';
- type = mkOptionType {
- name = "Toplevel NixOS config";
- merge = loc: defs:
- (import "${modulesPath}/../lib/eval-config.nix" {
- inherit (config'.nixpkgs) system;
- modules = {
- iso = [
- "${modulesPath}/installer/cd-dvd/iso-image.nix"
-
- ];
- vdi = [
- "${modulesPath}/virtualisation/virtualbox-image.nix"
- {
- virtualbox.memorySize =
- genodeConfig.guests.${name}.memorySize;
- }
- ];
- }.${genodeConfig.guests.${name}.bootFormat}
- ++ [{ system.nixos.tags = [ name ]; }]
- ++ (map (x: x.value) defs);
- prefix = [ "guests" name ];
- }).config;
- };
- };
-
- };
- }));
- default = { };
- };
-
- inputFilter = {
- extraChargen = mkOption {
- description =
- "Dhall expression of the type List Prelude.XML.Type
";
- type = types.str;
- default = "${./dhall/qwerty.chargen.dhall}";
- };
- };
-
- };
-
- config = {
-
- system.build.genode = {
- inherit firmware console;
- config = lib'.runDhallCommand "config.dhall" { }
- ''dhall > $out <<< "${initConfig}"'';
-
- xml = lib'.runDhallCommand "config.xml" { }
- ''${apps'.render-init.program} <<< "${initConfig}" > $out'';
- };
-
- boot.loader.grub = {
- extraEntries = ''
- menuentry Genode on NOVA {
- insmod multiboot2
- insmod gzio
- multiboot2 /bender
- module2 /hypervisor hypervisor iommu novpid serial logmem
- module2 /image.elf.gz image.elf
- }
- '';
-
- extraFiles = {
- "bender" = "${pkgs'.genodeSources}/tool/boot/bender";
- "hypervisor" = "${pkgs'.NOVA}/hypervisor-x86_64";
- "image.elf.gz" = "${firmware}/image.elf.gz";
- };
- };
-
- };
-
- };
-
- workman-layout.genode.inputFilter.extraChargen =
- "${./dhall/workman.chargen.dhall}";
-
-}
diff --git a/nixos-modules/dhall/console.dhall b/nixos-modules/dhall/console.dhall
deleted file mode 100644
index 160799d..0000000
--- a/nixos-modules/dhall/console.dhall
+++ /dev/null
@@ -1,201 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Prelude = Genode.Prelude
-
-let XML = Prelude.XML
-
-let Init = Genode.Init
-
-let Child = Init.Child
-
-let Resources = Init.Resources
-
-let ServiceRoute = Init.ServiceRoute
-
-let Libc = Genode.Libc
-
-let VFS = Genode.VFS
-
-in λ(params : { bash : Text, coreutils : Text, path : Text }) →
- let init =
- Init::{
- , verbose = True
- , routes =
- Prelude.List.map
- Text
- Init.ServiceRoute.Type
- Init.ServiceRoute.parent
- [ "Gui", "Rtc", "Timer" ]
- , children = toMap
- { gui_fb =
- Child.flat
- Child.Attributes::{
- , binary = "gui_fb"
- , config = Init.Config::{
- , attributes = toMap
- { xpos = "10"
- , ypos = "10"
- , initial_width = "800"
- , initial_height = "600"
- }
- }
- , exitPropagate = True
- , provides = [ "Framebuffer", "Input" ]
- , resources = Resources::{ ram = Genode.units.MiB 8 }
- }
- , terminal =
- Child.flat
- Child.Attributes::{
- , binary = "terminal"
- , config = Init.Config::{
- , content =
- [ XML.element
- { name = "vfs"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.element
- { name = "dir"
- , attributes = toMap { name = "fonts" }
- , content =
- [ XML.leaf
- { name = "fs"
- , attributes = toMap
- { label = "fonts" }
- }
- ]
- }
- ]
- }
- ]
- }
- , provides = [ "Terminal" ]
- , resources = Resources::{
- , caps = 256
- , ram = Genode.units.MiB 4
- }
- , routes =
- [ ServiceRoute.child "Framebuffer" "gui_fb"
- , ServiceRoute.child "Input" "gui_fb"
- , ServiceRoute.parent "File_system"
- ]
- }
- , vfs =
- Child.flat
- Child.Attributes::{
- , binary = "vfs"
- , config = Init.Config::{
- , content =
- [ VFS.vfs
- [ VFS.dir
- "dev"
- [ VFS.leaf "log"
- , VFS.leaf "null"
- , VFS.dir "pipe" [ VFS.leaf "pipe" ]
- , VFS.leaf "rtc"
- , VFS.leaf "terminal"
- , VFS.leaf "zero"
- ]
- , VFS.dir
- "usr"
- [ VFS.dir
- "bin"
- [ VFS.symlink
- "${params.coreutils}/bin/env"
- "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"
- , attributes = toMap
- { root = "/", writeable = "yes" }
- }
- ]
- }
- , provides = [ "File_system" ]
- , resources = Resources::{
- , caps = 256
- , ram = Genode.units.MiB 8
- }
- , routes =
- [ Init.ServiceRoute.parent "File_system"
- , Init.ServiceRoute.child "Terminal" "terminal"
- ]
- }
- , store_rom =
- Child.flat
- Child.Attributes::{
- , binary = "cached_fs_rom"
- , provides = [ "ROM" ]
- , resources = Resources::{
- , caps = 256
- , ram = Genode.units.MiB 4
- }
- , routes = [ Init.ServiceRoute.child "File_system" "vfs" ]
- }
- , shell =
- Child.flat
- Child.Attributes::{
- , binary = "bash"
- , config =
- Libc.toConfig
- Libc::{
- , stdin = Some "/dev/terminal"
- , stdout = Some "/dev/terminal"
- , stderr = Some "/dev/terminal"
- , pipe = Some "/dev/pipe"
- , rtc = Some "/dev/rtc"
- , vfs = [ VFS.leaf "fs" ]
- , env = toMap
- { TERM = "screen"
- , PATH = "${params.path}"
- , PS1 = "system:\$PWD"
- }
- , args = [ "bash" ]
- }
- , exitPropagate = True
- , resources = Resources::{
- , caps = 256
- , ram = Genode.units.MiB 8
- }
- , routes =
- [ Init.ServiceRoute.child "File_system" "vfs"
- , { service =
- { name = "ROM"
- , label =
- Init.LabelSelector.Type.Partial
- { prefix = Some "/nix/store/"
- , suffix = None Text
- }
- }
- , route =
- Init.Route.Type.Child
- { name = "store_rom"
- , label = None Text
- , diag = None Bool
- }
- }
- ]
- }
- }
- }
-
- in Init.toChild
- init
- Init.Attributes::{
- , routes =
- [ ServiceRoute.parent "File_system"
- , ServiceRoute.parent "Gui"
- , ServiceRoute.parent "Rtc"
- , ServiceRoute.parent "Timer"
- ]
- }
diff --git a/nixos-modules/dhall/fs-log.dhall b/nixos-modules/dhall/fs-log.dhall
deleted file mode 100644
index ee36389..0000000
--- a/nixos-modules/dhall/fs-log.dhall
+++ /dev/null
@@ -1,56 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Init = Genode.Init
-
-let Child = Init.Child
-
-let ServiceRoute = Init.ServiceRoute
-
-let routeLogRom =
- λ(label : Text) → ServiceRoute.parentLabel "ROM" (Some "log") (Some label)
-
-in Init::{
- , verbose = True
- , children = toMap
- { fs_log =
- Child.flat
- Child.Attributes::{
- , binary = "fs_log"
- , config = Init.Config::{
- , defaultPolicy = Some Init.Config.DefaultPolicy::{
- , attributes = toMap { merge = "yes", truncate = "yes" }
- }
- }
- , exitPropagate = True
- , provides = [ "LOG" ]
- , routes = [ ServiceRoute.parent "File_system" ]
- }
- , log_core =
- Child.flat
- Child.Attributes::{
- , binary = "log_core"
- , routes =
- [ routeLogRom "core_log"
- , ServiceRoute.childLabel
- "LOG"
- "fs_log"
- (Some "log")
- (Some "core")
- ]
- }
- , log_kernel =
- Child.flat
- Child.Attributes::{
- , binary = "log_core"
- , routes =
- [ routeLogRom "kernel_log"
- , ServiceRoute.childLabel
- "LOG"
- "fs_log"
- (Some "log")
- (Some "kernel")
- ]
- }
- }
- , routes = [ ServiceRoute.parent "Timer" ]
- }
diff --git a/nixos-modules/dhall/graphical-log.dhall b/nixos-modules/dhall/graphical-log.dhall
deleted file mode 100644
index d1e13ee..0000000
--- a/nixos-modules/dhall/graphical-log.dhall
+++ /dev/null
@@ -1,105 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Prelude = Genode.Prelude
-
-let XML = Prelude.XML
-
-let Init = Genode.Init
-
-let Child = Init.Child
-
-let Resources = Init.Resources
-
-let ServiceRoute = Init.ServiceRoute
-
-let routeLogRom =
- λ(label : Text) → ServiceRoute.parentLabel "ROM" (Some "log") (Some label)
-
-in Init::{
- , verbose = True
- , routes =
- Prelude.List.map
- Text
- Init.ServiceRoute.Type
- Init.ServiceRoute.parent
- [ "Gui", "Rtc", "Timer" ]
- , children = toMap
- { gui_fb =
- Child.flat
- Child.Attributes::{
- , binary = "gui_fb"
- , config = Init.Config::{
- , attributes = toMap
- { initial_width = "600", initial_height = "600" }
- }
- , exitPropagate = True
- , provides = [ "Framebuffer", "Input" ]
- , resources = Resources::{ ram = Genode.units.MiB 8 }
- }
- , terminal =
- Child.flat
- Child.Attributes::{
- , binary = "terminal"
- , config = Init.Config::{
- , content =
- [ XML.element
- { name = "vfs"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.element
- { name = "dir"
- , attributes = toMap { name = "fonts" }
- , content =
- [ XML.leaf
- { name = "fs"
- , attributes = toMap { label = "fonts" }
- }
- ]
- }
- ]
- }
- ]
- }
- , provides = [ "Terminal" ]
- , resources = Resources::{ caps = 256, ram = Genode.units.MiB 4 }
- , routes =
- [ ServiceRoute.child "Framebuffer" "gui_fb"
- , ServiceRoute.child "Input" "gui_fb"
- , ServiceRoute.parent "File_system"
- ]
- }
- , terminal_log =
- Child.flat
- Child.Attributes::{
- , binary = "terminal_log"
- , provides = [ "LOG" ]
- , routes = [ ServiceRoute.child "Terminal" "terminal" ]
- }
- , log_core =
- Child.flat
- Child.Attributes::{
- , binary = "log_core"
- , routes =
- [ routeLogRom "core_log"
- , ServiceRoute.childLabel
- "LOG"
- "terminal_log"
- (Some "log")
- (Some "core")
- ]
- }
- , log_kernel =
- Child.flat
- Child.Attributes::{
- , binary = "log_core"
- , routes =
- [ routeLogRom "kernel_log"
- , ServiceRoute.childLabel
- "LOG"
- "terminal_log"
- (Some "log")
- (Some "kernel")
- ]
- }
- }
- }
diff --git a/nixos-modules/dhall/intel_fb_drv.dhall b/nixos-modules/dhall/intel_fb_drv.dhall
deleted file mode 100644
index 2ecb1b9..0000000
--- a/nixos-modules/dhall/intel_fb_drv.dhall
+++ /dev/null
@@ -1,23 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Init = Genode.Init
-
-let Child = Init.Child
-
-let ServiceRoute = Init.ServiceRoute
-
-in Child.flat
- Child.Attributes::{
- , binary = "intel_fb_drv"
- , provides = [ "Framebuffer" ]
- , resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 48 }
- , routes =
- [ ServiceRoute.parent "IO_MEM"
- , ServiceRoute.parent "IO_PORT"
- , ServiceRoute.childLabel
- "Platform"
- "platform_drv"
- (None Text)
- (Some "intel_fb_drv")
- ]
- }
diff --git a/nixos-modules/dhall/partition-type b/nixos-modules/dhall/partition-type
deleted file mode 100644
index 2cca25d..0000000
--- a/nixos-modules/dhall/partition-type
+++ /dev/null
@@ -1 +0,0 @@
-"24b69406-18a1-428d-908e-d21a1437122c"
diff --git a/nixos-modules/dhall/qwerty.chargen.dhall b/nixos-modules/dhall/qwerty.chargen.dhall
deleted file mode 100644
index 860cf2c..0000000
--- a/nixos-modules/dhall/qwerty.chargen.dhall
+++ /dev/null
@@ -1,297 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Prelude = Genode.Prelude
-
-let XML = Prelude.XML
-
-let Key = < Ascii : Natural | Char : Text | Code : Natural > : Type
-
-let Map =
- { Type =
- { keys : Prelude.Map.Type Text Key
- , mod1 : Bool
- , mod2 : Bool
- , mod3 : Bool
- , mod4 : Bool
- }
- , default = { mod1 = False, mod2 = False, mod3 = False, mod4 = False }
- }
-
-let boolToAttr = λ(_ : Bool) → if _ then "yes" else "no"
-
-let keyToXML =
- λ(x : Prelude.Map.Entry Text Key) →
- XML.leaf
- { name = "key"
- , attributes =
- [ merge
- { Ascii =
- λ(_ : Natural) →
- { mapKey = "ascii", mapValue = Prelude.Natural.show _ }
- , Char = λ(_ : Text) → { mapKey = "char", mapValue = _ }
- , Code =
- λ(_ : Natural) →
- { mapKey = "code", mapValue = Prelude.Natural.show _ }
- }
- x.mapValue
- , { mapKey = "name", mapValue = x.mapKey }
- ]
- }
-
-let mapToXML =
- λ(map : Map.Type) →
- XML.element
- { name = "map"
- , attributes = toMap
- { mod1 = boolToAttr map.mod1
- , mod2 = boolToAttr map.mod2
- , mod3 = boolToAttr map.mod3
- , mod4 = boolToAttr map.mod4
- }
- , content =
- Prelude.List.map
- (Prelude.Map.Entry Text Key)
- XML.Type
- keyToXML
- map.keys
- }
-
-let qwerty =
- [ Map::{
- , mod1 = False
- , mod2 = False
- , mod3 = False
- , mod4 = False
- , keys = toMap
- { KEY_1 = Key.Code 49
- , KEY_2 = Key.Code 50
- , KEY_3 = Key.Code 51
- , KEY_4 = Key.Code 52
- , KEY_5 = Key.Code 53
- , KEY_6 = Key.Code 54
- , KEY_7 = Key.Code 55
- , KEY_8 = Key.Code 56
- , KEY_9 = Key.Code 57
- , KEY_0 = Key.Code 48
- , KEY_MINUS = Key.Code 45
- , KEY_EQUAL = Key.Code 61
- , KEY_Q = Key.Code 113
- , KEY_W = Key.Code 119
- , KEY_E = Key.Code 101
- , KEY_R = Key.Code 114
- , KEY_T = Key.Code 116
- , KEY_Y = Key.Code 121
- , KEY_U = Key.Code 117
- , KEY_I = Key.Code 105
- , KEY_O = Key.Code 111
- , KEY_P = Key.Code 112
- , KEY_LEFTBRACE = Key.Code 91
- , KEY_RIGHTBRACE = Key.Code 93
- , KEY_A = Key.Code 97
- , KEY_S = Key.Code 115
- , KEY_D = Key.Code 100
- , KEY_F = Key.Code 102
- , KEY_G = Key.Code 103
- , KEY_H = Key.Code 104
- , KEY_J = Key.Code 106
- , KEY_K = Key.Code 107
- , KEY_L = Key.Code 108
- , KEY_SEMICOLON = Key.Code 59
- , KEY_APOSTROPHE = Key.Code 39
- , KEY_GRAVE = Key.Code 96
- , KEY_BACKSLASH = Key.Code 92
- , KEY_Z = Key.Code 122
- , KEY_X = Key.Code 120
- , KEY_C = Key.Code 99
- , KEY_V = Key.Code 118
- , KEY_B = Key.Code 98
- , KEY_N = Key.Code 110
- , KEY_M = Key.Code 109
- , KEY_COMMA = Key.Code 44
- , KEY_DOT = Key.Code 46
- , KEY_SLASH = Key.Code 47
- , KEY_KPASTERISK = Key.Code 42
- , KEY_SPACE = Key.Code 32
- , KEY_KP7 = Key.Code 55
- , KEY_KP8 = Key.Code 56
- , KEY_KP9 = Key.Code 57
- , KEY_KPMINUS = Key.Code 45
- , KEY_KP4 = Key.Code 52
- , KEY_KP5 = Key.Code 53
- , KEY_KP6 = Key.Code 54
- , KEY_KPPLUS = Key.Code 43
- , KEY_KP1 = Key.Code 49
- , KEY_KP2 = Key.Code 50
- , KEY_KP3 = Key.Code 51
- , KEY_KP0 = Key.Code 48
- , KEY_KPDOT = Key.Code 46
- , KEY_102ND = Key.Code 60
- , KEY_KPSLASH = Key.Code 47
- , KEY_ESC = Key.Ascii 27
- , KEY_BACKSPACE = Key.Ascii 8
- , KEY_TAB = Key.Ascii 9
- , KEY_ENTER = Key.Ascii 10
- , KEY_KPENTER = Key.Ascii 10
- , KEY_DELETE = Key.Ascii 127
- }
- }
- , Map::{
- , mod1 = True
- , mod2 = False
- , mod3 = False
- , mod4 = False
- , keys = toMap
- { KEY_1 = Key.Code 33
- , KEY_2 = Key.Code 64
- , KEY_3 = Key.Code 35
- , KEY_4 = Key.Code 36
- , KEY_5 = Key.Code 37
- , KEY_6 = Key.Code 94
- , KEY_7 = Key.Code 38
- , KEY_8 = Key.Code 42
- , KEY_9 = Key.Code 40
- , KEY_0 = Key.Code 41
- , KEY_MINUS = Key.Code 95
- , KEY_EQUAL = Key.Code 43
- , KEY_Q = Key.Code 81
- , KEY_W = Key.Code 87
- , KEY_E = Key.Code 69
- , KEY_R = Key.Code 82
- , KEY_T = Key.Code 84
- , KEY_Y = Key.Code 89
- , KEY_U = Key.Code 85
- , KEY_I = Key.Code 73
- , KEY_O = Key.Code 79
- , KEY_P = Key.Code 80
- , KEY_LEFTBRACE = Key.Code 123
- , KEY_RIGHTBRACE = Key.Code 125
- , KEY_A = Key.Code 65
- , KEY_S = Key.Code 83
- , KEY_D = Key.Code 68
- , KEY_F = Key.Code 70
- , KEY_G = Key.Code 71
- , KEY_H = Key.Code 72
- , KEY_J = Key.Code 74
- , KEY_K = Key.Code 75
- , KEY_L = Key.Code 76
- , KEY_SEMICOLON = Key.Code 58
- , KEY_APOSTROPHE = Key.Code 34
- , KEY_GRAVE = Key.Code 126
- , KEY_BACKSLASH = Key.Code 124
- , KEY_Z = Key.Code 90
- , KEY_X = Key.Code 88
- , KEY_C = Key.Code 67
- , KEY_V = Key.Code 86
- , KEY_B = Key.Code 66
- , KEY_N = Key.Code 78
- , KEY_M = Key.Code 77
- , KEY_COMMA = Key.Code 60
- , KEY_DOT = Key.Code 62
- , KEY_SLASH = Key.Code 63
- , KEY_KPASTERISK = Key.Code 42
- , KEY_KPMINUS = Key.Code 45
- , KEY_KPPLUS = Key.Code 43
- , KEY_102ND = Key.Code 62
- , KEY_KPSLASH = Key.Code 47
- }
- }
- , Map::{
- , mod1 = False
- , mod2 = False
- , mod3 = True
- , mod4 = False
- , keys = toMap { KEY_5 = Key.Code 8364, KEY_102ND = Key.Code 124 }
- }
- , Map::{
- , mod1 = False
- , mod2 = False
- , mod3 = False
- , mod4 = True
- , keys = toMap
- { KEY_Q = Key.Code 81
- , KEY_W = Key.Code 87
- , KEY_E = Key.Code 69
- , KEY_R = Key.Code 82
- , KEY_T = Key.Code 84
- , KEY_Y = Key.Code 89
- , KEY_U = Key.Code 85
- , KEY_I = Key.Code 73
- , KEY_O = Key.Code 79
- , KEY_P = Key.Code 80
- , KEY_A = Key.Code 65
- , KEY_S = Key.Code 83
- , KEY_D = Key.Code 68
- , KEY_F = Key.Code 70
- , KEY_G = Key.Code 71
- , KEY_H = Key.Code 72
- , KEY_J = Key.Code 74
- , KEY_K = Key.Code 75
- , KEY_L = Key.Code 76
- , KEY_Z = Key.Code 90
- , KEY_X = Key.Code 88
- , KEY_C = Key.Code 67
- , KEY_V = Key.Code 86
- , KEY_B = Key.Code 66
- , KEY_N = Key.Code 78
- , KEY_M = Key.Code 77
- }
- }
- , Map::{
- , mod1 = True
- , mod2 = False
- , mod3 = False
- , mod4 = True
- , keys = toMap
- { KEY_1 = Key.Code 33
- , KEY_2 = Key.Code 64
- , KEY_3 = Key.Code 35
- , KEY_4 = Key.Code 36
- , KEY_5 = Key.Code 37
- , KEY_6 = Key.Code 94
- , KEY_7 = Key.Code 38
- , KEY_8 = Key.Code 42
- , KEY_9 = Key.Code 40
- , KEY_0 = Key.Code 41
- , KEY_MINUS = Key.Code 95
- , KEY_EQUAL = Key.Code 43
- , KEY_Q = Key.Code 113
- , KEY_W = Key.Code 119
- , KEY_E = Key.Code 101
- , KEY_R = Key.Code 114
- , KEY_T = Key.Code 116
- , KEY_Y = Key.Code 121
- , KEY_U = Key.Code 117
- , KEY_I = Key.Code 105
- , KEY_O = Key.Code 111
- , KEY_P = Key.Code 112
- , KEY_LEFTBRACE = Key.Code 123
- , KEY_RIGHTBRACE = Key.Code 125
- , KEY_A = Key.Code 97
- , KEY_S = Key.Code 115
- , KEY_D = Key.Code 100
- , KEY_F = Key.Code 102
- , KEY_G = Key.Code 103
- , KEY_H = Key.Code 104
- , KEY_J = Key.Code 106
- , KEY_K = Key.Code 107
- , KEY_L = Key.Code 108
- , KEY_SEMICOLON = Key.Code 58
- , KEY_APOSTROPHE = Key.Code 34
- , KEY_GRAVE = Key.Code 126
- , KEY_BACKSLASH = Key.Code 124
- , KEY_Z = Key.Code 122
- , KEY_X = Key.Code 120
- , KEY_C = Key.Code 99
- , KEY_V = Key.Code 118
- , KEY_B = Key.Code 98
- , KEY_N = Key.Code 110
- , KEY_M = Key.Code 109
- , KEY_COMMA = Key.Code 60
- , KEY_DOT = Key.Code 62
- , KEY_SLASH = Key.Code 63
- , KEY_102ND = Key.Code 62
- }
- }
- ]
-
-in Prelude.List.map Map.Type XML.Type mapToXML qwerty
diff --git a/nixos-modules/dhall/root.dhall b/nixos-modules/dhall/root.dhall
deleted file mode 100644
index 66e6bb3..0000000
--- a/nixos-modules/dhall/root.dhall
+++ /dev/null
@@ -1,745 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Prelude = Genode.Prelude
-
-let XML = Prelude.XML
-
-let Init = Genode.Init
-
-let Child = Init.Child
-
-let Resources = Init.Resources
-
-let ServiceRoute = Init.ServiceRoute
-
-let Policy = Init.Config.Policy
-
-let DefaultPolicy = Init.Config.DefaultPolicy
-
-let LabelSelector = Init.LabelSelector
-
-let label =
- λ(label : Text) →
- { local = label, route = label } : Child.Attributes.Label
-
-let rootInit =
- λ ( params
- : { fbDriver : Init.Child.Type
- , guests : Init.Children.Type
- , inputFilterChargens : List XML.Type
- , partitionType : Text
- , wm : Init.Type
- , graphical-log : Init.Type
- , fs-log : Init.Type
- , systemLabel : Text
- }
- ) →
- Init::{
- , children = toMap
- { timer =
- Child.flat
- Child.Attributes::{
- , binary = "timer_drv"
- , provides = [ "Timer" ]
- }
- , rtc =
- Child.flat
- Child.Attributes::{
- , binary = "rtc_drv"
- , provides = [ "Rtc" ]
- , routes =
- [ ServiceRoute.parent "IO_PORT"
- , ServiceRoute.parent "IO_MEM"
- ]
- }
- , acpi_drv =
- Child.flat
- Child.Attributes::{
- , binary = "acpi_drv"
- , priority = 1
- , resources = Resources::{
- , caps = 350
- , ram = Genode.units.MiB 4
- }
- , romReports = [ label "acpi", label "smbios_table" ]
- , routes = [ ServiceRoute.parent "IO_MEM" ]
- }
- , platform_drv =
- Child.flat
- Child.Attributes::{
- , binary = "platform_drv"
- , resources = Resources::{
- , caps = 400
- , ram = Genode.units.MiB 4
- , constrainPhys = True
- }
- , reportRoms = [ label "acpi" ]
- , romReports = [ label "pci" ]
- , provides = [ "Acpi", "Platform" ]
- , routes =
- [ ServiceRoute.parent "IRQ"
- , ServiceRoute.parent "IO_MEM"
- , ServiceRoute.parent "IO_PORT"
- , ServiceRoute.parentLabel
- "ROM"
- (Some "system")
- (Some "system")
- ]
- , config = Init.Config::{
- , attributes = toMap { system = "yes" }
- , content =
- let PciPolicy/Type =
- { labelSuffix : Text, pciClass : Text }
-
- in [ XML.text
- ''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ''
- ]
- # Prelude.List.map
- PciPolicy/Type
- XML.Type
- ( λ(policy : PciPolicy/Type) →
- XML.element
- { name = "policy"
- , attributes = toMap
- { label_suffix = policy.labelSuffix }
- , content =
- [ XML.leaf
- { name = "pci"
- , attributes = toMap
- { class = policy.pciClass }
- }
- ]
- }
- )
- [ { labelSuffix = "ahci_drv"
- , pciClass = "AHCI"
- }
- , { labelSuffix = "nic_drv"
- , pciClass = "ETHERNET"
- }
- , { labelSuffix = "usb_drv", pciClass = "USB" }
- , { labelSuffix = "vesa_fb_drv"
- , pciClass = "VGA"
- }
- ]
- }
- }
- , framebuffer = params.fbDriver
- , event_filter =
- Child.flat
- Child.Attributes::{
- , binary = "event_filter"
- , config =
- let key =
- λ(name : Text) →
- XML.leaf
- { name = "key", attributes = toMap { name } }
-
- let remap =
- λ(name : Text) →
- λ(to : Text) →
- XML.leaf
- { name = "key"
- , attributes = toMap { name, to }
- }
-
- in Init.Config::{
- , content =
- [ XML.leaf
- { name = "input"
- , attributes = toMap { label = "ps2" }
- }
- , XML.leaf
- { name = "input"
- , attributes = toMap { label = "usb" }
- }
- , XML.element
- { name = "output"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.element
- { name = "chargen"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.element
- { name = "remap"
- , attributes =
- XML.emptyAttributes
- , content =
- [ remap
- "KEY_LEFTMETA"
- "KEY_SCREEN"
- , XML.element
- { name = "merge"
- , attributes =
- XML.emptyAttributes
- , content =
- [ XML.leaf
- { name = "input"
- , attributes = toMap
- { name = "ps2" }
- }
- , XML.leaf
- { name = "input"
- , attributes = toMap
- { name = "usb" }
- }
- ]
- }
- ]
- }
- , XML.element
- { name = "mod1"
- , attributes =
- XML.emptyAttributes
- , content =
- [ key "KEY_LEFTSHIFT"
- , key "KEY_RIGHTSHIFT"
- ]
- }
- , XML.element
- { name = "mod2"
- , attributes =
- XML.emptyAttributes
- , content =
- [ key "KEY_LEFTCTRL"
- , key "KEY_RIGHTCTRL"
- ]
- }
- , XML.element
- { name = "mod3"
- , attributes =
- XML.emptyAttributes
- , content =
- [ key "KEY_RIGHTALT" ]
- }
- ]
- # params.inputFilterChargens
- }
- ]
- }
- ]
- }
- , provides = [ "Input" ]
- , routes =
- [ ServiceRoute.parentLabel
- "ROM"
- (Some "config")
- (Some "config -> event_filter.config")
- , ServiceRoute.childLabel
- "Input"
- "ps2_drv"
- (Some "ps2")
- (None Text)
- , ServiceRoute.childLabel
- "Input"
- "usb_drv"
- (Some "usb")
- (None Text)
- , ServiceRoute.child "Capture" "nitpicker"
- ]
- }
- , ps2_drv =
- Child.flat
- Child.Attributes::{
- , binary = "ps2_drv"
- , provides = [ "Input" ]
- , routes =
- [ ServiceRoute.childLabel
- "Platform"
- "platform_drv"
- (None Text)
- (Some "ps2_drv")
- ]
- }
- , usb_drv =
- Child.flat
- Child.Attributes::{
- , binary = "usb_drv"
- , config = Init.Config::{
- , attributes = toMap
- { uhci = "yes"
- , ohci = "yes"
- , ehci = "yes"
- , xhci = "yes"
- , bios_handoff = "yes"
- }
- , content =
- [ XML.leaf
- { name = "hid", attributes = XML.emptyAttributes }
- ]
- }
- , provides = [ "Input" ]
- , resources = Init.Resources::{
- , caps = 128
- , ram = Genode.units.MiB 12
- }
- , routes =
- [ ServiceRoute.childLabel
- "Platform"
- "platform_drv"
- (None Text)
- (Some "usb_drv")
- ]
- }
- , wm =
- Init.toChild
- params.wm
- Init.Attributes::{
- , provides = [ "Capture", "Event", "Gui", "Report", "ROM" ]
- , romReports = [ label "clipboard", label "shape" ]
- , routes =
- [ ServiceRoute.child "Framebuffer" "framebuffer"
- , ServiceRoute.child "Input" "event_filter"
- ]
- }
- , fonts_fs =
- Child.flat
- Child.Attributes::{
- , binary = "vfs"
- , config = Init.Config::{
- , content =
- [ XML.element
- { name = "vfs"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.leaf
- { name = "rom"
- , attributes = toMap
- { name = "Inconsolata.ttf" }
- }
- , XML.element
- { name = "dir"
- , attributes = toMap { name = "fonts" }
- , content =
- [ XML.element
- { name = "dir"
- , attributes = toMap { name = "title" }
- , content =
- [ XML.leaf
- { name = "ttf"
- , attributes = toMap
- { name = "regular"
- , path = "/Inconsolata.ttf"
- , size_px = "12"
- }
- }
- ]
- }
- , XML.element
- { name = "dir"
- , attributes = toMap { name = "text" }
- , content =
- [ XML.leaf
- { name = "ttf"
- , attributes = toMap
- { name = "regular"
- , path = "/Inconsolata.ttf"
- , size_px = "12"
- }
- }
- ]
- }
- , XML.element
- { name = "dir"
- , attributes = toMap
- { name = "annotation" }
- , content =
- [ XML.leaf
- { name = "ttf"
- , attributes = toMap
- { name = "regular"
- , path = "/Inconsolata.ttf"
- , size_px = "12"
- }
- }
- ]
- }
- , XML.element
- { name = "dir"
- , attributes = toMap
- { name = "monospace" }
- , content =
- [ XML.leaf
- { name = "ttf"
- , attributes = toMap
- { name = "regular"
- , path = "/Inconsolata.ttf"
- , size_px = "12"
- }
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- , defaultPolicy = Some DefaultPolicy::{
- , attributes = toMap { root = "/fonts" }
- }
- }
- , provides = [ "File_system" ]
- , resources = Init.Resources::{
- , caps = 256
- , ram = Genode.units.MiB 12
- }
- , routes = [ ServiceRoute.child "Block" "block_router" ]
- }
- , graphical-log =
- Init.toChild
- params.graphical-log
- Init.Attributes::{
- , routes =
- [ ServiceRoute.child "Gui" "wm"
- , ServiceRoute.child "File_system" "fonts_fs"
- ]
- }
- , fs-log =
- Init.toChild
- params.fs-log
- Init.Attributes::{
- , routes =
- [ ServiceRoute.childLabel
- "File_system"
- "chroot"
- (None Text)
- (Some "dump")
- ]
- }
- , rom_to_file =
- Child.flat
- Child.Attributes::{
- , binary = "rom_to_file"
- , config = Init.Config::{
- , attributes = toMap { rom = "init.config" }
- }
- , routes =
- [ ServiceRoute.childLabel
- "File_system"
- "chroot"
- (None Text)
- (Some "dump")
- , ServiceRoute.parentLabel
- "ROM"
- (Some "init.config")
- (Some "config")
- ]
- }
- , block =
- Child.flat
- Child.Attributes::{
- , binary = "ahci_drv"
- , config = Init.Config::{
- , defaultPolicy = Some DefaultPolicy::{
- , attributes = toMap { device = "0", writeable = "yes" }
- }
- }
- , provides = [ "Block" ]
- , resources = Init.Resources::{
- , caps = 256
- , ram = Genode.units.MiB 10
- }
- , routes =
- [ ServiceRoute.childLabel
- "Platform"
- "platform_drv"
- (None Text)
- (Some "ahci_drv")
- ]
- }
- , block_partitions =
- Child.flat
- Child.Attributes::{
- , binary = "part_block"
- , config = Init.Config::{
- , content =
- Prelude.List.map
- Natural
- XML.Type
- ( λ(i : Natural) →
- XML.leaf
- { name = "policy"
- , attributes =
- let partition =
- Prelude.Natural.show (i + 1)
-
- in toMap
- { label_suffix = " ${partition}"
- , partition
- , writeable = "yes"
- }
- }
- )
- (Prelude.Natural.enumerate 128)
- # [ XML.leaf
- { name = "report"
- , attributes = toMap { partitions = "yes" }
- }
- ]
- }
- , resources = Resources::{
- , caps = 256
- , ram = Genode.units.MiB 8
- }
- , provides = [ "Block" ]
- , routes =
- [ ServiceRoute.child "Block" "block"
- , ServiceRoute.child "Report" "block_router"
- ]
- }
- , block_router =
- Child.flat
- Child.Attributes::{
- , binary = "block_router"
- , config = Init.Config::{
- , attributes = toMap { verbose = "yes" }
- , content =
- [ XML.element
- { name = "default-policy"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.leaf
- { name = "partition"
- , attributes = toMap
- { type = params.partitionType
- , writeable = "yes"
- }
- }
- ]
- }
- ]
- }
- , resources = Resources::{
- , caps = 256
- , ram = Genode.units.MiB 8
- }
- , provides = [ "Block", "Report" ]
- , routes = [ ServiceRoute.child "Block" "block_partitions" ]
- }
- , file_system =
- Child.flat
- Child.Attributes::{
- , binary = "vfs"
- , config = Init.Config::{
- , content =
- [ XML.element
- { name = "vfs"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.element
- { name = "dir"
- , attributes = toMap { name = "ext2" }
- , content =
- [ XML.leaf
- { name = "rump"
- , attributes = toMap
- { fs = "ext2fs"
- , writeable = "yes"
- , ram = "8M"
- }
- }
- ]
- }
- ]
- }
- ]
- , policies =
- [ Policy::{
- , label = LabelSelector.suffix "nix/store"
- , attributes = toMap
- { root = "/ext2/nix/store", writeable = "no" }
- }
- , Policy::{
- , label = LabelSelector.prefix "chroot"
- , attributes = toMap
- { root = "/ext2", writeable = "yes", path = "/" }
- }
- , Policy::{
- , label = LabelSelector.prefix "init -> console"
- , attributes = toMap { root = "/", writeable = "yes" }
- }
- ]
- }
- , provides = [ "File_system" ]
- , resources = Init.Resources::{
- , caps = 256
- , ram = Genode.units.MiB 12
- }
- , routes = [ ServiceRoute.child "Block" "block_router" ]
- }
- , chroot =
- Child.flat
- Child.Attributes::{
- , binary = "chroot"
- , config = Init.Config::{
- , policies =
- [ Policy::{
- , label = LabelSelector.label "dump"
- , attributes = toMap
- { path = params.systemLabel, writeable = "yes" }
- }
- ]
- , defaultPolicy = Some DefaultPolicy::{
- , attributes = toMap { writeable = "yes" }
- }
- }
- , provides = [ "File_system" ]
- , routes = [ ServiceRoute.child "File_system" "file_system" ]
- }
- , nic_drv =
- Child.flat
- Child.Attributes::{
- , binary = "ipxe_nic_drv"
- , provides = [ "Nic" ]
- , resources = Init.Resources::{
- , caps = 128
- , ram = Genode.units.MiB 4
- }
- , routes =
- [ ServiceRoute.childLabel
- "Platform"
- "platform_drv"
- (None Text)
- (Some "nic_drv")
- ]
- }
- , nic_router =
- Child.flat
- Child.Attributes::{
- , binary = "nic_router"
- , config = Init.Config::{
- , content =
- [ XML.leaf
- { name = "uplink"
- , attributes = toMap { domain = "uplink" }
- }
- , XML.element
- { name = "domain"
- , attributes = toMap { name = "uplink" }
- , content =
- [ XML.leaf
- { name = "nat"
- , attributes = toMap
- { domain = "default"
- , tcp-ports = "1024"
- , udp-ports = "1024"
- , icmp-ids = "1024"
- }
- }
- ]
- }
- , XML.element
- { name = "domain"
- , attributes = toMap
- { name = "default", interface = "10.0.1.1/24" }
- , content =
- [ XML.leaf
- { name = "dhcp-server"
- , attributes = toMap
- { ip_first = "10.0.1.2"
- , ip_last = "10.0.1.200"
- , dns_server_from = "uplink"
- }
- }
- ]
- # Prelude.List.map
- Text
- XML.Type
- ( λ(proto : Text) →
- XML.element
- { name = proto
- , attributes = toMap
- { dst = "0.0.0.0/0"
- , domain = "uplink"
- }
- , content =
- [ XML.leaf
- { name = "permit-any"
- , attributes = toMap
- { domain = "uplink" }
- }
- ]
- }
- )
- [ "tcp", "udp", "icmp" ]
- }
- ]
- , defaultPolicy = Some DefaultPolicy::{
- , attributes = toMap { domain = "default" }
- }
- }
- , provides = [ "Nic" ]
- , resources = Init.Resources::{ ram = Genode.units.MiB 8 }
- , routes = [ ServiceRoute.child "Nic" "nic_drv" ]
- }
- , init =
- Init.toChild
- Init::{ children = params.guests }
- Init.Attributes::{
- , routes =
- [ ServiceRoute.parent "VM"
- , ServiceRoute.child "Gui" "wm"
- , { service =
- { name = "File_system"
- , label = LabelSelector.last "fonts"
- }
- , route =
- Init.Route.Type.Child
- { name = "fonts_fs"
- , label = None Text
- , diag = None Bool
- }
- }
- , { service =
- { name = "File_system"
- , label = LabelSelector.suffix "nix/store"
- }
- , route =
- Init.Route.Type.Child
- { name = "file_system"
- , label = Some "nix/store"
- , diag = None Bool
- }
- }
- , { service =
- { name = "File_system"
- , label = LabelSelector.prefix "console"
- }
- , route =
- Init.Route.Type.Child
- { name = "file_system"
- , label = None Text
- , diag = None Bool
- }
- }
- , ServiceRoute.child "File_system" "chroot"
- , ServiceRoute.child "Nic" "nic_router"
- , ServiceRoute.child "Rtc" "rtc"
- , ServiceRoute.parentLabel
- "ROM"
- (Some "platform_info")
- (Some "platform_info")
- , ServiceRoute.child "Report" "_report_rom"
- ]
- }
- }
- , routes = [ ServiceRoute.child "Timer" "timer" ]
- }
-
-in rootInit
diff --git a/nixos-modules/dhall/show_input.dhall b/nixos-modules/dhall/show_input.dhall
deleted file mode 100644
index 687a11b..0000000
--- a/nixos-modules/dhall/show_input.dhall
+++ /dev/null
@@ -1,41 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Prelude = Genode.Prelude
-
-let XML = Prelude.XML
-
-let Init = Genode.Init
-
-let Child = Init.Child
-
-let Resources = Init.Resources
-
-let ServiceRoute = Init.ServiceRoute
-
-in Child.flat
- Child.Attributes::{
- , binary = "show_input"
- , config = Init.Config::{
- , content =
- [ XML.element
- { name = "vfs"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.element
- { name = "dir"
- , attributes = toMap { name = "fonts" }
- , content =
- [ XML.leaf
- { name = "fs"
- , attributes = toMap { label = "fonts" }
- }
- ]
- }
- ]
- }
- ]
- }
- , resources = Resources::{ ram = Genode.units.MiB 32 }
- , routes =
- [ ServiceRoute.parent "File_system", ServiceRoute.parent "Gui" ]
- }
diff --git a/nixos-modules/dhall/vbox-guest.dhall b/nixos-modules/dhall/vbox-guest.dhall
deleted file mode 100644
index 4e26bee..0000000
--- a/nixos-modules/dhall/vbox-guest.dhall
+++ /dev/null
@@ -1,219 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Prelude = Genode.Prelude
-
-let XML = Prelude.XML
-
-let Init = Genode.Init
-
-let Child = Init.Child
-
-let Resources = Init.Resources
-
-let ServiceRoute = Init.ServiceRoute
-
-let Libc = Genode.Libc
-
-let VFS = Genode.VFS
-
-let BootFormat = < ISO | VDI >
-
-let Params
- : Type
- = { bootFilename : Text
- , bootPkg : Text
- , bootUuid : Text
- , bootFormat : BootFormat
- , memorySize : Natural
- , vmName : Text
- }
-
-let toVbox =
- λ(params : Params) →
- let vboxConfig =
- let hardDisks =
- merge
- { ISO = XML.text ""
- , VDI =
- XML.leaf
- { name = "HardDisk"
- , attributes = toMap
- { uuid = "{${params.bootUuid}}"
- , location = "${params.bootFilename}"
- , format = "VDI"
- , type = "Normal"
- }
- }
- }
- params.bootFormat
-
- let dvdImages =
- merge
- { ISO =
- XML.leaf
- { name = "Image"
- , attributes = toMap
- { uuid = "{${params.bootUuid}}"
- , location = "${params.bootFilename}"
- }
- }
- , VDI = XML.text ""
- }
- params.bootFormat
-
- let attachedDevices =
- XML.element
- { name = "AttachedDevice"
- , attributes =
- merge
- { ISO = toMap
- { passthrough = "false"
- , type = "DVD"
- , port = "3"
- , device = "0"
- }
- , VDI = toMap
- { type = "HardDisk", port = "0", device = "0" }
- }
- params.bootFormat
- , content =
- [ XML.leaf
- { name = "Image"
- , attributes = toMap
- { uuid = "{${params.bootUuid}}" }
- }
- ]
- }
-
- in ''
-
-
-
- ${XML.render hardDisks}
- ${XML.render dvdImages}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ${XML.render attachedDevices}
-
-
-
-
- ''
-
- in Child.flat
- Child.Attributes::{
- , binary = "virtualbox5"
- , config =
- ( Libc.toConfig
- Libc::{
- , vfs =
- let mutableVfs =
- let fsNode =
- [ XML.leaf
- { name = "fs"
- , attributes = toMap
- { label = "nix/store"
- , root = "${params.bootPkg}"
- }
- }
- ]
-
- in merge
- { ISO =
- [ XML.leaf
- { name = "fs"
- , attributes = toMap
- { writeable = "yes" }
- }
- , XML.element
- { name = "import"
- , attributes = toMap
- { overwrite = "no" }
- , content = fsNode
- }
- ]
- , VDI =
- [ XML.leaf
- { name = "fs"
- , attributes = toMap
- { writeable = "yes" }
- }
- , XML.element
- { name = "import"
- , attributes = toMap
- { overwrite = "no" }
- , content = fsNode
- }
- ]
- }
- params.bootFormat
-
- in [ VFS.inline "machine.vbox" vboxConfig
- , VFS.dir
- "dev"
- [ VFS.leaf "log"
- , VFS.leaf "null"
- , VFS.leaf "rtc"
- ]
- ]
- # mutableVfs
- }
- )
- with attributes = toMap
- { vbox_file = "machine.vbox", vm_name = params.vmName }
- , resources = Resources::{
- , caps = 1024
- , ram =
- Genode.units.MiB 128 + Genode.units.MiB params.memorySize
- }
- , routes =
- [ ServiceRoute.parent "File_system"
- , ServiceRoute.parent "Nic"
- , ServiceRoute.parent "Gui"
- , ServiceRoute.parent "Rtc"
- , ServiceRoute.parent "Timer"
- , ServiceRoute.parent "VM"
- , ServiceRoute.parent "Report"
- , ServiceRoute.parentLabel
- "ROM"
- (Some "platform_info")
- (Some "platform_info")
- ]
- }
-
-in toVbox
diff --git a/nixos-modules/dhall/vesa_fb_drv.dhall b/nixos-modules/dhall/vesa_fb_drv.dhall
deleted file mode 100644
index 50c7daa..0000000
--- a/nixos-modules/dhall/vesa_fb_drv.dhall
+++ /dev/null
@@ -1,27 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let ServiceRoute = Genode.Init.ServiceRoute
-
-let Child = Genode.Init.Child
-
-in Child.flat
- Child.Attributes::{
- , binary = "vesa_fb_drv"
- , config = Genode.Init.Config::{
- , attributes = toMap { width = "1024", height = "768" }
- }
- , provides = [ "Framebuffer" ]
- , resources = Genode.Init.Resources::{
- , caps = 256
- , ram = Genode.units.MiB 16
- }
- , routes =
- [ ServiceRoute.parent "IO_MEM"
- , ServiceRoute.parent "IO_PORT"
- , ServiceRoute.childLabel
- "Platform"
- "platform_drv"
- (None Text)
- (Some "vesa_fb_drv")
- ]
- }
diff --git a/nixos-modules/dhall/wm.dhall b/nixos-modules/dhall/wm.dhall
deleted file mode 100644
index 442e089..0000000
--- a/nixos-modules/dhall/wm.dhall
+++ /dev/null
@@ -1,237 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Prelude = Genode.Prelude
-
-let XML = Prelude.XML
-
-let Init = Genode.Init
-
-let Child = Init.Child
-
-let Resources = Init.Resources
-
-let ServiceRoute = Init.ServiceRoute
-
-let Policy = Init.Config.Policy
-
-let DefaultPolicy = Init.Config.DefaultPolicy
-
-let LabelSelector = Init.LabelSelector
-
-let label =
- λ(label : Text) →
- { local = label, route = label } : Child.Attributes.Label
-
-in Init::{
- , children = toMap
- { nitpicker =
- Child.flat
- Child.Attributes::{
- , binary = "nitpicker"
- , config = Init.Config::{
- , attributes = toMap { focus = "rom" }
- , content =
- [ XML.text
- ''
-
-
-
-
-
-
- ''
- ]
- , policies =
- [ Policy::{
- , label = LabelSelector.prefix "pointer"
- , attributes = toMap { domain = "pointer" }
- }
- , Policy::{
- , label = LabelSelector.suffix "-> decorator"
- , attributes = toMap { domain = "decorator" }
- }
- , Policy::{
- , label = LabelSelector.prefix "wm"
- , attributes = toMap { domain = "desktop" }
- }
- , Policy::{
- , label = LabelSelector.label "backdrop"
- , attributes = toMap { domain = "backdrop" }
- }
- ]
- , defaultPolicy = Some DefaultPolicy::{
- , attributes = toMap { domain = "default" }
- }
- }
- , provides = [ "Gui", "Capture", "Event" ]
- , resources = Resources::{ caps = 256, ram = Genode.units.MiB 64 }
- , routes =
- [ ServiceRoute.parent "Framebuffer"
- , ServiceRoute.parent "Input"
- ]
- }
- , pointer =
- Child.flat
- Child.Attributes::{
- , binary = "pointer"
- , routes = [ ServiceRoute.child "Gui" "nitpicker" ]
- }
- , wm =
- Child.flat
- Child.Attributes::{
- , binary = "wm"
- , config = Init.Config::{
- , policies =
- [ Policy::{
- , attributes = toMap { role = "decorator" }
- , label = LabelSelector.prefix "decorator"
- }
- , Policy::{
- , attributes = toMap { role = "layouter" }
- , label = LabelSelector.prefix "layouter"
- }
- ]
- , defaultPolicy = Some DefaultPolicy::{=}
- }
- , provides = [ "Gui", "Report", "ROM" ]
- , reportRoms = [ label "focus", label "resize_request" ]
- , romReports =
- [ label "focus_request"
- , label "pointer"
- , label "shape"
- , label "window_list"
- ]
- , resources = Init.Resources::{
- , caps = 256
- , ram = Genode.units.MiB 8
- }
- , routes =
- [ ServiceRoute.childLabel
- "Gui"
- "nitpicker"
- (Some "")
- (Some "focus")
- , ServiceRoute.child "Gui" "nitpicker"
- , ServiceRoute.parentLabel
- "Report"
- (Some "clipboard")
- (Some "clipboard")
- , ServiceRoute.parentLabel
- "Report"
- (Some "shape")
- (Some "shape")
- ]
- }
- , layouter =
- Child.flat
- Child.Attributes::{
- , binary = "window_layouter"
- , config = Init.Config::{
- , attributes = toMap { rules = "rom" }
- , content =
- [ XML.text
- ''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ''
- ]
- }
- , provides = [ "Gui", "Report", "ROM" ]
- , romReports =
- [ label "focus"
- , label "resize_request"
- , label "rules"
- , label "window_layout"
- ]
- , reportRoms =
- [ label "decorator_margins"
- , label "focus_request"
- , label "hover"
- , label "rules"
- , label "shape"
- , label "window_list"
- ]
- , resources = Init.Resources::{
- , caps = 256
- , ram = Genode.units.MiB 8
- }
- , routes = [ ServiceRoute.child "Gui" "wm" ]
- }
- , decorator =
- Child.flat
- Child.Attributes::{
- , binary = "decorator"
- , config = Init.Config::{
- , content =
- [ XML.element
- { name = "controls"
- , attributes = XML.emptyAttributes
- , content =
- [ XML.leaf
- { name = "maximizer"
- , attributes = XML.emptyAttributes
- }
- , XML.leaf
- { name = "title", attributes = XML.emptyAttributes }
- ]
- }
- ]
- , defaultPolicy = Some DefaultPolicy::{=}
- }
- , provides = [ "Gui", "Report", "ROM" ]
- , reportRoms = [ label "window_layout", label "pointer" ]
- , romReports = [ label "decorator_margins", label "hover" ]
- , resources = Init.Resources::{
- , caps = 128
- , ram = Genode.units.MiB 12
- }
- , routes = [ ServiceRoute.child "Gui" "wm" ]
- }
- }
- , routes = [ ServiceRoute.parent "Timer" ]
- , services =
- [ ServiceRoute.child "Gui" "wm"
- , ServiceRoute.child "Report" "wm"
- , ServiceRoute.child "ROM" "wm"
- , ServiceRoute.child "Event" "Nitpicker"
- , ServiceRoute.child "Capture" "Nitpicker"
- ]
- }
diff --git a/nixos-modules/dhall/workman.chargen.dhall b/nixos-modules/dhall/workman.chargen.dhall
deleted file mode 100644
index 6988bf0..0000000
--- a/nixos-modules/dhall/workman.chargen.dhall
+++ /dev/null
@@ -1,245 +0,0 @@
-let Genode = env:DHALL_GENODE
-
-let Prelude = Genode.Prelude
-
-let XML = Prelude.XML
-
-let Key = < Ascii : Natural | Char : Text | Code : Natural > : Type
-
-let Map =
- { Type =
- { keys : Prelude.Map.Type Text Key
- , mod1 : Bool
- , mod2 : Bool
- , mod3 : Bool
- , mod4 : Bool
- }
- , default = { mod1 = False, mod2 = False, mod3 = False, mod4 = False }
- }
-
-let boolToAttr = λ(_ : Bool) → if _ then "yes" else "no"
-
-let keyToXML =
- λ(x : Prelude.Map.Entry Text Key) →
- XML.leaf
- { name = "key"
- , attributes =
- [ merge
- { Ascii =
- λ(_ : Natural) →
- { mapKey = "ascii", mapValue = Prelude.Natural.show _ }
- , Char = λ(_ : Text) → { mapKey = "char", mapValue = _ }
- , Code =
- λ(_ : Natural) →
- { mapKey = "code", mapValue = Prelude.Natural.show _ }
- }
- x.mapValue
- , { mapKey = "name", mapValue = x.mapKey }
- ]
- }
-
-let mapToXML =
- λ(map : Map.Type) →
- XML.element
- { name = "map"
- , attributes = toMap
- { mod1 = boolToAttr map.mod1
- , mod2 = boolToAttr map.mod2
- , mod3 = boolToAttr map.mod3
- , mod4 = boolToAttr map.mod4
- }
- , content =
- Prelude.List.map
- (Prelude.Map.Entry Text Key)
- XML.Type
- keyToXML
- map.keys
- }
-
-let workman =
- [ Map::{
- , keys = toMap
- { KEY_ESC = Key.Ascii 27
- , KEY_1 = Key.Char "1"
- , KEY_2 = Key.Char "2"
- , KEY_3 = Key.Char "3"
- , KEY_4 = Key.Char "4"
- , KEY_5 = Key.Char "5"
- , KEY_6 = Key.Char "6"
- , KEY_7 = Key.Char "7"
- , KEY_8 = Key.Char "8"
- , KEY_9 = Key.Char "9"
- , KEY_0 = Key.Char "0"
- , KEY_MINUS = Key.Char "-"
- , KEY_EQUAL = Key.Char "="
- , KEY_BACKSPACE = Key.Ascii 8
- , KEY_TAB = Key.Ascii 9
- , KEY_Q = Key.Char "q"
- , KEY_W = Key.Char "d"
- , KEY_E = Key.Char "r"
- , KEY_R = Key.Char "w"
- , KEY_T = Key.Char "b"
- , KEY_Y = Key.Char "j"
- , KEY_U = Key.Char "f"
- , KEY_I = Key.Char "u"
- , KEY_O = Key.Char "p"
- , KEY_P = Key.Char ";"
- , KEY_LEFTBRACE = Key.Char "["
- , KEY_RIGHTBRACE = Key.Char "]"
- , KEY_ENTER = Key.Ascii 10
- , KEY_A = Key.Char "a"
- , KEY_S = Key.Char "s"
- , KEY_D = Key.Char "h"
- , KEY_F = Key.Char "t"
- , KEY_G = Key.Char "g"
- , KEY_H = Key.Char "y"
- , KEY_J = Key.Char "n"
- , KEY_K = Key.Char "e"
- , KEY_L = Key.Char "o"
- , KEY_SEMICOLON = Key.Char "i"
- , KEY_APOSTROPHE = Key.Char "'"
- , KEY_GRAVE = Key.Char "`"
- , KEY_BACKSLASH = Key.Ascii 92
- , KEY_Z = Key.Char "z"
- , KEY_X = Key.Char "x"
- , KEY_C = Key.Char "m"
- , KEY_V = Key.Char "c"
- , KEY_B = Key.Char "v"
- , KEY_N = Key.Char "k"
- , KEY_M = Key.Char "l"
- , KEY_COMMA = Key.Char ","
- , KEY_DOT = Key.Char "."
- , KEY_SLASH = Key.Char "/"
- , KEY_SPACE = Key.Char " "
- , KEY_KP7 = Key.Char "7"
- , KEY_KP8 = Key.Char "8"
- , KEY_KP9 = Key.Char "9"
- , KEY_KPMINUS = Key.Char "-"
- , KEY_KP4 = Key.Char "4"
- , KEY_KP5 = Key.Char "5"
- , KEY_KP6 = Key.Char "6"
- , KEY_KPPLUS = Key.Char "+"
- , KEY_KP1 = Key.Char "1"
- , KEY_KP2 = Key.Char "2"
- , KEY_KP3 = Key.Char "3"
- , KEY_KP0 = Key.Char "0"
- , KEY_KPDOT = Key.Char "."
- , KEY_KPENTER = Key.Ascii 10
- , KEY_KPSLASH = Key.Char "/"
- }
- }
- , Map::{
- , mod1 = True
- , keys = toMap
- { KEY_1 = Key.Char "!"
- , KEY_2 = Key.Char "@"
- , KEY_3 = Key.Char "#"
- , KEY_4 = Key.Char "\$"
- , KEY_5 = Key.Char "%"
- , KEY_6 = Key.Char "^"
- , KEY_7 = Key.Ascii 38
- , KEY_8 = Key.Char "*"
- , KEY_9 = Key.Char "("
- , KEY_0 = Key.Char ")"
- , KEY_MINUS = Key.Char "_"
- , KEY_EQUAL = Key.Char "+"
- , KEY_Q = Key.Char "Q"
- , KEY_W = Key.Char "D"
- , KEY_E = Key.Char "R"
- , KEY_R = Key.Char "W"
- , KEY_T = Key.Char "B"
- , KEY_Y = Key.Char "J"
- , KEY_U = Key.Char "F"
- , KEY_I = Key.Char "U"
- , KEY_O = Key.Char "P"
- , KEY_P = Key.Char ":"
- , KEY_LEFTBRACE = Key.Char "{"
- , KEY_RIGHTBRACE = Key.Char "}"
- , KEY_A = Key.Char "A"
- , KEY_S = Key.Char "S"
- , KEY_D = Key.Char "H"
- , KEY_F = Key.Char "T"
- , KEY_G = Key.Char "G"
- , KEY_H = Key.Char "Y"
- , KEY_J = Key.Char "N"
- , KEY_K = Key.Char "E"
- , KEY_L = Key.Char "O"
- , KEY_SEMICOLON = Key.Char "I"
- , KEY_APOSTROPHE = Key.Ascii 34
- , KEY_GRAVE = Key.Char "~"
- , KEY_BACKSLASH = Key.Char "|"
- , KEY_Z = Key.Char "Z"
- , KEY_X = Key.Char "X"
- , KEY_C = Key.Char "M"
- , KEY_V = Key.Char "C"
- , KEY_B = Key.Char "V"
- , KEY_N = Key.Char "K"
- , KEY_M = Key.Char "L"
- , KEY_COMMA = Key.Ascii 60
- , KEY_DOT = Key.Ascii 62
- , KEY_SLASH = Key.Char "?"
- }
- }
- , Map::{
- , mod2 = True
- , keys = toMap
- { KEY_A = Key.Ascii 1
- , KEY_B = Key.Ascii 22
- , KEY_C = Key.Ascii 13
- , KEY_D = Key.Ascii 8
- , KEY_E = Key.Ascii 18
- , KEY_F = Key.Ascii 20
- , KEY_G = Key.Ascii 7
- , KEY_H = Key.Ascii 25
- , KEY_I = Key.Ascii 21
- , KEY_J = Key.Ascii 14
- , KEY_K = Key.Ascii 5
- , KEY_L = Key.Ascii 15
- , KEY_M = Key.Ascii 12
- , KEY_N = Key.Ascii 11
- , KEY_O = Key.Ascii 16
- , KEY_P = Key.Ascii 9
- , KEY_Q = Key.Ascii 17
- , KEY_R = Key.Ascii 23
- , KEY_S = Key.Ascii 19
- , KEY_T = Key.Ascii 2
- , KEY_U = Key.Ascii 6
- , KEY_V = Key.Ascii 3
- , KEY_W = Key.Ascii 4
- , KEY_X = Key.Ascii 24
- , KEY_Y = Key.Ascii 10
- , KEY_Z = Key.Ascii 26
- }
- }
- , Map::{
- , mod3 = True
- , keys = toMap
- { KEY_4 = Key.Code 8364
- , KEY_A = Key.Code 228
- , KEY_S = Key.Code 223
- , KEY_I = Key.Code 252
- , KEY_DOT = Key.Code 8230
- , KEY_K = Key.Code 235
- , KEY_C = Key.Code 181
- , KEY_L = Key.Code 246
- }
- }
- , Map::{
- , mod1 = True
- , mod3 = True
- , keys = toMap
- { KEY_0 = Key.Code 8320
- , KEY_1 = Key.Code 8321
- , KEY_2 = Key.Code 8322
- , KEY_3 = Key.Code 8323
- , KEY_4 = Key.Code 8324
- , KEY_5 = Key.Code 8325
- , KEY_6 = Key.Code 8326
- , KEY_7 = Key.Code 8327
- , KEY_8 = Key.Code 8328
- , KEY_9 = Key.Code 8329
- }
- }
- ]
-
-in Prelude.List.map Map.Type XML.Type mapToXML workman
diff --git a/tests/test-driver/test-driver.py b/tests/test-driver/test-driver.py
deleted file mode 100644
index 45137fc..0000000
--- a/tests/test-driver/test-driver.py
+++ /dev/null
@@ -1,912 +0,0 @@
-#! /somewhere/python3
-# Copyright (c) 2003-2020 Nixpkgs/NixOS contributors
-
-from contextlib import contextmanager, _GeneratorContextManager
-from queue import Queue, Empty
-from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List
-from xml.sax.saxutils import XMLGenerator
-import _thread
-import atexit
-import base64
-import codecs
-import os
-import pathlib
-import ptpython.repl
-import pty
-import re
-import shlex
-import shutil
-import socket
-import subprocess
-import sys
-import tempfile
-import time
-import unicodedata
-
-CHAR_TO_KEY = {
- "A": "shift-a",
- "N": "shift-n",
- "-": "0x0C",
- "_": "shift-0x0C",
- "B": "shift-b",
- "O": "shift-o",
- "=": "0x0D",
- "+": "shift-0x0D",
- "C": "shift-c",
- "P": "shift-p",
- "[": "0x1A",
- "{": "shift-0x1A",
- "D": "shift-d",
- "Q": "shift-q",
- "]": "0x1B",
- "}": "shift-0x1B",
- "E": "shift-e",
- "R": "shift-r",
- ";": "0x27",
- ":": "shift-0x27",
- "F": "shift-f",
- "S": "shift-s",
- "'": "0x28",
- '"': "shift-0x28",
- "G": "shift-g",
- "T": "shift-t",
- "`": "0x29",
- "~": "shift-0x29",
- "H": "shift-h",
- "U": "shift-u",
- "\\": "0x2B",
- "|": "shift-0x2B",
- "I": "shift-i",
- "V": "shift-v",
- ",": "0x33",
- "<": "shift-0x33",
- "J": "shift-j",
- "W": "shift-w",
- ".": "0x34",
- ">": "shift-0x34",
- "K": "shift-k",
- "X": "shift-x",
- "/": "0x35",
- "?": "shift-0x35",
- "L": "shift-l",
- "Y": "shift-y",
- " ": "spc",
- "M": "shift-m",
- "Z": "shift-z",
- "\n": "ret",
- "!": "shift-0x02",
- "@": "shift-0x03",
- "#": "shift-0x04",
- "$": "shift-0x05",
- "%": "shift-0x06",
- "^": "shift-0x07",
- "&": "shift-0x08",
- "*": "shift-0x09",
- "(": "shift-0x0A",
- ")": "shift-0x0B",
-}
-
-# Forward references
-log: "Logger"
-machines: "List[Machine]"
-
-
-def eprint(*args: object, **kwargs: Any) -> None:
- print(*args, file=sys.stderr, **kwargs)
-
-
-def make_command(args: list) -> str:
- return " ".join(map(shlex.quote, (map(str, args))))
-
-
-def retry(fn: Callable) -> None:
- """Call the given function repeatedly, with 1 second intervals,
- until it returns True or a timeout is reached.
- """
-
- for _ in range(900):
- if fn(False):
- return
- time.sleep(1)
-
- if not fn(True):
- raise Exception("action timed out")
-
-
-class Logger:
- def __init__(self) -> None:
- self.logfile = os.environ.get("LOGFILE", "/dev/null")
- self.logfile_handle = codecs.open(self.logfile, "wb")
- self.xml = XMLGenerator(self.logfile_handle, encoding="utf-8")
- self.queue: "Queue[Dict[str, str]]" = Queue()
-
- self.xml.startDocument()
- self.xml.startElement("logfile", attrs={})
-
- def close(self) -> None:
- self.xml.endElement("logfile")
- self.xml.endDocument()
- self.logfile_handle.close()
-
- def sanitise(self, message: str) -> str:
- return "".join(ch for ch in message if unicodedata.category(ch)[0] != "C")
-
- def maybe_prefix(self, message: str, attributes: Dict[str, str]) -> str:
- if "machine" in attributes:
- return "{}: {}".format(attributes["machine"], message)
- return message
-
- def log_line(self, message: str, attributes: Dict[str, str]) -> None:
- self.xml.startElement("line", attributes)
- self.xml.characters(message)
- self.xml.endElement("line")
-
- def log(self, message: str, attributes: Dict[str, str] = {}) -> None:
- eprint(self.maybe_prefix(message, attributes))
- self.drain_log_queue()
- self.log_line(message, attributes)
-
- def enqueue(self, message: Dict[str, str]) -> None:
- self.queue.put(message)
-
- def drain_log_queue(self) -> None:
- try:
- while True:
- item = self.queue.get_nowait()
- attributes = {"machine": item["machine"], "type": "serial"}
- self.log_line(self.sanitise(item["msg"]), attributes)
- except Empty:
- pass
-
- @contextmanager
- def nested(self, message: str, attributes: Dict[str, str] = {}) -> Iterator[None]:
- eprint(self.maybe_prefix(message, attributes))
-
- self.xml.startElement("nest", attrs={})
- self.xml.startElement("head", attributes)
- self.xml.characters(message)
- self.xml.endElement("head")
-
- tic = time.time()
- self.drain_log_queue()
- yield
- self.drain_log_queue()
- toc = time.time()
- self.log("({:.2f} seconds)".format(toc - tic))
-
- self.xml.endElement("nest")
-
-
-class Machine:
- def __init__(self, args: Dict[str, Any]) -> None:
- if "name" in args:
- self.name = args["name"]
- else:
- self.name = "machine"
- cmd = args.get("startCommand", None)
- if cmd:
- match = re.search("bin/run-(.+)-vm$", cmd)
- if match:
- self.name = match.group(1)
-
- self.script = args.get("startCommand", self.create_startcommand(args))
-
- tmp_dir = os.environ.get("TMPDIR", tempfile.gettempdir())
-
- def create_dir(name: str) -> str:
- path = os.path.join(tmp_dir, name)
- os.makedirs(path, mode=0o700, exist_ok=True)
- return path
-
- self.state_dir = create_dir("vm-state-{}".format(self.name))
- self.shared_dir = create_dir("shared-xchg")
-
- self.booted = False
- self.connected = False
- self.pid: Optional[int] = None
- self.socket = None
- self.monitor: Optional[socket.socket] = None
- self.logger: Logger = args["log"]
- self.serialQueue: "Queue[str]" = Queue()
-
- self.allow_reboot = args.get("allowReboot", False)
-
- @staticmethod
- def create_startcommand(args: Dict[str, str]) -> str:
- net_backend = "-netdev user,id=net0"
- net_frontend = "-device virtio-net-pci,netdev=net0"
-
- start_command = "qemu-system-x86_64 -m 384 $QEMU_OPTS "
-
- if "hda" in args:
- hda_path = os.path.abspath(args["hda"])
- if args.get("hdaInterface", "") == "scsi":
- start_command += (
- "-drive id=hda,file="
- + hda_path
- + ",werror=report,if=none "
- + "-device scsi-hd,drive=hda "
- )
- else:
- start_command += (
- "-drive file="
- + hda_path
- + ",if="
- + args["hdaInterface"]
- + ",werror=report "
- )
-
- if "cdrom" in args:
- start_command += "-cdrom " + args["cdrom"] + " "
-
- if "usb" in args:
- start_command += (
- "-device piix3-usb-uhci -drive "
- + "id=usbdisk,file="
- + args["usb"]
- + ",if=none,readonly "
- + "-device usb-storage,drive=usbdisk "
- )
- if "bios" in args:
- start_command += "-bios " + args["bios"] + " "
-
- start_command += args.get("qemuFlags", "")
-
- return start_command
-
- def is_up(self) -> bool:
- return self.booted and self.connected
-
- def log(self, msg: str) -> None:
- self.logger.log(msg, {"machine": self.name})
-
- def nested(self, msg: str, attrs: Dict[str, str] = {}) -> _GeneratorContextManager:
- my_attrs = {"machine": self.name}
- my_attrs.update(attrs)
- return self.logger.nested(msg, my_attrs)
-
- def wait_for_monitor_prompt(self) -> str:
- assert self.monitor is not None
- answer = ""
- while True:
- undecoded_answer = self.monitor.recv(1024)
- if not undecoded_answer:
- break
- answer += undecoded_answer.decode()
- if answer.endswith("(qemu) "):
- break
- return answer
-
- def send_monitor_command(self, command: str) -> str:
- message = ("{}\n".format(command)).encode()
- self.log("sending monitor command: {}".format(command))
- assert self.monitor is not None
- self.monitor.send(message)
- return self.wait_for_monitor_prompt()
-
- def wait_for_unit(self, unit: str, user: Optional[str] = None) -> None:
- """Wait for a systemd unit to get into "active" state.
- Throws exceptions on "failed" and "inactive" states as well as
- after timing out.
- """
-
- def check_active(_: Any) -> bool:
- info = self.get_unit_info(unit, user)
- state = info["ActiveState"]
- if state == "failed":
- raise Exception('unit "{}" reached state "{}"'.format(unit, state))
-
- if state == "inactive":
- status, jobs = self.systemctl("list-jobs --full 2>&1", user)
- if "No jobs" in jobs:
- info = self.get_unit_info(unit, user)
- if info["ActiveState"] == state:
- raise Exception(
- (
- 'unit "{}" is inactive and there ' "are no pending jobs"
- ).format(unit)
- )
-
- return state == "active"
-
- retry(check_active)
-
- def get_unit_info(self, unit: str, user: Optional[str] = None) -> Dict[str, str]:
- status, lines = self.systemctl('--no-pager show "{}"'.format(unit), user)
- if status != 0:
- raise Exception(
- 'retrieving systemctl info for unit "{}" {} failed with exit code {}'.format(
- unit, "" if user is None else 'under user "{}"'.format(user), status
- )
- )
-
- line_pattern = re.compile(r"^([^=]+)=(.*)$")
-
- def tuple_from_line(line: str) -> Tuple[str, str]:
- match = line_pattern.match(line)
- assert match is not None
- return match[1], match[2]
-
- return dict(
- tuple_from_line(line)
- for line in lines.split("\n")
- if line_pattern.match(line)
- )
-
- def systemctl(self, q: str, user: Optional[str] = None) -> Tuple[int, str]:
- if user is not None:
- q = q.replace("'", "\\'")
- return self.execute(
- (
- "su -l {} --shell /bin/sh -c "
- "$'XDG_RUNTIME_DIR=/run/user/`id -u` "
- "systemctl --user {}'"
- ).format(user, q)
- )
- return self.execute("systemctl {}".format(q))
-
- def require_unit_state(self, unit: str, require_state: str = "active") -> None:
- with self.nested(
- "checking if unit ‘{}’ has reached state '{}'".format(unit, require_state)
- ):
- info = self.get_unit_info(unit)
- state = info["ActiveState"]
- if state != require_state:
- raise Exception(
- "Expected unit ‘{}’ to to be in state ".format(unit)
- + "'{}' but it is in state ‘{}’".format(require_state, state)
- )
-
- def execute(self, command: str) -> Tuple[int, str]:
- self.connect()
-
- out_command = "( {} ); echo '|!=EOF' $?\n".format(command)
- self.shell.send(out_command.encode())
-
- output = ""
- status_code_pattern = re.compile(r"(.*)\|\!=EOF\s+(\d+)")
-
- while True:
- chunk = self.shell.recv(4096).decode(errors="ignore")
- match = status_code_pattern.match(chunk)
- if match:
- output += match[1]
- status_code = int(match[2])
- return (status_code, output)
- output += chunk
-
- def succeed(self, *commands: str) -> str:
- """Execute each command and check that it succeeds."""
- output = ""
- for command in commands:
- with self.nested("must succeed: {}".format(command)):
- (status, out) = self.execute(command)
- if status != 0:
- self.log("output: {}".format(out))
- raise Exception(
- "command `{}` failed (exit code {})".format(command, status)
- )
- output += out
- return output
-
- def fail(self, *commands: str) -> None:
- """Execute each command and check that it fails."""
- for command in commands:
- with self.nested("must fail: {}".format(command)):
- status, output = self.execute(command)
- if status == 0:
- raise Exception(
- "command `{}` unexpectedly succeeded".format(command)
- )
-
- def wait_until_succeeds(self, command: str) -> str:
- """Wait until a command returns success and return its output.
- Throws an exception on timeout.
- """
- output = ""
-
- def check_success(_: Any) -> bool:
- nonlocal output
- status, output = self.execute(command)
- return status == 0
-
- with self.nested("waiting for success: {}".format(command)):
- retry(check_success)
- return output
-
- def wait_until_fails(self, command: str) -> str:
- """Wait until a command returns failure.
- Throws an exception on timeout.
- """
- output = ""
-
- def check_failure(_: Any) -> bool:
- nonlocal output
- status, output = self.execute(command)
- return status != 0
-
- with self.nested("waiting for failure: {}".format(command)):
- retry(check_failure)
- return output
-
- def wait_for_shutdown(self) -> None:
- if not self.booted:
- return
-
- with self.nested("waiting for the VM to power off"):
- sys.stdout.flush()
- self.process.wait()
-
- self.pid = None
- self.booted = False
- self.connected = False
-
- def get_tty_text(self, tty: str) -> str:
- status, output = self.execute(
- "fold -w$(stty -F /dev/tty{0} size | "
- "awk '{{print $2}}') /dev/vcs{0}".format(tty)
- )
- return output
-
- def wait_until_tty_matches(self, tty: str, regexp: str) -> None:
- """Wait until the visible output on the chosen TTY matches regular
- expression. Throws an exception on timeout.
- """
- matcher = re.compile(regexp)
-
- def tty_matches(last: bool) -> bool:
- text = self.get_tty_text(tty)
- if last:
- self.log(
- f"Last chance to match /{regexp}/ on TTY{tty}, "
- f"which currently contains: {text}"
- )
- return len(matcher.findall(text)) > 0
-
- with self.nested("waiting for {} to appear on tty {}".format(regexp, tty)):
- retry(tty_matches)
-
- def wait_until_serial_output(self, regexp: str) -> None:
- """Wait until the serial output matches regular expression.
- Throws an exception on timeout.
- """
- matcher = re.compile(regexp)
-
- def serial_matches(last: bool) -> bool:
- while not self.serialQueue.empty():
- text = self.serialQueue.get()
- if last:
- self.log(
- f"Last chance to match /{regexp}/ on serial, "
- f"which currently contains: {text}"
- )
- if len(matcher.findall(text)) > 0:
- return True
- return False
-
- with self.nested("waiting for {} to appear on serial output".format(regexp)):
- retry(serial_matches)
-
- def send_chars(self, chars: List[str]) -> None:
- with self.nested("sending keys ‘{}‘".format(chars)):
- for char in chars:
- self.send_key(char)
-
- def wait_for_file(self, filename: str) -> None:
- """Waits until the file exists in machine's file system."""
-
- def check_file(_: Any) -> bool:
- status, _ = self.execute("test -e {}".format(filename))
- return status == 0
-
- with self.nested("waiting for file ‘{}‘".format(filename)):
- retry(check_file)
-
- def wait_for_open_port(self, port: int) -> None:
- def port_is_open(_: Any) -> bool:
- status, _ = self.execute("nc -z localhost {}".format(port))
- return status == 0
-
- with self.nested("waiting for TCP port {}".format(port)):
- retry(port_is_open)
-
- def wait_for_closed_port(self, port: int) -> None:
- def port_is_closed(_: Any) -> bool:
- status, _ = self.execute("nc -z localhost {}".format(port))
- return status != 0
-
- retry(port_is_closed)
-
- def start_job(self, jobname: str, user: Optional[str] = None) -> Tuple[int, str]:
- return self.systemctl("start {}".format(jobname), user)
-
- def stop_job(self, jobname: str, user: Optional[str] = None) -> Tuple[int, str]:
- return self.systemctl("stop {}".format(jobname), user)
-
- def wait_for_job(self, jobname: str) -> None:
- self.wait_for_unit(jobname)
-
- def connect(self) -> None:
- if self.connected:
- return
-
- with self.nested("waiting for the VM to finish booting"):
- self.start()
-
- tic = time.time()
- self.shell.recv(1024)
- # TODO: Timeout
- toc = time.time()
-
- self.log("connected to guest root shell")
- self.log("(connecting took {:.2f} seconds)".format(toc - tic))
- self.connected = True
-
- def screenshot(self, filename: str) -> None:
- out_dir = os.environ.get("out", os.getcwd())
- word_pattern = re.compile(r"^\w+$")
- if word_pattern.match(filename):
- filename = os.path.join(out_dir, "{}.png".format(filename))
- tmp = "{}.ppm".format(filename)
-
- with self.nested(
- "making screenshot {}".format(filename),
- {"image": os.path.basename(filename)},
- ):
- self.send_monitor_command("screendump {}".format(tmp))
- ret = subprocess.run("pnmtopng {} > {}".format(tmp, filename), shell=True)
- os.unlink(tmp)
- if ret.returncode != 0:
- raise Exception("Cannot convert screenshot")
-
- def copy_from_host_via_shell(self, source: str, target: str) -> None:
- """Copy a file from the host into the guest by piping it over the
- shell into the destination file. Works without host-guest shared folder.
- Prefer copy_from_host for whenever possible.
- """
- with open(source, "rb") as fh:
- content_b64 = base64.b64encode(fh.read()).decode()
- self.succeed(
- f"mkdir -p $(dirname {target})",
- f"echo -n {content_b64} | base64 -d > {target}",
- )
-
- def copy_from_host(self, source: str, target: str) -> None:
- """Copy a file from the host into the guest via the `shared_dir` shared
- among all the VMs (using a temporary directory).
- """
- host_src = pathlib.Path(source)
- vm_target = pathlib.Path(target)
- with tempfile.TemporaryDirectory(dir=self.shared_dir) as shared_td:
- shared_temp = pathlib.Path(shared_td)
- host_intermediate = shared_temp / host_src.name
- vm_shared_temp = pathlib.Path("/tmp/shared") / shared_temp.name
- vm_intermediate = vm_shared_temp / host_src.name
-
- self.succeed(make_command(["mkdir", "-p", vm_shared_temp]))
- if host_src.is_dir():
- shutil.copytree(host_src, host_intermediate)
- else:
- shutil.copy(host_src, host_intermediate)
- self.succeed("sync")
- self.succeed(make_command(["mkdir", "-p", vm_target.parent]))
- self.succeed(make_command(["cp", "-r", vm_intermediate, vm_target]))
- # Make sure the cleanup is synced into VM
- self.succeed("sync")
-
- def copy_from_vm(self, source: str, target_dir: str = "") -> None:
- """Copy a file from the VM (specified by an in-VM source path) to a path
- relative to `$out`. The file is copied via the `shared_dir` shared among
- all the VMs (using a temporary directory).
- """
- # Compute the source, target, and intermediate shared file names
- out_dir = pathlib.Path(os.environ.get("out", os.getcwd()))
- vm_src = pathlib.Path(source)
- with tempfile.TemporaryDirectory(dir=self.shared_dir) as shared_td:
- shared_temp = pathlib.Path(shared_td)
- vm_shared_temp = pathlib.Path("/tmp/shared") / shared_temp.name
- vm_intermediate = vm_shared_temp / vm_src.name
- intermediate = shared_temp / vm_src.name
- # Copy the file to the shared directory inside VM
- self.succeed(make_command(["mkdir", "-p", vm_shared_temp]))
- self.succeed(make_command(["cp", "-r", vm_src, vm_intermediate]))
- self.succeed("sync")
- abs_target = out_dir / target_dir / vm_src.name
- abs_target.parent.mkdir(exist_ok=True, parents=True)
- # Copy the file from the shared directory outside VM
- if intermediate.is_dir():
- shutil.copytree(intermediate, abs_target)
- else:
- shutil.copy(intermediate, abs_target)
- # Make sure the cleanup is synced into VM
- self.succeed("sync")
-
- def dump_tty_contents(self, tty: str) -> None:
- """Debugging: Dump the contents of the TTY
- """
- self.execute("fold -w 80 /dev/vcs{} | systemd-cat".format(tty))
-
- def get_screen_text(self) -> str:
- if shutil.which("tesseract") is None:
- raise Exception("get_screen_text used but enableOCR is false")
-
- magick_args = (
- "-filter Catrom -density 72 -resample 300 "
- + "-contrast -normalize -despeckle -type grayscale "
- + "-sharpen 1 -posterize 3 -negate -gamma 100 "
- + "-blur 1x65535"
- )
-
- tess_args = "-c debug_file=/dev/null --psm 11 --oem 2"
-
- with self.nested("performing optical character recognition"):
- with tempfile.NamedTemporaryFile() as tmpin:
- self.send_monitor_command("screendump {}".format(tmpin.name))
-
- cmd = "convert {} {} tiff:- | tesseract - - {}".format(
- magick_args, tmpin.name, tess_args
- )
- ret = subprocess.run(cmd, shell=True, capture_output=True)
- if ret.returncode != 0:
- raise Exception(
- "OCR failed with exit code {}".format(ret.returncode)
- )
-
- return ret.stdout.decode("utf-8")
-
- def wait_for_text(self, regex: str) -> None:
- def screen_matches(last: bool) -> bool:
- text = self.get_screen_text()
- matches = re.search(regex, text) is not None
-
- if last and not matches:
- self.log("Last OCR attempt failed. Text was: {}".format(text))
-
- return matches
-
- with self.nested("waiting for {} to appear on screen".format(regex)):
- retry(screen_matches)
-
- def send_key(self, key: str) -> None:
- key = CHAR_TO_KEY.get(key, key)
- self.send_monitor_command("sendkey {}".format(key))
-
- def start(self) -> None:
- if self.booted:
- return
-
- self.log("starting vm")
-
- def create_socket(path: str) -> socket.socket:
- if os.path.exists(path):
- os.unlink(path)
- s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM)
- s.bind(path)
- s.listen(1)
- return s
-
- monitor_path = os.path.join(self.state_dir, "monitor")
- self.monitor_socket = create_socket(monitor_path)
-
- shell_path = os.path.join(self.state_dir, "shell")
- self.shell_socket = create_socket(shell_path)
-
- qemu_options = (
- " ".join(
- [
- "" if self.allow_reboot else "-no-reboot",
- "-monitor unix:{}".format(monitor_path),
- "-chardev socket,id=shell,path={}".format(shell_path),
- "-device virtio-serial",
- "-device virtconsole,chardev=shell",
- "-device virtio-rng-pci",
- "-serial stdio" if "DISPLAY" in os.environ else "-nographic",
- ]
- )
- + " "
- + os.environ.get("QEMU_OPTS", "")
- )
-
- environment = dict(os.environ)
- environment.update(
- {
- "TMPDIR": self.state_dir,
- "SHARED_DIR": self.shared_dir,
- "USE_TMPDIR": "1",
- "QEMU_OPTS": qemu_options,
- }
- )
-
- self.process = subprocess.Popen(
- self.script,
- bufsize=1,
- stdin=subprocess.DEVNULL,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- shell=True,
- cwd=self.state_dir,
- env=environment,
- )
- self.monitor, _ = self.monitor_socket.accept()
- self.shell, _ = self.shell_socket.accept()
-
- def process_serial_output() -> None:
- assert self.process.stdout is not None
- for _line in self.process.stdout:
- # Ignore undecodable bytes that may occur in boot menus
- line = _line.decode(errors="ignore").replace("\r", "").rstrip()
- eprint("{} # {}".format(self.name, line))
- self.logger.enqueue({"msg": line, "machine": self.name})
- self.serialQueue.put(line)
-
- _thread.start_new_thread(process_serial_output, ())
-
- self.wait_for_monitor_prompt()
-
- self.pid = self.process.pid
- self.booted = True
-
- self.log("QEMU running (pid {})".format(self.pid))
-
- def shutdown(self) -> None:
- if not self.booted:
- return
-
- self.shell.send("poweroff\n".encode())
- self.wait_for_shutdown()
-
- def crash(self) -> None:
- if not self.booted:
- return
-
- self.log("forced crash")
- self.send_monitor_command("quit")
- self.wait_for_shutdown()
-
- def wait_for_x(self) -> None:
- """Wait until it is possible to connect to the X server. Note that
- testing the existence of /tmp/.X11-unix/X0 is insufficient.
- """
-
- def check_x(_: Any) -> bool:
- cmd = (
- "journalctl -b SYSLOG_IDENTIFIER=systemd | "
- + 'grep "Reached target Current graphical"'
- )
- status, _ = self.execute(cmd)
- if status != 0:
- return False
- status, _ = self.execute("[ -e /tmp/.X11-unix/X0 ]")
- return status == 0
-
- with self.nested("waiting for the X11 server"):
- retry(check_x)
-
- def get_window_names(self) -> List[str]:
- return self.succeed(
- r"xwininfo -root -tree | sed 's/.*0x[0-9a-f]* \"\([^\"]*\)\".*/\1/; t; d'"
- ).splitlines()
-
- def wait_for_window(self, regexp: str) -> None:
- pattern = re.compile(regexp)
-
- def window_is_visible(last_try: bool) -> bool:
- names = self.get_window_names()
- if last_try:
- self.log(
- "Last chance to match {} on the window list,".format(regexp)
- + " which currently contains: "
- + ", ".join(names)
- )
- return any(pattern.search(name) for name in names)
-
- with self.nested("Waiting for a window to appear"):
- retry(window_is_visible)
-
- def sleep(self, secs: int) -> None:
- time.sleep(secs)
-
- def forward_port(self, host_port: int = 8080, guest_port: int = 80) -> None:
- """Forward a TCP port on the host to a TCP port on the guest.
- Useful during interactive testing.
- """
- self.send_monitor_command(
- "hostfwd_add tcp::{}-:{}".format(host_port, guest_port)
- )
-
- def block(self) -> None:
- """Make the machine unreachable by shutting down eth1 (the multicast
- interface used to talk to the other VMs). We keep eth0 up so that
- the test driver can continue to talk to the machine.
- """
- self.send_monitor_command("set_link virtio-net-pci.1 off")
-
- def unblock(self) -> None:
- """Make the machine reachable.
- """
- self.send_monitor_command("set_link virtio-net-pci.1 on")
-
-
-def create_machine(args: Dict[str, Any]) -> Machine:
- global log
- args["log"] = log
- args["redirectSerial"] = os.environ.get("USE_SERIAL", "0") == "1"
- return Machine(args)
-
-
-def start_all() -> None:
- global machines
- with log.nested("starting all VMs"):
- for machine in machines:
- machine.start()
-
-
-def join_all() -> None:
- global machines
- with log.nested("waiting for all VMs to finish"):
- for machine in machines:
- machine.wait_for_shutdown()
-
-
-def test_script() -> None:
- exec(os.environ["testScript"])
-
-
-def run_tests() -> None:
- global machines
- tests = os.environ.get("tests", None)
- if tests is not None:
- with log.nested("running the VM test script"):
- try:
- exec(tests, globals())
- except Exception as e:
- eprint("error: {}".format(str(e)))
- sys.exit(1)
- else:
- ptpython.repl.embed(locals(), globals())
-
- # TODO: Collect coverage data
-
- for machine in machines:
- if machine.is_up():
- machine.execute("sync")
-
-
-@contextmanager
-def subtest(name: str) -> Iterator[None]:
- with log.nested(name):
- try:
- yield
- return True
- except Exception as e:
- log.log(f'Test "{name}" failed with error: "{e}"')
- raise e
-
- return False
-
-
-if __name__ == "__main__":
- log = Logger()
-
- vm_scripts = sys.argv[1:]
- machines = [create_machine({"startCommand": s}) for s in vm_scripts]
- machine_eval = [
- "{0} = machines[{1}]".format(m.name, idx) for idx, m in enumerate(machines)
- ]
- exec("\n".join(machine_eval))
-
- @atexit.register
- def clean_up() -> None:
- with log.nested("cleaning up"):
- for machine in machines:
- if machine.pid is None:
- continue
- log.log("killing {} (pid {})".format(machine.name, machine.pid))
- machine.process.kill()
-
- log.close()
-
- tic = time.time()
- run_tests()
- toc = time.time()
- print("test script finished in {:.2f}s".format(toc - tic))