2
0
Fork 0

WiP! nixos: Vbox guests

This commit is contained in:
Ehmry - 2020-12-21 12:28:33 +01:00
parent 5d4fee3bf2
commit b4f0b8f3a0
3 changed files with 336 additions and 3 deletions

View File

@ -1,12 +1,18 @@
{ flake }:
let
baseModules =
[ ./genode-core.nix ./genode-init.nix ./gui ./hardware.nix ./systemd.nix ];
baseModules = [
./genode-core.nix
./genode-init.nix
./guest-vbox-linux.nix
./gui
./hardware.nix
./systemd.nix
];
in {
x86_64 = {
imports = [ baseModules ];
imports = baseModules;
nixpkgs = rec {
localSystem = "x86_64-linux";
crossSystem = "x86_64-genode";

View File

@ -0,0 +1,110 @@
{ config, lib, pkgs, modulesPath, ... }:
with lib;
let cfg = config.genode.vbox;
in {
options.genode.vbox.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.
'';
default = { };
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 = cfg.guests.${name}.memorySize; }
];
}.${genodeConfig.guests.${name}.bootFormat}
++ [{ system.nixos.tags = [ name ]; }]
++ (map (x: x.value) defs);
prefix = [ "guests" name ];
}).config;
};
};
};
}));
};
config = {
genode.init.children = mapAttrs' (name: cfg:
let
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 {
inputs = with pkgs.genodePackages; [ libiconv vbox5 vfs_pipe ];
coreROMs = [ "platform_info" ];
configFile = pkgs.writeText "${name}.vbox.dhall" ''
${./vbox-guest.dhall}
{ bootFilename = "${boot.filename}"
, bootFormat = "${boot.format}"
, bootPkg = "${boot.storeRoot}"
, bootUuid = ${boot.uuid}
, memorySize = ${toString cfg.memorySize}
, vmName = "${vmName}"
}
'';
}) config.genode.vbox.guests;
};
}

View File

@ -0,0 +1,217 @@
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 → Genode.Init.Child.Type
= λ(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 ''
<VirtualBox xmlns="http://www.virtualbox.org/" version="1.14-freebsd">
<Machine uuid="{37ab43a5-38d8-4491-93f5-5b0b077f5c32}" name="${params.vmName}" OSType="Linux26_64" snapshotFolder="Snapshots" lastStateChange="2018-01-23T18:40:00Z">
<MediaRegistry>
<HardDisks>${XML.render hardDisks}</HardDisks>
<DVDImages>${XML.render dvdImages}</DVDImages>
</MediaRegistry>
<Hardware>
<CPU count="2">
<PAE enabled="true"/>
<LongMode enabled="true"/>
<HardwareVirtExLargePages enabled="false"/>
</CPU>
<Memory RAMSize="${Prelude.Natural.show
params.memorySize}"/>
<HID Pointing="USBTablet"/>
<Display VRAMSize="20"/>
<RemoteDisplay enabled="false"/>
<BIOS>
<IOAPIC enabled="true"/>
</BIOS>
<USB>
<Controllers/>
</USB>
<Network>
<Adapter slot="0" enabled="true" MACAddress="0800271D7901" cable="true" type="82540EM">
<BridgedInterface/>
</Adapter>
</Network>
<UART>
<Port slot="0" enabled="false" IOBase="0x3f8" IRQ="4" hostMode="Disconnected"/>
<Port slot="1" enabled="false" IOBase="0x2f8" IRQ="3" hostMode="Disconnected"/>
</UART>
<LPT>
<Port slot="0" enabled="false" IOBase="0x378" IRQ="7"/>
<Port slot="1" enabled="false" IOBase="0x378" IRQ="7"/>
</LPT>
<AudioAdapter controller="HDA" driver="OSS" enabled="false"/>
<RTC localOrUTC="UTC"/>
<SharedFolders/>
</Hardware>
<StorageControllers>
<StorageController name="SATA" type="AHCI" PortCount="4" useHostIOCache="true" Bootable="true" IDE0MasterEmulationPort="0" IDE0SlaveEmulationPort="1" IDE1MasterEmulationPort="2" IDE1SlaveEmulationPort="3">
${XML.render attachedDevices}
</StorageController>
</StorageControllers>
</Machine>
</VirtualBox>
''
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
}
, romReports = [ "clipboard", "shape" ]
, routes =
[ ServiceRoute.parent "File_system"
, ServiceRoute.parent "Nic"
, ServiceRoute.parent "Gui"
, ServiceRoute.parent "Rtc"
, ServiceRoute.parent "Timer"
, ServiceRoute.parent "VM"
, ServiceRoute.parent "Report"
]
}
in toVbox