mirror of
https://github.com/pgsty/minio.git
synced 2026-11-06 07:42:02 +03:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d04c9c585 | |||
| e210cb3670 | |||
| 47b577fcc0 | |||
| e9d970154d | |||
| 202d0b64eb | |||
| c25816eabc | |||
| ee028a4693 | |||
| 9c65168312 | |||
| 16aeb68c28 |
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.16.x]
|
||||
go-version: [1.16.x, 1.17.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.16.x]
|
||||
go-version: [1.16.x, 1.17.x]
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.16.x]
|
||||
go-version: [1.16.x, 1.17.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
+1
-14
@@ -487,20 +487,7 @@ func setAuthHandler(h http.Handler) http.Handler {
|
||||
// handler for validating incoming authorization headers.
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
aType := getRequestAuthType(r)
|
||||
if isSupportedS3AuthType(aType) {
|
||||
// Let top level caller validate for anonymous and known signed requests.
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
} else if aType == authTypeJWT {
|
||||
// Validate Authorization header if its valid for JWT request.
|
||||
if _, _, authErr := webRequestAuthenticate(r); authErr != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(authErr.Error()))
|
||||
return
|
||||
}
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
} else if aType == authTypeSTS {
|
||||
if isSupportedS3AuthType(aType) || aType == authTypeJWT || aType == authTypeSTS {
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -188,7 +188,9 @@ func verifyServerSystemConfig(ctx context.Context, endpointServerPools EndpointS
|
||||
// after 5 retries start logging that servers are not reachable yet
|
||||
if retries >= 5 {
|
||||
logger.Info(fmt.Sprintf("Waiting for atleast %d remote servers to be online for bootstrap check", len(clnts)/2))
|
||||
logger.Info(fmt.Sprintf("Following servers are currently offline or unreachable %s", offlineEndpoints))
|
||||
if len(offlineEndpoints) > 0 {
|
||||
logger.Info(fmt.Sprintf("Following servers are currently offline or unreachable %s", offlineEndpoints))
|
||||
}
|
||||
retries = 0 // reset to log again after 5 retries.
|
||||
}
|
||||
offlineEndpoints = nil
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/minio/internal/auth"
|
||||
@@ -93,6 +94,52 @@ func getAnonWriteOnlyObjectPolicy(bucketName, prefix string) *policy.Policy {
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper for calling Create Bucket and ensure we get one and only one success.
|
||||
func TestCreateBucket(t *testing.T) {
|
||||
ExecObjectLayerAPITest(t, testCreateBucket, []string{"MakeBucketWithLocation"})
|
||||
}
|
||||
|
||||
// testCreateBucket - Test for calling Create Bucket and ensure we get one and only one success.
|
||||
func testCreateBucket(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler,
|
||||
credentials auth.Credentials, t *testing.T) {
|
||||
bucketName1 := fmt.Sprintf("%s-1", bucketName)
|
||||
|
||||
const n = 100
|
||||
var start = make(chan struct{})
|
||||
var ok, errs int
|
||||
var wg sync.WaitGroup
|
||||
var mu sync.Mutex
|
||||
wg.Add(n)
|
||||
for i := 0; i < n; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
// Sync start.
|
||||
<-start
|
||||
if err := obj.MakeBucketWithLocation(GlobalContext, bucketName1, BucketOptions{}); err != nil {
|
||||
if _, ok := err.(BucketExists); !ok {
|
||||
t.Logf("unexpected error: %T: %v", err, err)
|
||||
return
|
||||
}
|
||||
mu.Lock()
|
||||
errs++
|
||||
mu.Unlock()
|
||||
return
|
||||
}
|
||||
mu.Lock()
|
||||
ok++
|
||||
mu.Unlock()
|
||||
}()
|
||||
}
|
||||
close(start)
|
||||
wg.Wait()
|
||||
if ok != 1 {
|
||||
t.Fatalf("want 1 ok, got %d", ok)
|
||||
}
|
||||
if errs != n-1 {
|
||||
t.Fatalf("want %d errors, got %d", n-1, errs)
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper for calling Put Bucket Policy HTTP handler tests for both Erasure multiple disks and single node setup.
|
||||
func TestPutBucketPolicyHandler(t *testing.T) {
|
||||
ExecObjectLayerAPITest(t, testPutBucketPolicyHandler, []string{"PutBucketPolicy"})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -278,6 +278,18 @@ func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time.
|
||||
h.Write([]byte(fmt.Sprintf("%v", meta.Erasure.Distribution)))
|
||||
// make sure that length of Data is same
|
||||
h.Write([]byte(fmt.Sprintf("%v", len(meta.Data))))
|
||||
|
||||
// ILM transition fields
|
||||
h.Write([]byte(meta.TransitionStatus))
|
||||
h.Write([]byte(meta.TransitionTier))
|
||||
h.Write([]byte(meta.TransitionedObjName))
|
||||
h.Write([]byte(meta.TransitionVersionID))
|
||||
|
||||
// Server-side replication fields
|
||||
h.Write([]byte(fmt.Sprintf("%v", meta.MarkDeleted)))
|
||||
h.Write([]byte(meta.DeleteMarkerReplicationStatus))
|
||||
h.Write([]byte(meta.VersionPurgeStatus))
|
||||
h.Write([]byte(meta.Metadata[xhttp.AmzBucketReplicationStatus]))
|
||||
metaHashes[i] = hex.EncodeToString(h.Sum(nil))
|
||||
h.Reset()
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ func (er erasureObjects) renameAll(ctx context.Context, bucket, prefix string) {
|
||||
wg.Add(1)
|
||||
go func(disk StorageAPI) {
|
||||
defer wg.Done()
|
||||
disk.RenameFile(ctx, bucket, prefix, minioMetaTmpBucket, mustGetUUID())
|
||||
disk.RenameFile(ctx, bucket, prefix, minioMetaTmpDeletedBucket, mustGetUUID())
|
||||
}(disk)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
+26
-13
@@ -582,6 +582,15 @@ func (z *erasureServerPools) NSScanner(ctx context.Context, bf *bloomFilter, upd
|
||||
func (z *erasureServerPools) MakeBucketWithLocation(ctx context.Context, bucket string, opts BucketOptions) error {
|
||||
g := errgroup.WithNErrs(len(z.serverPools))
|
||||
|
||||
// Lock the bucket name before creating.
|
||||
lk := z.NewNSLock(minioMetaTmpBucket, bucket+".lck")
|
||||
lkctx, err := lk.GetLock(ctx, globalOperationTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx = lkctx.Context()
|
||||
defer lk.Unlock(lkctx.Cancel)
|
||||
|
||||
// Create buckets in parallel across all sets.
|
||||
for index := range z.serverPools {
|
||||
index := index
|
||||
@@ -1060,6 +1069,22 @@ func maxKeysPlusOne(maxKeys int, addOne bool) int {
|
||||
|
||||
func (z *erasureServerPools) ListObjects(ctx context.Context, bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) {
|
||||
var loi ListObjectsInfo
|
||||
|
||||
if len(prefix) > 0 && maxKeys == 1 && delimiter == "" && marker == "" {
|
||||
// Optimization for certain applications like
|
||||
// - Cohesity
|
||||
// - Actifio, Splunk etc.
|
||||
// which send ListObjects requests where the actual object
|
||||
// itself is the prefix and max-keys=1 in such scenarios
|
||||
// we can simply verify locally if such an object exists
|
||||
// to avoid the need for ListObjects().
|
||||
objInfo, err := z.GetObjectInfo(ctx, bucket, prefix, ObjectOptions{NoLock: true})
|
||||
if err == nil {
|
||||
loi.Objects = append(loi.Objects, objInfo)
|
||||
return loi, nil
|
||||
}
|
||||
}
|
||||
|
||||
opts := listPathOptions{
|
||||
Bucket: bucket,
|
||||
Prefix: prefix,
|
||||
@@ -1405,20 +1430,8 @@ func (z *erasureServerPools) DeleteBucket(ctx context.Context, bucket string, fo
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteAll will delete a bucket+prefix unconditionally across all disks.
|
||||
// Note that set distribution is ignored so it should only be used in cases where
|
||||
// data is not distributed across sets.
|
||||
// Errors are logged but individual disk failures are not returned.
|
||||
func (z *erasureServerPools) deleteAll(ctx context.Context, bucket, prefix string) {
|
||||
for _, servers := range z.serverPools {
|
||||
for _, set := range servers.sets {
|
||||
set.deleteAll(ctx, bucket, prefix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// renameAll will rename bucket+prefix unconditionally across all disks to
|
||||
// minioMetaTmpBucket + unique uuid,
|
||||
// minioMetaTmpDeletedBucket + unique uuid,
|
||||
// Note that set distribution is ignored so it should only be used in cases where
|
||||
// data is not distributed across sets. Errors are logged but individual
|
||||
// disk failures are not returned.
|
||||
|
||||
@@ -213,15 +213,6 @@ func getReqAccessCred(r *http.Request, region string) (cred auth.Credentials) {
|
||||
if cred.AccessKey == "" {
|
||||
cred, _, _ = getReqAccessKeyV2(r)
|
||||
}
|
||||
if cred.AccessKey == "" {
|
||||
claims, owner, _ := webRequestAuthenticate(r)
|
||||
if owner {
|
||||
return globalActiveCred
|
||||
}
|
||||
if claims != nil {
|
||||
cred, _ = globalIAMSys.GetUser(claims.AccessKey)
|
||||
}
|
||||
}
|
||||
return cred
|
||||
}
|
||||
|
||||
|
||||
+37
-25
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/minio/minio/internal/auth"
|
||||
xjwt "github.com/minio/minio/internal/jwt"
|
||||
"github.com/minio/minio/internal/logger"
|
||||
iampolicy "github.com/minio/pkg/iam/policy"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -97,29 +98,6 @@ func authenticateURL(accessKey, secretKey string) (string, error) {
|
||||
return authenticateJWTUsers(accessKey, secretKey, defaultURLJWTExpiry)
|
||||
}
|
||||
|
||||
// Callback function used for parsing
|
||||
func webTokenCallback(claims *xjwt.MapClaims) ([]byte, error) {
|
||||
if claims.AccessKey == globalActiveCred.AccessKey {
|
||||
return []byte(globalActiveCred.SecretKey), nil
|
||||
}
|
||||
ok, _, err := globalIAMSys.IsTempUser(claims.AccessKey)
|
||||
if err != nil {
|
||||
if err == errNoSuchUser {
|
||||
return nil, errInvalidAccessKeyID
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if ok {
|
||||
return []byte(globalActiveCred.SecretKey), nil
|
||||
}
|
||||
cred, ok := globalIAMSys.GetUser(claims.AccessKey)
|
||||
if !ok {
|
||||
return nil, errInvalidAccessKeyID
|
||||
}
|
||||
return []byte(cred.SecretKey), nil
|
||||
|
||||
}
|
||||
|
||||
// Check if the request is authenticated.
|
||||
// Returns nil if the request is authenticated. errNoAuthToken if token missing.
|
||||
// Returns errAuthentication for all other errors.
|
||||
@@ -132,10 +110,44 @@ func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, bool, error) {
|
||||
return nil, false, err
|
||||
}
|
||||
claims := xjwt.NewMapClaims()
|
||||
if err := xjwt.ParseWithClaims(token, claims, webTokenCallback); err != nil {
|
||||
if err := xjwt.ParseWithClaims(token, claims, func(claims *xjwt.MapClaims) ([]byte, error) {
|
||||
if claims.AccessKey == globalActiveCred.AccessKey {
|
||||
return []byte(globalActiveCred.SecretKey), nil
|
||||
}
|
||||
cred, ok := globalIAMSys.GetUser(claims.AccessKey)
|
||||
if !ok {
|
||||
return nil, errInvalidAccessKeyID
|
||||
}
|
||||
return []byte(cred.SecretKey), nil
|
||||
}); err != nil {
|
||||
return claims, false, errAuthentication
|
||||
}
|
||||
owner := claims.AccessKey == globalActiveCred.AccessKey
|
||||
owner := true
|
||||
if globalActiveCred.AccessKey != claims.AccessKey {
|
||||
// Check if the access key is part of users credentials.
|
||||
ucred, ok := globalIAMSys.GetUser(claims.AccessKey)
|
||||
if !ok {
|
||||
return nil, false, errInvalidAccessKeyID
|
||||
}
|
||||
|
||||
// get embedded claims
|
||||
eclaims, s3Err := checkClaimsFromToken(req, ucred)
|
||||
if s3Err != ErrNone {
|
||||
return nil, false, errAuthentication
|
||||
}
|
||||
|
||||
for k, v := range eclaims {
|
||||
claims.MapClaims[k] = v
|
||||
}
|
||||
|
||||
// Now check if we have a sessionPolicy.
|
||||
if _, ok = eclaims[iampolicy.SessionPolicyName]; ok {
|
||||
owner = false
|
||||
} else {
|
||||
owner = globalActiveCred.AccessKey == ucred.ParentUser
|
||||
}
|
||||
}
|
||||
|
||||
return claims, owner, nil
|
||||
}
|
||||
|
||||
|
||||
+21
-6
@@ -110,11 +110,6 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
var scanDir func(path string) error
|
||||
|
||||
scanDir = func(current string) error {
|
||||
// always skip the directory that doesn't match the prefix
|
||||
if len(current) > 0 && !strings.HasPrefix(current, prefix) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Skip forward, if requested...
|
||||
forward := ""
|
||||
if len(opts.ForwardTo) > 0 && strings.HasPrefix(opts.ForwardTo, current) {
|
||||
@@ -126,7 +121,9 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
if contextCanceled(ctx) {
|
||||
return ctx.Err()
|
||||
}
|
||||
s.walkMu.Lock()
|
||||
entries, err := s.ListDir(ctx, opts.Bucket, current, -1)
|
||||
s.walkMu.Unlock()
|
||||
if err != nil {
|
||||
// Folder could have gone away in-between
|
||||
if err != errVolumeNotFound && err != errFileNotFound {
|
||||
@@ -143,7 +140,16 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
}
|
||||
dirObjects := make(map[string]struct{})
|
||||
for i, entry := range entries {
|
||||
if len(prefix) > 0 && !strings.HasPrefix(entry, prefix) {
|
||||
// Do do not retain the file, since it doesn't
|
||||
// match the prefix.
|
||||
entries[i] = ""
|
||||
continue
|
||||
}
|
||||
if len(forward) > 0 && entry < forward {
|
||||
// Do do not retain the file, since its
|
||||
// lexially smaller than 'forward'
|
||||
entries[i] = ""
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(entry, slashSeparator) {
|
||||
@@ -167,7 +173,9 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
// If root was an object return it as such.
|
||||
if HasSuffix(entry, xlStorageFormatFile) {
|
||||
var meta metaCacheEntry
|
||||
s.walkMu.Lock()
|
||||
meta.metadata, err = s.readMetadata(pathJoin(volumeDir, current, entry))
|
||||
s.walkMu.Unlock()
|
||||
if err != nil {
|
||||
logger.LogIf(ctx, err)
|
||||
continue
|
||||
@@ -182,7 +190,9 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
// Check legacy.
|
||||
if HasSuffix(entry, xlStorageFormatFileV1) {
|
||||
var meta metaCacheEntry
|
||||
s.walkMu.Lock()
|
||||
meta.metadata, err = xioutil.ReadFile(pathJoin(volumeDir, current, entry))
|
||||
s.walkMu.Unlock()
|
||||
if err != nil {
|
||||
logger.LogIf(ctx, err)
|
||||
continue
|
||||
@@ -199,6 +209,7 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
// Process in sort order.
|
||||
sort.Strings(entries)
|
||||
dirStack := make([]string, 0, 5)
|
||||
prefix = "" // Remove prefix after first level as we have already filtered the list.
|
||||
if len(forward) > 0 {
|
||||
idx := sort.SearchStrings(entries, forward)
|
||||
if idx > 0 {
|
||||
@@ -237,7 +248,9 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
meta.name = meta.name[:len(meta.name)-1] + globalDirSuffixWithSlash
|
||||
}
|
||||
|
||||
s.walkMu.Lock()
|
||||
meta.metadata, err = s.readMetadata(pathJoin(volumeDir, meta.name, xlStorageFormatFile))
|
||||
s.walkMu.Unlock()
|
||||
switch {
|
||||
case err == nil:
|
||||
// It was an object
|
||||
@@ -246,7 +259,9 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
}
|
||||
out <- meta
|
||||
case osIsNotExist(err):
|
||||
s.walkMu.Lock()
|
||||
meta.metadata, err = xioutil.ReadFile(pathJoin(volumeDir, meta.name, xlStorageFormatFileV1))
|
||||
s.walkMu.Unlock()
|
||||
if err == nil {
|
||||
// It was an object
|
||||
out <- meta
|
||||
@@ -326,7 +341,7 @@ func (s *storageRESTServer) WalkDirHandler(w http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
|
||||
var reportNotFound bool
|
||||
if v := vars[storageRESTReportNotFound]; v != "" {
|
||||
if v := r.Form.Get(storageRESTReportNotFound); v != "" {
|
||||
reportNotFound, err = strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
s.writeErrorResponse(w, err)
|
||||
|
||||
+1
-1
@@ -149,5 +149,5 @@ func (m *metacache) delete(ctx context.Context) {
|
||||
logger.LogIf(ctx, errors.New("metacache.delete: expected objAPI to be *erasureServerPools"))
|
||||
return
|
||||
}
|
||||
ez.deleteAll(ctx, minioMetaBucket, metacachePrefixForID(m.bucket, m.id))
|
||||
ez.renameAll(ctx, minioMetaBucket, metacachePrefixForID(m.bucket, m.id))
|
||||
}
|
||||
|
||||
@@ -84,6 +84,10 @@ func testListObjects(obj ObjectLayer, instanceType string, t1 TestErrHandler) {
|
||||
{testBuckets[4], "file1/guidSplunk-aaaa/file", "content", nil},
|
||||
{testBuckets[5], "dir/day_id=2017-10-10/issue", "content", nil},
|
||||
{testBuckets[5], "dir/day_id=2017-10-11/issue", "content", nil},
|
||||
{testBuckets[5], "foo/201910/1122", "content", nil},
|
||||
{testBuckets[5], "foo/201910/1112", "content", nil},
|
||||
{testBuckets[5], "foo/201910/2112", "content", nil},
|
||||
{testBuckets[5], "foo/201910_txt", "content", nil},
|
||||
}
|
||||
for _, object := range testObjects {
|
||||
md5Bytes := md5.Sum([]byte(object.content))
|
||||
@@ -477,6 +481,24 @@ func testListObjects(obj ObjectLayer, instanceType string, t1 TestErrHandler) {
|
||||
IsTruncated: true,
|
||||
Prefixes: []string{"dir/day_id=2017-10-10/"},
|
||||
},
|
||||
// ListObjectsResult-37 list with prefix match 2 levels deep
|
||||
{
|
||||
IsTruncated: false,
|
||||
Objects: []ObjectInfo{
|
||||
{Name: "foo/201910/1112"},
|
||||
{Name: "foo/201910/1122"},
|
||||
},
|
||||
},
|
||||
// ListObjectsResult-38 list with prefix match 1 level deep
|
||||
{
|
||||
IsTruncated: false,
|
||||
Objects: []ObjectInfo{
|
||||
{Name: "foo/201910/1112"},
|
||||
{Name: "foo/201910/1122"},
|
||||
{Name: "foo/201910/2112"},
|
||||
{Name: "foo/201910_txt"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
@@ -602,6 +624,9 @@ func testListObjects(obj ObjectLayer, instanceType string, t1 TestErrHandler) {
|
||||
{testBuckets[4], "file1/", "", "guidSplunk", 1000, resultCases[35], nil, true},
|
||||
// Test listing at prefix with expected prefix markers
|
||||
{testBuckets[5], "dir/", "", SlashSeparator, 1, resultCases[36], nil, true},
|
||||
// Test listing with prefix match
|
||||
{testBuckets[5], "foo/201910/11", "", "", 1000, resultCases[37], nil, true},
|
||||
{testBuckets[5], "foo/201910", "", "", 1000, resultCases[38], nil, true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build freebsd || openbsd || netbsd
|
||||
// +build freebsd openbsd netbsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build (linux || darwin) && !appengine
|
||||
// +build linux darwin
|
||||
// +build !appengine
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build darwin || freebsd || openbsd || netbsd
|
||||
// +build darwin freebsd openbsd netbsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux && !appengine
|
||||
// +build linux,!appengine
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build plan9 || solaris
|
||||
// +build plan9 solaris
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build (linux && !appengine) || darwin || freebsd || netbsd || openbsd
|
||||
// +build linux,!appengine darwin freebsd netbsd openbsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build fips
|
||||
// +build fips
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !fips
|
||||
// +build !fips
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -139,6 +139,9 @@ type xlStorage struct {
|
||||
|
||||
ctx context.Context
|
||||
sync.RWMutex
|
||||
|
||||
// mutex to prevent concurrent read operations overloading walks.
|
||||
walkMu sync.Mutex
|
||||
}
|
||||
|
||||
// checkPathLength - returns error if given path name length more than 255
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows || darwin || freebsd
|
||||
// +build windows darwin freebsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows && !darwin && !freebsd
|
||||
// +build !windows,!darwin,!freebsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
// +build linux darwin dragonfly freebsd netbsd openbsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -2,7 +2,7 @@ version: '3.7'
|
||||
|
||||
# Settings and configurations that are common for all containers
|
||||
x-minio-common: &minio-common
|
||||
image: minio/minio:RELEASE.2021-08-05T22-01-19Z
|
||||
image: minio/minio:RELEASE.2021-08-17T20-53-08Z
|
||||
command: server --console-address ":9001" http://minio{1...4}/data{1...2}
|
||||
expose:
|
||||
- "9000"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -18,10 +18,8 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -155,39 +153,27 @@ M9ofSEt/bdRD
|
||||
}
|
||||
defer os.Remove(tempFile5)
|
||||
|
||||
nonexistentErr := fmt.Errorf("open nonexistent-file: no such file or directory")
|
||||
if runtime.GOOS == "windows" {
|
||||
// Below concatenation is done to get rid of goline error
|
||||
// "error strings should not be capitalized or end with punctuation or a newline"
|
||||
nonexistentErr = fmt.Errorf("open nonexistent-file:" + " The system cannot find the file specified.")
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
certFile string
|
||||
expectedResultLen int
|
||||
expectedErr error
|
||||
expectedErr bool
|
||||
}{
|
||||
{"nonexistent-file", 0, nonexistentErr},
|
||||
{tempFile1, 0, fmt.Errorf("Empty public certificate file %s", tempFile1)},
|
||||
{tempFile2, 0, fmt.Errorf("Could not read PEM block from file %s", tempFile2)},
|
||||
{tempFile3, 0, fmt.Errorf("asn1: structure error: sequence tag mismatch")},
|
||||
{tempFile4, 1, nil},
|
||||
{tempFile5, 2, nil},
|
||||
{"nonexistent-file", 0, true},
|
||||
{tempFile1, 0, true},
|
||||
{tempFile2, 0, true},
|
||||
{tempFile3, 0, true},
|
||||
{tempFile4, 1, false},
|
||||
{tempFile5, 2, false},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
certs, err := ParsePublicCertFile(testCase.certFile)
|
||||
|
||||
if testCase.expectedErr == nil {
|
||||
if err != nil {
|
||||
t.Fatalf("error: expected = <nil>, got = %v", err)
|
||||
}
|
||||
} else if err == nil {
|
||||
t.Fatalf("error: expected = %v, got = <nil>", testCase.expectedErr)
|
||||
} else if testCase.expectedErr.Error() != err.Error() {
|
||||
t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err)
|
||||
if !testCase.expectedErr && err != nil {
|
||||
t.Fatalf("error: expected = <nil>, got = %v", err)
|
||||
}
|
||||
if testCase.expectedErr && err == nil {
|
||||
t.Fatal("error: expected err, got = <nil>")
|
||||
}
|
||||
|
||||
if len(certs) != testCase.expectedResultLen {
|
||||
t.Fatalf("certs: expected = %v, got = %v", testCase.expectedResultLen, len(certs))
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !fips
|
||||
// +build !fips
|
||||
|
||||
package openid
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !fips
|
||||
// +build !fips
|
||||
|
||||
package openid
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux || netbsd || freebsd
|
||||
// +build linux netbsd freebsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !linux && !netbsd && !freebsd && !darwin
|
||||
// +build !linux,!netbsd,!freebsd,!darwin
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !netbsd && !solaris
|
||||
// +build !netbsd,!solaris
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build freebsd || netbsd || openbsd || darwin
|
||||
// +build freebsd netbsd openbsd darwin
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !linux && !netbsd && !freebsd && !darwin && !openbsd
|
||||
// +build !linux,!netbsd,!freebsd,!darwin,!openbsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build darwin || dragonfly
|
||||
// +build darwin dragonfly
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build freebsd
|
||||
// +build freebsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux && !s390x && !arm && !386
|
||||
// +build linux,!s390x,!arm,!386
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build (linux && arm) || (linux && 386)
|
||||
// +build linux,arm linux,386
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux && s390x
|
||||
// +build linux,s390x
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build netbsd
|
||||
// +build netbsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build openbsd
|
||||
// +build openbsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build solaris
|
||||
// +build solaris
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build darwin || freebsd || dragonfly || openbsd || solaris
|
||||
// +build darwin freebsd dragonfly openbsd solaris
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux && !s390x && !arm && !386
|
||||
// +build linux,!s390x,!arm,!386
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build fips && linux && amd64
|
||||
// +build fips,linux,amd64
|
||||
|
||||
package fips
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build !fips
|
||||
// +build !fips
|
||||
|
||||
package fips
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build fips
|
||||
// +build fips
|
||||
|
||||
package hash
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build !fips
|
||||
// +build !fips
|
||||
|
||||
package hash
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd || rumprun
|
||||
// +build linux darwin dragonfly freebsd netbsd openbsd rumprun
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows || plan9 || solaris
|
||||
// +build windows plan9 solaris
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows || darwin || freebsd
|
||||
// +build windows darwin freebsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows && !darwin && !freebsd
|
||||
// +build !windows,!darwin,!freebsd
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows && !plan9 && !solaris
|
||||
// +build !windows,!plan9,!solaris
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build solaris
|
||||
// +build solaris
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !linux && !windows
|
||||
// +build !linux,!windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build testrunmain
|
||||
// +build testrunmain
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user