diff --git a/ruby-hello/Config.uk b/ruby-hello/Config.uk new file mode 100644 index 00000000..f80912aa --- /dev/null +++ b/ruby-hello/Config.uk @@ -0,0 +1,7 @@ +config APPRUBYHELLO + bool "ruby-hello" + default y + select LIBRUBY + select LIBNEWLIBC + select LIBLWIP + select LIBPTHREAD_EMBEDDED diff --git a/ruby-hello/Makefile b/ruby-hello/Makefile new file mode 100644 index 00000000..c8275067 --- /dev/null +++ b/ruby-hello/Makefile @@ -0,0 +1,9 @@ +UK_ROOT ?= $(PWD)/workdir/unikraft +UK_LIBS ?= $(PWD)/workdir/libs +LIBS := $(UK_LIBS)/newlib:$(UK_LIBS)/lwip:$(UK_LIBS)/pthread-embedded:$(UK_LIBS)/ruby:$(UK_LIBS)/compiler-rt + +all: + @make -C $(UK_ROOT) A=$(PWD) L=$(LIBS) + +$(MAKECMDGOALS): + @make -C $(UK_ROOT) A=$(PWD) L=$(LIBS) $(MAKECMDGOALS) diff --git a/ruby-hello/Makefile.uk b/ruby-hello/Makefile.uk new file mode 100644 index 00000000..b2febd68 --- /dev/null +++ b/ruby-hello/Makefile.uk @@ -0,0 +1,4 @@ +$(eval $(call addlib,apprubyhello)) + +# Adding the rootfs directory as the filesystem entry point +APP_ROOTFS_FLAGS-y += -DROOTFS_DIR=\"$(APP_BASE)/rootfs\" diff --git a/ruby-hello/README.md b/ruby-hello/README.md new file mode 100644 index 00000000..cb8c7c98 --- /dev/null +++ b/ruby-hello/README.md @@ -0,0 +1,51 @@ +# Ruby Hello on Unikraft + +Build and run a Ruby Hello program as a Unikraft unikernel. Follow the instructions below to set up, configure, build, and run the application using the standard Makefile-based workflow. + +## Set Up + +Set up the required repositories by creating symbolic links to the central resource directory. Be sure to run the top-level setup.sh script first to populate the global repos/ directory. + +## Shell + +```console +./setup.sh +``` + +## Clean + +While not strictly required, it is safest to clean the previous build artifacts before a new configuration: + +```console +make distclean +``` + +## Configure + +To configure the unikernel, use the standard menu interface: + +```console +make menuconfig +``` + +In the menu, select the target architecture (e.g., x86_64) and the platform (e.g., KVM guest). Under Library Configuration, ensure ruby is selected and configure any necessary extensions. + +## Build + +Build the application for the current configuration: + +```console +make -j $(nproc) +``` + +The resulting unikernel image will be created in the build/ directory as ruby-hello_kvm-x86_64. + +## Run +To run the resulting image on Firecracker (x86_64), use the following command: + +```console +rm -f firecracker.socket +firecracker-x86_64 --config-file fc.x86_64.json --api-sock firecracker.socket +``` + +A successful run will start the Ruby interpreter and execute the helloworld.rb script inside the unikernel. diff --git a/ruby-hello/fc.x86_64.json b/ruby-hello/fc.x86_64.json new file mode 100644 index 00000000..b197752d --- /dev/null +++ b/ruby-hello/fc.x86_64.json @@ -0,0 +1,12 @@ +{ + "boot-source": { + "kernel_image_path": "build/ruby-hello_kvm-x86_64", + "boot_args": "ruby-hello_kvm-x86_64 -- /helloworld.rb" + }, + "drives": [], + "machine-config": { + "vcpu_count": 1, + "mem_size_mib": 256, + "ht_enabled": false + } +} diff --git a/ruby-hello/helloworld.rb b/ruby-hello/helloworld.rb new file mode 100644 index 00000000..5351f082 --- /dev/null +++ b/ruby-hello/helloworld.rb @@ -0,0 +1 @@ +puts 'Hello, world!' diff --git a/ruby-hello/setup.sh b/ruby-hello/setup.sh new file mode 100755 index 00000000..a7f2297e --- /dev/null +++ b/ruby-hello/setup.sh @@ -0,0 +1,37 @@ +#!/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 + +check_exists_and_create_symlink "unikraft" +check_exists_and_create_symlink "libs/newlib" +check_exists_and_create_symlink "libs/lwip" +check_exists_and_create_symlink "libs/compiler-rt" +check_exists_and_create_symlink "libs/pthread-embedded" +check_exists_and_create_symlink "libs/ruby" diff --git a/setup.sh b/setup.sh index 451b924d..e5e4c404 100755 --- a/setup.sh +++ b/setup.sh @@ -15,3 +15,8 @@ test -d repos/apps/elfloader || git clone https://github.com/unikraft/app-elfloa test -d repos/libs/redis || git clone https://github.com/unikraft/lib-redis repos/libs/redis test -d repos/libs/wamr || git clone https://github.com/unikraft/lib-wamr repos/libs/wamr test -d repos/libs/sqlite || git clone https://github.com/unikraft/lib-sqlite repos/libs/sqlite + +# for ruby +test -d repos/libs/newlib || git clone https://github.com/unikraft/lib-newlib repos/libs/newlib +test -d repos/libs/pthread-embedded || git clone https://github.com/unikraft/lib-pthread-embedded repos/libs/pthread-embedded +test -d repos/libs/ruby || git clone https://github.com/unikraft/lib-ruby repos/libs/ruby