diff --git a/Makefile.am b/Makefile.am index e10ff5cfac..d2cbbd62a2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,6 +51,7 @@ libcrun_SOURCES = src/libcrun/utils.c \ src/libcrun/handlers/handler-utils.c \ src/libcrun/handlers/krun.c \ src/libcrun/handlers/mono.c \ + src/libcrun/handlers/spin.c \ src/libcrun/handlers/wasmedge.c \ src/libcrun/handlers/wasmer.c \ src/libcrun/handlers/wasmtime.c \ diff --git a/configure.ac b/configure.ac index 870f0bed07..0b3746141f 100644 --- a/configure.ac +++ b/configure.ac @@ -132,6 +132,10 @@ AS_IF([test "x$with_libkrun" = "xyes"], AC_CHECK_HEADERS([libkrun.h], AC_DEFINE( AM_CONDITIONAL([ENABLE_KRUN], [test "x$with_libkrun" = xyes]) +dnl include support for spin (EXPERIMENTAL) +AC_ARG_WITH([spin], AS_HELP_STRING([--with-spin], [build with spin support])) +AS_IF([test "x$with_spin" = "xyes"], AC_DEFINE([HAVE_SPIN], 1, [Define if spin is available])) + dnl libseccomp AC_ARG_ENABLE([seccomp], diff --git a/src/libcrun/custom-handler.c b/src/libcrun/custom-handler.c index 57ce2009b8..472f918189 100644 --- a/src/libcrun/custom-handler.c +++ b/src/libcrun/custom-handler.c @@ -48,6 +48,9 @@ extern struct custom_handler_s handler_wasmer; #if HAVE_DLOPEN && HAVE_MONO extern struct custom_handler_s handler_mono; #endif +#if HAVE_DLOPEN && HAVE_SPIN +extern struct custom_handler_s handler_spin; +#endif static struct custom_handler_s *static_handlers[] = { #if HAVE_DLOPEN && HAVE_LIBKRUN @@ -64,6 +67,9 @@ static struct custom_handler_s *static_handlers[] = { #endif #if HAVE_DLOPEN && HAVE_MONO &handler_mono, +#endif +#if HAVE_DLOPEN && HAVE_SPIN + &handler_spin, #endif NULL, }; diff --git a/src/libcrun/handlers/spin.c b/src/libcrun/handlers/spin.c new file mode 100644 index 0000000000..94fac12d92 --- /dev/null +++ b/src/libcrun/handlers/spin.c @@ -0,0 +1,116 @@ +/* + * crun - OCI runtime written in C + * + * Copyright (C) 2023 Sven Pfennig + * crun is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * crun is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with crun. If not, see . + */ +#define _GNU_SOURCE + +#include +#include "../custom-handler.h" +#include "../linux.h" +#include + +#ifdef HAVE_DLOPEN +# include +#endif + +#ifdef HAVE_SPIN + +#endif + +#if HAVE_DLOPEN && HAVE_SPIN +static int +spin_exec (void *cookie arg_unused, libcrun_container_t *container arg_unused, + const char *pathname arg_unused, char *const argv[] arg_unused) +{ + // wasmtime fails to determine default config path if $HOME is not set + char *newenviron[] = { "HOME=/root", NULL }; + char *newargv[] = { "/bin/spin", "up", "--listen", "0.0.0.0:80", NULL }; + + // spin up needs a /tmp folder + int dir_result = mkdir ("/tmp", 0777); + if (dir_result != 0 && errno != EEXIST) + { + error (EXIT_FAILURE, errno, "failed to execute mkdir `/tmp`"); + } + + execve (newargv[0], newargv, newenviron); + perror ("execve"); + exit (EXIT_FAILURE); +} + +static int +spin_load (void **cookie, libcrun_error_t *err) +{ + return 0; +} + +static int +spin_configure_container (void *cookie arg_unused, enum handler_configure_phase phase, + libcrun_context_t *context arg_unused, libcrun_container_t *container, + const char *rootfs arg_unused, libcrun_error_t *err) +{ + int ret; + if (phase != HANDLER_CONFIGURE_MOUNTS) + return 0; + + char *options[] = { + "ro", + "rprivate", + "nosuid", + "nodev", + "rbind" + }; + + ret = libcrun_container_do_bind_mount (container, "/usr/local/bin/spin", "/bin/spin", options, 5, err); + if (ret != 0) + return ret; + + /* release any error if set since we are going to be returning from here */ + crun_error_release (err); + + return 0; +} + +static int +spin_unload (void *cookie, libcrun_error_t *err) +{ + return 0; +} + +static int +spin_can_handle_container (libcrun_container_t *container, libcrun_error_t *err arg_unused) +{ + const char *entrypoint_executable; + + if (container->container_def->process == NULL || container->container_def->process->args == NULL) + return 0; + + entrypoint_executable = container->container_def->process->args[0]; + return strcmp (entrypoint_executable, "/") ? 0 : 1; +} + +struct custom_handler_s handler_spin = { + .name = "spin", + .alias = NULL, + .feature_string = "WASM:spin", + .load = spin_load, + .unload = spin_unload, + .run_func = spin_exec, + .can_handle_container = spin_can_handle_container, + .configure_container = spin_configure_container, +}; + +#endif