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-06-28 15:21:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/minio-client (Old) and /work/SRC/openSUSE:Factory/.minio-client.new.1548 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "minio-client" Tue Jun 28 15:21:46 2022 rev:9 rq:985331 version:20220626T185148Z Changes: -------- --- /work/SRC/openSUSE:Factory/minio-client/minio-client.changes 2022-06-23 10:25:07.983796233 +0200 +++ /work/SRC/openSUSE:Factory/.minio-client.new.1548/minio-client.changes 2022-06-28 15:21:58.065906156 +0200 @@ -1,0 +2,10 @@ +Mon Jun 27 13:22:50 UTC 2022 - ka...@b1-systems.de + +- Update to version 20220626T185148Z: + * change admin console to support logs show (#4132) + * admin: add admin cluster iam import/export cmd (#4102) + * Save license at the time of registration (#4123) + * add further license banners in default 'help' output (#4129) + * Switch to last commit time based release (#4128) + +------------------------------------------------------------------- Old: ---- mc-20220617T025250Z.tar.gz New: ---- mc-20220626T185148Z.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ minio-client.spec ++++++ --- /var/tmp/diff_new_pack.7ZZsjN/_old 2022-06-28 15:21:58.789907237 +0200 +++ /var/tmp/diff_new_pack.7ZZsjN/_new 2022-06-28 15:21:58.797907249 +0200 @@ -22,7 +22,7 @@ %define binary_name minio-client Name: minio-client -Version: 20220617T025250Z +Version: 20220626T185148Z Release: 0 Summary: Client for MinIO License: AGPL-3.0-only ++++++ _service ++++++ --- /var/tmp/diff_new_pack.7ZZsjN/_old 2022-06-28 15:21:58.825907290 +0200 +++ /var/tmp/diff_new_pack.7ZZsjN/_new 2022-06-28 15:21:58.829907297 +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-06-17T02-52-50Z</param> + <param name="revision">RELEASE.2022-06-26T18-51-48Z</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-20220617T025250Z.tar.gz</param> + <param name="archive">mc-20220626T185148Z.tar.gz</param> </service> </services> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.7ZZsjN/_old 2022-06-28 15:21:58.849907326 +0200 +++ /var/tmp/diff_new_pack.7ZZsjN/_new 2022-06-28 15:21:58.853907333 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/minio/mc</param> - <param name="changesrevision">0e44ad30db7ee58386117f9bed143418c79d2980</param></service></servicedata> + <param name="changesrevision">40ee1a4ed60f3b2f618c4eef282ff8b29ace7045</param></service></servicedata> (No newline at EOF) ++++++ mc-20220617T025250Z.tar.gz -> mc-20220626T185148Z.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/buildscripts/gen-ldflags.go new/mc-20220626T185148Z/buildscripts/gen-ldflags.go --- old/mc-20220617T025250Z/buildscripts/gen-ldflags.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/buildscripts/gen-ldflags.go 2022-06-26 20:51:48.000000000 +0200 @@ -28,10 +28,9 @@ "time" ) -func genLDFlags(now time.Time) string { - version := now.Format(time.RFC3339) - releaseTag := releaseTag(version) - copyrightYear := fmt.Sprintf("%d", now.Year()) +func genLDFlags(version string) string { + releaseTag, date := releaseTag(version) + copyrightYear := fmt.Sprintf("%d", date.Year()) var ldflagsStr string ldflagsStr = "-s -w -X github.com/minio/mc/cmd.Version=" + version + " " @@ -42,8 +41,8 @@ return ldflagsStr } -// genReleaseTag prints release tag to the console for easy git tagging. -func releaseTag(version string) string { +// releaseTag prints release tag to the console for easy git tagging. +func releaseTag(version string) (string, time.Time) { relPrefix := "DEVELOPMENT" if prefix := os.Getenv("MC_RELEASE"); prefix != "" { relPrefix = prefix @@ -52,7 +51,12 @@ relTag := strings.Replace(version, " ", "-", -1) relTag = strings.Replace(relTag, ":", "-", -1) relTag = strings.Replace(relTag, ",", "", -1) - return relPrefix + "." + relTag + t, err := time.Parse("2006-01-02T15-04-05Z", relTag) + if err != nil { + panic(err) + } + + return relPrefix + "." + relTag, t } // commitID returns the abbreviated commit-id hash of the last commit. @@ -72,6 +76,35 @@ return strings.TrimSpace(string(commit)) } +func commitTime() time.Time { + // git log --format=%cD -n1 + var ( + commitUnix []byte + err error + ) + cmdName := "git" + cmdArgs := []string{"log", "--format=%cI", "-n1"} + if commitUnix, err = exec.Command(cmdName, cmdArgs...).Output(); err != nil { + fmt.Fprintln(os.Stderr, "Error generating git commit-time: ", err) + os.Exit(1) + } + + t, err := time.Parse(time.RFC3339, strings.TrimSpace(string(commitUnix))) + if err != nil { + fmt.Fprintln(os.Stderr, "Error generating git commit-time: ", err) + os.Exit(1) + } + + return t.UTC() +} + func main() { - fmt.Println(genLDFlags(time.Now().UTC())) + var version string + if len(os.Args) > 1 { + version = os.Args[1] + } else { + version = commitTime().Format(time.RFC3339) + } + + fmt.Println(genLDFlags(version)) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/admin-cluster-iam-export.go new/mc-20220626T185148Z/cmd/admin-cluster-iam-export.go --- old/mc-20220617T025250Z/cmd/admin-cluster-iam-export.go 1970-01-01 01:00:00.000000000 +0100 +++ new/mc-20220626T185148Z/cmd/admin-cluster-iam-export.go 2022-06-26 20:51:48.000000000 +0200 @@ -0,0 +1,125 @@ +// Copyright (c) 2022 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 ( + "context" + "fmt" + "io" + "io/ioutil" + "os" + "time" + + "github.com/fatih/color" + "github.com/minio/cli" + json "github.com/minio/colorjson" + "github.com/minio/mc/pkg/probe" + "github.com/minio/pkg/console" +) + +var adminClusterIAMExportCmd = cli.Command{ + Name: "export", + Usage: "exports IAM info to zipped file", + Action: mainClusterIAMExport, + OnUsageError: onUsageError, + Before: setGlobalsFromContext, + Flags: globalFlags, + HideHelpCommand: true, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] TARGET + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Download all IAM metadata for cluster into zip file. + {{.Prompt}} {{.HelpName}} myminio +`, +} + +func checkIAMExportSyntax(ctx *cli.Context) { + if len(ctx.Args()) != 1 { + cli.ShowCommandHelpAndExit(ctx, "export", 1) // last argument is exit code + } +} + +// mainClusterIAMExport - metadata export command +func mainClusterIAMExport(ctx *cli.Context) error { + // Check for command syntax + checkIAMExportSyntax(ctx) + + // Get the alias parameter from cli + args := ctx.Args() + aliasedURL := args.Get(0) + console.SetColor("File", color.New(color.FgWhite, color.Bold)) + + // Create a new MinIO Admin Client + client, err := newAdminClient(aliasedURL) + if err != nil { + fatalIf(err.Trace(aliasedURL), "Unable to initialize admin client.") + return nil + } + + r, ierr := client.ExportIAM(context.Background()) + fatalIf(probe.NewError(ierr).Trace(aliasedURL), "Unable to export IAM info.") + + // Create iam info zip file + tmpFile, e := ioutil.TempFile("", fmt.Sprintf("%s-iam-info", aliasedURL)) + fatalIf(probe.NewError(e), "Unable to download file data.") + + ext := "zip" + // Copy zip content to target download file + _, e = io.Copy(tmpFile, r) + fatalIf(probe.NewError(e), "Unable to download IAM info.") + + // Close everything + r.Close() + tmpFile.Close() + + downloadPath := fmt.Sprintf("%s-iam-info.%s", aliasedURL, ext) + fi, e := os.Stat(downloadPath) + if e == nil && !fi.IsDir() { + e = moveFile(downloadPath, downloadPath+"."+time.Now().Format(dateTimeFormatFilename)) + fatalIf(probe.NewError(e), "Unable to create a backup of "+downloadPath) + } else { + if !os.IsNotExist(e) { + fatal(probe.NewError(e), "Unable to download file data") + } + } + + fatalIf(probe.NewError(moveFile(tmpFile.Name(), downloadPath)), "Unable to rename downloaded data, file exists at %s", tmpFile.Name()) + + if !globalJSON { + console.Infof("IAM info successfully downloaded as %s\n", downloadPath) + return nil + } + + v := struct { + File string `json:"file"` + Key string `json:"key,omitempty"` + }{ + File: downloadPath, + } + b, e := json.Marshal(v) + fatalIf(probe.NewError(e), "Unable to serialize data") + console.Println(string(b)) + return nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/admin-cluster-iam-import.go new/mc-20220626T185148Z/cmd/admin-cluster-iam-import.go --- old/mc-20220617T025250Z/cmd/admin-cluster-iam-import.go 1970-01-01 01:00:00.000000000 +0100 +++ new/mc-20220626T185148Z/cmd/admin-cluster-iam-import.go 2022-06-26 20:51:48.000000000 +0200 @@ -0,0 +1,101 @@ +// Copyright (c) 2022 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 ( + "context" + "fmt" + "io" + "os" + + "github.com/klauspost/compress/zip" + "github.com/minio/cli" + "github.com/minio/mc/pkg/probe" + "github.com/minio/pkg/console" +) + +var adminClusterIAMImportCmd = cli.Command{ + Name: "import", + Usage: "imports IAM info from zipped file", + Action: mainClusterIAMImport, + OnUsageError: onUsageError, + Before: setGlobalsFromContext, + Flags: globalFlags, + HideHelpCommand: true, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] TARGET/BUCKET /path/to/myminio-iam-info.zip + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Set IAM info from previously exported metadata zip file. + {{.Prompt}} {{.HelpName}} myminio /tmp/myminio-iam-info.zip + +`, +} + +func checkIAMImportSyntax(ctx *cli.Context) { + if len(ctx.Args()) != 2 { + cli.ShowCommandHelpAndExit(ctx, "import", 1) // last argument is exit code + } +} + +// mainClusterIAMImport - iam info import command +func mainClusterIAMImport(ctx *cli.Context) error { + // Check for command syntax + checkIAMImportSyntax(ctx) + + // Get the alias parameter from cli + args := ctx.Args() + aliasedURL := args.Get(0) + var r io.Reader + var sz int64 + f, e := os.Open(args.Get(1)) + if e != nil { + fatalIf(probe.NewError(e).Trace(args...), "Unable to get IAM info") + } + if st, e := f.Stat(); e == nil { + sz = st.Size() + } + defer f.Close() + r = f + + _, e = zip.NewReader(r.(io.ReaderAt), sz) + fatalIf(probe.NewError(e).Trace(args...), fmt.Sprintf("Unable to read zip file %s", args.Get(1))) + + f, e = os.Open(args.Get(1)) + fatalIf(probe.NewError(e).Trace(args...), "Unable to get IAM info") + + // Create a new MinIO Admin Client + client, err := newAdminClient(aliasedURL) + if err != nil { + fatalIf(err.Trace(aliasedURL), "Unable to initialize admin client.") + return nil + } + + ierr := client.ImportIAM(context.Background(), f) + fatalIf(probe.NewError(ierr).Trace(aliasedURL), "Unable to import IAM info.") + if !globalJSON { + console.Infof("IAM info imported to %s from %s\n", aliasedURL, args.Get(1)) + } + return nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/admin-cluster-iam.go new/mc-20220626T185148Z/cmd/admin-cluster-iam.go --- old/mc-20220617T025250Z/cmd/admin-cluster-iam.go 1970-01-01 01:00:00.000000000 +0100 +++ new/mc-20220626T185148Z/cmd/admin-cluster-iam.go 2022-06-26 20:51:48.000000000 +0200 @@ -0,0 +1,42 @@ +// Copyright (c) 2022 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 "github.com/minio/cli" + +var adminClusterIAMSubcommands = []cli.Command{ + adminClusterIAMImportCmd, + adminClusterIAMExportCmd, +} + +var adminClusterIAMCmd = cli.Command{ + Name: "iam", + Usage: "manage IAM info on MinIO cluster", + Action: mainadminClusterIAM, + Before: setGlobalsFromContext, + Flags: globalFlags, + Subcommands: adminClusterIAMSubcommands, + HideHelpCommand: true, +} + +// mainadminClusterIAM is the handle for "mc admin cluster bucket" command. +func mainadminClusterIAM(ctx *cli.Context) error { + commandNotFound(ctx, adminClusterIAMSubcommands) + return nil + // Sub-commands like "export", "import" have their own main. +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/admin-cluster.go new/mc-20220626T185148Z/cmd/admin-cluster.go --- old/mc-20220617T025250Z/cmd/admin-cluster.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/cmd/admin-cluster.go 2022-06-26 20:51:48.000000000 +0200 @@ -21,6 +21,7 @@ var adminClusterSubcommands = []cli.Command{ adminClusterBucketCmd, + adminClusterIAMCmd, } var adminClusterCmd = cli.Command{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/admin-console.go new/mc-20220626T185148Z/cmd/admin-console.go --- old/mc-20220617T025250Z/cmd/admin-console.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/cmd/admin-console.go 2022-06-26 20:51:48.000000000 +0200 @@ -18,21 +18,13 @@ package cmd import ( - "context" "fmt" "strings" - "time" - "github.com/fatih/color" "github.com/minio/cli" - json "github.com/minio/colorjson" - "github.com/minio/madmin-go" - "github.com/minio/mc/pkg/probe" "github.com/minio/pkg/console" ) -const logTimeFormat string = "15:04:05 MST 01/02/2006" - var adminConsoleFlags = []cli.Flag{ cli.IntFlag{ Name: "limit, l", @@ -47,173 +39,35 @@ } var adminConsoleCmd = cli.Command{ - Name: "console", - Usage: "show console logs for MinIO server", - Action: mainAdminConsole, - OnUsageError: onUsageError, - Before: setGlobalsFromContext, - Flags: append(adminConsoleFlags, globalFlags...), - HideHelpCommand: true, - CustomHelpTemplate: `NAME: - {{.HelpName}} - {{.Usage}} - -USAGE: - {{.HelpName}} [FLAGS] TARGET [NODENAME] - -FLAGS: - {{range .VisibleFlags}}{{.}} - {{end}} -EXAMPLES: - 1. Show console logs for a MinIO server with alias 'play' - {{.Prompt}} {{.HelpName}} play - - 2. Show last 5 log entries for node 'node1' on MinIO server with alias 'myminio' - {{.Prompt}} {{.HelpName}} --limit 5 myminio node1 - - 3. Show application error logs on MinIO server with alias 'play' - {{.Prompt}} {{.HelpName}} --type application play -`, -} - -func checkAdminLogSyntax(ctx *cli.Context) { - if len(ctx.Args()) == 0 || len(ctx.Args()) > 3 { - cli.ShowCommandHelpAndExit(ctx, "console", 1) // last argument is exit code - } -} - -// Extend madmin.LogInfo to add String() and JSON() methods -type logMessage struct { - Status string `json:"status"` - madmin.LogInfo -} - -// JSON - jsonify loginfo -func (l logMessage) JSON() string { - l.Status = "success" - logJSON, err := json.MarshalIndent(&l, "", " ") - fatalIf(probe.NewError(err), "Unable to marshal into JSON.") - - return string(logJSON) -} - -func getLogTime(lt string) string { - tm, err := time.Parse(time.RFC3339Nano, lt) - if err != nil { - return lt - } - return tm.Format(logTimeFormat) -} - -// String - return colorized loginfo as string. -func (l logMessage) String() string { - var hostStr string - b := &strings.Builder{} - if l.NodeName != "" { - hostStr = fmt.Sprintf("%s ", colorizedNodeName(l.NodeName)) - } - log := l.LogInfo - if log.ConsoleMsg != "" { - if strings.HasPrefix(log.ConsoleMsg, "\n") { - fmt.Fprintf(b, "%s\n", hostStr) - log.ConsoleMsg = strings.TrimPrefix(log.ConsoleMsg, "\n") - } - fmt.Fprintf(b, "%s %s", hostStr, log.ConsoleMsg) - return b.String() - } - if l.API != nil { - apiString := "API: " + l.API.Name + "(" - if l.API.Args != nil && l.API.Args.Bucket != "" { - apiString = apiString + "bucket=" + l.API.Args.Bucket - } - if l.API.Args != nil && l.API.Args.Object != "" { - apiString = apiString + ", object=" + l.API.Args.Object - } - apiString += ")" - fmt.Fprintf(b, "\n%s %s", hostStr, console.Colorize("API", apiString)) - } - if l.Time != "" { - fmt.Fprintf(b, "\n%s Time: %s", hostStr, getLogTime(l.Time)) - } - if l.DeploymentID != "" { - fmt.Fprintf(b, "\n%s DeploymentID: %s", hostStr, l.DeploymentID) - } - if l.RequestID != "" { - fmt.Fprintf(b, "\n%s RequestID: %s", hostStr, l.RequestID) - } - if l.RemoteHost != "" { - fmt.Fprintf(b, "\n%s RemoteHost: %s", hostStr, l.RemoteHost) - } - if l.UserAgent != "" { - fmt.Fprintf(b, "\n%s UserAgent: %s", hostStr, l.UserAgent) - } - if l.Trace != nil { - if l.Trace.Message != "" { - fmt.Fprintf(b, "\n%s Error: %s", hostStr, console.Colorize("LogMessage", l.Trace.Message)) - } - if l.Trace.Variables != nil { - for key, value := range l.Trace.Variables { - if value != "" { - fmt.Fprintf(b, "\n%s %s=%s", hostStr, key, value) - } - } - } - if l.Trace.Source != nil { - traceLength := len(l.Trace.Source) - for i, element := range l.Trace.Source { - fmt.Fprintf(b, "\n%s %8v: %s", hostStr, traceLength-i, element) - } - } - } - logMsg := strings.TrimPrefix(b.String(), "\n") - return fmt.Sprintf("%s\n", logMsg) + Name: "console", + Usage: "show MinIO logs", + Action: mainAdminConsole, + OnUsageError: onUsageError, + Before: setGlobalsFromContext, + Flags: append(adminConsoleFlags, globalFlags...), + Hidden: true, + HideHelpCommand: true, + CustomHelpTemplate: "This command is not supported now and replaced by 'support logs show' command. Please use 'mc support logs show'.\n", } // mainAdminConsole - the entry function of console command func mainAdminConsole(ctx *cli.Context) error { - // Check for command syntax - checkAdminLogSyntax(ctx) - console.SetColor("LogMessage", color.New(color.Bold, color.FgRed)) - console.SetColor("Api", color.New(color.Bold, color.FgWhite)) - for _, c := range colors { - console.SetColor(fmt.Sprintf("Node%d", c), color.New(c)) - } - aliasedURL := ctx.Args().Get(0) - var node string - if len(ctx.Args()) > 1 { - node = ctx.Args().Get(1) - } - var limit int + newCmd := []string{"mc support logs show"} + + var flgStr string + if ctx.IsSet("limit") { - limit = ctx.Int("limit") - if limit <= 0 { - fatalIf(errInvalidArgument().Trace(ctx.Args()...), "please set a proper limit, for example: '--limit 5' to display last 5 logs, omit this flag to display all available logs") - } - } - logType := strings.ToLower(ctx.String("type")) - if logType != "minio" && logType != "application" && logType != "all" { - fatalIf(errInvalidArgument().Trace(ctx.Args()...), "Invalid value for --type flag. Valid options are [minio, application, all]") + flgStr = fmt.Sprintf("%s %d", "--last", ctx.Int("limit")) + newCmd = append(newCmd, flgStr) } - // Create a new MinIO Admin Client - client, err := newAdminClient(aliasedURL) - if err != nil { - fatalIf(err.Trace(aliasedURL), "Unable to initialize admin client.") - return nil - } - - ctxt, cancel := context.WithCancel(globalContext) - defer cancel() - // Start listening on all console log activity. - logCh := client.GetLogs(ctxt, node, limit, logType) - for logInfo := range logCh { - if logInfo.Err != nil { - fatalIf(probe.NewError(logInfo.Err), "Unable to listen to console logs") - } - // drop nodeName from output if specified as cli arg - if node != "" { - logInfo.NodeName = "" - } - printMsg(logMessage{LogInfo: logInfo}) + if ctx.IsSet("type") { + flgStr = fmt.Sprintf("%s %s", "--type", strings.ToLower(ctx.String("type"))) + newCmd = append(newCmd, flgStr) } + newCmd = append(newCmd, ctx.Args()...) + + msg := fmt.Sprintf("Please use '%s'", strings.Join(newCmd, " ")) + console.Infoln(msg) return nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/auto-complete.go new/mc-20220626T185148Z/cmd/auto-complete.go --- old/mc-20220617T025250Z/cmd/auto-complete.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/cmd/auto-complete.go 2022-06-26 20:51:48.000000000 +0200 @@ -403,20 +403,25 @@ "/admin/cluster/bucket/export": aliasCompleter, "/admin/cluster/bucket/import": aliasCompleter, + "/admin/cluster/iam/export": aliasCompleter, + "/admin/cluster/iam/import": aliasCompleter, "/alias/set": nil, "/alias/list": aliasCompleter, "/alias/remove": aliasCompleter, "/alias/import": nil, - "/support/callhome": aliasCompleter, - "/support/logs": aliasCompleter, - "/support/register": aliasCompleter, - "/support/diag": aliasCompleter, - "/support/profile": aliasCompleter, - "/support/inspect": aliasCompleter, - "/support/perf": aliasCompleter, - "/support/metrics": aliasCompleter, + "/support/callhome": aliasCompleter, + "/support/logs/enable": aliasCompleter, + "/support/logs/disable": aliasCompleter, + "/support/logs/status": aliasCompleter, + "/support/logs/show": aliasCompleter, + "/support/register": aliasCompleter, + "/support/diag": aliasCompleter, + "/support/profile": aliasCompleter, + "/support/inspect": aliasCompleter, + "/support/perf": aliasCompleter, + "/support/metrics": aliasCompleter, "/update": nil, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/main.go new/mc-20220626T185148Z/cmd/main.go --- old/mc-20220617T025250Z/cmd/main.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/cmd/main.go 2022-06-26 20:51:48.000000000 +0200 @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2021 MinIO, Inc. +// Copyright (c) 2015-2022 MinIO, Inc. // // This file is part of MinIO Object Storage stack // @@ -70,12 +70,12 @@ TIP: Use '{{.Name}} --autocompletion' to enable shell autocompletion -VERSION: - ` + ReleaseTag + - `{{ "\n"}}{{range $key, $value := ExtraInfo}} -{{$key}}: - {{$value}} -{{end}}` +COPYRIGHT: + Copyright (c) 2015-` + CopyrightYear + ` MinIO, Inc. + +LICENSE: + GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html> +` func init() { if env.IsSet(mcEnvConfigFile) { @@ -259,28 +259,6 @@ migrateShare() } -// Get os/arch/platform specific information. -// Returns a map of current os/arch/platform/memstats. -func getSystemData() map[string]string { - host, e := os.Hostname() - fatalIf(probe.NewError(e), "Unable to determine the hostname.") - - memstats := &runtime.MemStats{} - runtime.ReadMemStats(memstats) - mem := fmt.Sprintf("Used: %s | Allocated: %s | UsedHeap: %s | AllocatedHeap: %s", - pb.Format(int64(memstats.Alloc)).To(pb.U_BYTES), - pb.Format(int64(memstats.TotalAlloc)).To(pb.U_BYTES), - pb.Format(int64(memstats.HeapAlloc)).To(pb.U_BYTES), - pb.Format(int64(memstats.HeapSys)).To(pb.U_BYTES)) - platform := fmt.Sprintf("Host: %s | OS: %s | Arch: %s", host, runtime.GOOS, runtime.GOARCH) - goruntime := fmt.Sprintf("Version: %s | CPUs: %s", runtime.Version(), strconv.Itoa(runtime.NumCPU())) - return map[string]string{ - "PLATFORM": platform, - "RUNTIME": goruntime, - "MEM": mem, - } -} - // initMC - initialize 'mc'. func initMC() { // Check if mc config exists. @@ -478,7 +456,7 @@ fmt.Fprintf(c.App.Writer, "%s version %s (commit-id=%s)\n", c.App.Name, c.App.Version, CommitID) fmt.Fprintf(c.App.Writer, "Runtime: %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH) fmt.Fprintf(c.App.Writer, "Copyright (c) 2015-%s MinIO, Inc.\n", CopyrightYear) - fmt.Fprintf(c.App.Writer, "Licence AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>\n") + fmt.Fprintf(c.App.Writer, "License GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>\n") } func registerApp(name string) *cli.App { @@ -514,15 +492,8 @@ } app.Before = registerBefore - app.ExtraInfo = func() map[string]string { - if globalDebug { - return getSystemData() - } - return make(map[string]string) - } - app.HideHelpCommand = true - app.Usage = "MinIO Client for cloud storage and filesystems." + app.Usage = "MinIO Client for object storage and filesystems." app.Commands = appCmds app.Author = "MinIO, Inc." app.Version = ReleaseTag diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/subnet-utils.go new/mc-20220626T185148Z/cmd/subnet-utils.go --- old/mc-20220617T025250Z/cmd/subnet-utils.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/cmd/subnet-utils.go 2022-06-26 20:51:48.000000000 +0200 @@ -291,24 +291,44 @@ return false } -func setSubnetAPIKeyConfig(alias string, apiKey string) { - _, supported := getKeyFromMinIOConfig(alias, "subnet", "api_key") - if supported { - // Create a new MinIO Admin Client - client, err := newAdminClient(alias) - fatalIf(err, "Unable to initialize admin connection.") - - configStr := "subnet license= api_key=" + apiKey - _, e := client.SetConfigKV(globalContext, configStr) - fatalIf(probe.NewError(e), "Unable to set SUBNET API key config on MinIO") - return - } +func setSubnetCredsInMcConfig(alias string, apiKey string, lic string) { mcCfg := mcConfig() aliasCfg := mcCfg.Aliases[alias] - aliasCfg.APIKey = apiKey + if len(apiKey) > 0 { + aliasCfg.APIKey = apiKey + } + if len(lic) > 0 { + aliasCfg.License = lic + } setAlias(alias, aliasCfg) } +func setSubnetCreds(alias string, apiKey string, lic string) { + if len(apiKey) == 0 && len(lic) == 0 { + fatal(errDummy().Trace(), "At least one of api key and license must be passed.") + } + + _, apiKeySupported := getKeyFromMinIOConfig(alias, "subnet", "api_key") + _, licSupported := getKeyFromMinIOConfig(alias, "subnet", "license") + if !(apiKeySupported || licSupported) { + setSubnetCredsInMcConfig(alias, apiKey, lic) + return + } + + client, err := newAdminClient(alias) + fatalIf(err, "Unable to initialize admin connection.") + + configStr := "subnet" + if apiKeySupported && len(apiKey) > 0 { + configStr += " api_key=" + apiKey + } + if licSupported && len(lic) > 0 { + configStr += " license=" + lic + } + _, e := client.SetConfigKV(globalContext, configStr) + fatalIf(probe.NewError(e), "Unable to set SUBNET license/api_key config on MinIO") +} + func getClusterRegInfo(admInfo madmin.InfoMessage, clusterName string) ClusterRegistrationInfo { noOfPools := 1 noOfDrives := 0 @@ -469,10 +489,11 @@ return apiKey, lic, nil } -// extractAndSaveAPIKey - extract api key from response and set it in minio config -func extractAndSaveAPIKey(alias string, resp string) { +// extractAndSaveSubnetCreds - extract license / api key from response and set it in minio config +func extractAndSaveSubnetCreds(alias string, resp string) { subnetAPIKey := gjson.Parse(resp).Get("api_key").String() - if len(subnetAPIKey) > 0 { - setSubnetAPIKeyConfig(alias, subnetAPIKey) + subnetLic := gjson.Parse(resp).Get("license").String() + if len(subnetAPIKey) > 0 || len(subnetLic) > 0 { + setSubnetCreds(alias, subnetAPIKey, subnetLic) } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/support-diag.go new/mc-20220626T185148Z/cmd/support-diag.go --- old/mc-20220617T025250Z/cmd/support-diag.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/cmd/support-diag.go 2022-06-26 20:51:48.000000000 +0200 @@ -284,8 +284,6 @@ return e } - extractAndSaveAPIKey(alias, resp) - // Delete the report after successful upload os.Remove(filename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/support-logs-disable.go new/mc-20220626T185148Z/cmd/support-logs-disable.go --- old/mc-20220617T025250Z/cmd/support-logs-disable.go 1970-01-01 01:00:00.000000000 +0100 +++ new/mc-20220626T185148Z/cmd/support-logs-disable.go 2022-06-26 20:51:48.000000000 +0200 @@ -0,0 +1,49 @@ +// Copyright (c) 2015-2022 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 ( + "github.com/minio/cli" +) + +var supportLogsDisableCmd = cli.Command{ + Name: "disable", + Usage: "disable uploading MinIO logs to SUBNET", + OnUsageError: onUsageError, + Action: mainDisableLogs, + Before: setGlobalsFromContext, + Flags: logsConfigureFlags, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} +USAGE: + {{.HelpName}} ALIAS +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Disable uploading logs for cluster with alias 'play' to SUBNET + {{.Prompt}} {{.HelpName}} play +`, +} + +func mainDisableLogs(ctx *cli.Context) error { + setToggleMessageColor() + alias := validateLogsToggleCmd(ctx, "disable") + configureSubnetWebhook(alias, false) + return nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/support-logs-enable.go new/mc-20220626T185148Z/cmd/support-logs-enable.go --- old/mc-20220617T025250Z/cmd/support-logs-enable.go 1970-01-01 01:00:00.000000000 +0100 +++ new/mc-20220626T185148Z/cmd/support-logs-enable.go 2022-06-26 20:51:48.000000000 +0200 @@ -0,0 +1,50 @@ +// Copyright (c) 2015-2022 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 ( + "github.com/minio/cli" +) + +var supportLogsEnableCmd = cli.Command{ + Name: "enable", + Usage: "enable uploading real-time MinIO logs to SUBNET", + Action: mainEnableLogs, + OnUsageError: onUsageError, + Before: setGlobalsFromContext, + Flags: logsConfigureFlags, + HideHelpCommand: true, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} +USAGE: + {{.HelpName}} ALIAS +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Enable uploading real-time logs for cluster with alias 'play' to SUBNET. + {{.Prompt}} {{.HelpName}} play +`, +} + +func mainEnableLogs(ctx *cli.Context) error { + setToggleMessageColor() + alias := validateLogsToggleCmd(ctx, "enable") + configureSubnetWebhook(alias, true) + return nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/support-logs-show.go new/mc-20220626T185148Z/cmd/support-logs-show.go --- old/mc-20220617T025250Z/cmd/support-logs-show.go 1970-01-01 01:00:00.000000000 +0100 +++ new/mc-20220626T185148Z/cmd/support-logs-show.go 2022-06-26 20:51:48.000000000 +0200 @@ -0,0 +1,215 @@ +// Copyright (c) 2015-2022 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 ( + "context" + "fmt" + "strings" + "time" + + "github.com/fatih/color" + "github.com/minio/cli" + json "github.com/minio/colorjson" + "github.com/minio/madmin-go" + "github.com/minio/mc/pkg/probe" + "github.com/minio/pkg/console" +) + +const logTimeFormat string = "15:04:05 MST 01/02/2006" + +var logsShowFlags = []cli.Flag{ + cli.IntFlag{ + Name: "last, l", + Usage: "show last n log entries", + Value: 10, + }, + cli.StringFlag{ + Name: "type, t", + Usage: "list error logs by type. Valid options are '[minio, application, all]'", + Value: "all", + }, +} + +var supportLogsShowCmd = cli.Command{ + Name: "show", + Usage: "show MinIO logs", + Action: mainLogsShowConsole, + OnUsageError: onUsageError, + Before: setGlobalsFromContext, + Flags: append(logsShowFlags, globalFlags...), + HideHelpCommand: true, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} +USAGE: + {{.HelpName}} [FLAGS] TARGET [NODENAME] +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Show logs for a MinIO server with alias 'play' + {{.Prompt}} {{.HelpName}} play + 2. Show last 5 log entries for node 'node1' for a MinIO server with alias 'myminio' + {{.Prompt}} {{.HelpName}} --last 5 myminio node1 + 3. Show application errors in logs for a MinIO server with alias 'play' + {{.Prompt}} {{.HelpName}} --type application play +`, +} + +func checkLogsShowSyntax(ctx *cli.Context) { + if len(ctx.Args()) == 0 || len(ctx.Args()) > 3 { + cli.ShowCommandHelpAndExit(ctx, "show", 1) // last argument is exit code + } +} + +// Extend madmin.LogInfo to add String() and JSON() methods +type logMessage struct { + Status string `json:"status"` + madmin.LogInfo +} + +// JSON - jsonify loginfo +func (l logMessage) JSON() string { + l.Status = "success" + logJSON, err := json.MarshalIndent(&l, "", " ") + fatalIf(probe.NewError(err), "Unable to marshal into JSON.") + + return string(logJSON) +} + +func getLogTime(lt string) string { + tm, err := time.Parse(time.RFC3339Nano, lt) + if err != nil { + return lt + } + return tm.Format(logTimeFormat) +} + +// String - return colorized loginfo as string. +func (l logMessage) String() string { + var hostStr string + b := &strings.Builder{} + if l.NodeName != "" { + hostStr = fmt.Sprintf("%s ", colorizedNodeName(l.NodeName)) + } + log := l.LogInfo + if log.ConsoleMsg != "" { + if strings.HasPrefix(log.ConsoleMsg, "\n") { + fmt.Fprintf(b, "%s\n", hostStr) + log.ConsoleMsg = strings.TrimPrefix(log.ConsoleMsg, "\n") + } + fmt.Fprintf(b, "%s %s", hostStr, log.ConsoleMsg) + return b.String() + } + if l.API != nil { + apiString := "API: " + l.API.Name + "(" + if l.API.Args != nil && l.API.Args.Bucket != "" { + apiString = apiString + "bucket=" + l.API.Args.Bucket + } + if l.API.Args != nil && l.API.Args.Object != "" { + apiString = apiString + ", object=" + l.API.Args.Object + } + apiString += ")" + fmt.Fprintf(b, "\n%s %s", hostStr, console.Colorize("API", apiString)) + } + if l.Time != "" { + fmt.Fprintf(b, "\n%s Time: %s", hostStr, getLogTime(l.Time)) + } + if l.DeploymentID != "" { + fmt.Fprintf(b, "\n%s DeploymentID: %s", hostStr, l.DeploymentID) + } + if l.RequestID != "" { + fmt.Fprintf(b, "\n%s RequestID: %s", hostStr, l.RequestID) + } + if l.RemoteHost != "" { + fmt.Fprintf(b, "\n%s RemoteHost: %s", hostStr, l.RemoteHost) + } + if l.UserAgent != "" { + fmt.Fprintf(b, "\n%s UserAgent: %s", hostStr, l.UserAgent) + } + if l.Trace != nil { + if l.Trace.Message != "" { + fmt.Fprintf(b, "\n%s Error: %s", hostStr, console.Colorize("LogMessage", l.Trace.Message)) + } + if l.Trace.Variables != nil { + for key, value := range l.Trace.Variables { + if value != "" { + fmt.Fprintf(b, "\n%s %s=%s", hostStr, key, value) + } + } + } + if l.Trace.Source != nil { + traceLength := len(l.Trace.Source) + for i, element := range l.Trace.Source { + fmt.Fprintf(b, "\n%s %8v: %s", hostStr, traceLength-i, element) + } + } + } + logMsg := strings.TrimPrefix(b.String(), "\n") + return fmt.Sprintf("%s\n", logMsg) +} + +// mainLogsShowConsole - the entry function of support logs show +func mainLogsShowConsole(ctx *cli.Context) error { + // Check for command syntax + checkLogsShowSyntax(ctx) + console.SetColor("LogMessage", color.New(color.Bold, color.FgRed)) + console.SetColor("Api", color.New(color.Bold, color.FgWhite)) + for _, c := range colors { + console.SetColor(fmt.Sprintf("Node%d", c), color.New(c)) + } + aliasedURL := ctx.Args().Get(0) + var node string + if len(ctx.Args()) > 1 { + node = ctx.Args().Get(1) + } + var last int + if ctx.IsSet("last") { + last = ctx.Int("last") + if last <= 0 { + fatalIf(errInvalidArgument().Trace(ctx.Args()...), "please set a proper limit, for example: '--last 5' to display last 5 logs, omit this flag to display all available logs") + } + } + logType := strings.ToLower(ctx.String("type")) + if logType != "minio" && logType != "application" && logType != "all" { + fatalIf(errInvalidArgument().Trace(ctx.Args()...), "Invalid value for --type flag. Valid options are [minio, application, all]") + } + // Create a new MinIO Admin Client + client, err := newAdminClient(aliasedURL) + if err != nil { + fatalIf(err.Trace(aliasedURL), "Unable to initialize admin client.") + return nil + } + + ctxt, cancel := context.WithCancel(globalContext) + defer cancel() + + // Start listening on all console log activity. + logCh := client.GetLogs(ctxt, node, last, logType) + for logInfo := range logCh { + if logInfo.Err != nil { + fatalIf(probe.NewError(logInfo.Err), "Unable to listen to console logs") + } + // drop nodeName from output if specified as cli arg + if node != "" { + logInfo.NodeName = "" + } + printMsg(logMessage{LogInfo: logInfo}) + } + return nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/support-logs-status.go new/mc-20220626T185148Z/cmd/support-logs-status.go --- old/mc-20220617T025250Z/cmd/support-logs-status.go 1970-01-01 01:00:00.000000000 +0100 +++ new/mc-20220626T185148Z/cmd/support-logs-status.go 2022-06-26 20:51:48.000000000 +0200 @@ -0,0 +1,54 @@ +// Copyright (c) 2015-2022 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 ( + "github.com/minio/cli" +) + +var supportLogsStatusCmd = cli.Command{ + Name: "status", + Usage: "show current status of MinIO logs", + OnUsageError: onUsageError, + Action: mainStatusLogs, + Before: setGlobalsFromContext, + Flags: logsConfigureFlags, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} +USAGE: + {{.HelpName}} ALIAS +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Show current status of MinIO logs with alias 'play', whether + it is uploading to SUBNET or not + {{.Prompt}} {{.HelpName}} play +`, +} + +func mainStatusLogs(ctx *cli.Context) error { + setToggleMessageColor() + alias := validateLogsToggleCmd(ctx, "status") + enabled := isFeatureEnabled(alias, "logger_webhook", "logger_webhook:subnet") + printMsg(supportLogsMessage{ + Logs: featureStatusStr(enabled), + }) + + return nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/support-logs.go new/mc-20220626T185148Z/cmd/support-logs.go --- old/mc-20220617T025250Z/cmd/support-logs.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/cmd/support-logs.go 2022-06-26 20:51:48.000000000 +0200 @@ -26,43 +26,28 @@ "github.com/minio/pkg/console" ) -var logsFlags = append(globalFlags, cli.BoolFlag{ +var supportLogsSubcommands = []cli.Command{ + supportLogsEnableCmd, + supportLogsDisableCmd, + supportLogsStatusCmd, + supportLogsShowCmd, +} + +var logsConfigureFlags = append(globalFlags, cli.BoolFlag{ Name: "dev", Usage: "development mode - talks to local SUBNET", Hidden: true, }) var supportLogsCmd = cli.Command{ - Name: "logs", - Usage: "configure logs settings", - OnUsageError: onUsageError, - Action: mainLogs, - Before: setGlobalsFromContext, - Flags: logsFlags, - CustomHelpTemplate: `NAME: - {{.HelpName}} - {{.Usage}} - -USAGE: - {{.HelpName}} enable|disable|status ALIAS - -OPTIONS: - enable - Enable pushing MinIO logs to SUBNET in real-time - disable - Disable pushing MinIO logs to SUBNET - status - Display logs settings - -FLAGS: - {{range .VisibleFlags}}{{.}} - {{end}} -EXAMPLES: - 1. Enable logs for cluster with alias 'play' - {{.Prompt}} {{.HelpName}} enable play - - 2. Disable logs for cluster with alias 'play' - {{.Prompt}} {{.HelpName}} disable play - - 3. Check logs status for cluster with alias 'play' - {{.Prompt}} {{.HelpName}} status play -`, + Name: "logs", + Usage: "configure/display MinIO console logs", + OnUsageError: onUsageError, + Action: mainLogs, + Before: setGlobalsFromContext, + Flags: globalFlags, + HideHelpCommand: true, + Subcommands: supportLogsSubcommands, } type supportLogsMessage struct { @@ -85,23 +70,6 @@ return string(jsonBytes) } -func mainLogs(ctx *cli.Context) error { - setToggleMessageColor() - alias, arg := checkToggleCmdSyntax(ctx, "logs") - - if arg == "status" { - enabled := isFeatureEnabled(alias, "logger_webhook", "logger_webhook:subnet") - printMsg(supportLogsMessage{ - Logs: featureStatusStr(enabled), - }) - return nil - } - - configureSubnetWebhook(alias, arg == "enable") - - return nil -} - func configureSubnetWebhook(alias string, enable bool) { // Create a new MinIO Admin Client client, err := newAdminClient(alias) @@ -126,3 +94,18 @@ MsgPfx: "Logging to support is now ", }) } + +func validateLogsToggleCmd(ctx *cli.Context, cmdName string) string { + if len(ctx.Args()) != 1 { + cli.ShowCommandHelpAndExit(ctx, cmdName, 1) // last argument is exit code + } + alias, _ := url2Alias(ctx.Args().Get(0)) + return alias +} + +// mainLogs is the handle for "mc support logs" command. +func mainLogs(ctx *cli.Context) error { + commandNotFound(ctx, supportLogsSubcommands) + return nil + // Sub-commands like "enable", "disable", "status", "print" have their own main. +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/cmd/support-register.go new/mc-20220626T185148Z/cmd/support-register.go --- old/mc-20220617T025250Z/cmd/support-register.go 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/cmd/support-register.go 2022-06-26 20:51:48.000000000 +0200 @@ -24,6 +24,7 @@ "strings" "github.com/fatih/color" + "github.com/golang-jwt/jwt/v4" "github.com/google/uuid" "github.com/minio/cli" "github.com/minio/mc/pkg/probe" @@ -173,19 +174,29 @@ ` + regToken + ` -Step 2: Enter the API key generated by SUBNET: `) +Step 2: Enter the key generated by SUBNET: `) reader := bufio.NewReader(os.Stdin) - apiKey, e := reader.ReadString('\n') - fatalIf(probe.NewError(e), "Error in reading API key") - apiKey = strings.TrimSpace(apiKey) - - if len(apiKey) > 0 { - _, e := uuid.Parse(apiKey) - fatalIf(probe.NewError(e), "Invalid API key specified:") - setSubnetAPIKeyConfig(alias, apiKey) + key, e := reader.ReadString('\n') + fatalIf(probe.NewError(e), "Error in reading the key") + key = strings.TrimSpace(key) + + if len(key) > 0 { + _, e := uuid.Parse(key) + if e == nil { + // key is the api key + setSubnetCreds(alias, key, "") + return + } + + // Not api-key (uuid). Must be license (jwt) + _, _, e = new(jwt.Parser).ParseUnverified(key, jwt.MapClaims{}) + if e != nil { + fatalIf(probe.NewError(e), "Invalid key specified:") + } + setSubnetCreds(alias, "", key) } else { - console.Fatalln("Invalid API key specified. Please run the command again with a valid SUBNET API key to complete registration.") + console.Fatalln("Invalid key specified. Please run the command again with a valid key to complete registration.") } } @@ -193,5 +204,5 @@ resp, e := registerClusterOnSubnet(alias, clusterRegInfo) fatalIf(probe.NewError(e), "Could not register cluster with SUBNET:") - extractAndSaveAPIKey(alias, resp) + extractAndSaveSubnetCreds(alias, resp) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/docs/minio-admin-complete-guide.md new/mc-20220626T185148Z/docs/minio-admin-complete-guide.md --- old/mc-20220617T025250Z/docs/minio-admin-complete-guide.md 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/docs/minio-admin-complete-guide.md 2022-06-26 20:51:48.000000000 +0200 @@ -708,34 +708,7 @@ <a name="console"></a> ### Command `console` - show console logs for MinIO server -`console` command displays server logs of one or all MinIO servers (under distributed cluster) - -```sh -NAME: - mc admin console - show console logs for MinIO server - -FLAGS: - --limit value, -l value show last n log entries (default: 10) - --help, -h show help -``` - -*Example: Display MinIO server http trace.* - -```sh -mc admin console myminio - - API: SYSTEM(bucket=images) - Time: 22:48:06 PDT 09/05/2019 - DeploymentID: 6faeded5-5cf3-4133-8a37-07c5d500207c - RequestID: <none> - RemoteHost: <none> - UserAgent: <none> - Error: ARN 'arn:minio:sqs:us-east-1:1:webhook' not found - 4: cmd/notification.go:1189:cmd.readNotificationConfig() - 3: cmd/notification.go:780:cmd.(*NotificationSys).refresh() - 2: cmd/notification.go:815:cmd.(*NotificationSys).Init() - 1: cmd/server-main.go:375:cmd.serverMain() -``` +This command is deprecated and will be removed in a future release. Use 'mc support logs show' instead. <a name="prometheus"></a> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mc-20220617T025250Z/docs/minio-client-complete-guide.md new/mc-20220626T185148Z/docs/minio-client-complete-guide.md --- old/mc-20220617T025250Z/docs/minio-client-complete-guide.md 2022-06-16 22:17:03.000000000 +0200 +++ new/mc-20220626T185148Z/docs/minio-client-complete-guide.md 2022-06-26 20:51:48.000000000 +0200 @@ -1922,6 +1922,7 @@ mc support perf analyze object, network and drive performance mc support inspect upload raw object contents for analysis mc support profile generate profile data for debugging + mc support logs configure/display MinIO console logs ``` @@ -1953,4 +1954,14 @@ Get CPU profiling for 2 minutes ``` mc support profile --type cpu --duration 120 myminio/ +``` + +Print last 5 application error logs entries for node 'node1' on MinIO server with alias 'myminio' +``` +mc support logs show --last 5 --type application myminio node1 +``` + +Enable logs for cluster with alias 'play' +``` +mc support logs enable play ``` \ No newline at end of file ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/minio-client/vendor.tar.gz /work/SRC/openSUSE:Factory/.minio-client.new.1548/vendor.tar.gz differ: char 5, line 1