diff --git a/Makefile.am b/Makefile.am index 23781ed..509349e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,6 +16,7 @@ odkrun_SOURCES = src/odkrun.c \ src/backend.h \ src/backend-docker.c src/backend-docker.h \ src/backend-singularity.c src/backend-singularity.h \ + src/backend-podman.c src/backend-podman.h \ src/backend-native.c src/backend-native.h \ src/backend-apple.c src/backend-apple.h \ src/owlapi.c src/owlapi.h src/owlapi-options.h \ diff --git a/README.md b/README.md index d1a7611..924980f 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ by the ODK workflows. Currently, four different backends are supported: Docker, Singularity, Apple Container, and “native” environments. -### Docker, Singularity, and Apple Container +### Docker, Singularity, Podman, and Apple Container Docker is the primary backend, and the most well supported. Unless configured otherwise at build time (option `--with-default-backend`), @@ -118,17 +118,22 @@ in an ephemeral container based on that image. The exact image used may be specified using the `--image` (`-i`) and `--tag` (`-t`) option; the default is `obolibrary/odkfull:latest`. -The Singularity and Apple Container backends rely on the same Docker -images, but used through the [Singularity container -platform](https://docs.sylabs.io/guides/latest/user-guide/#) or the -[Apple `container` tool](https://github.com/apple/container), -respectively. As its name may imply, the Apple Container backend is only -available on macOS. - -Use the `--singularity` (`-s`) option to select the Singularity backend, -and the `--apple` (`-a`) option to select the Apple Container backend. -The image to use may be selected using the same `-i` and `-t` options as -for the Docker backend. +Several other backends are available, that rely on the same Docker +images, but used through other containerization tools. The table below +lists the available backends along with the command-line options that +select them: + +| Backend | Option | +| ------- | ------ | +| [Singularity](https://docs.sylabs.io/guides/latest/user-guide/#) | `--singularity` (`-s`) | +| [Podman](https://podman.io/) | `--podman` (`-p`) | +| [Apple Container](https://github.com/apple/container) | `--apple` (`a`) | + +As its name may imply, the Apple Container backend is only available on +macOS. + +With all those backends, the image to use may be selected using the same +`-i` and `-t` options as for the Docker backend. ### Native backend diff --git a/configure.ac b/configure.ac index 25984c2..ccc336b 100644 --- a/configure.ac +++ b/configure.ac @@ -46,12 +46,13 @@ AC_DEFINE_UNQUOTED([ODK_EXECUTABLE], ["$with_odk_executable"], [Name or path of dnl Default backend AC_ARG_WITH([default-backend], [AS_HELP_STRING([--with-default-backend], - [Name of the backend to use by default. One of docker, singularity, apple, native, or none.])], + [Name of the backend to use by default. One of docker, singularity, podman, apple, native, or none.])], [], [with_default_backend=docker]) AS_CASE([$with_default_backend], [docker], [AC_DEFINE([ODK_DEFAULT_BACKEND], [odk_backend_docker_init], [Docker backend])], [singularity], [AC_DEFINE([ODK_DEFAULT_BACKEND], [odk_backend_singularity_init], [Singularity backend])], + [podman], [AC_DEFINE([ODK_DEFAULT_BACKEND], [odk_backend_podman_init], [Podman backend])], [apple], [AC_DEFINE([ODK_DEFAULT_BACKEND], [odk_backend_apple_init], [Apple Container backend])], [native], [AC_DEFINE([ODK_DEFAULT_BACKEND], [odk_backend_native_init], [Native backend])], [none], [AC_DEFINE([ODK_DEFAULT_BACKEND], [NULL], [No default backend])], diff --git a/doc/odkrun.1.in b/doc/odkrun.1.in index db18ba2..319827a 100644 --- a/doc/odkrun.1.in +++ b/doc/odkrun.1.in @@ -15,6 +15,7 @@ odkrun - ODK Runner tool .RB [ -l | --lite ] .RB [ -D | --docker ] .RB [ -s | --singulary ] +.RB [ -p | --podman ] .RB [ -a | --apple ] .RB [ -n | --native ] .RB [ --root ] @@ -71,6 +72,10 @@ backend, unless specified otherwise at configure time. Run the container with Singularity rather than Docker. This is experimental but should mostly work. .TP +.BR -p ", " --podman +Run the container with Podman rather than Docker. This is +experimental but should mostly work. +.TP .BR -a ", " --apple Run the container with Apple Container rather than Docker. This is only available on macOS. This is experimental but diff --git a/src/backend-podman.c b/src/backend-podman.c new file mode 100644 index 0000000..de6a664 --- /dev/null +++ b/src/backend-podman.c @@ -0,0 +1,122 @@ +/* + * ODK Runner + * Copyright (C) 2026 Damien Goutte-Gattat + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "backend-podman.h" + +#include +#include +#include + +#if defined(ODK_RUNNER_LINUX) +#include /* for getuid/getgid */ +#endif + +#include "backend-docker.h" + +static int +prepare(odk_backend_t *backend, odk_run_config_t *cfg) +{ + (void) backend; + + if ( (cfg->flags & ODK_FLAG_RUNASROOT) == 0 ) { +#if defined(ODK_RUNNER_LINUX) + char *user_id = mr_sprintf(NULL, "%u", getuid()); + char *group_id = mr_sprintf(NULL, "%u", getgid()); +#else + char *user_id = "1000"; + char *group_id = "1000"; +#endif + + odk_add_env_var(cfg, "ODK_USER_ID", user_id, 0); + odk_add_env_var(cfg, "ODK_GROUP_ID", group_id, 0); + } + + return 0; +} + +static int +run(odk_backend_t *backend, odk_run_config_t *cfg, char **command) +{ + int rc; + char **argv; + mem_registry_t mr = { 0 }; + + (void) backend; + + argv = odk_backend_docker_build_command(&mr, cfg, command); + argv[0] = "podman"; + rc = spawn_process(argv); + mr_free(&mr); + + return rc; +} + +static int +close_backend(odk_backend_t *backend) +{ + (void) backend; + + return 0; +} + +static int +get_total_memory(odk_backend_info_t *info) +{ + FILE *p; + int ret = -1; + + if ( (p = popen("podman info --format={{.Host.MemTotal}}", "r")) != NULL ) { + if ( fscanf(p, "%lu", &(info->total_memory)) == 1 ) + ret = 0; + else + errno = ESRCH; + pclose(p); + } + + return ret; +} + +int +odk_backend_podman_init(odk_backend_t *backend) +{ + int ret; + + backend->prepare = prepare; + backend->run = run; + backend->close = close_backend; + + ret = get_total_memory(&(backend->info)); + + return ret; +} diff --git a/src/backend-podman.h b/src/backend-podman.h new file mode 100644 index 0000000..e2b12e3 --- /dev/null +++ b/src/backend-podman.h @@ -0,0 +1,52 @@ +/* + * ODK Runner + * Copyright (C) 2026 Damien Goutte-Gattat + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ICP20261007_BACKEND_PODMAN_H +#define ICP20261007_BACKEND_PODMAN_H + +#include + +#include "backend.h" +#include "procutil.h" + +#ifdef __cpluscplus +extern "C" { +#endif + +int +odk_backend_podman_init(odk_backend_t *); + +#define odk_backend_podman_available() check_process("podman", "--version") + +#ifdef __cpluscplus +} +#endif + +#endif /* !ICP20261007_BACKEND_PODMAN_H */ diff --git a/src/odkrun.c b/src/odkrun.c index ff19043..15b2f79 100644 --- a/src/odkrun.c +++ b/src/odkrun.c @@ -47,8 +47,9 @@ #include "util.h" #include "backend-docker.h" #include "backend-singularity.h" -#include "backend-native.h" +#include "backend-podman.h" #include "backend-apple.h" +#include "backend-native.h" #include "oaklib.h" #include "owlapi.h" #include "runconf.h" @@ -85,6 +86,8 @@ Start a ODK container.\n"); -D, --docker Run the container with Docker. This is normally\n\ the default.\n\ -s, --singularity Run the container with Singularity rather\n\ + than Docker (experimental).\n\ + -p, --podman Run the container with Podman rather than\n\ than Docker (experimental)."); #if defined(ODK_RUNNER_MACOS) puts("\ @@ -462,6 +465,7 @@ main(int argc, char **argv) { "lite", 0, NULL, 'l' }, { "docker", 0, NULL, 'D' }, { "singularity", 0, NULL, 's' }, + { "podman", 0, NULL, 'p' }, #if defined (ODK_RUNNER_MACOS) { "apple", 0, NULL, 'a' }, #endif @@ -484,7 +488,7 @@ main(int argc, char **argv) odk_init_config(&cfg); - while ( (c = getopt_long(argc, argv, "+hvdi:t:lse:k:Km:D" BACKEND_OPTS, + while ( (c = getopt_long(argc, argv, "+hvdi:t:lse:k:Km:Dp" BACKEND_OPTS, options, NULL)) != -1 ) { switch ( c ) { case 'h': @@ -524,6 +528,10 @@ main(int argc, char **argv) backend_init = odk_backend_singularity_init; break; + case 'p': + backend_init = odk_backend_podman_init; + break; + #if !defined(ODK_RUNNER_WINDOWS) case 'n': backend_init = odk_backend_native_init; @@ -597,6 +605,8 @@ main(int argc, char **argv) backend_init = odk_backend_docker_init; else if ( odk_backend_singularity_available() ) backend_init = odk_backend_singularity_init; + else if ( odk_backend_podman_available() ) + backend_init = odk_backend_podman_init; else if ( odk_backend_apple_available() ) backend_init = odk_backend_apple_init; else if ( odk_backend_native_available() )