summary refs log tree commit diff
path: root/img/app
diff options
context:
space:
mode:
Diffstat (limited to 'img/app')
-rw-r--r--img/app/Makefile127
l---------img/app/bin1
-rw-r--r--img/app/default.nix92
-rw-r--r--img/app/etc/fstab8
-rwxr-xr-ximg/app/etc/init5
-rw-r--r--img/app/etc/mdev.conf5
-rwxr-xr-ximg/app/etc/mdev/iface36
-rw-r--r--img/app/etc/passwd1
-rw-r--r--img/app/etc/passwd.license2
-rw-r--r--img/app/etc/resolv.conf4
-rwxr-xr-ximg/app/etc/s6-linux-init/scripts/rc.init11
-rwxr-xr-ximg/app/etc/s6-rc/app/run26
-rw-r--r--img/app/etc/s6-rc/app/type1
-rw-r--r--img/app/etc/s6-rc/app/type.license2
-rw-r--r--img/app/etc/s6-rc/mdevd-coldplug/dependencies4
-rw-r--r--img/app/etc/s6-rc/mdevd-coldplug/type1
-rw-r--r--img/app/etc/s6-rc/mdevd-coldplug/type.license2
-rw-r--r--img/app/etc/s6-rc/mdevd-coldplug/up4
-rw-r--r--img/app/etc/s6-rc/mdevd/notification-fd1
-rw-r--r--img/app/etc/s6-rc/mdevd/notification-fd.license2
-rw-r--r--img/app/etc/s6-rc/mdevd/run5
-rw-r--r--img/app/etc/s6-rc/mdevd/type1
-rw-r--r--img/app/etc/s6-rc/mdevd/type.license2
-rw-r--r--img/app/etc/s6-rc/ok-all/contents4
-rw-r--r--img/app/etc/s6-rc/ok-all/type1
-rw-r--r--img/app/etc/s6-rc/ok-all/type.license2
l---------img/app/etc/ssl/certs/ca-certificates.crt1
-rw-r--r--img/app/shell.nix24
28 files changed, 375 insertions, 0 deletions
diff --git a/img/app/Makefile b/img/app/Makefile
new file mode 100644
index 0000000..c5a4684
--- /dev/null
+++ b/img/app/Makefile
@@ -0,0 +1,127 @@
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is>
+
+# qemu-kvm is non-standard, but is present in at least Fedora and
+# Nixpkgs.  If you don't have qemu-kvm, you'll need to set e.g.
+# QEMU_KVM = qemu-system-x86_64 -enable-kvm.
+QEMU_KVM = qemu-kvm
+CLOUD_HYPERVISOR = cloud-hypervisor
+
+prefix = /usr/local
+imgdir = $(prefix)/img
+
+VMM = qemu
+SCRIPTS = ../../scripts
+
+HOST_BUILD_FILES = \
+	build/host/appvm/blk/root.img \
+	build/host/appvm/vmlinux
+
+all: $(HOST_BUILD_FILES)
+.PHONY: all
+
+install: $(HOST_BUILD_FILES)
+	mkdir -p $(imgdir)
+	tar -c $(HOST_BUILD_FILES) | tar -C $(imgdir) -x --strip-components 2
+.PHONY: install
+
+build/host/appvm/vmlinux: $(VMLINUX)
+	mkdir -p $$(dirname $@)
+	cp $(VMLINUX) $@
+
+build/host/appvm/blk/root.img: $(SCRIPTS)/make-gpt.sh $(SCRIPTS)/sfdisk-field.awk build/rootfs.ext4
+	mkdir -p $$(dirname $@)
+	$(SCRIPTS)/make-gpt.sh $@.tmp \
+	    build/rootfs.ext4:4f68bce3-e8cd-4db1-96e7-fbcaf984b709:5460386f-2203-4911-8694-91400125c604:root
+	mv $@.tmp $@
+
+# tar2ext4 will leave half a filesystem behind if it's interrupted
+# half way through.
+build/rootfs.ext4: build/rootfs.tar
+	mkdir -p $$(dirname $@)
+	tar2ext4 -i build/rootfs.tar -o $@.tmp
+	mv $@.tmp $@
+
+VM_FILES = \
+	etc/fstab \
+	etc/init \
+	etc/mdev.conf \
+	etc/mdev/iface \
+	etc/passwd \
+	etc/resolv.conf \
+	etc/s6-linux-init/scripts/rc.init
+VM_DIRS = dev run proc sys \
+	etc/s6-linux-init/env \
+	etc/s6-linux-init/run-image/ext \
+	etc/s6-linux-init/run-image/service
+
+# These are separate because they need to be included, but putting
+# them as make dependencies would confuse make.
+VM_LINKS = bin etc/ssl/certs/ca-certificates.crt
+
+VM_BUILD_FILES = build/etc/s6-rc
+
+build/empty:
+	mkdir -p $@
+
+build/rootfs.tar: build/empty $(PACKAGES_TAR) $(VM_FILES) $(VM_BUILD_FILES)
+	cp --no-preserve=mode -f $(PACKAGES_TAR) $@
+	tar $(TARFLAGS) --append -f $@ $(VM_FILES) $(VM_LINKS)
+	echo $(VM_BUILD_FILES) | cut -d/ -f2 | \
+	    tar $(TARFLAGS) --append -f $@ -C build -T -
+	for m in $(VM_DIRS); do \
+	    tar $(TARFLAGS) --append -hf $@ --xform="s,.*,$$m," build/empty ; \
+	done
+
+VM_S6_RC_FILES = \
+	etc/s6-rc/app/run \
+	etc/s6-rc/app/type \
+	etc/s6-rc/mdevd-coldplug/dependencies \
+	etc/s6-rc/mdevd-coldplug/type \
+	etc/s6-rc/mdevd-coldplug/up \
+	etc/s6-rc/mdevd/notification-fd \
+	etc/s6-rc/mdevd/run \
+	etc/s6-rc/mdevd/type \
+	etc/s6-rc/ok-all/contents \
+	etc/s6-rc/ok-all/type
+
+build/etc/s6-rc: $(VM_S6_RC_FILES)
+	mkdir -p $$(dirname $@)
+	rm -rf $@
+
+	dir=$$(mktemp -d) && \
+	    tar -c $(VM_S6_RC_FILES) | tar -C $$dir -x --strip-components 2 && \
+	    s6-rc-compile $@ $$dir; \
+	    exit=$$?; rm -r $$dir; exit $$exit
+
+run-qemu: build/host/appvm/blk/root.img
+	$(QEMU_KVM) -m 128 -cpu host -machine q35,kernel=$(KERNEL) -vga none \
+	  -drive file=build/host/appvm/blk/root.img,if=virtio,format=raw,readonly=on \
+	  -drive file=$(RUN_IMG),if=virtio,format=raw,readonly=on \
+	  -append "console=ttyS0 root=PARTLABEL=root" \
+	  -netdev user,id=net0 \
+	  -device virtio-net,netdev=net0,mac=0A:B3:EC:00:00:00 \
+	  -chardev vc,id=virtiocon0 \
+	  -device virtio-serial-pci \
+	  -device virtconsole,chardev=virtiocon0
+.PHONY: run-qemu
+
+run-cloud-hypervisor: build/host/appvm/blk/root.img
+	$(CLOUD_HYPERVISOR) \
+	    --api-socket path=vmm.sock \
+	    --memory size=128M \
+	    --disk path=build/host/appvm/blk/root.img,readonly=on \
+	           path=$(RUN_IMG),readonly=on \
+	    --net tap=tap0,mac=0A:B3:EC:00:00:00 \
+	    --kernel $(KERNEL) \
+	    --cmdline "console=ttyS0 root=PARTLABEL=root" \
+	    --console tty \
+	    --serial pty
+.PHONY: run-cloud-hypervisor
+
+run: run-$(VMM)
+.PHONY: run
+
+clean:
+	rm -rf build
+.PHONY: clean
diff --git a/img/app/bin b/img/app/bin
new file mode 120000
index 0000000..1e881ed
--- /dev/null
+++ b/img/app/bin
@@ -0,0 +1 @@
+usr/bin
\ No newline at end of file
diff --git a/img/app/default.nix b/img/app/default.nix
new file mode 100644
index 0000000..e7d5366
--- /dev/null
+++ b/img/app/default.nix
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is>
+
+{ config ? import ../../nix/eval-config.nix {}
+, terminfo ? config.pkgs.foot.terminfo
+}:
+
+config.pkgs.pkgsStatic.callPackage (
+
+{ lib, stdenvNoCC, runCommand, writeReferencesToFile, buildPackages
+, jq, s6-rc, tar2ext4, util-linux
+, busybox, cacert, execline, kmod, mdevd, s6, s6-linux-init
+}:
+
+let
+  inherit (lib) cleanSource cleanSourceWith concatMapStringsSep hasSuffix;
+
+  scripts = import ../../scripts { inherit config; };
+
+  packages = [
+    execline kmod mdevd s6 s6-linux-init s6-rc
+
+    (busybox.override {
+      extraConfig = ''
+        CONFIG_DEPMOD n
+        CONFIG_INSMOD n
+        CONFIG_LSMOD n
+        CONFIG_MODINFO n
+        CONFIG_MODPROBE n
+        CONFIG_RMMOD n
+      '';
+    })
+  ];
+
+  packagesSysroot = runCommand "packages-sysroot" {
+    inherit packages;
+    passAsFile = [ "packages" ];
+  } ''
+    mkdir -p $out/usr/bin $out/usr/share
+    ln -s ${concatMapStringsSep " " (p: "${p}/bin/*") packages} $out/usr/bin
+    ln -s ${kernel}/lib "$out"
+    ln -s ${terminfo}/share/terminfo $out/usr/share
+    ln -s ${cacert}/etc/ssl $out/usr/share
+  '';
+
+  packagesTar = runCommand "packages.tar" {} ''
+    cd ${packagesSysroot}
+    tar -cf $out --verbatim-files-from \
+        -T ${writeReferencesToFile packagesSysroot} .
+  '';
+
+  kernel = buildPackages.linux.override {
+    structuredExtraConfig = with lib.kernel; {
+      VIRTIO = yes;
+      VIRTIO_PCI = yes;
+      VIRTIO_BLK = yes;
+      VIRTIO_CONSOLE = yes;
+      EXT4_FS = yes;
+      DRM_BOCHS = yes;
+      DRM = yes;
+      AGP = yes;
+    };
+  };
+in
+
+stdenvNoCC.mkDerivation {
+  name = "spectrum-appvm";
+
+  src = cleanSourceWith {
+    filter = name: _type:
+      name != "${toString ./.}/build" &&
+      !(hasSuffix ".nix" name);
+    src = cleanSource ./.;
+  };
+
+  nativeBuildInputs = [ jq s6-rc tar2ext4 util-linux ];
+
+  PACKAGES_TAR = packagesTar;
+  VMLINUX = "${kernel.dev}/vmlinux";
+
+  makeFlags = [ "SCRIPTS=${scripts}" "prefix=$(out)" ];
+
+  enableParallelBuilding = true;
+
+  passthru = { inherit kernel packagesSysroot; };
+
+  meta = with lib; {
+    license = licenses.eupl12;
+    platforms = platforms.linux;
+  };
+}
+) {}
diff --git a/img/app/etc/fstab b/img/app/etc/fstab
new file mode 100644
index 0000000..95bfe2b
--- /dev/null
+++ b/img/app/etc/fstab
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: CC0-1.0
+# SPDX-FileCopyrightText: 2020-2022 Alyssa Ross <hi@alyssa.is>
+proc		/proc		proc	defaults					0	0
+devpts		/dev/pts	devpts	defaults,gid=4,mode=620				0	0
+tmpfs		/dev/shm	tmpfs	defaults					0	0
+sysfs		/sys		sysfs	defaults					0	0
+LABEL=ext	/run/ext	ext4	ro						0	0
+store		/nix/store	overlay	ro,lowerdir=/nix/store:/run/ext/nix/store	0	0
diff --git a/img/app/etc/init b/img/app/etc/init
new file mode 100755
index 0000000..6424e22
--- /dev/null
+++ b/img/app/etc/init
@@ -0,0 +1,5 @@
+#!/bin/execlineb -s0
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2022 Alyssa Ross <hi@alyssa.is>
+
+/bin/s6-linux-init -Bc /etc/s6-linux-init -- $@
diff --git a/img/app/etc/mdev.conf b/img/app/etc/mdev.conf
new file mode 100644
index 0000000..f114719
--- /dev/null
+++ b/img/app/etc/mdev.conf
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
+
+-$MODALIAS=.* 0:0 660 +importas -iu MODALIAS MODALIAS modprobe -q $MODALIAS
+$INTERFACE=.* 0:0 660 ! +/etc/mdev/iface
diff --git a/img/app/etc/mdev/iface b/img/app/etc/mdev/iface
new file mode 100755
index 0000000..d8ceda5
--- /dev/null
+++ b/img/app/etc/mdev/iface
@@ -0,0 +1,36 @@
+#!/bin/execlineb -P
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is>
+
+importas -i INTERFACE INTERFACE
+
+if { test $INTERFACE != lo }
+
+# Our IP is encoded in the NIC-specific portion of the interface's MAC
+# address.
+backtick -E LOCAL_IP {
+  awk -F: "{printf \"100.64.%d.%d\\n\", \"0x\" $5, \"0x\" $6}"
+  /sys/class/net/${INTERFACE}/address
+}
+
+if { ip address add ${LOCAL_IP}/32 dev $INTERFACE }
+if { ip link set $INTERFACE up }
+if { ip route add 169.254.0.1 dev $INTERFACE }
+if { ip route add default via 169.254.0.1 dev $INTERFACE }
+
+# Try to wait for the network to be up.
+# If we time out, well, there's not much we can do, so just carry on.
+# In future, it would be better if the network VM notified us about
+# network changes.
+foreground { printf "Waiting for network… " }
+foreground {
+  ifte { echo "Connected." } { echo "Timed out." }
+  pipeline { seq 10 }
+  forstdin _
+  if -n {
+    redirfd -w 2 /dev/null
+    wget -qT 6 -O /dev/null http://ipv4.connman.net/online/status.html
+  }
+}
+
+s6-rc -u change app
diff --git a/img/app/etc/passwd b/img/app/etc/passwd
new file mode 100644
index 0000000..29f3b25
--- /dev/null
+++ b/img/app/etc/passwd
@@ -0,0 +1 @@
+root:x:0:0:System administrator:/:/bin/sh
diff --git a/img/app/etc/passwd.license b/img/app/etc/passwd.license
new file mode 100644
index 0000000..2b3b032
--- /dev/null
+++ b/img/app/etc/passwd.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is>
diff --git a/img/app/etc/resolv.conf b/img/app/etc/resolv.conf
new file mode 100644
index 0000000..7fcdf3a
--- /dev/null
+++ b/img/app/etc/resolv.conf
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: CC0-1.0
+# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
+
+nameserver 1.1.1.1
diff --git a/img/app/etc/s6-linux-init/scripts/rc.init b/img/app/etc/s6-linux-init/scripts/rc.init
new file mode 100755
index 0000000..b46afb7
--- /dev/null
+++ b/img/app/etc/s6-linux-init/scripts/rc.init
@@ -0,0 +1,11 @@
+#!/bin/execlineb -P
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2020-2022 Alyssa Ross <hi@alyssa.is>
+
+if { s6-rc-init -c /etc/s6-rc /run/service }
+
+if { mkdir -p /dev/pts /dev/shm }
+if { modprobe overlay }
+if { mount -a }
+
+s6-rc change ok-all
diff --git a/img/app/etc/s6-rc/app/run b/img/app/etc/s6-rc/app/run
new file mode 100755
index 0000000..2a628b7
--- /dev/null
+++ b/img/app/etc/s6-rc/app/run
@@ -0,0 +1,26 @@
+#!/bin/execlineb -P
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
+
+export TERM foot
+export TERMINFO_DIRS /usr/share/terminfo
+export TMPDIR /run
+
+backtick USER { id -un }
+backtick HOME {
+  importas -i user USER
+  homeof $user
+}
+
+importas -i home HOME
+cd $home
+
+redirfd -u 0 /dev/hvc0
+fdmove -c 1 0
+fdmove -c 2 0
+
+foreground { clear }
+unexport ?
+
+foreground { /run/ext/run }
+exec -l sh
diff --git a/img/app/etc/s6-rc/app/type b/img/app/etc/s6-rc/app/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/img/app/etc/s6-rc/app/type
@@ -0,0 +1 @@
+longrun
diff --git a/img/app/etc/s6-rc/app/type.license b/img/app/etc/s6-rc/app/type.license
new file mode 100644
index 0000000..c49c11b
--- /dev/null
+++ b/img/app/etc/s6-rc/app/type.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
diff --git a/img/app/etc/s6-rc/mdevd-coldplug/dependencies b/img/app/etc/s6-rc/mdevd-coldplug/dependencies
new file mode 100644
index 0000000..59b02b7
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd-coldplug/dependencies
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: CC0-1.0
+# SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is>
+#
+mdevd
diff --git a/img/app/etc/s6-rc/mdevd-coldplug/type b/img/app/etc/s6-rc/mdevd-coldplug/type
new file mode 100644
index 0000000..bdd22a1
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd-coldplug/type
@@ -0,0 +1 @@
+oneshot
diff --git a/img/app/etc/s6-rc/mdevd-coldplug/type.license b/img/app/etc/s6-rc/mdevd-coldplug/type.license
new file mode 100644
index 0000000..2b3b032
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd-coldplug/type.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is>
diff --git a/img/app/etc/s6-rc/mdevd-coldplug/up b/img/app/etc/s6-rc/mdevd-coldplug/up
new file mode 100644
index 0000000..8698f7d
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd-coldplug/up
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is>
+
+mdevd-coldplug
diff --git a/img/app/etc/s6-rc/mdevd/notification-fd b/img/app/etc/s6-rc/mdevd/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/img/app/etc/s6-rc/mdevd/notification-fd.license b/img/app/etc/s6-rc/mdevd/notification-fd.license
new file mode 100644
index 0000000..2b3b032
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd/notification-fd.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is>
diff --git a/img/app/etc/s6-rc/mdevd/run b/img/app/etc/s6-rc/mdevd/run
new file mode 100644
index 0000000..6dacb13
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd/run
@@ -0,0 +1,5 @@
+#!/bin/execlineb -P
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is>
+
+mdevd -D3
diff --git a/img/app/etc/s6-rc/mdevd/type b/img/app/etc/s6-rc/mdevd/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd/type
@@ -0,0 +1 @@
+longrun
diff --git a/img/app/etc/s6-rc/mdevd/type.license b/img/app/etc/s6-rc/mdevd/type.license
new file mode 100644
index 0000000..2b3b032
--- /dev/null
+++ b/img/app/etc/s6-rc/mdevd/type.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is>
diff --git a/img/app/etc/s6-rc/ok-all/contents b/img/app/etc/s6-rc/ok-all/contents
new file mode 100644
index 0000000..c4ea84f
--- /dev/null
+++ b/img/app/etc/s6-rc/ok-all/contents
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: CC0-1.0
+# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
+#
+mdevd-coldplug
diff --git a/img/app/etc/s6-rc/ok-all/type b/img/app/etc/s6-rc/ok-all/type
new file mode 100644
index 0000000..757b422
--- /dev/null
+++ b/img/app/etc/s6-rc/ok-all/type
@@ -0,0 +1 @@
+bundle
diff --git a/img/app/etc/s6-rc/ok-all/type.license b/img/app/etc/s6-rc/ok-all/type.license
new file mode 100644
index 0000000..c49c11b
--- /dev/null
+++ b/img/app/etc/s6-rc/ok-all/type.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
diff --git a/img/app/etc/ssl/certs/ca-certificates.crt b/img/app/etc/ssl/certs/ca-certificates.crt
new file mode 120000
index 0000000..42d8e23
--- /dev/null
+++ b/img/app/etc/ssl/certs/ca-certificates.crt
@@ -0,0 +1 @@
+/usr/share/ssl/certs/ca-bundle.crt
\ No newline at end of file
diff --git a/img/app/shell.nix b/img/app/shell.nix
new file mode 100644
index 0000000..83dcd76
--- /dev/null
+++ b/img/app/shell.nix
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is>
+
+{ config ? import ../../nix/eval-config.nix {}
+, run ? ../../vm/app/catgirl.nix
+}:
+
+with config.pkgs;
+
+(import ./. { inherit config; }).overrideAttrs (
+{ passthru ? {}, nativeBuildInputs ? [], ... }:
+
+{
+  nativeBuildInputs = nativeBuildInputs ++ [
+    cloud-hypervisor jq qemu_kvm reuse
+  ];
+
+  KERNEL = "${passthru.kernel.dev}/vmlinux";
+
+  runDef = import run { inherit config; };
+  shellHook = ''
+    export RUN_IMG="$(printf "%s\n" "$runDef"/blk/run.img)"
+  '';
+})