From 487d2d64794f3cc25e247bf162ce4c7f5c43ad25 Mon Sep 17 00:00:00 2001 From: alxcris Date: Tue, 7 Jul 2026 10:18:38 +0300 Subject: [PATCH 1/5] Fixed bincompat-django6.0-python3.12 Signed-off-by: alxcris --- bincompat-django6.0-python3.12/.gitignore | 2 + bincompat-django6.0-python3.12/README.md | 101 +++++++++++++ bincompat-django6.0-python3.12/fc.arm64.json | 21 +++ bincompat-django6.0-python3.12/fc.x86_64.json | 21 +++ .../rootfs/Dockerfile | 35 +++++ .../rootfs/Makefile | 13 ++ .../rootfs/requirements.txt | 1 + .../rootfs/server.py | 24 ++++ .../scripts/build/fc.x86_64 | 4 + .../scripts/build/kernel.fc.x86_64 | 4 + .../scripts/build/kernel.qemu.x86_64 | 4 + .../scripts/build/qemu.x86_64 | 4 + .../scripts/build/rootfs.x86_64 | 6 + .../scripts/common.sh | 134 ++++++++++++++++++ .../scripts/run/fc.x86_64 | 20 +++ .../scripts/run/qemu.x86_64 | 22 +++ .../scripts/test/.gitignore | 1 + .../scripts/test/all.sh | 31 ++++ .../scripts/test/common.sh | 20 +++ .../scripts/test/wrapper.sh | 24 ++++ bincompat-django6.0-python3.12/setup.sh | 38 +++++ 21 files changed, 530 insertions(+) create mode 100644 bincompat-django6.0-python3.12/.gitignore create mode 100644 bincompat-django6.0-python3.12/README.md create mode 100644 bincompat-django6.0-python3.12/fc.arm64.json create mode 100644 bincompat-django6.0-python3.12/fc.x86_64.json create mode 100644 bincompat-django6.0-python3.12/rootfs/Dockerfile create mode 100644 bincompat-django6.0-python3.12/rootfs/Makefile create mode 100644 bincompat-django6.0-python3.12/rootfs/requirements.txt create mode 100644 bincompat-django6.0-python3.12/rootfs/server.py create mode 100644 bincompat-django6.0-python3.12/scripts/build/fc.x86_64 create mode 100644 bincompat-django6.0-python3.12/scripts/build/kernel.fc.x86_64 create mode 100644 bincompat-django6.0-python3.12/scripts/build/kernel.qemu.x86_64 create mode 100644 bincompat-django6.0-python3.12/scripts/build/qemu.x86_64 create mode 100644 bincompat-django6.0-python3.12/scripts/build/rootfs.x86_64 create mode 100644 bincompat-django6.0-python3.12/scripts/common.sh create mode 100644 bincompat-django6.0-python3.12/scripts/run/fc.x86_64 create mode 100644 bincompat-django6.0-python3.12/scripts/run/qemu.x86_64 create mode 100644 bincompat-django6.0-python3.12/scripts/test/.gitignore create mode 100644 bincompat-django6.0-python3.12/scripts/test/all.sh create mode 100644 bincompat-django6.0-python3.12/scripts/test/common.sh create mode 100644 bincompat-django6.0-python3.12/scripts/test/wrapper.sh create mode 100644 bincompat-django6.0-python3.12/setup.sh diff --git a/bincompat-django6.0-python3.12/.gitignore b/bincompat-django6.0-python3.12/.gitignore new file mode 100644 index 00000000..21dc2b05 --- /dev/null +++ b/bincompat-django6.0-python3.12/.gitignore @@ -0,0 +1,2 @@ +/__pycache__/ +/workdir/ diff --git a/bincompat-django6.0-python3.12/README.md b/bincompat-django6.0-python3.12/README.md new file mode 100644 index 00000000..9b1d21ea --- /dev/null +++ b/bincompat-django6.0-python3.12/README.md @@ -0,0 +1,101 @@ +# Django 6.0 on Unikraft + +Build and run the Django 6.0 web application with the ELF Loader. The ELF Loader uses the Unikraft binary-compatibility layer in order to run native Linux binaries (ELFs) with Unikraft. The ELF has to be PIE (Position-Independent Executable), either static or dynamic. + +Follow the instructions below to set up, configure, build and run the ELF Loader for Django. + +## Quick Setup (aka TLDR) + +For a quick setup, run the commands below. +Before everything, make sure you run the command `../setup.sh` from the catalog-core repository. + +To extract, build and run Django using the Unikraft ELF Loader, use the commands below: + +```console +./setup.sh +mkdir rootfs +docker build -t unikraft-django-fs . +docker container create --name unikraft-django-container unikraft-django-fs sh +docker export unikraft-django-container -o rootfs.tar +tar xvf rootfs.tar -C rootfs/ +test -f initrd.cpio || ./workdir/unikraft/support/scripts/mkcpio initrd.cpio ./rootfs/ +make distclean +make menuconfig +make -j $(nproc) +qemu-system-x86_64 \ + -nographic \ + -m 256 \ + -netdev user,id=net0,hostfwd=tcp::8080-:8080 \ + -device virtio-net-pci,netdev=net0 \ + -kernel workdir/build/elfloader_qemu-x86_64 \ + -initrd ./initrd.cpio \ + -append "netdev.ip=172.44.0.2/24:172.44.0.1::: -- /usr/local/bin/python3 /app/server.py" +``` + +This will configure, build and run the Unikraft ELF Loader with Django. + +## Prepare the Linux ELF + +Extract the rootfs and build the filesystem to be used by the ELF Loader using: + +```console +mkdir rootfs +docker build -t unikraft-django-fs . +docker container create --name unikraft-django-container unikraft-django-fs sh +docker export unikraft-django-container -o rootfs.tar +tar xvf rootfs.tar -C rootfs/ +test -f initrd.cpio || ./workdir/unikraft/support/scripts/mkcpio initrd.cpio ./rootfs/ +``` + +## Set Up + +Set up the required repositories by running the `setup.sh` script from the catalog-core repository. + +## Clean + +To clean the previous build artifacts: + +```console +make distclean +``` + +## Configure + +To configure the kernel, use: + +```console +make menuconfig +``` + +In the console menu interface choose the platform (KVM/QEMU). + +## Build + +Build the application for the current configuration: + +```console + +make -j $(nproc) +``` + +This results in the creation of the `workdir/build/` directory storing the build artifacts. + +## Run + +Run the resulting image using QEMU: + +```console +qemu-system-x86_64 \ + -nographic \ + -m 256 \ + -netdev user,id=net0,hostfwd=tcp::8080-:8080 \ + -device virtio-net-pci,netdev=net0 \ + -kernel workdir/build/elfloader_qemu-x86_64 \ + -initrd ./initrd.cpio \ + -append "netdev.ip=172.44.0.2/24:172.44.0.1::: -- /usr/local/bin/python3 /app/server.py" +``` + +Access the Django application at http://localhost:8080 + +## Close QEMU +To close the QEMU virtual machine, use the Ctrl+a x keyboard shortcut. diff --git a/bincompat-django6.0-python3.12/fc.arm64.json b/bincompat-django6.0-python3.12/fc.arm64.json new file mode 100644 index 00000000..fd8668f1 --- /dev/null +++ b/bincompat-django6.0-python3.12/fc.arm64.json @@ -0,0 +1,21 @@ +{ + "boot-source": { + "kernel_image_path": "workdir/build/elfloader_fc-arm64", + "boot_args": "elfloader_fc-arm64 netdev.ip=172.44.0.2/24:172.44.0.1::: vfs.fstab=[ \"initrd0:/:extract::ramfs=1:\" ] -- /usr/local/bin/python3 /app/server.py", + "initrd_path": "initrd.cpio" + }, + "drives": [], + "machine-config": { + "vcpu_count": 1, + "mem_size_mib": 256, + "smt": false, + "track_dirty_pages": false + }, + "network-interfaces": [ + { + "iface_id": "net1", + "guest_mac": "06:00:ac:10:00:02", + "host_dev_name": "tap0" + } + ] +} diff --git a/bincompat-django6.0-python3.12/fc.x86_64.json b/bincompat-django6.0-python3.12/fc.x86_64.json new file mode 100644 index 00000000..f990816e --- /dev/null +++ b/bincompat-django6.0-python3.12/fc.x86_64.json @@ -0,0 +1,21 @@ +{ + "boot-source": { + "kernel_image_path": "workdir/build/elfloader_fc-x86_64", + "boot_args": "elfloader_fc-x86_64 netdev.ip=172.44.0.2/24:172.44.0.1::: vfs.fstab=[ \"initrd0:/:extract::ramfs=1:\" ] -- /usr/local/bin/python3 /app/server.py", + "initrd_path": "initrd.cpio" + }, + "drives": [], + "machine-config": { + "vcpu_count": 1, + "mem_size_mib": 256, + "smt": false, + "track_dirty_pages": false + }, + "network-interfaces": [ + { + "iface_id": "net1", + "guest_mac": "06:00:ac:10:00:02", + "host_dev_name": "tap0" + } + ] +} diff --git a/bincompat-django6.0-python3.12/rootfs/Dockerfile b/bincompat-django6.0-python3.12/rootfs/Dockerfile new file mode 100644 index 00000000..3ca252e7 --- /dev/null +++ b/bincompat-django6.0-python3.12/rootfs/Dockerfile @@ -0,0 +1,35 @@ +FROM python:3.12.11-bookworm AS base + +WORKDIR /app + +COPY requirements.txt /app +RUN pip3 install -r requirements.txt --no-cache-dir + +RUN /usr/sbin/ldconfig /usr/local/lib + +FROM scratch + +# Python executable +COPY --from=base /usr/local/bin/python3 /usr/local/bin/python3 + +# System libraries +COPY --from=base \ + /lib/x86_64-linux-gnu/libc.so.6 \ + /lib/x86_64-linux-gnu/libdl.so.2 \ + /lib/x86_64-linux-gnu/libm.so.6 \ + /lib/x86_64-linux-gnu/libpthread.so.0 \ + /lib/x86_64-linux-gnu/libutil.so.1 \ + /lib/x86_64-linux-gnu/libz.so.1 \ + /lib/x86_64-linux-gnu/ + +# Python libraries +COPY --from=base /usr/local/lib /usr/local/lib + +# Dynamic linker / loader +COPY --from=base /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 + +# Dynamic linker cache +COPY --from=base /etc/ld.so.cache /etc/ld.so.cache + +# Application files +COPY ./server.py /app/server.py diff --git a/bincompat-django6.0-python3.12/rootfs/Makefile b/bincompat-django6.0-python3.12/rootfs/Makefile new file mode 100644 index 00000000..364844b6 --- /dev/null +++ b/bincompat-django6.0-python3.12/rootfs/Makefile @@ -0,0 +1,13 @@ +UK_ROOT ?= $(PWD)/workdir/unikraft +UK_BUILD ?= $(PWD)/workdir/build +UK_APP ?= $(PWD)/workdir/apps/elfloader +LIBS_BASE = $(PWD)/workdir/libs +UK_LIBS ?= $(LIBS_BASE)/libelf + +.PHONY: all + +all: + @$(MAKE) -C $(UK_ROOT) L=$(UK_LIBS) A=$(UK_APP) O=$(UK_BUILD) + +$(MAKECMDGOALS): + @$(MAKE) -C $(UK_ROOT) L=$(UK_LIBS) A=$(UK_APP) O=$(UK_BUILD) $(MAKECMDGOALS) diff --git a/bincompat-django6.0-python3.12/rootfs/requirements.txt b/bincompat-django6.0-python3.12/rootfs/requirements.txt new file mode 100644 index 00000000..6683ee5e --- /dev/null +++ b/bincompat-django6.0-python3.12/rootfs/requirements.txt @@ -0,0 +1 @@ +django==6.0 diff --git a/bincompat-django6.0-python3.12/rootfs/server.py b/bincompat-django6.0-python3.12/rootfs/server.py new file mode 100644 index 00000000..8d501c36 --- /dev/null +++ b/bincompat-django6.0-python3.12/rootfs/server.py @@ -0,0 +1,24 @@ +import django +from django.conf import settings +from django.http import HttpResponse +from django.urls import path + +settings.configure( + ROOT_URLCONF=__name__, + ALLOWED_HOSTS=["*"], + SECRET_KEY="s3cr3t", +) +django.setup() + + +def hello(request): + return HttpResponse("Bye, World!\n") + + +urlpatterns = [ + path("", hello), +] + +if __name__ == "__main__": + from django.core.management import execute_from_command_line + execute_from_command_line(["", "runserver", "0.0.0.0:8080", "--noreload"]) \ No newline at end of file diff --git a/bincompat-django6.0-python3.12/scripts/build/fc.x86_64 b/bincompat-django6.0-python3.12/scripts/build/fc.x86_64 new file mode 100644 index 00000000..9d302a0d --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/build/fc.x86_64 @@ -0,0 +1,4 @@ +#!/bin/sh + +./scripts/build/rootfs.x86_64 +./scripts/build/kernel.fc.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/build/kernel.fc.x86_64 b/bincompat-django6.0-python3.12/scripts/build/kernel.fc.x86_64 new file mode 100644 index 00000000..e3e1b64b --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/build/kernel.fc.x86_64 @@ -0,0 +1,4 @@ +#!/bin/sh + +. ./scripts/common.sh +build_elfloader_base fc.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/build/kernel.qemu.x86_64 b/bincompat-django6.0-python3.12/scripts/build/kernel.qemu.x86_64 new file mode 100644 index 00000000..22ce322b --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/build/kernel.qemu.x86_64 @@ -0,0 +1,4 @@ +#!/bin/sh + +. ./scripts/common.sh +build_elfloader_base qemu.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/build/qemu.x86_64 b/bincompat-django6.0-python3.12/scripts/build/qemu.x86_64 new file mode 100644 index 00000000..043c96b5 --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/build/qemu.x86_64 @@ -0,0 +1,4 @@ +#!/bin/sh + +./scripts/build/rootfs.x86_64 +./scripts/build/kernel.qemu.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/build/rootfs.x86_64 b/bincompat-django6.0-python3.12/scripts/build/rootfs.x86_64 new file mode 100644 index 00000000..dc4bf990 --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/build/rootfs.x86_64 @@ -0,0 +1,6 @@ +#!/bin/sh + +rm -f initrd.cpio +make -C rootfs/ clean +make -C rootfs/ +./workdir/unikraft/support/scripts/mkcpio initrd.cpio ./rootfs/ diff --git a/bincompat-django6.0-python3.12/scripts/common.sh b/bincompat-django6.0-python3.12/scripts/common.sh new file mode 100644 index 00000000..897205bb --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/common.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +if test -z "$log_file"; then + log_file="/dev/null" +fi + +clean_up() +{ + { + # Clean up any previous instances. + sudo pkill -9 qemu-system + sudo pkill -9 firecracker + kraft stop --all + kraft rm --all + sudo kraft stop --all + sudo kraft rm --all + + # Remove previously created network interfaces. + sudo ip link set dev tap0 down + sudo ip link del dev tap0 + sudo ip link set dev virbr0 down + sudo ip link del dev virbr0 + } > /dev/null 2>&1 +} + +start_instance() +{ + # Start instance. + setsid --fork "$start_command" 1>&2 & + if test $? -ne 0; then + echo "Cannot start instance" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_ping() +{ + host="$1" + + # Connect to instance. + ping -c 1 "$host" 1>&2 + if test $? -ne 0; then + echo "Cannot ping $host" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_curl_connect() +{ + host="$1" + port="$2" + + # Query instance. + curl --retry 1 --connect-timeout 1 --max-time 10 "$host":"$port" 1>&2 + if test $? -ne 0; then + echo "Cannot connect to $host:$port" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_curl_check_reply() +{ + host="$1" + port="$2" + message="$3" + + # Check server message contents. + curl --retry 1 --connect-timeout 1 --max-time 10 "$host":"$port" | grep "$message" 1>&2 + if test $? -ne 0; then + echo "Wrong message from $host:$port" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_netcat_connect() +{ + host="$1" + port="$2" + + # Check connection. + netcat -w 3 "$host" "$port" < /dev/null 1>&2 + if test $? -ne 0; then + echo "Cannot connect to $host:$port" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_redis_connect() +{ + host="$1" + port="$2" + + redis-cli -h "$host" -p "$port" < /dev/null 1>&2 + if test $? -ne 0; then + echo "Cannot connect client to Redis server at $host:$port" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_redis_cli() +{ + host="$1" + port="$2" + + redis-cli -h "$host" -p "$port" set a 1 1>&2 + redis-cli -h "$host" -p "$port" get a 1>&2 + if test $? -eq 1; then + echo "FAILED" + echo "Cannot talk to Redis server at $host:$port" 1>&2 + clean_up + exit 1 + fi +} + +end_with_success() +{ + echo "PASSED" + clean_up + exit 0 +} + +start_command="$1" diff --git a/bincompat-django6.0-python3.12/scripts/run/fc.x86_64 b/bincompat-django6.0-python3.12/scripts/run/fc.x86_64 new file mode 100644 index 00000000..5b40e2cd --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/run/fc.x86_64 @@ -0,0 +1,20 @@ +#!/bin/sh + +if test ! -f initrd.cpio; then + echo "No initrd.cpio file found." 1>&2 + echo "Did you run the build script?" 1>&2 + exit 1 +fi + +base_kernel="workdir/base/build/elfloader_fc-x86_64" +if test ! -f "$base_kernel"; then + echo "No kernel file $base_kernel." 1>&2 + echo "Did you run the build script?" 1>&2 + exit 1 +fi + +rm -f firecracker.socket + +firecracker-x86_64 \ + --api-sock firecracker.socket \ + --config-file fc.x86_64.json diff --git a/bincompat-django6.0-python3.12/scripts/run/qemu.x86_64 b/bincompat-django6.0-python3.12/scripts/run/qemu.x86_64 new file mode 100644 index 00000000..80a9f4d4 --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/run/qemu.x86_64 @@ -0,0 +1,22 @@ +#!/bin/sh + +if test ! -f initrd.cpio; then + echo "No initrd.cpio file found." 1>&2 + echo "Did you run the build script?" 1>&2 + exit 1 +fi + +base_kernel="workdir/base/build/elfloader_qemu-x86_64" +if test ! -f "$base_kernel"; then + echo "No kernel file $base_kernel." 1>&2 + echo "Did you run the build script?" 1>&2 + exit 1 +fi + +qemu-system-x86_64 \ + -nographic \ + -m 64 \ + -cpu max \ + -append "elfloader_qemu-x86_64 vfs.fstab=[ \"initrd0:/:extract::ramfs=1:\" ] -- /hello-c" \ + -kernel "$base_kernel" \ + -initrd ./initrd.cpio diff --git a/bincompat-django6.0-python3.12/scripts/test/.gitignore b/bincompat-django6.0-python3.12/scripts/test/.gitignore new file mode 100644 index 00000000..8297d08b --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/test/.gitignore @@ -0,0 +1 @@ +/log/ diff --git a/bincompat-django6.0-python3.12/scripts/test/all.sh b/bincompat-django6.0-python3.12/scripts/test/all.sh new file mode 100644 index 00000000..055b8777 --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/test/all.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +test_build() +{ + printf "%-46s ... " build."$1" + ./scripts/build/"$1" > ./scripts/test/log/build."$1" 2>&1 + if test $? -eq 0; then + echo "PASSED" + else + echo "FAILED" + fi +} + +test_build_run() +{ + printf "%-46s ... " build."$1" + ./scripts/build/"$1" > ./scripts/test/log/build."$1" 2>&1 + if test $? -eq 0; then + echo "PASSED" + else + echo "FAILED" + fi + + printf " %-42s ... " run."$1" + ./scripts/test/wrapper.sh ./scripts/run/"$1" 2> ./scripts/test/log/run."$1" +} + +./setup.sh +test -d ./scripts/test/log || mkdir ./scripts/test/log +test_build_run qemu.x86_64 +test_build_run fc.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/test/common.sh b/bincompat-django6.0-python3.12/scripts/test/common.sh new file mode 100644 index 00000000..07793947 --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/test/common.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +elfloader_base="elfloader-basic" + +if ! test -d workdir; then + mkdir workdir +fi + +ln -sfn "../../$elfloader_base/workdir" workdir/base + +build_elfloader_base() +{ + ( + cd "../$elfloader_base" && + ./setup.sh && + make distclean && + "./scripts/build/$1" + ) || exit 1 +} + diff --git a/bincompat-django6.0-python3.12/scripts/test/wrapper.sh b/bincompat-django6.0-python3.12/scripts/test/wrapper.sh new file mode 100644 index 00000000..c612e230 --- /dev/null +++ b/bincompat-django6.0-python3.12/scripts/test/wrapper.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +. ./scripts/test/common.sh + +if test $# -ne 1; then + echo "Unknown arguments." 1>&2 + echo "Usage: $0 " 1>&2 + exit 1 +fi + +# Clean up previous instances. +clean_up + +# Start instance. +start_instance 2>&1 | grep "Hello from Unikraft!" 1>&2 +if test $? -ne 0; then + echo "Wrong message printed." 1>&2 + echo "FAILED" + clean_up + exit 1 +fi + +# Stop instance. +end_with_success diff --git a/bincompat-django6.0-python3.12/setup.sh b/bincompat-django6.0-python3.12/setup.sh new file mode 100644 index 00000000..fdd6e534 --- /dev/null +++ b/bincompat-django6.0-python3.12/setup.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +check_exists_and_create_symlink() +{ + path="$1" + + if ! test -d workdir/"$path"; then + if ! test -d ../repos/"$path"; then + echo "No directory ../repos/$path. Run the top-level setup.sh script first." 1>&2 + exit 1 + fi + depth=$(echo "$path" | awk -F / '{ print NF }') + if test "$depth" -eq 1; then + ln -sfn ../../repos/"$path" workdir/"$path" + elif test "$depth" -eq 2; then + ln -sfn ../../../repos/"$path" workdir/"$path" + else + echo "Unknown depth of path $path." 1>&2 + exit 1 + fi + fi +} + +if ! test -d workdir; then + mkdir workdir +fi + +if ! test -d workdir/libs; then + mkdir workdir/libs +fi + +if ! test -d workdir/apps; then + mkdir workdir/apps +fi + +check_exists_and_create_symlink "unikraft" +check_exists_and_create_symlink "libs/libelf" +check_exists_and_create_symlink "apps/elfloader" From ee3487af794b5df05a182cdb7b723b088f7b0c70 Mon Sep 17 00:00:00 2001 From: alxcris Date: Tue, 7 Jul 2026 10:52:38 +0300 Subject: [PATCH 2/5] Rename scripts directory to .scripts Signed-off-by: alxcris --- .../{scripts => .scripts}/build/fc.x86_64 | 0 .../{scripts => .scripts}/build/kernel.fc.x86_64 | 0 .../{scripts => .scripts}/build/kernel.qemu.x86_64 | 0 .../{scripts => .scripts}/build/qemu.x86_64 | 0 .../{scripts => .scripts}/build/rootfs.x86_64 | 0 bincompat-django6.0-python3.12/{scripts => .scripts}/common.sh | 0 .../{scripts => .scripts}/run/fc.x86_64 | 0 .../{scripts => .scripts}/run/qemu.x86_64 | 0 .../{scripts => .scripts}/test/.gitignore | 0 bincompat-django6.0-python3.12/{scripts => .scripts}/test/all.sh | 0 .../{scripts => .scripts}/test/common.sh | 0 .../{scripts => .scripts}/test/wrapper.sh | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename bincompat-django6.0-python3.12/{scripts => .scripts}/build/fc.x86_64 (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/build/kernel.fc.x86_64 (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/build/kernel.qemu.x86_64 (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/build/qemu.x86_64 (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/build/rootfs.x86_64 (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/common.sh (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/run/fc.x86_64 (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/run/qemu.x86_64 (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/test/.gitignore (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/test/all.sh (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/test/common.sh (100%) rename bincompat-django6.0-python3.12/{scripts => .scripts}/test/wrapper.sh (100%) diff --git a/bincompat-django6.0-python3.12/scripts/build/fc.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/fc.x86_64 similarity index 100% rename from bincompat-django6.0-python3.12/scripts/build/fc.x86_64 rename to bincompat-django6.0-python3.12/.scripts/build/fc.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/build/kernel.fc.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/kernel.fc.x86_64 similarity index 100% rename from bincompat-django6.0-python3.12/scripts/build/kernel.fc.x86_64 rename to bincompat-django6.0-python3.12/.scripts/build/kernel.fc.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/build/kernel.qemu.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/kernel.qemu.x86_64 similarity index 100% rename from bincompat-django6.0-python3.12/scripts/build/kernel.qemu.x86_64 rename to bincompat-django6.0-python3.12/.scripts/build/kernel.qemu.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/build/qemu.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/qemu.x86_64 similarity index 100% rename from bincompat-django6.0-python3.12/scripts/build/qemu.x86_64 rename to bincompat-django6.0-python3.12/.scripts/build/qemu.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/build/rootfs.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/rootfs.x86_64 similarity index 100% rename from bincompat-django6.0-python3.12/scripts/build/rootfs.x86_64 rename to bincompat-django6.0-python3.12/.scripts/build/rootfs.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/common.sh b/bincompat-django6.0-python3.12/.scripts/common.sh similarity index 100% rename from bincompat-django6.0-python3.12/scripts/common.sh rename to bincompat-django6.0-python3.12/.scripts/common.sh diff --git a/bincompat-django6.0-python3.12/scripts/run/fc.x86_64 b/bincompat-django6.0-python3.12/.scripts/run/fc.x86_64 similarity index 100% rename from bincompat-django6.0-python3.12/scripts/run/fc.x86_64 rename to bincompat-django6.0-python3.12/.scripts/run/fc.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/run/qemu.x86_64 b/bincompat-django6.0-python3.12/.scripts/run/qemu.x86_64 similarity index 100% rename from bincompat-django6.0-python3.12/scripts/run/qemu.x86_64 rename to bincompat-django6.0-python3.12/.scripts/run/qemu.x86_64 diff --git a/bincompat-django6.0-python3.12/scripts/test/.gitignore b/bincompat-django6.0-python3.12/.scripts/test/.gitignore similarity index 100% rename from bincompat-django6.0-python3.12/scripts/test/.gitignore rename to bincompat-django6.0-python3.12/.scripts/test/.gitignore diff --git a/bincompat-django6.0-python3.12/scripts/test/all.sh b/bincompat-django6.0-python3.12/.scripts/test/all.sh similarity index 100% rename from bincompat-django6.0-python3.12/scripts/test/all.sh rename to bincompat-django6.0-python3.12/.scripts/test/all.sh diff --git a/bincompat-django6.0-python3.12/scripts/test/common.sh b/bincompat-django6.0-python3.12/.scripts/test/common.sh similarity index 100% rename from bincompat-django6.0-python3.12/scripts/test/common.sh rename to bincompat-django6.0-python3.12/.scripts/test/common.sh diff --git a/bincompat-django6.0-python3.12/scripts/test/wrapper.sh b/bincompat-django6.0-python3.12/.scripts/test/wrapper.sh similarity index 100% rename from bincompat-django6.0-python3.12/scripts/test/wrapper.sh rename to bincompat-django6.0-python3.12/.scripts/test/wrapper.sh From d7d4fd331f9b31f514a4fc7f99a4f8b846ff32e0 Mon Sep 17 00:00:00 2001 From: alxcris Date: Tue, 7 Jul 2026 11:00:20 +0300 Subject: [PATCH 3/5] Add and adapt compiling scripts for Django Signed-off-by: alxcris --- .../.scripts/build/fc.x86_64 | 4 +- .../.scripts/build/kernel.fc.x86_64 | 2 +- .../.scripts/build/kernel.qemu.x86_64 | 2 +- .../.scripts/build/qemu.x86_64 | 4 +- .../.scripts/common.sh | 43 ++---- .../.scripts/run/fc.x86_64 | 2 +- .../.scripts/run/qemu.x86_64 | 18 ++- .../.scripts/test/README.md | 14 ++ .../.scripts/test/all.sh | 10 +- .../.scripts/test/common.sh | 140 ++++++++++++++++-- .../.scripts/test/wrapper.sh | 2 +- 11 files changed, 183 insertions(+), 58 deletions(-) create mode 100644 bincompat-django6.0-python3.12/.scripts/test/README.md diff --git a/bincompat-django6.0-python3.12/.scripts/build/fc.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/fc.x86_64 index 9d302a0d..363a161b 100644 --- a/bincompat-django6.0-python3.12/.scripts/build/fc.x86_64 +++ b/bincompat-django6.0-python3.12/.scripts/build/fc.x86_64 @@ -1,4 +1,4 @@ #!/bin/sh -./scripts/build/rootfs.x86_64 -./scripts/build/kernel.fc.x86_64 +./.scripts/build/rootfs.x86_64 +./.scripts/build/kernel.fc.x86_64 \ No newline at end of file diff --git a/bincompat-django6.0-python3.12/.scripts/build/kernel.fc.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/kernel.fc.x86_64 index e3e1b64b..18b3504d 100644 --- a/bincompat-django6.0-python3.12/.scripts/build/kernel.fc.x86_64 +++ b/bincompat-django6.0-python3.12/.scripts/build/kernel.fc.x86_64 @@ -1,4 +1,4 @@ #!/bin/sh -. ./scripts/common.sh +. ./.scripts/common.sh build_elfloader_base fc.x86_64 diff --git a/bincompat-django6.0-python3.12/.scripts/build/kernel.qemu.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/kernel.qemu.x86_64 index 22ce322b..86bd156c 100644 --- a/bincompat-django6.0-python3.12/.scripts/build/kernel.qemu.x86_64 +++ b/bincompat-django6.0-python3.12/.scripts/build/kernel.qemu.x86_64 @@ -1,4 +1,4 @@ #!/bin/sh -. ./scripts/common.sh +. ./.scripts/common.sh build_elfloader_base qemu.x86_64 diff --git a/bincompat-django6.0-python3.12/.scripts/build/qemu.x86_64 b/bincompat-django6.0-python3.12/.scripts/build/qemu.x86_64 index 043c96b5..96adfc6c 100644 --- a/bincompat-django6.0-python3.12/.scripts/build/qemu.x86_64 +++ b/bincompat-django6.0-python3.12/.scripts/build/qemu.x86_64 @@ -1,4 +1,4 @@ #!/bin/sh -./scripts/build/rootfs.x86_64 -./scripts/build/kernel.qemu.x86_64 +./.scripts/build/rootfs.x86_64 +./.scripts/build/kernel.qemu.x86_64 diff --git a/bincompat-django6.0-python3.12/.scripts/common.sh b/bincompat-django6.0-python3.12/.scripts/common.sh index 897205bb..7a61c7ec 100644 --- a/bincompat-django6.0-python3.12/.scripts/common.sh +++ b/bincompat-django6.0-python3.12/.scripts/common.sh @@ -1,38 +1,21 @@ -#!/bin/bash +#!/bin/sh -if test -z "$log_file"; then - log_file="/dev/null" +elfloader_base="elfloader-net" + +if ! test -d workdir; then + mkdir workdir fi -clean_up() -{ - { - # Clean up any previous instances. - sudo pkill -9 qemu-system - sudo pkill -9 firecracker - kraft stop --all - kraft rm --all - sudo kraft stop --all - sudo kraft rm --all - - # Remove previously created network interfaces. - sudo ip link set dev tap0 down - sudo ip link del dev tap0 - sudo ip link set dev virbr0 down - sudo ip link del dev virbr0 - } > /dev/null 2>&1 -} +ln -sfn "../../$elfloader_base/workdir" workdir/base -start_instance() +build_elfloader_base() { - # Start instance. - setsid --fork "$start_command" 1>&2 & - if test $? -ne 0; then - echo "Cannot start instance" 1>&2 - echo "FAILED" - clean_up - exit 1 - fi + ( + cd "../$elfloader_base" && + ./setup.sh && + make distclean && + "./.scripts/build/$1" + ) || exit 1 } test_ping() diff --git a/bincompat-django6.0-python3.12/.scripts/run/fc.x86_64 b/bincompat-django6.0-python3.12/.scripts/run/fc.x86_64 index 5b40e2cd..50664f78 100644 --- a/bincompat-django6.0-python3.12/.scripts/run/fc.x86_64 +++ b/bincompat-django6.0-python3.12/.scripts/run/fc.x86_64 @@ -17,4 +17,4 @@ rm -f firecracker.socket firecracker-x86_64 \ --api-sock firecracker.socket \ - --config-file fc.x86_64.json + --config-file fc.x86_64.json \ No newline at end of file diff --git a/bincompat-django6.0-python3.12/.scripts/run/qemu.x86_64 b/bincompat-django6.0-python3.12/.scripts/run/qemu.x86_64 index 80a9f4d4..9a068638 100644 --- a/bincompat-django6.0-python3.12/.scripts/run/qemu.x86_64 +++ b/bincompat-django6.0-python3.12/.scripts/run/qemu.x86_64 @@ -13,10 +13,24 @@ if test ! -f "$base_kernel"; then exit 1 fi -qemu-system-x86_64 \ +{ +# Remove previously created network interface. +sudo ip link set dev virbr0 down +sudo ip link del dev virbr0 +sudo ip link set dev tap0 down +sudo ip link del dev tap0 +} > /dev/null 2>&1 + +# Create bridge interface for QEMU networking. +sudo ip link add dev virbr0 type bridge +sudo ip address add 172.44.0.1/24 dev virbr0 +sudo ip link set dev virbr0 up + +sudo qemu-system-x86_64 \ -nographic \ -m 64 \ -cpu max \ - -append "elfloader_qemu-x86_64 vfs.fstab=[ \"initrd0:/:extract::ramfs=1:\" ] -- /hello-c" \ + -netdev bridge,id=en0,br=virbr0 -device virtio-net-pci,netdev=en0 \ + -append "elfloader_qemu-x86_64 netdev.ip=172.44.0.2/24:172.44.0.1::: vfs.fstab=[ \"initrd0:/:extract::ramfs=1:\" ] -- /usr/local/bin/python3 /app/server.py" \ -kernel "$base_kernel" \ -initrd ./initrd.cpio diff --git a/bincompat-django6.0-python3.12/.scripts/test/README.md b/bincompat-django6.0-python3.12/.scripts/test/README.md new file mode 100644 index 00000000..b24e365b --- /dev/null +++ b/bincompat-django6.0-python3.12/.scripts/test/README.md @@ -0,0 +1,14 @@ +# Testing Django-Python Hello on Unikraft + +These are companion instructions to the main instructions in the [`README`](../../README.md) and to the scripted run instructions in the [`.scripts/README`](../README.md). +Use these scripts to test C Hello on Unikraft. + +**Note**: Run scripts from the application directory. + +Use the `all.sh` script to test all builds and all available runs: + +```console +./.scripts/test/all.sh +``` + +Logs are stored in the `./.scripts/test/log/` directory. \ No newline at end of file diff --git a/bincompat-django6.0-python3.12/.scripts/test/all.sh b/bincompat-django6.0-python3.12/.scripts/test/all.sh index 055b8777..05510ad7 100644 --- a/bincompat-django6.0-python3.12/.scripts/test/all.sh +++ b/bincompat-django6.0-python3.12/.scripts/test/all.sh @@ -3,7 +3,7 @@ test_build() { printf "%-46s ... " build."$1" - ./scripts/build/"$1" > ./scripts/test/log/build."$1" 2>&1 + ./.scripts/build/"$1" > ./.scripts/test/log/build."$1" 2>&1 if test $? -eq 0; then echo "PASSED" else @@ -14,7 +14,7 @@ test_build() test_build_run() { printf "%-46s ... " build."$1" - ./scripts/build/"$1" > ./scripts/test/log/build."$1" 2>&1 + ./.scripts/build/"$1" > ./.scripts/test/log/build."$1" 2>&1 if test $? -eq 0; then echo "PASSED" else @@ -22,10 +22,10 @@ test_build_run() fi printf " %-42s ... " run."$1" - ./scripts/test/wrapper.sh ./scripts/run/"$1" 2> ./scripts/test/log/run."$1" + ./.scripts/test/wrapper.sh ./.scripts/run/"$1" 2> ./.scripts/test/log/run."$1" } ./setup.sh -test -d ./scripts/test/log || mkdir ./scripts/test/log +test -d ./.scripts/test/log || mkdir ./.scripts/test/log test_build_run qemu.x86_64 -test_build_run fc.x86_64 +test_build_run fc.x86_64 \ No newline at end of file diff --git a/bincompat-django6.0-python3.12/.scripts/test/common.sh b/bincompat-django6.0-python3.12/.scripts/test/common.sh index 07793947..3cb25a35 100644 --- a/bincompat-django6.0-python3.12/.scripts/test/common.sh +++ b/bincompat-django6.0-python3.12/.scripts/test/common.sh @@ -1,20 +1,134 @@ -#!/bin/sh +#!/bin/bash -elfloader_base="elfloader-basic" - -if ! test -d workdir; then - mkdir workdir +if test -z "$log_file"; then + log_file="/dev/null" fi -ln -sfn "../../$elfloader_base/workdir" workdir/base +clean_up() +{ + { + # Clean up any previous instances. + sudo pkill -9 qemu-system + sudo pkill -9 firecracker + kraft stop --all + kraft rm --all + sudo kraft stop --all + sudo kraft rm --all + + # Remove previously created network interfaces. + sudo ip link set dev tap0 down + sudo ip link del dev tap0 + sudo ip link set dev virbr0 down + sudo ip link del dev virbr0 + } > /dev/null 2>&1 +} + +start_instance() +{ + # Start instance. + setsid --fork "$start_command" 1>&2 & + if test $? -ne 0; then + echo "Cannot start instance" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_ping() +{ + host="$1" + + # Connect to instance. + ping -c 1 "$host" 1>&2 + if test $? -ne 0; then + echo "Cannot ping $host" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_curl_connect() +{ + host="$1" + port="$2" + + # Query instance. + curl --retry 1 --connect-timeout 1 --max-time 10 "$host":"$port" 1>&2 + if test $? -ne 0; then + echo "Cannot connect to $host:$port" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_curl_check_reply() +{ + host="$1" + port="$2" + message="$3" + + # Check server message contents. + curl --retry 1 --connect-timeout 1 --max-time 10 "$host":"$port" | grep "$message" 1>&2 + if test $? -ne 0; then + echo "Wrong message from $host:$port" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_netcat_connect() +{ + host="$1" + port="$2" + + # Check connection. + netcat -w 3 "$host" "$port" < /dev/null 1>&2 + if test $? -ne 0; then + echo "Cannot connect to $host:$port" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_redis_connect() +{ + host="$1" + port="$2" + + redis-cli -h "$host" -p "$port" < /dev/null 1>&2 + if test $? -ne 0; then + echo "Cannot connect client to Redis server at $host:$port" 1>&2 + echo "FAILED" + clean_up + exit 1 + fi +} + +test_redis_cli() +{ + host="$1" + port="$2" + + redis-cli -h "$host" -p "$port" set a 1 1>&2 + redis-cli -h "$host" -p "$port" get a 1>&2 + if test $? -eq 1; then + echo "FAILED" + echo "Cannot talk to Redis server at $host:$port" 1>&2 + clean_up + exit 1 + fi +} -build_elfloader_base() +end_with_success() { - ( - cd "../$elfloader_base" && - ./setup.sh && - make distclean && - "./scripts/build/$1" - ) || exit 1 + echo "PASSED" + clean_up + exit 0 } +start_command="$1" \ No newline at end of file diff --git a/bincompat-django6.0-python3.12/.scripts/test/wrapper.sh b/bincompat-django6.0-python3.12/.scripts/test/wrapper.sh index c612e230..40f5066c 100644 --- a/bincompat-django6.0-python3.12/.scripts/test/wrapper.sh +++ b/bincompat-django6.0-python3.12/.scripts/test/wrapper.sh @@ -1,6 +1,6 @@ #!/bin/sh -. ./scripts/test/common.sh +. ./.scripts/test/common.sh if test $# -ne 1; then echo "Unknown arguments." 1>&2 From d92f19a7f33c76d42b4bda52d761bd54d91522d3 Mon Sep 17 00:00:00 2001 From: alxcris Date: Tue, 7 Jul 2026 11:32:19 +0300 Subject: [PATCH 4/5] Removed arm64.json Signed-off-by: alxcris --- bincompat-django6.0-python3.12/fc.arm64.json | 21 -------------------- 1 file changed, 21 deletions(-) delete mode 100644 bincompat-django6.0-python3.12/fc.arm64.json diff --git a/bincompat-django6.0-python3.12/fc.arm64.json b/bincompat-django6.0-python3.12/fc.arm64.json deleted file mode 100644 index fd8668f1..00000000 --- a/bincompat-django6.0-python3.12/fc.arm64.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "boot-source": { - "kernel_image_path": "workdir/build/elfloader_fc-arm64", - "boot_args": "elfloader_fc-arm64 netdev.ip=172.44.0.2/24:172.44.0.1::: vfs.fstab=[ \"initrd0:/:extract::ramfs=1:\" ] -- /usr/local/bin/python3 /app/server.py", - "initrd_path": "initrd.cpio" - }, - "drives": [], - "machine-config": { - "vcpu_count": 1, - "mem_size_mib": 256, - "smt": false, - "track_dirty_pages": false - }, - "network-interfaces": [ - { - "iface_id": "net1", - "guest_mac": "06:00:ac:10:00:02", - "host_dev_name": "tap0" - } - ] -} From 82fd7c3226b74be40ae8a63c64d0f15004a3a6df Mon Sep 17 00:00:00 2001 From: alxcris Date: Tue, 7 Jul 2026 11:36:31 +0300 Subject: [PATCH 5/5] Added scripts README Signed-off-by: alxcris --- .../.scripts/README.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 bincompat-django6.0-python3.12/.scripts/README.md diff --git a/bincompat-django6.0-python3.12/.scripts/README.md b/bincompat-django6.0-python3.12/.scripts/README.md new file mode 100644 index 00000000..5b70c783 --- /dev/null +++ b/bincompat-django6.0-python3.12/.scripts/README.md @@ -0,0 +1,48 @@ +# Scripts for Bincompat Django server on Unikraft + +These are companions instruction to the main instructions in the [`README`](README.md). + +Use scripts as quick actions for building and running the bincompat C HTTP server on Unikraft: + +**Note**: Run scripts from the application directory. + +## Build for / : + +```console +./.scripts/build/. +``` + +e.g.: + +```console +./.scripts/build/qemu.x86_64 +./.scripts/build/fc.x86_64 +``` + +## Build for / using a different compiler + +```console +CC=/path/to/compiler ./.scripts/build/. +``` + +e.g. + +```console +CC=/usr/bin/gcc-12 ./.scripts/build/qemu.x86_64 +CC=/usr/bin/clang ./.scripts/build/qemu.x86_64 +CC=/usr/bin/gcc-12 ./.scripts/build/fc.x86_64 +CC=/usr/bin/clang ./.scripts/build/fc.x86_64 +``` + +## Run on / + +```console +./.scripts/run/. +``` + +e.g. + +```console +./.scripts/run/qemu.x86_64 +./.scripts/run/fc.x86_64 +```