Hello community,

here is the log from the commit of package singularity for openSUSE:Factory 
checked in at 2020-10-20 16:17:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/singularity (Old)
 and      /work/SRC/openSUSE:Factory/.singularity.new.3486 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "singularity"

Tue Oct 20 16:17:55 2020 rev:21 rq:842715 version:3.6.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/singularity/singularity.changes  2020-09-21 
17:31:09.768357685 +0200
+++ /work/SRC/openSUSE:Factory/.singularity.new.3486/singularity.changes        
2020-10-20 16:24:23.478407021 +0200
@@ -1,0 +2,11 @@
+Tue Oct 20 07:56:37 UTC 2020 - Ana Guerrero Lopez <aguerr...@suse.com>
+
+- New version 3.6.4 addresses a security issue:
+  - CVE-2020-15229, bsc#1177901
+  Due to insecure handling of path traversal and the lack of path 
+  sanitization within unsquashfs, it is possible to overwrite/create 
+  files on the host filesystem during the extraction of a crafted 
+  squashfs filesystem. Affects unprivileged execution of SIF/SquashFS 
+  images, and image builds from SIF/SquashFS images.
+
+-------------------------------------------------------------------

Old:
----
  singularity-3.6.3.tar.gz

New:
----
  singularity-3.6.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ singularity.spec ++++++
--- /var/tmp/diff_new_pack.r8Hxhn/_old  2020-10-20 16:24:25.238407855 +0200
+++ /var/tmp/diff_new_pack.r8Hxhn/_new  2020-10-20 16:24:25.238407855 +0200
@@ -23,7 +23,7 @@
 License:        BSD-3-Clause-LBNL
 Group:          Productivity/Clustering/Computing
 Name:           singularity
-Version:        3.6.3
+Version:        3.6.4
 Release:        0
 # https://spdx.org/licenses/BSD-3-Clause-LBNL.html
 URL:            https://github.com/hpcng/singularity

++++++ singularity-3.6.3.tar.gz -> singularity-3.6.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/CHANGELOG.md new/singularity/CHANGELOG.md
--- old/singularity/CHANGELOG.md        2020-09-15 16:05:03.000000000 +0200
+++ new/singularity/CHANGELOG.md        2020-10-13 16:36:52.000000000 +0200
@@ -9,6 +9,27 @@
 
 _The old changelog can be found in the `release-2.6` branch_
 
