Singularity: Multi-stage build fail to copy links using an absolute path

Created on 7 Oct 2019  路  5Comments  路  Source: hpcng/singularity

Version of Singularity:

$ singularity version
3.4.1-1

Expected behavior

Using the image.def definition file below:

bootstrap: library
from: alpine
stage: one

%post
    mkdir /copy /original
    touch /original/a_file
    ln -s /original/a_file /copy/a_file

bootstrap: library
from: alpine
stage: two

%files from one
    /original
    /copy

and giving the following command:

$ sudo singularity build image.sif image.def

I would expect to create an image with a copy of the /original and /copy folders from stage one.

Actual behavior

The build command errors out when trying to copy the folder containing the symlink:

$ sudo singularity -d build image.sif image.def


Long error message below

DEBUG   [U=0,P=15532]      createConfDir()               /root/.singularity already exists. Not creating.
DEBUG   [U=0,P=15532]      getCacheBasedir()             environment variable SINGULARITY_CACHEDIR not set, using default image cache
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/library
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/oci-tmp
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/oci
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/net
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/shub
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/oras
DEBUG   [U=0,P=15532]      Init()                        Image format detection
DEBUG   [U=0,P=15532]      Init()                        Check for sandbox image format
DEBUG   [U=0,P=15532]      Init()                        sandbox format initializer returned: not a directory image
DEBUG   [U=0,P=15532]      Init()                        Check for sif image format
DEBUG   [U=0,P=15532]      Init()                        sif format initializer returned: can't read first 2048 bytes: %!s(<nil>)
DEBUG   [U=0,P=15532]      Init()                        Check for squashfs image format
DEBUG   [U=0,P=15532]      Init()                        squashfs format initializer returned: can't read first 2048 bytes: %!s(<nil>)
DEBUG   [U=0,P=15532]      Init()                        Check for ext3 image format
DEBUG   [U=0,P=15532]      Init()                        ext3 format initializer returned: can't read first 2048 bytes: %!s(<nil>)
DEBUG   [U=0,P=15532]      bundleCommon()                Created temporary directory for bundle /tmp/sbuild-860698289
DEBUG   [U=0,P=15532]      bundleCommon()                Created temporary directory for bundle /tmp/sbuild-980878940
DEBUG   [U=0,P=15532]      ensureGzipComp()              Ensuring gzip compression for mksquashfs
DEBUG   [U=0,P=15532]      ensureGzipComp()              Gzip compression by default ensured
INFO    [U=0,P=15532]      Full()                        Starting build...
DEBUG   [U=0,P=15532]      Get()                         Getting container from Library
DEBUG   [U=0,P=15532]      Get()                         LibraryURL: https://library.sylabs.io
DEBUG   [U=0,P=15532]      Get()                         LibraryRef: alpine
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/library/sha256.63259fd0a2acb88bb652702c08c1460b071df51149ff85dc88db5034532a14a0
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/library/sha256.63259fd0a2acb88bb652702c08c1460b071df51149ff85dc88db5034532a14a0
DEBUG   [U=0,P=15532]      Init()                        Image format detection
DEBUG   [U=0,P=15532]      Init()                        Check for sandbox image format
DEBUG   [U=0,P=15532]      Init()                        sandbox format initializer returned: not a directory image
DEBUG   [U=0,P=15532]      Init()                        Check for sif image format
DEBUG   [U=0,P=15532]      Init()                        sif image format detected
DEBUG   [U=0,P=15532]      GetLocalPacker()              Packing from SIF
DEBUG   [U=0,P=15532]      Init()                        Image format detection
DEBUG   [U=0,P=15532]      Init()                        Check for sandbox image format
DEBUG   [U=0,P=15532]      Init()                        sandbox format initializer returned: not a directory image
DEBUG   [U=0,P=15532]      Init()                        Check for sif image format
DEBUG   [U=0,P=15532]      Init()                        sif image format detected
DEBUG   [U=0,P=15532]      runBuildEngine()              Starting build engine
VERBOSE [U=0,P=15571]      print()                       Set messagelevel to: 5
VERBOSE [U=0,P=15571]      init()                        Starter initialization
DEBUG   [U=0,P=15571]      get_pipe_exec_fd()            PIPE_EXEC_FD value: 10
VERBOSE [U=0,P=15571]      is_suid()                     Check if we are running as setuid
DEBUG   [U=0,P=15571]      init()                        Read engine configuration
DEBUG   [U=0,P=15571]      init()                        Wait completion of stage1
DEBUG   [U=0,P=15572]      set_parent_death_signal()     Set parent death signal to 9
VERBOSE [U=0,P=15572]      init()                        Spawn stage 1
DEBUG   [U=0,P=15572]      startup()                     imgbuild runtime engine selected
VERBOSE [U=0,P=15572]      startup()                     Execute stage 1
DEBUG   [U=0,P=15572]      StageOne()                    Entering stage 1
VERBOSE [U=0,P=15571]      wait_child()                  stage 1 exited with status 0
DEBUG   [U=0,P=15571]      cleanup_fd()                  Close file descriptor 4
DEBUG   [U=0,P=15571]      init()                        Set child signal mask
DEBUG   [U=0,P=15571]      init()                        Create socketpair for master communication channel
DEBUG   [U=0,P=15571]      init()                        Create RPC socketpair for communication between stage 2 and RPC server
VERBOSE [U=0,P=15571]      priv_escalate()               Get root privileges
VERBOSE [U=0,P=15571]      priv_escalate()               Change filesystem uid to 0
VERBOSE [U=0,P=15571]      init()                        Spawn master process
DEBUG   [U=0,P=15579]      set_parent_death_signal()     Set parent death signal to 9
VERBOSE [U=0,P=15579]      create_namespace()            Create mount namespace
VERBOSE [U=0,P=15571]      enter_namespace()             Entering in mount namespace
DEBUG   [U=0,P=15571]      enter_namespace()             Opening namespace file ns/mnt
VERBOSE [U=0,P=15579]      create_namespace()            Create mount namespace
DEBUG   [U=0,P=15580]      set_parent_death_signal()     Set parent death signal to 9
VERBOSE [U=0,P=15580]      init()                        Spawn RPC server
DEBUG   [U=0,P=15580]      startup()                     imgbuild runtime engine selected
VERBOSE [U=0,P=15580]      startup()                     Serve RPC requests
DEBUG   [U=0,P=15571]      startup()                     imgbuild runtime engine selected
VERBOSE [U=0,P=15571]      startup()                     Execute master process
DEBUG   [U=0,P=15571]      CreateContainer()             Mounting image directory /tmp/sbuild-860698289/fs
DEBUG   [U=0,P=15571]      CreateContainer()             Mounting /tmp at /usr/local/var/singularity/mnt/session/tmp
DEBUG   [U=0,P=15571]      CreateContainer()             Mounting /var/tmp at /usr/local/var/singularity/mnt/session/var/tmp
DEBUG   [U=0,P=15571]      CreateContainer()             Copying files from host
DEBUG   [U=0,P=15571]      CreateContainer()             Mounting /proc at /usr/local/var/singularity/mnt/session/proc
DEBUG   [U=0,P=15571]      CreateContainer()             Mounting /sys at /usr/local/var/singularity/mnt/session/sys
DEBUG   [U=0,P=15571]      CreateContainer()             Mounting /dev at /usr/local/var/singularity/mnt/session/dev
DEBUG   [U=0,P=15571]      CreateContainer()             Mounting /etc/resolv.conf at /usr/local/var/singularity/mnt/session/etc/resolv.conf
DEBUG   [U=0,P=15571]      CreateContainer()             Mounting /etc/hosts at /usr/local/var/singularity/mnt/session/etc/hosts
DEBUG   [U=0,P=15571]      CreateContainer()             Chdir into /usr/local/var/singularity/mnt/session
DEBUG   [U=0,P=15571]      CreateContainer()             Set RPC mount propagation flag to PRIVATE
DEBUG   [U=0,P=15571]      CreateContainer()             Chroot into /usr/local/var/singularity/mnt/session
DEBUG   [U=0,P=15580]      Chroot()                      Change current directory to /usr/local/var/singularity/mnt/session
DEBUG   [U=0,P=15580]      Chroot()                      Hold reference to host / directory
DEBUG   [U=0,P=15580]      Chroot()                      Called pivot_root on /usr/local/var/singularity/mnt/session
DEBUG   [U=0,P=15580]      Chroot()                      Change current directory to host / directory
DEBUG   [U=0,P=15580]      Chroot()                      Apply slave mount propagation for host / directory
DEBUG   [U=0,P=15580]      Chroot()                      Called unmount(/, syscall.MNT_DETACH)
DEBUG   [U=0,P=15580]      Chroot()                      Changing directory to / to avoid getpwd issues
DEBUG   [U=0,P=15571]      CreateContainer()             Chdir into / to avoid errors
VERBOSE [U=0,P=15579]      wait_child()                  rpc server exited with status 0
DEBUG   [U=0,P=15579]      apply_container_privileges()  Set user ID to 0
DEBUG   [U=0,P=15579]      set_parent_death_signal()     Set parent death signal to 9
DEBUG   [U=0,P=15579]      startup()                     imgbuild runtime engine selected
VERBOSE [U=0,P=15579]      startup()                     Execute stage 2
DEBUG   [U=0,P=15579]      StageTwo()                    Entering stage 2
VERBOSE [U=0,P=15579]      SetContainerEnv()             Not forwarding SINGULARITY_ROOTFS from user to container environment
VERBOSE [U=0,P=15579]      SetContainerEnv()             Not forwarding SINGULARITY_ENVIRONMENT from user to container environment
VERBOSE [U=0,P=15579]      SetContainerEnv()             HOME = /root
INFO    [U=0,P=15579]      runScriptSection()            Running post scriptlet
+ mkdir /copy /original
+ touch /original/a_file
+ ln -s /original/a_file /copy/a_file
DEBUG   [U=0,P=15571]      Master()                      Child exited with exit status 0
DEBUG   [U=0,P=15532]      Full()                        Inserting Metadata
DEBUG   [U=0,P=15532]      Get()                         Getting container from Library
DEBUG   [U=0,P=15532]      Get()                         LibraryURL: https://library.sylabs.io
DEBUG   [U=0,P=15532]      Get()                         LibraryRef: alpine
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/library/sha256.63259fd0a2acb88bb652702c08c1460b071df51149ff85dc88db5034532a14a0
DEBUG   [U=0,P=15532]      updateCacheSubdir()           Caching directory set to /root/.singularity/cache/library/sha256.63259fd0a2acb88bb652702c08c1460b071df51149ff85dc88db5034532a14a0
DEBUG   [U=0,P=15532]      Init()                        Image format detection
DEBUG   [U=0,P=15532]      Init()                        Check for sandbox image format
DEBUG   [U=0,P=15532]      Init()                        sandbox format initializer returned: not a directory image
DEBUG   [U=0,P=15532]      Init()                        Check for sif image format
DEBUG   [U=0,P=15532]      Init()                        sif image format detected
DEBUG   [U=0,P=15532]      GetLocalPacker()              Packing from SIF
DEBUG   [U=0,P=15532]      Init()                        Image format detection
DEBUG   [U=0,P=15532]      Init()                        Check for sandbox image format
DEBUG   [U=0,P=15532]      Init()                        sandbox format initializer returned: not a directory image
DEBUG   [U=0,P=15532]      Init()                        Check for sif image format
DEBUG   [U=0,P=15532]      Init()                        sif image format detected
DEBUG   [U=0,P=15532]      copyFiles()                   Copying files from stage: one
INFO    [U=0,P=15532]      copyFiles()                   Copying /tmp/sbuild-860698289/fs/original to /tmp/sbuild-980878940/fs/original
INFO    [U=0,P=15532]      copyFiles()                   Copying /tmp/sbuild-860698289/fs/copy to /tmp/sbuild-980878940/fs/copy
DEBUG   [U=0,P=15532]      cleanUp()                     Build bundle(s) cleaned: [/tmp/sbuild-860698289 /tmp/sbuild-980878940]
FATAL   [U=0,P=15532]      run()                         While performing build: unable to copy files a stage to container fs: while copying [/tmp/sbuild-860698289/fs/copy] to /tmp/sbuild-980878940/fs/copy: exit status 1: /bin/cp: cannot stat '/tmp/sbuild-860698289/fs/copy/a_file': No such file or directory

