diff --git a/1817.diff b/1817.diff deleted file mode 100644 index 3f06f4b..0000000 --- a/1817.diff +++ /dev/null @@ -1,2319 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index b4c76cd..5785734 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -404,7 +404,6 @@ AC_CONFIG_FILES([ - src/lib/runtime/files/group/Makefile - src/lib/runtime/files/passwd/Makefile - src/lib/runtime/files/resolvconf/Makefile -- src/lib/runtime/files/libs/Makefile - src/lib/runtime/mounts/Makefile - src/lib/runtime/mounts/cwd/Makefile - src/lib/runtime/mounts/dev/Makefile -@@ -412,9 +411,11 @@ AC_CONFIG_FILES([ - src/lib/runtime/mounts/home/Makefile - src/lib/runtime/mounts/hostfs/Makefile - src/lib/runtime/mounts/kernelfs/Makefile -+ src/lib/runtime/mounts/libs/Makefile - src/lib/runtime/mounts/tmp/Makefile - src/lib/runtime/mounts/userbinds/Makefile - src/lib/runtime/mounts/scratch/Makefile -+ src/lib/runtime/mounts/domounts/Makefile - src/lib/runtime/enter/Makefile - src/lib/runtime/enter/chroot/Makefile - src/lib/runtime/environment/Makefile -diff --git a/etc/singularity.conf.in b/etc/singularity.conf.in -index ecfff37..61a9cbd 100644 ---- a/etc/singularity.conf.in -+++ b/etc/singularity.conf.in -@@ -137,6 +137,14 @@ bind path = /etc/hosts - @ENABLE_OVERLAY@ = @ENABLE_OVERLAY_DEFAULT@ - - -+# ENABLE UNDERLAY: [yes/no] -+# DEFAULT: @ENABLE_UNDERLAY_DEFAULT@ -+# Enabling this option will make it possible to specify bind paths to locations -+# that do not currently exist within the container, similar to the overlay -+# option. This will only be used if overlay is not enabled. -+@ENABLE_UNDERLAY@ = @ENABLE_UNDERLAY_DEFAULT@ -+ -+ - # MOUNT SLAVE: [BOOL] - # DEFAULT: @MOUNT_SLAVE_DEFAULT@ - # Should we automatically propagate file-system changes from the host? -diff --git a/src/Makefile.am b/src/Makefile.am -index 9cb40b6..e1eff01 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -15,7 +15,7 @@ EXTRA_PROGRAMS = action-suid mount-suid start-suid - cleanupd_SOURCES = cleanupd.c util/util.c util/file.c util/message.c util/privilege.c util/config_parser.c util/registry.c - cleanupd_CPPFLAGS = $(AM_CPPFLAGS) - --action_SOURCES = action.c util/util.c util/file.c util/registry.c util/privilege.c util/sessiondir.c util/suid.c util/cleanupd.c util/daemon.c util/mount.c -+action_SOURCES = action.c util/util.c util/file.c util/registry.c util/privilege.c util/sessiondir.c util/suid.c util/cleanupd.c util/daemon.c util/mount.c util/mountlist.c - action_LDADD = lib/image/libsingularity-image.la lib/runtime/libsingularity-runtime.la action-lib/libinternal.la - action_CPPFLAGS = $(AM_CPPFLAGS) - -@@ -24,7 +24,7 @@ builddef_LDADD = lib/image/libsingularity-image.la lib/runtime/libsingularity-ru - builddef_CPPFLAGS = $(AM_CPPFLAGS) - builddef_LDFLAGS = -static - --start_SOURCES = start.c util/util.c util/file.c util/registry.c util/privilege.c util/sessiondir.c util/suid.c util/cleanupd.c util/fork.c util/daemon.c util/signal.c util/mount.c -+start_SOURCES = start.c util/util.c util/file.c util/registry.c util/privilege.c util/sessiondir.c util/suid.c util/cleanupd.c util/fork.c util/daemon.c util/signal.c util/mount.c util/mountlist.c - start_LDADD = lib/image/libsingularity-image.la lib/runtime/libsingularity-runtime.la action-lib/libinternal.la - start_CPPFLAGS = $(AM_CPPFLAGS) - -@@ -33,7 +33,7 @@ docker_extract_LDADD = -larchive - docker_extract_CPPFLAGS = $(AM_CPPFLAGS) - docker_extract_LDFLAGS = -static - --mount_SOURCES = mount.c util/util.c util/file.c util/registry.c util/suid.c util/privilege.c util/mount.c -+mount_SOURCES = mount.c util/util.c util/file.c util/registry.c util/suid.c util/privilege.c util/mount.c util/mountlist.c - mount_LDADD = lib/image/libsingularity-image.la lib/runtime/libsingularity-runtime.la - mount_CPPFLAGS = $(AM_CPPFLAGS) - -diff --git a/src/lib/image/Makefile.am b/src/lib/image/Makefile.am -index 81e7161..44cfb42 100644 ---- a/src/lib/image/Makefile.am -+++ b/src/lib/image/Makefile.am -@@ -13,7 +13,7 @@ distincludedir = $(includedir)/singularity - noinst_LTLIBRARIES = libimage.la - #libimage_la_LIBADD = bind/libinternal.la create/libinternal.la check/libinternal.la expand/libinternal.la mount/libinternal.la offset/libinternal.la open/libinternal.la ext3/libinternal.la dir/libinternal.la squashfs/libinternal.la - libimage_la_LIBADD = ext3/libinternal.la dir/libinternal.la squashfs/libinternal.la --libimage_la_SOURCES = image.c bind.c ../../util/registry.c ../../util/message.c ../../util/config_parser.c ../../util/privilege.c ../../util/util.c ../../util/file.c ../../util/suid.c ../../util/mount.c -+libimage_la_SOURCES = image.c bind.c ../../util/registry.c ../../util/message.c ../../util/config_parser.c ../../util/privilege.c ../../util/util.c ../../util/file.c ../../util/suid.c ../../util/mount.c ../../util/mountlist.c - libimage_la_CFLAGS = $(AM_CFLAGS) # This fixes duplicate sources in library and progs - - distinclude_HEADERS = image.h bind.h -diff --git a/src/lib/runtime/Makefile.am b/src/lib/runtime/Makefile.am -index ed83005..d292cca 100644 ---- a/src/lib/runtime/Makefile.am -+++ b/src/lib/runtime/Makefile.am -@@ -11,7 +11,7 @@ distincludedir = $(includedir)/singularity - - noinst_LTLIBRARIES = libinternal.la - libinternal_la_LIBADD = ns/libinternal.la mounts/libinternal.la files/libinternal.la enter/libinternal.la overlayfs/libinternal.la environment/libinternal.la autofs/libinternal.la --libinternal_la_SOURCES = runtime.c ../../util/fork.c ../../util/registry.c ../../util/message.c ../../util/config_parser.c ../../util/privilege.c ../../util/util.c ../../util/file.c ../../util/setns.c ../../util/mount.c ../../util/cleanupd.c ../../util/sessiondir.c ../../action-lib/ready.c -+libinternal_la_SOURCES = runtime.c ../../util/fork.c ../../util/registry.c ../../util/message.c ../../util/config_parser.c ../../util/privilege.c ../../util/util.c ../../util/file.c ../../util/setns.c ../../util/mount.c ../../util/cleanupd.c ../../util/sessiondir.c ../../action-lib/ready.c ../../util/mountlist.c - libinternal_la_CFLAGS = $(AM_CFLAGS) # This fixes duplicate sources in library and progs - - distinclude_HEADERS = runtime.h -diff --git a/src/lib/runtime/files/Makefile.am b/src/lib/runtime/files/Makefile.am -index 017c0ee..c2551ce 100644 ---- a/src/lib/runtime/files/Makefile.am -+++ b/src/lib/runtime/files/Makefile.am -@@ -1,4 +1,4 @@ --SUBDIRS = passwd group resolvconf libs -+SUBDIRS = passwd group resolvconf - - MAINTAINERCLEANFILES = Makefile.in - DISTCLEANFILES = Makefile -@@ -11,7 +11,7 @@ AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\ - - noinst_LTLIBRARIES = libinternal.la - --libinternal_la_LIBADD = passwd/libinternal.la group/libinternal.la resolvconf/libinternal.la libs/libinternal.la -+libinternal_la_LIBADD = passwd/libinternal.la group/libinternal.la resolvconf/libinternal.la - libinternal_la_SOURCES = files.c file-bind.c - - EXTRA_DIST = file-bind.h files.h -diff --git a/src/lib/runtime/files/files.c b/src/lib/runtime/files/files.c -index 434d53c..915f81a 100644 ---- a/src/lib/runtime/files/files.c -+++ b/src/lib/runtime/files/files.c -@@ -36,7 +36,6 @@ - #include "./passwd/passwd.h" - #include "./group/group.h" - #include "./resolvconf/resolvconf.h" --#include "./libs/libs.h" - - - int _singularity_runtime_files(void) { -@@ -46,7 +45,6 @@ int _singularity_runtime_files(void) { - retval += _singularity_runtime_files_passwd(); - retval += _singularity_runtime_files_group(); - retval += _singularity_runtime_files_resolvconf(); -- retval += _singularity_runtime_files_libs(); - - return(retval); - } -diff --git a/src/lib/runtime/files/libs/Makefile.am b/src/lib/runtime/files/libs/Makefile.am -deleted file mode 100644 -index f54f504..0000000 ---- a/src/lib/runtime/files/libs/Makefile.am -+++ /dev/null -@@ -1,12 +0,0 @@ --MAINTAINERCLEANFILES = Makefile.in --DISTCLEANFILES = Makefile --CLEANFILES = core.* *~ *.la -- --AM_CFLAGS = -Wall -fpie --AM_LDFLAGS = -pie --AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DLIBEXECDIR=\"$(libexecdir)\" $(SINGULARITY_DEFINES) -- --noinst_LTLIBRARIES = libinternal.la --libinternal_la_SOURCES = libs.c -- --EXTRA_DIST = libs.h -diff --git a/src/lib/runtime/files/libs/libs.c b/src/lib/runtime/files/libs/libs.c -deleted file mode 100644 -index 4ba6f78..0000000 ---- a/src/lib/runtime/files/libs/libs.c -+++ /dev/null -@@ -1,169 +0,0 @@ --/* -- * Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. -- * Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -- * -- * Copyright (c) 2015-2017, Gregory M. Kurtzer. All rights reserved. -- * -- * Copyright (c) 2016-2017, The Regents of the University of California, -- * through Lawrence Berkeley National Laboratory (subject to receipt of any -- * required approvals from the U.S. Dept. of Energy). All rights reserved. -- * -- * This software is licensed under a customized 3-clause BSD license. Please -- * consult LICENSE file distributed with the sources of this project regarding -- * your rights to use or distribute this software. -- * -- * NOTICE. This Software was developed under funding from the U.S. Department of -- * Energy and the U.S. Government consequently retains certain rights. As such, -- * the U.S. Government has been granted for itself and others acting on its -- * behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software -- * to reproduce, distribute copies to the public, prepare derivative works, and -- * perform publicly and display publicly, and to permit other to do so. -- * --*/ -- --#ifndef _GNU_SOURCE --#define _GNU_SOURCE --#endif -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "config.h" --#include "util/file.h" --#include "util/util.h" --#include "util/message.h" --#include "util/privilege.h" --#include "util/config_parser.h" --#include "util/registry.h" --#include "util/mount.h" -- --#include "../file-bind.h" --#include "../../runtime.h" -- -- --int _singularity_runtime_files_libs(void) { -- char *container_dir = CONTAINER_FINALDIR; -- char *tmpdir = singularity_registry_get("SESSIONDIR"); -- char *includelibs_string; -- char *libdir = joinpath(tmpdir, "/libs"); -- char *libdir_contained = joinpath(container_dir, "/.singularity.d/libs"); -- -- if ( ( includelibs_string = singularity_registry_get("CONTAINLIBS") ) != NULL ) { -- char *tok = NULL; -- char *current = strtok_r(strdup(includelibs_string), ",", &tok); -- -- singularity_message(DEBUG, "Parsing SINGULARITY_CONTAINLIBS for user-specified libraries to include.\n"); -- -- free(includelibs_string); -- -- singularity_message(DEBUG, "Checking if libdir in container exists: %s\n", libdir_contained); -- if ( is_dir(libdir_contained) != 0 ) { -- singularity_message(WARNING, "Library bind directory not present in container, update container\n"); -- } -- -- singularity_message(DEBUG, "Creating session libdir at: %s\n", libdir); -- if ( container_mkpath_nopriv(libdir, 0755) != 0 ) { -- singularity_message(ERROR, "Failed creating temp lib directory at: %s\n", libdir); -- ABORT(255); -- } -- -- while (current != NULL ) { -- char *dest = NULL; -- char *source = NULL; -- -- singularity_message(DEBUG, "Evaluating requested library path: %s\n", current); -- -- dest = joinpath(libdir, basename(current)); -- -- if ( is_file(dest) == 0 ) { -- singularity_message(VERBOSE3, "Staged library exists, skipping: %s\n", current); -- current = strtok_r(NULL, ",", &tok); -- continue; -- } -- -- if ( is_link(current) == 0 ) { -- char *link_name; -- ssize_t len; -- -- link_name = (char *) malloc(PATH_MAX); -- -- len = readlink(current, link_name, PATH_MAX-1); // Flawfinder: ignore -- if ( ( len > 0 ) && ( len <= PATH_MAX) ) { -- link_name[len] = '\0'; -- singularity_message(VERBOSE3, "Found library link source: %s -> %s\n", current, link_name); -- if ( link_name[0] == '/' ) { -- source = strdup(link_name); -- } else { -- if ( link_name[0] == '/' ) { -- source = strdup(link_name); -- } else { -- source = joinpath(dirname(strdup(current)), link_name); -- } -- } -- } else { -- singularity_message(WARNING, "Failed reading library link for %s: %s\n", current, strerror(errno)); -- ABORT(255); -- } -- free(link_name); -- -- } else if (is_file(current) == 0 ) { -- source = strdup(current); -- singularity_message(VERBOSE3, "Found library source: %s\n", source); -- } else { -- singularity_message(WARNING, "Could not find library: %s\n", current); -- current = strtok_r(NULL, ",", &tok); -- continue; -- } -- -- singularity_message(DEBUG, "Binding library source here: %s -> %s\n", source, dest); -- -- if ( fileput_nopriv(dest, "") != 0 ) { -- singularity_message(ERROR, "Failed creating file at %s: %s\n", dest, strerror(errno)); -- ABORT(255); -- } -- -- singularity_message(VERBOSE, "Binding file '%s' to '%s'\n", source, dest); -- if ( singularity_mount(source, dest, NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error binding %s to %s: %s\n", source, dest, strerror(errno)); -- ABORT(255); -- } -- -- free(source); -- free(dest); -- current = strtok_r(NULL, ",", &tok); -- } -- -- if ( is_dir(libdir_contained) != 0 ) { -- char *ld_path; -- singularity_message(DEBUG, "Attempting to create contained libdir\n"); -- if ( container_mkpath_priv(libdir_contained, 0755) != 0 ) { -- singularity_message(ERROR, "Failed creating directory %s :%s\n", libdir_contained, strerror(errno)); -- ABORT(255); -- } -- ld_path = envar_path("LD_LIBRARY_PATH"); -- if ( ld_path == NULL ) { -- singularity_message(DEBUG, "Setting LD_LIBRARY_PATH to '/.singularity.d/libs'\n"); -- envar_set("LD_LIBRARY_PATH", "/.singularity.d/libs", 1); -- } else { -- singularity_message(DEBUG, "Prepending '/.singularity.d/libs' to LD_LIBRARY_PATH\n"); -- envar_set("LD_LIBRARY_PATH", strjoin("/.singularity.d/libs:", ld_path), 1); -- } -- } -- -- singularity_message(VERBOSE, "Binding libdir '%s' to '%s'\n", libdir, libdir_contained); -- if ( singularity_mount(libdir, libdir_contained, NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error binding %s to %s: %s\n", libdir, libdir_contained, strerror(errno)); -- ABORT(255); -- } -- } -- -- return(0); --} -diff --git a/src/lib/runtime/files/libs/libs.h b/src/lib/runtime/files/libs/libs.h -deleted file mode 100644 -index e5f843d..0000000 ---- a/src/lib/runtime/files/libs/libs.h -+++ /dev/null -@@ -1,30 +0,0 @@ --/* -- * Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. -- * Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -- * -- * Copyright (c) 2015-2017, Gregory M. Kurtzer. All rights reserved. -- * -- * Copyright (c) 2016-2017, The Regents of the University of California, -- * through Lawrence Berkeley National Laboratory (subject to receipt of any -- * required approvals from the U.S. Dept. of Energy). All rights reserved. -- * -- * This software is licensed under a customized 3-clause BSD license. Please -- * consult LICENSE file distributed with the sources of this project regarding -- * your rights to use or distribute this software. -- * -- * NOTICE. This Software was developed under funding from the U.S. Department of -- * Energy and the U.S. Government consequently retains certain rights. As such, -- * the U.S. Government has been granted for itself and others acting on its -- * behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software -- * to reproduce, distribute copies to the public, prepare derivative works, and -- * perform publicly and display publicly, and to permit other to do so. -- * --*/ -- --#ifndef __SINGULARITY_RUNTIME_FILES_LIBS_H_ --#define __SINGULARITY_RUNTIME_FILES_LIBS_H_ -- --extern int _singularity_runtime_files_libs(void); -- --#endif /* __SINGULARITY_RUNTIME_FILES_LIBS_H */ -- -diff --git a/src/lib/runtime/mounts/Makefile.am b/src/lib/runtime/mounts/Makefile.am -index f945dc2..8ec7c7f 100644 ---- a/src/lib/runtime/mounts/Makefile.am -+++ b/src/lib/runtime/mounts/Makefile.am -@@ -1,4 +1,4 @@ --SUBDIRS = binds cwd dev home hostfs kernelfs scratch tmp userbinds -+SUBDIRS = binds cwd dev domounts home hostfs kernelfs libs scratch tmp userbinds - - MAINTAINERCLEANFILES = Makefile.in - DISTCLEANFILES = Makefile -@@ -11,7 +11,7 @@ AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\ - - noinst_LTLIBRARIES = libinternal.la - --libinternal_la_LIBADD = binds/libinternal.la cwd/libinternal.la dev/libinternal.la home/libinternal.la hostfs/libinternal.la kernelfs/libinternal.la scratch/libinternal.la tmp/libinternal.la userbinds/libinternal.la -+libinternal_la_LIBADD = binds/libinternal.la cwd/libinternal.la dev/libinternal.la domounts/libinternal.la home/libinternal.la hostfs/libinternal.la kernelfs/libinternal.la libs/libinternal.la scratch/libinternal.la tmp/libinternal.la userbinds/libinternal.la - libinternal_la_SOURCES = mounts.c - - EXTRA_DIST = mounts.h -diff --git a/src/lib/runtime/mounts/binds/binds.c b/src/lib/runtime/mounts/binds/binds.c -index f27323b..4865aea 100644 ---- a/src/lib/runtime/mounts/binds/binds.c -+++ b/src/lib/runtime/mounts/binds/binds.c -@@ -35,17 +35,17 @@ - #include "util/file.h" - #include "util/util.h" - #include "util/message.h" --#include "util/privilege.h" - #include "util/config_parser.h" - #include "util/registry.h" --#include "util/mount.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - - --int _singularity_runtime_mount_binds(void) { -+int _singularity_runtime_mount_binds(struct mountlist *mountlist) { - char *tmp_config_string; -- char *container_dir = CONTAINER_FINALDIR; -+ char *source = NULL; -+ char *dest = NULL; - - if ( singularity_registry_get("CONTAIN") != NULL ) { - singularity_message(DEBUG, "Skipping bind mounts as contain was requested\n"); -@@ -60,14 +60,21 @@ int _singularity_runtime_mount_binds(void) { - while ( *tmp_config_string_list != NULL ) { - tmp_config_string = strdup(*tmp_config_string_list); - tmp_config_string_list++; -- char *source = strtok(tmp_config_string, ":"); -- char *dest = strtok(NULL, ":"); -+ if (source != NULL) -+ free(source); -+ if (dest != NULL) -+ free(dest); -+ source = strtok(tmp_config_string, ":"); -+ dest = strtok(NULL, ":"); -+ source = strdup(source); - chomp(source); - if ( dest == NULL ) { - dest = strdup(source); - } else { -+ dest = strdup(dest); - chomp(dest); - } -+ free(tmp_config_string); - - singularity_message(VERBOSE2, "Found 'bind path' = %s, %s\n", source, dest); - -@@ -76,62 +83,17 @@ int _singularity_runtime_mount_binds(void) { - continue; - } - -- singularity_message(DEBUG, "Checking if bind point is already mounted: %s\n", dest); -- if ( check_mounted(dest) >= 0 ) { -- singularity_message(VERBOSE, "Not mounting bind point (already mounted): %s\n", dest); -- continue; -- } -- -- if ( ( is_file(source) == 0 ) && ( is_file(joinpath(container_dir, dest)) < 0 ) ) { -- if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { -- char *basedir = dirname(joinpath(container_dir, dest)); -- -- singularity_message(DEBUG, "Checking base directory for file %s ('%s')\n", dest, basedir); -- if ( is_dir(basedir) != 0 ) { -- singularity_message(DEBUG, "Creating base directory for file bind\n"); -- if ( container_mkpath_priv(basedir, 0755) != 0 ) { -- singularity_message(ERROR, "Failed creating base directory to bind file: %s\n", dest); -- ABORT(255); -- } -- } -- -- free(basedir); -- -- singularity_message(VERBOSE3, "Creating bind file on overlay file system: %s\n", dest); -- if ( fileput_priv(joinpath(container_dir, dest), "") != 0 ) { -- continue; -- } -- singularity_message(DEBUG, "Created bind file: %s\n", dest); -- } else { -- singularity_message(WARNING, "Non existent bind point (file) in container: '%s'\n", dest); -- continue; -- } -- } else if ( ( is_dir(source) == 0 ) && ( is_dir(joinpath(container_dir, dest)) < 0 ) ) { -- if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { -- singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest); -- if ( container_mkpath_priv(joinpath(container_dir, dest), 0755) < 0 ) { -- singularity_message(WARNING, "Could not create bind point directory in container %s: %s\n", dest, strerror(errno)); -- continue; -- } -- } else { -- singularity_message(WARNING, "Non existent bind point (directory) in container: '%s'\n", dest); -- continue; -- } -- } -- -- singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", source, container_dir, dest); -- if ( singularity_mount(source, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error binding the path %s: %s\n", source, strerror(errno)); -- ABORT(255); -- } -- if ( singularity_priv_userns_enabled() != 1 ) { -- if ( singularity_mount(NULL, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC|MS_REMOUNT, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error remounting the path %s: %s\n", source, strerror(errno)); -- ABORT(255); -- } -- } -+ singularity_message(VERBOSE, "Queuing bind mount of '%s' to '%s'\n", source, dest); -+ mountlist_add(mountlist, source, dest, NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, 0); -+ source = NULL; -+ dest = NULL; - } - -+ if (source != NULL) -+ free(source); -+ if (dest != NULL) -+ free(dest); -+ - return(0); - } - -diff --git a/src/lib/runtime/mounts/binds/binds.h b/src/lib/runtime/mounts/binds/binds.h -index f555370..200ab76 100644 ---- a/src/lib/runtime/mounts/binds/binds.h -+++ b/src/lib/runtime/mounts/binds/binds.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_BINDS_H_ - #define __SINGULARITY_RUNTIME_MOUNT_BINDS_H_ - --extern int _singularity_runtime_mount_binds(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_binds(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_BINDS_H */ - -diff --git a/src/lib/runtime/mounts/cwd/cwd.c b/src/lib/runtime/mounts/cwd/cwd.c -index c251edc..c90ffa4 100644 ---- a/src/lib/runtime/mounts/cwd/cwd.c -+++ b/src/lib/runtime/mounts/cwd/cwd.c -@@ -40,18 +40,15 @@ - #include "util/file.h" - #include "util/util.h" - #include "util/message.h" --#include "util/privilege.h" - #include "util/config_parser.h" - #include "util/registry.h" --#include "util/mount.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - - --int _singularity_runtime_mount_cwd(void) { -- char *container_dir = CONTAINER_FINALDIR; -+int _singularity_runtime_mount_cwd(struct mountlist *mountlist) { - char *cwd_path = (char *)malloc(PATH_MAX); -- int r; - - singularity_message(DEBUG, "Checking to see if we should mount current working directory\n"); - if ( cwd_path == NULL ) { -@@ -73,34 +70,6 @@ int _singularity_runtime_mount_cwd(void) { - return(0); - } - -- singularity_message(DEBUG, "Checking if current directory already available within container: %s\n", cwd_path); -- if ( is_dir(joinpath(container_dir, cwd_path)) == 0 ) { -- char *cwd_fileid = file_devino(cwd_path); -- char *container_cwd_fileid = file_devino(joinpath(container_dir, cwd_path)); -- -- singularity_message(DEBUG, "Checking if container's cwd == host's cwd\n"); -- if ( strcmp(cwd_fileid, container_cwd_fileid) == 0 ) { -- singularity_message(VERBOSE, "Not mounting current directory: location already available within container\n"); -- free(cwd_path); -- free(cwd_fileid); -- free(container_cwd_fileid); -- return(0); -- } else { -- singularity_message(DEBUG, "Container's cwd is not the same as the host, continuing on...\n"); -- } -- } else { -- singularity_message(VERBOSE, "Not mounting CWD, directory does not exist within container: %s\n", cwd_path); -- free(cwd_path); -- return(0); -- } -- -- singularity_message(DEBUG, "Checking if CWD is already mounted: %s\n", cwd_path); -- if ( check_mounted(cwd_path) >= 0 ) { -- singularity_message(VERBOSE, "Not mounting CWD (already mounted in container): %s\n", cwd_path); -- free(cwd_path); -- return(0); -- } -- - singularity_message(DEBUG, "Checking if cwd is in an operating system directory\n"); - if ( ( strcmp(cwd_path, "/") == 0 ) || - ( strcmp(cwd_path, "/bin") == 0 ) || -@@ -131,16 +100,9 @@ int _singularity_runtime_mount_cwd(void) { - return(0); - } - -- singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", cwd_path, container_dir, cwd_path); -- r = singularity_mount(cwd_path, joinpath(container_dir, cwd_path), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL); -- if ( singularity_priv_userns_enabled() != 1 ) { -- r = singularity_mount(NULL, joinpath(container_dir, cwd_path), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC|MS_REMOUNT, NULL); -- } -- if ( r < 0 ) { -- singularity_message(WARNING, "Could not bind CWD to container %s: %s\n", cwd_path, strerror(errno)); -- } -+ singularity_message(VERBOSE, "Queuing bind mount of '%s' to '%s' if mountpoint exists\n", cwd_path, cwd_path); -+ mountlist_add(mountlist, NULL, cwd_path, NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, ML_ONLY_IF_POINT_PRESENT); - -- free(cwd_path); - return(0); - } - -diff --git a/src/lib/runtime/mounts/cwd/cwd.h b/src/lib/runtime/mounts/cwd/cwd.h -index c2c9fd0..3404e12 100644 ---- a/src/lib/runtime/mounts/cwd/cwd.h -+++ b/src/lib/runtime/mounts/cwd/cwd.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_CWD_H_ - #define __SINGULARITY_RUNTIME_MOUNT_CWD_H_ - --extern int _singularity_runtime_mount_cwd(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_cwd(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_CWD_H */ - -diff --git a/src/lib/runtime/mounts/dev/dev.c b/src/lib/runtime/mounts/dev/dev.c -index 7dc7a76..cbd6f19 100644 ---- a/src/lib/runtime/mounts/dev/dev.c -+++ b/src/lib/runtime/mounts/dev/dev.c -@@ -43,14 +43,14 @@ - #include "util/registry.h" - #include "util/mount.h" - #include "util/suid.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - - static int bind_dev(char *tmpdir, char *dev); - - --int _singularity_runtime_mount_dev(void) { -- char *container_dir = CONTAINER_FINALDIR; -+int _singularity_runtime_mount_dev(struct mountlist *mountlist) { - - if ( ( singularity_registry_get("CONTAIN") != NULL ) || ( strcmp("minimal", singularity_config_get_value(MOUNT_DEV)) == 0 ) ) { - char *sessiondir = singularity_registry_get("SESSIONDIR"); -@@ -58,22 +58,6 @@ int _singularity_runtime_mount_dev(void) { - char *nvopt = singularity_registry_get("NV"); - char memfs_type[] = "tmpfs"; - -- if ( is_dir(joinpath(container_dir, "/dev")) < 0 ) { -- int ret; -- -- if ( singularity_registry_get("OVERLAYFS_ENABLED") == NULL ) { -- singularity_message(WARNING, "Not mounting devices as /dev directory does not exist within container\n"); -- return(-1); -- } -- -- ret = container_mkpath_priv(joinpath(container_dir, "/dev"), 0755); -- -- if ( ret < 0 ) { -- singularity_message(ERROR, "Could not create /dev inside container\n"); -- ABORT(255); -- } -- } -- - singularity_message(DEBUG, "Creating temporary staged /dev\n"); - if ( container_mkpath_nopriv(devdir, 0755) != 0 ) { - singularity_message(ERROR, "Failed creating the session device directory %s: %s\n", devdir, strerror(errno)); -@@ -220,31 +204,18 @@ int _singularity_runtime_mount_dev(void) { - free(devpts_opts); - } - -- singularity_message(DEBUG, "Mounting minimal staged /dev into container\n"); -- if ( singularity_mount(devdir, joinpath(container_dir, "/dev"), NULL, MS_BIND|MS_REC, NULL) < 0 ) { -- singularity_message(WARNING, "Could not stage dev tree: '%s' -> '%s': %s\n", devdir, joinpath(container_dir, "/dev"), strerror(errno)); -- free(sessiondir); -- free(devdir); -- return(-1); -- } -+ singularity_message(DEBUG, "Queuing bind mount of minimal staged /dev to mount into container\n"); -+ mountlist_add(mountlist, devdir, strdup("/dev"), NULL, MS_BIND|MS_REC, 0); - - free(sessiondir); -- free(devdir); - - return(0); - } - - singularity_message(DEBUG, "Checking configuration file for 'mount dev'\n"); - if ( singularity_config_get_bool_char(MOUNT_DEV) > 0 ) { -- if ( is_dir(joinpath(container_dir, "/dev")) == 0 ) { -- singularity_message(VERBOSE, "Bind mounting /dev\n"); -- if ( singularity_mount("/dev", joinpath(container_dir, "/dev"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "Could not bind mount container's /dev: %s\n", strerror(errno)); -- ABORT(255); -- } -- } else { -- singularity_message(WARNING, "Not mounting /dev, container has no bind directory\n"); -- } -+ singularity_message(VERBOSE, "Queuing bind mount of /dev\n"); -+ mountlist_add(mountlist, NULL, strdup("/dev"), NULL, MS_BIND|MS_NOSUID|MS_REC, 0); - return(0); - } - -diff --git a/src/lib/runtime/mounts/dev/dev.h b/src/lib/runtime/mounts/dev/dev.h -index 2e15d20..f929017 100644 ---- a/src/lib/runtime/mounts/dev/dev.h -+++ b/src/lib/runtime/mounts/dev/dev.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_DEV_H_ - #define __SINGULARITY_RUNTIME_MOUNT_DEV_H_ - --extern int _singularity_runtime_mount_dev(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_dev(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_DEV_H */ - -diff --git a/src/lib/runtime/mounts/domounts/Makefile.am b/src/lib/runtime/mounts/domounts/Makefile.am -new file mode 100644 -index 0000000..0774cef ---- /dev/null -+++ b/src/lib/runtime/mounts/domounts/Makefile.am -@@ -0,0 +1,12 @@ -+MAINTAINERCLEANFILES = Makefile.in -+DISTCLEANFILES = Makefile -+CLEANFILES = core.* *~ *.la -+ -+AM_CFLAGS = -Wall -fpie -+AM_LDFLAGS = -pie -+AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DLIBEXECDIR=\"$(libexecdir)\" $(SINGULARITY_DEFINES) -+ -+noinst_LTLIBRARIES = libinternal.la -+libinternal_la_SOURCES = domounts.c -+ -+EXTRA_DIST = domounts.h -diff --git a/src/lib/runtime/mounts/domounts/domounts.c b/src/lib/runtime/mounts/domounts/domounts.c -new file mode 100644 -index 0000000..485a87d ---- /dev/null -+++ b/src/lib/runtime/mounts/domounts/domounts.c -@@ -0,0 +1,415 @@ -+/* -+ * Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. -+ * Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -+ * -+ * Copyright (c) 2015-2017, Gregory M. Kurtzer. All rights reserved. -+ * -+ * Copyright (c) 2016-2017, The Regents of the University of California, -+ * through Lawrence Berkeley National Laboratory (subject to receipt of any -+ * required approvals from the U.S. Dept. of Energy). All rights reserved. -+ * -+ * This software is licensed under a customized 3-clause BSD license. Please -+ * consult LICENSE file distributed with the sources of this project regarding -+ * your rights to use or distribute this software. -+ * -+ * NOTICE. This Software was developed under funding from the U.S. Department of -+ * Energy and the U.S. Government consequently retains certain rights. As such, -+ * the U.S. Government has been granted for itself and others acting on its -+ * behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software -+ * to reproduce, distribute copies to the public, prepare derivative works, and -+ * perform publicly and display publicly, and to permit other to do so. -+ * -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "config.h" -+#include "util/config_parser.h" -+#include "util/file.h" -+#include "util/util.h" -+#include "util/message.h" -+#include "util/privilege.h" -+#include "util/registry.h" -+#include "util/mount.h" -+#include "util/mountlist.h" -+ -+void singularity_runtime_domounts_init(struct mountlist *mountlist) { -+ memset(mountlist, 0, sizeof(*mountlist)); -+ -+ singularity_registry_set("UNDERLAY_ENABLED", NULL); -+ if ( ( singularity_config_get_bool_char(ENABLE_UNDERLAY) > 0 ) ) { -+ if ( singularity_registry_get("DISABLE_UNDERLAY") != NULL ) { -+ singularity_message(VERBOSE3, "Not enabling underlay via environment\n"); -+ } else { -+ singularity_message(VERBOSE3, "Enabling underlay\n"); -+ singularity_registry_set("UNDERLAY_ENABLED", "1"); -+ } -+ } -+} -+ -+static void bind_image_final(char *source, char *sub_path) { -+ char *target = joinpath(CONTAINER_FINALDIR, sub_path); -+ singularity_message(VERBOSE3, "Binding %s to %s\n", source, target); -+ if ( singularity_mount(source, target, NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) { -+ -+ singularity_message(ERROR, "Failed binding %s to %s\n", source, target); -+ ABORT(255); -+ } -+ free(target); -+} -+ -+static void mount_missing(char *image_path, char *underlay_path, char *sub_path) { -+ DIR *dir; -+ struct dirent *dp; -+ char *source = NULL; -+ char *target = NULL; -+ char *existing_path = NULL; -+ int binds = 0; -+ -+ singularity_message(VERBOSE3, "Mounting missing files/directories from %s\n", image_path); -+ -+ // First find an existing mountpoint inside the underlay directory, if any -+ if ( ( dir = opendir(underlay_path) ) == NULL ) { -+ singularity_message(ERROR, "Could not open underlay dir %s", underlay_path); -+ ABORT(255); -+ } -+ while ( (dp = readdir(dir) ) != NULL ) { -+ if ( ( strcmp(dp->d_name, ".") != 0 ) && -+ ( strcmp(dp->d_name, "..") != 0 ) ) { -+ break; -+ } -+ } -+ if ( dp == NULL ) { -+ singularity_message(VERBOSE3, "Skipping empty underlay directory: %s\n", underlay_path); -+ closedir(dir); -+ return; -+ } -+ singularity_message(DEBUG, "There is at least one mountpoint in %s: %s\n", underlay_path, dp->d_name); -+ existing_path = joinpath(sub_path, dp->d_name); -+ closedir(dir); -+ -+ // Now search through the image for missing mountpoints in the underlay -+ if ( ( dir = opendir(image_path) ) == NULL ) { -+ singularity_message(ERROR, "Could not open dir %s", image_path); -+ ABORT(255); -+ } -+ -+ while ( ( dp = readdir(dir) ) != NULL ) { -+ if ( (strcmp(dp->d_name, ".") == 0 ) || (strcmp(dp->d_name, "..") == 0 ) ) -+ continue; -+ if ( source != NULL ) -+ free(source); -+ if ( target != NULL ) -+ free(target); -+ source = joinpath(image_path, dp->d_name); -+ target = joinpath(underlay_path, dp->d_name); -+ char *new_sub_path; -+ if ( strcmp(sub_path, "/") == 0 ) -+ new_sub_path = strdup(dp->d_name); -+ else -+ new_sub_path = joinpath(sub_path, dp->d_name); -+ struct stat statbuf; -+ int statret = lstat(target, &statbuf); -+ -+ if ( is_link(source) == 0 ) { -+ if ( statret < 0 ) { -+ char link[PATH_MAX+1]; -+ ssize_t linksize = readlink(source, link, PATH_MAX); // Flawfinder: ignore not controllable by user -+ if ( linksize <= 0 ) { -+ singularity_message(WARNING, "Failure reading link info from %s, skipping: %s\n", source, strerror(errno)); -+ } else { -+ link[linksize] = '\0'; -+ singularity_message(VERBOSE3, "Creating symlink on underlay file system: %s->%s\n", target, link); -+ singularity_priv_escalate(); -+ if ( symlink(link, target) < 0 ) -+ singularity_message(WARNING, "Failure making link to %s at %s, skipping: %s\n", target, source, strerror(errno)); -+ singularity_priv_drop(); -+ } -+ } else if ( S_ISDIR(statbuf.st_mode) ) { -+ // It has been replaced by a directory, recurse into it -+ mount_missing(source, target, new_sub_path); -+ } else { -+ singularity_message(VERBOSE3, "Link point on underlay file system already exists, skipping: %s\n", target); -+ } -+ } else if ( is_file(source) == 0 ) { -+ if ( statret < 0 ) { -+ singularity_message(VERBOSE3, "Creating file mountpoint on underlay file system: %s\n", target); -+ if ( fileput_priv(target, "") != 0 ) { -+ singularity_message(ERROR, "Failed creating underlay file mountpoint: %s\n", target); -+ ABORT(255); -+ } -+ bind_image_final(source, new_sub_path); -+ binds++; -+ } else { -+ singularity_message(VERBOSE3, "File mountpoint on underlay file system already exists, skipping: %s\n", target); -+ } -+ } else if ( is_dir(source) == 0 ) { -+ if ( statret < 0 ) { -+ singularity_message(VERBOSE3, "Creating directory mountpoint on underlay file system: %s\n", target); -+ if ( container_mkpath_priv(target, 0755) < 0 ) { -+ singularity_message(ERROR, "Failed creating underlay directory mountpoint: %s\n", target); -+ ABORT(255); -+ } -+ bind_image_final(source, new_sub_path); -+ binds++; -+ } else if ( S_ISDIR(statbuf.st_mode) ) { -+ mount_missing(source, target, new_sub_path); -+ } else { -+ singularity_message(VERBOSE3, "Skipping non-directory target with directory source: %s\n", target); -+ } -+ } else { -+ singularity_message(VERBOSE3, "Skipping source that is neither file nor directory nor symlink: %s\n", source); -+ } -+ free(new_sub_path); -+ } -+ -+ if ( source != NULL ) -+ free(source); -+ if ( target != NULL ) -+ free(target); -+ closedir(dir); -+ -+ if ( binds > 50 ) { -+ singularity_message(WARNING, "Underlay of /%s required more than 50 (%d) bind mounts\n", -+ existing_path, binds); -+ } else { -+ singularity_message(DEBUG, "Did %d bind mounts around /%s\n", -+ binds, existing_path); -+ } -+ free(existing_path); -+} -+ -+static int do_mounts(struct mountlist *mountlist, int overlay) { -+ char *container_dir = CONTAINER_FINALDIR; -+ char *source = NULL; -+ char *target = NULL; -+ struct mountlist_point *point; -+ -+ for (point = mountlist->first; point != NULL; point = point->next) { -+ source = (char *) point->source; -+ if ( source == NULL ) -+ source = (char *) point->target; -+ if ( target != NULL ) -+ free(target); -+ target = joinpath(container_dir, point->target); -+ -+ if ( check_mounted(point->target) >= 0 ) { -+ // make the message only information if ML_ONLY_IF_POINT_PRESENT -+ int msglevel = ( point->mountlistflags & ML_ONLY_IF_POINT_PRESENT ) ? VERBOSE : WARNING; -+ singularity_message(msglevel, "Not mounting %s (already mounted in container)\n", point->target); -+ continue; -+ } -+ -+ if ( ( is_file(source) == 0 ) && ( is_file(target) < 0 ) ) { -+ if ( point->mountlistflags & ML_ONLY_IF_POINT_PRESENT ) { -+ singularity_message(VERBOSE, "Not mounting '%s', file does not exist within container\n", source); -+ continue; -+ } -+ if ( overlay ) { -+ char *basedir = strdup(target); -+ basedir = dirname(basedir); -+ -+ singularity_message(DEBUG, "Checking base directory for file %s ('%s')\n", target, basedir); -+ if ( is_dir(basedir) != 0 ) { -+ singularity_message(DEBUG, "Creating base directory for file mount\n"); -+ if ( container_mkpath_priv(basedir, 0755) != 0 ) { -+ singularity_message(ERROR, "Failed creating base directory for mounted file: %s\n", target); -+ ABORT(255); -+ } -+ } -+ -+ free(basedir); -+ -+ singularity_message(VERBOSE3, "Creating file mountpoint on overlay file system: %s\n", target); -+ if ( fileput_priv(target, "") != 0 ) { -+ continue; -+ } -+ singularity_message(DEBUG, "Created bind file: %s\n", target); -+ } else { -+ singularity_message(WARNING, "Non existent mount point (file) in container: '%s'\n", target); -+ continue; -+ } -+ } else if ( ( is_dir(source) == 0 ) && ( is_dir(target) < 0 ) ) { -+ if ( point->mountlistflags & ML_ONLY_IF_POINT_PRESENT ) { -+ singularity_message(VERBOSE, "Not mounting '%s', directory does not exist within container\n", source); -+ continue; -+ } -+ if ( overlay ) { -+ singularity_message(VERBOSE3, "Creating mount directory on overlay file system: %s\n", target); -+ if ( container_mkpath_priv(target, 0755) < 0 ) { -+ singularity_message(WARNING, "Could not create mount point directory in container %s: %s\n", target, strerror(errno)); -+ continue; -+ } -+ } else { -+ singularity_message(WARNING, "Non existent mountpoint (directory) in container: '%s'\n", target); -+ continue; -+ } -+ } -+ -+ singularity_message(VERBOSE, "Mounting '%s' at '%s'\n", source, target); -+ int read_only = ( (point->mountflags & MS_RDONLY) != 0 ); -+ point->mountflags &= ~MS_RDONLY; -+ if ( singularity_mount_point(point) < 0 ) { -+ singularity_message(ERROR, "There was an error mounting %s: %s\n", source, strerror(errno)); -+ ABORT(255); -+ } -+ -+ if ( read_only ) { -+ if ( singularity_priv_userns_enabled() == 1 ) { -+ singularity_message(WARNING, "Can not make mount read only within the user namespace: %s\n", target); -+ } else { -+ singularity_message(VERBOSE, "Remounting %s read-only\n", target); -+ point->mountflags |= MS_REMOUNT|MS_RDONLY; -+ if ( singularity_mount_point(point) < 0 ) { -+ singularity_message(ERROR, "There was an error write-protecting the path %s: %s\n", source, strerror(errno)); -+ ABORT(255); -+ } -+ if ( access(target, W_OK) == 0 || (errno != EROFS && errno != EACCES) ) { // Flawfinder: ignore (precautionary confirmation, not necessary) -+ singularity_message(ERROR, "Failed to write-protect the path %s: %s\n", source, strerror(errno)); -+ ABORT(255); -+ } -+ } -+ } else if ( singularity_priv_userns_enabled() != 1 ) { -+ point->mountflags |= MS_REMOUNT; -+ singularity_message(VERBOSE, "Remounting %s\n", target); -+ if ( singularity_mount_point(point) < 0 ) { -+ singularity_message(ERROR, "There was an error remounting the path %s: %s\n", source, strerror(errno)); -+ ABORT(255); -+ } -+ } -+ } -+ -+ if ( target != NULL ) -+ free(target); -+ -+ return(0); -+} -+ -+static int underlay_mounts(struct mountlist *mountlist) { -+ char *underlay_dir = joinpath(singularity_registry_get("SESSIONDIR"), "underlay"); -+ char *image_dir = CONTAINER_MOUNTDIR; -+ char *final_dir = CONTAINER_FINALDIR; -+ char *source = NULL; -+ char *underlay_target = NULL; -+ char *image_target = NULL; -+ struct mountlist_point *point; -+ -+ singularity_message(DEBUG, "Creating directory for underlay: %s\n", underlay_dir); -+ if ( container_mkpath_priv(underlay_dir, 0755) < 0 ) { -+ singularity_message(ERROR, "Failed creating underlay directory %s: %s\n", underlay_dir, strerror(errno)); -+ ABORT(255); -+ } -+ -+ singularity_message(DEBUG, "Unmounting final dir %s\n", final_dir); -+ singularity_priv_escalate(); -+ if ( umount(final_dir) != 0 ) { -+ singularity_message(ERROR, "Could not umount final directory %s: %s\n", final_dir, strerror(errno)); -+ ABORT(255); -+ } -+ singularity_priv_drop(); -+ -+ singularity_message(DEBUG, "Binding underlay directory to final directory %s->%s\n", underlay_dir, final_dir); -+ if ( singularity_mount(underlay_dir, final_dir, NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) { -+ singularity_message(ERROR, "Could not bind mount underlay directory to final directory %s->%s: %s\n", underlay_dir, final_dir, strerror(errno)); -+ ABORT(255); -+ } -+ -+ // It's important for the underlay directory to be mounted read-only -+ // because otherwise when running unprivileged the code inside the -+ // container would be able to modify it's own root filesystem. -+ // It's not necessary when running setuid because then the -+ // root filesystem directory is owned by root, but do the same -+ // thing anyway for consistency. -+ singularity_message(DEBUG, "Remounting underlay directory to final directory read-only %s->%s\n", underlay_dir, final_dir); -+ if ( singularity_mount(underlay_dir, final_dir, NULL, MS_REMOUNT|MS_BIND|MS_NOSUID|MS_REC|MS_RDONLY, NULL) < 0 ) { -+ singularity_message(ERROR, "Could not re-mount underlay directory to final directory read-only %s->%s: %s\n", underlay_dir, final_dir, strerror(errno)); -+ ABORT(255); -+ } -+ errno = 0; -+ if ( access(final_dir, W_OK) == 0 || (errno != EROFS && errno != EACCES) ) { // Flawfinder: ignore (precautionary confirmation, not necessary) -+ singularity_message(ERROR, "Failed to write-protect the final directory %s: %s\n", final_dir, strerror(errno)); -+ ABORT(255); -+ } -+ -+ // make missing mount points in the underlay area -+ for (point = mountlist->first; point != NULL; point = point->next) { -+ if ( point->mountlistflags & ML_ONLY_IF_POINT_PRESENT ) -+ continue; -+ -+ source = (char *) point->source; -+ if ( source == NULL ) -+ source = (char *) point->target; -+ if ( underlay_target != NULL ) -+ free(underlay_target); -+ if ( image_target != NULL ) -+ free(image_target); -+ underlay_target = joinpath(underlay_dir, point->target); -+ image_target = joinpath(image_dir, point->target); -+ char *basedir = strdup(underlay_target); -+ basedir = dirname(basedir); -+ -+ if ( ( is_file(source) == 0 ) && ( is_file(underlay_target) < 0 ) && -+ ( ( is_file(image_target) < 0 ) || ( is_dir(basedir) == 0 ) ) ) { -+ -+ singularity_message(DEBUG, "Checking base directory for file %s ('%s')\n", underlay_target, basedir); -+ if ( is_dir(basedir) != 0 ) { -+ singularity_message(DEBUG, "Creating base directory for file mount\n"); -+ if ( container_mkpath_priv(basedir, 0755) != 0 ) { -+ singularity_message(ERROR, "Failed creating base directory for mounted file: %s\n", underlay_target); -+ ABORT(255); -+ } -+ } -+ -+ -+ singularity_message(VERBOSE3, "Creating file mountpoint on underlay file system: %s\n", underlay_target); -+ if ( fileput_priv(underlay_target, "") != 0 ) { -+ singularity_message(ERROR, "Could not create mount point file in underlay %s: %s\n", underlay_target, strerror(errno)); -+ ABORT(255); -+ } -+ singularity_message(DEBUG, "Created bind file: %s\n", underlay_target); -+ } else if ( ( ( point->filesystemtype != NULL ) || -+ ( is_dir(source) == 0 ) ) && -+ ( is_dir(underlay_target) < 0 ) && -+ ( ( is_dir(image_target) < 0 ) || -+ ( is_dir(basedir) == 0 ) ) ) { -+ singularity_message(VERBOSE3, "Creating mount directory on underlay file system: %s\n", underlay_target); -+ if ( container_mkpath_priv(underlay_target, 0755) < 0 ) { -+ singularity_message(ERROR, "Could not create mount point directory in underlay %s: %s\n", underlay_target, strerror(errno)); -+ ABORT(255); -+ } -+ } -+ free(basedir); -+ } -+ -+ if ( image_target != NULL ) -+ free(image_target); -+ if ( underlay_target != NULL ) -+ free(underlay_target); -+ -+ // mount everything else from the image into the underlay area -+ mount_missing(image_dir, underlay_dir, "/"); -+ -+ free(underlay_dir); -+ -+ // finally, do the requested mounts -+ return(do_mounts(mountlist, 0)); -+} -+ -+int _singularity_runtime_domounts(struct mountlist *mountlist) { -+ if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) -+ return(do_mounts(mountlist, 1)); -+ -+ if ( singularity_registry_get("UNDERLAY_ENABLED") != NULL ) -+ return(underlay_mounts(mountlist)); -+ -+ return(do_mounts(mountlist, 0)); -+} -diff --git a/src/lib/runtime/mounts/domounts/domounts.h b/src/lib/runtime/mounts/domounts/domounts.h -new file mode 100644 -index 0000000..d7464b2 ---- /dev/null -+++ b/src/lib/runtime/mounts/domounts/domounts.h -@@ -0,0 +1,33 @@ -+/* -+ * Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. -+ * Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -+ * -+ * Copyright (c) 2015-2017, Gregory M. Kurtzer. All rights reserved. -+ * -+ * Copyright (c) 2016-2017, The Regents of the University of California, -+ * through Lawrence Berkeley National Laboratory (subject to receipt of any -+ * required approvals from the U.S. Dept. of Energy). All rights reserved. -+ * -+ * This software is licensed under a customized 3-clause BSD license. Please -+ * consult LICENSE file distributed with the sources of this project regarding -+ * your rights to use or distribute this software. -+ * -+ * NOTICE. This Software was developed under funding from the U.S. Department of -+ * Energy and the U.S. Government consequently retains certain rights. As such, -+ * the U.S. Government has been granted for itself and others acting on its -+ * behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software -+ * to reproduce, distribute copies to the public, prepare derivative works, and -+ * perform publicly and display publicly, and to permit other to do so. -+ * -+*/ -+ -+#ifndef __SINGULARITY_RUNTIME_MOUNT_DOMOUNTS_H_ -+#define __SINGULARITY_RUNTIME_MOUNT_DOMOUNTS_H_ -+ -+struct mountlist; -+ -+extern int _singularity_runtime_domounts_init(struct mountlist *mountlist); -+extern int _singularity_runtime_domounts(struct mountlist *mountlist); -+ -+#endif /* __SINGULARITY_RUNTIME_MOUNT_DOMOUNTS_H */ -+ -diff --git a/src/lib/runtime/mounts/home/home.c b/src/lib/runtime/mounts/home/home.c -index 665d256..c05c216 100644 ---- a/src/lib/runtime/mounts/home/home.c -+++ b/src/lib/runtime/mounts/home/home.c -@@ -39,15 +39,15 @@ - #include "util/config_parser.h" - #include "util/registry.h" - #include "util/mount.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - - --int _singularity_runtime_mount_home(void) { -+int _singularity_runtime_mount_home(struct mountlist *mountlist) { - char *home_source = singularity_priv_homedir(); - char *home_dest = singularity_priv_home(); - char *session_dir = singularity_registry_get("SESSIONDIR"); -- char *container_dir = CONTAINER_FINALDIR; - - singularity_message(DEBUG, "Checking that home directry is configured: %s\n", home_dest); - if ( home_dest == NULL ) { -@@ -83,12 +83,6 @@ int _singularity_runtime_mount_home(void) { - ABORT(255); - } - -- singularity_message(DEBUG, "Checking if home directory is already mounted: %s\n", home_dest); -- if ( check_mounted(home_dest) >= 0 ) { -- singularity_message(VERBOSE, "Not mounting home directory (already mounted in container): %s\n", home_dest); -- return(0); -- } -- - singularity_message(DEBUG, "Creating temporary directory to stage home: %s\n", joinpath(session_dir, home_dest)); - if ( container_mkpath_nopriv(joinpath(session_dir, home_dest), 0755) < 0 ) { - singularity_message(ERROR, "Failed creating home directory stage %s: %s\n", joinpath(session_dir, home_dest), strerror(errno)); -@@ -112,8 +106,9 @@ int _singularity_runtime_mount_home(void) { - singularity_message(VERBOSE, "Using sessiondir for home directory\n"); - } - -- singularity_message(DEBUG, "Checking if overlay is enabled\n"); -- if ( singularity_registry_get("OVERLAYFS_ENABLED") == NULL ) { -+ singularity_message(DEBUG, "Checking if overlay or underlay is enabled\n"); -+ if ( ( singularity_registry_get("OVERLAYFS_ENABLED") == NULL ) && -+ ( singularity_registry_get("UNDERLAY_ENABLED") == NULL ) ) { - char *homedir_base; - - singularity_message(DEBUG, "Staging home directory base\n"); -@@ -124,33 +119,12 @@ int _singularity_runtime_mount_home(void) { - ABORT(255); - } - -- singularity_message(DEBUG, "Checking home directory base exists in container: %s\n", homedir_base); -- if ( is_dir(joinpath(container_dir, homedir_base)) != 0 ) { -- singularity_message(ERROR, "Base home directory does not exist within the container: %s\n", homedir_base); -- ABORT(255); -- } -- -- singularity_message(VERBOSE, "Mounting staged home directory base to container's base dir: %s -> %s\n", joinpath(session_dir, homedir_base), joinpath(container_dir, homedir_base)); -- if ( singularity_mount(joinpath(session_dir, homedir_base), joinpath(container_dir, homedir_base), NULL, MS_BIND | MS_NOSUID | MS_NODEV | MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "Failed to mount staged home base: %s -> %s: %s\n", joinpath(session_dir, homedir_base), joinpath(container_dir, homedir_base), strerror(errno)); -- ABORT(255); -- } -+ singularity_message(VERBOSE, "Queuing bind mount of staged home directory base to container's base dir: %s/%s -> %s\n", session_dir, homedir_base, homedir_base); -+ mountlist_add(mountlist, joinpath(session_dir, homedir_base), strdup(homedir_base), NULL, MS_BIND | MS_NOSUID | MS_NODEV | MS_REC, 0); - -- free(homedir_base); - } else { -- singularity_message(DEBUG, "Staging home directory\n"); -- -- singularity_message(DEBUG, "Creating home directory within container: %s\n", joinpath(container_dir, home_dest)); -- if ( container_mkpath_priv(joinpath(container_dir, home_dest), 0755) < 0 ) { -- singularity_message(ERROR, "Failed creating home directory in container %s: %s\n", joinpath(container_dir, home_dest), strerror(errno)); -- ABORT(255); -- } -- -- singularity_message(VERBOSE, "Mounting staged home directory to container: %s -> %s\n", joinpath(session_dir, home_dest), joinpath(container_dir, home_dest)); -- if ( singularity_mount(joinpath(session_dir, home_dest), joinpath(container_dir, home_dest), NULL, MS_BIND | MS_NOSUID | MS_NODEV | MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "Failed to mount staged home base: %s -> %s: %s\n", joinpath(session_dir, home_dest), joinpath(container_dir, home_dest), strerror(errno)); -- ABORT(255); -- } -+ singularity_message(VERBOSE, "Queuing bind mount of staged home directory to container: %s/%s -> %s\n", session_dir, home_dest, home_dest); -+ mountlist_add(mountlist, joinpath(session_dir, home_dest), strdup(home_dest), NULL, MS_BIND | MS_NOSUID | MS_NODEV | MS_REC, 0); - } - - envar_set("HOME", home_dest, 1); -diff --git a/src/lib/runtime/mounts/home/home.h b/src/lib/runtime/mounts/home/home.h -index a150177..2553d75 100644 ---- a/src/lib/runtime/mounts/home/home.h -+++ b/src/lib/runtime/mounts/home/home.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_HOME_H_ - #define __SINGULARITY_RUNTIME_MOUNT_HOME_H_ - --extern int _singularity_runtime_mount_home(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_home(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_HOME_H */ - -diff --git a/src/lib/runtime/mounts/hostfs/hostfs.c b/src/lib/runtime/mounts/hostfs/hostfs.c -index 2040d53..a56c5cc 100644 ---- a/src/lib/runtime/mounts/hostfs/hostfs.c -+++ b/src/lib/runtime/mounts/hostfs/hostfs.c -@@ -37,20 +37,18 @@ - #include "util/file.h" - #include "util/util.h" - #include "util/message.h" --#include "util/privilege.h" - #include "util/config_parser.h" - #include "util/registry.h" --#include "util/mount.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - - #define MAX_LINE_LEN 4096 - - --int _singularity_runtime_mount_hostfs(void) { -+int _singularity_runtime_mount_hostfs(struct mountlist *mountlist) { - FILE *mounts; - char *line = NULL; -- char *container_dir = CONTAINER_FINALDIR; - - if ( singularity_config_get_bool(MOUNT_HOSTFS) <= 0 ) { - singularity_message(DEBUG, "Not mounting host file systems per configuration\n"); -@@ -88,7 +86,7 @@ int _singularity_runtime_mount_hostfs(void) { - singularity_message(VERBOSE3, "Skipping blank or comment line in /proc/mounts\n"); - continue; - } -- if ( ( source = strtok(strdup(line), " ") ) == NULL ) { -+ if ( ( source = strtok(line, " ") ) == NULL ) { - singularity_message(VERBOSE3, "Could not obtain mount source from /proc/mounts: %s\n", line); - continue; - } -@@ -129,8 +127,8 @@ int _singularity_runtime_mount_hostfs(void) { - singularity_message(DEBUG, "Skipping /var based file system: %s,%s,%s\n", source, mountpoint, filesystem); - continue; - } -- if ( strncmp(mountpoint, container_dir, strlength(container_dir, PATH_MAX)) == 0 ) { -- singularity_message(DEBUG, "Skipping final_dir (%s) based file system: %s,%s,%s\n", container_dir, source, mountpoint, filesystem); -+ if ( strncmp(mountpoint, CONTAINER_FINALDIR, strlength(CONTAINER_FINALDIR, PATH_MAX)) == 0 ) { -+ singularity_message(DEBUG, "Skipping final_dir (%s) based file system: %s,%s,%s\n", CONTAINER_FINALDIR, source, mountpoint, filesystem); - continue; - } - if ( strcmp(mountpoint, CONTAINER_MOUNTDIR) == 0 ) { -@@ -149,37 +147,9 @@ int _singularity_runtime_mount_hostfs(void) { - singularity_message(DEBUG, "Skipping ramfs file system: %s,%s,%s\n", source, mountpoint, filesystem); - continue; - } -- singularity_message(DEBUG, "Checking if host file system is already mounted: %s\n", mountpoint); -- if ( check_mounted(mountpoint) >= 0 ) { -- singularity_message(VERBOSE, "Not mounting host FS (already mounted in container): %s\n", mountpoint); -- continue; -- } -- -- if ( ( is_dir(mountpoint) == 0 ) && ( is_dir(joinpath(container_dir, mountpoint)) < 0 ) ) { -- if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { -- if ( container_mkpath_priv(joinpath(container_dir, mountpoint), 0755) < 0 ) { -- singularity_message(WARNING, "Could not create bind point directory in container %s: %s\n", mountpoint, strerror(errno)); -- continue; -- } -- } else { -- singularity_message(WARNING, "Non existent 'bind point' directory in container: '%s'\n", mountpoint); -- continue; -- } -- } -- -- -- singularity_message(VERBOSE, "Binding '%s'(%s) to '%s/%s'\n", mountpoint, filesystem, container_dir, mountpoint); -- if ( singularity_mount(mountpoint, joinpath(container_dir, mountpoint), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error binding the path %s: %s\n", mountpoint, strerror(errno)); -- ABORT(255); -- } -- if ( singularity_priv_userns_enabled() != 1 ) { -- if ( singularity_mount(NULL, joinpath(container_dir, mountpoint), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC|MS_REMOUNT, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error remounting the path %s: %s\n", mountpoint, strerror(errno)); -- ABORT(255); -- } -- } - -+ singularity_message(VERBOSE, "Queuing bind mount of '%s'(%s) to '%s'\n", mountpoint, filesystem, mountpoint); -+ mountlist_add(mountlist, NULL, strdup(mountpoint), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, 0); - } - - free(line); -diff --git a/src/lib/runtime/mounts/hostfs/hostfs.h b/src/lib/runtime/mounts/hostfs/hostfs.h -index 9d9f6ab..62617a1 100644 ---- a/src/lib/runtime/mounts/hostfs/hostfs.h -+++ b/src/lib/runtime/mounts/hostfs/hostfs.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_HOSTFS_H_ - #define __SINGULARITY_RUNTIME_MOUNT_HOSTFS_H_ - --extern int _singularity_runtime_mount_hostfs(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_hostfs(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_HOSTFS_H */ - -diff --git a/src/lib/runtime/mounts/kernelfs/kernelfs.c b/src/lib/runtime/mounts/kernelfs/kernelfs.c -index cc0de35..bfe9741 100644 ---- a/src/lib/runtime/mounts/kernelfs/kernelfs.c -+++ b/src/lib/runtime/mounts/kernelfs/kernelfs.c -@@ -37,34 +37,23 @@ - #include "util/privilege.h" - #include "util/config_parser.h" - #include "util/registry.h" --#include "util/mount.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - #include "../../ns/ns.h" - - --int _singularity_runtime_mount_kernelfs(void) { -- char *container_dir = CONTAINER_FINALDIR; -+int _singularity_runtime_mount_kernelfs(struct mountlist *mountlist) { - - // Mount /proc if we are configured - singularity_message(DEBUG, "Checking configuration file for 'mount proc'\n"); - if ( singularity_config_get_bool(MOUNT_PROC) > 0 ) { -- if ( is_dir(joinpath(container_dir, "/proc")) == 0 ) { -- if ( singularity_registry_get("PIDNS_ENABLED") == NULL ) { -- singularity_message(VERBOSE, "Bind-mounting host /proc\n"); -- if ( singularity_mount("/proc", joinpath(container_dir, "/proc"), NULL, MS_BIND | MS_NOSUID | MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "Could not bind-mount host /proc into container: %s\n", strerror(errno)); -- ABORT(255); -- } -- } else { -- singularity_message(VERBOSE, "Mounting new procfs\n"); -- if ( singularity_mount("proc", joinpath(container_dir, "/proc"), "proc", MS_NOSUID, NULL) < 0 ) { -- singularity_message(ERROR, "Could not mount new procfs into container: %s\n", strerror(errno)); -- ABORT(255); -- } -- } -+ if ( singularity_registry_get("PIDNS_ENABLED") == NULL ) { -+ singularity_message(VERBOSE, "Queuing bind mount of host /proc\n"); -+ mountlist_add(mountlist, NULL, strdup("/proc"), NULL, MS_BIND | MS_NOSUID | MS_REC, 0); - } else { -- singularity_message(WARNING, "Not mounting /proc, container has no bind directory\n"); -+ singularity_message(VERBOSE, "Queuing mount of new procfs\n"); -+ mountlist_add(mountlist, strdup("proc"), strdup("/proc"), "proc", MS_NOSUID, 0); - } - } else { - singularity_message(VERBOSE, "Skipping /proc mount\n"); -@@ -74,22 +63,12 @@ int _singularity_runtime_mount_kernelfs(void) { - // Mount /sys if we are configured - singularity_message(DEBUG, "Checking configuration file for 'mount sys'\n"); - if ( singularity_config_get_bool(MOUNT_SYS) > 0 ) { -- if ( is_dir(joinpath(container_dir, "/sys")) == 0 ) { -- if ( singularity_priv_userns_enabled() == 1 ) { -- singularity_message(VERBOSE, "Mounting /sys\n"); -- if ( singularity_mount("/sys", joinpath(container_dir, "/sys"), NULL, MS_BIND | MS_NOSUID | MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "Could not mount /sys into container: %s\n", strerror(errno)); -- ABORT(255); -- } -- } else { -- singularity_message(VERBOSE, "Mounting /sys\n"); -- if ( singularity_mount("sysfs", joinpath(container_dir, "/sys"), "sysfs", MS_NOSUID, NULL) < 0 ) { -- singularity_message(ERROR, "Could not mount /sys into container: %s\n", strerror(errno)); -- ABORT(255); -- } -- } -+ if ( singularity_priv_userns_enabled() == 1 ) { -+ singularity_message(VERBOSE, "Queuing bind mount of /sys\n"); -+ mountlist_add(mountlist, NULL, strdup("/sys"), NULL, MS_BIND | MS_NOSUID | MS_REC, 0); - } else { -- singularity_message(WARNING, "Not mounting /sys, container has no bind directory\n"); -+ singularity_message(VERBOSE, "Queuing mount of new sysfs\n"); -+ mountlist_add(mountlist, strdup("sysfs"), strdup("/sys"), "sysfs", MS_NOSUID, 0); - } - } else { - singularity_message(VERBOSE, "Skipping /sys mount\n"); -diff --git a/src/lib/runtime/mounts/kernelfs/kernelfs.h b/src/lib/runtime/mounts/kernelfs/kernelfs.h -index 63143c0..6b49c58 100644 ---- a/src/lib/runtime/mounts/kernelfs/kernelfs.h -+++ b/src/lib/runtime/mounts/kernelfs/kernelfs.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_KERNELFS_H_ - #define __SINGULARITY_RUNTIME_MOUNT_KERNELFS_H_ - --extern int _singularity_runtime_mount_kernelfs(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_kernelfs(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_KERNELFS_H */ - -diff --git a/src/lib/runtime/mounts/libs/Makefile.am b/src/lib/runtime/mounts/libs/Makefile.am -new file mode 100644 -index 0000000..f54f504 ---- /dev/null -+++ b/src/lib/runtime/mounts/libs/Makefile.am -@@ -0,0 +1,12 @@ -+MAINTAINERCLEANFILES = Makefile.in -+DISTCLEANFILES = Makefile -+CLEANFILES = core.* *~ *.la -+ -+AM_CFLAGS = -Wall -fpie -+AM_LDFLAGS = -pie -+AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DLIBEXECDIR=\"$(libexecdir)\" $(SINGULARITY_DEFINES) -+ -+noinst_LTLIBRARIES = libinternal.la -+libinternal_la_SOURCES = libs.c -+ -+EXTRA_DIST = libs.h -diff --git a/src/lib/runtime/mounts/libs/libs.c b/src/lib/runtime/mounts/libs/libs.c -new file mode 100644 -index 0000000..7c73771 ---- /dev/null -+++ b/src/lib/runtime/mounts/libs/libs.c -@@ -0,0 +1,157 @@ -+/* -+ * Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. -+ * Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -+ * -+ * Copyright (c) 2015-2017, Gregory M. Kurtzer. All rights reserved. -+ * -+ * Copyright (c) 2016-2017, The Regents of the University of California, -+ * through Lawrence Berkeley National Laboratory (subject to receipt of any -+ * required approvals from the U.S. Dept. of Energy). All rights reserved. -+ * -+ * This software is licensed under a customized 3-clause BSD license. Please -+ * consult LICENSE file distributed with the sources of this project regarding -+ * your rights to use or distribute this software. -+ * -+ * NOTICE. This Software was developed under funding from the U.S. Department of -+ * Energy and the U.S. Government consequently retains certain rights. As such, -+ * the U.S. Government has been granted for itself and others acting on its -+ * behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software -+ * to reproduce, distribute copies to the public, prepare derivative works, and -+ * perform publicly and display publicly, and to permit other to do so. -+ * -+*/ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "config.h" -+#include "util/file.h" -+#include "util/util.h" -+#include "util/message.h" -+#include "util/privilege.h" -+#include "util/config_parser.h" -+#include "util/registry.h" -+#include "util/mount.h" -+#include "util/mountlist.h" -+ -+#include "../../runtime.h" -+ -+ -+int _singularity_runtime_mount_libs(struct mountlist *mountlist) { -+ char *tmpdir = singularity_registry_get("SESSIONDIR"); -+ char *includelibs_string; -+ -+ if ( ( includelibs_string = singularity_registry_get("CONTAINLIBS") ) != NULL ) { -+ char *libdir = joinpath(tmpdir, "/libs"); -+ char *libdir_contained = joinpath(CONTAINER_MOUNTDIR, "/.singularity.d/libs"); -+ char *tok = NULL; -+ char *current = strtok_r(strdup(includelibs_string), ",", &tok); -+ -+ singularity_message(DEBUG, "Parsing SINGULARITY_CONTAINLIBS for user-specified libraries to include.\n"); -+ -+ free(includelibs_string); -+ -+ singularity_message(DEBUG, "Checking if libdir in container exists: %s\n", libdir_contained); -+ if ( is_dir(libdir_contained) != 0 ) { -+ singularity_message(WARNING, "Library bind directory not present in container, update container\n"); -+ char *ld_path = envar_path("LD_LIBRARY_PATH"); -+ if ( ld_path == NULL ) { -+ singularity_message(DEBUG, "Setting LD_LIBRARY_PATH to '/.singularity.d/libs'\n"); -+ envar_set("LD_LIBRARY_PATH", "/.singularity.d/libs", 1); -+ } else { -+ singularity_message(DEBUG, "Prepending '/.singularity.d/libs' to LD_LIBRARY_PATH\n"); -+ envar_set("LD_LIBRARY_PATH", strjoin("/.singularity.d/libs:", ld_path), 1); -+ } -+ } -+ free(libdir_contained); -+ -+ singularity_message(DEBUG, "Creating session libdir at: %s\n", libdir); -+ if ( container_mkpath_nopriv(libdir, 0755) != 0 ) { -+ singularity_message(ERROR, "Failed creating temp lib directory at: %s\n", libdir); -+ ABORT(255); -+ } -+ -+ while (current != NULL ) { -+ char *dest = NULL; -+ char *source = NULL; -+ -+ singularity_message(DEBUG, "Evaluating requested library path: %s\n", current); -+ -+ dest = joinpath(libdir, basename(current)); -+ -+ if ( is_file(dest) == 0 ) { -+ singularity_message(VERBOSE3, "Staged library exists, skipping: %s\n", current); -+ current = strtok_r(NULL, ",", &tok); -+ continue; -+ } -+ -+ if ( is_link(current) == 0 ) { -+ char *link_name; -+ ssize_t len; -+ -+ link_name = (char *) malloc(PATH_MAX); -+ -+ len = readlink(current, link_name, PATH_MAX-1); // Flawfinder: ignore -+ if ( ( len > 0 ) && ( len <= PATH_MAX) ) { -+ link_name[len] = '\0'; -+ singularity_message(VERBOSE3, "Found library link source: %s -> %s\n", current, link_name); -+ if ( link_name[0] == '/' ) { -+ source = strdup(link_name); -+ } else { -+ if ( link_name[0] == '/' ) { -+ source = strdup(link_name); -+ } else { -+ source = joinpath(dirname(strdup(current)), link_name); -+ } -+ } -+ } else { -+ singularity_message(WARNING, "Failed reading library link for %s: %s\n", current, strerror(errno)); -+ ABORT(255); -+ } -+ free(link_name); -+ -+ } else if (is_file(current) == 0 ) { -+ source = strdup(current); -+ singularity_message(VERBOSE3, "Found library source: %s\n", source); -+ } else { -+ singularity_message(WARNING, "Could not find library: %s\n", current); -+ current = strtok_r(NULL, ",", &tok); -+ continue; -+ } -+ -+ singularity_message(DEBUG, "Binding library source here: %s -> %s\n", source, dest); -+ -+ if ( fileput_nopriv(dest, "") != 0 ) { -+ singularity_message(ERROR, "Failed creating file at %s: %s\n", dest, strerror(errno)); -+ ABORT(255); -+ } -+ -+ singularity_message(VERBOSE, "Binding file '%s' to '%s'\n", source, dest); -+ if ( singularity_mount(source, dest, NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0 ) { -+ singularity_message(ERROR, "There was an error binding %s to %s: %s\n", source, dest, strerror(errno)); -+ ABORT(255); -+ } -+ -+ free(source); -+ free(dest); -+ current = strtok_r(NULL, ",", &tok); -+ } -+ -+ singularity_message(VERBOSE, "Queueing bind mount of libdir '%s' to '%s'\n", libdir, "/.singularity.d/libs"); -+ mountlist_add(mountlist, libdir, strdup("/.singularity.d/libs"), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, 0); -+ } -+ -+ return(0); -+} -diff --git a/src/lib/runtime/mounts/libs/libs.h b/src/lib/runtime/mounts/libs/libs.h -new file mode 100644 -index 0000000..4a6bdff ---- /dev/null -+++ b/src/lib/runtime/mounts/libs/libs.h -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. -+ * Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -+ * -+ * Copyright (c) 2015-2017, Gregory M. Kurtzer. All rights reserved. -+ * -+ * Copyright (c) 2016-2017, The Regents of the University of California, -+ * through Lawrence Berkeley National Laboratory (subject to receipt of any -+ * required approvals from the U.S. Dept. of Energy). All rights reserved. -+ * -+ * This software is licensed under a customized 3-clause BSD license. Please -+ * consult LICENSE file distributed with the sources of this project regarding -+ * your rights to use or distribute this software. -+ * -+ * NOTICE. This Software was developed under funding from the U.S. Department of -+ * Energy and the U.S. Government consequently retains certain rights. As such, -+ * the U.S. Government has been granted for itself and others acting on its -+ * behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software -+ * to reproduce, distribute copies to the public, prepare derivative works, and -+ * perform publicly and display publicly, and to permit other to do so. -+ * -+*/ -+ -+#ifndef __SINGULARITY_RUNTIME_MOUNT_LIBS_H_ -+#define __SINGULARITY_RUNTIME_MOUNT_LIBS_H_ -+ -+struct mountlist; -+ -+extern int _singularity_runtime_mount_libs(struct mountlist *); -+ -+#endif /* __SINGULARITY_RUNTIME_MOUNT_LIBS_H */ -+ -diff --git a/src/lib/runtime/mounts/mounts.c b/src/lib/runtime/mounts/mounts.c -index 4419281..6fa52d1 100644 ---- a/src/lib/runtime/mounts/mounts.c -+++ b/src/lib/runtime/mounts/mounts.c -@@ -32,6 +32,7 @@ - #include "util/file.h" - #include "util/util.h" - #include "util/message.h" -+#include "util/mountlist.h" - #include "util/privilege.h" - - #include "./binds/binds.h" -@@ -43,21 +44,31 @@ - #include "./cwd/cwd.h" - #include "./userbinds/userbinds.h" - #include "./scratch/scratch.h" -+#include "./libs/libs.h" -+#include "./domounts/domounts.h" - - - int _singularity_runtime_mounts(void) { - int retval = 0; -+ struct mountlist mountlist; -+ -+ singularity_runtime_domounts_init(&mountlist); - - singularity_message(VERBOSE, "Running all mount components\n"); -- retval += _singularity_runtime_mount_dev(); -- retval += _singularity_runtime_mount_kernelfs(); -- retval += _singularity_runtime_mount_hostfs(); -- retval += _singularity_runtime_mount_binds(); -- retval += _singularity_runtime_mount_home(); -- retval += _singularity_runtime_mount_userbinds(); -- retval += _singularity_runtime_mount_tmp(); -- retval += _singularity_runtime_mount_scratch(); -- retval += _singularity_runtime_mount_cwd(); -+ retval += _singularity_runtime_mount_dev(&mountlist); -+ retval += _singularity_runtime_mount_kernelfs(&mountlist); -+ retval += _singularity_runtime_mount_hostfs(&mountlist); -+ retval += _singularity_runtime_mount_binds(&mountlist); -+ retval += _singularity_runtime_mount_home(&mountlist); -+ retval += _singularity_runtime_mount_userbinds(&mountlist); -+ retval += _singularity_runtime_mount_tmp(&mountlist); -+ retval += _singularity_runtime_mount_scratch(&mountlist); -+ retval += _singularity_runtime_mount_cwd(&mountlist); -+ retval += _singularity_runtime_mount_libs(&mountlist); -+ -+ retval += _singularity_runtime_domounts(&mountlist); -+ -+ mountlist_cleanup(&mountlist); - - return(retval); - } -diff --git a/src/lib/runtime/mounts/scratch/scratch.c b/src/lib/runtime/mounts/scratch/scratch.c -index 66a5f60..4a8c829 100644 ---- a/src/lib/runtime/mounts/scratch/scratch.c -+++ b/src/lib/runtime/mounts/scratch/scratch.c -@@ -41,17 +41,15 @@ - #include "util/privilege.h" - #include "util/config_parser.h" - #include "util/registry.h" --#include "util/mount.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - - --int _singularity_runtime_mount_scratch(void) { -- char *container_dir = CONTAINER_FINALDIR; -+int _singularity_runtime_mount_scratch(struct mountlist *mountlist) { - char *scratchdir_path; - char *tmpdir_path; - char *sourcedir_path; -- int r; - - singularity_message(DEBUG, "Getting SINGULARITY_SCRATCHDIR from environment\n"); - if ( ( scratchdir_path = singularity_registry_get("SCRATCHDIR") ) == NULL ) { -@@ -78,54 +76,20 @@ int _singularity_runtime_mount_scratch(void) { - free(tmpdir_path); - - char *outside_token = NULL; -- char *current = strtok_r(strdup(scratchdir_path), ",", &outside_token); -- -- free(scratchdir_path); -+ char *current = strtok_r(scratchdir_path, ",", &outside_token); - - while ( current != NULL ) { -- -- char *full_sourcedir_path = joinpath(sourcedir_path, basename(strdup(current))); -- char *full_destdir_path = joinpath(container_dir, current); -- -- singularity_message(DEBUG, "Checking if bind point is already mounted: %s\n", current); -- if ( check_mounted(current) >= 0 ) { -- singularity_message(ERROR, "Not mounting requested scratch directory (already mounted in container): %s\n", current); -- ABORT(255); -- } -+ char *current_copy = strdup(current); -+ char *full_sourcedir_path = joinpath(sourcedir_path, basename(current_copy)); -+ free(current_copy); - - if ( container_mkpath_nopriv(full_sourcedir_path, 0750) < 0 ) { - singularity_message(ERROR, "Could not create scratch working directory %s: %s\n", full_sourcedir_path, strerror(errno)); - ABORT(255); - } - -- if ( is_dir(full_destdir_path) != 0 ) { -- if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { -- singularity_message(DEBUG, "Creating scratch directory inside container\n"); -- r = container_mkpath_priv(full_destdir_path, 0755); -- if ( r < 0 ) { -- singularity_message(VERBOSE, "Skipping scratch directory mount, could not create dir inside container %s: %s\n", current, strerror(errno)); -- current = strtok_r(NULL, ",", &outside_token); -- continue; -- } -- } else { -- singularity_message(WARNING, "Skipping scratch directory mount, target directory does not exist: %s\n", current); -- current = strtok_r(NULL, ",", &outside_token); -- continue; -- } -- } -- -- singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", full_sourcedir_path, container_dir, current); -- r = singularity_mount(full_sourcedir_path, joinpath(container_dir, current), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL); -- if ( singularity_priv_userns_enabled() != 1 ) { -- r += singularity_mount(NULL, joinpath(container_dir, current), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC|MS_REMOUNT, NULL); -- } -- if ( r < 0 ) { -- singularity_message(WARNING, "Could not bind scratch directory into container %s: %s\n", full_sourcedir_path, strerror(errno)); -- ABORT(255); -- } -- -- free(full_sourcedir_path); -- free(full_destdir_path); -+ singularity_message(VERBOSE, "Queuing bind mount of '%s' to '%s'\n", full_sourcedir_path, current); -+ mountlist_add(mountlist, full_sourcedir_path, strdup(current), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, 0); - - current = strtok_r(NULL, ",", &outside_token); - -@@ -134,6 +98,8 @@ int _singularity_runtime_mount_scratch(void) { - current = strtok_r(NULL, ",", &outside_token); - } - } -+ -+ free(scratchdir_path); - return(0); - } - -diff --git a/src/lib/runtime/mounts/scratch/scratch.h b/src/lib/runtime/mounts/scratch/scratch.h -index 00104c4..3ab46e4 100644 ---- a/src/lib/runtime/mounts/scratch/scratch.h -+++ b/src/lib/runtime/mounts/scratch/scratch.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_SCRATCH_H_ - #define __SINGULARITY_RUNTIME_MOUNT_SCRATCH_H_ - --extern int _singularity_runtime_mount_scratch(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_scratch(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_SCRATCH_H */ - -diff --git a/src/lib/runtime/mounts/tmp/tmp.c b/src/lib/runtime/mounts/tmp/tmp.c -index 7384b4a..1969306 100644 ---- a/src/lib/runtime/mounts/tmp/tmp.c -+++ b/src/lib/runtime/mounts/tmp/tmp.c -@@ -36,16 +36,14 @@ - #include "util/file.h" - #include "util/util.h" - #include "util/message.h" --#include "util/privilege.h" - #include "util/config_parser.h" - #include "util/registry.h" --#include "util/mount.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - - --int _singularity_runtime_mount_tmp(void) { -- char *container_dir = CONTAINER_FINALDIR; -+int _singularity_runtime_mount_tmp(struct mountlist *mountlist) { - char *tmp_source; - char *vartmp_source; - -@@ -74,60 +72,26 @@ int _singularity_runtime_mount_tmp(void) { - free(tmpdirpath); - } - -- if ( check_mounted("/tmp") < 0 ) { -- if ( s_mkpath(tmp_source, 0755) < 0 ) { -- singularity_message(ERROR, "Could not create source /tmp directory %s: %s\n", tmp_source, strerror(errno)); -- ABORT(255); -- } -- if ( is_dir(tmp_source) == 0 ) { -- if ( is_dir(joinpath(container_dir, "/tmp")) == 0 ) { -- singularity_message(VERBOSE, "Mounting directory: /tmp\n"); -- if ( singularity_mount(tmp_source, joinpath(container_dir, "/tmp"), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "Failed to mount %s -> /tmp: %s\n", tmp_source, strerror(errno)); -- ABORT(255); -- } -- if ( singularity_priv_userns_enabled() != 1 ) { -- if ( singularity_mount(NULL, joinpath(container_dir, "/tmp"), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC|MS_REMOUNT, NULL) < 0 ) { -- singularity_message(ERROR, "Failed to remount /tmp: %s\n", strerror(errno)); -- ABORT(255); -- } -- } -- } else { -- singularity_message(VERBOSE, "Could not mount container's /tmp directory: does not exist\n"); -- } -- } else { -- singularity_message(VERBOSE, "Could not mount host's /tmp directory (%s): does not exist\n", tmp_source); -- } -+ if ( s_mkpath(tmp_source, 0755) < 0 ) { -+ singularity_message(ERROR, "Could not create source /tmp directory %s: %s\n", tmp_source, strerror(errno)); -+ ABORT(255); -+ } -+ if ( is_dir(tmp_source) == 0 ) { -+ singularity_message(VERBOSE, "Queuing bind mount of /tmp\n"); -+ mountlist_add(mountlist, strdup(tmp_source), strdup("/tmp"), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, 0); - } else { -- singularity_message(VERBOSE, "Not mounting '/tmp', already mounted\n"); -+ singularity_message(VERBOSE, "Could not mount host's /tmp directory (%s): does not exist\n", tmp_source); - } - -- if ( check_mounted("/var/tmp") < 0 ) { -- if ( s_mkpath(vartmp_source, 0755) < 0 ) { -- singularity_message(ERROR, "Could not create source /var/tmp directory %s: %s\n", vartmp_source, strerror(errno)); -- ABORT(255); -- } -- if ( is_dir(vartmp_source) == 0 ) { -- if ( is_dir(joinpath(container_dir, "/var/tmp")) == 0 ) { -- singularity_message(VERBOSE, "Mounting directory: /var/tmp\n"); -- if ( singularity_mount(vartmp_source, joinpath(container_dir, "/var/tmp"), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "Failed to mount %s -> /var/tmp: %s\n", vartmp_source, strerror(errno)); -- ABORT(255); -- } -- if ( singularity_priv_userns_enabled() != 1 ) { -- if ( singularity_mount(NULL, joinpath(container_dir, "/var/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_NODEV|MS_REMOUNT, NULL) < 0 ) { -- singularity_message(ERROR, "Failed to remount /var/tmp: %s\n", strerror(errno)); -- ABORT(255); -- } -- } -- } else { -- singularity_message(VERBOSE, "Could not mount container's /var/tmp directory: does not exist\n"); -- } -- } else { -- singularity_message(VERBOSE, "Could not mount host's /var/tmp directory (%s): does not exist\n", vartmp_source); -- } -+ if ( s_mkpath(vartmp_source, 0755) < 0 ) { -+ singularity_message(ERROR, "Could not create source /var/tmp directory %s: %s\n", vartmp_source, strerror(errno)); -+ ABORT(255); -+ } -+ if ( is_dir(vartmp_source) == 0 ) { -+ singularity_message(VERBOSE, "Queuing bind mount of /var/tmp\n"); -+ mountlist_add(mountlist, strdup(vartmp_source), strdup("/var/tmp"), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, 0); - } else { -- singularity_message(VERBOSE, "Not mounting '/var/tmp', already mounted\n"); -+ singularity_message(VERBOSE, "Could not mount host's /var/tmp directory (%s): does not exist\n", vartmp_source); - } - - free(tmp_source); -diff --git a/src/lib/runtime/mounts/tmp/tmp.h b/src/lib/runtime/mounts/tmp/tmp.h -index d793b79..b6b2590 100644 ---- a/src/lib/runtime/mounts/tmp/tmp.h -+++ b/src/lib/runtime/mounts/tmp/tmp.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_TMP_H_ - #define __SINGULARITY_RUNTIME_MOUNT_TMP_H_ - --extern int _singularity_runtime_mount_tmp(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_tmp(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_TMP_H */ - -diff --git a/src/lib/runtime/mounts/userbinds/userbinds.c b/src/lib/runtime/mounts/userbinds/userbinds.c -index 7e6f0b8..f4dfd6b 100644 ---- a/src/lib/runtime/mounts/userbinds/userbinds.c -+++ b/src/lib/runtime/mounts/userbinds/userbinds.c -@@ -35,16 +35,14 @@ - #include "util/file.h" - #include "util/util.h" - #include "util/message.h" --#include "util/privilege.h" - #include "util/config_parser.h" - #include "util/registry.h" --#include "util/mount.h" -+#include "util/mountlist.h" - - #include "../../runtime.h" - - --int _singularity_runtime_mount_userbinds(void) { -- char *container_dir = CONTAINER_FINALDIR; -+int _singularity_runtime_mount_userbinds(struct mountlist *mountlist) { - char *bind_path_string; - - singularity_message(DEBUG, "Checking for environment variable 'SINGULARITY_BINDPATH'\n"); -@@ -59,12 +57,10 @@ int _singularity_runtime_mount_userbinds(void) { - singularity_message(DEBUG, "Parsing SINGULARITY_BINDPATH for user-specified bind mounts.\n"); - char *outside_token = NULL; - char *inside_token = NULL; -- char *current = strtok_r(strdup(bind_path_string), ",", &outside_token); -- -- free(bind_path_string); -+ char *current = strtok_r(bind_path_string, ",", &outside_token); - - while ( current != NULL ) { -- int read_only = 0; -+ unsigned long read_only = 0; - char *source = strtok_r(current, ":", &inside_token); - char *dest = strtok_r(NULL, ":", &inside_token); - char *opts = strtok_r(NULL, ":", &inside_token); -@@ -81,7 +77,7 @@ int _singularity_runtime_mount_userbinds(void) { - if ( strcmp(opts, "rw") == 0 ) { - // This is the default - } else if ( strcmp(opts, "ro") == 0 ) { -- read_only = 1; -+ read_only = MS_RDONLY; - } else { - singularity_message(WARNING, "Not mounting requested bind point, invalid mount option %s: %s\n", opts, dest); - continue; -@@ -89,79 +85,12 @@ int _singularity_runtime_mount_userbinds(void) { - } - - -- singularity_message(DEBUG, "Checking if bind point is already mounted: %s\n", dest); -- if ( check_mounted(dest) >= 0 ) { -- singularity_message(WARNING, "Not mounting requested bind point (already mounted in container): %s\n", dest); -- continue; -- } -- -- if ( ( is_file(source) == 0 ) && ( is_file(joinpath(container_dir, dest)) < 0 ) ) { -- if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { -- char *dir = dirname(strdup(dest)); -- if ( is_dir(joinpath(container_dir, dir)) < 0 ) { -- singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest); -- if ( container_mkpath_nopriv(joinpath(container_dir, dir), 0755) < 0 ) { -- singularity_message(VERBOSE3, "Retrying with privileges to create bind directory on overlay file system: %s\n", dest); -- if ( container_mkpath_priv(joinpath(container_dir, dir), 0755) < 0 ) { -- singularity_message(ERROR, "Could not create basedir for file bind %s: %s\n", dest, strerror(errno)); -- continue; -- } -- } -- } -- singularity_message(VERBOSE3, "Creating bind file on overlay file system: %s\n", dest); -- if ( fileput_priv(joinpath(container_dir, dest), "") != 0 ) { -- continue; -- } -- singularity_message(DEBUG, "Created bind file: %s\n", dest); -- } else { -- singularity_message(WARNING, "Skipping user bind, non existent bind point (file) in container: '%s'\n", dest); -- continue; -- } -- } else if ( ( is_dir(source) == 0 ) && ( is_dir(joinpath(container_dir, dest)) < 0 ) ) { -- if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) { -- singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest); -- if ( container_mkpath_nopriv(joinpath(container_dir, dest), 0755) < 0 ) { -- singularity_message(VERBOSE3, "Retrying with privileges to create bind directory on overlay file system: %s\n", dest); -- if ( container_mkpath_priv(joinpath(container_dir, dest), 0755) < 0 ) { -- singularity_message(WARNING, "Skipping user bind, could not create bind point %s: %s\n", dest, strerror(errno)); -- continue; -- } -- } -- } else { -- singularity_message(WARNING, "Skipping user bind, non existent bind point (directory) in container: '%s'\n", dest); -- continue; -- } -- } -- -- singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", source, container_dir, dest); -- if ( singularity_mount(source, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error binding the path %s: %s\n", source, strerror(errno)); -- ABORT(255); -- } -- if ( read_only ) { -- if ( singularity_priv_userns_enabled() == 1 ) { -- singularity_message(WARNING, "Can not make bind mount read only within the user namespace: %s\n", dest); -- } else { -- singularity_message(VERBOSE, "Remounting %s read-only\n", dest); -- if ( singularity_mount(NULL, joinpath(container_dir, dest), NULL, MS_RDONLY|MS_BIND|MS_NOSUID|MS_NODEV|MS_REC|MS_REMOUNT, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error write-protecting the path %s: %s\n", source, strerror(errno)); -- ABORT(255); -- } -- if ( access(joinpath(container_dir, dest), W_OK) == 0 || (errno != EROFS && errno != EACCES) ) { // Flawfinder: ignore (precautionary confirmation, not necessary) -- singularity_message(ERROR, "Failed to write-protect the path %s: %s\n", source, strerror(errno)); -- ABORT(255); -- } -- } -- } else { -- if ( singularity_priv_userns_enabled() <= 0 ) { -- if ( singularity_mount(NULL, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC|MS_REMOUNT, NULL) < 0 ) { -- singularity_message(ERROR, "There was an error remounting the path %s: %s\n", source, strerror(errno)); -- ABORT(255); -- } -- } -- } -+ singularity_message(VERBOSE, "Queuing bind mount of '%s' to '%s'\n", source, dest); -+ mountlist_add(mountlist, strdup(source), strdup(dest), NULL, MS_BIND|MS_NOSUID|MS_NODEV|MS_REC|read_only, 0); - } - -+ free(bind_path_string); -+ - singularity_message(DEBUG, "Unsetting environment variable 'SINGULARITY_BINDPATH'\n"); - unsetenv("SINGULARITY_BINDPATH"); - } else { -diff --git a/src/lib/runtime/mounts/userbinds/userbinds.h b/src/lib/runtime/mounts/userbinds/userbinds.h -index cd14d5d..34cd52a 100644 ---- a/src/lib/runtime/mounts/userbinds/userbinds.h -+++ b/src/lib/runtime/mounts/userbinds/userbinds.h -@@ -24,7 +24,9 @@ - #ifndef __SINGULARITY_RUNTIME_MOUNT_USERBINDS_H_ - #define __SINGULARITY_RUNTIME_MOUNT_USERBINDS_H_ - --extern int _singularity_runtime_mount_userbinds(void); -+struct mountlist; -+ -+extern int _singularity_runtime_mount_userbinds(struct mountlist *mountlist); - - #endif /* __SINGULARITY_RUNTIME_MOUNT_USERBINDS_H */ - -diff --git a/src/util/Makefile.am b/src/util/Makefile.am -index ad58525..7a78e4f 100644 ---- a/src/util/Makefile.am -+++ b/src/util/Makefile.am -@@ -20,6 +20,8 @@ EXTRA_DIST = cleanupd.c \ - message.h \ - mount.c \ - mount.h \ -+ mountlist.c \ -+ mountlist.h \ - privilege.c \ - privilege.h \ - registry.c \ -diff --git a/src/util/config_defaults.h.in b/src/util/config_defaults.h.in -index 6bfeb78..b1676f8 100644 ---- a/src/util/config_defaults.h.in -+++ b/src/util/config_defaults.h.in -@@ -41,6 +41,9 @@ - #define ENABLE_OVERLAY "enable overlay" - #define ENABLE_OVERLAY_DEFAULT "try" - -+#define ENABLE_UNDERLAY "enable underlay" -+#define ENABLE_UNDERLAY_DEFAULT "no" -+ - #define CONFIG_PASSWD "config passwd" - #define CONFIG_PASSWD_DEFAULT 1 - -diff --git a/src/util/mount.c b/src/util/mount.c -index f609f82..46d2874 100644 ---- a/src/util/mount.c -+++ b/src/util/mount.c -@@ -127,7 +127,7 @@ int singularity_mount(const char *source, const char *target, - return ret; - } - --int check_mounted(char *mountpoint) { -+int check_mounted(const char *mountpoint) { - int retval = -1; - FILE *mounts; - char *line = (char *)malloc(MAX_LINE_LEN); -diff --git a/src/util/mount.h b/src/util/mount.h -index 8c80ea9..afca177 100644 ---- a/src/util/mount.h -+++ b/src/util/mount.h -@@ -20,6 +20,6 @@ - int singularity_mount(const char *source, const char *target, - const char *filesystemtype, unsigned long mountflags, - const void *data); --int check_mounted(char *mountpoint); -+int check_mounted(const char *mountpoint); - - #endif /* __MOUNT_H_ */ -diff --git a/src/util/mountlist.c b/src/util/mountlist.c -new file mode 100644 -index 0000000..5aded49 ---- /dev/null -+++ b/src/util/mountlist.c -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. -+ * Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -+ * -+ * See the COPYRIGHT.md file at the top-level directory of this distribution and at -+ * https://github.com/singularityware/singularity/blob/master/COPYRIGHT.md. -+ * -+ * This file is part of the Singularity Linux container project. It is subject to the license -+ * terms in the LICENSE.md file found in the top-level directory of this distribution and -+ * at https://github.com/singularityware/singularity/blob/master/LICENSE.md. No part -+ * of Singularity, including this file, may be copied, modified, propagated, or distributed -+ * except according to the terms contained in the LICENSE.md file. -+ * -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "config.h" -+#include "util/util.h" -+#include "util/mount.h" -+#include "util/mountlist.h" -+#include "util/message.h" -+ -+void mountlist_add(struct mountlist *mountlist, -+ const char *source, const char *target, -+ const char *filesystemtype, unsigned long mountflags, -+ unsigned long mountlistflags) { -+ -+ struct mountlist_point *point; -+ point = (struct mountlist_point *) malloc(sizeof(struct mountlist_point)); -+ if (mountlist->first == NULL) -+ mountlist->first = point; -+ if (mountlist->last != NULL) -+ mountlist->last->next = point; -+ mountlist->last = point; -+ point->next = NULL; -+ point->source = source; -+ point->target = target; -+ point->filesystemtype = filesystemtype; -+ point->mountflags = mountflags; -+ point->mountlistflags = mountlistflags; -+ point->resolved_target = NULL; -+} -+ -+void mountlist_cleanup(struct mountlist *mountlist) { -+ struct mountlist_point *point = mountlist->first; -+ -+ while (point != NULL) { -+ if ( point->source != NULL) -+ free((char *)point->source); -+ if ( point->target != NULL) -+ free((char *)point->target); -+ if ( point->resolved_target != NULL) -+ free(point->resolved_target); -+ struct mountlist_point *next = point->next; -+ free(point); -+ point = next; -+ } -+ -+ mountlist->first = NULL; -+ mountlist->last = NULL; -+} -+ -+int singularity_mount_point(struct mountlist_point *point) { -+ -+ int retval; -+ char *target = joinpath(CONTAINER_FINALDIR, point->target); -+ const char *source = point->source; -+ if (source == NULL) -+ source = point->target; -+ -+ retval = singularity_mount(source, target, -+ point->filesystemtype, point->mountflags, NULL); -+ -+ free(target); -+ return retval; -+} -diff --git a/src/util/mountlist.h b/src/util/mountlist.h -new file mode 100644 -index 0000000..66d44a5 ---- /dev/null -+++ b/src/util/mountlist.h -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. -+ * Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -+ * -+ * See the COPYRIGHT.md file at the top-level directory of this distribution and at -+ * https://github.com/singularityware/singularity/blob/master/COPYRIGHT.md. -+ * -+ * This file is part of the Singularity Linux container project. It is subject to the license -+ * terms in the LICENSE.md file found in the top-level directory of this distribution and -+ * at https://github.com/singularityware/singularity/blob/master/LICENSE.md. No part -+ * of Singularity, including this file, may be copied, modified, propagated, or distributed -+ * except according to the terms contained in the LICENSE.md file. -+ * -+*/ -+ -+ -+#ifndef __MOUNTLIST_H_ -+#define __MOUNTLIST_H_ -+ -+// mountlist flags -+#define ML_ONLY_IF_POINT_PRESENT 0x01 -+ -+struct mountlist_point { -+ struct mountlist_point *next; -+ const char *source; -+ const char *target; -+ const char *filesystemtype; -+ unsigned long mountflags; -+ unsigned long mountlistflags; -+ char *resolved_target; -+}; -+ -+struct mountlist { -+ struct mountlist_point *first; -+ struct mountlist_point *last; -+}; -+ -+// if source is NULL, it will be copied from target -+// CONTAINER_FINALDIR will be prepended to target -+// target will be freed by mountlist_cleanup, as will source if it isn't NULL -+void mountlist_add(struct mountlist *mountlist, -+ const char *source, const char *target, -+ const char *filesystemtype, unsigned long mountflags, -+ unsigned long mountlistflags); -+void mountlist_cleanup(struct mountlist *mountlist); -+ -+int singularity_mount_point(struct mountlist_point *point); -+ -+#endif /* __MOUNTLIST_H_ */ diff --git a/1818.patch b/1818.patch deleted file mode 100644 index 7436cb5..0000000 --- a/1818.patch +++ /dev/null @@ -1,321 +0,0 @@ -From 08ad53f2bdb8ef3a1cc02ff8a423d5a6da434dff Mon Sep 17 00:00:00 2001 -From: Dave Dykstra <2129743+DrDaveD@users.noreply.github.com> -Date: Sun, 15 Jul 2018 14:43:57 -0500 -Subject: [PATCH] prefer python3 if present - ---- - configure.ac | 29 +++++++++++++++-------- - etc/configure_transform.py | 9 ++++++- - libexec/helpers/checks/1-bash-hiddens.py | 10 +++++++- - libexec/helpers/checks/1-cache-content.py | 10 +++++++- - libexec/helpers/checks/1-docker.py | 10 +++++++- - libexec/helpers/checks/3-cve.py | 10 +++++++- - libexec/python/helpers/json/add.py | 10 +++++++- - libexec/python/helpers/json/delete.py | 10 +++++++- - libexec/python/helpers/json/dump.py | 10 +++++++- - libexec/python/helpers/json/get.py | 10 +++++++- - libexec/python/helpers/json/inspect.py | 10 +++++++- - libexec/python/import.py | 10 +++++++- - libexec/python/pull.py | 10 +++++++- - libexec/python/shub/api.py | 10 +++++++- - libexec/python/size.py | 10 +++++++- - 15 files changed, 144 insertions(+), 24 deletions(-) - -diff --git a/configure.ac b/configure.ac -index b4c76cda3..836fb44bf 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -299,23 +299,32 @@ AM_COND_IF([FOUND_MKSQUASHFS],,[AC_MSG_WARN([mksquashfs not found - needed at ru - # PYTHON - # --------------------------------------------------------------------- - --AC_CHECK_PROG(PYTHON_CHECK,python,yes) --if test x"$PYTHON_CHECK" != x"yes" ; then -- AC_MSG_ERROR([Please install python before installing.]) -+_PYTHON_EXEC="" -+AC_CHECK_PROG(PYTHON_CHECK,python3,yes) -+if test x"$PYTHON_CHECK" = x"yes" ; then -+ _PYTHON_EXEC=python3 - else -+ AC_CHECK_PROG(PYTHON_CHECK,python,yes) -+ if test x"$PYTHON_CHECK" = x"yes" ; then -+ _PYTHON_EXEC=python -+ else -+ AC_MSG_ERROR([Please install python before installing.]) -+ fi -+fi - -+if test x"$_PYTHON_EXEC" != ""; then - PYTHON_MODULES="base64 datetime glob hashlib io itertools json math multiprocessing pickle pwd re shutil signal subprocess stat sys tarfile tempfile time" - for PYTHON_MODULE in $PYTHON_MODULES; do - AC_MSG_CHECKING([for the $PYTHON_MODULE python module]) -- python_module_result=`python -c "import $PYTHON_MODULE" 2>&1` -- if test -z "$python_module_result"; then -- AC_MSG_RESULT([yes]) -- else -- AC_MSG_RESULT([no]) -- AC_MSG_ERROR([cannot import Python module $PYTHON_MODULE. -+ python_module_result=`$_PYTHON_EXEC -c "import $PYTHON_MODULE" 2>&1` -+ if test -z "$python_module_result"; then -+ AC_MSG_RESULT([yes]) -+ else -+ AC_MSG_RESULT([no]) -+ AC_MSG_ERROR([cannot import Python module $PYTHON_MODULE. - Please check your Python installation. The error was: - $python_module_result]) -- fi -+ fi - done - - fi -diff --git a/etc/configure_transform.py b/etc/configure_transform.py -index 2d28114f1..42b165156 100755 ---- a/etc/configure_transform.py -+++ b/etc/configure_transform.py -@@ -1,4 +1,11 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' - - ''' - Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -diff --git a/libexec/helpers/checks/1-bash-hiddens.py b/libexec/helpers/checks/1-bash-hiddens.py -index fabca4bd9..b9e385104 100755 ---- a/libexec/helpers/checks/1-bash-hiddens.py -+++ b/libexec/helpers/checks/1-bash-hiddens.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - # - # Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. - # Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -diff --git a/libexec/helpers/checks/1-cache-content.py b/libexec/helpers/checks/1-cache-content.py -index d31c2829a..f08555511 100755 ---- a/libexec/helpers/checks/1-cache-content.py -+++ b/libexec/helpers/checks/1-cache-content.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - # - # Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. - # Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -diff --git a/libexec/helpers/checks/1-docker.py b/libexec/helpers/checks/1-docker.py -index 224506311..e4914a6a5 100755 ---- a/libexec/helpers/checks/1-docker.py -+++ b/libexec/helpers/checks/1-docker.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - # - # Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. - # Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -diff --git a/libexec/helpers/checks/3-cve.py b/libexec/helpers/checks/3-cve.py -index 319e90673..94829b102 100755 ---- a/libexec/helpers/checks/3-cve.py -+++ b/libexec/helpers/checks/3-cve.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - # - # Copyright (c) 2017-2018, SyLabs, Inc. All rights reserved. - # Copyright (c) 2017, SingularityWare, LLC. All rights reserved. -diff --git a/libexec/python/helpers/json/add.py b/libexec/python/helpers/json/add.py -index 9b533464d..0dab042ae 100644 ---- a/libexec/python/helpers/json/add.py -+++ b/libexec/python/helpers/json/add.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - -diff --git a/libexec/python/helpers/json/delete.py b/libexec/python/helpers/json/delete.py -index 0975e4e60..c2c95f95c 100644 ---- a/libexec/python/helpers/json/delete.py -+++ b/libexec/python/helpers/json/delete.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - -diff --git a/libexec/python/helpers/json/dump.py b/libexec/python/helpers/json/dump.py -index a1411565b..93c21ebf5 100644 ---- a/libexec/python/helpers/json/dump.py -+++ b/libexec/python/helpers/json/dump.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - -diff --git a/libexec/python/helpers/json/get.py b/libexec/python/helpers/json/get.py -index 355be9040..4e8a066ee 100644 ---- a/libexec/python/helpers/json/get.py -+++ b/libexec/python/helpers/json/get.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - -diff --git a/libexec/python/helpers/json/inspect.py b/libexec/python/helpers/json/inspect.py -index 85cbe47d5..40a836502 100644 ---- a/libexec/python/helpers/json/inspect.py -+++ b/libexec/python/helpers/json/inspect.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - -diff --git a/libexec/python/import.py b/libexec/python/import.py -index e67dda121..37dd22289 100644 ---- a/libexec/python/import.py -+++ b/libexec/python/import.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - -diff --git a/libexec/python/pull.py b/libexec/python/pull.py -index c3af8d4d0..21d967ca1 100644 ---- a/libexec/python/pull.py -+++ b/libexec/python/pull.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - -diff --git a/libexec/python/shub/api.py b/libexec/python/shub/api.py -index ce7574a1f..67d375e73 100644 ---- a/libexec/python/shub/api.py -+++ b/libexec/python/shub/api.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - -diff --git a/libexec/python/size.py b/libexec/python/size.py -index 34331fd27..3e8ee385a 100644 ---- a/libexec/python/size.py -+++ b/libexec/python/size.py -@@ -1,4 +1,12 @@ --#!/usr/bin/env python -+#!/bin/bash -+# the following line is the start of a comment to python and a no-op to bash -+''':' -+if type python3 >/dev/null 2>&1; then -+ exec python3 "$0" "$@" -+fi -+exec python "$0" "$@" -+''' -+ - - ''' - diff --git a/singularity.spec b/singularity.spec index 1b8319a..a0c11ab 100644 --- a/singularity.spec +++ b/singularity.spec @@ -21,176 +21,147 @@ # # -%global _hardened_build 1 +%define singgopath src/github.com/sylabs/singularity -%{!?_rel:%{expand:%%global _rel 1.1}} - -%if ! 0%{?osg} -%define require_python3 1 -%else -%define require_python3 0 -%endif +# Disable debugsource packages; otherwise it ends up with an empty %files +# file in debugsourcefiles.list on Fedora +%undefine _debugsource_packages Summary: Application and environment virtualization Name: singularity -Version: 2.6.1 -Release: %{_rel}%{?dist} +Version: 3.1.1 +Release: 1%{?dist} # https://spdx.org/licenses/BSD-3-Clause-LBNL.html -License: BSD and LBNL BSD -Group: System Environment/Base -URL: http://singularity.lbl.gov/ -Source: https://github.com/sylabs/singularity/releases/download/%{version}/%{name}-%{version}.tar.gz -Source2: %{name}.abignore -%if %{require_python3} -# from https://github.com/sylabs/singularity/pull/1818.patch -Patch1: 1818.patch -%endif -# Not from https://github.com/sylabs/singularity/pull/1817.diff -# because that includes renames; instead, check out the PR and do git diff -Patch2: 1817.diff +License: BSD-3-Clause-LBNL +URL: https://www.sylabs.io/singularity/ +Source: %{name}-%{version}.tar.gz ExclusiveOS: linux -BuildRoot: %{?_tmppath}%{!?_tmppath:/var/tmp}/%{name}-%{version}-%{release}-root -%if %{require_python3} -BuildRequires: /usr/bin/python3 +%if "%{_target_vendor}" == "suse" +%if "%{sles_version}" != "11" +BuildRequires: go +%endif %else -BuildRequires: python +BuildRequires: golang +%endif +BuildRequires: git +BuildRequires: gcc +BuildRequires: make +BuildRequires: libuuid-devel +BuildRequires: openssl-devel +%if ! 0%{?el6} +%if "%{sles_version}" != "11" +BuildRequires: libseccomp-devel +%endif %endif -BuildRequires: automake libtool -BuildRequires: libarchive-devel %if "%{_target_vendor}" == "suse" Requires: squashfs %else Requires: squashfs-tools %endif -Requires: %{name}-runtime = %{version}-%{release} +# there's no golang for ppc64, just ppc64le +ExcludeArch: ppc64 + +Provides: %{name}-runtime +Obsoletes: %{name}-runtime %description Singularity provides functionality to make portable containers that can be used across host environments. -%package devel -Summary: Development libraries for Singularity -Group: System Environment/Development - -%description devel -Development files for Singularity - -%package runtime -Summary: Support for running Singularity containers -Group: System Environment/Base - -%if %{require_python3} -Requires: /usr/bin/python3 -%endif - -%description runtime -This package contains support for running containers created -by the %{name} package. +%debug_package %prep -%setup -q -%if %{require_python3} -%patch1 -p1 -%endif -%patch2 -p1 - +# Create our build root +rm -rf %{name}-%{version} +mkdir %{name}-%{version} %build -# always invoke even if configure exists, because the corresponding -# automake version may be wrong -./autogen.sh - -%configure -%{__make} %{?mflags} - +cd %{name}-%{version} + +mkdir -p gopath/%{singgopath} +tar -C "gopath/src/github.com/sylabs/" -xf "%SOURCE0" + +export GOPATH=$PWD/gopath +export PATH=$GOPATH/bin:$PATH +cd $GOPATH/%{singgopath} + +# Not all of these parameters currently have an effect, but they might be +# used someday. They are the same parameters as in the configure macro. +./mconfig -V %{version}-%{release} \ + --prefix=%{_prefix} \ + --exec-prefix=%{_exec_prefix} \ + --bindir=%{_bindir} \ + --sbindir=%{_sbindir} \ + --sysconfdir=%{_sysconfdir} \ + --datadir=%{_datadir} \ + --includedir=%{_includedir} \ + --libdir=%{_libdir} \ + --libexecdir=%{_libexecdir} \ + --localstatedir=%{_localstatedir} \ + --sharedstatedir=%{_sharedstatedir} \ + --mandir=%{_mandir} \ + --infodir=%{_infodir} + +cd builddir +make old_config= %install -%{__make} install DESTDIR=$RPM_BUILD_ROOT %{?mflags_install} -rm -f $RPM_BUILD_ROOT/%{_libdir}/singularity/lib*.la -install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/%{_libdir}/singularity/ +cd %{name}-%{version} -%post runtime -p /sbin/ldconfig -%postun runtime -p /sbin/ldconfig +export GOPATH=$PWD/gopath +export PATH=$GOPATH/bin:$PATH +cd $GOPATH/%{singgopath}/builddir -%clean -rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1 +make DESTDIR=$RPM_BUILD_ROOT install man +chmod 644 $RPM_BUILD_ROOT%{_sysconfdir}/singularity/actions/* %files -%license LICENSE.md LICENSE-LBNL.md -%doc examples CONTRIBUTORS.md CONTRIBUTING.md COPYRIGHT.md INSTALL.md LICENSE-LBNL.md LICENSE.md README.md -%attr(0755, root, root) %dir %{_sysconfdir}/singularity -%attr(0644, root, root) %config(noreplace) %{_sysconfdir}/singularity/* - -%{_libexecdir}/singularity/cli/apps.* -%{_libexecdir}/singularity/cli/bootstrap.* -%{_libexecdir}/singularity/cli/build.* -%{_libexecdir}/singularity/cli/check.* -%{_libexecdir}/singularity/cli/create.* -%{_libexecdir}/singularity/cli/image.* -%{_libexecdir}/singularity/cli/inspect.* -%{_libexecdir}/singularity/cli/mount.* -%{_libexecdir}/singularity/cli/pull.* -%{_libexecdir}/singularity/cli/selftest.* -%{_libexecdir}/singularity/helpers - -# Binaries -%{_libexecdir}/singularity/bin/builddef -%{_libexecdir}/singularity/bin/get-section -%{_libexecdir}/singularity/bin/mount -%{_libexecdir}/singularity/bin/image-type -%{_libexecdir}/singularity/bin/prepheader - -#SUID programs -%attr(4755, root, root) %{_libexecdir}/singularity/bin/mount-suid - -%files runtime +%attr(4755, root, root) %{_libexecdir}/singularity/bin/starter-suid +%{_bindir}/* %dir %{_libexecdir}/singularity -%dir %{_localstatedir}/singularity -%dir %{_localstatedir}/singularity/mnt -%dir %{_localstatedir}/singularity/mnt/session -%dir %{_localstatedir}/singularity/mnt/container -%dir %{_localstatedir}/singularity/mnt/overlay -%dir %{_localstatedir}/singularity/mnt/final -%{_bindir}/singularity -%{_bindir}/run-singularity -%{_libdir}/singularity/lib*.so.* -%{_libdir}/singularity/*.abignore -%{_libexecdir}/singularity/cli/action_argparser.* -%{_libexecdir}/singularity/cli/exec.* -%{_libexecdir}/singularity/cli/help.* -%{_libexecdir}/singularity/cli/instance.* -%{_libexecdir}/singularity/cli/run.* -%{_libexecdir}/singularity/cli/shell.* -%{_libexecdir}/singularity/cli/test.* -%{_libexecdir}/singularity/bin/action -%{_libexecdir}/singularity/bin/get-configvals -%{_libexecdir}/singularity/bin/cleanupd -%{_libexecdir}/singularity/bin/start -%{_libexecdir}/singularity/bin/docker-extract -%{_libexecdir}/singularity/bootstrap-scripts -%{_libexecdir}/singularity/functions -%{_libexecdir}/singularity/handlers -%{_libexecdir}/singularity/image-handler.sh -%{_libexecdir}/singularity/python +%{_libexecdir}/singularity/bin/starter +%{_libexecdir}/singularity/cni/* %dir %{_sysconfdir}/singularity %config(noreplace) %{_sysconfdir}/singularity/* -%{_mandir}/man1/singularity.1* +%attr(755, root, root) %{_sysconfdir}/singularity/actions/exec +%attr(755, root, root) %{_sysconfdir}/singularity/actions/run +%attr(755, root, root) %{_sysconfdir}/singularity/actions/shell +%attr(755, root, root) %{_sysconfdir}/singularity/actions/start +%attr(755, root, root) %{_sysconfdir}/singularity/actions/test %dir %{_sysconfdir}/bash_completion.d -%{_sysconfdir}/bash_completion.d/singularity +%{_sysconfdir}/bash_completion.d/* +%dir %{_localstatedir}/singularity +%dir %{_localstatedir}/singularity/mnt +%dir %{_localstatedir}/singularity/mnt/session +# XXX: Not great since we can't control this location... +%{_mandir}/man1/* -#SUID programs -%attr(4755, root, root) %{_libexecdir}/singularity/bin/action-suid -%attr(4755, root, root) %{_libexecdir}/singularity/bin/start-suid -%files devel -%defattr(-, root, root) -%{_libdir}/singularity/lib*.so -%{_libdir}/singularity/lib*.a -%{_includedir}/singularity/*.h +%changelog +* Tue Apr 02 2019 Dave Dykstra - 3.1.1-1 +- Update to upstream 3.1.1-1 +* Mon Feb 25 2019 Dave Dykstra - 3.1.0-1 +- Update to upstream 3.1.0-1 + +* Tue Jan 22 2019 Dave Dykstra - 3.0.3-1 +- Update to upstream 3.0.3-1 release. + +* Fri Jan 18 2019 Dave Dykstra - 3.0.3-rc2 +- Update to upstream 3.0.3-rc2 + +* Wed Jan 16 2019 Dave Dykstra - 3.0.3-rc1 +- Update to upstream 3.0.3-rc1 + +* Wed Jan 09 2019 Dave Dykstra - 3.0.2-1.2 +- Add patch for PR 2531 + +* Mon Jan 07 2019 Dave Dykstra - 3.0.2-1.1 +- Update to upstream 3.0.2 +- Added patches for PRs 2472, 2478, 2481 -%changelog * Tue Dec 11 2018 Dave Dykstra - 2.6.1-1.1 - Update to released upstream 2.6.1 @@ -250,6 +221,15 @@ rm -rf $RPM_BUILD_ROOT * Mon Apr 16 2018 Dave Dykstra - 2.4.6-1 - Update to upstream version 2.4.6 +* Fri Feb 09 2018 Fedora Release Engineering - 2.2.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Aug 03 2017 Fedora Release Engineering - 2.2.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 2.2.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + * Sun May 21 2017 Dave Love - 2.2.1-3 - Drop patch 13, broken in the merged version - Fix remaining arch restriction @@ -335,6 +315,3 @@ rm -rf $RPM_BUILD_ROOT - New version - BR automake, libtool and run autogen -* Wed Apr 06 2016 Dave Love - 1.0-0.1.20150405 -- Initial version adapted for Fedora as minimally as possible from - bundled spec (can't run on el5) diff --git a/sources b/sources index 709aa7f..7b86f0f 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (singularity-2.6.1.tar.gz) = 063327c67dae2629d1decebc060c474a72e6741f6dc9b6373734e429ccf11d53ee55c1578c28e74e8f8bcda87f3e0b735a3a0e982c9ea894f03a31eaaadf617c +SHA512 (singularity-3.1.1.tar.gz) = fc425039802859135cf82c25e20e25d3970ef21338072747d771013cfc907dd13123a5893f7a6d7797143c9ffdc0a7b2111cbe00ad2da9a880bf86114f7264f0