Skip to content

Commit

Permalink
feat: service update provides now per node status
Browse files Browse the repository at this point in the history
  • Loading branch information
harshavardhana committed Jan 26, 2024
1 parent c13b1c8 commit e11167d
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 77 deletions.
2 changes: 1 addition & 1 deletion cmd/admin-service-freeze.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func mainAdminServiceFreeze(ctx *cli.Context) error {
fatalIf(err, "Unable to initialize admin connection.")

// Freeze the specified MinIO server
fatalIf(probe.NewError(client.ServiceFreeze(globalContext)), "Unable to freeze the server.")
fatalIf(probe.NewError(client.ServiceFreezeV2(globalContext)), "Unable to freeze the server.")

// Success..
printMsg(serviceFreezeCommand{Status: "success", ServerURL: aliasedURL})
Expand Down
101 changes: 51 additions & 50 deletions cmd/admin-service-restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ var serviceRestartFlag = []cli.Flag{
Name: "dry-run",
Usage: "do not attempt a restart, however verify the peer status",
},
cli.BoolFlag{
Name: "force",
Usage: "force trigger a restart without any pre-checks",
Hidden: true,
},
}

var adminServiceRestartCmd = cli.Command{
Expand Down Expand Up @@ -76,28 +71,31 @@ type serviceRestartCommand struct {

// String colorized service restart command message.
func (s serviceRestartCommand) String() string {
var rows []table.Row
for _, peerRes := range s.Result.Results {
errStr := tickCell
if peerRes.Err != "" {
errStr = peerRes.Err
} else if len(peerRes.WaitingDrives) > 0 {
errStr = fmt.Sprintf("%d drives are waiting for I/O and are offline, manual restart of OS is recommended", len(peerRes.WaitingDrives))
}
rows = append(rows, table.Row{peerRes.Host, errStr})
}

t := table.NewWriter()
var s1 strings.Builder
s1.WriteString("Restart command successfully sent to `" + s.ServerURL + "`. Type Ctrl-C to quit or wait to follow the status of the restart process.\n")
s1.WriteString("Restart command successfully sent to `" + s.ServerURL + "`. Type Ctrl-C to quit or wait to follow the status of the restart process.")

if len(s.Result.Results) > 0 {
s1.WriteString("\n")
var rows []table.Row
for _, peerRes := range s.Result.Results {
errStr := tickCell
if peerRes.Err != "" {
errStr = peerRes.Err
} else if len(peerRes.WaitingDrives) > 0 {
errStr = fmt.Sprintf("%d drives are waiting for I/O and are offline, manual restart of OS is recommended", len(peerRes.WaitingDrives))
}
rows = append(rows, table.Row{peerRes.Host, errStr})
}

t.SetOutputMirror(&s1)
t.SetColumnConfigs([]table.ColumnConfig{{Align: text.AlignCenter}})
t := table.NewWriter()
t.SetOutputMirror(&s1)
t.SetColumnConfigs([]table.ColumnConfig{{Align: text.AlignCenter}})

t.AppendHeader(table.Row{"Host", "Status"})
t.AppendRows(rows)
t.SetStyle(table.StyleLight)
t.Render()
t.AppendHeader(table.Row{"Host", "Status"})
t.AppendRows(rows)
t.SetStyle(table.StyleLight)
t.Render()
}

return console.Colorize("ServiceRestart", s1.String())
}
Expand Down Expand Up @@ -165,8 +163,12 @@ func mainAdminServiceRestart(ctx *cli.Context) error {
result, e := client.ServiceAction(ctxt, madmin.ServiceActionOpts{
Action: madmin.ServiceActionRestart,
DryRun: ctx.Bool("dry-run"),
Force: ctx.Bool("force"),
})
if e != nil {
// Attempt an older API server might be old
//lint:ignore SA1019 Ignore the deprecation warnings
e = client.ServiceRestart(ctxt)
}
fatalIf(probe.NewError(e), "Unable to restart the server.")

// Success..
Expand All @@ -190,36 +192,35 @@ func mainAdminServiceRestart(ctx *cli.Context) error {
printProgress()
mark = "."

timer := time.NewTimer(time.Second)
defer timer.Stop()

t := time.Now()
for {
healthCtx, healthCancel := context.WithTimeout(ctxt, 2*time.Second)

// Fetch the health status of the specified MinIO server
healthResult, healthErr := anonClient.Healthy(healthCtx, madmin.HealthOpts{})
healthCancel()

switch {
case healthErr == nil && healthResult.Healthy:
printMsg(serviceRestartMessage{
Status: "success",
ServerURL: aliasedURL,
TimeTaken: time.Since(t),
})
return nil
case healthErr == nil && !healthResult.Healthy:
coloring = color.New(color.FgYellow)
mark = "!"
fallthrough
default:
printProgress()
}

select {
case <-ctxt.Done():
return ctxt.Err()
case <-timer.C:
healthCtx, healthCancel := context.WithTimeout(ctxt, 3*time.Second)
// Fetch the health status of the specified MinIO server
healthResult, healthErr := anonClient.Healthy(healthCtx, madmin.HealthOpts{})
healthCancel()
switch {
case healthErr == nil && healthResult.Healthy:
printMsg(serviceRestartMessage{
Status: "success",
ServerURL: aliasedURL,
TimeTaken: time.Since(t),
})
return nil
case healthErr == nil && !healthResult.Healthy:
coloring = color.New(color.FgYellow)
mark = "!"
fallthrough
default:
printProgress()
}

timer.Reset(time.Second)
default:
time.Sleep(500 * time.Millisecond)
}
}
}
2 changes: 1 addition & 1 deletion cmd/admin-service-stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func mainAdminServiceStop(ctx *cli.Context) error {
fatalIf(err, "Unable to initialize admin connection.")

// Stop the specified MinIO server
fatalIf(probe.NewError(client.ServiceStop(globalContext)), "Unable to stop the server.")
fatalIf(probe.NewError(client.ServiceStopV2(globalContext)), "Unable to stop the server.")

// Success..
printMsg(serviceStopMessage{Status: "success", ServerURL: aliasedURL})
Expand Down
1 change: 1 addition & 0 deletions cmd/admin-service-unfreeze.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func mainAdminServiceUnfreeze(ctx *cli.Context) error {
fatalIf(err, "Unable to initialize admin connection.")

// Unfreeze the specified MinIO server
//lint:ignore SA1019 Ignore the deprecation warnings
fatalIf(probe.NewError(client.ServiceUnfreeze(globalContext)), "Unable to unfreeze the server.")

// Success..
Expand Down
52 changes: 36 additions & 16 deletions cmd/admin-update.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ import (
"strings"

"github.com/fatih/color"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/minio/cli"
json "github.com/minio/colorjson"
"github.com/minio/madmin-go/v3"
"github.com/minio/mc/pkg/probe"
"github.com/minio/pkg/v2/console"
)
Expand Down Expand Up @@ -64,22 +67,37 @@ EXAMPLES:

// serverUpdateMessage is container for ServerUpdate success and failure messages.
type serverUpdateMessage struct {
Status string `json:"status"`
ServerURL string `json:"serverURL"`
CurrentVersion string `json:"currentVersion"`
UpdatedVersion string `json:"updatedVersion"`
Status string `json:"status"`
ServerURL string `json:"serverURL"`
ServerUpdateStatus madmin.ServerUpdateStatusV2 `json:"serverUpdateStatus"`
}

// String colorized serverUpdate message.
func (s serverUpdateMessage) String() string {
if s.CurrentVersion != s.UpdatedVersion {
return console.Colorize("ServerUpdate",
fmt.Sprintf("Server `%s` updated successfully from %s to %s",
s.ServerURL, s.CurrentVersion, s.UpdatedVersion))
var rows []table.Row
for _, peerRes := range s.ServerUpdateStatus.Results {
errStr := fmt.Sprintf("upgraded server from %s to %s: %s", peerRes.CurrentVersion, peerRes.UpdatedVersion, tickCell)
if peerRes.Err != "" {
errStr = peerRes.Err
} else if len(peerRes.WaitingDrives) > 0 {
errStr = fmt.Sprintf("%d drives are hung, process was upgraded. However OS reboot is recommended.", len(peerRes.WaitingDrives))
}
rows = append(rows, table.Row{peerRes.Host, errStr})
}
return console.Colorize("ServerUpdate",
fmt.Sprintf("Server `%s` already running the most recent version %s of MinIO",
s.ServerURL, s.CurrentVersion))

t := table.NewWriter()
var s1 strings.Builder
s1.WriteString("Server update request sent successfully `" + s.ServerURL + "`\n")

t.SetOutputMirror(&s1)
t.SetColumnConfigs([]table.ColumnConfig{{Align: text.AlignCenter}})

t.AppendHeader(table.Row{"Host", "Status"})
t.AppendRows(rows)
t.SetStyle(table.StyleLight)
t.Render()

return console.Colorize("ServiceRestart", s1.String())
}

// JSON jsonified server update message.
Expand Down Expand Up @@ -128,15 +146,17 @@ func mainAdminServerUpdate(ctx *cli.Context) error {

// Update the specified MinIO server, optionally also
// with the provided update URL.
us, e := client.ServerUpdate(globalContext, updateURL)
us, e := client.ServerUpdateV2(globalContext, madmin.ServerUpdateOpts{
DryRun: ctx.Bool("dry-run"),
UpdateURL: updateURL,
})
fatalIf(probe.NewError(e), "Unable to update the server.")

// Success..
printMsg(serverUpdateMessage{
Status: "success",
ServerURL: aliasedURL,
CurrentVersion: us.CurrentVersion,
UpdatedVersion: us.UpdatedVersion,
Status: "success",
ServerURL: aliasedURL,
ServerUpdateStatus: us,
})
return nil
}
19 changes: 15 additions & 4 deletions cmd/humanized-duration.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,19 @@ import (

// humanizedDuration container to capture humanized time.
type humanizedDuration struct {
Days int64 `json:"days,omitempty"`
Hours int64 `json:"hours,omitempty"`
Minutes int64 `json:"minutes,omitempty"`
Seconds int64 `json:"seconds,omitempty"`
Days int64 `json:"days,omitempty"`
Hours int64 `json:"hours,omitempty"`
Minutes int64 `json:"minutes,omitempty"`
Seconds int64 `json:"seconds,omitempty"`
MilliSeconds int64 `json:"milliSeconds,omitempty"`
}

// StringShort() humanizes humanizedDuration to human readable short format.
// This does not print at seconds.
func (r humanizedDuration) StringShort() string {
switch {
case r.Days == 0 && r.Hours == 0 && r.Minutes == 0 && r.Seconds == 0:
return fmt.Sprintf("%d milliseconds", r.MilliSeconds)
case r.Days == 0 && r.Hours == 0 && r.Minutes == 0:
return fmt.Sprintf("%d seconds", r.Seconds)
case r.Days == 0 && r.Hours == 0:
Expand All @@ -50,6 +53,10 @@ func (r humanizedDuration) StringShort() string {

// String() humanizes humanizedDuration to human readable,
func (r humanizedDuration) String() string {
if r.Days == 0 && r.Hours == 0 && r.Minutes == 0 && r.Seconds == 0 {
return fmt.Sprintf("%d milliseconds", r.MilliSeconds)
}

if r.Days == 0 && r.Hours == 0 && r.Minutes == 0 {
return fmt.Sprintf("%d seconds", r.Seconds)
}
Expand All @@ -65,6 +72,10 @@ func (r humanizedDuration) String() string {
// timeDurationToHumanizedDuration convert golang time.Duration to a custom more readable humanizedDuration.
func timeDurationToHumanizedDuration(duration time.Duration) humanizedDuration {
r := humanizedDuration{}
if duration.Milliseconds() < 1000 {
r.MilliSeconds = int64(duration.Milliseconds())
return r
}
if duration.Seconds() < 60.0 {
r.Seconds = int64(duration.Seconds())
return r
Expand Down
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ require (
github.com/gdamore/tcell/v2 v2.7.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.37
github.com/minio/madmin-go/v3 v3.0.41
github.com/minio/pkg/v2 v2.0.7
github.com/muesli/reflow v0.3.0
github.com/navidys/tvxwidgets v0.4.1
Expand Down Expand Up @@ -131,5 +131,3 @@ require (
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

replace github.com/minio/madmin-go/v3 => ../madmin-go
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ github.com/minio/colorjson v1.0.6 h1:m7TUvpvt0u7FBmVIEQNIa0T4NBQlxrcMBp4wJKsg2Ik
github.com/minio/colorjson v1.0.6/go.mod h1:LUXwS5ZGNb6Eh9f+t+3uJiowD3XsIWtsvTriUBeqgYs=
github.com/minio/filepath v1.0.0 h1:fvkJu1+6X+ECRA6G3+JJETj4QeAYO9sV43I79H8ubDY=
github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEXx9T/Bw=
github.com/minio/madmin-go/v3 v3.0.37 h1:u8gl6xg6Vt+LLwes/8rJhAq2wtpIRWRULptNVQtH9JE=
github.com/minio/madmin-go/v3 v3.0.37/go.mod h1:4QN2NftLSV7MdlT50dkrenOMmNVHluxTvlqJou3hte8=
github.com/minio/madmin-go/v3 v3.0.41 h1:9pU7xW51cn8Ixy8ftaRfp4SbHtnhEPlwU6mMA9KwwB8=
github.com/minio/madmin-go/v3 v3.0.41/go.mod h1:4QN2NftLSV7MdlT50dkrenOMmNVHluxTvlqJou3hte8=
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/v7 v7.0.66 h1:bnTOXOHjOqv/gcMuiVbN9o2ngRItvqE774dG9nq0Dzw=
Expand Down

0 comments on commit e11167d

Please sign in to comment.