Skip to content

Commit

Permalink
keep pool display order and also pretty it
Browse files Browse the repository at this point in the history
```
mc admin info play/
●  play.min.io
   Uptime: 4 minutes
   Version: 2024-05-10T08:24:14Z
   Network: 1/1 OK
   Drives: 4/4 OK
   Pool: 1

┌──────┬───────────────────────┬─────────────────────┬──────────────┐
│ Pool │ Raw Usage             │ Erasure stripe size │ Erasure sets │
│ 1st  │ 8.5% (total: 120 GiB) │ 4                   │ 1            │
└──────┴───────────────────────┴─────────────────────┴──────────────┘

8.4 GiB Used, 479 Buckets, 3,585 Objects, 210 Versions, 27 Delete Markers
4 drives online, 0 drives offline, EC:1
```
  • Loading branch information
harshavardhana committed May 10, 2024
1 parent fdb36ac commit 51ff182
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 94 deletions.
7 changes: 1 addition & 6 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ linters:
- typecheck
- goimports
- misspell
- staticcheck
- govet
- revive
- ineffassign
Expand All @@ -19,9 +20,6 @@ linters-settings:
misspell:
locale: US

gofumpt:
lang-version: "1.17"

# Choose whether or not to use the extra rules that are disabled
# by default
extra-rules: false
Expand All @@ -32,6 +30,3 @@ issues:
- instead of using struct literal
- should have a package comment
- error strings should not be capitalized or end with punctuation or a newline

service:
golangci-lint-version: 1.43.0 # use the fixed version to not introduce new linters unexpectedly
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ getdeps:
@mkdir -p ${GOPATH}/bin
@echo "Installing golangci-lint" && curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin
@echo "Installing stringer" && go install -v golang.org/x/tools/cmd/stringer@latest
@echo "Installing staticheck" && go install honnef.co/go/tools/cmd/staticcheck@latest

crosscompile:
@(env bash $(PWD)/buildscripts/cross-compile.sh)
Expand All @@ -35,7 +34,6 @@ vet:
lint: getdeps
@echo "Running $@ check"
@GO111MODULE=on ${GOPATH}/bin/golangci-lint run --timeout=5m --config ./.golangci.yml
@GO111MODULE=on ${GOPATH}/bin/staticcheck -tests=false -checks="all,-ST1000,-ST1003,-ST1016,-ST1020,-ST1021,-ST1022,-ST1023,-ST1005" ./...

