commit
f1c022d84b
|
@ -14,7 +14,6 @@ import (
|
||||||
"github.com/containers/buildah/define"
|
"github.com/containers/buildah/define"
|
||||||
"github.com/containers/buildah/pkg/cli"
|
"github.com/containers/buildah/pkg/cli"
|
||||||
"github.com/containers/buildah/pkg/parse"
|
"github.com/containers/buildah/pkg/parse"
|
||||||
"github.com/containers/buildah/util"
|
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/containers/storage/pkg/unshare"
|
"github.com/containers/storage/pkg/unshare"
|
||||||
|
@ -238,7 +237,8 @@ func main() {
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
}
|
}
|
||||||
exitCode := cli.ExecErrorCodeGeneric
|
exitCode := cli.ExecErrorCodeGeneric
|
||||||
if ee, ok := (util.Cause(err)).(*exec.ExitError); ok {
|
var ee *exec.ExitError
|
||||||
|
if errors.As(err, &ee) {
|
||||||
if w, ok := ee.Sys().(syscall.WaitStatus); ok {
|
if w, ok := ee.Sys().(syscall.WaitStatus); ok {
|
||||||
exitCode = w.ExitStatus()
|
exitCode = w.ExitStatus()
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/buildah/util"
|
|
||||||
"github.com/containers/storage/pkg/idtools"
|
"github.com/containers/storage/pkg/idtools"
|
||||||
"github.com/containers/storage/pkg/reexec"
|
"github.com/containers/storage/pkg/reexec"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -556,7 +555,7 @@ func testPut(t *testing.T) {
|
||||||
defer os.RemoveAll(tmp)
|
defer os.RemoveAll(tmp)
|
||||||
err = Put(tmp, tmp, PutOptions{UIDMap: uidMap, GIDMap: gidMap, NoOverwriteDirNonDir: !overwrite}, bytes.NewReader(archive))
|
err = Put(tmp, tmp, PutOptions{UIDMap: uidMap, GIDMap: gidMap, NoOverwriteDirNonDir: !overwrite}, bytes.NewReader(archive))
|
||||||
if overwrite {
|
if overwrite {
|
||||||
if util.Cause(err) != syscall.EPERM {
|
if !errors.Is(err, syscall.EPERM) {
|
||||||
assert.Nilf(t, err, "expected to overwrite directory with type %c: %v", typeFlag, err)
|
assert.Nilf(t, err, "expected to overwrite directory with type %c: %v", typeFlag, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -584,7 +583,7 @@ func testPut(t *testing.T) {
|
||||||
defer os.RemoveAll(tmp)
|
defer os.RemoveAll(tmp)
|
||||||
err = Put(tmp, tmp, PutOptions{UIDMap: uidMap, GIDMap: gidMap, NoOverwriteNonDirDir: !overwrite}, bytes.NewReader(archive))
|
err = Put(tmp, tmp, PutOptions{UIDMap: uidMap, GIDMap: gidMap, NoOverwriteNonDirDir: !overwrite}, bytes.NewReader(archive))
|
||||||
if overwrite {
|
if overwrite {
|
||||||
if util.Cause(err) != syscall.EPERM {
|
if !errors.Is(err, syscall.EPERM) {
|
||||||
assert.Nilf(t, err, "expected to overwrite file with type %c: %v", typeFlag, err)
|
assert.Nilf(t, err, "expected to overwrite file with type %c: %v", typeFlag, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -660,7 +659,7 @@ func isExpectedError(err error, inSubdir bool, name string, expectedErrors []exp
|
||||||
if expectedError.name != name {
|
if expectedError.name != name {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !strings.Contains(util.Cause(err).Error(), util.Cause(expectedError.err).Error()) {
|
if !strings.Contains(err.Error(), expectedError.err.Error()) {
|
||||||
// not expecting this specific error
|
// not expecting this specific error
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
package copier
|
package copier
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/containers/buildah/util"
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,11 +45,11 @@ func Lgetxattrs(path string) (map[string]string, error) {
|
||||||
list = make([]byte, listSize)
|
list = make([]byte, listSize)
|
||||||
size, err := unix.Llistxattr(path, list)
|
size, err := unix.Llistxattr(path, list)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if util.Cause(err) == syscall.ERANGE {
|
if errors.Is(err, syscall.ERANGE) {
|
||||||
listSize *= 2
|
listSize *= 2
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (util.Cause(err) == syscall.ENOTSUP) || (util.Cause(err) == syscall.ENOSYS) {
|
if errors.Is(err, syscall.ENOTSUP) || errors.Is(err, syscall.ENOSYS) {
|
||||||
// treat these errors listing xattrs as equivalent to "no xattrs"
|
// treat these errors listing xattrs as equivalent to "no xattrs"
|
||||||
list = list[:0]
|
list = list[:0]
|
||||||
break
|
break
|
||||||
|
@ -71,7 +71,7 @@ func Lgetxattrs(path string) (map[string]string, error) {
|
||||||
attributeValue = make([]byte, attributeSize)
|
attributeValue = make([]byte, attributeSize)
|
||||||
size, err := unix.Lgetxattr(path, attribute, attributeValue)
|
size, err := unix.Lgetxattr(path, attribute, attributeValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if util.Cause(err) == syscall.ERANGE {
|
if errors.Is(err, syscall.ERANGE) {
|
||||||
attributeSize *= 2
|
attributeSize *= 2
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package copier
|
package copier
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containers/buildah/util"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func TestXattrs(t *testing.T) {
|
||||||
defer os.Remove(f.Name())
|
defer os.Remove(f.Name())
|
||||||
|
|
||||||
err = Lsetxattrs(f.Name(), map[string]string{attribute: value})
|
err = Lsetxattrs(f.Name(), map[string]string{attribute: value})
|
||||||
if util.Cause(err) == syscall.ENOTSUP {
|
if errors.Is(err, syscall.ENOTSUP) {
|
||||||
t.Skipf("extended attributes not supported on %q, skipping", tmp)
|
t.Skipf("extended attributes not supported on %q, skipping", tmp)
|
||||||
}
|
}
|
||||||
if !assert.Nil(t, err, "error setting attribute on file: %v", err) {
|
if !assert.Nil(t, err, "error setting attribute on file: %v", err) {
|
||||||
|
|
19
util/util.go
19
util/util.go
|
@ -466,22 +466,3 @@ func VerifyTagName(imageSpec string) (types.ImageReference, error) {
|
||||||
}
|
}
|
||||||
return ref, nil
|
return ref, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cause returns the most underlying error for the provided one. There is a
|
|
||||||
// maximum error depth of 100 to avoid endless loops. An additional error log
|
|
||||||
// message will be created if this maximum has reached.
|
|
||||||
func Cause(err error) (cause error) {
|
|
||||||
cause = err
|
|
||||||
|
|
||||||
const maxDepth = 100
|
|
||||||
for i := 0; i <= maxDepth; i++ {
|
|
||||||
res := errors.Unwrap(cause)
|
|
||||||
if res == nil {
|
|
||||||
return cause
|
|
||||||
}
|
|
||||||
cause = res
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.Errorf("Max error depth of %d reached, cannot unwrap until root cause: %v", maxDepth, err)
|
|
||||||
return cause
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMergeEnv(t *testing.T) {
|
func TestMergeEnv(t *testing.T) {
|
||||||
|
@ -138,47 +135,3 @@ func TestMountsSort(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCause(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
for _, tc := range []struct {
|
|
||||||
name string
|
|
||||||
err func() error
|
|
||||||
expectedErr error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "nil error",
|
|
||||||
err: func() error { return nil },
|
|
||||||
expectedErr: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "equal errors",
|
|
||||||
err: func() error { return errors.New("foo") },
|
|
||||||
expectedErr: errors.New("foo"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "wrapped error",
|
|
||||||
err: func() error { return fmt.Errorf("baz: %w", fmt.Errorf("bar: %w", errors.New("foo"))) },
|
|
||||||
expectedErr: errors.New("foo"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "max depth reached",
|
|
||||||
err: func() error {
|
|
||||||
err := errors.New("error")
|
|
||||||
for i := 0; i <= 101; i++ {
|
|
||||||
err = fmt.Errorf("%d: %w", i, err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
expectedErr: fmt.Errorf("0: %w", errors.New("error")),
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
tc := tc
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
err := Cause(tc.err())
|
|
||||||
assert.Equal(t, tc.expectedErr, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue