mirror of
https://github.com/minio/minio.git
synced 2025-04-11 06:57:49 -04:00
Add detailed scanner trace output and notifications (#16668)
This commit is contained in:
parent
8a08861dd9
commit
fd6622458b
@ -1142,6 +1142,17 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
UserAgent: r.UserAgent(),
|
UserAgent: r.UserAgent(),
|
||||||
Host: handlers.GetSourceIP(r),
|
Host: handlers.GetSourceIP(r),
|
||||||
})
|
})
|
||||||
|
if objInfo.NumVersions > dataScannerExcessiveVersionsThreshold {
|
||||||
|
defer sendEvent(eventArgs{
|
||||||
|
EventName: event.ObjectManyVersions,
|
||||||
|
BucketName: objInfo.Bucket,
|
||||||
|
Object: objInfo,
|
||||||
|
ReqParams: extractReqParams(r),
|
||||||
|
RespElements: extractRespElements(w),
|
||||||
|
UserAgent: r.UserAgent(),
|
||||||
|
Host: handlers.GetSourceIP(r),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if redirectURL != nil { // success_action_redirect is valid and set.
|
if redirectURL != nil { // success_action_redirect is valid and set.
|
||||||
v := redirectURL.Query()
|
v := redirectURL.Query()
|
||||||
|
@ -69,9 +69,9 @@ const (
|
|||||||
|
|
||||||
// log scanner action.
|
// log scanner action.
|
||||||
// Use for s > scannerMetricStartTrace
|
// Use for s > scannerMetricStartTrace
|
||||||
func (p *scannerMetrics) log(s scannerMetric, paths ...string) func() {
|
func (p *scannerMetrics) log(s scannerMetric, paths ...string) func(custom map[string]string) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
return func() {
|
return func(custom map[string]string) {
|
||||||
duration := time.Since(startTime)
|
duration := time.Since(startTime)
|
||||||
|
|
||||||
atomic.AddUint64(&p.operations[s], 1)
|
atomic.AddUint64(&p.operations[s], 1)
|
||||||
@ -80,7 +80,7 @@ func (p *scannerMetrics) log(s scannerMetric, paths ...string) func() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s > scannerMetricStartTrace && globalTrace.NumSubscribers(madmin.TraceScanner) > 0 {
|
if s > scannerMetricStartTrace && globalTrace.NumSubscribers(madmin.TraceScanner) > 0 {
|
||||||
globalTrace.Publish(scannerTrace(s, startTime, duration, strings.Join(paths, " ")))
|
globalTrace.Publish(scannerTrace(s, startTime, duration, strings.Join(paths, " "), custom))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -59,6 +60,9 @@ const (
|
|||||||
healDeleteDangling = true
|
healDeleteDangling = true
|
||||||
healFolderIncludeProb = 32 // Include a clean folder one in n cycles.
|
healFolderIncludeProb = 32 // Include a clean folder one in n cycles.
|
||||||
healObjectSelectProb = 512 // Overall probability of a file being scanned; one in n.
|
healObjectSelectProb = 512 // Overall probability of a file being scanned; one in n.
|
||||||
|
|
||||||
|
dataScannerExcessiveVersionsThreshold = 1000 // Issue a warning when a single object has more versions than this
|
||||||
|
dataScannerExcessiveFoldersThreshold = 50000 // Issue a warning when a folder has more subfolders than this in a *set*
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -207,7 +211,11 @@ func runDataScanner(ctx context.Context, objAPI ObjectLayer) {
|
|||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
err = objAPI.NSScanner(ctx, bf, results, uint32(cycleInfo.current), scanMode)
|
err = objAPI.NSScanner(ctx, bf, results, uint32(cycleInfo.current), scanMode)
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
stopFn()
|
res := map[string]string{"cycle": fmt.Sprint(cycleInfo.current)}
|
||||||
|
if err != nil {
|
||||||
|
res["error"] = err.Error()
|
||||||
|
}
|
||||||
|
stopFn(res)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Store new cycle...
|
// Store new cycle...
|
||||||
cycleInfo.next++
|
cycleInfo.next++
|
||||||
@ -566,6 +574,19 @@ func (f *folderScanner) scanFolder(ctx context.Context, folder cachedFolder, int
|
|||||||
len(existingFolders)+len(newFolders) >= dataScannerCompactAtFolders ||
|
len(existingFolders)+len(newFolders) >= dataScannerCompactAtFolders ||
|
||||||
len(existingFolders)+len(newFolders) >= dataScannerForceCompactAtFolders
|
len(existingFolders)+len(newFolders) >= dataScannerForceCompactAtFolders
|
||||||
|
|
||||||
|
if len(existingFolders)+len(newFolders) > dataScannerExcessiveFoldersThreshold {
|
||||||
|
// Notify object accessed via a GET request.
|
||||||
|
sendEvent(eventArgs{
|
||||||
|
EventName: event.PrefixManyFolders,
|
||||||
|
BucketName: f.root,
|
||||||
|
Object: ObjectInfo{
|
||||||
|
Name: strings.TrimSuffix(folder.name, "/") + "/",
|
||||||
|
Size: int64(len(existingFolders) + len(newFolders)),
|
||||||
|
},
|
||||||
|
UserAgent: "scanner",
|
||||||
|
Host: globalMinioHost,
|
||||||
|
})
|
||||||
|
}
|
||||||
if !into.Compacted && shouldCompact {
|
if !into.Compacted && shouldCompact {
|
||||||
into.Compacted = true
|
into.Compacted = true
|
||||||
newFolders = append(newFolders, existingFolders...)
|
newFolders = append(newFolders, existingFolders...)
|
||||||
@ -632,7 +653,8 @@ func (f *folderScanner) scanFolder(ctx context.Context, folder cachedFolder, int
|
|||||||
f.updateCurrentPath(folder.name)
|
f.updateCurrentPath(folder.name)
|
||||||
stopFn := globalScannerMetrics.log(scannerMetricScanFolder, f.root, folder.name)
|
stopFn := globalScannerMetrics.log(scannerMetricScanFolder, f.root, folder.name)
|
||||||
scanFolder(folder)
|
scanFolder(folder)
|
||||||
stopFn()
|
stopFn(map[string]string{"type": "new"})
|
||||||
|
|
||||||
// Add new folders if this is new and we don't have existing.
|
// Add new folders if this is new and we don't have existing.
|
||||||
if !into.Compacted {
|
if !into.Compacted {
|
||||||
parent := f.updateCache.find(thisHash.Key())
|
parent := f.updateCache.find(thisHash.Key())
|
||||||
@ -661,9 +683,9 @@ func (f *folderScanner) scanFolder(ctx context.Context, folder cachedFolder, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.updateCurrentPath(folder.name)
|
f.updateCurrentPath(folder.name)
|
||||||
stopFn := globalScannerMetrics.log(scannerMetricScanFolder, f.root, folder.name, "EXISTING")
|
stopFn := globalScannerMetrics.log(scannerMetricScanFolder, f.root, folder.name)
|
||||||
scanFolder(folder)
|
scanFolder(folder)
|
||||||
stopFn()
|
stopFn(map[string]string{"type": "existing"})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan for healing
|
// Scan for healing
|
||||||
@ -803,7 +825,7 @@ func (f *folderScanner) scanFolder(ctx context.Context, folder cachedFolder, int
|
|||||||
this := cachedFolder{name: k, parent: &thisHash, objectHealProbDiv: 1}
|
this := cachedFolder{name: k, parent: &thisHash, objectHealProbDiv: 1}
|
||||||
stopFn := globalScannerMetrics.log(scannerMetricScanFolder, f.root, this.name, "HEALED")
|
stopFn := globalScannerMetrics.log(scannerMetricScanFolder, f.root, this.name, "HEALED")
|
||||||
scanFolder(this)
|
scanFolder(this)
|
||||||
stopFn()
|
stopFn(map[string]string{"type": "healed"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -817,9 +839,6 @@ func (f *folderScanner) scanFolder(ctx context.Context, folder cachedFolder, int
|
|||||||
flat.Compacted = true
|
flat.Compacted = true
|
||||||
var compact bool
|
var compact bool
|
||||||
if flat.Objects < dataScannerCompactLeastObject {
|
if flat.Objects < dataScannerCompactLeastObject {
|
||||||
if flat.Objects > 1 {
|
|
||||||
globalScannerMetrics.log(scannerMetricCompactFolder, folder.name)
|
|
||||||
}
|
|
||||||
compact = true
|
compact = true
|
||||||
} else {
|
} else {
|
||||||
// Compact if we only have objects as children...
|
// Compact if we only have objects as children...
|
||||||
@ -832,13 +851,20 @@ func (f *folderScanner) scanFolder(ctx context.Context, folder cachedFolder, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if compact {
|
|
||||||
globalScannerMetrics.log(scannerMetricCompactFolder, folder.name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if compact {
|
if compact {
|
||||||
|
stop := globalScannerMetrics.log(scannerMetricCompactFolder, folder.name)
|
||||||
f.newCache.deleteRecursive(thisHash)
|
f.newCache.deleteRecursive(thisHash)
|
||||||
f.newCache.replaceHashed(thisHash, folder.parent, *flat)
|
f.newCache.replaceHashed(thisHash, folder.parent, *flat)
|
||||||
|
total := map[string]string{
|
||||||
|
"objects": fmt.Sprint(flat.Objects),
|
||||||
|
"size": fmt.Sprint(flat.Size),
|
||||||
|
}
|
||||||
|
if flat.Versions > 0 {
|
||||||
|
total["versions"] = fmt.Sprint(flat.Versions)
|
||||||
|
}
|
||||||
|
stop(total)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1082,8 +1108,27 @@ func (i *scannerItem) applyVersionActions(ctx context.Context, o ObjectLayer, fi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fivs, err := i.applyNewerNoncurrentVersionLimit(ctx, o, fivs)
|
||||||
|
if err != nil {
|
||||||
|
return fivs, err
|
||||||
|
}
|
||||||
|
|
||||||
return i.applyNewerNoncurrentVersionLimit(ctx, o, fivs)
|
// Check if we have many versions after applyNewerNoncurrentVersionLimit.
|
||||||
|
if len(fivs) > dataScannerExcessiveVersionsThreshold {
|
||||||
|
// Notify object accessed via a GET request.
|
||||||
|
sendEvent(eventArgs{
|
||||||
|
EventName: event.ObjectManyVersions,
|
||||||
|
BucketName: i.bucket,
|
||||||
|
Object: ObjectInfo{
|
||||||
|
Name: i.objectPath(),
|
||||||
|
},
|
||||||
|
UserAgent: "scanner",
|
||||||
|
Host: globalMinioHost,
|
||||||
|
RespElements: map[string]string{"x-minio-versions": strconv.Itoa(len(fivs))},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return fivs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyActions will apply lifecycle checks on to a scanned item.
|
// applyActions will apply lifecycle checks on to a scanned item.
|
||||||
|
@ -66,7 +66,7 @@ func (fi FileInfo) DataShardFixed() bool {
|
|||||||
return fi.Metadata[reservedMetadataPrefixLowerDataShardFix] == "true"
|
return fi.Metadata[reservedMetadataPrefixLowerDataShardFix] == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heals a bucket if it doesn't exist on one of the disks, additionally
|
// HealBucket heals a bucket if it doesn't exist on one of the disks, additionally
|
||||||
// also heals the missing entries for bucket metadata files
|
// also heals the missing entries for bucket metadata files
|
||||||
// `policy.json, notification.xml, listeners.json`.
|
// `policy.json, notification.xml, listeners.json`.
|
||||||
func (er erasureObjects) HealBucket(ctx context.Context, bucket string, opts madmin.HealOpts) (
|
func (er erasureObjects) HealBucket(ctx context.Context, bucket string, opts madmin.HealOpts) (
|
||||||
@ -1062,7 +1062,12 @@ func healTrace(funcName healingMetric, startTime time.Time, bucket, object strin
|
|||||||
Path: pathJoin(bucket, decodeDirObject(object)),
|
Path: pathJoin(bucket, decodeDirObject(object)),
|
||||||
}
|
}
|
||||||
if opts != nil {
|
if opts != nil {
|
||||||
tr.Message = fmt.Sprintf("dry:%v, rm:%v, recreate:%v mode:%v", opts.DryRun, opts.Remove, opts.Recreate, opts.ScanMode)
|
tr.Custom = map[string]string{
|
||||||
|
"dry": fmt.Sprint(opts.DryRun),
|
||||||
|
"remove": fmt.Sprint(opts.Remove),
|
||||||
|
"recreate": fmt.Sprint(opts.Recreate),
|
||||||
|
"mode": fmt.Sprint(opts.ScanMode),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tr.Error = err.Error()
|
tr.Error = err.Error()
|
||||||
|
@ -1918,7 +1918,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
|
|||||||
writeSuccessResponseHeadersOnly(w)
|
writeSuccessResponseHeadersOnly(w)
|
||||||
|
|
||||||
// Notify object created event.
|
// Notify object created event.
|
||||||
sendEvent(eventArgs{
|
evt := eventArgs{
|
||||||
EventName: event.ObjectCreatedPut,
|
EventName: event.ObjectCreatedPut,
|
||||||
BucketName: bucket,
|
BucketName: bucket,
|
||||||
Object: objInfo,
|
Object: objInfo,
|
||||||
@ -1926,7 +1926,12 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
|
|||||||
RespElements: extractRespElements(w),
|
RespElements: extractRespElements(w),
|
||||||
UserAgent: r.UserAgent(),
|
UserAgent: r.UserAgent(),
|
||||||
Host: handlers.GetSourceIP(r),
|
Host: handlers.GetSourceIP(r),
|
||||||
})
|
}
|
||||||
|
sendEvent(evt)
|
||||||
|
if objInfo.NumVersions > dataScannerExcessiveVersionsThreshold {
|
||||||
|
evt.EventName = event.ObjectManyVersions
|
||||||
|
sendEvent(evt)
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the transitioned object whose object version is being overwritten.
|
// Remove the transitioned object whose object version is being overwritten.
|
||||||
if !globalTierConfigMgr.Empty() {
|
if !globalTierConfigMgr.Empty() {
|
||||||
|
@ -1019,7 +1019,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
|
|||||||
writeSuccessResponseXML(w, encodedSuccessResponse)
|
writeSuccessResponseXML(w, encodedSuccessResponse)
|
||||||
|
|
||||||
// Notify object created event.
|
// Notify object created event.
|
||||||
sendEvent(eventArgs{
|
evt := eventArgs{
|
||||||
EventName: event.ObjectCreatedCompleteMultipartUpload,
|
EventName: event.ObjectCreatedCompleteMultipartUpload,
|
||||||
BucketName: bucket,
|
BucketName: bucket,
|
||||||
Object: objInfo,
|
Object: objInfo,
|
||||||
@ -1027,7 +1027,13 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
|
|||||||
RespElements: extractRespElements(w),
|
RespElements: extractRespElements(w),
|
||||||
UserAgent: r.UserAgent(),
|
UserAgent: r.UserAgent(),
|
||||||
Host: handlers.GetSourceIP(r),
|
Host: handlers.GetSourceIP(r),
|
||||||
})
|
}
|
||||||
|
sendEvent(evt)
|
||||||
|
|
||||||
|
if objInfo.NumVersions > dataScannerExcessiveVersionsThreshold {
|
||||||
|
evt.EventName = event.ObjectManyVersions
|
||||||
|
sendEvent(evt)
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the transitioned object whose object version is being overwritten.
|
// Remove the transitioned object whose object version is being overwritten.
|
||||||
if !globalTierConfigMgr.Empty() {
|
if !globalTierConfigMgr.Empty() {
|
||||||
|
@ -555,7 +555,7 @@ func storageTrace(s storageMetric, startTime time.Time, duration time.Duration,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func scannerTrace(s scannerMetric, startTime time.Time, duration time.Duration, path string) madmin.TraceInfo {
|
func scannerTrace(s scannerMetric, startTime time.Time, duration time.Duration, path string, custom map[string]string) madmin.TraceInfo {
|
||||||
return madmin.TraceInfo{
|
return madmin.TraceInfo{
|
||||||
TraceType: madmin.TraceScanner,
|
TraceType: madmin.TraceScanner,
|
||||||
Time: startTime,
|
Time: startTime,
|
||||||
@ -563,6 +563,7 @@ func scannerTrace(s scannerMetric, startTime time.Time, duration time.Duration,
|
|||||||
FuncName: "scanner." + s.String(),
|
FuncName: "scanner." + s.String(),
|
||||||
Duration: duration,
|
Duration: duration,
|
||||||
Path: path,
|
Path: path,
|
||||||
|
Custom: custom,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,11 +492,15 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
|
|||||||
return sizeSummary{}, errSkipFile
|
return sizeSummary{}, errSkipFile
|
||||||
}
|
}
|
||||||
stopFn := globalScannerMetrics.log(scannerMetricScanObject, s.diskPath, pathJoin(item.bucket, item.objectPath()))
|
stopFn := globalScannerMetrics.log(scannerMetricScanObject, s.diskPath, pathJoin(item.bucket, item.objectPath()))
|
||||||
defer stopFn()
|
res := make(map[string]string, 8)
|
||||||
|
defer func() {
|
||||||
|
stopFn(res)
|
||||||
|
}()
|
||||||
|
|
||||||
doneSz := globalScannerMetrics.timeSize(scannerMetricReadMetadata)
|
doneSz := globalScannerMetrics.timeSize(scannerMetricReadMetadata)
|
||||||
buf, err := s.readMetadata(ctx, item.Path)
|
buf, err := s.readMetadata(ctx, item.Path)
|
||||||
doneSz(len(buf))
|
doneSz(len(buf))
|
||||||
|
res["metasize"] = fmt.Sprint(len(buf))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if intDataUpdateTracker.debug {
|
if intDataUpdateTracker.debug {
|
||||||
console.Debugf(color.Green("scannerBucket:")+" object path missing: %v: %w\n", item.Path, err)
|
console.Debugf(color.Green("scannerBucket:")+" object path missing: %v: %w\n", item.Path, err)
|
||||||
@ -515,6 +519,7 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
|
|||||||
}
|
}
|
||||||
return sizeSummary{}, errSkipFile
|
return sizeSummary{}, errSkipFile
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeS := sizeSummary{}
|
sizeS := sizeSummary{}
|
||||||
var noTiers bool
|
var noTiers bool
|
||||||
if noTiers = globalTierConfigMgr.Empty(); !noTiers {
|
if noTiers = globalTierConfigMgr.Empty(); !noTiers {
|
||||||
@ -560,12 +565,45 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply tier sweep action on free versions
|
// apply tier sweep action on free versions
|
||||||
|
if len(fivs.FreeVersions) > 0 {
|
||||||
|
res["free-versions"] = fmt.Sprint(len(fivs.FreeVersions))
|
||||||
|
}
|
||||||
for _, freeVersion := range fivs.FreeVersions {
|
for _, freeVersion := range fivs.FreeVersions {
|
||||||
oi := freeVersion.ToObjectInfo(item.bucket, item.objectPath(), versioned)
|
oi := freeVersion.ToObjectInfo(item.bucket, item.objectPath(), versioned)
|
||||||
done = globalScannerMetrics.time(scannerMetricTierObjSweep)
|
done = globalScannerMetrics.time(scannerMetricTierObjSweep)
|
||||||
item.applyTierObjSweep(ctx, objAPI, oi)
|
item.applyTierObjSweep(ctx, objAPI, oi)
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These are rather expensive. Skip if nobody listens.
|
||||||
|
if globalTrace.NumSubscribers(madmin.TraceScanner) > 0 {
|
||||||
|
if sizeS.versions > 0 {
|
||||||
|
res["versions"] = fmt.Sprint()
|
||||||
|
}
|
||||||
|
res["size"] = fmt.Sprint(sizeS.totalSize)
|
||||||
|
if len(sizeS.tiers) > 0 {
|
||||||
|
for name, tier := range sizeS.tiers {
|
||||||
|
res["size-"+name] = fmt.Sprint(tier.TotalSize)
|
||||||
|
res["versions-"+name] = fmt.Sprint(tier.NumVersions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sizeS.failedCount > 0 {
|
||||||
|
res["repl-failed"] = fmt.Sprintf("%d versions, %d bytes", sizeS.failedCount, sizeS.failedSize)
|
||||||
|
}
|
||||||
|
if sizeS.pendingCount > 0 {
|
||||||
|
res["repl-pending"] = fmt.Sprintf("%d versions, %d bytes", sizeS.pendingCount, sizeS.pendingSize)
|
||||||
|
}
|
||||||
|
for tgt, st := range sizeS.replTargetStats {
|
||||||
|
res["repl-size-"+tgt] = fmt.Sprint(st.replicatedSize)
|
||||||
|
if st.failedCount > 0 {
|
||||||
|
res["repl-failed-"+tgt] = fmt.Sprintf("%d versions, %d bytes", st.failedCount, st.failedSize)
|
||||||
|
}
|
||||||
|
if st.pendingCount > 0 {
|
||||||
|
res["repl-pending-"+tgt] = fmt.Sprintf("%d versions, %d bytes", st.pendingCount, st.pendingSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sizeS, nil
|
return sizeS, nil
|
||||||
}, scanMode)
|
}, scanMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
2
go.mod
2
go.mod
@ -48,7 +48,7 @@ require (
|
|||||||
github.com/minio/dperf v0.4.2
|
github.com/minio/dperf v0.4.2
|
||||||
github.com/minio/highwayhash v1.0.2
|
github.com/minio/highwayhash v1.0.2
|
||||||
github.com/minio/kes-go v0.1.0
|
github.com/minio/kes-go v0.1.0
|
||||||
github.com/minio/madmin-go/v2 v2.0.12
|
github.com/minio/madmin-go/v2 v2.0.13-0.20230220143547-e6641ef0b8d5
|
||||||
github.com/minio/minio-go/v7 v7.0.48
|
github.com/minio/minio-go/v7 v7.0.48
|
||||||
github.com/minio/mux v1.9.0
|
github.com/minio/mux v1.9.0
|
||||||
github.com/minio/pkg v1.6.1
|
github.com/minio/pkg v1.6.1
|
||||||
|
4
go.sum
4
go.sum
@ -776,8 +776,8 @@ github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLT
|
|||||||
github.com/minio/kes-go v0.1.0 h1:h201DyOYP5sTqajkxFGxmXz/kPbT8HQNX1uh3Yx2PFc=
|
github.com/minio/kes-go v0.1.0 h1:h201DyOYP5sTqajkxFGxmXz/kPbT8HQNX1uh3Yx2PFc=
|
||||||
github.com/minio/kes-go v0.1.0/go.mod h1:VorHLaIYis9/MxAHAtXN4d8PUMNKhIxTIlvFt0hBOEo=
|
github.com/minio/kes-go v0.1.0/go.mod h1:VorHLaIYis9/MxAHAtXN4d8PUMNKhIxTIlvFt0hBOEo=
|
||||||
github.com/minio/madmin-go v1.6.6/go.mod h1:ATvkBOLiP3av4D++2v1UEHC/QzsGtgXD5kYvvRYzdKs=
|
github.com/minio/madmin-go v1.6.6/go.mod h1:ATvkBOLiP3av4D++2v1UEHC/QzsGtgXD5kYvvRYzdKs=
|
||||||
github.com/minio/madmin-go/v2 v2.0.12 h1:3PKFAhiZOMjeShxhtY10INw1kDrY/2VwH55FAat3hM4=
|
github.com/minio/madmin-go/v2 v2.0.13-0.20230220143547-e6641ef0b8d5 h1:IZa7nXFFDdOigg2wufK51C6oTB5q9c6LCV969u3L0YY=
|
||||||
github.com/minio/madmin-go/v2 v2.0.12/go.mod h1:5aFi/VLWBHC2DEFfGIlUmAeJhaF4ZAjuYpEWZFU14Zw=
|
github.com/minio/madmin-go/v2 v2.0.13-0.20230220143547-e6641ef0b8d5/go.mod h1:5aFi/VLWBHC2DEFfGIlUmAeJhaF4ZAjuYpEWZFU14Zw=
|
||||||
github.com/minio/mc v0.0.0-20230216192011-54e2edd1be94 h1:umgaS1OMD7qHLca/GH/eoox8RL44tQenBp34ZV1aWkU=
|
github.com/minio/mc v0.0.0-20230216192011-54e2edd1be94 h1:umgaS1OMD7qHLca/GH/eoox8RL44tQenBp34ZV1aWkU=
|
||||||
github.com/minio/mc v0.0.0-20230216192011-54e2edd1be94/go.mod h1:4tBWo9BLlIUajqXqo5HdxxpQAdXktlOLSVvHaHFNYjE=
|
github.com/minio/mc v0.0.0-20230216192011-54e2edd1be94/go.mod h1:4tBWo9BLlIUajqXqo5HdxxpQAdXktlOLSVvHaHFNYjE=
|
||||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
|
@ -57,6 +57,8 @@ const (
|
|||||||
ObjectRestoreCompleted
|
ObjectRestoreCompleted
|
||||||
ObjectTransitionFailed
|
ObjectTransitionFailed
|
||||||
ObjectTransitionComplete
|
ObjectTransitionComplete
|
||||||
|
ObjectManyVersions
|
||||||
|
PrefixManyFolders
|
||||||
|
|
||||||
objectSingleTypesEnd
|
objectSingleTypesEnd
|
||||||
// Start Compound types that require expansion:
|
// Start Compound types that require expansion:
|
||||||
@ -67,6 +69,7 @@ const (
|
|||||||
ObjectReplicationAll
|
ObjectReplicationAll
|
||||||
ObjectRestoreAll
|
ObjectRestoreAll
|
||||||
ObjectTransitionAll
|
ObjectTransitionAll
|
||||||
|
ObjectScannerAll
|
||||||
Everything
|
Everything
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -113,6 +116,11 @@ func (name Name) Expand() []Name {
|
|||||||
ObjectTransitionFailed,
|
ObjectTransitionFailed,
|
||||||
ObjectTransitionComplete,
|
ObjectTransitionComplete,
|
||||||
}
|
}
|
||||||
|
case ObjectScannerAll:
|
||||||
|
return []Name{
|
||||||
|
ObjectManyVersions,
|
||||||
|
PrefixManyFolders,
|
||||||
|
}
|
||||||
case Everything:
|
case Everything:
|
||||||
res := make([]Name, objectSingleTypesEnd-1)
|
res := make([]Name, objectSingleTypesEnd-1)
|
||||||
for i := range res {
|
for i := range res {
|
||||||
@ -202,6 +210,10 @@ func (name Name) String() string {
|
|||||||
return "s3:ObjectTransition:Failed"
|
return "s3:ObjectTransition:Failed"
|
||||||
case ObjectTransitionComplete:
|
case ObjectTransitionComplete:
|
||||||
return "s3:ObjectTransition:Complete"
|
return "s3:ObjectTransition:Complete"
|
||||||
|
case ObjectManyVersions:
|
||||||
|
return "s3:Scanner:ManyVersions"
|
||||||
|
case PrefixManyFolders:
|
||||||
|
return "s3:Scanner:BigPrefix"
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
@ -314,6 +326,10 @@ func ParseName(s string) (Name, error) {
|
|||||||
return ObjectTransitionComplete, nil
|
return ObjectTransitionComplete, nil
|
||||||
case "s3:ObjectTransition:*":
|
case "s3:ObjectTransition:*":
|
||||||
return ObjectTransitionAll, nil
|
return ObjectTransitionAll, nil
|
||||||
|
case "s3:Scanner:ManyVersions":
|
||||||
|
return ObjectManyVersions, nil
|
||||||
|
case "s3:Scanner:BigPrefix":
|
||||||
|
return PrefixManyFolders, nil
|
||||||
default:
|
default:
|
||||||
return 0, &ErrInvalidEventName{s}
|
return 0, &ErrInvalidEventName{s}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user