Steps to reproduce this behavior

sudo singularity -d build image.sif image.def

with the definition file posted above

What OS/distro are you running

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.3 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

How did you install Singularity

Singularity installed manually on a system where I have root access from the 3.4.1 souce tarballs.

Bug

Most helpful comment

Okay - can we say let's do that for 3.6.0 and see how it goes?

All 5 comments

The function that takes care of copying files among stages is files.Copy. There we have this line:

https://github.com/sylabs/singularity/blob/f0d18ce50b7685092e06d4a88c33d6932b8b03c8/internal/pkg/build/files/copy.go#L56-L57

that sets the -L flag to always follow symbolic links. Removing that flag would solve this particular issue but will also introduce a change in the current behavior. Wondering if there's any preference on the way forward. Should we go for this one character change or give users the possibility to choose among following / non-following links?

Perhaps it is reasonable for a %files block copying in external files alone to follow the symlink by default (unchanged), but the %files from during a multi stage build would not follow the link. I'm not sure. @ikaneshiro may have informed opinions :-)

Another reasonable behavior might be to follow symlinks if a single file is copied in, don't follow if it is a directory (whatever is the source of the file or directory, external or previous stage).

@alalazo @dctrud I think Dave's suggestion is the best way forward wrt to this issue

Okay - can we say let's do that for 3.6.0 and see how it goes?

Was this page helpful?
0 / 5 - 0 ratings