diff options
Diffstat (limited to 'img/app')
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)" + ''; +}) |