Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package minio-client for openSUSE:Factory checked in at 2022-10-29 20:17:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/minio-client (Old) and /work/SRC/openSUSE:Factory/.minio-client.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "minio-client" Sat Oct 29 20:17:50 2022 rev:20 rq:1032217 version:20221029T100923Z Changes: -------- --- /work/SRC/openSUSE:Factory/minio-client/minio-client.changes 2022-10-25 11:39:45.428515762 +0200 +++ /work/SRC/openSUSE:Factory/.minio-client.new.2275/minio-client.changes 2022-10-29 20:19:01.578824303 +0200 @@ -1,0 +2,9 @@ +Sat Oct 29 15:39:08 UTC 2022 - ka...@b1-systems.de + +- Update to version 20221029T100923Z: + * Add new healing summary (#4323) + * support inspect: bump up metadata version (#4331) + * Improve format of perf tests output (#4330) + * Updating usage for mc replicate edit (#4328) + +------------------------------------------------------------------- Old: ---- mc-20221022T033929Z.tar.gz New: ---- mc-20221029T100923Z.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ minio-client.spec ++++++ --- /var/tmp/diff_new_pack.hcx4xp/_old 2022-10-29 20:19:02.418828778 +0200 +++ /var/tmp/diff_new_pack.hcx4xp/_new 2022-10-29 20:19:02.426828821 +0200 @@ -22,7 +22,7 @@ %define binary_name minio-client Name: minio-client -Version: 20221022T033929Z +Version: 20221029T100923Z Release: 0 Summary: Client for MinIO License: AGPL-3.0-only ++++++ _service ++++++ --- /var/tmp/diff_new_pack.hcx4xp/_old 2022-10-29 20:19:02.486829141 +0200 +++ /var/tmp/diff_new_pack.hcx4xp/_new 2022-10-29 20:19:02.490829162 +0200 @@ -5,7 +5,7 @@ <param name="exclude">.git</param> <param name="changesgenerate">enable</param> <param name="versionformat">@PARENT_TAG@</param> - <param name="revision">RELEASE.2022-10-22T03-39-29Z</param> + <param name="revision">RELEASE.2022-10-29T10-09-23Z</param> <param name="match-tag">RELEASE.*</param> <param name="versionrewrite-pattern">RELEASE\.(.*)-(.*)-(.*)-(.*)-(.*)</param> <param name="versionrewrite-replacement">\1\2\3\4\5</param> @@ -21,7 +21,7 @@ <param name="compression">gz</param> </service> <service name="go_modules" mode="disabled"> - <param name="archive">mc-20221022T033929Z.tar.gz</param> + <param name="archive">mc-20221029T100923Z.tar.gz</param> </service> </services> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.hcx4xp/_old 2022-10-29 20:19:02.514829290 +0200 +++ /var/tmp/diff_new_pack.hcx4xp/_new 2022-10-29 20:19:02.522829332 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/minio/mc</param> - <param name="changesrevision">88796ea618092bb27368c00e2b387857945357fb</param></service></servicedata> + <param name="changesrevision">929062c86be50d7f6350ab2da929585720f4fe74</param></service></servicedata> (No newline at EOF) ++++++ mc-20221022T033929Z.tar.gz -> mc-20221029T100923Z.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20221022T033929Z/cmd/admin-heal.go new/mc-20221029T100923Z/cmd/admin-heal.go --- old/mc-20221022T033929Z/cmd/admin-heal.go 2022-10-22 05:39:29.000000000 +0200 +++ new/mc-20221029T100923Z/cmd/admin-heal.go 2022-10-29 12:09:23.000000000 +0200 @@ -19,13 +19,14 @@ import ( "fmt" + "math" "net/url" "path/filepath" "sort" "strings" "time" - humanize "github.com/dustin/go-humanize" + "github.com/dustin/go-humanize" "github.com/fatih/color" "github.com/minio/cli" json "github.com/minio/colorjson" @@ -465,11 +466,17 @@ func (s shortBackgroundHealStatusMessage) String() string { healPrettyMsg := "" var ( - totalItems uint64 - totalBytes uint64 - itemsHealed uint64 - bytesHealed uint64 - startedAt time.Time + totalItems uint64 + totalBytes uint64 + itemsHealed uint64 + bytesHealed uint64 + itemsFailed uint64 + bytesFailed uint64 + itemsHealedPerSec float64 + bytesHealedPerSec float64 + startedAt time.Time + setsExceedsStd int + setsExceedsReduced int // The addition of Elapsed time of each parallel healing operation // this is needed to calculate the rate of healing @@ -481,50 +488,70 @@ var problematicDisks int - dedup := make(map[setIndex]struct{}) - for _, set := range s.HealInfo.Sets { setsStatus := generateSetsStatus(set.Disks) + // Furthest along disk... + var furthestHealingDisk *madmin.Disk + missingInSet := 0 for _, disk := range set.Disks { // Ignore disk with non 'ok' status if disk.State != madmin.DriveStateOk { if disk.State != madmin.DriveStateUnformatted { + missingInSet++ problematicDisks++ } continue } if disk.HealInfo != nil { - // Avoid counting two disks beloning to the same pool/set - diskSet := setIndex{pool: disk.PoolIndex, set: disk.SetIndex} - _, found := dedup[diskSet] - if found { + missingInSet++ + disk := disk + if furthestHealingDisk == nil { + furthestHealingDisk = &disk + continue + } + if disk.HealInfo.ItemsHealed+disk.HealInfo.ItemsFailed > furthestHealingDisk.HealInfo.ItemsHealed+furthestHealingDisk.HealInfo.ItemsFailed { + furthestHealingDisk = &disk continue } - dedup[diskSet] = struct{}{} + } + } + if furthestHealingDisk != nil { + disk := furthestHealingDisk + diskSet := setIndex{pool: disk.PoolIndex, set: disk.SetIndex} + + // Approximate values + totalItems += disk.HealInfo.ObjectsTotalCount + totalBytes += disk.HealInfo.ObjectsTotalSize + itemsHealed += disk.HealInfo.ItemsHealed + bytesHealed += disk.HealInfo.BytesDone + bytesFailed += disk.HealInfo.BytesFailed + itemsFailed += disk.HealInfo.ItemsFailed + + if !disk.HealInfo.Started.IsZero() { + if !disk.HealInfo.Started.Before(startedAt) { + startedAt = disk.HealInfo.Started + } + + if !disk.HealInfo.LastUpdate.IsZero() { + accumulatedElapsedTime += disk.HealInfo.LastUpdate.Sub(disk.HealInfo.Started) + } + + bytesHealedPerSec += float64(time.Second) * float64(disk.HealInfo.BytesDone) / float64(disk.HealInfo.LastUpdate.Sub(disk.HealInfo.Started)) + itemsHealedPerSec += float64(time.Second) * float64(disk.HealInfo.ItemsHealed+disk.HealInfo.ItemsFailed) / float64(disk.HealInfo.LastUpdate.Sub(disk.HealInfo.Started)) - // Approximate values - totalItems += disk.HealInfo.ObjectsTotalCount - totalBytes += disk.HealInfo.ObjectsTotalSize - itemsHealed += disk.HealInfo.ItemsHealed - bytesHealed += disk.HealInfo.BytesDone - - if !disk.HealInfo.Started.IsZero() { - if !disk.HealInfo.Started.Before(startedAt) { - startedAt = disk.HealInfo.Started - } - - if !disk.HealInfo.LastUpdate.IsZero() { - accumulatedElapsedTime += disk.HealInfo.LastUpdate.Sub(disk.HealInfo.Started) - } - - scanSpeed := float64(disk.UsedSpace) / float64(time.Now().Sub(disk.HealInfo.Started)) - remainingTime := time.Duration(float64(setsStatus[diskSet].maxUsedSpace-disk.UsedSpace) / scanSpeed) - if remainingTime > healingRemaining { - healingRemaining = remainingTime - } + scanSpeed := float64(disk.UsedSpace) / float64(time.Now().Sub(disk.HealInfo.Started)) + remainingTime := time.Duration(float64(setsStatus[diskSet].maxUsedSpace-disk.UsedSpace) / scanSpeed) + if remainingTime > healingRemaining { + healingRemaining = remainingTime } } + if n, ok := s.HealInfo.SCParity["STANDARD"]; ok && missingInSet > n { + setsExceedsStd++ + } + if n, ok := s.HealInfo.SCParity["REDUCED_REDUNDANCY"]; ok && missingInSet > n { + setsExceedsReduced++ + } } } @@ -540,19 +567,25 @@ if totalItems > 0 && totalBytes > 0 { // Objects healed information - itemsPct := 100 * float64(itemsHealed) / float64(totalItems) - bytesPct := 100 * float64(bytesHealed) / float64(totalBytes) + itemsPct := math.Min(100, 100*float64(itemsHealed)/float64(totalItems)) + bytesPct := math.Min(100, 100*float64(bytesHealed)/float64(totalBytes)) healPrettyMsg += fmt.Sprintf("Objects Healed: %s/%s (%s), %s/%s (%s)\n", humanize.Comma(int64(itemsHealed)), humanize.Comma(int64(totalItems)), humanize.CommafWithDigits(itemsPct, 1)+"%%", humanize.Bytes(bytesHealed), humanize.Bytes(totalBytes), humanize.CommafWithDigits(bytesPct, 1)+"%%") + + if itemsFailed > 0 { + itemsPct := math.Min(100, 100*float64(itemsFailed)/float64(totalItems)) + bytesPct := math.Min(100, 100*float64(bytesFailed)/float64(totalBytes)) + healPrettyMsg += fmt.Sprintf("Objects Failed: %s/%s (%s), %s/%s (%s)\n", + humanize.Comma(int64(itemsFailed)), humanize.Comma(int64(totalItems)), humanize.CommafWithDigits(itemsPct, 1)+"%%", + humanize.Bytes(bytesFailed), humanize.Bytes(totalBytes), humanize.CommafWithDigits(bytesPct, 1)+"%%") + } } else { healPrettyMsg += fmt.Sprintf("Objects Healed: %s, %s\n", humanize.Comma(int64(itemsHealed)), humanize.Bytes(bytesHealed)) } if accumulatedElapsedTime > 0 { - bytesHealedPerSec := float64(uint64(time.Second)*bytesHealed) / float64(accumulatedElapsedTime) - itemsHealedPerSec := float64(uint64(time.Second)*itemsHealed) / float64(accumulatedElapsedTime) healPrettyMsg += fmt.Sprintf("Heal rate: %d obj/s, %s/s\n", int64(itemsHealedPerSec), humanize.IBytes(uint64(bytesHealedPerSec))) } @@ -564,7 +597,14 @@ healPrettyMsg += "\n" healPrettyMsg += fmt.Sprintf("%d offline disk(s) found.", problematicDisks) } - + if setsExceedsStd > 0 { + healPrettyMsg += "\n" + healPrettyMsg += fmt.Sprintf("%d of %d sets exceeds standard parity count EC:%d lost/offline disks", setsExceedsStd, len(s.HealInfo.Sets), s.HealInfo.SCParity["STANDARD"]) + } + if setsExceedsReduced > 0 { + healPrettyMsg += "\n" + healPrettyMsg += fmt.Sprintf("%d of %d sets exceeds reduced parity count EC:%d lost/offline disks", setsExceedsReduced, len(s.HealInfo.Sets), s.HealInfo.SCParity["REDUCED_REDUNDANCY"]) + } return healPrettyMsg } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20221022T033929Z/cmd/inspect-export.go new/mc-20221029T100923Z/cmd/inspect-export.go --- old/mc-20221022T033929Z/cmd/inspect-export.go 2022-10-22 05:39:29.000000000 +0200 +++ new/mc-20221029T100923Z/cmd/inspect-export.go 2022-10-29 12:09:23.000000000 +0200 @@ -290,7 +290,7 @@ const ( xlHeaderVersion = 2 - xlMetaVersion = 1 + xlMetaVersion = 2 ) func decodeXLHeaders(buf []byte) (versions int, b []byte, e error) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20221022T033929Z/cmd/replicate-edit.go new/mc-20221029T100923Z/cmd/replicate-edit.go --- old/mc-20221022T033929Z/cmd/replicate-edit.go 2022-10-22 05:39:29.000000000 +0200 +++ new/mc-20221029T100923Z/cmd/replicate-edit.go 2022-10-29 12:09:23.000000000 +0200 @@ -73,7 +73,7 @@ {{.HelpName}} - {{.Usage}} USAGE: - {{.HelpName}} TARGET + {{.HelpName}} TARGET --id=RULE-ID [FLAGS] FLAGS: {{range .VisibleFlags}}{{.}} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20221022T033929Z/cmd/support-perf-drive.go new/mc-20221029T100923Z/cmd/support-perf-drive.go --- old/mc-20221022T033929Z/cmd/support-perf-drive.go 2022-10-22 05:39:29.000000000 +0200 +++ new/mc-20221029T100923Z/cmd/support-perf-drive.go 2022-10-29 12:09:23.000000000 +0200 @@ -68,11 +68,12 @@ if globalJSON { if e != nil { - printMsg(PerfTestResult{ + printMsg(convertPerfResult(PerfTestResult{ Type: DrivePerfTest, Err: e.Error(), Final: true, - }) + })) + return nil } @@ -82,11 +83,11 @@ results = append(results, result) } } - printMsg(PerfTestResult{ + printMsg(convertPerfResult(PerfTestResult{ Type: DrivePerfTest, DriveResult: results, Final: true, - }) + })) return nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20221022T033929Z/cmd/support-perf-net.go new/mc-20221029T100923Z/cmd/support-perf-net.go --- old/mc-20221022T033929Z/cmd/support-perf-net.go 2022-10-22 05:39:29.000000000 +0200 +++ new/mc-20221029T100923Z/cmd/support-perf-net.go 2022-10-29 12:09:23.000000000 +0200 @@ -64,17 +64,17 @@ if globalJSON { select { case e := <-errorCh: - printMsg(PerfTestResult{ + printMsg(convertPerfResult(PerfTestResult{ Type: NetPerfTest, Err: e.Error(), Final: true, - }) + })) case result := <-resultCh: - printMsg(PerfTestResult{ + printMsg(convertPerfResult(PerfTestResult{ Type: NetPerfTest, NetResult: &result, Final: true, - }) + })) } return nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20221022T033929Z/cmd/support-perf-object.go new/mc-20221029T100923Z/cmd/support-perf-object.go --- old/mc-20221022T033929Z/cmd/support-perf-object.go 2022-10-22 05:39:29.000000000 +0200 +++ new/mc-20221029T100923Z/cmd/support-perf-object.go 2022-10-29 12:09:23.000000000 +0200 @@ -95,11 +95,11 @@ if globalJSON { if e != nil { - printMsg(PerfTestResult{ + printMsg(convertPerfResult(PerfTestResult{ Type: ObjectPerfTest, Err: e.Error(), Final: true, - }) + })) return nil } @@ -108,17 +108,13 @@ if result.Version == "" { continue } - printMsg(PerfTestResult{ - Type: ObjectPerfTest, - ObjectResult: &result, - }) } - printMsg(PerfTestResult{ + printMsg(convertPerfResult(PerfTestResult{ Type: ObjectPerfTest, ObjectResult: &result, Final: true, - }) + })) return nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20221022T033929Z/cmd/support-perf.go new/mc-20221029T100923Z/cmd/support-perf.go --- old/mc-20221022T033929Z/cmd/support-perf.go 2022-10-22 05:39:29.000000000 +0200 +++ new/mc-20221029T100923Z/cmd/support-perf.go 2022-10-29 12:09:23.000000000 +0200 @@ -106,6 +106,53 @@ `, } +// PerfTestOutput - stores the final output of performance test(s) +type PerfTestOutput struct { + ObjectResult *ObjTestResult `json:"object,omitempty"` + NetResult *madmin.NetperfResult `json:"network,omitempty"` + DriveResult []DriveTestResult `json:"drive,omitempty"` + Error string `json:"error,omitempty"` +} + +// DriveTestResult - result of the drive performance test +type DriveTestResult struct { + Endpoint string `json:"endpoint"` + DrivePerf []madmin.DrivePerf `json:"drivePerf,omitempty"` + Error string `json:"error,omitempty"` +} + +// ObjTestResult - result of the object performance test +type ObjTestResult struct { + Servers int `json:"servers"` + Drives int `json:"drives"` + Size int `json:"size"` + Concurrent int `json:"concurrent"` + PUTStats ObjPUTStats `json:"PUTStats"` + GETStats ObjGETStats `json:"GETStats"` +} + +// ObjStatServer - Server level object performance stats +type ObjStatServer struct { + Endpoint string `json:"endpoint"` + Throughput uint64 `json:"throughput"` + ObjectsPerSec uint64 `json:"objectsPerSec"` + Error string `json:"error,omitempty"` +} + +// ObjPUTStats - PUT stats of all the servers +type ObjPUTStats struct { + Throughput uint64 `json:"throughput"` + ObjectsPerSec uint64 `json:"objectsPerSec"` + Response madmin.Timings `json:"responseTime"` + Servers []ObjStatServer `json:"servers"` +} + +// ObjGETStats - GET stats of all the servers +type ObjGETStats struct { + ObjPUTStats + TTFB madmin.Timings `json:"ttfb,omitempty"` +} + func objectTestVerboseResult(result *madmin.SpeedTestResult) (msg string) { msg += "PUT:\n" for _, node := range result.PUTStats.Servers { @@ -136,12 +183,13 @@ return msg } -func (p PerfTestResult) String() string { +// String - dummy function to confirm to the 'message' interface. Not used. +func (p PerfTestOutput) String() string { return "" } -// JSON - jsonified update message. -func (p PerfTestResult) JSON() string { +// JSON - jsonified output of the perf tests +func (p PerfTestOutput) JSON() string { JSONBytes, e := json.MarshalIndent(p, "", " ") fatalIf(probe.NewError(e), "Unable to marshal into JSON.") return string(JSONBytes) @@ -176,6 +224,94 @@ return nil } +func convertDriveTestResult(dr madmin.DriveSpeedTestResult) DriveTestResult { + return DriveTestResult{ + Endpoint: dr.Endpoint, + DrivePerf: dr.DrivePerf, + Error: dr.Error, + } +} + +func convertDriveTestResults(driveResults []madmin.DriveSpeedTestResult) []DriveTestResult { + results := []DriveTestResult{} + for _, dr := range driveResults { + results = append(results, convertDriveTestResult(dr)) + } + return results +} + +func convertObjStatServers(ss []madmin.SpeedTestStatServer) []ObjStatServer { + out := []ObjStatServer{} + for _, s := range ss { + out = append(out, ObjStatServer{ + Endpoint: s.Endpoint, + Throughput: s.ThroughputPerSec, + ObjectsPerSec: s.ObjectsPerSec, + Error: s.Err, + }) + } + return out +} + +func convertPUTStats(stats madmin.SpeedTestStats) ObjPUTStats { + return ObjPUTStats{ + Throughput: stats.ThroughputPerSec, + ObjectsPerSec: stats.ObjectsPerSec, + Response: stats.Response, + Servers: convertObjStatServers(stats.Servers), + } +} + +func convertGETStats(stats madmin.SpeedTestStats) ObjGETStats { + return ObjGETStats{ + ObjPUTStats: convertPUTStats(stats), + TTFB: stats.TTFB, + } +} + +func convertObjTestResult(objResult *madmin.SpeedTestResult) ObjTestResult { + if objResult == nil { + return ObjTestResult{} + } + result := ObjTestResult{ + Servers: objResult.Servers, + Drives: objResult.Disks, + Size: objResult.Size, + Concurrent: objResult.Concurrent, + } + result.PUTStats = convertPUTStats(objResult.PUTStats) + result.GETStats = convertGETStats(objResult.GETStats) + return result +} + +func updatePerfOutput(r PerfTestResult, out *PerfTestOutput) { + switch r.Type { + case DrivePerfTest: + out.DriveResult = convertDriveTestResults(r.DriveResult) + case ObjectPerfTest: + or := convertObjTestResult(r.ObjectResult) + out.ObjectResult = &or + case NetPerfTest: + out.NetResult = r.NetResult + default: + fatalIf(errDummy().Trace(), fmt.Sprintf("Invalid test type %d", r.Type)) + } +} + +func convertPerfResult(r PerfTestResult) PerfTestOutput { + out := PerfTestOutput{} + updatePerfOutput(r, &out) + return out +} + +func convertPerfResults(results []PerfTestResult) PerfTestOutput { + out := PerfTestOutput{} + for _, r := range results { + updatePerfOutput(r, &out) + } + return out +} + func execSupportPerf(ctx *cli.Context, aliasedURL string, perfType string) { alias, apiKey := initSubnetConnectivity(ctx, aliasedURL, true) if len(apiKey) == 0 { @@ -193,7 +329,7 @@ resultFileName := resultFileNamePfx + ".json" regInfo := getClusterRegInfo(getAdminInfo(aliasedURL), alias) - tmpFileName, e := zipPerfResult(results, resultFileName, regInfo) + tmpFileName, e := zipPerfResult(convertPerfResults(results), resultFileName, regInfo) fatalIf(probe.NewError(e), "Error creating zip from perf test results:") if globalAirgapped { @@ -268,7 +404,7 @@ } // compress MinIO performance output -func zipPerfResult(perfResult []PerfTestResult, resultFilename string, regInfo ClusterRegistrationInfo) (string, error) { +func zipPerfResult(perfOutput PerfTestOutput, resultFilename string, regInfo ClusterRegistrationInfo) (string, error) { // Create profile zip file tmpArchive, e := os.CreateTemp("", "mc-perf-") @@ -280,7 +416,7 @@ zipWriter := zip.NewWriter(tmpArchive) defer zipWriter.Close() - e = writeJSONObjToZip(zipWriter, perfResult, resultFilename) + e = writeJSONObjToZip(zipWriter, perfOutput, resultFilename) if e != nil { return "", e } ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/minio-client/vendor.tar.gz /work/SRC/openSUSE:Factory/.minio-client.new.2275/vendor.tar.gz differ: char 5, line 1