From 3103e4d071c1b06681e03324a3af317648708868 Mon Sep 17 00:00:00 2001 From: Lilac Date: Thu, 15 Oct 2026 01:10:33 -0400 Subject: [PATCH] jaslkdfj --- flake.nix | 4 +--- hooks.nix | 36 ++++++++++++++++++++++++++++++++++++ init.nix | 45 +++++++++++++++++++++++++++++++++++++++++++++ kernel.nix | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ rootfs.nix | 28 ++++++++++++++++++++++++++++ run.nix | 14 ++++++++++++++ vmconfig.nix | 45 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 218 insertions(+), 3 deletions(-) create mode 100644 hooks.nix create mode 100644 init.nix create mode 100644 kernel.nix create mode 100644 rootfs.nix create mode 100644 run.nix create mode 100644 vmconfig.nix diff --git a/flake.nix b/flake.nix index 40c8b74..4ba0e0d 100644 --- a/flake.nix +++ b/flake.nix @@ -3,9 +3,7 @@ outputs = { self, nixpkgs }: let - pkgs = import nixpkgs { - system = "x86_64-linux"; - }; + pkgs = import nixpkgs { system = "x86_64-linux"; }; in { packages.x86_64-linux.pigeon-kernel = pkgs.callPackage ./kernel/kernel.nix { }; packages.x86_64-linux.pigeon-rootfs = pkgs.callPackage ./rootfs/rootfs.nix { diff --git a/hooks.nix b/hooks.nix new file mode 100644 index 0000000..fd94c65 --- /dev/null +++ b/hooks.nix @@ -0,0 +1,36 @@ +{ + writeText, + + pigeon +}: + +writeText "pigeon-hooks.json" (builtins.toJSON [{ + id = "release"; + execute-command = "${pigeon}"; + include-command-output-in-response = false; + pass-arguments-to-command = [ + { source = "payload"; name = "project.git_http_url"; } + { source = "payload"; name = "project.id"; } + { source = "payload"; name = "tag"; } + { source = "payload"; name = "commit.id"; } + ]; + trigger-rule.and = [ + { + match = { + type = "value"; + parameter = { source = "header"; name = "X-Gitlab-Event"; }; + value = "Release Hook"; + }; + match = { + type = "value"; + parameter = { source = "payload"; name = "action"; }; + value = "create"; + }; + match = { + type = "value"; + parameter = { source = "header"; name = "X-Gitlab-Token"; }; + value = "{{ getenv `PIGEON_GITLAB_TOKEN` | js }}"; + }; + } + ]; +}]) diff --git a/init.nix b/init.nix new file mode 100644 index 0000000..c14424f --- /dev/null +++ b/init.nix @@ -0,0 +1,45 @@ +{ + writeShellApplication, + pigeon-toolchain +}: + +writeShellApplication { + name = "pigeon-init"; + runtimeInputs = [ pigeon-toolchain ]; + text = '' + finish() { + umount /root/results || true + sync + echo 1 >/proc/sys/kernel/sysrq + echo b >/proc/sysrq-trigger + } + trap 'finish' EXIT + + mount -t proc proc /proc + mount -t devtmpfs devtmpfs /dev + mount -t tmpfs -o mode=1777,size=64m tmp /tmp + mount -t ext4 -r /dev/vdb /root/student + mount -t ext4 -r /dev/vdc /root/grader + mount -t ext4 /dev/vdd /root/results + + mkdir -p /tmp/build + cp -a /root/student/. /tmp/build/ + cp -a --remove-destination /root/grader/build/. /tmp/build/ + chown -R 65534:65534 /tmp/build + + ( + cd /tmp/build + ulimit -t 30 -u 256 -n 256 -f 2048 + setpriv --reuid=65534 --regid=65534 --clear-groups \ + timeout -s 9 30 make >/root/results/build.log 2>&1 + echo $? >/root/results/build.status + ) || true + + [ "$(cat /root/results/build.status || true)" != 0 ] && exit + + for TEST in /root/grader/tests/*.sh ; do + NAME="$(basename "$TEST" .sh)" + timeout -s 9 10 "$TEST" 2>/dev/null >"/root/results/$NAME" || true + done + ''; +} diff --git a/kernel.nix b/kernel.nix new file mode 100644 index 0000000..c11f38a --- /dev/null +++ b/kernel.nix @@ -0,0 +1,49 @@ +{ + mkDerivation, + linux_6_1, bc, bison, elfutils, flex, perl, + pigeon-kernel-params ? [ + "64BIT" "TTY" "SERIAL_8250" "SERIAL_8250_CONSOLE" "PRINTK" + + "HYPERVISOR_GUEST" "PARAVIRT" "KVM_GUEST" + + "BLOCK" "VIRTIO_MENU" "VIRTIO" "VIRTIO_PCI" "VIRTIO_MMIO" "VIRTIO_BLK" + "EXT4_FS" "SHMEM" "TMPFS" "PROC_FS" "PROC_SYSCTL" "SYSFS" "DEVTMPFS" + + "ACPI" "PCI" "PCI_MSI" "MAGIC_SYSRQ" + + "BINFMT_ELF" "BINFMT_SCRIPT" "MULTIUSER" "FUTEX" "EPOLL" "EVENTFD" + "SIGNALFD" "TIMERFD" "POSIX_TIMERS" "FILE_LOCKING" "ADVISE_SYSCALLS" + "NET" "UNIX" + ] +}: + +mkDerivation { + inherit (linux_6_1) src version; + pname = "pigeon-kernel"; + + nativeBuildInputs = [ bc bison elfutils flex perl ]; + hardeningDisable = [ "all" ]; + enableParallelBuilding = true; + + configurePhase = '' + runHook preConfigure + patchShebangs scripts tools + make tinyconfig + for OPTION in ${toString pigeon-kernel-params}; do + scripts/config --enable $OPTION + done + make olddefconfig + for OPTION in ${toString pigeon-kernel-params}; do + grep -qx "CONFIG_$OPTION=y" .config || exit 1 + done + runHook postConfigure + ''; + + buildFlags = [ "vmlinux" ]; + + installPhase = '' + runHook preInstall + cp vmlinux "$out" + runHook postInstall + ''; +} diff --git a/rootfs.nix b/rootfs.nix new file mode 100644 index 0000000..c328393 --- /dev/null +++ b/rootfs.nix @@ -0,0 +1,28 @@ +{ + closureInfo, runCommand, + e2fsprogs, + pigeon-toolchain, + pigeon-disc-size ? "1G", + pigeon-init, + pigeon-run +}: + +let + closure = closureInfo { rootPaths = [ toolchain ]; }; +in + runCommand "pigeon-rootfs" { nativeBuildInputs = [ e2fsprogs ]; } '' + mkdir -p rootfs && cd rootfs + mkdir -p dev proc sys tmp usr nix/store root/student root/grader root/results + chmod 700 root + + for FILE in $(cat ${closure}/store-paths); do + cp -a "$FILE" nix/store + done + ln -s ${pigeon-toolchain}/bin bin + ln -s ${pigeon-toolchain}/bin usr/bin + install -m 755 ${pigeon-init}/bin/pigeon-init init + install -m 755 ${pigeon-run}/bin/pigeon-run run + + cd .. + mkfs.ext4 -q -F -d rootfs $out ${pigeon-disc-size} + '' diff --git a/run.nix b/run.nix new file mode 100644 index 0000000..c7e281b --- /dev/null +++ b/run.nix @@ -0,0 +1,14 @@ +{ + writeShellApplication, + pigeon-toolchain +}: + +writeShellApplication { + name = "pigeon-run"; + runtimeInputs = [ pigeon-toolchain ]; + text = '' + cd /tmp/build + ulimit -t 1 -u 256 -n 256 -f 2048 + exec setpriv --reuid=65534 --regid=65534 --clear-groups timeout -s 9 2 ./program "$@" + ''; +} diff --git a/vmconfig.nix b/vmconfig.nix new file mode 100644 index 0000000..4ab9979 --- /dev/null +++ b/vmconfig.nix @@ -0,0 +1,45 @@ +{ + writeText, + + pigeon-vcpu-count ? 1, + pigeon-memory-size-mb ? 512, + pigeon-kernel, + pigeon-rootfs +}: + +writeText "pigeon-vm.json" (builtins.toJSON { + boot-source = { + kernel_image_path = "${pigeon-kernel}"; + boot_args = "reboot=k panic=1 quiet init=/init nomodule 8250.nr_uarts=0 i8042.noaux i8042.nomux i8042.dumbkbd swiotlb=noforce"; + }; + drives = [ + { + drive_id = "rootfs"; + path_on_host = "${pigeon-rootfs}"; + is_root_device = true; + is_read_only = true; + } + { + drive_id = "student"; + path_on_host = ""; + is_root_device = false; + is_read_only = true; + } + { + drive_id = "grader"; + path_on_host = ""; + is_root_device = false; + is_read_only = true; + } + { + drive_id = "results"; + path_on_host = ""; + is_root_device = false; + is_read_only = false; + } + ]; + machine-config = { + vcpu_count = pigeon-vcpu-count; + mem_size_mib = pigeon-memory-size; + }; +})