summary refs log tree commit diff
path: root/pkgs/os-specific/linux/spectrum
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-04-21 19:28:29 +0000
committerAlyssa Ross <hi@alyssa.is>2020-04-22 16:42:10 +0000
commit817a1a9b0de30d8bbc2ad2e80a802d87c56e96ff (patch)
tree8b42c11b35a68613f76c323e8d4af99fc08d9c05 /pkgs/os-specific/linux/spectrum
parent48c645aed80cf14cae8cad9053616ee9eb7a33cd (diff)
downloadnixpkgs-817a1a9b0de30d8bbc2ad2e80a802d87c56e96ff.tar
nixpkgs-817a1a9b0de30d8bbc2ad2e80a802d87c56e96ff.tar.gz
nixpkgs-817a1a9b0de30d8bbc2ad2e80a802d87c56e96ff.tar.bz2
nixpkgs-817a1a9b0de30d8bbc2ad2e80a802d87c56e96ff.tar.lz
nixpkgs-817a1a9b0de30d8bbc2ad2e80a802d87c56e96ff.tar.xz
nixpkgs-817a1a9b0de30d8bbc2ad2e80a802d87c56e96ff.tar.zst
nixpkgs-817a1a9b0de30d8bbc2ad2e80a802d87c56e96ff.zip
spectrumPackages: init
This is a modular version of what was previously start-vm.nix.  It
introduces a program, spectrum-vm, that allows for customising the
crosvm, kernel, and rootfs paths.  And, it can run a custom command
inside the VM!  I think this is going to be a big improvement over
start-vm.nix.
Diffstat (limited to 'pkgs/os-specific/linux/spectrum')
-rw-r--r--pkgs/os-specific/linux/spectrum/default.nix14
-rw-r--r--pkgs/os-specific/linux/spectrum/linux/vm.nix24
-rw-r--r--pkgs/os-specific/linux/spectrum/rootfs/default.nix51
-rw-r--r--pkgs/os-specific/linux/spectrum/rootfs/etc/group2
-rw-r--r--pkgs/os-specific/linux/spectrum/rootfs/etc/passwd2
-rw-r--r--pkgs/os-specific/linux/spectrum/rootfs/generic.nix47
-rw-r--r--pkgs/os-specific/linux/spectrum/rootfs/services.nix28
-rw-r--r--pkgs/os-specific/linux/spectrum/rootfs/stage1.nix46
-rw-r--r--pkgs/os-specific/linux/spectrum/spectrum-vm/default.nix35
-rwxr-xr-xpkgs/os-specific/linux/spectrum/spectrum-vm/spectrum-vm.in67
10 files changed, 316 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/spectrum/default.nix b/pkgs/os-specific/linux/spectrum/default.nix
new file mode 100644
index 00000000000..ea4fa902e95
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/default.nix
@@ -0,0 +1,14 @@
+{ newScope, linux_cros }:
+
+let
+  self = with self; {
+    callPackage = newScope self;
+
+    spectrum-vm = callPackage ./spectrum-vm { linux = linux_vm; };
+
+    linux_vm = callPackage ./linux/vm.nix { linux = linux_cros; };
+
+    rootfs = callPackage ./rootfs { };
+  };
+in
+self
diff --git a/pkgs/os-specific/linux/spectrum/linux/vm.nix b/pkgs/os-specific/linux/spectrum/linux/vm.nix
new file mode 100644
index 00000000000..d91d600cb77
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/linux/vm.nix
@@ -0,0 +1,24 @@
+{ lib, linux }:
+
+with lib.kernel;
+
+linux.override {
+  structuredExtraConfig = {
+    VIRTIO_PCI = yes;
+    VIRTIO_BLK = yes;
+    VIRTIO_WL = yes;
+    VIRTIO_NET = yes;
+    DEVTMPFS_MOUNT = yes;
+    SQUASHFS = yes;
+
+    # VOP is needed to work around a Kconfig bug:
+    # https://lore.kernel.org/lkml/87wob4tf9b.fsf@alyssa.is/
+    VOP = yes;
+    VOP_BUS = yes;
+    HW_RANDOM = yes;
+    HW_RANDOM_VIRTIO = yes;
+
+    NET_9P = yes;
+    "9P_FS" = yes;
+  };
+}
diff --git a/pkgs/os-specific/linux/spectrum/rootfs/default.nix b/pkgs/os-specific/linux/spectrum/rootfs/default.nix
new file mode 100644
index 00000000000..efc15140cdf
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/rootfs/default.nix
@@ -0,0 +1,51 @@
+{ runCommandNoCC, writeScript, writeText, makeFontsConf, writeReferencesToFile
+, lib, dash, busybox, execline, s6, s6-portable-utils, s6-linux-utils
+, s6-linux-init, mesa, squashfs-tools-ng
+, source-code-pro, zsh, emacs26-nox, gcc, sway-unwrapped, sommelier, westonLite
+}:
+
+let
+  makeRootfs = import ./generic.nix {
+    inherit runCommandNoCC writeScript writeReferencesToFile makeFontsConf lib
+      dash execline s6 s6-portable-utils s6-linux-utils s6-linux-init busybox
+      mesa squashfs-tools-ng;
+  };
+
+  path = [
+    zsh emacs26-nox gcc sway-unwrapped sommelier westonLite busybox s6 execline
+  ];
+
+  login = writeScript "login" ''
+    #! ${execline}/bin/execlineb -s0
+    unexport !
+    ${busybox}/bin/login -p -f root $@
+  '';
+
+  swayConfig = writeText "sway-config" ''
+    xwayland disable
+    input * xkb_layout dvorak
+
+    exec weston-terminal --shell ${zsh}/bin/zsh
+  '';
+in
+
+makeRootfs {
+  services.getty.run = writeScript "getty-run" ''
+    #! ${execline}/bin/execlineb -P
+    ${busybox}/bin/getty -i -n -l ${login} 38400 ttyS0
+  '';
+
+  run = ''
+    if { chown user /dev/wl0 }
+
+    s6-applyuidgid -u 1000 -g 1000
+    export XDG_RUNTIME_DIR /run/user/1000
+
+    export PATH ${lib.makeBinPath path}
+
+    ${sommelier}/bin/sommelier
+    sway -Vc ${swayConfig}
+  '';
+
+  fonts = [ source-code-pro ];
+}
diff --git a/pkgs/os-specific/linux/spectrum/rootfs/etc/group b/pkgs/os-specific/linux/spectrum/rootfs/etc/group
new file mode 100644
index 00000000000..e1f50c66958
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/rootfs/etc/group
@@ -0,0 +1,2 @@
+root:x:0:root
+user:x:1000:user
diff --git a/pkgs/os-specific/linux/spectrum/rootfs/etc/passwd b/pkgs/os-specific/linux/spectrum/rootfs/etc/passwd
new file mode 100644
index 00000000000..467ffc9e42c
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/rootfs/etc/passwd
@@ -0,0 +1,2 @@
+root:x:0:0:System administrator:/:/bin/sh
+user:x:1000:1000:User:/:/bin/sh
diff --git a/pkgs/os-specific/linux/spectrum/rootfs/generic.nix b/pkgs/os-specific/linux/spectrum/rootfs/generic.nix
new file mode 100644
index 00000000000..782eecea0b5
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/rootfs/generic.nix
@@ -0,0 +1,47 @@
+{ runCommandNoCC, writeScript, writeReferencesToFile, makeFontsConf, lib
+, dash, execline, s6, s6-portable-utils, s6-linux-utils, s6-linux-init, busybox
+, mesa, squashfs-tools-ng
+}:
+
+{ services, run, fonts ? [], path ? [] }:
+
+let
+  makeStage1 = import ./stage1.nix {
+    inherit writeScript lib
+      execline s6 s6-portable-utils s6-linux-utils s6-linux-init busybox mesa;
+  };
+
+  makeServicesDir = import ./services.nix {
+    inherit runCommandNoCC writeScript lib execline;
+  };
+
+  fontsConf = makeFontsConf { fontDirectories = fonts; };
+
+  squashfs = runCommandNoCC "root-squashfs" {} ''
+    cd ${rootfs}
+    (
+        grep -v ^${rootfs} ${writeReferencesToFile rootfs}
+        printf "%s\n" *
+    ) \
+        | xargs tar -cP --owner root:0 --group root:0 --hard-dereference \
+        | ${squashfs-tools-ng}/bin/tar2sqfs -c gzip -X level=1 $out
+  '';
+
+  rootfs = runCommandNoCC "rootfs" { passthru = { inherit squashfs; }; } ''
+    mkdir $out
+    cd $out
+
+    mkdir bin sbin dev etc proc run tmp
+    ln -s ${dash}/bin/dash bin/sh
+    ln -s ${makeStage1 { inherit run; }} sbin/init
+    cp ${./etc/passwd} etc/passwd
+    cp ${./etc/group} etc/group
+
+    mkdir etc/fonts
+    ln -s ${fontsConf} etc/fonts/fonts.conf
+
+    touch etc/login.defs
+    cp -r ${makeServicesDir { inherit services; }} etc/service
+  '';
+in
+rootfs
diff --git a/pkgs/os-specific/linux/spectrum/rootfs/services.nix b/pkgs/os-specific/linux/spectrum/rootfs/services.nix
new file mode 100644
index 00000000000..b2b09faa06e
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/rootfs/services.nix
@@ -0,0 +1,28 @@
+{ runCommandNoCC, writeScript, lib, execline }:
+
+{ services ? [] }:
+
+let
+  services' = {
+    ".s6-svscan" = {
+      finish = writeScript "init-stage3" ''
+        #! ${execline}/bin/execlineb -P
+        foreground { s6-nuke -th }
+        s6-sleep -m -- 2000
+        foreground { s6-nuke -k }
+        wait { }
+        s6-linux-init-hpr -fr
+      '';
+    } // services.".s6-svscan" or {};
+  } // services;
+in
+
+runCommandNoCC "services" {} ''
+  mkdir $out
+  ${lib.concatStrings (lib.mapAttrsToList (name: attrs: ''
+    mkdir $out/${name}
+    ${lib.concatStrings (lib.mapAttrsToList (key: value: ''
+      cp ${value} $out/${name}/${key}
+    '') attrs)}
+  '') services')}
+''
diff --git a/pkgs/os-specific/linux/spectrum/rootfs/stage1.nix b/pkgs/os-specific/linux/spectrum/rootfs/stage1.nix
new file mode 100644
index 00000000000..3efda40991c
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/rootfs/stage1.nix
@@ -0,0 +1,46 @@
+{ writeScript, lib
+, execline, s6, s6-portable-utils, s6-linux-utils, s6-linux-init, busybox, mesa
+}:
+
+{ run ? "true" }:
+
+let
+  path = [ s6 s6-portable-utils s6-linux-utils s6-linux-init busybox execline ];
+in
+
+writeScript "init-stage1" ''
+  #! ${execline}/bin/execlineb -P
+  export PATH ${lib.makeBinPath path}
+  ${s6}/bin/s6-setsid -qb --
+
+  importas -i spectrumcmd spectrumcmd
+
+  umask 022
+  if { s6-mount -t tmpfs -o mode=0755 tmpfs /run }
+  if { s6-hiercopy /etc/service /run/service }
+  emptyenv -p
+
+  background {
+    s6-setsid --
+    if { s6-mkdir -p /run/user/0 /dev/pts /dev/shm }
+    if { install -o user -g user -d /run/user/1000 }
+    if { s6-mount -t devpts -o gid=4,mode=620 none /dev/pts }
+    if { s6-mount -t tmpfs none /dev/shm }
+    if { s6-mount -t proc none /proc }
+    if { s6-ln -s ${mesa.drivers} /run/opengl-driver }
+
+    export XDG_RUNTIME_DIR /run/user/0
+    foreground {
+      ifelse { test -n $spectrumcmd }
+        { pipeline { heredoc 0 $spectrumcmd base64 -d } /bin/sh }
+        ${run}
+    }
+    importas -i ? ?
+    if { s6-echo STATUS: $? }
+    s6-svscanctl -6 /run/service
+  }
+
+  unexport !
+  cd /run/service
+  s6-svscan
+''
diff --git a/pkgs/os-specific/linux/spectrum/spectrum-vm/default.nix b/pkgs/os-specific/linux/spectrum/spectrum-vm/default.nix
new file mode 100644
index 00000000000..56f1eadea99
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/spectrum-vm/default.nix
@@ -0,0 +1,35 @@
+{ stdenv, lib, makeWrapper, utillinux, crosvm, linux, rootfs }:
+
+stdenv.mkDerivation {
+  name = "spectrum-vm";
+
+  src = ./spectrum-vm.in;
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  unpackPhase = ''
+    cp $src spectrum-vm.in
+  '';
+
+  configurePhase = ''
+    substituteAll spectrum-vm.in spectrum-vm
+    chmod +x spectrum-vm
+  '';
+
+  getopt = "${lib.getBin utillinux}/bin/getopt";
+  crosvm = "${lib.getBin crosvm}/bin/crosvm";
+  kernel = "${linux}/bzImage";
+  rootfs = rootfs.squashfs;
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp spectrum-vm $out/bin
+  '';
+
+  meta = with lib; {
+    description = "Utility for testing Spectrum VM components";
+    maintainers = with maintainers; [ qyliss ];
+    license = licenses.gpl3Plus;
+    inherit (crosvm.meta) platforms;
+  };
+}
diff --git a/pkgs/os-specific/linux/spectrum/spectrum-vm/spectrum-vm.in b/pkgs/os-specific/linux/spectrum/spectrum-vm/spectrum-vm.in
new file mode 100755
index 00000000000..97cb5dbfa58
--- /dev/null
+++ b/pkgs/os-specific/linux/spectrum/spectrum-vm/spectrum-vm.in
@@ -0,0 +1,67 @@
+#!@shell@
+set -ue
+
+ex_usage() {
+    cat <<EOF
+Usage: $(basename "$0") [OPTION]...
+
+  -c COMMAND         shell command to run inside VM
+  -C, --crosvm PATH  path to custom crosvm executable
+  -k, --kernel PATH  path to custom kernel image
+  -f, --rootfs PATH  path to custom root file system image
+EOF
+    exit "$1"
+}
+
+args="$(@getopt@ -s sh -l crosvm:,help,kernel:,rootfs: -o c:C:hk:f: -- "$@" || exit 1)"
+eval set -- "$args"
+
+command=
+crosvm=@crosvm@
+kernel=@kernel@
+rootfs=@rootfs@
+
+while :
+do
+    case "$1" in
+	-c)
+	    shift
+	    command="$1"
+	    shift
+	    ;;
+        -C|--crosvm)
+            shift
+            crosvm="$1"
+	    shift
+            ;;
+	-h|--help)
+	    ex_usage 0
+	    ;;
+        -k|--kernel)
+            shift
+            kernel="$1"
+	    shift
+            ;;
+        -f|--rootfs)
+            shift
+            rootfs="$1"
+	    shift
+            ;;
+        --)
+            shift
+            break
+            ;;
+    esac
+done
+
+if [ "$#" -ne 0 ]; then
+    ex_usage 1 >&2
+fi
+
+exec "$crosvm" run \
+    --wayland-sock "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" \
+    -s "$XDG_RUNTIME_DIR" \
+    -p init=/sbin/init \
+    -p "spectrumcmd=$(printf %s "$command" | base64)" \
+    --root "$rootfs" \
+    "$kernel"