# Builds mc, runs the verifiers then runs the tests.
check: test
Expand Down
2 changes: 1 addition & 1 deletion cmd/admin-decom-status.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func mainAdminDecommissionStatus(ctx *cli.Context) error {
cellText[0] = []string{
"ID",
"Pools",
"Raw Drives Usage",
"Drives Usage",
"Status",
}
for idx, pool := range poolStatuses {
Expand Down
122 changes: 81 additions & 41 deletions cmd/admin-info.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2015-2023 MinIO, Inc.
// Copyright (c) 2015-2024 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
Expand Down Expand Up @@ -59,11 +59,13 @@ EXAMPLES:
}

type poolSummary struct {
index int
setsCount int
drivesPerSet int
driveTolerance int
endpoints set.StringSet
index int
setsCount int
drivesPerSet int
driveTolerance int
drivesTotalFreeSpace uint64
drivesTotalUsableSpace uint64
endpoints set.StringSet
}

type clusterInfo map[int]*poolSummary
Expand All @@ -73,6 +75,10 @@ func clusterSummaryInfo(info madmin.InfoMessage) clusterInfo {

for _, srv := range info.Servers {
for _, disk := range srv.Disks {
if disk.PoolIndex < 0 {
continue
}

pool := summary[disk.PoolIndex]
if pool == nil {
pool = &poolSummary{
Expand All @@ -81,25 +87,28 @@ func clusterSummaryInfo(info madmin.InfoMessage) clusterInfo {
driveTolerance: info.StandardParity(),
}
}
// Deprecated calculation based on disk location
if disk.SetIndex+1 > pool.setsCount {
pool.setsCount = disk.SetIndex + 1
}
// Deprecated calculation based on disk location
if disk.DiskIndex+1 > pool.drivesPerSet {
pool.drivesPerSet = disk.DiskIndex + 1

if disk.DiskIndex < (info.Backend.DrivesPerSet[disk.PoolIndex] - info.Backend.StandardSCParity) {
pool.drivesTotalFreeSpace += disk.AvailableSpace
pool.drivesTotalUsableSpace += disk.TotalSpace
}

pool.endpoints.Add(srv.Endpoint)
summary[disk.PoolIndex] = pool
}
}

if len(info.Backend.TotalSets) > 0 { // Check if this is a recent enough MinIO version
for _, pool := range summary {
pool.setsCount = info.Backend.TotalSets[pool.index]
pool.drivesPerSet = info.Backend.DrivesPerSet[pool.index]
// This was already added in 2022 enough time has passed to remove
// any other deprecated calculations
for idx := range info.Backend.TotalSets {
pool := summary[idx]
if pool != nil {
pool.setsCount = info.Backend.TotalSets[idx]
pool.drivesPerSet = info.Backend.DrivesPerSet[idx]
summary[idx] = pool
}
}

return summary
}

Expand All @@ -120,30 +129,21 @@ type clusterStruct struct {
Info madmin.InfoMessage `json:"info,omitempty"`
}

// String provides colorized info messages depending on the type of a server
//
// FS server non-FS server
//
// ============================== ===================================
// ● <ip>:<port> ● <ip>:<port>
//
// Uptime: xxx Uptime: xxx
// Version: xxx Version: xxx
// Network: X/Y OK Network: X/Y OK
//
// U Used, B Buckets, O Objects Drives: N/N OK
//
// U Used, B Buckets, O Objects
// N drives online, K drives offline
// String provides colorized info messages
func (u clusterStruct) String() (msg string) {
// Check cluster level "Status" field for error
if u.Status == "error" {
fatal(probe.NewError(errors.New(u.Error)), "Unable to get service status")
fatal(probe.NewError(errors.New(u.Error)), "Unable to get service info")
}

// If nothing has been collected, error out
if u.Info.Servers == nil {
fatal(probe.NewError(errors.New("Unable to get service status")), "")
fatal(probe.NewError(errors.New("Unable to get service info")), "")
}

// Validate such that we expect the server to be atleast from 2022
if len(u.Info.Backend.TotalSets) == 0 || len(u.Info.Backend.DrivesPerSet) == 0 {
fatal(probe.NewError(errors.New("Unable to display service info, server is too old")), "")
}

// Initialization
Expand Down Expand Up @@ -211,7 +211,7 @@ func (u clusterStruct) String() (msg string) {

// Version
version := srv.Version
if srv.Version == "DEVELOPMENT.GOGET" {
if strings.Contains(srv.Version, "DEVELOPMENT") {
version = "<development>"
}
msg += fmt.Sprintf(" Version: %s\n", version)
Expand Down Expand Up @@ -266,14 +266,54 @@ func (u clusterStruct) String() (msg string) {
}

if backendType == madmin.Erasure {
msg += "Pools:\n"
for pool, summary := range clusterSummary {
msg += fmt.Sprintf(" %s, Erasure sets: %d, Drives per erasure set: %d\n",
console.Colorize("Info", humanize.Ordinal(pool+1)), summary.setsCount, summary.drivesPerSet)
dspOrder := []col{colGreen} // Header
for i := 0; i < len(clusterSummary); i++ {
dspOrder = append(dspOrder, colGrey)
}
var printColors []*color.Color
for _, c := range dspOrder {
printColors = append(printColors, getPrintCol(c))
}
}

msg += "\n"
tbl := console.NewTable(printColors, []bool{false, false, false, false}, 0)

var builder strings.Builder
cellText := make([][]string, 0, len(clusterSummary)+1)
cellText = append(cellText, []string{
"Pool",
"Drives Usage",
"Erasure stripe size",
"Erasure sets",
})

// Keep the pool order while printing the output
for poolIdx := 0; poolIdx < len(clusterSummary); poolIdx++ {
summary := clusterSummary[poolIdx]
if summary == nil {
break
}
totalSize := summary.drivesTotalUsableSpace
usedCurrent := summary.drivesTotalUsableSpace - summary.drivesTotalFreeSpace
var capacity string
if totalSize == 0 {
capacity = "0% (total: 0B)"
} else {
capacity = fmt.Sprintf("%.1f%% (total: %s)", 100*float64(usedCurrent)/float64(totalSize), humanize.IBytes(totalSize))
}

cellText = append(cellText, []string{
humanize.Ordinal(poolIdx + 1),
capacity,
strconv.Itoa(summary.drivesPerSet),
strconv.Itoa(summary.setsCount),
})
}

e := tbl.PopulateTable(&builder, cellText)
fatalIf(probe.NewError(e), "unable to populate the table")

msg += builder.String() + "\n"
}

// Summary on used space, total no of buckets and
// total no of objects at the Cluster level
Expand Down
1 change: 1 addition & 0 deletions cmd/admin-policy-info.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func getPolicyInfo(client *madmin.AdminClient, policyName string) (*madmin.Polic

if pinfo.PolicyName == "" {
// Likely server only supports the older version.
// nolint:staticcheck
pinfo.Policy, e = client.InfoCannedPolicy(globalContext, policyName)
if e != nil {
return nil, e
Expand Down
2 changes: 1 addition & 1 deletion cmd/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2455,7 +2455,7 @@ func validateObjectMetaData(t *testing.T, file *testFile) {
found := false

for ii, vv := range file.MinioStat.Metadata {
if metaPrefix+strings.Title(i) == ii {
if metaPrefix+http.CanonicalHeaderKey(i) == ii {
found = true
if v != vv {
fmt.Println("------------------------")
Expand Down
30 changes: 15 additions & 15 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ require (
github.com/prometheus/prom2json v1.3.3 // indirect
github.com/rjeczalik/notify v0.9.3
github.com/rs/xid v1.5.0
github.com/shirou/gopsutil/v3 v3.24.3
github.com/shirou/gopsutil/v3 v3.24.4
github.com/tidwall/gjson v1.17.1
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/net v0.24.0
golang.org/x/text v0.14.0
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0
golang.org/x/text v0.15.0
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
gopkg.in/yaml.v2 v2.4.0
)
Expand All @@ -41,13 +41,13 @@ require (
github.com/charmbracelet/lipgloss v0.10.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/juju/ratelimit v1.0.2
github.com/minio/madmin-go/v3 v3.0.50
github.com/minio/pkg/v2 v2.0.17
github.com/minio/madmin-go/v3 v3.0.51
github.com/minio/pkg/v2 v2.0.19
github.com/minio/selfupdate v0.6.0
github.com/muesli/reflow v0.3.0
github.com/olekukonko/tablewriter v0.0.5
github.com/vbauerster/mpb/v8 v8.7.3
golang.org/x/term v0.19.0
golang.org/x/term v0.20.0
)

require (
Expand All @@ -62,8 +62,8 @@ require (
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/safchain/ethtool v0.3.0 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240509183442-62759503f434 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 // indirect
)

require (
Expand Down Expand Up @@ -98,24 +98,24 @@ require (
github.com/philhofer/fwd v1.1.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/prometheus/common v0.52.3 // indirect
github.com/prometheus/procfs v0.13.0
github.com/prometheus/common v0.53.0 // indirect
github.com/prometheus/procfs v0.14.0
github.com/rivo/uniseg v0.4.7 // indirect
github.com/secure-io/sio-go v0.3.1 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tinylib/msgp v1.1.9 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/etcd/api/v3 v3.5.13 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
go.etcd.io/etcd/client/v3 v3.5.13 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.19.0
golang.org/x/sys v0.20.0
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.33.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
Loading

0 comments on commit 51ff182

Please sign in to comment.