mirror of
https://github.com/pgsty/minio.git
synced 2026-08-10 08:13:28 +03:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d7408fc99 | |||
| 864f80e226 | |||
| 0379d6a37f | |||
| 43aa8e4259 | |||
| e2ed696619 | |||
| fb3f67a597 | |||
| 7ee75368e0 | |||
| 1d6478b8ae | |||
| 0581001b6f | |||
| 479303e7e9 | |||
| 89aec6804b | |||
| eb33bc6bf5 | |||
| 3310f740f0 | |||
| 4595293ca0 | |||
| 02a67cbd2a | |||
| 2b34e5b9ae | |||
| a6258668a6 | |||
| d0cada583f | |||
| 0bd8f06b62 | |||
| 6640be3bed | |||
| eafeb27e90 | |||
| f2c9eb0f79 |
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
# are turned off - i.e. if ldap="", then ldap server is not enabled for
|
||||
# the tests.
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
ldap: ["", "localhost:389"]
|
||||
etcd: ["", "http://localhost:2379"]
|
||||
openid: ["", "http://127.0.0.1:5556/dex"]
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
- name: setup-go-step
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.23.x
|
||||
go-version: 1.24.x
|
||||
|
||||
- name: github sha short
|
||||
id: vars
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.23.x]
|
||||
go-version: [1.24.x]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
|
||||
@@ -21,7 +21,8 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.23.5
|
||||
go-version: 1.24.0
|
||||
cached: false
|
||||
- name: Get official govulncheck
|
||||
run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
shell: bash
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.23-alpine as build
|
||||
FROM golang:1.24-alpine as build
|
||||
|
||||
ARG TARGETARCH
|
||||
ARG RELEASE
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.23-alpine AS build
|
||||
FROM golang:1.24-alpine AS build
|
||||
|
||||
ARG TARGETARCH
|
||||
ARG RELEASE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.23-alpine AS build
|
||||
FROM golang:1.24-alpine AS build
|
||||
|
||||
ARG TARGETARCH
|
||||
ARG RELEASE
|
||||
|
||||
@@ -122,7 +122,7 @@ You can also connect using any S3-compatible tool, such as the MinIO Client `mc`
|
||||
|
||||
## Install from Source
|
||||
|
||||
Use the following commands to compile and run a standalone MinIO server from source. Source installation is only intended for developers and advanced users. If you do not have a working Golang environment, please follow [How to install Golang](https://golang.org/doc/install). Minimum version required is [go1.21](https://golang.org/dl/#stable)
|
||||
Use the following commands to compile and run a standalone MinIO server from source. Source installation is only intended for developers and advanced users. If you do not have a working Golang environment, please follow [How to install Golang](https://golang.org/doc/install). Minimum version required is [go1.24](https://golang.org/dl/#stable)
|
||||
|
||||
```sh
|
||||
go install github.com/minio/minio@latest
|
||||
|
||||
@@ -69,8 +69,10 @@ __init__() {
|
||||
|
||||
## this is needed because github actions don't have
|
||||
## docker-compose on all runners
|
||||
go install github.com/docker/compose/v2/cmd@latest
|
||||
mv -v /tmp/gopath/bin/cmd /tmp/gopath/bin/docker-compose
|
||||
COMPOSE_VERSION=v2.35.1
|
||||
mkdir -p /tmp/gopath/bin/
|
||||
wget -O /tmp/gopath/bin/docker-compose https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-linux-x86_64
|
||||
chmod +x /tmp/gopath/bin/docker-compose
|
||||
|
||||
cleanup
|
||||
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
// Copyright (c) 2015-2025 MinIO, Inc.
|
||||
//
|
||||
// This file is part of MinIO Object Storage stack
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/minio/minio-go/v7/pkg/set"
|
||||
"github.com/minio/pkg/v3/policy"
|
||||
)
|
||||
|
||||
const dummyRoleARN = "dummy-internal"
|
||||
|
||||
// ListAccessKeysOpenIDBulk - GET /minio/admin/v3/idp/openid/list-access-keys-bulk
|
||||
func (a adminAPIHandlers) ListAccessKeysOpenIDBulk(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || globalNotificationSys == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
cred, owner, s3Err := validateAdminSignature(ctx, r, "")
|
||||
if s3Err != ErrNone {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
if !globalIAMSys.OpenIDConfig.Enabled {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminOpenIDNotEnabled), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
userList := r.Form["users"]
|
||||
isAll := r.Form.Get("all") == "true"
|
||||
selfOnly := !isAll && len(userList) == 0
|
||||
cfgName := r.Form.Get("configName")
|
||||
allConfigs := r.Form.Get("allConfigs") == "true"
|
||||
if cfgName == "" && !allConfigs {
|
||||
cfgName = madmin.Default
|
||||
}
|
||||
|
||||
if isAll && len(userList) > 0 {
|
||||
// This should be checked on client side, so return generic error
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
// Empty DN list and not self, list access keys for all users
|
||||
if isAll {
|
||||
if !globalIAMSys.IsAllowed(policy.Args{
|
||||
AccountName: cred.AccessKey,
|
||||
Groups: cred.Groups,
|
||||
Action: policy.ListUsersAdminAction,
|
||||
ConditionValues: getConditionValues(r, "", cred),
|
||||
IsOwner: owner,
|
||||
Claims: cred.Claims,
|
||||
}) {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL)
|
||||
return
|
||||
}
|
||||
} else if len(userList) == 1 && userList[0] == cred.ParentUser {
|
||||
selfOnly = true
|
||||
}
|
||||
|
||||
if !globalIAMSys.IsAllowed(policy.Args{
|
||||
AccountName: cred.AccessKey,
|
||||
Groups: cred.Groups,
|
||||
Action: policy.ListServiceAccountsAdminAction,
|
||||
ConditionValues: getConditionValues(r, "", cred),
|
||||
IsOwner: owner,
|
||||
Claims: cred.Claims,
|
||||
DenyOnly: selfOnly,
|
||||
}) {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
if selfOnly && len(userList) == 0 {
|
||||
selfDN := cred.AccessKey
|
||||
if cred.ParentUser != "" {
|
||||
selfDN = cred.ParentUser
|
||||
}
|
||||
userList = append(userList, selfDN)
|
||||
}
|
||||
|
||||
listType := r.Form.Get("listType")
|
||||
var listSTSKeys, listServiceAccounts bool
|
||||
switch listType {
|
||||
case madmin.AccessKeyListUsersOnly:
|
||||
listSTSKeys = false
|
||||
listServiceAccounts = false
|
||||
case madmin.AccessKeyListSTSOnly:
|
||||
listSTSKeys = true
|
||||
listServiceAccounts = false
|
||||
case madmin.AccessKeyListSvcaccOnly:
|
||||
listSTSKeys = false
|
||||
listServiceAccounts = true
|
||||
case madmin.AccessKeyListAll:
|
||||
listSTSKeys = true
|
||||
listServiceAccounts = true
|
||||
default:
|
||||
err := errors.New("invalid list type")
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErrWithErr(ErrInvalidRequest, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
s := globalServerConfig.Clone()
|
||||
roleArnMap := make(map[string]string)
|
||||
// Map of configs to a map of users to their access keys
|
||||
cfgToUsersMap := make(map[string]map[string]madmin.OpenIDUserAccessKeys)
|
||||
configs, err := globalIAMSys.OpenIDConfig.GetConfigList(s)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
for _, config := range configs {
|
||||
if !allConfigs && cfgName != config.Name {
|
||||
continue
|
||||
}
|
||||
arn := dummyRoleARN
|
||||
if config.RoleARN != "" {
|
||||
arn = config.RoleARN
|
||||
}
|
||||
roleArnMap[arn] = config.Name
|
||||
newResp := make(map[string]madmin.OpenIDUserAccessKeys)
|
||||
cfgToUsersMap[config.Name] = newResp
|
||||
}
|
||||
if len(roleArnMap) == 0 {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminNoSuchConfigTarget), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
userSet := set.CreateStringSet(userList...)
|
||||
accessKeys, err := globalIAMSys.ListAllAccessKeys(ctx)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
for _, accessKey := range accessKeys {
|
||||
// Filter out any disqualifying access keys
|
||||
_, ok := accessKey.Claims[subClaim]
|
||||
if !ok {
|
||||
continue // OpenID access keys must have a sub claim
|
||||
}
|
||||
if (!listSTSKeys && !accessKey.IsServiceAccount()) || (!listServiceAccounts && accessKey.IsServiceAccount()) {
|
||||
continue // skip if not the type we want
|
||||
}
|
||||
arn, ok := accessKey.Claims[roleArnClaim].(string)
|
||||
if !ok {
|
||||
if _, ok := accessKey.Claims[iamPolicyClaimNameOpenID()]; !ok {
|
||||
continue // skip if no roleArn and no policy claim
|
||||
}
|
||||
}
|
||||
matchingCfgName, ok := roleArnMap[arn]
|
||||
if !ok {
|
||||
continue // skip if not part of the target config
|
||||
}
|
||||
var id string
|
||||
if idClaim := globalIAMSys.OpenIDConfig.GetUserIDClaim(matchingCfgName); idClaim != "" {
|
||||
id, _ = accessKey.Claims[idClaim].(string)
|
||||
}
|
||||
if !userSet.IsEmpty() && !userSet.Contains(accessKey.ParentUser) && !userSet.Contains(id) {
|
||||
continue // skip if not in the user list
|
||||
}
|
||||
openIDUserAccessKeys, ok := cfgToUsersMap[matchingCfgName][accessKey.ParentUser]
|
||||
|
||||
// Add new user to map if not already present
|
||||
if !ok {
|
||||
var readableClaim string
|
||||
if rc := globalIAMSys.OpenIDConfig.GetUserReadableClaim(matchingCfgName); rc != "" {
|
||||
readableClaim, _ = accessKey.Claims[rc].(string)
|
||||
}
|
||||
openIDUserAccessKeys = madmin.OpenIDUserAccessKeys{
|
||||
MinioAccessKey: accessKey.ParentUser,
|
||||
ID: id,
|
||||
ReadableName: readableClaim,
|
||||
}
|
||||
}
|
||||
svcAccInfo := madmin.ServiceAccountInfo{
|
||||
AccessKey: accessKey.AccessKey,
|
||||
Expiration: &accessKey.Expiration,
|
||||
}
|
||||
if accessKey.IsServiceAccount() {
|
||||
openIDUserAccessKeys.ServiceAccounts = append(openIDUserAccessKeys.ServiceAccounts, svcAccInfo)
|
||||
} else {
|
||||
openIDUserAccessKeys.STSKeys = append(openIDUserAccessKeys.STSKeys, svcAccInfo)
|
||||
}
|
||||
cfgToUsersMap[matchingCfgName][accessKey.ParentUser] = openIDUserAccessKeys
|
||||
}
|
||||
|
||||
// Convert map to slice and sort
|
||||
resp := make([]madmin.ListAccessKeysOpenIDResp, 0, len(cfgToUsersMap))
|
||||
for cfgName, usersMap := range cfgToUsersMap {
|
||||
users := make([]madmin.OpenIDUserAccessKeys, 0, len(usersMap))
|
||||
for _, user := range usersMap {
|
||||
users = append(users, user)
|
||||
}
|
||||
sort.Slice(users, func(i, j int) bool {
|
||||
return users[i].MinioAccessKey < users[j].MinioAccessKey
|
||||
})
|
||||
resp = append(resp, madmin.ListAccessKeysOpenIDResp{
|
||||
ConfigName: cfgName,
|
||||
Users: users,
|
||||
})
|
||||
}
|
||||
sort.Slice(resp, func(i, j int) bool {
|
||||
return resp[i].ConfigName < resp[j].ConfigName
|
||||
})
|
||||
|
||||
data, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
encryptedData, err := madmin.EncryptData(cred.SecretKey, data)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
writeSuccessResponseJSON(w, encryptedData)
|
||||
}
|
||||
@@ -2068,6 +2068,149 @@ func (a adminAPIHandlers) RevokeTokens(w http.ResponseWriter, r *http.Request) {
|
||||
writeSuccessNoContent(w)
|
||||
}
|
||||
|
||||
// InfoAccessKey - GET /minio/admin/v3/info-access-key?access-key=<access-key>
|
||||
func (a adminAPIHandlers) InfoAccessKey(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || globalNotificationSys == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
cred, owner, s3Err := validateAdminSignature(ctx, r, "")
|
||||
if s3Err != ErrNone {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
accessKey := mux.Vars(r)["accessKey"]
|
||||
if accessKey == "" {
|
||||
accessKey = cred.AccessKey
|
||||
}
|
||||
|
||||
u, ok := globalIAMSys.GetUser(ctx, accessKey)
|
||||
targetCred := u.Credentials
|
||||
|
||||
if !globalIAMSys.IsAllowed(policy.Args{
|
||||
AccountName: cred.AccessKey,
|
||||
Groups: cred.Groups,
|
||||
Action: policy.ListServiceAccountsAdminAction,
|
||||
ConditionValues: getConditionValues(r, "", cred),
|
||||
IsOwner: owner,
|
||||
Claims: cred.Claims,
|
||||
}) {
|
||||
// If requested user does not exist and requestor is not allowed to list service accounts, return access denied.
|
||||
if !ok {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
requestUser := cred.AccessKey
|
||||
if cred.ParentUser != "" {
|
||||
requestUser = cred.ParentUser
|
||||
}
|
||||
|
||||
if requestUser != targetCred.ParentUser {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !ok {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminNoSuchAccessKey), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
sessionPolicy *policy.Policy
|
||||
err error
|
||||
userType string
|
||||
)
|
||||
switch {
|
||||
case targetCred.IsTemp():
|
||||
userType = "STS"
|
||||
_, sessionPolicy, err = globalIAMSys.GetTemporaryAccount(ctx, accessKey)
|
||||
if err == errNoSuchTempAccount {
|
||||
err = errNoSuchAccessKey
|
||||
}
|
||||
case targetCred.IsServiceAccount():
|
||||
userType = "Service Account"
|
||||
_, sessionPolicy, err = globalIAMSys.GetServiceAccount(ctx, accessKey)
|
||||
if err == errNoSuchServiceAccount {
|
||||
err = errNoSuchAccessKey
|
||||
}
|
||||
default:
|
||||
err = errNoSuchAccessKey
|
||||
}
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
// if session policy is nil or empty, then it is implied policy
|
||||
impliedPolicy := sessionPolicy == nil || (sessionPolicy.Version == "" && len(sessionPolicy.Statements) == 0)
|
||||
|
||||
var svcAccountPolicy policy.Policy
|
||||
|
||||
if !impliedPolicy {
|
||||
svcAccountPolicy = *sessionPolicy
|
||||
} else {
|
||||
policiesNames, err := globalIAMSys.PolicyDBGet(targetCred.ParentUser, targetCred.Groups...)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
svcAccountPolicy = globalIAMSys.GetCombinedPolicy(policiesNames...)
|
||||
}
|
||||
|
||||
policyJSON, err := json.MarshalIndent(svcAccountPolicy, "", " ")
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
var expiration *time.Time
|
||||
if !targetCred.Expiration.IsZero() && !targetCred.Expiration.Equal(timeSentinel) {
|
||||
expiration = &targetCred.Expiration
|
||||
}
|
||||
|
||||
userProvider := guessUserProvider(targetCred)
|
||||
|
||||
infoResp := madmin.InfoAccessKeyResp{
|
||||
AccessKey: accessKey,
|
||||
InfoServiceAccountResp: madmin.InfoServiceAccountResp{
|
||||
ParentUser: targetCred.ParentUser,
|
||||
Name: targetCred.Name,
|
||||
Description: targetCred.Description,
|
||||
AccountStatus: targetCred.Status,
|
||||
ImpliedPolicy: impliedPolicy,
|
||||
Policy: string(policyJSON),
|
||||
Expiration: expiration,
|
||||
},
|
||||
|
||||
UserType: userType,
|
||||
UserProvider: userProvider,
|
||||
}
|
||||
|
||||
populateProviderInfoFromClaims(targetCred.Claims, userProvider, &infoResp)
|
||||
|
||||
data, err := json.Marshal(infoResp)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
encryptedData, err := madmin.EncryptData(cred.SecretKey, data)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
writeSuccessResponseJSON(w, encryptedData)
|
||||
}
|
||||
|
||||
const (
|
||||
allPoliciesFile = "policies.json"
|
||||
allUsersFile = "users.json"
|
||||
|
||||
@@ -263,7 +263,7 @@ func buildAdminRequest(queryVal url.Values, method, path string,
|
||||
}
|
||||
|
||||
func TestAdminServerInfo(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
adminTestBed, err := prepareAdminErasureTestBed(ctx)
|
||||
|
||||
@@ -246,6 +246,7 @@ func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
|
||||
|
||||
// Access key (service account/STS) operations
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-access-keys-bulk").HandlerFunc(adminMiddleware(adminAPI.ListAccessKeysBulk)).Queries("listType", "{listType:.*}")
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/info-access-key").HandlerFunc(adminMiddleware(adminAPI.InfoAccessKey)).Queries("accessKey", "{accessKey:.*}")
|
||||
|
||||
// Info policy IAM latest
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/info-canned-policy").HandlerFunc(adminMiddleware(adminAPI.InfoCannedPolicy)).Queries("name", "{name:.*}")
|
||||
@@ -312,6 +313,11 @@ func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
|
||||
// LDAP IAM operations
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/idp/ldap/policy-entities").HandlerFunc(adminMiddleware(adminAPI.ListLDAPPolicyMappingEntities))
|
||||
adminRouter.Methods(http.MethodPost).Path(adminVersion + "/idp/ldap/policy/{operation}").HandlerFunc(adminMiddleware(adminAPI.AttachDetachPolicyLDAP))
|
||||
|
||||
// OpenID specific service accounts ops
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/idp/openid/list-access-keys-bulk").
|
||||
HandlerFunc(adminMiddleware(adminAPI.ListAccessKeysOpenIDBulk)).Queries("listType", "{listType:.*}")
|
||||
|
||||
// -- END IAM APIs --
|
||||
|
||||
// GetBucketQuotaConfig
|
||||
|
||||
@@ -215,6 +215,8 @@ const (
|
||||
ErrExcessData
|
||||
ErrPolicyInvalidName
|
||||
ErrNoTokenRevokeType
|
||||
ErrAdminOpenIDNotEnabled
|
||||
ErrAdminNoSuchAccessKey
|
||||
// Add new error codes here.
|
||||
|
||||
// SSE-S3/SSE-KMS related API errors
|
||||
@@ -568,6 +570,11 @@ var errorCodes = errorCodeMap{
|
||||
Description: "Policy name may not contain comma",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrAdminOpenIDNotEnabled: {
|
||||
Code: "OpenIDNotEnabled",
|
||||
Description: "No enabled OpenID Connect identity providers",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrPolicyTooLarge: {
|
||||
Code: "PolicyTooLarge",
|
||||
Description: "Policy exceeds the maximum allowed document size.",
|
||||
@@ -1270,6 +1277,11 @@ var errorCodes = errorCodeMap{
|
||||
Description: "No token revoke type specified and one could not be inferred from the request",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrAdminNoSuchAccessKey: {
|
||||
Code: "XMinioAdminNoSuchAccessKey",
|
||||
Description: "The specified access key does not exist.",
|
||||
HTTPStatusCode: http.StatusNotFound,
|
||||
},
|
||||
|
||||
// S3 extensions.
|
||||
ErrContentSHA256Mismatch: {
|
||||
@@ -2167,6 +2179,8 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) {
|
||||
apiErr = ErrAdminNoSuchUserLDAPWarn
|
||||
case errNoSuchServiceAccount:
|
||||
apiErr = ErrAdminServiceAccountNotFound
|
||||
case errNoSuchAccessKey:
|
||||
apiErr = ErrAdminNoSuchAccessKey
|
||||
case errNoSuchGroup:
|
||||
apiErr = ErrAdminNoSuchGroup
|
||||
case errGroupNotEmpty:
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
@@ -64,7 +63,7 @@ var toAPIErrorTests = []struct {
|
||||
}
|
||||
|
||||
func TestAPIErrCode(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
for i, testCase := range toAPIErrorTests {
|
||||
errCode := toAPIErrorCode(ctx, testCase.err)
|
||||
if errCode != testCase.errCode {
|
||||
|
||||
+201
-199
File diff suppressed because one or more lines are too long
@@ -413,7 +413,7 @@ func TestIsReqAuthenticated(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCheckAdminRequestAuthType(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
objLayer, fsDir, err := prepareFS(ctx)
|
||||
@@ -450,7 +450,7 @@ func TestCheckAdminRequestAuthType(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateAdminSignature(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
objLayer, fsDir, err := prepareFS(ctx)
|
||||
|
||||
+104
-68
@@ -424,12 +424,12 @@ func batchObjsForDelete(ctx context.Context, r *BatchJobExpire, ri *batchJobInfo
|
||||
go func(toExpire []expireObjInfo) {
|
||||
defer wk.Give()
|
||||
|
||||
toExpireAll := make([]ObjectInfo, 0, len(toExpire))
|
||||
toExpireAll := make([]expireObjInfo, 0, len(toExpire))
|
||||
toDel := make([]ObjectToDelete, 0, len(toExpire))
|
||||
oiCache := newObjInfoCache()
|
||||
for _, exp := range toExpire {
|
||||
if exp.ExpireAll {
|
||||
toExpireAll = append(toExpireAll, exp.ObjectInfo)
|
||||
toExpireAll = append(toExpireAll, exp)
|
||||
continue
|
||||
}
|
||||
// Cache ObjectInfo value via pointers for
|
||||
@@ -527,7 +527,8 @@ func batchObjsForDelete(ctx context.Context, r *BatchJobExpire, ri *batchJobInfo
|
||||
|
||||
type expireObjInfo struct {
|
||||
ObjectInfo
|
||||
ExpireAll bool
|
||||
ExpireAll bool
|
||||
DeleteMarkerCount int64
|
||||
}
|
||||
|
||||
// Start the batch expiration job, resumes if there was a pending job via "job.ID"
|
||||
@@ -624,80 +625,115 @@ func (r *BatchJobExpire) Start(ctx context.Context, api ObjectLayer, job BatchJo
|
||||
matchedFilter BatchJobExpireFilter
|
||||
versionsCount int
|
||||
toDel []expireObjInfo
|
||||
failed bool
|
||||
done bool
|
||||
)
|
||||
failed := false
|
||||
for result := range results {
|
||||
if result.Err != nil {
|
||||
failed = true
|
||||
batchLogIf(ctx, result.Err)
|
||||
continue
|
||||
deleteMarkerCountMap := map[string]int64{}
|
||||
pushToExpire := func() {
|
||||
// set preObject deleteMarkerCount
|
||||
if len(toDel) > 0 {
|
||||
lastDelIndex := len(toDel) - 1
|
||||
lastDel := toDel[lastDelIndex]
|
||||
if lastDel.ExpireAll {
|
||||
toDel[lastDelIndex].DeleteMarkerCount = deleteMarkerCountMap[lastDel.Name]
|
||||
// delete the key
|
||||
delete(deleteMarkerCountMap, lastDel.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply filter to find the matching rule to apply expiry
|
||||
// actions accordingly.
|
||||
// nolint:gocritic
|
||||
if result.Item.IsLatest {
|
||||
// send down filtered entries to be deleted using
|
||||
// DeleteObjects method
|
||||
if len(toDel) > 10 { // batch up to 10 objects/versions to be expired simultaneously.
|
||||
xfer := make([]expireObjInfo, len(toDel))
|
||||
copy(xfer, toDel)
|
||||
|
||||
var done bool
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
done = true
|
||||
case expireCh <- xfer:
|
||||
toDel = toDel[:0] // resetting toDel
|
||||
}
|
||||
if done {
|
||||
break
|
||||
}
|
||||
// send down filtered entries to be deleted using
|
||||
// DeleteObjects method
|
||||
if len(toDel) > 10 { // batch up to 10 objects/versions to be expired simultaneously.
|
||||
xfer := make([]expireObjInfo, len(toDel))
|
||||
copy(xfer, toDel)
|
||||
select {
|
||||
case expireCh <- xfer:
|
||||
toDel = toDel[:0] // resetting toDel
|
||||
case <-ctx.Done():
|
||||
done = true
|
||||
}
|
||||
var match BatchJobExpireFilter
|
||||
var found bool
|
||||
for _, rule := range r.Rules {
|
||||
if rule.Matches(result.Item, now) {
|
||||
match = rule
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
prevObj = result.Item
|
||||
matchedFilter = match
|
||||
versionsCount = 1
|
||||
// Include the latest version
|
||||
if matchedFilter.Purge.RetainVersions == 0 {
|
||||
toDel = append(toDel, expireObjInfo{
|
||||
ObjectInfo: result.Item,
|
||||
ExpireAll: true,
|
||||
})
|
||||
continue
|
||||
}
|
||||
} else if prevObj.Name == result.Item.Name {
|
||||
if matchedFilter.Purge.RetainVersions == 0 {
|
||||
continue // including latest version in toDel suffices, skipping other versions
|
||||
}
|
||||
versionsCount++
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
|
||||
if versionsCount <= matchedFilter.Purge.RetainVersions {
|
||||
continue // retain versions
|
||||
}
|
||||
toDel = append(toDel, expireObjInfo{
|
||||
ObjectInfo: result.Item,
|
||||
})
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case result, ok := <-results:
|
||||
if !ok {
|
||||
done = true
|
||||
break
|
||||
}
|
||||
if result.Err != nil {
|
||||
failed = true
|
||||
batchLogIf(ctx, result.Err)
|
||||
continue
|
||||
}
|
||||
if result.Item.DeleteMarker {
|
||||
deleteMarkerCountMap[result.Item.Name]++
|
||||
}
|
||||
// Apply filter to find the matching rule to apply expiry
|
||||
// actions accordingly.
|
||||
// nolint:gocritic
|
||||
if result.Item.IsLatest {
|
||||
var match BatchJobExpireFilter
|
||||
var found bool
|
||||
for _, rule := range r.Rules {
|
||||
if rule.Matches(result.Item, now) {
|
||||
match = rule
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
if prevObj.Name != result.Item.Name {
|
||||
// switch the object
|
||||
pushToExpire()
|
||||
}
|
||||
|
||||
prevObj = result.Item
|
||||
matchedFilter = match
|
||||
versionsCount = 1
|
||||
// Include the latest version
|
||||
if matchedFilter.Purge.RetainVersions == 0 {
|
||||
toDel = append(toDel, expireObjInfo{
|
||||
ObjectInfo: result.Item,
|
||||
ExpireAll: true,
|
||||
})
|
||||
continue
|
||||
}
|
||||
} else if prevObj.Name == result.Item.Name {
|
||||
if matchedFilter.Purge.RetainVersions == 0 {
|
||||
continue // including latest version in toDel suffices, skipping other versions
|
||||
}
|
||||
versionsCount++
|
||||
} else {
|
||||
// switch the object
|
||||
pushToExpire()
|
||||
// a file switched with no LatestVersion, logging it
|
||||
batchLogIf(ctx, fmt.Errorf("skipping object %s, no latest version found", result.Item.Name))
|
||||
continue
|
||||
}
|
||||
|
||||
if versionsCount <= matchedFilter.Purge.RetainVersions {
|
||||
continue // retain versions
|
||||
}
|
||||
toDel = append(toDel, expireObjInfo{
|
||||
ObjectInfo: result.Item,
|
||||
})
|
||||
pushToExpire()
|
||||
case <-ctx.Done():
|
||||
done = true
|
||||
}
|
||||
if done {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if context.Cause(ctx) != nil {
|
||||
xioutil.SafeClose(expireCh)
|
||||
return context.Cause(ctx)
|
||||
}
|
||||
pushToExpire()
|
||||
// Send any remaining objects downstream
|
||||
if len(toDel) > 0 {
|
||||
select {
|
||||
|
||||
+36
-28
@@ -881,21 +881,23 @@ func (ri *batchJobInfo) clone() *batchJobInfo {
|
||||
defer ri.mu.RUnlock()
|
||||
|
||||
return &batchJobInfo{
|
||||
Version: ri.Version,
|
||||
JobID: ri.JobID,
|
||||
JobType: ri.JobType,
|
||||
RetryAttempts: ri.RetryAttempts,
|
||||
Complete: ri.Complete,
|
||||
Failed: ri.Failed,
|
||||
StartTime: ri.StartTime,
|
||||
LastUpdate: ri.LastUpdate,
|
||||
Bucket: ri.Bucket,
|
||||
Object: ri.Object,
|
||||
Objects: ri.Objects,
|
||||
ObjectsFailed: ri.ObjectsFailed,
|
||||
BytesTransferred: ri.BytesTransferred,
|
||||
BytesFailed: ri.BytesFailed,
|
||||
Attempts: ri.Attempts,
|
||||
Version: ri.Version,
|
||||
JobID: ri.JobID,
|
||||
JobType: ri.JobType,
|
||||
RetryAttempts: ri.RetryAttempts,
|
||||
Complete: ri.Complete,
|
||||
Failed: ri.Failed,
|
||||
StartTime: ri.StartTime,
|
||||
LastUpdate: ri.LastUpdate,
|
||||
Bucket: ri.Bucket,
|
||||
Object: ri.Object,
|
||||
Objects: ri.Objects,
|
||||
ObjectsFailed: ri.ObjectsFailed,
|
||||
DeleteMarkers: ri.DeleteMarkers,
|
||||
DeleteMarkersFailed: ri.DeleteMarkersFailed,
|
||||
BytesTransferred: ri.BytesTransferred,
|
||||
BytesFailed: ri.BytesFailed,
|
||||
Attempts: ri.Attempts,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -994,11 +996,13 @@ func (ri *batchJobInfo) updateAfter(ctx context.Context, api ObjectLayer, durati
|
||||
// Note: to be used only with batch jobs that affect multiple versions through
|
||||
// a single action. e.g batch-expire has an option to expire all versions of an
|
||||
// object which matches the given filters.
|
||||
func (ri *batchJobInfo) trackMultipleObjectVersions(info ObjectInfo, success bool) {
|
||||
func (ri *batchJobInfo) trackMultipleObjectVersions(info expireObjInfo, success bool) {
|
||||
if success {
|
||||
ri.Objects += int64(info.NumVersions)
|
||||
ri.Objects += int64(info.NumVersions) - info.DeleteMarkerCount
|
||||
ri.DeleteMarkers += info.DeleteMarkerCount
|
||||
} else {
|
||||
ri.ObjectsFailed += int64(info.NumVersions)
|
||||
ri.ObjectsFailed += int64(info.NumVersions) - info.DeleteMarkerCount
|
||||
ri.DeleteMarkersFailed += info.DeleteMarkerCount
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2134,12 +2138,14 @@ func (ri *batchJobInfo) metric() madmin.JobMetric {
|
||||
switch ri.JobType {
|
||||
case string(madmin.BatchJobReplicate):
|
||||
m.Replicate = &madmin.ReplicateInfo{
|
||||
Bucket: ri.Bucket,
|
||||
Object: ri.Object,
|
||||
Objects: ri.Objects,
|
||||
ObjectsFailed: ri.ObjectsFailed,
|
||||
BytesTransferred: ri.BytesTransferred,
|
||||
BytesFailed: ri.BytesFailed,
|
||||
Bucket: ri.Bucket,
|
||||
Object: ri.Object,
|
||||
Objects: ri.Objects,
|
||||
DeleteMarkers: ri.DeleteMarkers,
|
||||
ObjectsFailed: ri.ObjectsFailed,
|
||||
DeleteMarkersFailed: ri.DeleteMarkersFailed,
|
||||
BytesTransferred: ri.BytesTransferred,
|
||||
BytesFailed: ri.BytesFailed,
|
||||
}
|
||||
case string(madmin.BatchJobKeyRotate):
|
||||
m.KeyRotate = &madmin.KeyRotationInfo{
|
||||
@@ -2150,10 +2156,12 @@ func (ri *batchJobInfo) metric() madmin.JobMetric {
|
||||
}
|
||||
case string(madmin.BatchJobExpire):
|
||||
m.Expired = &madmin.ExpirationInfo{
|
||||
Bucket: ri.Bucket,
|
||||
Object: ri.Object,
|
||||
Objects: ri.Objects,
|
||||
ObjectsFailed: ri.ObjectsFailed,
|
||||
Bucket: ri.Bucket,
|
||||
Object: ri.Object,
|
||||
Objects: ri.Objects,
|
||||
DeleteMarkers: ri.DeleteMarkers,
|
||||
ObjectsFailed: ri.ObjectsFailed,
|
||||
DeleteMarkersFailed: ri.DeleteMarkersFailed,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -35,7 +35,7 @@ func runPutObjectBenchmark(b *testing.B, obj ObjectLayer, objSize int) {
|
||||
// obtains random bucket name.
|
||||
bucket := getRandomBucketName()
|
||||
// create bucket.
|
||||
err = obj.MakeBucket(context.Background(), bucket, MakeBucketOptions{})
|
||||
err = obj.MakeBucket(b.Context(), bucket, MakeBucketOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -54,7 +54,7 @@ func runPutObjectBenchmark(b *testing.B, obj ObjectLayer, objSize int) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
// insert the object.
|
||||
objInfo, err := obj.PutObject(context.Background(), bucket, "object"+strconv.Itoa(i),
|
||||
objInfo, err := obj.PutObject(b.Context(), bucket, "object"+strconv.Itoa(i),
|
||||
mustGetPutObjReader(b, bytes.NewReader(textData), int64(len(textData)), md5hex, sha256hex), ObjectOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
@@ -76,7 +76,7 @@ func runPutObjectPartBenchmark(b *testing.B, obj ObjectLayer, partSize int) {
|
||||
object := getRandomObjectName()
|
||||
|
||||
// create bucket.
|
||||
err = obj.MakeBucket(context.Background(), bucket, MakeBucketOptions{})
|
||||
err = obj.MakeBucket(b.Context(), bucket, MakeBucketOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func runPutObjectPartBenchmark(b *testing.B, obj ObjectLayer, partSize int) {
|
||||
textData := generateBytesData(objSize)
|
||||
// generate md5sum for the generated data.
|
||||
// md5sum of the data to written is required as input for NewMultipartUpload.
|
||||
res, err := obj.NewMultipartUpload(context.Background(), bucket, object, ObjectOptions{})
|
||||
res, err := obj.NewMultipartUpload(b.Context(), bucket, object, ObjectOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -113,7 +113,7 @@ func runPutObjectPartBenchmark(b *testing.B, obj ObjectLayer, partSize int) {
|
||||
}
|
||||
md5hex := getMD5Hash(textPartData)
|
||||
var partInfo PartInfo
|
||||
partInfo, err = obj.PutObjectPart(context.Background(), bucket, object, res.UploadID, j,
|
||||
partInfo, err = obj.PutObjectPart(b.Context(), bucket, object, res.UploadID, j,
|
||||
mustGetPutObjReader(b, bytes.NewReader(textPartData), int64(len(textPartData)), md5hex, sha256hex), ObjectOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
@@ -130,7 +130,7 @@ func runPutObjectPartBenchmark(b *testing.B, obj ObjectLayer, partSize int) {
|
||||
// creates Erasure/FS backend setup, obtains the object layer and calls the runPutObjectPartBenchmark function.
|
||||
func benchmarkPutObjectPart(b *testing.B, instanceType string, objSize int) {
|
||||
// create a temp Erasure/FS backend.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(b.Context())
|
||||
defer cancel()
|
||||
objLayer, disks, err := prepareTestBackend(ctx, instanceType)
|
||||
if err != nil {
|
||||
@@ -146,7 +146,7 @@ func benchmarkPutObjectPart(b *testing.B, instanceType string, objSize int) {
|
||||
// creates Erasure/FS backend setup, obtains the object layer and calls the runPutObjectBenchmark function.
|
||||
func benchmarkPutObject(b *testing.B, instanceType string, objSize int) {
|
||||
// create a temp Erasure/FS backend.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(b.Context())
|
||||
defer cancel()
|
||||
objLayer, disks, err := prepareTestBackend(ctx, instanceType)
|
||||
if err != nil {
|
||||
@@ -162,7 +162,7 @@ func benchmarkPutObject(b *testing.B, instanceType string, objSize int) {
|
||||
// creates Erasure/FS backend setup, obtains the object layer and runs parallel benchmark for put object.
|
||||
func benchmarkPutObjectParallel(b *testing.B, instanceType string, objSize int) {
|
||||
// create a temp Erasure/FS backend.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(b.Context())
|
||||
defer cancel()
|
||||
objLayer, disks, err := prepareTestBackend(ctx, instanceType)
|
||||
if err != nil {
|
||||
@@ -196,7 +196,7 @@ func runPutObjectBenchmarkParallel(b *testing.B, obj ObjectLayer, objSize int) {
|
||||
// obtains random bucket name.
|
||||
bucket := getRandomBucketName()
|
||||
// create bucket.
|
||||
err := obj.MakeBucket(context.Background(), bucket, MakeBucketOptions{})
|
||||
err := obj.MakeBucket(b.Context(), bucket, MakeBucketOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -218,7 +218,7 @@ func runPutObjectBenchmarkParallel(b *testing.B, obj ObjectLayer, objSize int) {
|
||||
i := 0
|
||||
for pb.Next() {
|
||||
// insert the object.
|
||||
objInfo, err := obj.PutObject(context.Background(), bucket, "object"+strconv.Itoa(i),
|
||||
objInfo, err := obj.PutObject(b.Context(), bucket, "object"+strconv.Itoa(i),
|
||||
mustGetPutObjReader(b, bytes.NewReader(textData), int64(len(textData)), md5hex, sha256hex), ObjectOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
@@ -34,7 +33,7 @@ func testBitrotReaderWriterAlgo(t *testing.T, bitrotAlgo BitrotAlgorithm) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
disk.MakeVol(context.Background(), volume)
|
||||
disk.MakeVol(t.Context(), volume)
|
||||
|
||||
writer := newBitrotWriter(disk, "", volume, filePath, 35, bitrotAlgo, 10)
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/minio/internal/bucket/replication"
|
||||
@@ -184,7 +183,7 @@ var parseReplicationDecisionTest = []struct {
|
||||
|
||||
func TestParseReplicateDecision(t *testing.T) {
|
||||
for i, test := range parseReplicationDecisionTest {
|
||||
dsc, err := parseReplicateDecision(context.Background(), "bucket", test.expDsc.String())
|
||||
dsc, err := parseReplicateDecision(t.Context(), "bucket", test.expDsc.String())
|
||||
if err != nil {
|
||||
if test.expErr != err {
|
||||
t.Errorf("Test%d (%s): Expected parse error got %t , want %t", i+1, test.name, err, test.expErr)
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
@@ -86,7 +85,7 @@ var replicationConfigTests = []struct {
|
||||
}
|
||||
|
||||
func TestReplicationResync(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
for i, test := range replicationConfigTests {
|
||||
if sync := test.rcfg.Resync(ctx, test.info, test.dsc, test.tgtStatuses); sync.mustResync() != test.expectedSync {
|
||||
t.Errorf("Test%d (%s): Resync got %t , want %t", i+1, test.name, sync.mustResync(), test.expectedSync)
|
||||
|
||||
+58
-29
@@ -47,6 +47,7 @@ import (
|
||||
"github.com/minio/console/api/operations"
|
||||
consoleoauth2 "github.com/minio/console/pkg/auth/idp/oauth2"
|
||||
consoleCerts "github.com/minio/console/pkg/certs"
|
||||
"github.com/minio/kms-go/kes"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/set"
|
||||
@@ -831,55 +832,83 @@ func serverHandleEnvVars() {
|
||||
globalEnableSyncBoot = env.Get("MINIO_SYNC_BOOT", config.EnableOff) == config.EnableOn
|
||||
}
|
||||
|
||||
func loadRootCredentials() {
|
||||
func loadRootCredentials() auth.Credentials {
|
||||
// At this point, either both environment variables
|
||||
// are defined or both are not defined.
|
||||
// Check both cases and authenticate them if correctly defined
|
||||
var user, password string
|
||||
var hasCredentials bool
|
||||
var legacyCredentials bool
|
||||
//nolint:gocritic
|
||||
if env.IsSet(config.EnvRootUser) && env.IsSet(config.EnvRootPassword) {
|
||||
user = env.Get(config.EnvRootUser, "")
|
||||
password = env.Get(config.EnvRootPassword, "")
|
||||
hasCredentials = true
|
||||
} else if env.IsSet(config.EnvAccessKey) && env.IsSet(config.EnvSecretKey) {
|
||||
user = env.Get(config.EnvAccessKey, "")
|
||||
password = env.Get(config.EnvSecretKey, "")
|
||||
legacyCredentials = true
|
||||
hasCredentials = true
|
||||
} else if globalServerCtxt.RootUser != "" && globalServerCtxt.RootPwd != "" {
|
||||
user, password = globalServerCtxt.RootUser, globalServerCtxt.RootPwd
|
||||
hasCredentials = true
|
||||
}
|
||||
if hasCredentials {
|
||||
cred, err := auth.CreateCredentials(user, password)
|
||||
if err != nil {
|
||||
if legacyCredentials {
|
||||
logger.Fatal(config.ErrInvalidCredentials(err),
|
||||
"Unable to validate credentials inherited from the shell environment")
|
||||
} else {
|
||||
logger.Fatal(config.ErrInvalidRootUserCredentials(err),
|
||||
"Unable to validate credentials inherited from the shell environment")
|
||||
}
|
||||
if user == "" || password == "" {
|
||||
return auth.Credentials{}
|
||||
}
|
||||
cred, err := auth.CreateCredentials(user, password)
|
||||
if err != nil {
|
||||
if legacyCredentials {
|
||||
logger.Fatal(config.ErrInvalidCredentials(err),
|
||||
"Unable to validate credentials inherited from the shell environment")
|
||||
} else {
|
||||
logger.Fatal(config.ErrInvalidRootUserCredentials(err),
|
||||
"Unable to validate credentials inherited from the shell environment")
|
||||
}
|
||||
if env.IsSet(config.EnvAccessKey) && env.IsSet(config.EnvSecretKey) {
|
||||
msg := fmt.Sprintf("WARNING: %s and %s are deprecated.\n"+
|
||||
" Please use %s and %s",
|
||||
config.EnvAccessKey, config.EnvSecretKey,
|
||||
config.EnvRootUser, config.EnvRootPassword)
|
||||
logger.Info(color.RedBold(msg))
|
||||
}
|
||||
globalActiveCred = cred
|
||||
globalCredViaEnv = true
|
||||
} else {
|
||||
globalActiveCred = auth.DefaultCredentials
|
||||
}
|
||||
if env.IsSet(config.EnvAccessKey) && env.IsSet(config.EnvSecretKey) {
|
||||
msg := fmt.Sprintf("WARNING: %s and %s are deprecated.\n"+
|
||||
" Please use %s and %s",
|
||||
config.EnvAccessKey, config.EnvSecretKey,
|
||||
config.EnvRootUser, config.EnvRootPassword)
|
||||
logger.Info(color.RedBold(msg))
|
||||
}
|
||||
globalCredViaEnv = true
|
||||
return cred
|
||||
}
|
||||
|
||||
// autoGenerateRootCredentials generates root credentials deterministically if
|
||||
// a KMS is configured, no manual credentials have been specified and if root
|
||||
// access is disabled.
|
||||
func autoGenerateRootCredentials() auth.Credentials {
|
||||
if GlobalKMS == nil {
|
||||
return globalActiveCred
|
||||
}
|
||||
|
||||
var err error
|
||||
globalNodeAuthToken, err = authenticateNode(globalActiveCred.AccessKey, globalActiveCred.SecretKey)
|
||||
aKey, err := GlobalKMS.MAC(GlobalContext, &kms.MACRequest{Message: []byte("root access key")})
|
||||
if IsErrIgnored(err, kes.ErrNotAllowed, kms.ErrNotSupported, errors.ErrUnsupported, kms.ErrPermission) {
|
||||
// If we don't have permission to compute the HMAC, don't change the cred.
|
||||
return globalActiveCred
|
||||
}
|
||||
if err != nil {
|
||||
logger.Fatal(err, "Unable to generate internode credentials")
|
||||
logger.Fatal(err, "Unable to generate root access key using KMS")
|
||||
}
|
||||
|
||||
sKey, err := GlobalKMS.MAC(GlobalContext, &kms.MACRequest{Message: []byte("root secret key")})
|
||||
if err != nil {
|
||||
// Here, we must have permission. Otherwise, we would have failed earlier.
|
||||
logger.Fatal(err, "Unable to generate root secret key using KMS")
|
||||
}
|
||||
|
||||
accessKey, err := auth.GenerateAccessKey(20, bytes.NewReader(aKey))
|
||||
if err != nil {
|
||||
logger.Fatal(err, "Unable to generate root access key")
|
||||
}
|
||||
secretKey, err := auth.GenerateSecretKey(32, bytes.NewReader(sKey))
|
||||
if err != nil {
|
||||
logger.Fatal(err, "Unable to generate root secret key")
|
||||
}
|
||||
|
||||
logger.Info("Automatically generated root access key and secret key with the KMS")
|
||||
return auth.Credentials{
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,17 +18,13 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/minio/kms-go/kes"
|
||||
"github.com/minio/minio/internal/auth"
|
||||
"github.com/minio/minio/internal/config/browser"
|
||||
"github.com/minio/minio/internal/kms"
|
||||
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/minio/minio/internal/config"
|
||||
@@ -570,7 +566,6 @@ func applyDynamicConfigForSubSys(ctx context.Context, objAPI ObjectLayer, s conf
|
||||
}
|
||||
|
||||
globalAPIConfig.init(apiConfig, setDriveCounts, objAPI.Legacy())
|
||||
autoGenerateRootCredentials() // Generate the KMS root credentials here since we don't know whether API root access is disabled until now.
|
||||
setRemoteInstanceTransport(NewHTTPTransportWithTimeout(apiConfig.RemoteTransportDeadline))
|
||||
case config.CompressionSubSys:
|
||||
cmpCfg, err := compress.LookupConfig(s[config.CompressionSubSys][config.Default])
|
||||
@@ -729,47 +724,6 @@ func applyDynamicConfigForSubSys(ctx context.Context, objAPI ObjectLayer, s conf
|
||||
return nil
|
||||
}
|
||||
|
||||
// autoGenerateRootCredentials generates root credentials deterministically if
|
||||
// a KMS is configured, no manual credentials have been specified and if root
|
||||
// access is disabled.
|
||||
func autoGenerateRootCredentials() {
|
||||
if GlobalKMS == nil {
|
||||
return
|
||||
}
|
||||
if globalAPIConfig.permitRootAccess() || !globalActiveCred.Equal(auth.DefaultCredentials) {
|
||||
return
|
||||
}
|
||||
|
||||
aKey, err := GlobalKMS.MAC(GlobalContext, &kms.MACRequest{Message: []byte("root access key")})
|
||||
if errors.Is(err, kes.ErrNotAllowed) || errors.Is(err, errors.ErrUnsupported) {
|
||||
return // If we don't have permission to compute the HMAC, don't change the cred.
|
||||
}
|
||||
if err != nil {
|
||||
logger.Fatal(err, "Unable to generate root access key using KMS")
|
||||
}
|
||||
|
||||
sKey, err := GlobalKMS.MAC(GlobalContext, &kms.MACRequest{Message: []byte("root secret key")})
|
||||
if err != nil {
|
||||
// Here, we must have permission. Otherwise, we would have failed earlier.
|
||||
logger.Fatal(err, "Unable to generate root secret key using KMS")
|
||||
}
|
||||
|
||||
accessKey, err := auth.GenerateAccessKey(20, bytes.NewReader(aKey))
|
||||
if err != nil {
|
||||
logger.Fatal(err, "Unable to generate root access key")
|
||||
}
|
||||
secretKey, err := auth.GenerateSecretKey(32, bytes.NewReader(sKey))
|
||||
if err != nil {
|
||||
logger.Fatal(err, "Unable to generate root secret key")
|
||||
}
|
||||
|
||||
logger.Info("Automatically generated root access key and secret key with the KMS")
|
||||
globalActiveCred = auth.Credentials{
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
}
|
||||
}
|
||||
|
||||
// applyDynamicConfig will apply dynamic config values.
|
||||
// Dynamic systems should be in config.SubSystemsDynamic as well.
|
||||
func applyDynamicConfig(ctx context.Context, objAPI ObjectLayer, s config.Config) error {
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
)
|
||||
|
||||
func TestServerConfig(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
objLayer, fsDir, err := prepareFS(ctx)
|
||||
@@ -56,7 +56,7 @@ func TestServerConfig(t *testing.T) {
|
||||
t.Errorf("Expecting region `us-west-1` found %s", globalSite.Region())
|
||||
}
|
||||
|
||||
if err := saveServerConfig(context.Background(), objLayer, globalServerConfig); err != nil {
|
||||
if err := saveServerConfig(t.Context(), objLayer, globalServerConfig); err != nil {
|
||||
t.Fatalf("Unable to save updated config file %s", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -1036,6 +1036,9 @@ type actionsAccountingFn func(oi ObjectInfo, sz, actualSz int64, sizeS *sizeSumm
|
||||
// The metadata will be compared to consensus on the object layer before any changes are applied.
|
||||
// If no metadata is supplied, -1 is returned if no action is taken.
|
||||
func (i *scannerItem) applyActions(ctx context.Context, objAPI ObjectLayer, objInfos []ObjectInfo, lr lock.Retention, sizeS *sizeSummary, fn actionsAccountingFn) {
|
||||
if len(objInfos) == 0 {
|
||||
return
|
||||
}
|
||||
healActions := func(oi ObjectInfo, actualSz int64) int64 {
|
||||
size := actualSz
|
||||
if i.heal.enabled {
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"slices"
|
||||
@@ -38,7 +37,7 @@ import (
|
||||
|
||||
func TestApplyNewerNoncurrentVersionsLimit(t *testing.T) {
|
||||
// Prepare object layer
|
||||
objAPI, disks, err := prepareErasure(context.Background(), 8)
|
||||
objAPI, disks, err := prepareErasure(t.Context(), 8)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to initialize object layer: %v", err)
|
||||
}
|
||||
@@ -102,7 +101,7 @@ func TestApplyNewerNoncurrentVersionsLimit(t *testing.T) {
|
||||
}
|
||||
globalBucketMetadataSys.Set(bucket, meta)
|
||||
// Prepare lifecycle expiration workers
|
||||
es := newExpiryState(context.Background(), objAPI, 0)
|
||||
es := newExpiryState(t.Context(), objAPI, 0)
|
||||
globalExpiryState = es
|
||||
|
||||
// Prepare object versions
|
||||
@@ -245,6 +244,12 @@ func TestApplyNewerNoncurrentVersionsLimit(t *testing.T) {
|
||||
wants: nil,
|
||||
wantExpired: []ObjectToDelete{{ObjectV: ObjectV{ObjectName: obj, VersionID: allVersExpObjInfos[0].VersionID}}},
|
||||
},
|
||||
{
|
||||
// When no versions are present, in practice this could be an object with only free versions
|
||||
objInfos: nil,
|
||||
wants: nil,
|
||||
wantExpired: nil,
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
t.Run(fmt.Sprintf("TestApplyNewerNoncurrentVersionsLimit-%d", i), func(t *testing.T) {
|
||||
@@ -270,7 +275,7 @@ func TestApplyNewerNoncurrentVersionsLimit(t *testing.T) {
|
||||
sizeS sizeSummary
|
||||
gots []ObjectInfo
|
||||
)
|
||||
item.applyActions(context.TODO(), objAPI, test.objInfos, test.lr, &sizeS, func(oi ObjectInfo, sz, _ int64, _ *sizeSummary) {
|
||||
item.applyActions(t.Context(), objAPI, test.objInfos, test.lr, &sizeS, func(oi ObjectInfo, sz, _ int64, _ *sizeSummary) {
|
||||
if sz != 0 {
|
||||
gots = append(gots, oi)
|
||||
}
|
||||
@@ -393,7 +398,7 @@ func TestEvalActionFromLifecycle(t *testing.T) {
|
||||
|
||||
for i, test := range tests {
|
||||
t.Run(fmt.Sprintf("TestEvalAction-%d", i), func(t *testing.T) {
|
||||
gotEvent := evalActionFromLifecycle(context.Background(), test.ilm, *test.retention, nil, test.obj)
|
||||
gotEvent := evalActionFromLifecycle(t.Context(), test.ilm, *test.retention, nil, test.obj)
|
||||
if gotEvent.Action != test.want {
|
||||
t.Fatalf("Expected %v but got %v", test.want, gotEvent.Action)
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestDataUsageUpdate(t *testing.T) {
|
||||
})
|
||||
weSleep := func() bool { return false }
|
||||
|
||||
got, err := scanDataFolder(context.Background(), nil, &xls, dataUsageCache{Info: dataUsageCacheInfo{Name: bucket}}, getSize, 0, weSleep)
|
||||
got, err := scanDataFolder(t.Context(), nil, &xls, dataUsageCache{Info: dataUsageCacheInfo{Name: bucket}}, getSize, 0, weSleep)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func TestDataUsageUpdate(t *testing.T) {
|
||||
}
|
||||
// Changed dir must be picked up in this many cycles.
|
||||
for i := 0; i < dataUsageUpdateDirCycles; i++ {
|
||||
got, err = scanDataFolder(context.Background(), nil, &xls, got, getSize, 0, weSleep)
|
||||
got, err = scanDataFolder(t.Context(), nil, &xls, got, getSize, 0, weSleep)
|
||||
got.Info.NextCycle++
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -294,7 +294,7 @@ func TestDataUsageUpdatePrefix(t *testing.T) {
|
||||
return DiskInfo{Total: 1 << 40, Free: 1 << 40}, nil
|
||||
})
|
||||
|
||||
got, err := scanDataFolder(context.Background(), nil, &xls, dataUsageCache{Info: dataUsageCacheInfo{Name: "bucket"}}, getSize, 0, weSleep)
|
||||
got, err := scanDataFolder(t.Context(), nil, &xls, dataUsageCache{Info: dataUsageCacheInfo{Name: "bucket"}}, getSize, 0, weSleep)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -429,7 +429,7 @@ func TestDataUsageUpdatePrefix(t *testing.T) {
|
||||
}
|
||||
// Changed dir must be picked up in this many cycles.
|
||||
for i := 0; i < dataUsageUpdateDirCycles; i++ {
|
||||
got, err = scanDataFolder(context.Background(), nil, &xls, got, getSize, 0, weSleep)
|
||||
got, err = scanDataFolder(t.Context(), nil, &xls, got, getSize, 0, weSleep)
|
||||
got.Info.NextCycle++
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -582,7 +582,7 @@ func TestDataUsageCacheSerialize(t *testing.T) {
|
||||
return DiskInfo{Total: 1 << 40, Free: 1 << 40}, nil
|
||||
})
|
||||
weSleep := func() bool { return false }
|
||||
want, err := scanDataFolder(context.Background(), nil, &xls, dataUsageCache{Info: dataUsageCacheInfo{Name: bucket}}, getSize, 0, weSleep)
|
||||
want, err := scanDataFolder(t.Context(), nil, &xls, dataUsageCache{Info: dataUsageCacheInfo{Name: bucket}}, getSize, 0, weSleep)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func TestErasureDecode(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: failed to create test setup: %v", i, err)
|
||||
}
|
||||
erasure, err := NewErasure(context.Background(), test.dataBlocks, test.onDisks-test.dataBlocks, test.blocksize)
|
||||
erasure, err := NewErasure(t.Context(), test.dataBlocks, test.onDisks-test.dataBlocks, test.blocksize)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: failed to create ErasureStorage: %v", i, err)
|
||||
}
|
||||
@@ -108,7 +108,7 @@ func TestErasureDecode(t *testing.T) {
|
||||
for i, disk := range disks {
|
||||
writers[i] = newBitrotWriter(disk, "", "testbucket", "object", erasure.ShardFileSize(test.data), writeAlgorithm, erasure.ShardSize())
|
||||
}
|
||||
n, err := erasure.Encode(context.Background(), bytes.NewReader(data), writers, buffer, erasure.dataBlocks+1)
|
||||
n, err := erasure.Encode(t.Context(), bytes.NewReader(data), writers, buffer, erasure.dataBlocks+1)
|
||||
closeBitrotWriters(writers)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: failed to create erasure test file: %v", i, err)
|
||||
@@ -134,7 +134,7 @@ func TestErasureDecode(t *testing.T) {
|
||||
}
|
||||
|
||||
writer := bytes.NewBuffer(nil)
|
||||
_, err = erasure.Decode(context.Background(), writer, bitrotReaders, test.offset, test.length, test.data, nil)
|
||||
_, err = erasure.Decode(t.Context(), writer, bitrotReaders, test.offset, test.length, test.data, nil)
|
||||
closeBitrotReaders(bitrotReaders)
|
||||
if err != nil && !test.shouldFail {
|
||||
t.Errorf("Test %d: should pass but failed with: %v", i, err)
|
||||
@@ -177,7 +177,7 @@ func TestErasureDecode(t *testing.T) {
|
||||
bitrotReaders[0] = nil
|
||||
}
|
||||
writer.Reset()
|
||||
_, err = erasure.Decode(context.Background(), writer, bitrotReaders, test.offset, test.length, test.data, nil)
|
||||
_, err = erasure.Decode(t.Context(), writer, bitrotReaders, test.offset, test.length, test.data, nil)
|
||||
closeBitrotReaders(bitrotReaders)
|
||||
if err != nil && !test.shouldFailQuorum {
|
||||
t.Errorf("Test %d: should pass but failed with: %v", i, err)
|
||||
@@ -211,7 +211,7 @@ func TestErasureDecodeRandomOffsetLength(t *testing.T) {
|
||||
return
|
||||
}
|
||||
disks := setup.disks
|
||||
erasure, err := NewErasure(context.Background(), dataBlocks, parityBlocks, blockSize)
|
||||
erasure, err := NewErasure(t.Context(), dataBlocks, parityBlocks, blockSize)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create ErasureStorage: %v", err)
|
||||
}
|
||||
@@ -236,7 +236,7 @@ func TestErasureDecodeRandomOffsetLength(t *testing.T) {
|
||||
|
||||
// Create a test file to read from.
|
||||
buffer := make([]byte, blockSize, 2*blockSize)
|
||||
n, err := erasure.Encode(context.Background(), bytes.NewReader(data), writers, buffer, erasure.dataBlocks+1)
|
||||
n, err := erasure.Encode(t.Context(), bytes.NewReader(data), writers, buffer, erasure.dataBlocks+1)
|
||||
closeBitrotWriters(writers)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -266,7 +266,7 @@ func TestErasureDecodeRandomOffsetLength(t *testing.T) {
|
||||
tillOffset := erasure.ShardFileOffset(offset, readLen, length)
|
||||
bitrotReaders[index] = newStreamingBitrotReader(disk, nil, "testbucket", "object", tillOffset, DefaultBitrotAlgorithm, erasure.ShardSize())
|
||||
}
|
||||
_, err = erasure.Decode(context.Background(), buf, bitrotReaders, offset, readLen, length, nil)
|
||||
_, err = erasure.Decode(t.Context(), buf, bitrotReaders, offset, readLen, length, nil)
|
||||
closeBitrotReaders(bitrotReaders)
|
||||
if err != nil {
|
||||
t.Fatal(err, offset, readLen)
|
||||
|
||||
@@ -88,7 +88,7 @@ func TestErasureEncode(t *testing.T) {
|
||||
t.Fatalf("Test %d: failed to create test setup: %v", i, err)
|
||||
}
|
||||
disks := setup.disks
|
||||
erasure, err := NewErasure(context.Background(), test.dataBlocks, test.onDisks-test.dataBlocks, test.blocksize)
|
||||
erasure, err := NewErasure(t.Context(), test.dataBlocks, test.onDisks-test.dataBlocks, test.blocksize)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: failed to create ErasureStorage: %v", i, err)
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func TestErasureEncode(t *testing.T) {
|
||||
}
|
||||
writers[i] = newBitrotWriter(disk, "", "testbucket", "object", erasure.ShardFileSize(int64(len(data[test.offset:]))), test.algorithm, erasure.ShardSize())
|
||||
}
|
||||
n, err := erasure.Encode(context.Background(), bytes.NewReader(data[test.offset:]), writers, buffer, erasure.dataBlocks+1)
|
||||
n, err := erasure.Encode(t.Context(), bytes.NewReader(data[test.offset:]), writers, buffer, erasure.dataBlocks+1)
|
||||
closeBitrotWriters(writers)
|
||||
if err != nil && !test.shouldFail {
|
||||
t.Errorf("Test %d: should pass but failed with: %v", i, err)
|
||||
@@ -140,7 +140,7 @@ func TestErasureEncode(t *testing.T) {
|
||||
if test.offDisks > 0 {
|
||||
writers[0] = nil
|
||||
}
|
||||
n, err = erasure.Encode(context.Background(), bytes.NewReader(data[test.offset:]), writers, buffer, erasure.dataBlocks+1)
|
||||
n, err = erasure.Encode(t.Context(), bytes.NewReader(data[test.offset:]), writers, buffer, erasure.dataBlocks+1)
|
||||
closeBitrotWriters(writers)
|
||||
if err != nil && !test.shouldFailQuorum {
|
||||
t.Errorf("Test %d: should pass but failed with: %v", i, err)
|
||||
|
||||
@@ -19,7 +19,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"os"
|
||||
@@ -75,7 +74,7 @@ func TestErasureHeal(t *testing.T) {
|
||||
t.Fatalf("Test %d: failed to setup Erasure environment: %v", i, err)
|
||||
}
|
||||
disks := setup.disks
|
||||
erasure, err := NewErasure(context.Background(), test.dataBlocks, test.disks-test.dataBlocks, test.blocksize)
|
||||
erasure, err := NewErasure(t.Context(), test.dataBlocks, test.disks-test.dataBlocks, test.blocksize)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: failed to create ErasureStorage: %v", i, err)
|
||||
}
|
||||
@@ -88,7 +87,7 @@ func TestErasureHeal(t *testing.T) {
|
||||
for i, disk := range disks {
|
||||
writers[i] = newBitrotWriter(disk, "", "testbucket", "testobject", erasure.ShardFileSize(test.size), test.algorithm, erasure.ShardSize())
|
||||
}
|
||||
_, err = erasure.Encode(context.Background(), bytes.NewReader(data), writers, buffer, erasure.dataBlocks+1)
|
||||
_, err = erasure.Encode(t.Context(), bytes.NewReader(data), writers, buffer, erasure.dataBlocks+1)
|
||||
closeBitrotWriters(writers)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: failed to create random test data: %v", i, err)
|
||||
@@ -132,7 +131,7 @@ func TestErasureHeal(t *testing.T) {
|
||||
}
|
||||
|
||||
// test case setup is complete - now call Heal()
|
||||
err = erasure.Heal(context.Background(), staleWriters, readers, test.size, nil)
|
||||
err = erasure.Heal(t.Context(), staleWriters, readers, test.size, nil)
|
||||
closeBitrotReaders(readers)
|
||||
closeBitrotWriters(staleWriters)
|
||||
if err != nil && !test.shouldFail {
|
||||
|
||||
@@ -152,7 +152,7 @@ func TestListOnlineDisks(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, disks, err := prepareErasure16(ctx)
|
||||
@@ -160,7 +160,7 @@ func TestListOnlineDisks(t *testing.T) {
|
||||
t.Fatalf("Prepare Erasure backend failed - %v", err)
|
||||
}
|
||||
setObjectLayer(obj)
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(disks)
|
||||
|
||||
type tamperKind int
|
||||
@@ -276,7 +276,7 @@ func TestListOnlineDisks(t *testing.T) {
|
||||
// and check if that disk
|
||||
// appears in outDatedDisks.
|
||||
tamperedIndex = index
|
||||
dErr := erasureDisks[index].Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{
|
||||
dErr := erasureDisks[index].Delete(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -328,7 +328,7 @@ func TestListOnlineDisks(t *testing.T) {
|
||||
// TestListOnlineDisksSmallObjects - checks if listOnlineDisks and outDatedDisks
|
||||
// are consistent with each other.
|
||||
func TestListOnlineDisksSmallObjects(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, disks, err := prepareErasure16(ctx)
|
||||
@@ -336,7 +336,7 @@ func TestListOnlineDisksSmallObjects(t *testing.T) {
|
||||
t.Fatalf("Prepare Erasure backend failed - %v", err)
|
||||
}
|
||||
setObjectLayer(obj)
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(disks)
|
||||
|
||||
type tamperKind int
|
||||
@@ -456,7 +456,7 @@ func TestListOnlineDisksSmallObjects(t *testing.T) {
|
||||
// and check if that disk
|
||||
// appears in outDatedDisks.
|
||||
tamperedIndex = index
|
||||
dErr := erasureDisks[index].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
dErr := erasureDisks[index].Delete(t.Context(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -507,14 +507,14 @@ func TestListOnlineDisksSmallObjects(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDisksWithAllParts(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
obj, disks, err := prepareErasure16(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Prepare Erasure backend failed - %v", err)
|
||||
}
|
||||
setObjectLayer(obj)
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(disks)
|
||||
|
||||
bucket := "bucket"
|
||||
|
||||
@@ -55,10 +55,6 @@ func (er erasureObjects) listAndHeal(ctx context.Context, bucket, prefix string,
|
||||
return errors.New("listAndHeal: No non-healing drives found")
|
||||
}
|
||||
|
||||
expectedDisks := len(disks)/2 + 1
|
||||
fallbackDisks := disks[expectedDisks:]
|
||||
disks = disks[:expectedDisks]
|
||||
|
||||
// How to resolve partial results.
|
||||
resolver := metadataResolutionParams{
|
||||
dirQuorum: 1,
|
||||
@@ -75,7 +71,6 @@ func (er erasureObjects) listAndHeal(ctx context.Context, bucket, prefix string,
|
||||
|
||||
lopts := listPathRawOptions{
|
||||
disks: disks,
|
||||
fallbackDisks: fallbackDisks,
|
||||
bucket: bucket,
|
||||
path: path,
|
||||
filterPrefix: filterPrefix,
|
||||
|
||||
+60
-60
@@ -311,14 +311,14 @@ func TestIsObjectDangling(t *testing.T) {
|
||||
|
||||
// Tests both object and bucket healing.
|
||||
func TestHealing(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDirs, err := prepareErasure16(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
|
||||
// initialize the server and obtain the credentials and root.
|
||||
// credentials are necessary to sign the HTTP request.
|
||||
@@ -353,7 +353,7 @@ func TestHealing(t *testing.T) {
|
||||
}
|
||||
|
||||
disk := er.getDisks()[0]
|
||||
fileInfoPreHeal, err := disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPreHeal, err := disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -376,7 +376,7 @@ func TestHealing(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fileInfoPostHeal, err := disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal, err := disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -395,7 +395,7 @@ func TestHealing(t *testing.T) {
|
||||
// gone down when an object was replaced by a new object.
|
||||
fileInfoOutDated := fileInfoPreHeal
|
||||
fileInfoOutDated.ModTime = time.Now()
|
||||
err = disk.WriteMetadata(context.Background(), "", bucket, object, fileInfoOutDated)
|
||||
err = disk.WriteMetadata(t.Context(), "", bucket, object, fileInfoOutDated)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -405,7 +405,7 @@ func TestHealing(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fileInfoPostHeal, err = disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal, err = disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func TestHealing(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Stat the bucket to make sure that it was created.
|
||||
_, err = er.getDisks()[0].StatVol(context.Background(), bucket)
|
||||
_, err = er.getDisks()[0].StatVol(t.Context(), bucket)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -465,14 +465,14 @@ func TestHealing(t *testing.T) {
|
||||
|
||||
// Tests both object and bucket healing.
|
||||
func TestHealingVersioned(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDirs, err := prepareErasure16(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
|
||||
// initialize the server and obtain the credentials and root.
|
||||
// credentials are necessary to sign the HTTP request.
|
||||
@@ -513,11 +513,11 @@ func TestHealingVersioned(t *testing.T) {
|
||||
}
|
||||
|
||||
disk := er.getDisks()[0]
|
||||
fileInfoPreHeal1, err := disk.ReadVersion(context.Background(), "", bucket, object, oi1.VersionID, ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPreHeal1, err := disk.ReadVersion(t.Context(), "", bucket, object, oi1.VersionID, ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fileInfoPreHeal2, err := disk.ReadVersion(context.Background(), "", bucket, object, oi2.VersionID, ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPreHeal2, err := disk.ReadVersion(t.Context(), "", bucket, object, oi2.VersionID, ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -540,11 +540,11 @@ func TestHealingVersioned(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fileInfoPostHeal1, err := disk.ReadVersion(context.Background(), "", bucket, object, oi1.VersionID, ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal1, err := disk.ReadVersion(t.Context(), "", bucket, object, oi1.VersionID, ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fileInfoPostHeal2, err := disk.ReadVersion(context.Background(), "", bucket, object, oi2.VersionID, ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal2, err := disk.ReadVersion(t.Context(), "", bucket, object, oi2.VersionID, ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -566,7 +566,7 @@ func TestHealingVersioned(t *testing.T) {
|
||||
// gone down when an object was replaced by a new object.
|
||||
fileInfoOutDated := fileInfoPreHeal1
|
||||
fileInfoOutDated.ModTime = time.Now()
|
||||
err = disk.WriteMetadata(context.Background(), "", bucket, object, fileInfoOutDated)
|
||||
err = disk.WriteMetadata(t.Context(), "", bucket, object, fileInfoOutDated)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -576,7 +576,7 @@ func TestHealingVersioned(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fileInfoPostHeal1, err = disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal1, err = disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -586,7 +586,7 @@ func TestHealingVersioned(t *testing.T) {
|
||||
t.Fatal("HealObject failed")
|
||||
}
|
||||
|
||||
fileInfoPostHeal2, err = disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal2, err = disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -638,14 +638,14 @@ func TestHealingVersioned(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Stat the bucket to make sure that it was created.
|
||||
_, err = er.getDisks()[0].StatVol(context.Background(), bucket)
|
||||
_, err = er.getDisks()[0].StatVol(t.Context(), bucket)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHealingDanglingObject(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
resetGlobalHealState()
|
||||
@@ -724,7 +724,7 @@ func TestHealingDanglingObject(t *testing.T) {
|
||||
// Restore...
|
||||
setDisks(orgDisks[:4]...)
|
||||
|
||||
fileInfoPreHeal, err := disks[0].ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPreHeal, err := disks[0].ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -741,7 +741,7 @@ func TestHealingDanglingObject(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fileInfoPostHeal, err := disks[0].ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal, err := disks[0].ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -771,7 +771,7 @@ func TestHealingDanglingObject(t *testing.T) {
|
||||
|
||||
setDisks(orgDisks[:4]...)
|
||||
disk := getDisk(0)
|
||||
fileInfoPreHeal, err = disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPreHeal, err = disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -789,7 +789,7 @@ func TestHealingDanglingObject(t *testing.T) {
|
||||
}
|
||||
|
||||
disk = getDisk(0)
|
||||
fileInfoPostHeal, err = disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal, err = disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -820,7 +820,7 @@ func TestHealingDanglingObject(t *testing.T) {
|
||||
setDisks(orgDisks[:4]...)
|
||||
|
||||
disk = getDisk(0)
|
||||
fileInfoPreHeal, err = disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPreHeal, err = disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -838,7 +838,7 @@ func TestHealingDanglingObject(t *testing.T) {
|
||||
}
|
||||
|
||||
disk = getDisk(0)
|
||||
fileInfoPostHeal, err = disk.ReadVersion(context.Background(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
fileInfoPostHeal, err = disk.ReadVersion(t.Context(), "", bucket, object, "", ReadOptions{ReadData: false, Healing: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -849,7 +849,7 @@ func TestHealingDanglingObject(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHealCorrectQuorum(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
resetGlobalHealState()
|
||||
@@ -933,7 +933,7 @@ func TestHealCorrectQuorum(t *testing.T) {
|
||||
}
|
||||
|
||||
for i := 0; i < nfi.Erasure.ParityBlocks; i++ {
|
||||
erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
erasureDisks[i].Delete(t.Context(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -960,7 +960,7 @@ func TestHealCorrectQuorum(t *testing.T) {
|
||||
}
|
||||
|
||||
for i := 0; i < nfi.Erasure.ParityBlocks; i++ {
|
||||
erasureDisks[i].Delete(context.Background(), minioMetaBucket, pathJoin(cfgFile, xlStorageFormatFile), DeleteOptions{
|
||||
erasureDisks[i].Delete(t.Context(), minioMetaBucket, pathJoin(cfgFile, xlStorageFormatFile), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -980,7 +980,7 @@ func TestHealCorrectQuorum(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
resetGlobalHealState()
|
||||
@@ -1044,7 +1044,7 @@ func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
er := set.sets[0]
|
||||
erasureDisks := er.getDisks()
|
||||
firstDisk := erasureDisks[0]
|
||||
err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
err = firstDisk.Delete(t.Context(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1063,11 +1063,11 @@ func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
t.Fatalf("Failed to getLatestFileInfo - %v", err)
|
||||
}
|
||||
|
||||
if _, err = firstDisk.StatInfoFile(context.Background(), bucket, object+"/"+xlStorageFormatFile, false); err != nil {
|
||||
if _, err = firstDisk.StatInfoFile(t.Context(), bucket, object+"/"+xlStorageFormatFile, false); err != nil {
|
||||
t.Errorf("Expected xl.meta file to be present but stat failed - %v", err)
|
||||
}
|
||||
|
||||
err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{
|
||||
err = firstDisk.Delete(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1075,7 +1075,7 @@ func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
t.Errorf("Failure during deleting part.1 - %v", err)
|
||||
}
|
||||
|
||||
err = firstDisk.WriteAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), []byte{})
|
||||
err = firstDisk.WriteAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"), []byte{})
|
||||
if err != nil {
|
||||
t.Errorf("Failure during creating part.1 - %v", err)
|
||||
}
|
||||
@@ -1095,7 +1095,7 @@ func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
t.Fatalf("FileInfo not equal after healing: %v != %v", fi, nfi)
|
||||
}
|
||||
|
||||
err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{
|
||||
err = firstDisk.Delete(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1104,7 +1104,7 @@ func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
}
|
||||
|
||||
bdata := bytes.Repeat([]byte("b"), int(nfi.Size))
|
||||
err = firstDisk.WriteAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), bdata)
|
||||
err = firstDisk.WriteAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"), bdata)
|
||||
if err != nil {
|
||||
t.Errorf("Failure during creating part.1 - %v", err)
|
||||
}
|
||||
@@ -1127,7 +1127,7 @@ func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
// Test 4: checks if HealObject returns an error when xl.meta is not found
|
||||
// in more than read quorum number of disks, to create a corrupted situation.
|
||||
for i := 0; i <= nfi.Erasure.DataBlocks; i++ {
|
||||
erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
erasureDisks[i].Delete(t.Context(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1148,7 +1148,7 @@ func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
}
|
||||
|
||||
for i := 0; i < (nfi.Erasure.DataBlocks + nfi.Erasure.ParityBlocks); i++ {
|
||||
stats, _ := erasureDisks[i].StatInfoFile(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), false)
|
||||
stats, _ := erasureDisks[i].StatInfoFile(t.Context(), bucket, pathJoin(object, xlStorageFormatFile), false)
|
||||
if len(stats) != 0 {
|
||||
t.Errorf("Expected xl.meta file to be not present, but succeeded")
|
||||
}
|
||||
@@ -1156,7 +1156,7 @@ func TestHealObjectCorruptedPools(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHealObjectCorruptedXLMeta(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
resetGlobalHealState()
|
||||
@@ -1222,7 +1222,7 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) {
|
||||
t.Fatalf("Failed to getLatestFileInfo - %v", err)
|
||||
}
|
||||
|
||||
err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
err = firstDisk.Delete(t.Context(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1235,7 +1235,7 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) {
|
||||
t.Fatalf("Failed to heal object - %v", err)
|
||||
}
|
||||
|
||||
if _, err = firstDisk.StatInfoFile(context.Background(), bucket, object+"/"+xlStorageFormatFile, false); err != nil {
|
||||
if _, err = firstDisk.StatInfoFile(t.Context(), bucket, object+"/"+xlStorageFormatFile, false); err != nil {
|
||||
t.Errorf("Expected xl.meta file to be present but stat failed - %v", err)
|
||||
}
|
||||
|
||||
@@ -1250,7 +1250,7 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test 2: Test with a corrupted xl.meta
|
||||
err = firstDisk.WriteAll(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), []byte("abcd"))
|
||||
err = firstDisk.WriteAll(t.Context(), bucket, pathJoin(object, xlStorageFormatFile), []byte("abcd"))
|
||||
if err != nil {
|
||||
t.Errorf("Failure during creating part.1 - %v", err)
|
||||
}
|
||||
@@ -1273,7 +1273,7 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) {
|
||||
// Test 3: checks if HealObject returns an error when xl.meta is not found
|
||||
// in more than read quorum number of disks, to create a corrupted situation.
|
||||
for i := 0; i <= nfi2.Erasure.DataBlocks; i++ {
|
||||
erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
erasureDisks[i].Delete(t.Context(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1295,7 +1295,7 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
resetGlobalHealState()
|
||||
@@ -1362,18 +1362,18 @@ func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
t.Fatalf("Failed to getLatestFileInfo - %v", err)
|
||||
}
|
||||
|
||||
part1Disk1Origin, err := firstDisk.ReadAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
part1Disk1Origin, err := firstDisk.ReadAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read a file - %v", err)
|
||||
}
|
||||
|
||||
part1Disk2Origin, err := secondDisk.ReadAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
part1Disk2Origin, err := secondDisk.ReadAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read a file - %v", err)
|
||||
}
|
||||
|
||||
// Test 1, remove part.1
|
||||
err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{
|
||||
err = firstDisk.Delete(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1386,7 +1386,7 @@ func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
t.Fatalf("Failed to heal object - %v", err)
|
||||
}
|
||||
|
||||
part1Replaced, err := firstDisk.ReadAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
part1Replaced, err := firstDisk.ReadAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read a file - %v", err)
|
||||
}
|
||||
@@ -1396,7 +1396,7 @@ func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test 2, Corrupt part.1
|
||||
err = firstDisk.WriteAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), []byte("foobytes"))
|
||||
err = firstDisk.WriteAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"), []byte("foobytes"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write a file - %v", err)
|
||||
}
|
||||
@@ -1406,7 +1406,7 @@ func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
t.Fatalf("Failed to heal object - %v", err)
|
||||
}
|
||||
|
||||
part1Replaced, err = firstDisk.ReadAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
part1Replaced, err = firstDisk.ReadAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read a file - %v", err)
|
||||
}
|
||||
@@ -1416,12 +1416,12 @@ func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test 3, Corrupt one part and remove data in another disk
|
||||
err = firstDisk.WriteAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), []byte("foobytes"))
|
||||
err = firstDisk.WriteAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"), []byte("foobytes"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write a file - %v", err)
|
||||
}
|
||||
|
||||
err = secondDisk.Delete(context.Background(), bucket, object, DeleteOptions{
|
||||
err = secondDisk.Delete(t.Context(), bucket, object, DeleteOptions{
|
||||
Recursive: true,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1434,7 +1434,7 @@ func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
t.Fatalf("Failed to heal object - %v", err)
|
||||
}
|
||||
|
||||
partReconstructed, err := firstDisk.ReadAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
partReconstructed, err := firstDisk.ReadAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read a file - %v", err)
|
||||
}
|
||||
@@ -1443,7 +1443,7 @@ func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
t.Fatalf("part.1 not healed correctly")
|
||||
}
|
||||
|
||||
partReconstructed, err = secondDisk.ReadAll(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
partReconstructed, err = secondDisk.ReadAll(t.Context(), bucket, pathJoin(object, fi.DataDir, "part.1"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read a file - %v", err)
|
||||
}
|
||||
@@ -1455,7 +1455,7 @@ func TestHealObjectCorruptedParts(t *testing.T) {
|
||||
|
||||
// Tests healing of object.
|
||||
func TestHealObjectErasure(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
nDisks := 16
|
||||
@@ -1512,7 +1512,7 @@ func TestHealObjectErasure(t *testing.T) {
|
||||
}
|
||||
|
||||
// Delete the whole object folder
|
||||
err = firstDisk.Delete(context.Background(), bucket, object, DeleteOptions{
|
||||
err = firstDisk.Delete(t.Context(), bucket, object, DeleteOptions{
|
||||
Recursive: true,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1525,7 +1525,7 @@ func TestHealObjectErasure(t *testing.T) {
|
||||
t.Fatalf("Failed to heal object - %v", err)
|
||||
}
|
||||
|
||||
if _, err = firstDisk.StatInfoFile(context.Background(), bucket, object+"/"+xlStorageFormatFile, false); err != nil {
|
||||
if _, err = firstDisk.StatInfoFile(t.Context(), bucket, object+"/"+xlStorageFormatFile, false); err != nil {
|
||||
t.Errorf("Expected xl.meta file to be present but stat failed - %v", err)
|
||||
}
|
||||
|
||||
@@ -1534,7 +1534,7 @@ func TestHealObjectErasure(t *testing.T) {
|
||||
er.getDisks = func() []StorageAPI {
|
||||
// Nil more than half the disks, to remove write quorum.
|
||||
for i := 0; i <= len(erasureDisks)/2; i++ {
|
||||
err := erasureDisks[i].Delete(context.Background(), bucket, object, DeleteOptions{
|
||||
err := erasureDisks[i].Delete(t.Context(), bucket, object, DeleteOptions{
|
||||
Recursive: true,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1560,7 +1560,7 @@ func TestHealObjectErasure(t *testing.T) {
|
||||
|
||||
// Tests healing of empty directories
|
||||
func TestHealEmptyDirectoryErasure(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
nDisks := 16
|
||||
@@ -1596,7 +1596,7 @@ func TestHealEmptyDirectoryErasure(t *testing.T) {
|
||||
z := obj.(*erasureServerPools)
|
||||
er := z.serverPools[0].sets[0]
|
||||
firstDisk := er.getDisks()[0]
|
||||
err = firstDisk.DeleteVol(context.Background(), pathJoin(bucket, encodeDirObject(object)), true)
|
||||
err = firstDisk.DeleteVol(t.Context(), pathJoin(bucket, encodeDirObject(object)), true)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to delete a file - %v", err)
|
||||
}
|
||||
@@ -1608,7 +1608,7 @@ func TestHealEmptyDirectoryErasure(t *testing.T) {
|
||||
}
|
||||
|
||||
// Check if the empty directory is restored in the first disk
|
||||
_, err = firstDisk.StatVol(context.Background(), pathJoin(bucket, encodeDirObject(object)))
|
||||
_, err = firstDisk.StatVol(t.Context(), pathJoin(bucket, encodeDirObject(object)))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected object to be present but stat failed - %v", err)
|
||||
}
|
||||
@@ -1656,7 +1656,7 @@ func TestHealLastDataShard(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
nDisks := 16
|
||||
|
||||
@@ -99,11 +99,11 @@ func TestReduceErrs(t *testing.T) {
|
||||
}
|
||||
// Validates list of all the testcases for returning valid errors.
|
||||
for i, testCase := range testCases {
|
||||
gotErr := reduceReadQuorumErrs(context.Background(), testCase.errs, testCase.ignoredErrs, 5)
|
||||
gotErr := reduceReadQuorumErrs(t.Context(), testCase.errs, testCase.ignoredErrs, 5)
|
||||
if gotErr != testCase.err {
|
||||
t.Errorf("Test %d : expected %s, got %s", i+1, testCase.err, gotErr)
|
||||
}
|
||||
gotNewErr := reduceWriteQuorumErrs(context.Background(), testCase.errs, testCase.ignoredErrs, 6)
|
||||
gotNewErr := reduceWriteQuorumErrs(t.Context(), testCase.errs, testCase.ignoredErrs, 6)
|
||||
if gotNewErr != errErasureWriteQuorum {
|
||||
t.Errorf("Test %d : expected %s, got %s", i+1, errErasureWriteQuorum, gotErr)
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func TestHashOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestShuffleDisks(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
nDisks := 16
|
||||
@@ -196,7 +196,7 @@ func testShuffleDisks(t *testing.T, z *erasureServerPools) {
|
||||
|
||||
// TestEvalDisks tests the behavior of evalDisks
|
||||
func TestEvalDisks(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
nDisks := 16
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
@@ -146,7 +145,7 @@ func TestObjectToPartOffset(t *testing.T) {
|
||||
|
||||
// Test them.
|
||||
for _, testCase := range testCases {
|
||||
index, offset, err := fi.ObjectToPartOffset(context.Background(), testCase.offset)
|
||||
index, offset, err := fi.ObjectToPartOffset(t.Context(), testCase.offset)
|
||||
if err != testCase.expectedErr {
|
||||
t.Fatalf("%+v: expected = %s, got: %s", testCase, testCase.expectedErr, err)
|
||||
}
|
||||
@@ -272,7 +271,7 @@ func TestFindFileInfoInQuorum(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run("", func(t *testing.T) {
|
||||
fi, err := findFileInfoInQuorum(context.Background(), test.fis, test.modTime, "", test.expectedQuorum)
|
||||
fi, err := findFileInfoInQuorum(t.Context(), test.fis, test.modTime, "", test.expectedQuorum)
|
||||
_, ok1 := err.(InsufficientReadQuorum)
|
||||
_, ok2 := test.expectedErr.(InsufficientReadQuorum)
|
||||
if ok1 != ok2 {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2023 MinIO, Inc.
|
||||
// Copyright (c) 2015-2025 MinIO, Inc.
|
||||
//
|
||||
// This file is part of MinIO Object Storage stack
|
||||
//
|
||||
@@ -928,7 +928,19 @@ func (er erasureObjects) ListObjectParts(ctx context.Context, bucket, object, up
|
||||
}
|
||||
|
||||
start := objectPartIndexNums(partNums, partNumberMarker)
|
||||
if start != -1 {
|
||||
if partNumberMarker > 0 && start == -1 {
|
||||
// Marker not present among what is present on the
|
||||
// server, we return an empty list.
|
||||
return result, nil
|
||||
}
|
||||
|
||||
if partNumberMarker > 0 && start != -1 {
|
||||
if start+1 >= len(partNums) {
|
||||
// Marker indicates that we are the end
|
||||
// of the list, so we simply return empty
|
||||
return result, nil
|
||||
}
|
||||
|
||||
partNums = partNums[start+1:]
|
||||
}
|
||||
|
||||
|
||||
+27
-27
@@ -36,7 +36,7 @@ import (
|
||||
)
|
||||
|
||||
func TestRepeatPutObjectPart(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
var objLayer ObjectLayer
|
||||
@@ -50,7 +50,7 @@ func TestRepeatPutObjectPart(t *testing.T) {
|
||||
}
|
||||
|
||||
// cleaning up of temporary test directories
|
||||
defer objLayer.Shutdown(context.Background())
|
||||
defer objLayer.Shutdown(t.Context())
|
||||
defer removeRoots(disks)
|
||||
|
||||
err = objLayer.MakeBucket(ctx, "bucket1", MakeBucketOptions{})
|
||||
@@ -91,7 +91,7 @@ func TestErasureDeleteObjectBasic(t *testing.T) {
|
||||
{"bucket", "dir/obj", nil},
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend
|
||||
@@ -99,7 +99,7 @@ func TestErasureDeleteObjectBasic(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer xl.Shutdown(context.Background())
|
||||
defer xl.Shutdown(t.Context())
|
||||
|
||||
err = xl.MakeBucket(ctx, "bucket", MakeBucketOptions{})
|
||||
if err != nil {
|
||||
@@ -132,7 +132,7 @@ func TestErasureDeleteObjectBasic(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDeleteObjectsVersionedTwoPools(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDirs, err := prepareErasurePools()
|
||||
@@ -201,7 +201,7 @@ func TestDeleteObjectsVersionedTwoPools(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDeleteObjectsVersioned(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDirs, err := prepareErasure(ctx, 16)
|
||||
@@ -280,7 +280,7 @@ func TestDeleteObjectsVersioned(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErasureDeleteObjectsErasureSet(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDirs, err := prepareErasureSets32(ctx)
|
||||
@@ -353,7 +353,7 @@ func TestErasureDeleteObjectsErasureSet(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErasureDeleteObjectDiskNotFound(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend.
|
||||
@@ -362,7 +362,7 @@ func TestErasureDeleteObjectDiskNotFound(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Cleanup backend directories
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
z := obj.(*erasureServerPools)
|
||||
@@ -422,7 +422,7 @@ func TestErasureDeleteObjectDiskNotFound(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErasureDeleteObjectDiskNotFoundErasure4(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend.
|
||||
@@ -431,7 +431,7 @@ func TestErasureDeleteObjectDiskNotFoundErasure4(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Cleanup backend directories
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
z := obj.(*erasureServerPools)
|
||||
@@ -482,7 +482,7 @@ func TestErasureDeleteObjectDiskNotFoundErasure4(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErasureDeleteObjectDiskNotFoundErr(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend.
|
||||
@@ -491,7 +491,7 @@ func TestErasureDeleteObjectDiskNotFoundErr(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Cleanup backend directories
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
z := obj.(*erasureServerPools)
|
||||
@@ -553,7 +553,7 @@ func TestErasureDeleteObjectDiskNotFoundErr(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetObjectNoQuorum(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend.
|
||||
@@ -562,7 +562,7 @@ func TestGetObjectNoQuorum(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Cleanup backend directories.
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
z := obj.(*erasureServerPools)
|
||||
@@ -662,7 +662,7 @@ func TestGetObjectNoQuorum(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHeadObjectNoQuorum(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend.
|
||||
@@ -671,7 +671,7 @@ func TestHeadObjectNoQuorum(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Cleanup backend directories.
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
z := obj.(*erasureServerPools)
|
||||
@@ -739,7 +739,7 @@ func TestHeadObjectNoQuorum(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPutObjectNoQuorum(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend.
|
||||
@@ -749,7 +749,7 @@ func TestPutObjectNoQuorum(t *testing.T) {
|
||||
}
|
||||
|
||||
// Cleanup backend directories.
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
z := obj.(*erasureServerPools)
|
||||
@@ -802,7 +802,7 @@ func TestPutObjectNoQuorum(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPutObjectNoQuorumSmall(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend.
|
||||
@@ -812,7 +812,7 @@ func TestPutObjectNoQuorumSmall(t *testing.T) {
|
||||
}
|
||||
|
||||
// Cleanup backend directories.
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
z := obj.(*erasureServerPools)
|
||||
@@ -869,7 +869,7 @@ func TestPutObjectNoQuorumSmall(t *testing.T) {
|
||||
// Test PutObject twice, one small and another bigger
|
||||
// than small data threshold and checks reading them again
|
||||
func TestPutObjectSmallInlineData(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
const numberOfDisks = 4
|
||||
@@ -881,7 +881,7 @@ func TestPutObjectSmallInlineData(t *testing.T) {
|
||||
}
|
||||
|
||||
// Cleanup backend directories.
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
bucket := "bucket"
|
||||
@@ -1131,7 +1131,7 @@ func testObjectQuorumFromMeta(obj ObjectLayer, instanceType string, dirs []strin
|
||||
|
||||
// In some deployments, one object has data inlined in one disk and not inlined in other disks.
|
||||
func TestGetObjectInlineNotInline(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create a backend with 4 disks named disk{1...4}, this name convention
|
||||
@@ -1151,7 +1151,7 @@ func TestGetObjectInlineNotInline(t *testing.T) {
|
||||
}
|
||||
|
||||
// cleaning up of temporary test directories
|
||||
defer objLayer.Shutdown(context.Background())
|
||||
defer objLayer.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
// Create a testbucket
|
||||
@@ -1192,7 +1192,7 @@ func TestGetObjectWithOutdatedDisks(t *testing.T) {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
// Create an instance of xl backend.
|
||||
@@ -1202,7 +1202,7 @@ func TestGetObjectWithOutdatedDisks(t *testing.T) {
|
||||
}
|
||||
|
||||
// Cleanup backend directories.
|
||||
defer obj.Shutdown(context.Background())
|
||||
defer obj.Shutdown(t.Context())
|
||||
defer removeRoots(fsDirs)
|
||||
|
||||
z := obj.(*erasureServerPools)
|
||||
|
||||
@@ -1182,29 +1182,32 @@ func (z *erasureServerPools) checkAfterDecom(ctx context.Context, idx int) error
|
||||
return
|
||||
}
|
||||
|
||||
// `.usage-cache.bin` still exists, must be not readable ignore it.
|
||||
if bi.Name == minioMetaBucket && strings.Contains(entry.name, dataUsageCacheName) {
|
||||
// skipping bucket usage cache name, as its autogenerated.
|
||||
return
|
||||
}
|
||||
|
||||
fivs, err := entry.fileInfoVersions(bi.Name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// We need a reversed order for decommissioning,
|
||||
// to create the appropriate stack.
|
||||
versionsSorter(fivs.Versions).reverse()
|
||||
var ignored int
|
||||
|
||||
for _, version := range fivs.Versions {
|
||||
// Apply lifecycle rules on the objects that are expired.
|
||||
if filterLifecycle(bi.Name, version.Name, version) {
|
||||
ignored++
|
||||
continue
|
||||
}
|
||||
|
||||
// `.usage-cache.bin` still exists, must be not readable ignore it.
|
||||
if bi.Name == minioMetaBucket && strings.Contains(version.Name, dataUsageCacheName) {
|
||||
// skipping bucket usage cache name, as its autogenerated.
|
||||
if version.Deleted {
|
||||
ignored++
|
||||
continue
|
||||
}
|
||||
|
||||
versionsFound++
|
||||
}
|
||||
|
||||
versionsFound += len(fivs.Versions) - ignored
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import (
|
||||
"github.com/minio/minio/internal/logger"
|
||||
"github.com/minio/pkg/v3/sync/errgroup"
|
||||
"github.com/minio/pkg/v3/wildcard"
|
||||
"github.com/minio/pkg/v3/workers"
|
||||
"github.com/puzpuzpuz/xsync/v3"
|
||||
)
|
||||
|
||||
@@ -2467,7 +2468,7 @@ func (z *erasureServerPools) HealObjects(ctx context.Context, bucket, prefix str
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
var poolErrs [][]error
|
||||
poolErrs := make([][]error, len(z.serverPools))
|
||||
for idx, erasureSet := range z.serverPools {
|
||||
if opts.Pool != nil && *opts.Pool != idx {
|
||||
continue
|
||||
@@ -2476,20 +2477,20 @@ func (z *erasureServerPools) HealObjects(ctx context.Context, bucket, prefix str
|
||||
continue
|
||||
}
|
||||
errs := make([]error, len(erasureSet.sets))
|
||||
var wg sync.WaitGroup
|
||||
wk, _ := workers.New(3)
|
||||
for idx, set := range erasureSet.sets {
|
||||
if opts.Set != nil && *opts.Set != idx {
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
wk.Take()
|
||||
go func(idx int, set *erasureObjects) {
|
||||
defer wg.Done()
|
||||
defer wk.Give()
|
||||
|
||||
errs[idx] = set.listAndHeal(ctx, bucket, prefix, opts.Recursive, opts.ScanMode, healEntry)
|
||||
}(idx, set)
|
||||
}
|
||||
wg.Wait()
|
||||
poolErrs = append(poolErrs, errs)
|
||||
wk.Wait()
|
||||
poolErrs[idx] = errs
|
||||
}
|
||||
for _, errs := range poolErrs {
|
||||
for _, err := range errs {
|
||||
|
||||
@@ -159,7 +159,7 @@ func TestCrcHashMod(t *testing.T) {
|
||||
// TestNewErasure - tests initialization of all input disks
|
||||
// and constructs a valid `Erasure` object
|
||||
func TestNewErasureSets(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
nDisks := 16 // Maximum disks.
|
||||
|
||||
+5
-6
@@ -19,7 +19,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"testing"
|
||||
@@ -52,11 +51,11 @@ func TestErasureEncodeDecode(t *testing.T) {
|
||||
buffer := make([]byte, len(data), 2*len(data))
|
||||
copy(buffer, data)
|
||||
|
||||
erasure, err := NewErasure(context.Background(), test.dataBlocks, test.parityBlocks, blockSizeV2)
|
||||
erasure, err := NewErasure(t.Context(), test.dataBlocks, test.parityBlocks, blockSizeV2)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: failed to create erasure: %v", i, err)
|
||||
}
|
||||
encoded, err := erasure.EncodeData(context.Background(), buffer)
|
||||
encoded, err := erasure.EncodeData(t.Context(), buffer)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: failed to encode data: %v", i, err)
|
||||
}
|
||||
@@ -69,7 +68,7 @@ func TestErasureEncodeDecode(t *testing.T) {
|
||||
}
|
||||
|
||||
if test.reconstructParity {
|
||||
err = erasure.DecodeDataAndParityBlocks(context.Background(), encoded)
|
||||
err = erasure.DecodeDataAndParityBlocks(t.Context(), encoded)
|
||||
} else {
|
||||
err = erasure.DecodeDataBlocks(encoded)
|
||||
}
|
||||
@@ -98,7 +97,7 @@ func TestErasureEncodeDecode(t *testing.T) {
|
||||
}
|
||||
|
||||
decodedData := new(bytes.Buffer)
|
||||
if _, err = writeDataBlocks(context.Background(), decodedData, decoded, test.dataBlocks, 0, int64(len(data))); err != nil {
|
||||
if _, err = writeDataBlocks(t.Context(), decodedData, decoded, test.dataBlocks, 0, int64(len(data))); err != nil {
|
||||
t.Errorf("Test %d: failed to write data blocks: %v", i, err)
|
||||
}
|
||||
if !bytes.Equal(decodedData.Bytes(), data) {
|
||||
@@ -127,7 +126,7 @@ func newErasureTestSetup(tb testing.TB, dataBlocks int, parityBlocks int, blockS
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = disks[i].MakeVol(context.Background(), "testbucket")
|
||||
err = disks[i].MakeVol(tb.Context(), "testbucket")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+1
-6
@@ -352,10 +352,6 @@ func (er *erasureObjects) healErasureSet(ctx context.Context, buckets []string,
|
||||
disks[i], disks[j] = disks[j], disks[i]
|
||||
})
|
||||
|
||||
expectedDisks := len(disks)/2 + 1
|
||||
fallbackDisks := disks[expectedDisks:]
|
||||
disks = disks[:expectedDisks]
|
||||
|
||||
filterLifecycle := func(bucket, object string, fi FileInfo) bool {
|
||||
if lc == nil {
|
||||
return false
|
||||
@@ -518,7 +514,6 @@ func (er *erasureObjects) healErasureSet(ctx context.Context, buckets []string,
|
||||
|
||||
err = listPathRaw(ctx, listPathRawOptions{
|
||||
disks: disks,
|
||||
fallbackDisks: fallbackDisks,
|
||||
bucket: bucket,
|
||||
recursive: true,
|
||||
forwardTo: forwardTo,
|
||||
@@ -540,7 +535,7 @@ func (er *erasureObjects) healErasureSet(ctx context.Context, buckets []string,
|
||||
},
|
||||
finished: func(errs []error) {
|
||||
success := countErrs(errs, nil)
|
||||
if success < expectedDisks {
|
||||
if success < len(disks)/2+1 {
|
||||
retErr = fmt.Errorf("one or more errors reported during listing: %v", errors.Join(errs...))
|
||||
}
|
||||
},
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
|
||||
// Tests validate bucket LocationConstraint.
|
||||
func TestIsValidLocationConstraint(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
@@ -163,7 +163,7 @@ func TestExtractMetadataHeaders(t *testing.T) {
|
||||
// Validate if the extracting headers.
|
||||
for i, testCase := range testCases {
|
||||
metadata := make(map[string]string)
|
||||
err := extractMetadataFromMime(context.Background(), textproto.MIMEHeader(testCase.header), metadata)
|
||||
err := extractMetadataFromMime(t.Context(), textproto.MIMEHeader(testCase.header), metadata)
|
||||
if err != nil && !testCase.shouldFail {
|
||||
t.Fatalf("Test %d failed to extract metadata: %v", i+1, err)
|
||||
}
|
||||
|
||||
@@ -2777,6 +2777,31 @@ func (store *IAMStoreSys) ListSTSAccounts(ctx context.Context, accessKey string)
|
||||
return stsAccounts, nil
|
||||
}
|
||||
|
||||
// ListAccessKeys - lists all access keys (sts/service accounts)
|
||||
func (store *IAMStoreSys) ListAccessKeys(ctx context.Context) ([]auth.Credentials, error) {
|
||||
cache := store.rlock()
|
||||
defer store.runlock()
|
||||
|
||||
accessKeys := store.getSTSAndServiceAccounts(cache)
|
||||
for i, accessKey := range accessKeys {
|
||||
accessKeys[i].SecretKey = ""
|
||||
if accessKey.IsTemp() {
|
||||
secret, err := getTokenSigningKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
claims, err := getClaimsFromTokenWithSecret(accessKey.SessionToken, secret)
|
||||
if err != nil {
|
||||
continue // ignore invalid session tokens
|
||||
}
|
||||
accessKeys[i].Claims = claims.MapClaims
|
||||
}
|
||||
accessKeys[i].SessionToken = ""
|
||||
}
|
||||
|
||||
return accessKeys, nil
|
||||
}
|
||||
|
||||
// AddUser - adds/updates long term user account to storage.
|
||||
func (store *IAMStoreSys) AddUser(ctx context.Context, accessKey string, ureq madmin.AddOrUpdateUserReq) (updatedAt time.Time, err error) {
|
||||
cache := store.lock()
|
||||
@@ -2839,6 +2864,10 @@ func (store *IAMStoreSys) GetSTSAndServiceAccounts() []auth.Credentials {
|
||||
cache := store.rlock()
|
||||
defer store.runlock()
|
||||
|
||||
return store.getSTSAndServiceAccounts(cache)
|
||||
}
|
||||
|
||||
func (store *IAMStoreSys) getSTSAndServiceAccounts(cache *iamCache) []auth.Credentials {
|
||||
var res []auth.Credentials
|
||||
for _, u := range cache.iamUsersMap {
|
||||
cred := u.Credentials
|
||||
|
||||
+14
@@ -1246,6 +1246,20 @@ func (sys *IAMSys) ListSTSAccounts(ctx context.Context, accessKey string) ([]aut
|
||||
}
|
||||
}
|
||||
|
||||
// ListAllAccessKeys - lists all access keys (sts/service accounts)
|
||||
func (sys *IAMSys) ListAllAccessKeys(ctx context.Context) ([]auth.Credentials, error) {
|
||||
if !sys.Initialized() {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
|
||||
select {
|
||||
case <-sys.configLoaded:
|
||||
return sys.store.ListAccessKeys(ctx)
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
// GetServiceAccount - wrapper method to get information about a service account
|
||||
func (sys *IAMSys) GetServiceAccount(ctx context.Context, accessKey string) (auth.Credentials, *policy.Policy, error) {
|
||||
sa, embeddedPolicy, err := sys.getServiceAccount(ctx, accessKey)
|
||||
|
||||
+4
-4
@@ -37,7 +37,7 @@ func getTokenString(accessKey, secretKey string) (string, error) {
|
||||
|
||||
// Tests web request authenticator.
|
||||
func TestWebRequestAuthenticate(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
@@ -94,7 +94,7 @@ func TestWebRequestAuthenticate(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkParseJWTStandardClaims(b *testing.B) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(b.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
@@ -125,7 +125,7 @@ func BenchmarkParseJWTStandardClaims(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkParseJWTMapClaims(b *testing.B) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(b.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
@@ -158,7 +158,7 @@ func BenchmarkParseJWTMapClaims(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkAuthenticateNode(b *testing.B) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(b.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -769,7 +768,7 @@ func TestKMSHandlerNotConfiguredOrInvalidCreds(t *testing.T) {
|
||||
}
|
||||
|
||||
func setupKMSTest(t *testing.T, enableKMS bool) (*adminErasureTestBed, func()) {
|
||||
adminTestBed, err := prepareAdminErasureTestBed(context.Background())
|
||||
adminTestBed, err := prepareAdminErasureTestBed(t.Context())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -810,7 +809,7 @@ func buildKMSRequest(t *testing.T, method, path, accessKey, secretKey string, qu
|
||||
// setupKMSUser is a test helper that creates a new user with the provided access key and secret key
|
||||
// and applies the given policy to the user.
|
||||
func setupKMSUser(t *testing.T, accessKey, secretKey, p string) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
createUserParams := madmin.AddOrUpdateUserReq{
|
||||
SecretKey: secretKey,
|
||||
Status: madmin.AccountEnabled,
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
@@ -34,7 +33,7 @@ func TestLocalLockerExpire(t *testing.T) {
|
||||
rResources := make([]string, 1000)
|
||||
quorum := 0
|
||||
l := newLocker()
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
for i := range wResources {
|
||||
arg := dsync.LockArgs{
|
||||
UID: mustGetUUID(),
|
||||
@@ -112,7 +111,7 @@ func TestLocalLockerUnlock(t *testing.T) {
|
||||
wUIDs := make([]string, n)
|
||||
rUIDs := make([]string, 0, n*2)
|
||||
l := newLocker()
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
quorum := 0
|
||||
for i := range wResources {
|
||||
names := [m]string{}
|
||||
@@ -287,7 +286,7 @@ func Test_localLocker_expireOldLocksExpire(t *testing.T) {
|
||||
|
||||
for i := 0; i < readers; i++ {
|
||||
rng.Read(tmp[:])
|
||||
ok, err := l.RLock(context.Background(), dsync.LockArgs{
|
||||
ok, err := l.RLock(t.Context(), dsync.LockArgs{
|
||||
UID: uuid.NewString(),
|
||||
Resources: res,
|
||||
Source: hex.EncodeToString(tmp[:8]),
|
||||
@@ -374,7 +373,7 @@ func Test_localLocker_RUnlock(t *testing.T) {
|
||||
|
||||
for i := 0; i < readers; i++ {
|
||||
rng.Read(tmp[:])
|
||||
ok, err := l.RLock(context.Background(), dsync.LockArgs{
|
||||
ok, err := l.RLock(t.Context(), dsync.LockArgs{
|
||||
UID: uuid.NewString(),
|
||||
Resources: res,
|
||||
Source: hex.EncodeToString(tmp[:8]),
|
||||
@@ -398,7 +397,7 @@ func Test_localLocker_RUnlock(t *testing.T) {
|
||||
}
|
||||
start := time.Now()
|
||||
for _, lock := range toUnLock {
|
||||
ok, err := l.ForceUnlock(context.Background(), lock)
|
||||
ok, err := l.ForceUnlock(t.Context(), lock)
|
||||
if err != nil || !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -423,7 +422,7 @@ func Test_localLocker_RUnlock(t *testing.T) {
|
||||
}
|
||||
start = time.Now()
|
||||
for _, lock := range toUnLock {
|
||||
ok, err := l.RUnlock(context.TODO(), lock)
|
||||
ok, err := l.RUnlock(t.Context(), lock)
|
||||
if err != nil || !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func TestLockRESTlient(t *testing.T) {
|
||||
}
|
||||
endpointLocal.IsLocal = true
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
err = initGlobalLockGrid(ctx, []PoolEndpoints{{Endpoints: Endpoints{endpoint, endpointLocal}}})
|
||||
if err != nil {
|
||||
@@ -50,22 +50,22 @@ func TestLockRESTlient(t *testing.T) {
|
||||
}
|
||||
|
||||
// Attempt all calls.
|
||||
_, err = lkClient.RLock(context.Background(), dsync.LockArgs{})
|
||||
_, err = lkClient.RLock(t.Context(), dsync.LockArgs{})
|
||||
if err == nil {
|
||||
t.Fatal("Expected for Rlock to fail")
|
||||
}
|
||||
|
||||
_, err = lkClient.Lock(context.Background(), dsync.LockArgs{})
|
||||
_, err = lkClient.Lock(t.Context(), dsync.LockArgs{})
|
||||
if err == nil {
|
||||
t.Fatal("Expected for Lock to fail")
|
||||
}
|
||||
|
||||
_, err = lkClient.RUnlock(context.Background(), dsync.LockArgs{})
|
||||
_, err = lkClient.RUnlock(t.Context(), dsync.LockArgs{})
|
||||
if err == nil {
|
||||
t.Fatal("Expected for RUnlock to fail")
|
||||
}
|
||||
|
||||
_, err = lkClient.Unlock(context.Background(), dsync.LockArgs{})
|
||||
_, err = lkClient.Unlock(t.Context(), dsync.LockArgs{})
|
||||
if err == nil {
|
||||
t.Fatal("Expected for Unlock to fail")
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func createLockTestServer(ctx context.Context, t *testing.T) (string, *lockRESTS
|
||||
|
||||
// Test function to remove lock entries from map based on name & uid combination
|
||||
func TestLockRpcServerRemoveEntry(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
testPath, locker, _ := createLockTestServer(ctx, t)
|
||||
|
||||
@@ -19,7 +19,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
@@ -278,7 +277,7 @@ func Test_metacacheReader_readAll(t *testing.T) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
readErr = r.readAll(context.Background(), objs)
|
||||
readErr = r.readAll(t.Context(), objs)
|
||||
wg.Done()
|
||||
}()
|
||||
want := loadMetacacheSampleNames
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -33,8 +32,8 @@ import (
|
||||
func TestGetSource(t *testing.T) {
|
||||
currentSource := func() string { return getSource(2) }
|
||||
gotSource := currentSource()
|
||||
// Hard coded line number, 35, in the "expectedSource" value
|
||||
expectedSource := "[namespace-lock_test.go:35:TestGetSource()]"
|
||||
// Hard coded line number, 34, in the "expectedSource" value
|
||||
expectedSource := "[namespace-lock_test.go:34:TestGetSource()]"
|
||||
if gotSource != expectedSource {
|
||||
t.Errorf("expected : %s, got : %s", expectedSource, gotSource)
|
||||
}
|
||||
@@ -44,7 +43,7 @@ func TestGetSource(t *testing.T) {
|
||||
func TestNSLockRace(t *testing.T) {
|
||||
t.Skip("long test skip it")
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
for i := 0; i < 10000; i++ {
|
||||
nsLk := newNSLock(false)
|
||||
|
||||
@@ -163,14 +163,14 @@ func testListObjectsVersionedFolders(obj ObjectLayer, instanceType string, t1 Te
|
||||
testCase.prefix, "marker:", testCase.marker, "delimiter:",
|
||||
testCase.delimiter, "maxkeys:", testCase.maxKeys)
|
||||
|
||||
resultV, err = obj.ListObjectVersions(context.Background(), testCase.bucketName,
|
||||
resultV, err = obj.ListObjectVersions(t.Context(), testCase.bucketName,
|
||||
testCase.prefix, testCase.marker, "", testCase.delimiter, testCase.maxKeys)
|
||||
} else {
|
||||
t.Log("ListObjects, bucket:", testCase.bucketName, "prefix:",
|
||||
testCase.prefix, "marker:", testCase.marker, "delimiter:",
|
||||
testCase.delimiter, "maxkeys:", testCase.maxKeys)
|
||||
|
||||
resultL, err = obj.ListObjects(context.Background(), testCase.bucketName,
|
||||
resultL, err = obj.ListObjects(t.Context(), testCase.bucketName,
|
||||
testCase.prefix, testCase.marker, testCase.delimiter, testCase.maxKeys)
|
||||
}
|
||||
if err != nil && testCase.shouldPass {
|
||||
@@ -944,7 +944,7 @@ func _testListObjects(obj ObjectLayer, instanceType string, t1 TestErrHandler, v
|
||||
testCase := testCase
|
||||
t.Run(fmt.Sprintf("%s-Test%d", instanceType, i+1), func(t *testing.T) {
|
||||
t.Log("ListObjects, bucket:", testCase.bucketName, "prefix:", testCase.prefix, "marker:", testCase.marker, "delimiter:", testCase.delimiter, "maxkeys:", testCase.maxKeys)
|
||||
result, err := obj.ListObjects(context.Background(), testCase.bucketName,
|
||||
result, err := obj.ListObjects(t.Context(), testCase.bucketName,
|
||||
testCase.prefix, testCase.marker, testCase.delimiter, int(testCase.maxKeys))
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: %s: Expected to pass, but failed with: <ERROR> %s", i+1, instanceType, err.Error())
|
||||
@@ -1675,7 +1675,7 @@ func testListObjectVersions(obj ObjectLayer, instanceType string, t1 TestErrHand
|
||||
for i, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(fmt.Sprintf("%s-Test%d", instanceType, i+1), func(t *testing.T) {
|
||||
result, err := obj.ListObjectVersions(context.Background(), testCase.bucketName,
|
||||
result, err := obj.ListObjectVersions(t.Context(), testCase.bucketName,
|
||||
testCase.prefix, testCase.marker, "", testCase.delimiter, int(testCase.maxKeys))
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("%s: Expected to pass, but failed with: <ERROR> %s", instanceType, err.Error())
|
||||
@@ -1830,7 +1830,7 @@ func testListObjectsContinuation(obj ObjectLayer, instanceType string, t1 TestEr
|
||||
var foundPrefixes []string
|
||||
marker := ""
|
||||
for {
|
||||
result, err := obj.ListObjects(context.Background(), testCase.bucketName,
|
||||
result, err := obj.ListObjects(t.Context(), testCase.bucketName,
|
||||
testCase.prefix, marker, testCase.delimiter, testCase.page)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: %s: Expected to pass, but failed with: <ERROR> %s", i+1, instanceType, err.Error())
|
||||
@@ -1905,7 +1905,7 @@ func BenchmarkListObjects(b *testing.B) {
|
||||
|
||||
bucket := "ls-benchmark-bucket"
|
||||
// Create a bucket.
|
||||
err := obj.MakeBucket(context.Background(), bucket, MakeBucketOptions{})
|
||||
err := obj.MakeBucket(b.Context(), bucket, MakeBucketOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -1913,7 +1913,7 @@ func BenchmarkListObjects(b *testing.B) {
|
||||
// Insert objects to be listed and benchmarked later.
|
||||
for i := 0; i < 20000; i++ {
|
||||
key := "obj" + strconv.Itoa(i)
|
||||
_, err = obj.PutObject(context.Background(), bucket, key, mustGetPutObjReader(b, bytes.NewBufferString(key), int64(len(key)), "", ""), ObjectOptions{})
|
||||
_, err = obj.PutObject(b.Context(), bucket, key, mustGetPutObjReader(b, bytes.NewBufferString(key), int64(len(key)), "", ""), ObjectOptions{})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -1923,7 +1923,7 @@ func BenchmarkListObjects(b *testing.B) {
|
||||
|
||||
// List the buckets over and over and over.
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err = obj.ListObjects(context.Background(), bucket, "", "obj9000", "", -1)
|
||||
_, err = obj.ListObjects(b.Context(), bucket, "", "obj9000", "", -1)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1378,6 +1378,24 @@ func testListObjectPartsStale(obj ObjectLayer, instanceType string, disks []stri
|
||||
},
|
||||
},
|
||||
},
|
||||
// partinfos - 4.
|
||||
{
|
||||
Bucket: bucketNames[0],
|
||||
Object: objectNames[0],
|
||||
MaxParts: 2,
|
||||
IsTruncated: false,
|
||||
UploadID: uploadIDs[0],
|
||||
PartNumberMarker: 4,
|
||||
},
|
||||
// partinfos - 5.
|
||||
{
|
||||
Bucket: bucketNames[0],
|
||||
Object: objectNames[0],
|
||||
MaxParts: 2,
|
||||
IsTruncated: false,
|
||||
UploadID: uploadIDs[0],
|
||||
PartNumberMarker: 100,
|
||||
},
|
||||
}
|
||||
|
||||
// Collection of non-exhaustive ListObjectParts test cases, valid errors
|
||||
@@ -1412,10 +1430,14 @@ func testListObjectPartsStale(obj ObjectLayer, instanceType string, disks []stri
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], 0, 10, partInfos[0], nil, true},
|
||||
// Test case with maxParts set to less than number of parts (Test number 13).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], 0, 3, partInfos[1], nil, true},
|
||||
// Test case with partNumberMarker set (Test number 14)-.
|
||||
// Test case with partNumberMarker set (Test number 14).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], 0, 2, partInfos[2], nil, true},
|
||||
// Test case with partNumberMarker set (Test number 15)-.
|
||||
// Test case with partNumberMarker set (Test number 15).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], 3, 2, partInfos[3], nil, true},
|
||||
// Test case with partNumberMarker set (Test number 16).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], 4, 2, partInfos[4], nil, true},
|
||||
// Test case with partNumberMarker set (Test number 17).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], 100, 2, partInfos[5], nil, true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
@@ -2148,7 +2170,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T
|
||||
testCase := testCase
|
||||
t.(*testing.T).Run("", func(t *testing.T) {
|
||||
opts = ObjectOptions{}
|
||||
actualResult, actualErr := obj.CompleteMultipartUpload(context.Background(), testCase.bucket, testCase.object, testCase.uploadID, testCase.parts, ObjectOptions{})
|
||||
actualResult, actualErr := obj.CompleteMultipartUpload(t.Context(), testCase.bucket, testCase.object, testCase.uploadID, testCase.parts, ObjectOptions{})
|
||||
if actualErr != nil && testCase.shouldPass {
|
||||
t.Errorf("%s: Expected to pass, but failed with: <ERROR> %s", instanceType, actualErr)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
@@ -32,7 +31,7 @@ import (
|
||||
func TestGetAndValidateAttributesOpts(t *testing.T) {
|
||||
globalBucketVersioningSys = &BucketVersioningSys{}
|
||||
bucket := minioMetaBucket
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
testCases := []struct {
|
||||
name string
|
||||
headers http.Header
|
||||
|
||||
@@ -19,7 +19,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
@@ -108,7 +107,7 @@ func TestCheckPreconditions(t *testing.T) {
|
||||
request.Header.Set(xhttp.IfModifiedSince, tc.ifModifiedSince)
|
||||
request.Header.Set(xhttp.IfMatch, tc.ifMatch)
|
||||
request.Header.Set(xhttp.IfUnmodifiedSince, tc.ifUnmodifiedSince)
|
||||
actualFlag := checkPreconditions(context.Background(), recorder, request, tc.objInfo, ObjectOptions{})
|
||||
actualFlag := checkPreconditions(t.Context(), recorder, request, tc.objInfo, ObjectOptions{})
|
||||
if tc.expectedFlag != actualFlag {
|
||||
t.Errorf("test: %s, got flag: %v, want: %v", tc.name, actualFlag, tc.expectedFlag)
|
||||
}
|
||||
@@ -170,7 +169,7 @@ func TestCheckPreconditions(t *testing.T) {
|
||||
request.Header.Set(xhttp.IfModifiedSince, tc.ifModifiedSince)
|
||||
request.Header.Set(xhttp.IfMatch, tc.ifMatch)
|
||||
request.Header.Set(xhttp.IfUnmodifiedSince, tc.ifUnmodifiedSince)
|
||||
actualFlag := checkPreconditions(context.Background(), recorder, request, tc.objInfo, ObjectOptions{})
|
||||
actualFlag := checkPreconditions(t.Context(), recorder, request, tc.objInfo, ObjectOptions{})
|
||||
if tc.expectedFlag != actualFlag {
|
||||
t.Errorf("test: %s, got flag: %v, want: %v", tc.name, actualFlag, tc.expectedFlag)
|
||||
}
|
||||
|
||||
+24
-4
@@ -47,6 +47,7 @@ import (
|
||||
"github.com/minio/minio/internal/bucket/bandwidth"
|
||||
"github.com/minio/minio/internal/color"
|
||||
"github.com/minio/minio/internal/config"
|
||||
"github.com/minio/minio/internal/config/api"
|
||||
"github.com/minio/minio/internal/handlers"
|
||||
"github.com/minio/minio/internal/hash/sha256"
|
||||
xhttp "github.com/minio/minio/internal/http"
|
||||
@@ -792,10 +793,6 @@ func serverMain(ctx *cli.Context) {
|
||||
// Handle all server environment vars.
|
||||
serverHandleEnvVars()
|
||||
|
||||
// Load the root credentials from the shell environment or from
|
||||
// the config file if not defined, set the default one.
|
||||
loadRootCredentials()
|
||||
|
||||
// Perform any self-tests
|
||||
bootstrapTrace("selftests", func() {
|
||||
bitrotSelfTest()
|
||||
@@ -806,6 +803,29 @@ func serverMain(ctx *cli.Context) {
|
||||
// Initialize KMS configuration
|
||||
bootstrapTrace("handleKMSConfig", handleKMSConfig)
|
||||
|
||||
// Load the root credentials from the shell environment or from
|
||||
// the config file if not defined, set the default one.
|
||||
bootstrapTrace("rootCredentials", func() {
|
||||
cred := loadRootCredentials()
|
||||
if !cred.IsValid() && (env.Get(api.EnvAPIRootAccess, config.EnableOn) == config.EnableOff) {
|
||||
// Generate KMS based credentials if root access is disabled
|
||||
// and no ENV is set.
|
||||
cred = autoGenerateRootCredentials()
|
||||
}
|
||||
|
||||
if !cred.IsValid() {
|
||||
cred = auth.DefaultCredentials
|
||||
}
|
||||
|
||||
var err error
|
||||
globalNodeAuthToken, err = authenticateNode(cred.AccessKey, cred.SecretKey)
|
||||
if err != nil {
|
||||
logger.Fatal(err, "Unable to generate internode credentials")
|
||||
}
|
||||
|
||||
globalActiveCred = cred
|
||||
})
|
||||
|
||||
// Initialize all help
|
||||
bootstrapTrace("initHelp", initHelp)
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestServerConfigFile(t *testing.T) {
|
||||
|
||||
// Tests initializing new object layer.
|
||||
func TestNewObjectLayer(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
// Tests for ErasureSD object layer.
|
||||
nDisks := 1
|
||||
|
||||
@@ -49,7 +49,7 @@ func TestStripStandardPorts(t *testing.T) {
|
||||
|
||||
// Test printing server common message.
|
||||
func TestPrintServerCommonMessage(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
@@ -67,7 +67,7 @@ func TestPrintServerCommonMessage(t *testing.T) {
|
||||
|
||||
// Tests print cli access message.
|
||||
func TestPrintCLIAccessMsg(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
@@ -85,7 +85,7 @@ func TestPrintCLIAccessMsg(t *testing.T) {
|
||||
|
||||
// Test print startup message.
|
||||
func TestPrintStartupMessage(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestResourceListSorting(t *testing.T) {
|
||||
|
||||
// Tests presigned v2 signature.
|
||||
func TestDoesPresignedV2SignatureMatch(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
@@ -164,7 +164,7 @@ func TestDoesPresignedV2SignatureMatch(t *testing.T) {
|
||||
|
||||
// TestValidateV2AuthHeader - Tests validate the logic of V2 Authorization header validator.
|
||||
func TestValidateV2AuthHeader(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
@@ -238,7 +238,7 @@ func TestValidateV2AuthHeader(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDoesPolicySignatureV2Match(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
)
|
||||
|
||||
func TestCheckValid(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
objLayer, fsDir, err := prepareFS(ctx)
|
||||
|
||||
@@ -37,7 +37,7 @@ func niceError(code APIErrorCode) string {
|
||||
}
|
||||
|
||||
func TestDoesPolicySignatureMatch(t *testing.T) {
|
||||
_, fsDir, err := prepareFS(context.Background())
|
||||
_, fsDir, err := prepareFS(t.Context())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -100,7 +100,7 @@ func TestDoesPolicySignatureMatch(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDoesPresignedSignatureMatch(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
obj, fsDir, err := prepareFS(ctx)
|
||||
|
||||
@@ -1156,7 +1156,7 @@ func checkDiskFatalErrs(errs []error) error {
|
||||
}
|
||||
|
||||
if countErrs(errs, errFileAccessDenied) == len(errs) {
|
||||
return errDiskAccessDenied
|
||||
return errFileAccessDenied
|
||||
}
|
||||
|
||||
if countErrs(errs, errDiskNotDir) == len(errs) {
|
||||
|
||||
+19
-20
@@ -19,7 +19,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
@@ -41,7 +40,7 @@ func testStorageAPIDiskInfo(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
_, err := storage.DiskInfo(context.Background(), DiskInfoOptions{Metrics: true})
|
||||
_, err := storage.DiskInfo(t.Context(), DiskInfoOptions{Metrics: true})
|
||||
expectErr := (err != nil)
|
||||
|
||||
if expectErr != testCase.expectErr {
|
||||
@@ -54,7 +53,7 @@ func testStorageAPIDiskInfo(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
func testStorageAPIStatInfoFile(t *testing.T, storage StorageAPI) {
|
||||
err := storage.AppendFile(context.Background(), "foo", pathJoin("myobject", xlStorageFormatFile), []byte("foo"))
|
||||
err := storage.AppendFile(t.Context(), "foo", pathJoin("myobject", xlStorageFormatFile), []byte("foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
@@ -70,7 +69,7 @@ func testStorageAPIStatInfoFile(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
_, err := storage.StatInfoFile(context.Background(), testCase.volumeName, testCase.objectName+"/"+xlStorageFormatFile, false)
|
||||
_, err := storage.StatInfoFile(t.Context(), testCase.volumeName, testCase.objectName+"/"+xlStorageFormatFile, false)
|
||||
expectErr := (err != nil)
|
||||
|
||||
if expectErr != testCase.expectErr {
|
||||
@@ -80,7 +79,7 @@ func testStorageAPIStatInfoFile(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
func testStorageAPIListDir(t *testing.T, storage StorageAPI) {
|
||||
err := storage.AppendFile(context.Background(), "foo", "path/to/myobject", []byte("foo"))
|
||||
err := storage.AppendFile(t.Context(), "foo", "path/to/myobject", []byte("foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
@@ -97,7 +96,7 @@ func testStorageAPIListDir(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
result, err := storage.ListDir(context.Background(), "", testCase.volumeName, testCase.prefix, -1)
|
||||
result, err := storage.ListDir(t.Context(), "", testCase.volumeName, testCase.prefix, -1)
|
||||
expectErr := (err != nil)
|
||||
|
||||
if expectErr != testCase.expectErr {
|
||||
@@ -113,7 +112,7 @@ func testStorageAPIListDir(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
func testStorageAPIReadAll(t *testing.T, storage StorageAPI) {
|
||||
err := storage.AppendFile(context.Background(), "foo", "myobject", []byte("foo"))
|
||||
err := storage.AppendFile(t.Context(), "foo", "myobject", []byte("foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
@@ -130,7 +129,7 @@ func testStorageAPIReadAll(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
result, err := storage.ReadAll(context.Background(), testCase.volumeName, testCase.objectName)
|
||||
result, err := storage.ReadAll(t.Context(), testCase.volumeName, testCase.objectName)
|
||||
expectErr := (err != nil)
|
||||
|
||||
if expectErr != testCase.expectErr {
|
||||
@@ -146,7 +145,7 @@ func testStorageAPIReadAll(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
func testStorageAPIReadFile(t *testing.T, storage StorageAPI) {
|
||||
err := storage.AppendFile(context.Background(), "foo", "myobject", []byte("foo"))
|
||||
err := storage.AppendFile(t.Context(), "foo", "myobject", []byte("foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
@@ -167,7 +166,7 @@ func testStorageAPIReadFile(t *testing.T, storage StorageAPI) {
|
||||
result := make([]byte, 100)
|
||||
for i, testCase := range testCases {
|
||||
result = result[testCase.offset:3]
|
||||
_, err := storage.ReadFile(context.Background(), testCase.volumeName, testCase.objectName, testCase.offset, result, nil)
|
||||
_, err := storage.ReadFile(t.Context(), testCase.volumeName, testCase.objectName, testCase.offset, result, nil)
|
||||
expectErr := (err != nil)
|
||||
|
||||
if expectErr != testCase.expectErr {
|
||||
@@ -209,7 +208,7 @@ func testStorageAPIAppendFile(t *testing.T, storage StorageAPI) {
|
||||
if testCase.ignoreIfWindows && runtime.GOOS == "windows" {
|
||||
continue
|
||||
}
|
||||
err := storage.AppendFile(context.Background(), testCase.volumeName, testCase.objectName, testCase.data)
|
||||
err := storage.AppendFile(t.Context(), testCase.volumeName, testCase.objectName, testCase.data)
|
||||
expectErr := (err != nil)
|
||||
|
||||
if expectErr != testCase.expectErr {
|
||||
@@ -217,7 +216,7 @@ func testStorageAPIAppendFile(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
if !testCase.expectErr {
|
||||
data, err := storage.ReadAll(context.Background(), testCase.volumeName, testCase.objectName)
|
||||
data, err := storage.ReadAll(t.Context(), testCase.volumeName, testCase.objectName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -230,7 +229,7 @@ func testStorageAPIAppendFile(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
func testStorageAPIDeleteFile(t *testing.T, storage StorageAPI) {
|
||||
err := storage.AppendFile(context.Background(), "foo", "myobject", []byte("foo"))
|
||||
err := storage.AppendFile(t.Context(), "foo", "myobject", []byte("foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
@@ -248,7 +247,7 @@ func testStorageAPIDeleteFile(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
err := storage.Delete(context.Background(), testCase.volumeName, testCase.objectName, DeleteOptions{
|
||||
err := storage.Delete(t.Context(), testCase.volumeName, testCase.objectName, DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -261,12 +260,12 @@ func testStorageAPIDeleteFile(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
func testStorageAPIRenameFile(t *testing.T, storage StorageAPI) {
|
||||
err := storage.AppendFile(context.Background(), "foo", "myobject", []byte("foo"))
|
||||
err := storage.AppendFile(t.Context(), "foo", "myobject", []byte("foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
err = storage.AppendFile(context.Background(), "foo", "otherobject", []byte("foo"))
|
||||
err = storage.AppendFile(t.Context(), "foo", "otherobject", []byte("foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
@@ -285,7 +284,7 @@ func testStorageAPIRenameFile(t *testing.T, storage StorageAPI) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
err := storage.RenameFile(context.Background(), testCase.volumeName, testCase.objectName, testCase.destVolumeName, testCase.destObjectName)
|
||||
err := storage.RenameFile(t.Context(), testCase.volumeName, testCase.objectName, testCase.destVolumeName, testCase.destObjectName)
|
||||
expectErr := (err != nil)
|
||||
|
||||
if expectErr != testCase.expectErr {
|
||||
@@ -341,11 +340,11 @@ func newStorageRESTHTTPServerClient(t testing.TB) *storageRESTClient {
|
||||
registerStorageRESTHandlers(tg.Mux[1], poolEps, tg.Managers[1])
|
||||
|
||||
storage := globalLocalSetDrives[0][0][0]
|
||||
if err = storage.MakeVol(context.Background(), "foo"); err != nil {
|
||||
if err = storage.MakeVol(t.Context(), "foo"); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
if err = storage.MakeVol(context.Background(), "bar"); err != nil {
|
||||
if err = storage.MakeVol(t.Context(), "bar"); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
@@ -355,7 +354,7 @@ func newStorageRESTHTTPServerClient(t testing.TB) *storageRESTClient {
|
||||
}
|
||||
|
||||
for {
|
||||
_, err := restClient.DiskInfo(context.Background(), DiskInfoOptions{})
|
||||
_, err := restClient.DiskInfo(t.Context(), DiskInfoOptions{})
|
||||
if err == nil || errors.Is(err, errUnformattedDisk) {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -947,7 +947,7 @@ func TestIAMExportImportWithLDAP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIAMImportAssetWithLDAP(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testDefaultTimeout)
|
||||
ctx, cancel := context.WithTimeout(t.Context(), testDefaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
exportContentStrings := map[string]string{
|
||||
|
||||
@@ -1932,7 +1932,7 @@ func ExecObjectLayerTestWithDirs(t TestErrHandler, objTest objTestTypeWithDirs)
|
||||
// ExecObjectLayerDiskAlteredTest - executes object layer tests while altering
|
||||
// disks in between tests. Creates Erasure ObjectLayer instance and runs test for Erasure layer.
|
||||
func ExecObjectLayerDiskAlteredTest(t *testing.T, objTest objTestDiskNotFoundType) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
objLayer, fsDirs, err := prepareErasure16(ctx)
|
||||
@@ -1956,7 +1956,7 @@ type objTestStaleFilesType func(obj ObjectLayer, instanceType string, dirs []str
|
||||
// ExecObjectLayerStaleFilesTest - executes object layer tests those leaves stale
|
||||
// files/directories under .minio/tmp. Creates Erasure ObjectLayer instance and runs test for Erasure layer.
|
||||
func ExecObjectLayerStaleFilesTest(t *testing.T, objTest objTestStaleFilesType) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
nDisks := 16
|
||||
@@ -2274,7 +2274,7 @@ func TestToErrIsNil(t *testing.T) {
|
||||
if toStorageErr(nil) != nil {
|
||||
t.Errorf("Test expected to return nil, failed instead got a non-nil value %s", toStorageErr(nil))
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
if toAPIError(ctx, nil) != noError {
|
||||
t.Errorf("Test expected error code to be ErrNone, failed instead provided %s", toAPIError(ctx, nil).Code)
|
||||
}
|
||||
|
||||
@@ -75,6 +75,9 @@ var errNoSuchServiceAccount = errors.New("Specified service account does not exi
|
||||
// error returned when temporary account is not found
|
||||
var errNoSuchTempAccount = errors.New("Specified temporary account does not exist")
|
||||
|
||||
// error returned when access key is not found
|
||||
var errNoSuchAccessKey = errors.New("Specified access key does not exist")
|
||||
|
||||
// error returned in IAM subsystem when an account doesn't exist.
|
||||
var errNoSuchAccount = errors.New("Specified account does not exist")
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/minio/minio/internal/auth"
|
||||
)
|
||||
|
||||
// getUserWithProvider - returns the appropriate internal username based on the user provider.
|
||||
@@ -55,3 +57,85 @@ func getUserWithProvider(ctx context.Context, userProvider, user string, validat
|
||||
return "", errIAMActionNotAllowed
|
||||
}
|
||||
}
|
||||
|
||||
// guessUserProvider - guesses the user provider based on the access key and claims.
|
||||
func guessUserProvider(credentials auth.Credentials) string {
|
||||
if !credentials.IsServiceAccount() && !credentials.IsTemp() {
|
||||
return madmin.BuiltinProvider // regular users are always internal
|
||||
}
|
||||
|
||||
claims := credentials.Claims
|
||||
if _, ok := claims[ldapUser]; ok {
|
||||
return madmin.LDAPProvider // ldap users
|
||||
}
|
||||
|
||||
if _, ok := claims[subClaim]; ok {
|
||||
providerPrefix, _, found := strings.Cut(credentials.ParentUser, getKeySeparator())
|
||||
if found {
|
||||
return providerPrefix // this is true for certificate and custom providers
|
||||
}
|
||||
return madmin.OpenIDProvider // openid users are already hashed, so no separator
|
||||
}
|
||||
|
||||
return madmin.BuiltinProvider // default to internal
|
||||
}
|
||||
|
||||
// getProviderInfoFromClaims - returns the provider info from the claims.
|
||||
func populateProviderInfoFromClaims(claims map[string]interface{}, provider string, resp *madmin.InfoAccessKeyResp) {
|
||||
resp.UserProvider = provider
|
||||
switch provider {
|
||||
case madmin.LDAPProvider:
|
||||
resp.LDAPSpecificInfo = getLDAPInfoFromClaims(claims)
|
||||
case madmin.OpenIDProvider:
|
||||
resp.OpenIDSpecificInfo = getOpenIDInfoFromClaims(claims)
|
||||
}
|
||||
}
|
||||
|
||||
func getOpenIDCfgNameFromClaims(claims map[string]interface{}) (string, bool) {
|
||||
roleArn := claims[roleArnClaim]
|
||||
|
||||
s := globalServerConfig.Clone()
|
||||
configs, err := globalIAMSys.OpenIDConfig.GetConfigList(s)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
for _, cfg := range configs {
|
||||
if cfg.RoleARN == roleArn {
|
||||
return cfg.Name, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func getOpenIDInfoFromClaims(claims map[string]interface{}) madmin.OpenIDSpecificAccessKeyInfo {
|
||||
info := madmin.OpenIDSpecificAccessKeyInfo{}
|
||||
|
||||
cfgName, ok := getOpenIDCfgNameFromClaims(claims)
|
||||
if !ok {
|
||||
return info
|
||||
}
|
||||
|
||||
info.ConfigName = cfgName
|
||||
if displayNameClaim := globalIAMSys.OpenIDConfig.GetUserReadableClaim(cfgName); displayNameClaim != "" {
|
||||
name, _ := claims[displayNameClaim].(string)
|
||||
info.DisplayName = name
|
||||
info.DisplayNameClaim = displayNameClaim
|
||||
}
|
||||
if idClaim := globalIAMSys.OpenIDConfig.GetUserIDClaim(cfgName); idClaim != "" {
|
||||
id, _ := claims[idClaim].(string)
|
||||
info.UserID = id
|
||||
info.UserIDClaim = idClaim
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
func getLDAPInfoFromClaims(claims map[string]interface{}) madmin.LDAPSpecificAccessKeyInfo {
|
||||
info := madmin.LDAPSpecificAccessKeyInfo{}
|
||||
|
||||
if name, ok := claims[ldapUser].(string); ok {
|
||||
info.Username = name
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
@@ -825,7 +825,7 @@ func decodeXLHeaders(buf []byte) (versions int, headerV, metaV uint8, b []byte,
|
||||
return 0, 0, 0, buf, err
|
||||
}
|
||||
if hdrVer > xlHeaderVersion {
|
||||
return 0, 0, 0, buf, fmt.Errorf("decodeXLHeaders: Unknown xl header version %d", metaVer)
|
||||
return 0, 0, 0, buf, fmt.Errorf("decodeXLHeaders: Unknown xl header version %d", hdrVer)
|
||||
}
|
||||
if metaVer > xlMetaVersion {
|
||||
return 0, 0, 0, buf, fmt.Errorf("decodeXLHeaders: Unknown xl meta version %d", metaVer)
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
@@ -1082,7 +1081,7 @@ func Test_mergeEntryChannels(t *testing.T) {
|
||||
entries = append(entries, ch)
|
||||
}
|
||||
out := make(chan metaCacheEntry, 1)
|
||||
err := mergeEntryChannels(context.Background(), entries, out, 1)
|
||||
err := mergeEntryChannels(t.Context(), entries, out, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
+82
-83
@@ -19,7 +19,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"net/url"
|
||||
@@ -142,7 +141,7 @@ func newXLStorageTestSetup(tb testing.TB) (*xlStorageDiskIDCheck, string, error)
|
||||
}
|
||||
|
||||
// Create a sample format.json file
|
||||
if err = storage.WriteAll(context.Background(), minioMetaBucket, formatConfigFile, []byte(`{"version":"1","format":"xl","id":"592a41c2-b7cc-4130-b883-c4b5cb15965b","xl":{"version":"3","this":"da017d62-70e3-45f1-8a1a-587707e69ad1","sets":[["e07285a6-8c73-4962-89c6-047fb939f803","33b8d431-482d-4376-b63c-626d229f0a29","cff6513a-4439-4dc1-bcaa-56c9e880c352","da017d62-70e3-45f1-8a1a-587707e69ad1","9c9f21d5-1f15-4737-bce6-835faa0d9626","0a59b346-1424-4fc2-9fa2-a2e80541d0c1","7924a3dc-b69a-4971-9a2e-014966d6aebb","4d2b8dd9-4e48-444b-bdca-c89194b26042"]],"distributionAlgo":"CRCMOD"}}`)); err != nil {
|
||||
if err = storage.WriteAll(tb.Context(), minioMetaBucket, formatConfigFile, []byte(`{"version":"1","format":"xl","id":"592a41c2-b7cc-4130-b883-c4b5cb15965b","xl":{"version":"3","this":"da017d62-70e3-45f1-8a1a-587707e69ad1","sets":[["e07285a6-8c73-4962-89c6-047fb939f803","33b8d431-482d-4376-b63c-626d229f0a29","cff6513a-4439-4dc1-bcaa-56c9e880c352","da017d62-70e3-45f1-8a1a-587707e69ad1","9c9f21d5-1f15-4737-bce6-835faa0d9626","0a59b346-1424-4fc2-9fa2-a2e80541d0c1","7924a3dc-b69a-4971-9a2e-014966d6aebb","4d2b8dd9-4e48-444b-bdca-c89194b26042"]],"distributionAlgo":"CRCMOD"}}`)); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
@@ -243,15 +242,15 @@ func TestXLStorageReadVersionLegacy(t *testing.T) {
|
||||
}
|
||||
|
||||
// Create files for the test cases.
|
||||
if err = xlStorage.MakeVol(context.Background(), "exists-legacy"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "exists-legacy"); err != nil {
|
||||
t.Fatalf("Unable to create a volume \"exists-legacy\", %s", err)
|
||||
}
|
||||
|
||||
if err = xlStorage.AppendFile(context.Background(), "exists-legacy", "as-file/xl.json", []byte(legacyJSON)); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "exists-legacy", "as-file/xl.json", []byte(legacyJSON)); err != nil {
|
||||
t.Fatalf("Unable to create a file \"as-file\", %s", err)
|
||||
}
|
||||
|
||||
fi, err := xlStorage.ReadVersion(context.Background(), "", "exists-legacy", "as-file", "", ReadOptions{})
|
||||
fi, err := xlStorage.ReadVersion(t.Context(), "", "exists-legacy", "as-file", "", ReadOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read older 'xl.json' content: %s", err)
|
||||
}
|
||||
@@ -273,19 +272,19 @@ func TestXLStorageReadVersion(t *testing.T) {
|
||||
fi, _ := getFileInfo(xlMeta, "exists", "as-file", "", fileInfoOpts{Data: false})
|
||||
|
||||
// Create files for the test cases.
|
||||
if err = xlStorage.MakeVol(context.Background(), "exists"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "exists"); err != nil {
|
||||
t.Fatalf("Unable to create a volume \"exists\", %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "exists", "as-directory/as-file/xl.meta", xlMeta); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "exists", "as-directory/as-file/xl.meta", xlMeta); err != nil {
|
||||
t.Fatalf("Unable to create a file \"as-directory/as-file\", %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "exists", "as-file/xl.meta", xlMeta); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "exists", "as-file/xl.meta", xlMeta); err != nil {
|
||||
t.Fatalf("Unable to create a file \"as-file\", %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "exists", "as-file-parent/xl.meta", xlMeta); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "exists", "as-file-parent/xl.meta", xlMeta); err != nil {
|
||||
t.Fatalf("Unable to create a file \"as-file-parent\", %s", err)
|
||||
}
|
||||
if err = xlStorage.MakeVol(context.Background(), "exists/as-file/"+fi.DataDir); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "exists/as-file/"+fi.DataDir); err != nil {
|
||||
t.Fatalf("Unable to create a dataDir %s, %s", fi.DataDir, err)
|
||||
}
|
||||
|
||||
@@ -341,7 +340,7 @@ func TestXLStorageReadVersion(t *testing.T) {
|
||||
|
||||
// Run through all the test cases and validate for ReadVersion.
|
||||
for i, testCase := range testCases {
|
||||
_, err = xlStorage.ReadVersion(context.Background(), "", testCase.volume, testCase.path, "", ReadOptions{})
|
||||
_, err = xlStorage.ReadVersion(t.Context(), "", testCase.volume, testCase.path, "", ReadOptions{})
|
||||
if err != testCase.err {
|
||||
t.Fatalf("TestXLStorage %d: Expected err \"%s\", got err \"%s\"", i+1, testCase.err, err)
|
||||
}
|
||||
@@ -357,16 +356,16 @@ func TestXLStorageReadAll(t *testing.T) {
|
||||
}
|
||||
|
||||
// Create files for the test cases.
|
||||
if err = xlStorage.MakeVol(context.Background(), "exists"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "exists"); err != nil {
|
||||
t.Fatalf("Unable to create a volume \"exists\", %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "exists", "as-directory/as-file", []byte("Hello, World")); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "exists", "as-directory/as-file", []byte("Hello, World")); err != nil {
|
||||
t.Fatalf("Unable to create a file \"as-directory/as-file\", %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "exists", "as-file", []byte("Hello, World")); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "exists", "as-file", []byte("Hello, World")); err != nil {
|
||||
t.Fatalf("Unable to create a file \"as-file\", %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "exists", "as-file-parent", []byte("Hello, World")); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "exists", "as-file-parent", []byte("Hello, World")); err != nil {
|
||||
t.Fatalf("Unable to create a file \"as-file-parent\", %s", err)
|
||||
}
|
||||
|
||||
@@ -423,7 +422,7 @@ func TestXLStorageReadAll(t *testing.T) {
|
||||
var dataRead []byte
|
||||
// Run through all the test cases and validate for ReadAll.
|
||||
for i, testCase := range testCases {
|
||||
dataRead, err = xlStorage.ReadAll(context.Background(), testCase.volume, testCase.path)
|
||||
dataRead, err = xlStorage.ReadAll(t.Context(), testCase.volume, testCase.path)
|
||||
if err != testCase.err {
|
||||
t.Errorf("TestXLStorage %d: Expected err \"%v\", got err \"%v\"", i+1, testCase.err, err)
|
||||
continue
|
||||
@@ -529,7 +528,7 @@ func TestXLStorageMakeVol(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
if err := xlStorage.MakeVol(context.Background(), testCase.volName); err != testCase.expectedErr {
|
||||
if err := xlStorage.MakeVol(t.Context(), testCase.volName); err != testCase.expectedErr {
|
||||
t.Fatalf("TestXLStorage %d: Expected: \"%s\", got: \"%s\"", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
}
|
||||
@@ -561,7 +560,7 @@ func TestXLStorageMakeVol(t *testing.T) {
|
||||
t.Fatalf("Unable to change permission to temporary directory %v. %v", permDeniedDir, err)
|
||||
}
|
||||
|
||||
if err := xlStorageNew.MakeVol(context.Background(), "test-vol"); err != errDiskAccessDenied {
|
||||
if err := xlStorageNew.MakeVol(t.Context(), "test-vol"); err != errDiskAccessDenied {
|
||||
t.Fatalf("expected: %s, got: %s", errDiskAccessDenied, err)
|
||||
}
|
||||
}
|
||||
@@ -576,7 +575,7 @@ func TestXLStorageDeleteVol(t *testing.T) {
|
||||
}
|
||||
|
||||
// Setup test environment.
|
||||
if err = xlStorage.MakeVol(context.Background(), "success-vol"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "success-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
|
||||
@@ -620,7 +619,7 @@ func TestXLStorageDeleteVol(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
if err = xlStorage.DeleteVol(context.Background(), testCase.volName, false); err != testCase.expectedErr {
|
||||
if err = xlStorage.DeleteVol(t.Context(), testCase.volName, false); err != testCase.expectedErr {
|
||||
t.Fatalf("TestXLStorage: %d, expected: %s, got: %s", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
}
|
||||
@@ -662,7 +661,7 @@ func TestXLStorageDeleteVol(t *testing.T) {
|
||||
t.Fatalf("Unable to change permission to temporary directory %v. %v", permDeniedDir, err)
|
||||
}
|
||||
|
||||
if err = xlStorageNew.DeleteVol(context.Background(), "mybucket", false); err != errDiskAccessDenied {
|
||||
if err = xlStorageNew.DeleteVol(t.Context(), "mybucket", false); err != errDiskAccessDenied {
|
||||
t.Fatalf("expected: Permission error, got: %s", err)
|
||||
}
|
||||
}
|
||||
@@ -676,7 +675,7 @@ func TestXLStorageDeleteVol(t *testing.T) {
|
||||
|
||||
// TestXLStorage for delete on an removed disk.
|
||||
// should fail with disk not found.
|
||||
err = xlStorageDeletedStorage.DeleteVol(context.Background(), "Del-Vol", false)
|
||||
err = xlStorageDeletedStorage.DeleteVol(t.Context(), "Del-Vol", false)
|
||||
if err != errDiskNotFound {
|
||||
t.Errorf("Expected: \"Drive not found\", got \"%s\"", err)
|
||||
}
|
||||
@@ -691,7 +690,7 @@ func TestXLStorageStatVol(t *testing.T) {
|
||||
}
|
||||
|
||||
// Setup test environment.
|
||||
if err = xlStorage.MakeVol(context.Background(), "success-vol"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "success-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
|
||||
@@ -718,7 +717,7 @@ func TestXLStorageStatVol(t *testing.T) {
|
||||
|
||||
for i, testCase := range testCases {
|
||||
var volInfo VolInfo
|
||||
volInfo, err = xlStorage.StatVol(context.Background(), testCase.volName)
|
||||
volInfo, err = xlStorage.StatVol(t.Context(), testCase.volName)
|
||||
if err != testCase.expectedErr {
|
||||
t.Fatalf("TestXLStorage case : %d, Expected: \"%s\", got: \"%s\"", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
@@ -740,7 +739,7 @@ func TestXLStorageStatVol(t *testing.T) {
|
||||
|
||||
// TestXLStorage for delete on an removed disk.
|
||||
// should fail with disk not found.
|
||||
_, err = xlStorageDeletedStorage.StatVol(context.Background(), "Stat vol")
|
||||
_, err = xlStorageDeletedStorage.StatVol(t.Context(), "Stat vol")
|
||||
if err != errDiskNotFound {
|
||||
t.Errorf("Expected: \"Drive not found\", got \"%s\"", err)
|
||||
}
|
||||
@@ -756,18 +755,18 @@ func TestXLStorageListVols(t *testing.T) {
|
||||
|
||||
var volInfos []VolInfo
|
||||
// TestXLStorage empty list vols.
|
||||
if volInfos, err = xlStorage.ListVols(context.Background()); err != nil {
|
||||
if volInfos, err = xlStorage.ListVols(t.Context()); err != nil {
|
||||
t.Fatalf("expected: <nil>, got: %s", err)
|
||||
} else if len(volInfos) != 1 {
|
||||
t.Fatalf("expected: one entry, got: %v", volInfos)
|
||||
}
|
||||
|
||||
// TestXLStorage non-empty list vols.
|
||||
if err = xlStorage.MakeVol(context.Background(), "success-vol"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "success-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
|
||||
volInfos, err = xlStorage.ListVols(context.Background())
|
||||
volInfos, err = xlStorage.ListVols(t.Context())
|
||||
if err != nil {
|
||||
t.Fatalf("expected: <nil>, got: %s", err)
|
||||
}
|
||||
@@ -788,7 +787,7 @@ func TestXLStorageListVols(t *testing.T) {
|
||||
// removing the path and simulating disk failure
|
||||
os.RemoveAll(path)
|
||||
// should fail with errDiskNotFound.
|
||||
if _, err = xlStorage.ListVols(context.Background()); err != errDiskNotFound {
|
||||
if _, err = xlStorage.ListVols(t.Context()); err != errDiskNotFound {
|
||||
t.Errorf("Expected to fail with \"%s\", but instead failed with \"%s\"", errDiskNotFound, err)
|
||||
}
|
||||
}
|
||||
@@ -809,13 +808,13 @@ func TestXLStorageListDir(t *testing.T) {
|
||||
// removing the disk, used to recreate disk not found error.
|
||||
os.RemoveAll(diskPath)
|
||||
// Setup test environment.
|
||||
if err = xlStorage.MakeVol(context.Background(), "success-vol"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "success-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "success-vol", "abc/def/ghi/success-file", []byte("Hello, world")); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "success-vol", "abc/def/ghi/success-file", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "success-vol", "abc/xyz/ghi/success-file", []byte("Hello, world")); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "success-vol", "abc/xyz/ghi/success-file", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
|
||||
@@ -874,7 +873,7 @@ func TestXLStorageListDir(t *testing.T) {
|
||||
|
||||
for i, testCase := range testCases {
|
||||
var dirList []string
|
||||
dirList, err = xlStorage.ListDir(context.Background(), "", testCase.srcVol, testCase.srcPath, -1)
|
||||
dirList, err = xlStorage.ListDir(t.Context(), "", testCase.srcVol, testCase.srcPath, -1)
|
||||
if err != testCase.expectedErr {
|
||||
t.Errorf("TestXLStorage case %d: Expected: \"%s\", got: \"%s\"", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
@@ -906,7 +905,7 @@ func TestXLStorageListDir(t *testing.T) {
|
||||
t.Fatalf("Unable to initialize xlStorage, %s", err)
|
||||
}
|
||||
|
||||
if err = xlStorageNew.Delete(context.Background(), "mybucket", "myobject", DeleteOptions{
|
||||
if err = xlStorageNew.Delete(t.Context(), "mybucket", "myobject", DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
}); err != errFileAccessDenied {
|
||||
@@ -916,7 +915,7 @@ func TestXLStorageListDir(t *testing.T) {
|
||||
|
||||
// TestXLStorage for delete on an removed disk.
|
||||
// should fail with disk not found.
|
||||
err = xlStorageDeletedStorage.Delete(context.Background(), "del-vol", "my-file", DeleteOptions{
|
||||
err = xlStorageDeletedStorage.Delete(t.Context(), "del-vol", "my-file", DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -938,17 +937,17 @@ func TestXLStorageDeleteFile(t *testing.T) {
|
||||
}
|
||||
|
||||
// Setup test environment.
|
||||
if err = xlStorage.MakeVol(context.Background(), "success-vol"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "success-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "success-vol", "success-file", []byte("Hello, world")); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "success-vol", "success-file", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
|
||||
if err = xlStorage.MakeVol(context.Background(), "no-permissions"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "no-permissions"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err.Error())
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), "no-permissions", "dir/file", []byte("Hello, world")); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), "no-permissions", "dir/file", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err.Error())
|
||||
}
|
||||
// Parent directory must have write permissions, this is read + execute.
|
||||
@@ -1002,7 +1001,7 @@ func TestXLStorageDeleteFile(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
if err = xlStorage.Delete(context.Background(), testCase.srcVol, testCase.srcPath, DeleteOptions{
|
||||
if err = xlStorage.Delete(t.Context(), testCase.srcVol, testCase.srcPath, DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
}); err != testCase.expectedErr {
|
||||
@@ -1029,7 +1028,7 @@ func TestXLStorageDeleteFile(t *testing.T) {
|
||||
t.Fatalf("Unable to initialize xlStorage, %s", err)
|
||||
}
|
||||
|
||||
if err = xlStorageNew.Delete(context.Background(), "mybucket", "myobject", DeleteOptions{
|
||||
if err = xlStorageNew.Delete(t.Context(), "mybucket", "myobject", DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
}); err != errFileAccessDenied {
|
||||
@@ -1050,7 +1049,7 @@ func TestXLStorageDeleteFile(t *testing.T) {
|
||||
|
||||
// TestXLStorage for delete on an removed disk.
|
||||
// should fail with disk not found.
|
||||
err = xlStorageDeletedStorage.Delete(context.Background(), "del-vol", "my-file", DeleteOptions{
|
||||
err = xlStorageDeletedStorage.Delete(t.Context(), "del-vol", "my-file", DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
})
|
||||
@@ -1069,7 +1068,7 @@ func TestXLStorageReadFile(t *testing.T) {
|
||||
|
||||
volume := "success-vol"
|
||||
// Setup test environment.
|
||||
if err = xlStorage.MakeVol(context.Background(), volume); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), volume); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
|
||||
@@ -1156,7 +1155,7 @@ func TestXLStorageReadFile(t *testing.T) {
|
||||
v := NewBitrotVerifier(SHA256, getSHA256Sum([]byte("hello, world")))
|
||||
// Create test files for further reading.
|
||||
for i, appendFile := range appendFiles {
|
||||
err = xlStorage.AppendFile(context.Background(), volume, appendFile.fileName, []byte("hello, world"))
|
||||
err = xlStorage.AppendFile(t.Context(), volume, appendFile.fileName, []byte("hello, world"))
|
||||
if err != appendFile.expectedErr {
|
||||
t.Fatalf("Creating file failed: %d %#v, expected: %s, got: %s", i+1, appendFile, appendFile.expectedErr, err)
|
||||
}
|
||||
@@ -1165,7 +1164,7 @@ func TestXLStorageReadFile(t *testing.T) {
|
||||
{
|
||||
buf := make([]byte, 5)
|
||||
// Test for negative offset.
|
||||
if _, err = xlStorage.ReadFile(context.Background(), volume, "myobject", -1, buf, v); err == nil {
|
||||
if _, err = xlStorage.ReadFile(t.Context(), volume, "myobject", -1, buf, v); err == nil {
|
||||
t.Fatalf("expected: error, got: <nil>")
|
||||
}
|
||||
}
|
||||
@@ -1176,7 +1175,7 @@ func TestXLStorageReadFile(t *testing.T) {
|
||||
var n int64
|
||||
// Common read buffer.
|
||||
buf := make([]byte, testCase.bufSize)
|
||||
n, err = xlStorage.ReadFile(context.Background(), testCase.volume, testCase.fileName, testCase.offset, buf, v)
|
||||
n, err = xlStorage.ReadFile(t.Context(), testCase.volume, testCase.fileName, testCase.offset, buf, v)
|
||||
if err != nil && testCase.expectedErr != nil {
|
||||
// Validate if the type string of the errors are an exact match.
|
||||
if err.Error() != testCase.expectedErr.Error() {
|
||||
@@ -1252,7 +1251,7 @@ func TestXLStorageReadFile(t *testing.T) {
|
||||
|
||||
// Common read buffer.
|
||||
buf := make([]byte, 10)
|
||||
if _, err = xlStoragePermStorage.ReadFile(context.Background(), "mybucket", "myobject", 0, buf, v); err != errFileAccessDenied {
|
||||
if _, err = xlStoragePermStorage.ReadFile(t.Context(), "mybucket", "myobject", 0, buf, v); err != errFileAccessDenied {
|
||||
t.Errorf("expected: %s, got: %s", errFileAccessDenied, err)
|
||||
}
|
||||
}
|
||||
@@ -1293,14 +1292,14 @@ func TestXLStorageReadFileWithVerify(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create xlStorage test setup, %s", err)
|
||||
}
|
||||
if err = xlStorage.MakeVol(context.Background(), volume); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), volume); err != nil {
|
||||
t.Fatalf("Unable to create volume %s: %v", volume, err)
|
||||
}
|
||||
data := make([]byte, 8*1024)
|
||||
if _, err = io.ReadFull(rand.Reader, data); err != nil {
|
||||
t.Fatalf("Unable to create generate random data: %v", err)
|
||||
}
|
||||
if err = xlStorage.AppendFile(context.Background(), volume, object, data); err != nil {
|
||||
if err = xlStorage.AppendFile(t.Context(), volume, object, data); err != nil {
|
||||
t.Fatalf("Unable to create object: %v", err)
|
||||
}
|
||||
|
||||
@@ -1312,7 +1311,7 @@ func TestXLStorageReadFileWithVerify(t *testing.T) {
|
||||
}
|
||||
|
||||
buffer := make([]byte, test.length)
|
||||
n, err := xlStorage.ReadFile(context.Background(), volume, test.file, int64(test.offset), buffer, NewBitrotVerifier(test.algorithm, h.Sum(nil)))
|
||||
n, err := xlStorage.ReadFile(t.Context(), volume, test.file, int64(test.offset), buffer, NewBitrotVerifier(test.algorithm, h.Sum(nil)))
|
||||
|
||||
switch {
|
||||
case err == nil && test.expError != nil:
|
||||
@@ -1335,7 +1334,7 @@ func TestXLStorageFormatFileChange(t *testing.T) {
|
||||
t.Fatalf("Unable to create xlStorage test setup, %s", err)
|
||||
}
|
||||
|
||||
if err = xlStorage.MakeVol(context.Background(), volume); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), volume); err != nil {
|
||||
t.Fatalf("MakeVol failed with %s", err)
|
||||
}
|
||||
|
||||
@@ -1344,7 +1343,7 @@ func TestXLStorageFormatFileChange(t *testing.T) {
|
||||
t.Fatalf("ioutil.WriteFile failed with %s", err)
|
||||
}
|
||||
|
||||
err = xlStorage.MakeVol(context.Background(), volume)
|
||||
err = xlStorage.MakeVol(t.Context(), volume)
|
||||
if err != errVolumeExists {
|
||||
t.Fatalf("MakeVol expected to fail with errDiskNotFound but failed with %s", err)
|
||||
}
|
||||
@@ -1359,7 +1358,7 @@ func TestXLStorageAppendFile(t *testing.T) {
|
||||
}
|
||||
|
||||
// Setup test environment.
|
||||
if err = xlStorage.MakeVol(context.Background(), "success-vol"); err != nil {
|
||||
if err = xlStorage.MakeVol(t.Context(), "success-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
|
||||
@@ -1389,7 +1388,7 @@ func TestXLStorageAppendFile(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
if err = xlStorage.AppendFile(context.Background(), "success-vol", testCase.fileName, []byte("hello, world")); err != testCase.expectedErr {
|
||||
if err = xlStorage.AppendFile(t.Context(), "success-vol", testCase.fileName, []byte("hello, world")); err != testCase.expectedErr {
|
||||
t.Errorf("Case: %d, expected: %s, got: %s", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
}
|
||||
@@ -1414,14 +1413,14 @@ func TestXLStorageAppendFile(t *testing.T) {
|
||||
t.Fatalf("Unable to initialize xlStorage, %s", err)
|
||||
}
|
||||
|
||||
if err = xlStoragePermStorage.AppendFile(context.Background(), "mybucket", "myobject", []byte("hello, world")); err != errFileAccessDenied {
|
||||
if err = xlStoragePermStorage.AppendFile(t.Context(), "mybucket", "myobject", []byte("hello, world")); err != errFileAccessDenied {
|
||||
t.Fatalf("expected: errFileAccessDenied error, got: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestXLStorage case with invalid volume name.
|
||||
// A valid volume name should be at least of size 3.
|
||||
err = xlStorage.AppendFile(context.Background(), "bn", "yes", []byte("hello, world"))
|
||||
err = xlStorage.AppendFile(t.Context(), "bn", "yes", []byte("hello, world"))
|
||||
if err != errVolumeNotFound {
|
||||
t.Fatalf("expected: \"Invalid argument error\", got: \"%s\"", err)
|
||||
}
|
||||
@@ -1436,32 +1435,32 @@ func TestXLStorageRenameFile(t *testing.T) {
|
||||
}
|
||||
|
||||
// Setup test environment.
|
||||
if err := xlStorage.MakeVol(context.Background(), "src-vol"); err != nil {
|
||||
if err := xlStorage.MakeVol(t.Context(), "src-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
|
||||
if err := xlStorage.MakeVol(context.Background(), "dest-vol"); err != nil {
|
||||
if err := xlStorage.MakeVol(t.Context(), "dest-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
|
||||
if err := xlStorage.AppendFile(context.Background(), "src-vol", "file1", []byte("Hello, world")); err != nil {
|
||||
if err := xlStorage.AppendFile(t.Context(), "src-vol", "file1", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
|
||||
if err := xlStorage.AppendFile(context.Background(), "src-vol", "file2", []byte("Hello, world")); err != nil {
|
||||
if err := xlStorage.AppendFile(t.Context(), "src-vol", "file2", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
if err := xlStorage.AppendFile(context.Background(), "src-vol", "file3", []byte("Hello, world")); err != nil {
|
||||
if err := xlStorage.AppendFile(t.Context(), "src-vol", "file3", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
if err := xlStorage.AppendFile(context.Background(), "src-vol", "file4", []byte("Hello, world")); err != nil {
|
||||
if err := xlStorage.AppendFile(t.Context(), "src-vol", "file4", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
|
||||
if err := xlStorage.AppendFile(context.Background(), "src-vol", "file5", []byte("Hello, world")); err != nil {
|
||||
if err := xlStorage.AppendFile(t.Context(), "src-vol", "file5", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
if err := xlStorage.AppendFile(context.Background(), "src-vol", "path/to/file1", []byte("Hello, world")); err != nil {
|
||||
if err := xlStorage.AppendFile(t.Context(), "src-vol", "path/to/file1", []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
|
||||
@@ -1638,7 +1637,7 @@ func TestXLStorageRenameFile(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
if err := xlStorage.RenameFile(context.Background(), testCase.srcVol, testCase.srcPath, testCase.destVol, testCase.destPath); err != testCase.expectedErr {
|
||||
if err := xlStorage.RenameFile(t.Context(), testCase.srcVol, testCase.srcPath, testCase.destVol, testCase.destPath); err != testCase.expectedErr {
|
||||
t.Fatalf("TestXLStorage %d: Expected the error to be : \"%v\", got: \"%v\".", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
}
|
||||
@@ -1651,7 +1650,7 @@ func TestXLStorageDeleteVersion(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create xlStorage test setup, %s", err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
volume := "myvol-vol"
|
||||
object := "my-object"
|
||||
@@ -1744,19 +1743,19 @@ func TestXLStorageStatInfoFile(t *testing.T) {
|
||||
}
|
||||
|
||||
// Setup test environment.
|
||||
if err := xlStorage.MakeVol(context.Background(), "success-vol"); err != nil {
|
||||
if err := xlStorage.MakeVol(t.Context(), "success-vol"); err != nil {
|
||||
t.Fatalf("Unable to create volume, %s", err)
|
||||
}
|
||||
|
||||
if err := xlStorage.AppendFile(context.Background(), "success-vol", pathJoin("success-file", xlStorageFormatFile), []byte("Hello, world")); err != nil {
|
||||
if err := xlStorage.AppendFile(t.Context(), "success-vol", pathJoin("success-file", xlStorageFormatFile), []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
|
||||
if err := xlStorage.AppendFile(context.Background(), "success-vol", pathJoin("path/to/success-file", xlStorageFormatFile), []byte("Hello, world")); err != nil {
|
||||
if err := xlStorage.AppendFile(t.Context(), "success-vol", pathJoin("path/to/success-file", xlStorageFormatFile), []byte("Hello, world")); err != nil {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
|
||||
if err := xlStorage.MakeVol(context.Background(), "success-vol/path/to/"+xlStorageFormatFile); err != nil {
|
||||
if err := xlStorage.MakeVol(t.Context(), "success-vol/path/to/"+xlStorageFormatFile); err != nil {
|
||||
t.Fatalf("Unable to create path, %s", err)
|
||||
}
|
||||
|
||||
@@ -1817,7 +1816,7 @@ func TestXLStorageStatInfoFile(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
_, err := xlStorage.StatInfoFile(context.Background(), testCase.srcVol, testCase.srcPath+"/"+xlStorageFormatFile, false)
|
||||
_, err := xlStorage.StatInfoFile(t.Context(), testCase.srcVol, testCase.srcPath+"/"+xlStorageFormatFile, false)
|
||||
if err != testCase.expectedErr {
|
||||
t.Errorf("TestXLStorage case %d: Expected: \"%s\", got: \"%s\"", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
@@ -1840,7 +1839,7 @@ func TestXLStorageVerifyFile(t *testing.T) {
|
||||
|
||||
volName := "testvol"
|
||||
fileName := "testfile"
|
||||
if err := storage.MakeVol(context.Background(), volName); err != nil {
|
||||
if err := storage.MakeVol(t.Context(), volName); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1854,29 +1853,29 @@ func TestXLStorageVerifyFile(t *testing.T) {
|
||||
h := algo.New()
|
||||
h.Write(data)
|
||||
hashBytes := h.Sum(nil)
|
||||
if err := storage.WriteAll(context.Background(), volName, fileName, data); err != nil {
|
||||
if err := storage.WriteAll(t.Context(), volName, fileName, data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := storage.storage.bitrotVerify(context.Background(), pathJoin(path, volName, fileName), size, algo, hashBytes, 0); err != nil {
|
||||
if err := storage.storage.bitrotVerify(t.Context(), pathJoin(path, volName, fileName), size, algo, hashBytes, 0); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// 2) Whole-file bitrot check on corrupted file
|
||||
if err := storage.AppendFile(context.Background(), volName, fileName, []byte("a")); err != nil {
|
||||
if err := storage.AppendFile(t.Context(), volName, fileName, []byte("a")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check if VerifyFile reports the incorrect file length (the correct length is `size+1`)
|
||||
if err := storage.storage.bitrotVerify(context.Background(), pathJoin(path, volName, fileName), size, algo, hashBytes, 0); err == nil {
|
||||
if err := storage.storage.bitrotVerify(t.Context(), pathJoin(path, volName, fileName), size, algo, hashBytes, 0); err == nil {
|
||||
t.Fatal("expected to fail bitrot check")
|
||||
}
|
||||
|
||||
// Check if bitrot fails
|
||||
if err := storage.storage.bitrotVerify(context.Background(), pathJoin(path, volName, fileName), size+1, algo, hashBytes, 0); err == nil {
|
||||
if err := storage.storage.bitrotVerify(t.Context(), pathJoin(path, volName, fileName), size+1, algo, hashBytes, 0); err == nil {
|
||||
t.Fatal("expected to fail bitrot check")
|
||||
}
|
||||
|
||||
if err := storage.Delete(context.Background(), volName, fileName, DeleteOptions{
|
||||
if err := storage.Delete(t.Context(), volName, fileName, DeleteOptions{
|
||||
Recursive: false,
|
||||
Immediate: false,
|
||||
}); err != nil {
|
||||
@@ -1904,7 +1903,7 @@ func TestXLStorageVerifyFile(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w.(io.Closer).Close()
|
||||
if err := storage.storage.bitrotVerify(context.Background(), pathJoin(path, volName, fileName), size, algo, nil, shardSize); err != nil {
|
||||
if err := storage.storage.bitrotVerify(t.Context(), pathJoin(path, volName, fileName), size, algo, nil, shardSize); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1919,10 +1918,10 @@ func TestXLStorageVerifyFile(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
if err := storage.storage.bitrotVerify(context.Background(), pathJoin(path, volName, fileName), size, algo, nil, shardSize); err == nil {
|
||||
if err := storage.storage.bitrotVerify(t.Context(), pathJoin(path, volName, fileName), size, algo, nil, shardSize); err == nil {
|
||||
t.Fatal("expected to fail bitrot check")
|
||||
}
|
||||
if err := storage.storage.bitrotVerify(context.Background(), pathJoin(path, volName, fileName), size+1, algo, nil, shardSize); err == nil {
|
||||
if err := storage.storage.bitrotVerify(t.Context(), pathJoin(path, volName, fileName), size+1, algo, nil, shardSize); err == nil {
|
||||
t.Fatal("expected to fail bitrot check")
|
||||
}
|
||||
}
|
||||
@@ -1937,8 +1936,8 @@ func TestXLStorageReadMetadata(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
disk.MakeVol(context.Background(), volume)
|
||||
if _, err := disk.readMetadata(context.Background(), pathJoin(tmpDir, volume, object)); err != errFileNameTooLong {
|
||||
disk.MakeVol(t.Context(), volume)
|
||||
if _, err := disk.readMetadata(t.Context(), pathJoin(tmpDir, volume, object)); err != errFileNameTooLong {
|
||||
t.Fatalf("Unexpected error from readMetadata - expect %v: got %v", errFileNameTooLong, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"syscall"
|
||||
@@ -55,7 +54,7 @@ func TestIsValidUmaskVol(t *testing.T) {
|
||||
|
||||
// Attempt to create a volume to verify the permissions later.
|
||||
// MakeVol creates 0777.
|
||||
if err = disk.MakeVol(context.Background(), testCase.volName); err != nil {
|
||||
if err = disk.MakeVol(t.Context(), testCase.volName); err != nil {
|
||||
t.Fatalf("Creating a volume failed with %s expected to pass.", err)
|
||||
}
|
||||
|
||||
@@ -93,18 +92,18 @@ func TestIsValidUmaskFile(t *testing.T) {
|
||||
|
||||
// Attempt to create a volume to verify the permissions later.
|
||||
// MakeVol creates directory with 0777 perms.
|
||||
if err = disk.MakeVol(context.Background(), testCase.volName); err != nil {
|
||||
if err = disk.MakeVol(t.Context(), testCase.volName); err != nil {
|
||||
t.Fatalf("Creating a volume failed with %s expected to pass.", err)
|
||||
}
|
||||
|
||||
// Attempt to create a file to verify the permissions later.
|
||||
// AppendFile creates file with 0666 perms.
|
||||
if err = disk.AppendFile(context.Background(), testCase.volName, pathJoin("hello-world.txt", xlStorageFormatFile), []byte("Hello World")); err != nil {
|
||||
if err = disk.AppendFile(t.Context(), testCase.volName, pathJoin("hello-world.txt", xlStorageFormatFile), []byte("Hello World")); err != nil {
|
||||
t.Fatalf("Create a file `test` failed with %s expected to pass.", err)
|
||||
}
|
||||
|
||||
// CheckFile - stat the file.
|
||||
if _, err := disk.StatInfoFile(context.Background(), testCase.volName, "hello-world.txt/"+xlStorageFormatFile, false); err != nil {
|
||||
if _, err := disk.StatInfoFile(t.Context(), testCase.volName, "hello-world.txt/"+xlStorageFormatFile, false); err != nil {
|
||||
t.Fatalf("Stat failed with %s expected to pass.", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module github.com/minio/minio/docs/debugging/inspect
|
||||
|
||||
go 1.23
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
github.com/klauspost/compress v1.17.11
|
||||
@@ -18,6 +19,6 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/minio/pkg/v3 v3.0.28 // indirect
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
)
|
||||
|
||||
@@ -24,13 +24,13 @@ github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
|
||||
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
module github.com/minio/minio/docs/debugging/s3-verify
|
||||
|
||||
go 1.23
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.24.2
|
||||
|
||||
require github.com/minio/minio-go/v7 v7.0.83
|
||||
|
||||
@@ -15,9 +17,9 @@ require (
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -23,14 +23,14 @@ github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -2,7 +2,7 @@ version: '3.7'
|
||||
|
||||
# Settings and configurations that are common for all containers
|
||||
x-minio-common: &minio-common
|
||||
image: quay.io/minio/minio:RELEASE.2025-03-12T18-04-18Z
|
||||
image: quay.io/minio/minio:RELEASE.2025-04-08T15-41-24Z
|
||||
command: server --console-address ":9001" http://minio{1...4}/data{1...2}
|
||||
expose:
|
||||
- "9000"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
module github.com/minio/minio
|
||||
|
||||
go 1.23.0
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.23.6
|
||||
toolchain go1.24.2
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.46.0
|
||||
@@ -51,8 +51,8 @@ require (
|
||||
github.com/minio/highwayhash v1.0.3
|
||||
github.com/minio/kms-go/kes v0.3.1
|
||||
github.com/minio/kms-go/kms v0.4.0
|
||||
github.com/minio/madmin-go/v3 v3.0.102
|
||||
github.com/minio/minio-go/v7 v7.0.89
|
||||
github.com/minio/madmin-go/v3 v3.0.109
|
||||
github.com/minio/minio-go/v7 v7.0.90
|
||||
github.com/minio/mux v1.9.2
|
||||
github.com/minio/pkg/v3 v3.1.0
|
||||
github.com/minio/selfupdate v0.6.0
|
||||
@@ -61,7 +61,7 @@ require (
|
||||
github.com/minio/xxml v0.0.3
|
||||
github.com/minio/zipindex v0.4.0
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/nats-io/nats-server/v2 v2.9.23
|
||||
github.com/nats-io/nats-server/v2 v2.10.27
|
||||
github.com/nats-io/nats.go v1.39.1
|
||||
github.com/nats-io/stan.go v0.10.4
|
||||
github.com/ncw/directio v1.0.5
|
||||
@@ -72,9 +72,9 @@ require (
|
||||
github.com/pkg/sftp v1.13.8
|
||||
github.com/pkg/xattr v0.4.10
|
||||
github.com/prometheus/client_golang v1.21.1
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.62.0
|
||||
github.com/prometheus/procfs v0.15.1
|
||||
github.com/prometheus/client_model v0.6.2
|
||||
github.com/prometheus/common v0.63.0
|
||||
github.com/prometheus/procfs v0.16.0
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1
|
||||
github.com/rabbitmq/amqp091-go v1.10.0
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
|
||||
@@ -90,11 +90,11 @@ require (
|
||||
go.uber.org/atomic v1.11.0
|
||||
go.uber.org/zap v1.27.0
|
||||
goftp.io/server/v2 v2.0.1
|
||||
golang.org/x/crypto v0.36.0
|
||||
golang.org/x/crypto v0.37.0
|
||||
golang.org/x/oauth2 v0.28.0
|
||||
golang.org/x/sync v0.12.0
|
||||
golang.org/x/sys v0.31.0
|
||||
golang.org/x/term v0.30.0
|
||||
golang.org/x/sync v0.13.0
|
||||
golang.org/x/sys v0.32.0
|
||||
golang.org/x/term v0.31.0
|
||||
golang.org/x/time v0.11.0
|
||||
google.golang.org/api v0.224.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
@@ -194,7 +194,7 @@ require (
|
||||
github.com/lestrrat-go/jwx/v2 v2.1.4 // indirect
|
||||
github.com/lestrrat-go/option v1.0.1 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-ieproxy v0.0.12 // indirect
|
||||
@@ -216,7 +216,7 @@ require (
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.16.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/nats-io/jwt/v2 v2.5.0 // indirect
|
||||
github.com/nats-io/jwt/v2 v2.7.3 // indirect
|
||||
github.com/nats-io/nats-streaming-server v0.24.6 // indirect
|
||||
github.com/nats-io/nkeys v0.4.10 // indirect
|
||||
github.com/nats-io/nuid v1.0.1 // indirect
|
||||
@@ -226,8 +226,8 @@ require (
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/posener/complete v1.2.3 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/prometheus/prom2json v1.4.1 // indirect
|
||||
github.com/prometheus/prometheus v0.302.1 // indirect
|
||||
github.com/prometheus/prom2json v1.4.2 // indirect
|
||||
github.com/prometheus/prometheus v0.303.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rjeczalik/notify v0.9.3 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
@@ -256,12 +256,12 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/net v0.37.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/tools v0.31.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250106144421-5f5ef82da422 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250311190419-81fb87f6b8bf // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf // indirect
|
||||
google.golang.org/grpc v1.71.0 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
)
|
||||
|
||||
@@ -384,8 +384,8 @@ github.com/lithammer/shortuuid/v4 v4.2.0 h1:LMFOzVB3996a7b8aBuEXxqOBflbfPQAiVzkI
|
||||
github.com/lithammer/shortuuid/v4 v4.2.0/go.mod h1:D5noHZ2oFw/YaKCfGy0YxyE7M0wMbezmMjPdhyEFe6Y=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d h1:fjMbDVUGsMQiVZnSQsmouYJvMdwsGiDipOZoN66v844=
|
||||
github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc=
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
@@ -436,15 +436,15 @@ github.com/minio/kms-go/kes v0.3.1 h1:K3sPFAvFbJx33XlCTUBnQo8JRmSZyDvT6T2/MQ2iC3
|
||||
github.com/minio/kms-go/kes v0.3.1/go.mod h1:Q9Ct0KUAuN9dH0hSVa0eva45Jg99cahbZpPxeqR9rOQ=
|
||||
github.com/minio/kms-go/kms v0.4.0 h1:cLPZceEp+05xHotVBaeFJrgL7JcXM4lBy6PU0idkE7I=
|
||||
github.com/minio/kms-go/kms v0.4.0/go.mod h1:q12CehiIy2qgBnDKq6Q7wmPi2PHSyRVug5DKp0HAVeE=
|
||||
github.com/minio/madmin-go/v3 v3.0.102 h1:bqy15D6d9uQOh/3B/sLfzRtWSJgZeuKnAI5VRDhvRQw=
|
||||
github.com/minio/madmin-go/v3 v3.0.102/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE=
|
||||
github.com/minio/madmin-go/v3 v3.0.109 h1:hRHlJ6yaIB3tlIj5mz9L9mGcyLC37S9qL1WtFrRtyQ0=
|
||||
github.com/minio/madmin-go/v3 v3.0.109/go.mod h1:WOe2kYmYl1OIlY2DSRHVQ8j1v4OItARQ6jGyQqcCud8=
|
||||
github.com/minio/mc v0.0.0-20250312172924-c1d5d4cbb4ca h1:Zeu+Gbsw/yoqJofAFaU3zbIVr51j9LULUrQqKFLQnGA=
|
||||
github.com/minio/mc v0.0.0-20250312172924-c1d5d4cbb4ca/go.mod h1:h5UQZ+5Qfq6XV81E4iZSgStPZ6Hy+gMuHMkLkjq4Gys=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v6 v6.0.46/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg=
|
||||
github.com/minio/minio-go/v7 v7.0.89 h1:hx4xV5wwTUfyv8LarhJAwNecnXpoTsj9v3f3q/ZkiJU=
|
||||
github.com/minio/minio-go/v7 v7.0.89/go.mod h1:2rFnGAp02p7Dddo1Fq4S2wYOfpF0MUTSeLTRC90I204=
|
||||
github.com/minio/minio-go/v7 v7.0.90 h1:TmSj1083wtAD0kEYTx7a5pFsv3iRYMsOJ6A4crjA1lE=
|
||||
github.com/minio/minio-go/v7 v7.0.90/go.mod h1:uvMUcGrpgeSAAI6+sD3818508nUyMULw94j2Nxku/Go=
|
||||
github.com/minio/mux v1.9.2 h1:dQchne49BUBgOlxIHjx5wVe1gl5VXF2sxd4YCXkikTw=
|
||||
github.com/minio/mux v1.9.2/go.mod h1:OuHAsZsux+e562bcO2P3Zv/P0LMo6fPQ310SmoyG7mQ=
|
||||
github.com/minio/pkg/v3 v3.1.0 h1:RoR1TMXV5y4LvKPkaB1WoeuM6CO7A+I55xYb1tzrvLQ=
|
||||
@@ -483,11 +483,11 @@ github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k=
|
||||
github.com/nats-io/jwt/v2 v2.5.0 h1:WQQ40AAlqqfx+f6ku+i0pOVm+ASirD4fUh+oQsiE9Ak=
|
||||
github.com/nats-io/jwt/v2 v2.5.0/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
|
||||
github.com/nats-io/jwt/v2 v2.7.3 h1:6bNPK+FXgBeAqdj4cYQ0F8ViHRbi7woQLq4W29nUAzE=
|
||||
github.com/nats-io/jwt/v2 v2.7.3/go.mod h1:GvkcbHhKquj3pkioy5put1wvPxs78UlZ7D/pY+BgZk4=
|
||||
github.com/nats-io/nats-server/v2 v2.8.2/go.mod h1:vIdpKz3OG+DCg4q/xVPdXHoztEyKDWRtykQ4N7hd7C4=
|
||||
github.com/nats-io/nats-server/v2 v2.9.23 h1:6Wj6H6QpP9FMlpCyWUaNu2yeZ/qGj+mdRkZ1wbikExU=
|
||||
github.com/nats-io/nats-server/v2 v2.9.23/go.mod h1:wEjrEy9vnqIGE4Pqz4/c75v9Pmaq7My2IgFmnykc4C0=
|
||||
github.com/nats-io/nats-server/v2 v2.10.27 h1:A/i3JqtrP897UHc2/Jia/mqaXkqj9+HGdpz+R0mC+sM=
|
||||
github.com/nats-io/nats-server/v2 v2.10.27/go.mod h1:SGzoWGU8wUVnMr/HJhEMv4R8U4f7hF4zDygmRxpNsvg=
|
||||
github.com/nats-io/nats-streaming-server v0.24.6 h1:iIZXuPSznnYkiy0P3L0AP9zEN9Etp+tITbbX1KKeq4Q=
|
||||
github.com/nats-io/nats-streaming-server v0.24.6/go.mod h1:tdKXltY3XLeBJ21sHiZiaPl+j8sK3vcCKBWVyxeQs10=
|
||||
github.com/nats-io/nats.go v1.13.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
|
||||
@@ -541,19 +541,19 @@ github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
|
||||
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/prometheus/prom2json v1.4.1 h1:7McxdrHgPEOtMwWjkKtd0v5AhpR2Q6QAnlHKVxq0+tQ=
|
||||
github.com/prometheus/prom2json v1.4.1/go.mod h1:CzOQykSKFxXuC7ELUZHOHQvwKesQ3eN0p2PWLhFitQM=
|
||||
github.com/prometheus/prometheus v0.302.1 h1:xqVdrwrB4WNpdgJqxsz5loqFWNUZitsK8myqLuSZ6Ag=
|
||||
github.com/prometheus/prometheus v0.302.1/go.mod h1:YcyCoTbUR/TM8rY3Aoeqr0AWTu/pu1Ehh+trpX3eRzg=
|
||||
github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM=
|
||||
github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg=
|
||||
github.com/prometheus/prom2json v1.4.2 h1:PxCTM+Whqi/eykO1MKsEL0p/zMpxp9ybpsmdFamw6po=
|
||||
github.com/prometheus/prom2json v1.4.2/go.mod h1:zuvPm7u3epZSbXPWHny6G+o8ETgu6eAK3oPr6yFkRWE=
|
||||
github.com/prometheus/prometheus v0.303.0 h1:wsNNsbd4EycMCphYnTmNY9JASBVbp7NWwJna857cGpA=
|
||||
github.com/prometheus/prometheus v0.303.0/go.mod h1:8PMRi+Fk1WzopMDeb0/6hbNs9nV6zgySkU/zds5Lu3o=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
||||
@@ -705,8 +705,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@@ -736,8 +736,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
||||
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -752,8 +752,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -792,8 +792,8 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@@ -805,8 +805,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
|
||||
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@@ -819,8 +819,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
@@ -856,8 +856,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
@@ -146,6 +146,9 @@ loop:
|
||||
|
||||
// Eval will return a lifecycle event for each object in objs
|
||||
func (e *Evaluator) Eval(objs []ObjectOpts) ([]Event, error) {
|
||||
if len(objs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(objs) != objs[0].NumVersions {
|
||||
return nil, fmt.Errorf("number of versions mismatch, expected %d, got %d", objs[0].NumVersions, len(objs))
|
||||
}
|
||||
|
||||
@@ -144,6 +144,12 @@ func TestNewerNoncurrentVersions(t *testing.T) {
|
||||
t.Fatalf("test-%d: got %v, want %v", i+1, gotEvents[i], wantEvents[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Test with zero versions
|
||||
events, err := evaluator.Eval(nil)
|
||||
if len(events) != 0 || err != nil {
|
||||
t.Fatal("expected no events nor error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyEvaluator(t *testing.T) {
|
||||
|
||||
@@ -46,7 +46,7 @@ func TestCacheCtx(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
cancel() // cancel context to test.
|
||||
|
||||
_, err := cache.GetWithCtx(ctx)
|
||||
@@ -54,7 +54,7 @@ func TestCacheCtx(t *testing.T) {
|
||||
t.Fatalf("expected context.Canceled err, got %v", err)
|
||||
}
|
||||
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
ctx, cancel = context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
t1, err := cache.GetWithCtx(ctx)
|
||||
|
||||
@@ -19,7 +19,6 @@ package openid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -148,7 +147,7 @@ func TestJWTHMACType(t *testing.T) {
|
||||
}
|
||||
|
||||
var claims jwtgo.MapClaims
|
||||
if err = cfg.Validate(context.Background(), DummyRoleARN, token, "", "", claims); err != nil {
|
||||
if err = cfg.Validate(t.Context(), DummyRoleARN, token, "", "", claims); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -200,7 +199,7 @@ func TestJWT(t *testing.T) {
|
||||
}
|
||||
|
||||
var claims jwtgo.MapClaims
|
||||
if err = cfg.Validate(context.Background(), DummyRoleARN, u.Query().Get("Token"), "", "", claims); err == nil {
|
||||
if err = cfg.Validate(t.Context(), DummyRoleARN, u.Query().Get("Token"), "", "", claims); err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,13 +43,15 @@ import (
|
||||
|
||||
// OpenID keys and envs.
|
||||
const (
|
||||
ClientID = "client_id"
|
||||
ClientSecret = "client_secret"
|
||||
ConfigURL = "config_url"
|
||||
ClaimName = "claim_name"
|
||||
ClaimUserinfo = "claim_userinfo"
|
||||
RolePolicy = "role_policy"
|
||||
DisplayName = "display_name"
|
||||
ClientID = "client_id"
|
||||
ClientSecret = "client_secret"
|
||||
ConfigURL = "config_url"
|
||||
ClaimName = "claim_name"
|
||||
ClaimUserinfo = "claim_userinfo"
|
||||
RolePolicy = "role_policy"
|
||||
DisplayName = "display_name"
|
||||
UserReadableClaim = "user_readable_claim"
|
||||
UserIDClaim = "user_id_claim"
|
||||
|
||||
Scopes = "scopes"
|
||||
RedirectURI = "redirect_uri"
|
||||
@@ -130,6 +132,14 @@ var (
|
||||
Key: KeyCloakAdminURL,
|
||||
Value: "",
|
||||
},
|
||||
config.KV{
|
||||
Key: UserReadableClaim,
|
||||
Value: "",
|
||||
},
|
||||
config.KV{
|
||||
Key: UserIDClaim,
|
||||
Value: "",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -628,3 +638,25 @@ func GetDefaultExpiration(dsecs string) (time.Duration, error) {
|
||||
|
||||
return defaultExpiryDuration, nil
|
||||
}
|
||||
|
||||
// GetUserReadableClaim returns the human readable claim name for the given
|
||||
// configuration name.
|
||||
func (r Config) GetUserReadableClaim(cfgName string) string {
|
||||
pCfg, ok := r.ProviderCfgs[cfgName]
|
||||
if ok {
|
||||
return pCfg.UserReadableClaim
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetUserIDClaim returns the user ID claim for the given configuration name, or "sub" if not set.
|
||||
func (r Config) GetUserIDClaim(cfgName string) string {
|
||||
pCfg, ok := r.ProviderCfgs[cfgName]
|
||||
if ok {
|
||||
if pCfg.UserIDClaim != "" {
|
||||
return pCfg.UserIDClaim
|
||||
}
|
||||
return "sub"
|
||||
}
|
||||
return "" // an incorrect config should be handled outside this function
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ type providerCfg struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
RolePolicy string
|
||||
UserReadableClaim string
|
||||
UserIDClaim string
|
||||
|
||||
roleArn arn.ARN
|
||||
provider provider.Provider
|
||||
@@ -64,6 +66,8 @@ func newProviderCfgFromConfig(getCfgVal func(cfgName string) string) providerCfg
|
||||
ClientID: getCfgVal(ClientID),
|
||||
ClientSecret: getCfgVal(ClientSecret),
|
||||
RolePolicy: getCfgVal(RolePolicy),
|
||||
UserReadableClaim: getCfgVal(UserReadableClaim),
|
||||
UserIDClaim: getCfgVal(UserIDClaim),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -482,6 +482,10 @@ func SetNotifyNATS(s config.Config, natsName string, cfg target.NATSArgs) error
|
||||
Key: target.NATSTLSSkipVerify,
|
||||
Value: config.FormatBool(cfg.Secure),
|
||||
},
|
||||
config.KV{
|
||||
Key: target.NATSTLSHandshakeFirst,
|
||||
Value: config.FormatBool(cfg.TLSHandshakeFirst),
|
||||
},
|
||||
config.KV{
|
||||
Key: target.NATSPingInterval,
|
||||
Value: strconv.FormatInt(cfg.PingInterval, 10),
|
||||
|
||||
@@ -959,6 +959,11 @@ func GetNotifyNATS(natsKVS map[string]config.KVS, rootCAs *x509.CertPool) (map[s
|
||||
tlsSkipVerifyEnv = tlsSkipVerifyEnv + config.Default + k
|
||||
}
|
||||
|
||||
tlsHandshakeFirstEnv := target.EnvNatsTLSHandshakeFirst
|
||||
if k != config.Default {
|
||||
tlsHandshakeFirstEnv = tlsHandshakeFirstEnv + config.Default + k
|
||||
}
|
||||
|
||||
subjectEnv := target.EnvNATSSubject
|
||||
if k != config.Default {
|
||||
subjectEnv = subjectEnv + config.Default + k
|
||||
@@ -1010,22 +1015,23 @@ func GetNotifyNATS(natsKVS map[string]config.KVS, rootCAs *x509.CertPool) (map[s
|
||||
}
|
||||
|
||||
natsArgs := target.NATSArgs{
|
||||
Enable: true,
|
||||
Address: *address,
|
||||
Subject: env.Get(subjectEnv, kv.Get(target.NATSSubject)),
|
||||
Username: env.Get(usernameEnv, kv.Get(target.NATSUsername)),
|
||||
UserCredentials: env.Get(userCredentialsEnv, kv.Get(target.NATSUserCredentials)),
|
||||
Password: env.Get(passwordEnv, kv.Get(target.NATSPassword)),
|
||||
CertAuthority: env.Get(certAuthorityEnv, kv.Get(target.NATSCertAuthority)),
|
||||
ClientCert: env.Get(clientCertEnv, kv.Get(target.NATSClientCert)),
|
||||
ClientKey: env.Get(clientKeyEnv, kv.Get(target.NATSClientKey)),
|
||||
Token: env.Get(tokenEnv, kv.Get(target.NATSToken)),
|
||||
TLS: env.Get(tlsEnv, kv.Get(target.NATSTLS)) == config.EnableOn,
|
||||
TLSSkipVerify: env.Get(tlsSkipVerifyEnv, kv.Get(target.NATSTLSSkipVerify)) == config.EnableOn,
|
||||
PingInterval: pingInterval,
|
||||
QueueDir: env.Get(queueDirEnv, kv.Get(target.NATSQueueDir)),
|
||||
QueueLimit: queueLimit,
|
||||
RootCAs: rootCAs,
|
||||
Enable: true,
|
||||
Address: *address,
|
||||
Subject: env.Get(subjectEnv, kv.Get(target.NATSSubject)),
|
||||
Username: env.Get(usernameEnv, kv.Get(target.NATSUsername)),
|
||||
UserCredentials: env.Get(userCredentialsEnv, kv.Get(target.NATSUserCredentials)),
|
||||
Password: env.Get(passwordEnv, kv.Get(target.NATSPassword)),
|
||||
CertAuthority: env.Get(certAuthorityEnv, kv.Get(target.NATSCertAuthority)),
|
||||
ClientCert: env.Get(clientCertEnv, kv.Get(target.NATSClientCert)),
|
||||
ClientKey: env.Get(clientKeyEnv, kv.Get(target.NATSClientKey)),
|
||||
Token: env.Get(tokenEnv, kv.Get(target.NATSToken)),
|
||||
TLS: env.Get(tlsEnv, kv.Get(target.NATSTLS)) == config.EnableOn,
|
||||
TLSSkipVerify: env.Get(tlsSkipVerifyEnv, kv.Get(target.NATSTLSSkipVerify)) == config.EnableOn,
|
||||
TLSHandshakeFirst: env.Get(tlsHandshakeFirstEnv, kv.Get(target.NATSTLSHandshakeFirst)) == config.EnableOn,
|
||||
PingInterval: pingInterval,
|
||||
QueueDir: env.Get(queueDirEnv, kv.Get(target.NATSQueueDir)),
|
||||
QueueLimit: queueLimit,
|
||||
RootCAs: rootCAs,
|
||||
}
|
||||
natsArgs.JetStream.Enable = env.Get(jetStreamEnableEnv, kv.Get(target.NATSJetStream)) == config.EnableOn
|
||||
|
||||
|
||||
@@ -33,14 +33,14 @@ const (
|
||||
|
||||
func testSimpleWriteLock(t *testing.T, duration time.Duration) (locked bool) {
|
||||
drwm1 := NewDRWMutex(ds, "simplelock")
|
||||
ctx1, cancel1 := context.WithCancel(context.Background())
|
||||
ctx1, cancel1 := context.WithCancel(t.Context())
|
||||
if !drwm1.GetRLock(ctx1, cancel1, id, source, Options{Timeout: time.Second}) {
|
||||
panic("Failed to acquire read lock")
|
||||
}
|
||||
// fmt.Println("1st read lock acquired, waiting...")
|
||||
|
||||
drwm2 := NewDRWMutex(ds, "simplelock")
|
||||
ctx2, cancel2 := context.WithCancel(context.Background())
|
||||
ctx2, cancel2 := context.WithCancel(t.Context())
|
||||
if !drwm2.GetRLock(ctx2, cancel2, id, source, Options{Timeout: time.Second}) {
|
||||
panic("Failed to acquire read lock")
|
||||
}
|
||||
@@ -48,25 +48,25 @@ func testSimpleWriteLock(t *testing.T, duration time.Duration) (locked bool) {
|
||||
|
||||
go func() {
|
||||
time.Sleep(2 * testDrwMutexAcquireTimeout)
|
||||
drwm1.RUnlock(context.Background())
|
||||
drwm1.RUnlock(t.Context())
|
||||
// fmt.Println("1st read lock released, waiting...")
|
||||
}()
|
||||
|
||||
go func() {
|
||||
time.Sleep(3 * testDrwMutexAcquireTimeout)
|
||||
drwm2.RUnlock(context.Background())
|
||||
drwm2.RUnlock(t.Context())
|
||||
// fmt.Println("2nd read lock released, waiting...")
|
||||
}()
|
||||
|
||||
drwm3 := NewDRWMutex(ds, "simplelock")
|
||||
// fmt.Println("Trying to acquire write lock, waiting...")
|
||||
ctx3, cancel3 := context.WithCancel(context.Background())
|
||||
ctx3, cancel3 := context.WithCancel(t.Context())
|
||||
locked = drwm3.GetLock(ctx3, cancel3, id, source, Options{Timeout: duration})
|
||||
if locked {
|
||||
// fmt.Println("Write lock acquired, waiting...")
|
||||
time.Sleep(testDrwMutexAcquireTimeout)
|
||||
|
||||
drwm3.Unlock(context.Background())
|
||||
drwm3.Unlock(t.Context())
|
||||
}
|
||||
// fmt.Println("Write lock failed due to timeout")
|
||||
return
|
||||
@@ -94,26 +94,26 @@ func testDualWriteLock(t *testing.T, duration time.Duration) (locked bool) {
|
||||
drwm1 := NewDRWMutex(ds, "duallock")
|
||||
|
||||
// fmt.Println("Getting initial write lock")
|
||||
ctx1, cancel1 := context.WithCancel(context.Background())
|
||||
ctx1, cancel1 := context.WithCancel(t.Context())
|
||||
if !drwm1.GetLock(ctx1, cancel1, id, source, Options{Timeout: time.Second}) {
|
||||
panic("Failed to acquire initial write lock")
|
||||
}
|
||||
|
||||
go func() {
|
||||
time.Sleep(3 * testDrwMutexAcquireTimeout)
|
||||
drwm1.Unlock(context.Background())
|
||||
drwm1.Unlock(t.Context())
|
||||
// fmt.Println("Initial write lock released, waiting...")
|
||||
}()
|
||||
|
||||
// fmt.Println("Trying to acquire 2nd write lock, waiting...")
|
||||
drwm2 := NewDRWMutex(ds, "duallock")
|
||||
ctx2, cancel2 := context.WithCancel(context.Background())
|
||||
ctx2, cancel2 := context.WithCancel(t.Context())
|
||||
locked = drwm2.GetLock(ctx2, cancel2, id, source, Options{Timeout: duration})
|
||||
if locked {
|
||||
// fmt.Println("2nd write lock acquired, waiting...")
|
||||
time.Sleep(testDrwMutexAcquireTimeout)
|
||||
|
||||
drwm2.Unlock(context.Background())
|
||||
drwm2.Unlock(t.Context())
|
||||
}
|
||||
// fmt.Println("2nd write lock failed due to timeout")
|
||||
return
|
||||
@@ -268,7 +268,7 @@ func TestUnlockPanic(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
mu := NewDRWMutex(ds, "test")
|
||||
mu.Unlock(context.Background())
|
||||
mu.Unlock(t.Context())
|
||||
}
|
||||
|
||||
// Borrowed from rwmutex_test.go
|
||||
@@ -278,10 +278,10 @@ func TestUnlockPanic2(t *testing.T) {
|
||||
if recover() == nil {
|
||||
t.Fatalf("unlock of unlocked RWMutex did not panic")
|
||||
}
|
||||
mu.RUnlock(context.Background()) // Unlock, so -test.count > 1 works
|
||||
mu.RUnlock(t.Context()) // Unlock, so -test.count > 1 works
|
||||
}()
|
||||
mu.RLock(id, source)
|
||||
mu.Unlock(context.Background())
|
||||
mu.Unlock(t.Context())
|
||||
}
|
||||
|
||||
// Borrowed from rwmutex_test.go
|
||||
@@ -292,7 +292,7 @@ func TestRUnlockPanic(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
mu := NewDRWMutex(ds, "test")
|
||||
mu.RUnlock(context.Background())
|
||||
mu.RUnlock(t.Context())
|
||||
}
|
||||
|
||||
// Borrowed from rwmutex_test.go
|
||||
@@ -302,10 +302,10 @@ func TestRUnlockPanic2(t *testing.T) {
|
||||
if recover() == nil {
|
||||
t.Fatalf("read unlock of unlocked RWMutex did not panic")
|
||||
}
|
||||
mu.Unlock(context.Background()) // Unlock, so -test.count > 1 works
|
||||
mu.Unlock(t.Context()) // Unlock, so -test.count > 1 works
|
||||
}()
|
||||
mu.Lock(id, source)
|
||||
mu.RUnlock(context.Background())
|
||||
mu.RUnlock(t.Context())
|
||||
}
|
||||
|
||||
// Borrowed from rwmutex_test.go
|
||||
@@ -320,14 +320,14 @@ func benchmarkRWMutex(b *testing.B, localWork, writeRatio int) {
|
||||
foo++
|
||||
if foo%writeRatio == 0 {
|
||||
rwm.Lock(id, source)
|
||||
rwm.Unlock(context.Background())
|
||||
rwm.Unlock(b.Context())
|
||||
} else {
|
||||
rwm.RLock(id, source)
|
||||
for i := 0; i != localWork; i++ {
|
||||
foo *= 2
|
||||
foo /= 2
|
||||
}
|
||||
rwm.RUnlock(context.Background())
|
||||
rwm.RUnlock(b.Context())
|
||||
}
|
||||
}
|
||||
_ = foo
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestSimpleLock(t *testing.T) {
|
||||
// fmt.Println("Lock acquired, waiting...")
|
||||
time.Sleep(testDrwMutexRefreshCallTimeout)
|
||||
|
||||
dm.Unlock(context.Background())
|
||||
dm.Unlock(t.Context())
|
||||
}
|
||||
|
||||
func TestSimpleLockUnlockMultipleTimes(t *testing.T) {
|
||||
@@ -77,23 +77,23 @@ func TestSimpleLockUnlockMultipleTimes(t *testing.T) {
|
||||
|
||||
dm.Lock(id, source)
|
||||
time.Sleep(time.Duration(10+(rand.Float32()*50)) * time.Millisecond)
|
||||
dm.Unlock(context.Background())
|
||||
dm.Unlock(t.Context())
|
||||
|
||||
dm.Lock(id, source)
|
||||
time.Sleep(time.Duration(10+(rand.Float32()*50)) * time.Millisecond)
|
||||
dm.Unlock(context.Background())
|
||||
dm.Unlock(t.Context())
|
||||
|
||||
dm.Lock(id, source)
|
||||
time.Sleep(time.Duration(10+(rand.Float32()*50)) * time.Millisecond)
|
||||
dm.Unlock(context.Background())
|
||||
dm.Unlock(t.Context())
|
||||
|
||||
dm.Lock(id, source)
|
||||
time.Sleep(time.Duration(10+(rand.Float32()*50)) * time.Millisecond)
|
||||
dm.Unlock(context.Background())
|
||||
dm.Unlock(t.Context())
|
||||
|
||||
dm.Lock(id, source)
|
||||
time.Sleep(time.Duration(10+(rand.Float32()*50)) * time.Millisecond)
|
||||
dm.Unlock(context.Background())
|
||||
dm.Unlock(t.Context())
|
||||
}
|
||||
|
||||
// Test two locks for same resource, one succeeds, one fails (after timeout)
|
||||
@@ -108,7 +108,7 @@ func TestTwoSimultaneousLocksForSameResource(t *testing.T) {
|
||||
time.Sleep(5 * testDrwMutexAcquireTimeout)
|
||||
// fmt.Println("Unlocking dm1")
|
||||
|
||||
dm1st.Unlock(context.Background())
|
||||
dm1st.Unlock(t.Context())
|
||||
}()
|
||||
|
||||
dm2nd.Lock(id, source)
|
||||
@@ -116,7 +116,7 @@ func TestTwoSimultaneousLocksForSameResource(t *testing.T) {
|
||||
// fmt.Printf("2nd lock obtained after 1st lock is released\n")
|
||||
time.Sleep(testDrwMutexRefreshCallTimeout * 2)
|
||||
|
||||
dm2nd.Unlock(context.Background())
|
||||
dm2nd.Unlock(t.Context())
|
||||
}
|
||||
|
||||
// Test three locks for same resource, one succeeds, one fails (after timeout)
|
||||
@@ -134,7 +134,7 @@ func TestThreeSimultaneousLocksForSameResource(t *testing.T) {
|
||||
time.Sleep(2 * testDrwMutexAcquireTimeout)
|
||||
// fmt.Println("Unlocking dm1")
|
||||
|
||||
dm1st.Unlock(context.Background())
|
||||
dm1st.Unlock(t.Context())
|
||||
}()
|
||||
expect += 2 * testDrwMutexAcquireTimeout
|
||||
|
||||
@@ -151,7 +151,7 @@ func TestThreeSimultaneousLocksForSameResource(t *testing.T) {
|
||||
time.Sleep(2 * testDrwMutexAcquireTimeout)
|
||||
// fmt.Println("Unlocking dm2")
|
||||
|
||||
dm2nd.Unlock(context.Background())
|
||||
dm2nd.Unlock(t.Context())
|
||||
}()
|
||||
|
||||
dm3rd.Lock(id, source)
|
||||
@@ -159,7 +159,7 @@ func TestThreeSimultaneousLocksForSameResource(t *testing.T) {
|
||||
// fmt.Printf("3rd lock obtained after 1st & 2nd locks are released\n")
|
||||
time.Sleep(testDrwMutexRefreshCallTimeout)
|
||||
|
||||
dm3rd.Unlock(context.Background())
|
||||
dm3rd.Unlock(t.Context())
|
||||
}()
|
||||
expect += 2*testDrwMutexAcquireTimeout + testDrwMutexRefreshCallTimeout
|
||||
|
||||
@@ -173,7 +173,7 @@ func TestThreeSimultaneousLocksForSameResource(t *testing.T) {
|
||||
time.Sleep(2 * testDrwMutexAcquireTimeout)
|
||||
// fmt.Println("Unlocking dm3")
|
||||
|
||||
dm3rd.Unlock(context.Background())
|
||||
dm3rd.Unlock(t.Context())
|
||||
}()
|
||||
|
||||
dm2nd.Lock(id, source)
|
||||
@@ -181,7 +181,7 @@ func TestThreeSimultaneousLocksForSameResource(t *testing.T) {
|
||||
// fmt.Printf("2nd lock obtained after 1st & 3rd locks are released\n")
|
||||
time.Sleep(testDrwMutexRefreshCallTimeout)
|
||||
|
||||
dm2nd.Unlock(context.Background())
|
||||
dm2nd.Unlock(t.Context())
|
||||
}()
|
||||
expect += 2*testDrwMutexAcquireTimeout + testDrwMutexRefreshCallTimeout
|
||||
|
||||
@@ -201,8 +201,8 @@ func TestTwoSimultaneousLocksForDifferentResources(t *testing.T) {
|
||||
|
||||
dm1.Lock(id, source)
|
||||
dm2.Lock(id, source)
|
||||
dm1.Unlock(context.Background())
|
||||
dm2.Unlock(context.Background())
|
||||
dm1.Unlock(t.Context())
|
||||
dm2.Unlock(t.Context())
|
||||
}
|
||||
|
||||
// Test refreshing lock - refresh should always return true
|
||||
@@ -214,7 +214,7 @@ func TestSuccessfulLockRefresh(t *testing.T) {
|
||||
dm := NewDRWMutex(ds, "aap")
|
||||
dm.refreshInterval = testDrwMutexRefreshInterval
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
|
||||
if !dm.GetLock(ctx, cancel, id, source, Options{Timeout: 5 * time.Minute}) {
|
||||
t.Fatal("GetLock() should be successful")
|
||||
@@ -230,7 +230,7 @@ func TestSuccessfulLockRefresh(t *testing.T) {
|
||||
}
|
||||
|
||||
// Should be safe operation in all cases
|
||||
dm.Unlock(context.Background())
|
||||
dm.Unlock(t.Context())
|
||||
}
|
||||
|
||||
// Test canceling context while quorum servers report lock not found
|
||||
@@ -250,7 +250,7 @@ func TestFailedRefreshLock(t *testing.T) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
ctx, cl := context.WithCancel(context.Background())
|
||||
ctx, cl := context.WithCancel(t.Context())
|
||||
cancel := func() {
|
||||
cl()
|
||||
wg.Done()
|
||||
@@ -267,7 +267,7 @@ func TestFailedRefreshLock(t *testing.T) {
|
||||
}
|
||||
|
||||
// Should be safe operation in all cases
|
||||
dm.Unlock(context.Background())
|
||||
dm.Unlock(t.Context())
|
||||
}
|
||||
|
||||
// Test Unlock should not timeout
|
||||
@@ -278,7 +278,7 @@ func TestUnlockShouldNotTimeout(t *testing.T) {
|
||||
|
||||
dm := NewDRWMutex(ds, "aap")
|
||||
dm.refreshInterval = testDrwMutexUnlockCallTimeout
|
||||
if !dm.GetLock(context.Background(), nil, id, source, Options{Timeout: 5 * time.Minute}) {
|
||||
if !dm.GetLock(t.Context(), nil, id, source, Options{Timeout: 5 * time.Minute}) {
|
||||
t.Fatal("GetLock() should be successful")
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ func TestUnlockShouldNotTimeout(t *testing.T) {
|
||||
|
||||
unlockReturned := make(chan struct{}, 1)
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 500*time.Millisecond)
|
||||
defer cancel()
|
||||
dm.Unlock(ctx)
|
||||
// Unlock is not blocking. Try to get a new lock.
|
||||
@@ -344,7 +344,7 @@ func BenchmarkMutexUncontended(b *testing.B) {
|
||||
mu := PaddedMutex{NewDRWMutex(ds, "")}
|
||||
for pb.Next() {
|
||||
mu.Lock(id, source)
|
||||
mu.Unlock(context.Background())
|
||||
mu.Unlock(b.Context())
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -361,7 +361,7 @@ func benchmarkMutex(b *testing.B, slack, work bool) {
|
||||
foo := 0
|
||||
for pb.Next() {
|
||||
mu.Lock(id, source)
|
||||
mu.Unlock(context.Background())
|
||||
mu.Unlock(b.Context())
|
||||
if work {
|
||||
for i := 0; i < 100; i++ {
|
||||
foo *= 2
|
||||
@@ -410,7 +410,7 @@ func BenchmarkMutexNoSpin(b *testing.B) {
|
||||
m.Lock(id, source)
|
||||
acc0 -= 100
|
||||
acc1 += 100
|
||||
m.Unlock(context.Background())
|
||||
m.Unlock(b.Context())
|
||||
} else {
|
||||
for i := 0; i < len(data); i += 4 {
|
||||
data[i]++
|
||||
@@ -442,7 +442,7 @@ func BenchmarkMutexSpin(b *testing.B) {
|
||||
m.Lock(id, source)
|
||||
acc0 -= 100
|
||||
acc1 += 100
|
||||
m.Unlock(context.Background())
|
||||
m.Unlock(b.Context())
|
||||
for i := 0; i < len(data); i += 4 {
|
||||
data[i]++
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package etag
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -138,7 +137,7 @@ var readerTests = []struct { // Reference values computed by: echo <content> | m
|
||||
|
||||
func TestReader(t *testing.T) {
|
||||
for i, test := range readerTests {
|
||||
reader := NewReader(context.Background(), strings.NewReader(test.Content), test.ETag, nil)
|
||||
reader := NewReader(t.Context(), strings.NewReader(test.Content), test.ETag, nil)
|
||||
if _, err := io.Copy(io.Discard, reader); err != nil {
|
||||
t.Fatalf("Test %d: read failed: %v", i, err)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user