+# v3.6.4 - [2020-10-13]
+
+## Security related fixes
+
+Singularity 3.6.4 addresses the following security issue.
+
+  - 
[CVE-2020-15229](https://github.com/hpcng/singularity/security/advisories/GHSA-7gcp-w6ww-2xv9):
+    Due to insecure handling of path traversal and the lack of path
+    sanitization within unsquashfs (a distribution provided utility
+    used by Singularity), it is possible to overwrite/create files on
+    the host filesystem during the extraction of a crafted squashfs
+    filesystem. Affects unprivileged execution of SIF / SquashFS
+    images, and image builds from SIF / SquashFS images.
+
+## Bug Fixes
+
+  - Update scs-library-client to support `library://` backends using an
+    3rd party S3 object store that does not strictly conform to v4
+    signature spec.
+
+
 # v3.6.3 - [2020-09-15]
 
 ## Security related fixes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/INSTALL.md new/singularity/INSTALL.md
--- old/singularity/INSTALL.md  2020-09-15 16:05:03.000000000 +0200
+++ new/singularity/INSTALL.md  2020-10-13 16:36:52.000000000 +0200
@@ -89,7 +89,7 @@
 To build a stable version of Singularity, check out a [release 
tag](https://github.com/sylabs/singularity/tags) before compiling:
 
 ```
-$ git checkout v3.6.3
+$ git checkout v3.6.4
 ```
 
 ## Compiling Singularity
@@ -132,7 +132,7 @@
 and use it to install the RPM like this: 
 
 ```
-$ export VERSION=3.6.3  # this is the singularity version, change as you need
+$ export VERSION=3.6.4  # this is the singularity version, change as you need
 
 $ wget 
https://github.com/sylabs/singularity/releases/download/v${VERSION}/singularity-${VERSION}.tar.gz
 && \
     rpmbuild -tb singularity-${VERSION}.tar.gz && \
@@ -148,7 +148,7 @@
 $ cd $GOPATH/src/github.com/sylabs/singularity && \
   ./mconfig && \
   make -C builddir rpm && \
-  sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/singularity-3.6.2*.x86_64.rpm # or 
whatever version you built
+  sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/singularity-3.6.4*.x86_64.rpm # or 
whatever version you built
 ```
 
 To build an rpm with an alternative install prefix set RPMPREFIX on the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/VERSION new/singularity/VERSION
--- old/singularity/VERSION     2020-09-15 16:11:54.000000000 +0200
+++ new/singularity/VERSION     2020-10-13 16:39:02.000000000 +0200
@@ -1 +1 @@
-3.6.3
+3.6.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/go.mod new/singularity/go.mod
--- old/singularity/go.mod      2020-09-14 22:14:11.000000000 +0200
+++ new/singularity/go.mod      2020-10-13 15:51:07.000000000 +0200
@@ -44,7 +44,7 @@
        github.com/sylabs/json-resp v0.7.0
        github.com/sylabs/scs-build-client v0.1.4
        github.com/sylabs/scs-key-client v0.5.1
-       github.com/sylabs/scs-library-client v0.5.5
+       github.com/sylabs/scs-library-client v0.5.7
        github.com/sylabs/sif v1.2.1
        github.com/vbauerster/mpb/v4 v4.12.2
        github.com/vishvananda/netlink v1.0.1-0.20190618143317-99a56c251ae6 // 
indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/go.sum new/singularity/go.sum
--- old/singularity/go.sum      2020-09-14 22:14:11.000000000 +0200
+++ new/singularity/go.sum      2020-10-13 15:51:07.000000000 +0200
@@ -533,8 +533,8 @@
 github.com/sylabs/scs-build-client v0.1.4/go.mod 
h1:HxxopmlbGhWbHjaLBlTlcnV10NuMJnbf90Lj9yyW+YA=
 github.com/sylabs/scs-key-client v0.5.1 
h1:Gig1O0Rs926UJtXyKJLAYn5Kn2Wmi3g5VupOWNizvnE=
 github.com/sylabs/scs-key-client v0.5.1/go.mod 
h1:iKD05EsmJMGaxKhcjjwh/thEShfaWmky1qo24zHE0pw=
-github.com/sylabs/scs-library-client v0.5.5 
h1:sjCtA1VbkZfGjdbbZ0SHbrCVOlqDmFLvjTqz2/m2u7Y=
-github.com/sylabs/scs-library-client v0.5.5/go.mod 
h1:aGApgDIqM7Seuk0BHztl+vow4cY6NlDFS5jViCDu90U=
+github.com/sylabs/scs-library-client v0.5.7 
h1:qJACZ/rJByKle7HyeG/iGZxcc39vAJezVMDLr5YV73E=
+github.com/sylabs/scs-library-client v0.5.7/go.mod 
h1:DqZKmwqx8B3PbYS0YrETlCVUviOTz+ZQewoLqWjU2AI=
 github.com/sylabs/sif v1.2.1 h1:BvNER55n5ppPzVO8TFxADfM8xMaZKdHur7BR5Yf3leE=
 github.com/sylabs/sif v1.2.1/go.mod 
h1:gLZA1tQWzKe8lr4Pt+iUP+rJUPcDXZJjs/142yRwmVE=
 github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod 
h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/pkg/image/unpacker/squashfs.go 
new/singularity/pkg/image/unpacker/squashfs.go
--- old/singularity/pkg/image/unpacker/squashfs.go      2020-08-24 
18:37:07.000000000 +0200
+++ new/singularity/pkg/image/unpacker/squashfs.go      2020-10-13 
16:36:52.000000000 +0200
@@ -1,3 +1,4 @@
+// Copyright (c) 2020, Control Command Inc. All rights reserved.
 // Copyright (c) 2019, Sylabs Inc. All rights reserved.
 // This software is licensed under a 3-clause BSD license. Please consult the
 // LICENSE.md file distributed with the sources of this project regarding your
@@ -17,6 +18,33 @@
        "github.com/sylabs/singularity/pkg/sylog"
 )
 
+const (
+       stdinFile = "/proc/self/fd/0"
+)
+
+var cmdFunc func(unsquashfs string, dest string, filename string, rootless 
bool) (*exec.Cmd, error)
+
+// unsquashfsCmd is the command instance for executing unsquashfs command
+// in a non sandboxed environment when this package is used for unit tests.
+func unsquashfsCmd(unsquashfs string, dest string, filename string, rootless 
bool) (*exec.Cmd, error) {
+       args := make([]string, 0)
+       if rootless {
+               args = append(args, "-user-xattrs")
+       }
+       // remove the destination directory if any, if the directory is
+       // not empty (typically during image build), the unsafe option -f is
+       // set, this is unfortunately required by image build
+       if err := os.Remove(dest); err != nil && !os.IsNotExist(err) {
+               if !os.IsExist(err) {
+                       return nil, fmt.Errorf("failed to remove %s: %s", dest, 
err)
+               }
+               // unsafe mode
+               args = append(args, "-f")
+       }
+       args = append(args, "-d", dest, filename)
+       return exec.Command(unsquashfs, args...), nil
+}
+
 // Squashfs represents a squashfs unpacker.
 type Squashfs struct {
        UnsquashfsPath string
@@ -41,7 +69,7 @@
 
        // pipe over stdin by default
        stdin := true
-       filename := "/proc/self/fd/0"
+       filename := stdinFile
 
        if _, ok := reader.(*os.File); !ok {
                // use the destination parent directory to store the
@@ -71,9 +99,12 @@
        //  have to fall back to not using that option on failure.
        if os.Geteuid() != 0 {
                sylog.Debugf("Rootless extraction. Trying -user-xattrs for 
unsquashfs")
-               args := []string{"-user-xattrs", "-f", "-d", dest, filename}
-               args = append(args, files...)
-               cmd := exec.Command(s.UnsquashfsPath, args...)
+
+               cmd, err := cmdFunc(s.UnsquashfsPath, dest, filename, true)
+               if err != nil {
+                       return fmt.Errorf("command error: %s", err)
+               }
+               cmd.Args = append(cmd.Args, files...)
                if stdin {
                        cmd.Stdin = reader
                }
@@ -85,7 +116,7 @@
 
                // Invalid options give output...
                // SYNTAX: unsquashfs [options] filesystem [directories or 
files to extract]
-               if bytes.HasPrefix(o, []byte("SYNTAX")) {
+               if bytes.Contains(o, []byte("SYNTAX")) {
                        sylog.Warningf("unsquashfs does not support 
-user-xattrs. Images with system xattrs may fail to extract")
                } else {
                        // A different error is fatal
@@ -93,9 +124,11 @@
                }
        }
 
-       args := []string{"-f", "-d", dest, filename}
-       args = append(args, files...)
-       cmd := exec.Command(s.UnsquashfsPath, args...)
+       cmd, err := cmdFunc(s.UnsquashfsPath, dest, filename, false)
+       if err != nil {
+               return fmt.Errorf("command error: %s", err)
+       }
+       cmd.Args = append(cmd.Args, files...)
        if stdin {
                cmd.Stdin = reader
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/pkg/image/unpacker/squashfs_no_singularity.go 
new/singularity/pkg/image/unpacker/squashfs_no_singularity.go
--- old/singularity/pkg/image/unpacker/squashfs_no_singularity.go       
1970-01-01 01:00:00.000000000 +0100
+++ new/singularity/pkg/image/unpacker/squashfs_no_singularity.go       
2020-10-13 16:36:52.000000000 +0200
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, Control Command Inc. All rights reserved.
+// This software is licensed under a 3-clause BSD license. Please consult the
+// LICENSE.md file distributed with the sources of this project regarding your
+// rights to use or distribute this software.
+
+// +build !singularity_engine
+
+package unpacker
+
+func init() {
+       cmdFunc = unsquashfsCmd
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/pkg/image/unpacker/squashfs_singularity.go 
new/singularity/pkg/image/unpacker/squashfs_singularity.go
--- old/singularity/pkg/image/unpacker/squashfs_singularity.go  1970-01-01 
01:00:00.000000000 +0100
+++ new/singularity/pkg/image/unpacker/squashfs_singularity.go  2020-10-13 
16:36:52.000000000 +0200
@@ -0,0 +1,228 @@
+// Copyright (c) 2020, Control Command Inc. All rights reserved.
+// This software is licensed under a 3-clause BSD license. Please consult the
+// LICENSE.md file distributed with the sources of this project regarding your
+// rights to use or distribute this software.
+
+// +build singularity_engine
+
+package unpacker
+
+import (
+       "bytes"
+       "debug/elf"
+       "fmt"
+       "io"
+       "io/ioutil"
+       "os"
+       "os/exec"
+       "path/filepath"
+       "regexp"
+       "strings"
+
+       "github.com/sylabs/singularity/internal/pkg/buildcfg"
+)
+
+func init() {
+       cmdFunc = unsquashfsSandboxCmd
+}
+
+// getLibraries returns the libraries required by the elf binary,
+// the binary path must be absolute.
+func getLibraries(binary string) ([]string, error) {
+       libs := make([]string, 0)
+
+       exe, err := elf.Open(binary)
+       if err != nil {
+               return nil, err
+       }
+       defer exe.Close()
+
+       interp := ""
+
+       // look for the interpreter
+       for _, p := range exe.Progs {
+               if p.Type != elf.PT_INTERP {
+                       continue
+               }
+               buf := make([]byte, 4096)
+               n, err := p.ReadAt(buf, 0)
+               if err != nil && err != io.EOF {
+                       return nil, err
+               } else if n > cap(buf) {
+                       return nil, fmt.Errorf("buffer too small to store 
interpreter")
+               }
+               // trim null byte to avoid an execution failure with
+               // an invalid argument error
+               interp = string(bytes.Trim(buf, "\x00"))
+       }
+
+       // this is a static binary, nothing to do
+       if interp == "" {
+               return libs, nil
+       }
+
+       // run interpreter to list library dependencies for the
+       // corresponding binary, eg:
+       // /lib64/ld-linux-x86-64.so.2 --list <program>
+       // /lib/ld-musl-x86_64.so.1 --list <program>
+       errBuf := new(bytes.Buffer)
+       buf := new(bytes.Buffer)
+
+       cmd := exec.Command(interp, "--list", binary)
+       cmd.Stdout = buf
+       cmd.Stderr = errBuf
+
+       if err := cmd.Run(); err != nil {
+               return nil, fmt.Errorf("while getting library dependencies: 
%s\n%s", err, errBuf.String())
+       }
+
+       // parse the output to get matches for ' /an/absolute/path ('
+       re := regexp.MustCompile(`[[:blank:]]?(\/.*)[[:blank:]]\(`)
+
+       match := re.FindAllStringSubmatch(buf.String(), -1)
+       for _, m := range match {
+               if len(m) < 2 {
+                       continue
+               }
+               lib := m[1]
+               has := false
+               for _, l := range libs {
+                       if l == lib {
+                               has = true
+                               break
+                       }
+               }
+               if !has {
+                       libs = append(libs, lib)
+               }
+       }
+
+       return libs, nil
+}
+
+// unsquashfsSandboxCmd is the command instance for executing unsquashfs 
command
+// in a sandboxed environment with singularity.
+func unsquashfsSandboxCmd(unsquashfs string, dest string, filename string, 
rootless bool) (*exec.Cmd, error) {
+       const (
+               // will contain both dest and filename inside the sandbox
+               rootfsImageDir = "/image"
+       )
+
+       // create the sandbox temporary directory
+       tmpdir := filepath.Dir(dest)
+       rootfs, err := ioutil.TempDir(tmpdir, "tmp-rootfs-")
+       if err != nil {
+               return nil, fmt.Errorf("failed to create chroot directory: %s", 
err)
+       }
+
+       overwrite := false
+
+       // remove the destination directory if any, if the directory is
+       // not empty (typically during image build), the unsafe option -f is
+       // set, this is unfortunately required by image build
+       if err := os.Remove(dest); err != nil && !os.IsNotExist(err) {
+               if !os.IsExist(err) {
+                       return nil, fmt.Errorf("failed to remove %s: %s", dest, 
err)
+               }
+               overwrite = true
+       }
+
+       // map destination into the sandbox
+       rootfsDest := filepath.Join(rootfsImageDir, filepath.Base(dest))
+
+       // sandbox required directories
+       rootfsDirs := []string{
+               // unsquashfs get available CPU from 
/sys/devices/system/cpu/online
+               filepath.Join(rootfs, "/sys"),
+               filepath.Join(rootfs, "/dev"),
+               filepath.Join(rootfs, rootfsImageDir),
+       }
+
+       for _, d := range rootfsDirs {
+               if err := os.Mkdir(d, 0700); err != nil {
+                       return nil, fmt.Errorf("while creating %s: %s", d, err)
+               }
+       }
+
+       // the decision to use user namespace is left to singularity
+       // which will detect automatically depending of the configuration
+       // what workflow it could use
+       args := []string{
+               "-q",
+               "exec",
+               "--no-home",
+               "--no-nv",
+               "--no-rocm",
+               "-C",
+               "--no-init",
+               "--writable",
+               "-B", fmt.Sprintf("%s:%s", tmpdir, rootfsImageDir),
+       }
+
+       if filename != stdinFile {
+               filename = filepath.Join(rootfsImageDir, 
filepath.Base(filename))
+       }
+
+       // get the library dependencies of unsquashfs
+       libs, err := getLibraries(unsquashfs)
+       if err != nil {
+               return nil, err
+       }
+       libraryPath := make([]string, 0)
+
+       roFiles := []string{
+               unsquashfs,
+       }
+
+       // add libraries for bind mount and also generate
+       // LD_LIBRARY_PATH
+       for _, l := range libs {
+               dir := filepath.Dir(l)
+               roFiles = append(roFiles, l)
+               has := false
+               for _, lp := range libraryPath {
+                       if lp == dir {
+                               has = true
+                               break
+                       }
+               }
+               if !has {
+                       libraryPath = append(libraryPath, dir)
+               }
+       }
+
+       // create files and directories in the sandbox and
+       // add singularity bind mount options
+       for _, b := range roFiles {
+               file := filepath.Join(rootfs, b)
+               dir := filepath.Dir(file)
+               if err := os.MkdirAll(dir, 0700); err != nil {
+                       return nil, fmt.Errorf("while creating %s: %s", dir, 
err)
+               }
+               if err := ioutil.WriteFile(file, []byte(""), 0600); err != nil {
+                       return nil, fmt.Errorf("while creating %s: %s", file, 
err)
+               }
+               args = append(args, "-B", fmt.Sprintf("%s:%s:ro", b, b))
+       }
+
+       // singularity sandbox
+       args = append(args, rootfs)
+
+       // unsquashfs execution arguments
+       args = append(args, unsquashfs)
+       if rootless {
+               args = append(args, "-user-xattrs")
+       }
+       if overwrite {
+               args = append(args, "-f")
+       }
+       args = append(args, "-d", rootfsDest, filename)
+
+       cmd := exec.Command(filepath.Join(buildcfg.BINDIR, "singularity"), 
args...)
+       cmd.Dir = "/"
+       cmd.Env = []string{
+               fmt.Sprintf("LD_LIBRARY_PATH=%s", strings.Join(libraryPath, 
string(os.PathListSeparator))),
+       }
+
+       return cmd, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/pkg/image/unpacker/squashfs_test.go 
new/singularity/pkg/image/unpacker/squashfs_test.go
--- old/singularity/pkg/image/unpacker/squashfs_test.go 2020-07-19 
23:38:50.000000000 +0200
+++ new/singularity/pkg/image/unpacker/squashfs_test.go 2020-10-13 
16:36:52.000000000 +0200
@@ -1,3 +1,4 @@
+// Copyright (c) 2020, Control Command Inc. All rights reserved.
 // Copyright (c) 2019, Sylabs Inc. All rights reserved.
 // This software is licensed under a 3-clause BSD license. Please consult the
 // LICENSE.md file distributed with the sources of this project regarding your
@@ -106,3 +107,8 @@
                t.Errorf("file extraction failed, %s is missing", path)
        }
 }
+
+func TestMain(m *testing.M) {
+       cmdFunc = unsquashfsCmd
+       os.Exit(m.Run())
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/singularity.spec 
new/singularity/singularity.spec
--- old/singularity/singularity.spec    2020-09-15 16:11:43.000000000 +0200
+++ new/singularity/singularity.spec    2020-10-13 16:38:57.000000000 +0200
@@ -29,12 +29,12 @@
 
 Summary: Application and environment virtualization
 Name: singularity
-Version: 3.6.3
+Version: 3.6.4
 Release: 1%{?dist}
 # https://spdx.org/licenses/BSD-3-Clause-LBNL.html
 License: BSD-3-Clause-LBNL
 URL: https://www.sylabs.io/singularity/
-Source: %{name}-3.6.3.tar.gz
+Source: %{name}-3.6.4.tar.gz
 ExclusiveOS: linux
 # RPM_BUILD_ROOT wasn't being set ... for some reason
 %if "%{sles_version}" == "11"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/vendor/github.com/sylabs/scs-library-client/client/push.go 
new/singularity/vendor/github.com/sylabs/scs-library-client/client/push.go
--- old/singularity/vendor/github.com/sylabs/scs-library-client/client/push.go  
2020-09-15 16:11:54.000000000 +0200
+++ new/singularity/vendor/github.com/sylabs/scs-library-client/client/push.go  
2020-10-13 16:39:02.000000000 +0200
@@ -24,6 +24,9 @@
        // prevent a round-trip to the server. The server will return HTTP 
status
        // 400 if the requsted multipart upload size is less than 5MiB.
        minimumPartSize = 64 * 1024 * 1024
+
+       // OptionS3Compliant indicates a 100% S3 compatible object store is 
being used by backend library server
+       OptionS3Compliant = "s3compliant"
 )
 
 // UploadCallback defines an interface used to perform a call-out to
@@ -307,6 +310,12 @@
 
        c.Logger.Logf("Multi-part upload: ID=[%s] totalParts=[%d] 
partSize=[%d]", response.UploadID, response.TotalParts, fileSize)
 
+       // Enable S3 compliancy mode by default
+       val := response.Options[OptionS3Compliant]
+       s3Compliant := val == "" || val == "true"
+
+       c.Logger.Logf("S3 compliant option: %v", s3Compliant)
+
        // maintain list of completed parts which will be passed to the 
completion function
        completedParts := []CompletedPart{}
 
@@ -324,12 +333,16 @@
                        UploadID: response.UploadID,
                }
 
-               etag, err := c.multipartUploadPart(ctx, nPart, mgr, callback)
+               // include "X-Amz-Content-Sha256" header only if object store 
is 100% S3 compatible
+               etag, err := c.multipartUploadPart(ctx, nPart, mgr, callback, 
s3Compliant)
                if err != nil {
                        // error uploading part
                        c.Logger.Logf("Error uploading part %d: %v", nPart, err)
 
-                       return c.abortMultipartUpload(ctx, mgr)
+                       if err := c.abortMultipartUpload(ctx, mgr); err != nil {
+                               c.Logger.Logf("Error aborting multipart upload: 
%v", err)
+                       }
+                       return err
                }
 
                // append completed part info to list
@@ -470,18 +483,23 @@
        return chunkHash, err
 }
 
-func (c *Client) multipartUploadPart(ctx context.Context, partNumber int, m 
*uploadManager, callback UploadCallback) (string, error) {
-       // calculate sha256sum of part being uploaded
-       chunkHash, err := getPartSHA256Sum(m.Source, int64(m.Size))
-       if err != nil {
-               c.Logger.Logf("Error calculating SHA256 checksum: %v", err)
-               return "", err
-       }
+func (c *Client) multipartUploadPart(ctx context.Context, partNumber int, m 
*uploadManager, callback UploadCallback, includeSHA256ChecksumHeader bool) 
(string, error) {
+       var chunkHash string
+       var err error
+
+       if includeSHA256ChecksumHeader {
+               // calculate sha256sum of part being uploaded
+               chunkHash, err = getPartSHA256Sum(m.Source, int64(m.Size))
+               if err != nil {
+                       c.Logger.Logf("Error calculating SHA256 checksum: %v", 
err)
+                       return "", err
+               }
 
-       // rollback file pointer to beginning of part
-       if _, err := m.Source.Seek(-(int64(m.Size)), io.SeekCurrent); err != 
nil {
-               c.Logger.Logf("Error repositioning file pointer: %v", err)
-               return "", err
+               // rollback file pointer to beginning of part
+               if _, err := m.Source.Seek(-(int64(m.Size)), io.SeekCurrent); 
err != nil {
+                       c.Logger.Logf("Error repositioning file pointer: %v", 
err)
+                       return "", err
+               }
        }
 
        // send request to cloud-library for presigned PUT url
@@ -512,7 +530,9 @@
 
        // add headers to be signed
        req.ContentLength = m.Size
-       req.Header.Add("x-amz-content-sha256", chunkHash)
+       if includeSHA256ChecksumHeader {
+               req.Header.Add("x-amz-content-sha256", chunkHash)
+       }
 
        resp, err := http.DefaultClient.Do(req.WithContext(ctx))
        if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/singularity/vendor/github.com/sylabs/scs-library-client/client/response.go 
new/singularity/vendor/github.com/sylabs/scs-library-client/client/response.go
--- 
old/singularity/vendor/github.com/sylabs/scs-library-client/client/response.go  
    2020-09-15 16:11:54.000000000 +0200
+++ 
new/singularity/vendor/github.com/sylabs/scs-library-client/client/response.go  
    2020-10-13 16:39:02.000000000 +0200
@@ -72,9 +72,10 @@
 
 // MultipartUpload - Contains data for multipart image upload start request
 type MultipartUpload struct {
-       UploadID   string `json:"uploadID"`
-       TotalParts int    `json:"totalParts"`
-       PartSize   int64  `json:"partSize"`
+       UploadID   string            `json:"uploadID"`
+       TotalParts int               `json:"totalParts"`
+       PartSize   int64             `json:"partSize"`
+       Options    map[string]string `json:"options"`
 }
 
 // MultipartUploadStartResponse - Response from the API for a multipart image 
upload start request
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/singularity/vendor/modules.txt 
new/singularity/vendor/modules.txt
--- old/singularity/vendor/modules.txt  2020-09-15 16:11:54.000000000 +0200
+++ new/singularity/vendor/modules.txt  2020-10-13 16:39:02.000000000 +0200
@@ -369,7 +369,7 @@
 github.com/sylabs/scs-build-client/client
 # github.com/sylabs/scs-key-client v0.5.1
 github.com/sylabs/scs-key-client/client
-# github.com/sylabs/scs-library-client v0.5.5
+# github.com/sylabs/scs-library-client v0.5.7
 github.com/sylabs/scs-library-client/client
 # github.com/sylabs/sif v1.2.1
 github.com/sylabs/sif/internal/app/siftool


Reply via email to