initial commit
This commit is contained in:
Generated
+27
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1791734076,
|
||||||
|
"narHash": "sha256-i5qk1kLiit98rRbh1AXmWBNT9QXC/y4l5Wk/u5EdpDQ=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "7fd4004d0511991fff3a0524856a9be09e28c5f0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
{
|
||||||
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs }:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||||
|
|
||||||
|
toolchain = pkgs.buildEnv {
|
||||||
|
name = "pigeon-toolchain";
|
||||||
|
paths = with pkgs; [ bash coreutils gcc gnumake util-linux ];
|
||||||
|
};
|
||||||
|
closure = pkgs.closureInfo {
|
||||||
|
rootPaths = [ toolchain ];
|
||||||
|
};
|
||||||
|
rootfs = pkgs.runCommand "pigeon-rootfs" {
|
||||||
|
nativeBuildInputs = with pkgs; [ e2fsprogs ];
|
||||||
|
} ''
|
||||||
|
mkdir -p rootfs && cd rootfs
|
||||||
|
umask 022
|
||||||
|
mkdir -p dev proc sys tmp usr nix/store root/student root/project root/results
|
||||||
|
chmod 777 tmp
|
||||||
|
|
||||||
|
for FILE in $(cat ${closure}/store-paths) ; do
|
||||||
|
cp -a "$FILE" nix/store
|
||||||
|
done
|
||||||
|
ln -s ${toolchain}/bin bin
|
||||||
|
ln -s ${toolchain}/bin usr/bin
|
||||||
|
cp ${./init.sh} init
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
mkfs.ext4 -q -F -d rootfs $out "1G"
|
||||||
|
'';
|
||||||
|
|
||||||
|
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" "MAGIC_SYSRQ"
|
||||||
|
"BINFMT_ELF" "BINFMT_SCRIPT" "MULTIUSER" "FUTEX" "EPOLL" "EVENTFD"
|
||||||
|
"SIGNALFD" "TIMERFD" "POSIX_TIMERS" "FILE_LOCKING" "ADVISE_SYSCALLS"
|
||||||
|
"NET" "UNIX"
|
||||||
|
];
|
||||||
|
kernel = pkgs.stdenv.mkDerivation {
|
||||||
|
inherit (pkgs.linux_6_1) src version;
|
||||||
|
pname = "pigeon-kernel";
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [ bc bison elfutils flex perl ];
|
||||||
|
hardeningDisable = [ "all" ];
|
||||||
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
|
configurePhase = ''
|
||||||
|
runHook preConfigure
|
||||||
|
patchShebangs scripts tools
|
||||||
|
make tinyconfig
|
||||||
|
for OPTION in ${toString kernel-params} ; do
|
||||||
|
scripts/config --enable "$OPTION"
|
||||||
|
done
|
||||||
|
make olddefconfig
|
||||||
|
for OPTION in ${toString kernel-params} ; do
|
||||||
|
grep -qx "CONFIG_$OPTION=y" .config || exit 1
|
||||||
|
done
|
||||||
|
runHook postConfigure
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildFlags = [ "vmlinux" ];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
cp vmlinux "$out"
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
pigeon = pkgs.writeShellApplication {
|
||||||
|
name = "pigeon";
|
||||||
|
runtimeInputs = with pkgs; [ coreutils curl e2fsprogs firecracker git ];
|
||||||
|
text = builtins.replaceStrings
|
||||||
|
[ "@kernel@" "@rootfs@" ] [ "${kernel}" "${rootfs}"]
|
||||||
|
(builtins.readFile ./pigeon.sh);
|
||||||
|
};
|
||||||
|
|
||||||
|
hooks = pkgs.writeText "pigeon-hooks.json"
|
||||||
|
(builtins.replaceStrings [ "@pigeon@" ] [ "${pigeon}" ]
|
||||||
|
(builtins.readFile ./hooks.json));
|
||||||
|
|
||||||
|
pigeon-webhook = pkgs.writeShellApplication {
|
||||||
|
name = "pigeon-webhook";
|
||||||
|
runtimeInputs = with pkgs; [ webhook ];
|
||||||
|
text = ''
|
||||||
|
: "''${PIGEON_GITLAB_SECRET:?}"
|
||||||
|
: "''${PIGEON_GITLAB_TOKEN:?}"
|
||||||
|
: "''${PIGEON_PROJECTS:?}"
|
||||||
|
exec webhook -hooks ${hooks} -template -port 3000 -verbose
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
packages.x86_64-linux.default = pigeon-webhook;
|
||||||
|
};
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "release",
|
||||||
|
"execute-command": "@pigeon@",
|
||||||
|
"include-command-output-in-response": false,
|
||||||
|
"pass-arguments-to-command": [
|
||||||
|
{ "source": "payload", "name": "project.id" },
|
||||||
|
{ "source": "payload", "name": "project.namespace" },
|
||||||
|
{ "source": "payload", "name": "project.name" },
|
||||||
|
{ "source": "payload", "name": "commit.id" },
|
||||||
|
{ "source": "payload", "name": "tag" }
|
||||||
|
],
|
||||||
|
"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_SECRET` | js }}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export PATH=/bin TMPDIR=/tmp
|
||||||
|
trap 'sync ; echo 1 >/proc/sys/kernel/sysrq ; echo b >/proc/sysrq-trigger' EXIT
|
||||||
|
|
||||||
|
mount -t proc proc /proc
|
||||||
|
mount -t devtmpfs devtmpfs /dev
|
||||||
|
mount -t tmpfs tmp /tmp
|
||||||
|
mount -t ext4 -r /dev/vdb /root/student
|
||||||
|
mount -t ext4 -r /dev/vdc /root/project
|
||||||
|
mount -t ext4 /dev/vdd /root/results
|
||||||
|
|
||||||
|
cp -a /root/student/. /tmp/
|
||||||
|
cp -a --remove-destination /root/project/build/. /tmp/
|
||||||
|
chmod -R 777 /tmp
|
||||||
|
cd /tmp
|
||||||
|
|
||||||
|
(
|
||||||
|
ulimit -t 30 -u 256 -n 256 -f 2048
|
||||||
|
timeout -s 9 30 \
|
||||||
|
setpriv --reuid=1 --regid=1 --clear-groups --no-new-privs --inh-caps=-all \
|
||||||
|
make >/root/results/build.log 2>&1
|
||||||
|
echo $? >/root/results/build.status
|
||||||
|
)
|
||||||
|
[ "$(cat /root/results/build.status)" != 0 ] && exit 1
|
||||||
|
|
||||||
|
for TEST in /root/project/tests/*.sh ; do
|
||||||
|
(
|
||||||
|
ulimit -t 2 -u 256 -n 256 -f 2048
|
||||||
|
timeout -s 9 2 \
|
||||||
|
setpriv --reuid=1 --regid=1 --clear-groups --no-new-privs --inh-caps=-all \
|
||||||
|
"$TEST" >"/root/results/$(basename "$TEST" .sh)" 2>/dev/null
|
||||||
|
)
|
||||||
|
done
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
ID="$1"
|
||||||
|
NAMESPACE="$2"
|
||||||
|
PROJECT="$3"
|
||||||
|
COMMIT="$4"
|
||||||
|
TAG="$5"
|
||||||
|
|
||||||
|
: "${PIGEON_GITLAB_TOKEN:?}"
|
||||||
|
: "${PIGEON_PROJECTS:?}"
|
||||||
|
|
||||||
|
DIRECTORY="$(mktemp -d /tmp/pigeon.XXXXXXXXXX)"
|
||||||
|
trap 'rm -rf "$DIRECTORY"' EXIT
|
||||||
|
cd "$DIRECTORY"
|
||||||
|
|
||||||
|
git -c advice.detachedHead=false clone -q --rev "$COMMIT" --depth 1 \
|
||||||
|
"https://oauth2:$PIGEON_GITLAB_TOKEN@gitlab.com/$NAMESPACE/$PROJECT.git" student/
|
||||||
|
rm -rf student/.git
|
||||||
|
|
||||||
|
mkdir -p project/tests project/build
|
||||||
|
cp -a "$PIGEON_PROJECTS/$PROJECT"/tests/*.sh project/tests/
|
||||||
|
cp -a "$PIGEON_PROJECTS/$PROJECT"/build/. project/build/
|
||||||
|
|
||||||
|
mkfs.ext4 -q -F -d student student.img 16M
|
||||||
|
mkfs.ext4 -q -F -d project project.img 16M
|
||||||
|
mkfs.ext4 -q -F results.img 16M
|
||||||
|
|
||||||
|
cat >vm.json <<'EOF'
|
||||||
|
{
|
||||||
|
"boot-source": {
|
||||||
|
"kernel_image_path": "@kernel@",
|
||||||
|
"boot_args": "reboot=k panic=1 init=/init quiet nomodule i8042.noaux i8042.nomux i8042.dumbkbd swiotlb=noforce console=ttyS0"
|
||||||
|
},
|
||||||
|
"drives": [
|
||||||
|
{ "drive_id": "rootfs", "path_on_host": "@rootfs@", "is_root_device": true, "is_read_only": true },
|
||||||
|
{ "drive_id": "student", "path_on_host": "student.img", "is_root_device": false, "is_read_only": true },
|
||||||
|
{ "drive_id": "project", "path_on_host": "project.img", "is_root_device": false, "is_read_only": true },
|
||||||
|
{ "drive_id": "results", "path_on_host": "results.img", "is_root_device": false, "is_read_only": false }
|
||||||
|
],
|
||||||
|
"machine-config": { "vcpu_count": 1, "mem_size_mib": 512 }
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
firecracker --no-api --level Error --config-file vm.json
|
||||||
|
|
||||||
|
RESULT=""
|
||||||
|
TESTS="$PIGEON_PROJECTS/$PROJECT/tests"
|
||||||
|
for TEST in "$TESTS"/*.sh ; do
|
||||||
|
debugfs -R "cat /$(basename "$TEST" .sh)" results.img >scratch 2>/dev/null
|
||||||
|
if cmp scratch "$TESTS/$(basename "$TEST" .sh).expected" ; then
|
||||||
|
RESULT="${RESULT}PASS\n"
|
||||||
|
else
|
||||||
|
RESULT="${RESULT}FAIL: $(cat "$TESTS/$(basename "$TEST" .sh).hint")\n"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
curl -s --show-error --out-null --request PUT \
|
||||||
|
--header "PRIVATE-TOKEN: $PIGEON_GITLAB_TOKEN" \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data "{\"description\": \"$RESULT\"}" \
|
||||||
|
--url "https://gitlab.com/api/v4/projects/$ID/releases/$TAG"
|
||||||
Reference in New Issue
Block a user