func mainConfigVersion(ctx *cli.Context) { if ctx.Args().First() == "help" { cli.ShowCommandHelpAndExit(ctx, "version", 1) // last argument is exit code } config, err := newConfig() fatalIf(err.Trace(), "Failed to initialize ‘quick’ configuration data structure.") configPath := mustGetMcConfigPath() err = config.Load(configPath) fatalIf(err.Trace(configPath), "Unable to load config path") // convert interface{} back to its original struct newConf := config.Data().(*configV5) type Version struct { Value string `json:"value"` } if globalJSONFlag { tB, e := json.Marshal( struct { Version Version `json:"version"` }{Version: Version{newConf.Version}}, ) fatalIf(probe.NewError(e), "Unable to construct version string.") console.Println(string(tB)) return } console.Println(newConf.Version) }
func mainVersion(ctx *cli.Context) { if ctx.Args().First() == "help" { cli.ShowCommandHelpAndExit(ctx, "version", 1) // last argument is exit code } setVersionPalette(ctx.GlobalString("colors")) if globalJSONFlag { tB, e := json.Marshal( struct { Version struct { Value string `json:"value"` Format string `json:"format"` } `json:"version"` }{ Version: struct { Value string `json:"value"` Format string `json:"format"` }{ Value: mcVersion, Format: "RFC2616", }, }, ) fatalIf(probe.NewError(e), "Unable to construct version string.") console.Println(string(tB)) return } msg := console.Colorize("Version", fmt.Sprintf("Version: %s\n", mcVersion)) msg += console.Colorize("Version", fmt.Sprintf("Release-Tag: %s", mcReleaseTag)) console.Println(msg) }
// printMsg prints message string or JSON structure depending on the type of output console. func printMsg(msg message) { if !globalJSONFlag { console.Println(msg.String()) } else { console.Println(msg.JSON()) } }
// PrintMsg prints message func (qs *QuietStatus) PrintMsg(msg message) { if !globalJSON { console.Println(msg.String()) } else { console.Println(msg.JSON()) } }
// PrintMsg prints message func (ds *DummyStatus) PrintMsg(msg message) { if !globalJSON { console.Println(msg.String()) } else { console.Println(msg.JSON()) } }
func mainVersion(ctx *cli.Context) { if ctx.Args().First() == "help" { cli.ShowCommandHelpAndExit(ctx, "version", 1) // last argument is exit code } t, _ := time.Parse(time.RFC3339Nano, Version) if t.IsZero() { console.Println("") return } type Version struct { Value time.Time `json:"value"` Format string `json:"format"` } if globalJSONFlag { tB, e := json.Marshal( struct { Version Version `json:"version"` }{Version: Version{t, "RFC3339Nano"}}, ) fatalIf(probe.NewError(e), "Unable to construct version string.") console.Println(string(tB)) return } console.Println(t.Format(http.TimeFormat)) }
// Prints startup message for Object API acces, prints link to our SDK documentation. func printObjectAPIMsg() { console.Println(colorBlue("\nObject API (Amazon S3 compatible):")) console.Println(colorBlue(" Go: ") + fmt.Sprintf(getFormatStr(len(goQuickStartGuide), 8), goQuickStartGuide)) console.Println(colorBlue(" Java: ") + fmt.Sprintf(getFormatStr(len(javaQuickStartGuide), 6), javaQuickStartGuide)) console.Println(colorBlue(" Python: ") + fmt.Sprintf(getFormatStr(len(pyQuickStartGuide), 4), pyQuickStartGuide)) console.Println(colorBlue(" JavaScript: ") + jsQuickStartGuide) }
func clearSession(sid string) { if sid == "all" { for _, sid := range getSessionIDs() { session, err := loadSessionV2(sid) fatalIf(err.Trace(sid), "Unable to load session ‘"+sid+"’.") fatalIf(session.Delete().Trace(sid), "Unable to load session ‘"+sid+"’.") console.Println(ClearSessionMessage{ Status: "success", SessionID: sid, }) } return } if !isSession(sid) { fatalIf(errDummy().Trace(), "Session ‘"+sid+"’ not found.") } session, err := loadSessionV2(sid) fatalIf(err.Trace(sid), "Unable to load session ‘"+sid+"’.") if session != nil { fatalIf(session.Delete().Trace(sid), "Unable to load session ‘"+sid+"’.") console.Println(ClearSessionMessage{ Status: "success", SessionID: sid, }) } }
func mainVersion(ctx *cli.Context) { if len(ctx.Args()) != 0 { cli.ShowCommandHelpAndExit(ctx, "version", 1) } console.Println("Version: " + Version) console.Println("Release-Tag: " + ReleaseTag) console.Println("Commit-ID: " + CommitID) }
func sessionExecute(bar barSend, s *sessionV1) { switch s.CommandType { case "cp": for cps := range doCopyCmdSession(bar, s) { if cps.Error != nil { console.Errors(ErrorMessage{ Message: "Failed with", Error: iodine.New(cps.Error, nil), }) } if cps.Done { if err := saveSession(s); err != nil { console.Fatals(ErrorMessage{ Message: "Failed with", Error: iodine.New(err, nil), }) } console.Println() console.Infos(InfoMessage{ Message: "Session terminated. To resume session type ‘mc session resume " + s.SessionID + "’", }) // this os.Exit is needed really to exit in-case of "os.Interrupt" os.Exit(0) } } case "sync": for ss := range doSyncCmdSession(bar, s) { if ss.Error != nil { console.Errors(ErrorMessage{ Message: "Failed with", Error: iodine.New(ss.Error, nil), }) } if ss.Done { if err := saveSession(s); err != nil { console.Fatals(ErrorMessage{ Message: "Failed with", Error: iodine.New(err, nil), }) } console.Println() console.Infos(InfoMessage{ Message: "Session terminated. To resume session type ‘mc session resume " + s.SessionID + "’", }) // this os.Exit is needed really to exit in-case of "os.Interrupt" os.Exit(0) } } } }
// Prints startup message for command line access. Prints link to our documentation // and custom platform specific message. func printCLIAccessMsg(endPoint string) { // Get saved credentials. cred := serverConfig.GetCredential() // Configure 'mc', following block prints platform specific information for minio client. console.Println(colorBlue("\nCommand-line Access: ") + mcQuickStartGuide) if runtime.GOOS == "windows" { mcMessage := fmt.Sprintf("$ mc.exe config host add myminio %s %s %s", endPoint, cred.AccessKeyID, cred.SecretAccessKey) console.Println(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) } else { mcMessage := fmt.Sprintf("$ mc config host add myminio %s %s %s", endPoint, cred.AccessKeyID, cred.SecretAccessKey) console.Println(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) } }
// fatalIf wrapper function which takes error and selectively prints stack frames if available on debug func fatalIf(err *probe.Error, msg string) { if err == nil { return } if globalJSON { errorMsg := errorMessage{ Message: msg, Type: "fatal", Cause: causeMessage{ Message: err.ToGoError().Error(), Error: err.ToGoError(), }, SysInfo: err.SysInfo, } if globalDebug { errorMsg.CallTrace = err.CallTrace } json, err := json.Marshal(struct { Status string `json:"status"` Error errorMessage `json:"error"` }{ Status: "error", Error: errorMsg, }) if err != nil { console.Fatalln(probe.NewError(err)) } console.Println(string(json)) console.Fatalln() } if !globalDebug { console.Fatalln(fmt.Sprintf("%s %s", msg, err.ToGoError())) } console.Fatalln(fmt.Sprintf("%s %s", msg, err)) }
// removeAlias - remove alias func removeAlias(alias string) { if alias == "" { fatalIf(errDummy().Trace(), "Alias or URL cannot be empty.") } conf := newConfigV2() config, err := quick.New(conf) fatalIf(err.Trace(conf.Version), "Failed to initialize ‘quick’ configuration data structure.") err = config.Load(mustGetMcConfigPath()) fatalIf(err.Trace(), "Unable to load config path") if isAliasReserved(alias) { fatalIf(errDummy().Trace(), fmt.Sprintf("Cannot use a reserved name ‘%s’ as an alias. Following are reserved names: [help, private, readonly, public, authenticated].", alias)) } if !isValidAliasName(alias) { fatalIf(errDummy().Trace(), fmt.Sprintf("Alias name ‘%s’ is invalid, valid examples are: mybucket, Area51, Grand-Nagus", alias)) } // convert interface{} back to its original struct newConf := config.Data().(*configV2) if _, ok := newConf.Aliases[alias]; !ok { fatalIf(errDummy().Trace(), fmt.Sprintf("Alias ‘%s’ does not exist.", alias)) } delete(newConf.Aliases, alias) newConfig, err := quick.New(newConf) fatalIf(err.Trace(conf.Version), "Failed to initialize ‘quick’ configuration data structure.") err = writeConfig(newConfig) fatalIf(err.Trace(alias), "Unable to save alias ‘"+alias+"’.") console.Println(AliasMessage{ op: "remove", Alias: alias, }) }
// Migrate session version '5' to version '6', all older sessions are // in-fact removed and not migrated. All session files from '6' and // above should be migrated - See: migrateSessionV6ToV7(). func migrateSessionV5ToV6() { for _, sid := range getSessionIDs() { sV6Header, err := loadSessionV6Header(sid) if err != nil { if os.IsNotExist(err.ToGoError()) { continue } fatalIf(err.Trace(sid), "Unable to load version ‘6’. Migration failed please report this issue at https://github.com/minio/mc/issues.") } sessionVersion, e := strconv.Atoi(sV6Header.Version) fatalIf(probe.NewError(e), "Unable to load version ‘6’. Migration failed please report this issue at https://github.com/minio/mc/issues.") if sessionVersion > 5 { // It is new format. continue } /*** Remove all session files older than v6 ***/ sessionFile, err := getSessionFile(sid) fatalIf(err.Trace(sid), "Unable to get session file.") sessionDataFile, err := getSessionDataFile(sid) fatalIf(err.Trace(sid), "Unable to get session data file.") console.Println("Removing unsupported session file ‘" + sessionFile + "’ version ‘" + sV6Header.Version + "’.") if e := os.Remove(sessionFile); e != nil { fatalIf(probe.NewError(e), "Unable to remove version ‘"+sV6Header.Version+"’ session file ‘"+sessionFile+"’.") } if e := os.Remove(sessionDataFile); e != nil { fatalIf(probe.NewError(e), "Unable to remove version ‘"+sV6Header.Version+"’ session data file ‘"+sessionDataFile+"’.") } } }
// Version '6' to '7' migrates config, removes previous fields related // to backend types and server address. This change further simplifies // the config for future additions. func migrateV6ToV7() error { cv6, err := loadConfigV6() if err != nil { if os.IsNotExist(err) { return nil } return fmt.Errorf("Unable to load config version ‘6’. %v", err) } if cv6.Version != "6" { return nil } // Save only the new fields, ignore the rest. srvConfig := &serverConfigV7{} srvConfig.Version = "7" srvConfig.Credential = cv6.Credential srvConfig.Region = cv6.Region if srvConfig.Region == "" { // Region needs to be set for AWS Signature Version 4. srvConfig.Region = "us-east-1" } srvConfig.Logger.Console = cv6.Logger.Console srvConfig.Logger.File = cv6.Logger.File srvConfig.Logger.Syslog = cv6.Logger.Syslog srvConfig.Notify.AMQP = make(map[string]amqpNotify) srvConfig.Notify.ElasticSearch = make(map[string]elasticSearchNotify) srvConfig.Notify.Redis = make(map[string]redisNotify) if len(cv6.Notify.AMQP) == 0 { srvConfig.Notify.AMQP["1"] = amqpNotify{} } else { srvConfig.Notify.AMQP = cv6.Notify.AMQP } if len(cv6.Notify.ElasticSearch) == 0 { srvConfig.Notify.ElasticSearch["1"] = elasticSearchNotify{} } else { srvConfig.Notify.ElasticSearch = cv6.Notify.ElasticSearch } if len(cv6.Notify.Redis) == 0 { srvConfig.Notify.Redis["1"] = redisNotify{} } else { srvConfig.Notify.Redis = cv6.Notify.Redis } qc, err := quick.New(srvConfig) if err != nil { return fmt.Errorf("Unable to initialize the quick config. %v", err) } configFile, err := getConfigFile() if err != nil { return fmt.Errorf("Unable to get config file. %v", err) } err = qc.Save(configFile) if err != nil { return fmt.Errorf("Failed to migrate config from ‘"+cv6.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) } console.Println("Migration from version ‘" + cv6.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") return nil }
// mainDiff - is a handler for mc diff command func mainDiff(ctx *cli.Context) { checkDiffSyntax(ctx) console.SetCustomTheme(map[string]*color.Color{ "DiffMessage": color.New(color.FgGreen, color.Bold), "DiffOnlyInFirst": color.New(color.FgRed, color.Bold), "DiffType": color.New(color.FgYellow, color.Bold), "DiffSize": color.New(color.FgMagenta, color.Bold), }) config := mustGetMcConfig() firstArg := ctx.Args().First() secondArg := ctx.Args().Last() firstURL, err := getCanonicalizedURL(firstArg, config.Aliases) fatalIf(err.Trace(firstArg), "Unable to parse first argument ‘"+firstArg+"’.") secondURL, err := getCanonicalizedURL(secondArg, config.Aliases) fatalIf(err.Trace(secondArg), "Unable to parse second argument ‘"+secondArg+"’.") newFirstURL := stripRecursiveURL(firstURL) for diff := range doDiffCmd(newFirstURL, secondURL, isURLRecursive(firstURL)) { fatalIf(diff.Error.Trace(newFirstURL, secondURL), "Failed to diff ‘"+firstURL+"’ and ‘"+secondURL+"’.") console.Println(diff.String()) } }
// errorIf synonymous with fatalIf but doesn't exit on error != nil func errorIf(err *probe.Error, msg string) { if err == nil { return } if globalJSONFlag { errorMessage := ErrorMessage{ Message: msg, Type: "error", Cause: err.ToGoError(), SysInfo: err.SysInfo, } if globalDebugFlag { errorMessage.CallTrace = err.CallTrace } json, err := json.Marshal(struct { Error ErrorMessage `json:"error"` }{ Error: errorMessage, }) if err != nil { console.Fatalln(probe.NewError(err)) } console.Println(string(json)) return } if !globalDebugFlag { console.Errorln(fmt.Sprintf("%s %s", msg, err.ToGoError())) return } console.Errorln(fmt.Sprintf("%s %s", msg, err)) }
// Version '3' to '4' migrates config, removes previous fields related // to backend types and server address. This change further simplifies // the config for future additions. func migrateV3ToV4() { cv3, err := loadConfigV3() if err != nil && os.IsNotExist(err) { return } fatalIf(err, "Unable to load config version ‘3’.") if cv3.Version != "3" { return } // Save only the new fields, ignore the rest. srvConfig := &configV4{} srvConfig.Version = "4" srvConfig.Credential = cv3.Credential srvConfig.Region = cv3.Region if srvConfig.Region == "" { // Region needs to be set for AWS Signature Version 4. srvConfig.Region = "us-east-1" } srvConfig.Logger.Console = cv3.Logger.Console srvConfig.Logger.File = cv3.Logger.File srvConfig.Logger.Syslog = cv3.Logger.Syslog qc, err := quick.New(srvConfig) fatalIf(err, "Unable to initialize the quick config.") configFile, err := getConfigFile() fatalIf(err, "Unable to get config file.") err = qc.Save(configFile) fatalIf(err, "Failed to migrate config from ‘"+cv3.Version+"’ to ‘"+srvConfig.Version+"’ failed.") console.Println("Migration from version ‘" + cv3.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") }
// mainDiff main for 'diff'. func mainDiff(ctx *cli.Context) { checkDiffSyntax(ctx) // Additional command speific theme customization. console.SetColor("DiffMessage", color.New(color.FgGreen, color.Bold)) console.SetColor("DiffOnlyInFirst", color.New(color.FgRed, color.Bold)) console.SetColor("DiffType", color.New(color.FgYellow, color.Bold)) console.SetColor("DiffSize", color.New(color.FgMagenta, color.Bold)) config := mustGetMcConfig() firstArg := ctx.Args().First() secondArg := ctx.Args().Last() firstURL := getAliasURL(firstArg, config.Aliases) secondURL := getAliasURL(secondArg, config.Aliases) newFirstURL := stripRecursiveURL(firstURL) for diff := range doDiffMain(newFirstURL, secondURL, isURLRecursive(firstURL)) { if diff.Error != nil { // Print in new line and adjust to top so that we don't print over the ongoing scan bar if !globalQuietFlag && !globalJSONFlag { console.Eraseline() } } fatalIf(diff.Error.Trace(newFirstURL, secondURL), "Failed to diff ‘"+firstURL+"’ and ‘"+secondURL+"’.") printMsg(diff) } // Print in new line and adjust to top so that we don't print over the ongoing scan bar if !globalQuietFlag && !globalJSONFlag { console.Eraseline() } console.Println(console.Colorize("DiffMessage", "Done.")) }
// doMirror - Mirror an object to multiple destination. mirrorURLs status contains a copy of sURLs and error if any. func doMirror(sURLs mirrorURLs, bar *barSend, mirrorQueueCh <-chan bool, wg *sync.WaitGroup, statusCh chan<- mirrorURLs) { defer wg.Done() // Notify that this copy routine is done. defer func() { <-mirrorQueueCh }() if sURLs.Error != nil { // Errorneous sURLs passed. sURLs.Error = sURLs.Error.Trace() statusCh <- sURLs return } if !globalQuietFlag && !globalJSONFlag { bar.SetCaption(sURLs.SourceContent.Name + ": ") } reader, length, err := getSource(sURLs.SourceContent.Name) if err != nil { if !globalQuietFlag && !globalJSONFlag { bar.ErrorGet(int64(length)) } sURLs.Error = err.Trace(sURLs.SourceContent.Name) statusCh <- sURLs return } var targetURLs []string for _, targetContent := range sURLs.TargetContents { targetURLs = append(targetURLs, targetContent.Name) } var newReader io.ReadCloser if globalQuietFlag || globalJSONFlag { console.Println(MirrorMessage{ Source: sURLs.SourceContent.Name, Targets: targetURLs, }.String()) newReader = reader } else { // set up progress newReader = bar.NewProxyReader(reader) } defer newReader.Close() err = putTargets(targetURLs, length, newReader) if err != nil { if !globalQuietFlag && !globalJSONFlag { bar.ErrorPut(int64(length)) } sURLs.Error = err.Trace(targetURLs...) statusCh <- sURLs return } sURLs.Error = nil // just for safety statusCh <- sURLs }
// Print once is a constructor returning a function printing once. // internally print uses sync.Once to perform exactly one action. func printOnceFn() printOnceFunc { var once sync.Once return func(msg string) { once.Do(func() { if !globalQuiet { console.Println(msg) } }) } }
// Finish displays the accounting summary func (qs *QuietStatus) Finish() { accntStat := qs.accounter.Stat() cpStatMessage := mirrorStatMessage{ Total: accntStat.Total, Transferred: accntStat.Transferred, Speed: accntStat.Speed, } console.Println(console.Colorize("Mirror", cpStatMessage.String())) }
func mainVersion(ctx *cli.Context) { if len(ctx.Args()) != 0 { cli.ShowCommandHelpAndExit(ctx, "version", 1) } // Set global variables after parsing passed arguments setGlobalsFromContext(ctx) // Initialization routine, such as config loading, enable logging, .. minioInit() if globalQuiet { return } console.Println("Version: " + Version) console.Println("Release-Tag: " + ReleaseTag) console.Println("Commit-ID: " + CommitID) }
func getReleaseUpdate() { clnt, err := url2Client(mcUpdateURL) fatalIf(err.Trace(mcUpdateURL), "Unable to initalize update URL.") data, _, err := clnt.GetObject(0, 0) fatalIf(err.Trace(mcUpdateURL), "Unable to read from update URL ‘"+mcUpdateURL+"’.") current, e := time.Parse(time.RFC3339Nano, Version) fatalIf(probe.NewError(e), "Unable to parse Version string as time.") if current.IsZero() { fatalIf(errDummy().Trace(), "Updates not supported for custom build. Version field is empty. Please download official releases from https://dl.minio.io:9000") } var updates Updates decoder := json.NewDecoder(data) e = decoder.Decode(&updates) fatalIf(probe.NewError(e), "Unable to decode update notification.") latest, e := time.Parse(http.TimeFormat, updates.BuildDate) fatalIf(probe.NewError(e), "Unable to parse BuildDate.") if latest.IsZero() { fatalIf(errDummy().Trace(), "Unable to validate any update available at this time. Please open an issue at https://github.com/minio/mc/issues") } mcUpdateURLParse := clnt.URL() if latest.After(current) { console.Println(UpdateMessage{ Update: true, Download: mcUpdateURLParse.Scheme + "://" + mcUpdateURLParse.Host + string(mcUpdateURLParse.Separator) + updates.Platforms[runtime.GOOS], Version: latest, }) return } console.Println(UpdateMessage{ Update: false, Download: mcUpdateURLParse.Scheme + "://" + mcUpdateURLParse.Host + string(mcUpdateURLParse.Separator) + updates.Platforms[runtime.GOOS], Version: latest, }) return }
// Version '2' to '3' config migration adds new fields and re-orders // previous fields. Simplifies config for future additions. func migrateV2ToV3() { cv2, err := loadConfigV2() if err != nil && os.IsNotExist(err) { return } fatalIf(err, "Unable to load config version ‘2’.") if cv2.Version != "2" { return } srvConfig := &configV3{} srvConfig.Version = "3" srvConfig.Addr = ":9000" srvConfig.Credential = credential{ AccessKeyID: cv2.Credentials.AccessKeyID, SecretAccessKey: cv2.Credentials.SecretAccessKey, } srvConfig.Region = cv2.Credentials.Region if srvConfig.Region == "" { // Region needs to be set for AWS Signature V4. srvConfig.Region = "us-east-1" } srvConfig.Logger.Console = consoleLogger{ Enable: true, Level: "fatal", } flogger := fileLogger{} flogger.Level = "error" if cv2.FileLogger.Filename != "" { flogger.Enable = true flogger.Filename = cv2.FileLogger.Filename } srvConfig.Logger.File = flogger slogger := syslogLogger{} slogger.Level = "debug" if cv2.SyslogLogger.Addr != "" { slogger.Enable = true slogger.Addr = cv2.SyslogLogger.Addr } srvConfig.Logger.Syslog = slogger qc, err := quick.New(srvConfig) fatalIf(err, "Unable to initialize config.") configFile, err := getConfigFile() fatalIf(err, "Unable to get config file.") // Migrate the config. err = qc.Save(configFile) fatalIf(err, "Failed to migrate config from ‘"+cv2.Version+"’ to ‘"+srvConfig.Version+"’ failed.") console.Println("Migration from version ‘" + cv2.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") }
// doCopy - Copy a singe file from source to destination func doCopy(cpURLs copyURLs, bar *barSend, cpQueue <-chan bool, wg *sync.WaitGroup, statusCh chan<- copyURLs) { defer wg.Done() // Notify that this copy routine is done. defer func() { <-cpQueue }() if cpURLs.Error != nil { cpURLs.Error.Trace() statusCh <- cpURLs return } if !globalQuietFlag && !globalJSONFlag { bar.SetCaption(cpURLs.SourceContent.Name + ": ") } reader, length, err := getSource(cpURLs.SourceContent.Name) if err != nil { if !globalQuietFlag || !globalJSONFlag { bar.ErrorGet(length) } cpURLs.Error = err.Trace() statusCh <- cpURLs return } var newReader io.ReadCloser if globalQuietFlag || globalJSONFlag { console.Println(CopyMessage{ Source: cpURLs.SourceContent.Name, Target: cpURLs.TargetContent.Name, Length: cpURLs.SourceContent.Size, }.String()) newReader = reader } else { // set up progress newReader = bar.NewProxyReader(reader) } defer newReader.Close() err = putTarget(cpURLs.TargetContent.Name, length, newReader) if err != nil { if !globalQuietFlag || !globalJSONFlag { bar.ErrorPut(length) } cpURLs.Error = err.Trace() statusCh <- cpURLs return } cpURLs.Error = nil // just for safety statusCh <- cpURLs }
// doShareList list shared url's func doShareList() *probe.Error { sURLs, err := loadSharedURLsV2() if err != nil { return err.Trace() } for i, data := range sURLs.URLs { if time.Since(data.Date) > data.Message.Expiry { sURLs.URLs = append(sURLs.URLs[:i], sURLs.URLs[i+1:]...) continue } expiry := data.Message.Expiry - time.Since(data.Date) if !globalJSONFlag { msg := console.Colorize("Share", "Name: ") msg += console.Colorize("URL", data.Message.Key+"\n") msg += console.Colorize("Share", "Expiry: ") msg += console.Colorize("Expires", timeDurationToHumanizedTime(expiry)) msg += "\n" console.Println(msg) continue } shareListBytes, err := json.Marshal(struct { Expiry humanizedTime `json:"expiry"` URL string `json:"url"` Key string `json:"keyName"` }{ Expiry: timeDurationToHumanizedTime(expiry), URL: data.Message.URL, Key: data.Message.Key, }) if err != nil { return probe.NewError(err) } console.Println(string(shareListBytes)) } if err := saveSharedURLsV2(sURLs); err != nil { return err.Trace() } return nil }
// Prints bucket notification configurations. func printEventNotifiers() { if globalEventNotifier == nil { // In case initEventNotifier() was not done or failed. return } arnMsg := colorBlue("SQS ARNs: ") if len(globalEventNotifier.queueTargets) == 0 { arnMsg += colorBold(fmt.Sprintf(getFormatStr(len("<none>"), 1), "<none>")) } for queueArn := range globalEventNotifier.queueTargets { arnMsg += colorBold(fmt.Sprintf(getFormatStr(len(queueArn), 1), queueArn)) } console.Println(arnMsg) }
// Check for updates and print a notification message func checkUpdate() { // Do not print update messages, if quiet flag is set. if !globalQuiet { updateMsg, _, err := getReleaseUpdate(minioUpdateStableURL, 1*time.Second) if err != nil { // Ignore any errors during getReleaseUpdate(), possibly // because of network errors. return } if updateMsg.Update { console.Println(updateMsg) } } }
// Migrates session header version '7' to '8'. The only // change was the adding of insecure global flag func migrateSessionV7ToV8() { for _, sid := range getSessionIDs() { sV7, err := loadSessionV7(sid) if err != nil { if os.IsNotExist(err.ToGoError()) { continue } fatalIf(err.Trace(sid), "Unable to load version ‘7’. Migration failed please report this issue at https://github.com/minio/mc/issues.") } sessionVersion, e := strconv.Atoi(sV7.Header.Version) fatalIf(probe.NewError(e), "Unable to load version ‘7’. Migration failed please report this issue at https://github.com/minio/mc/issues.") if sessionVersion > 7 { // It is new format. continue } sessionFile, err := getSessionFile(sid) fatalIf(err.Trace(sid), "Unable to get session file.") // Initialize v7 header and migrate to new config. sV8Header := &sessionV8Header{} sV8Header.Version = "8" sV8Header.When = sV7.Header.When sV8Header.RootPath = sV7.Header.RootPath sV8Header.GlobalBoolFlags = sV7.Header.GlobalBoolFlags sV8Header.GlobalIntFlags = sV7.Header.GlobalIntFlags sV8Header.GlobalStringFlags = sV7.Header.GlobalStringFlags sV8Header.CommandType = sV7.Header.CommandType sV8Header.CommandArgs = sV7.Header.CommandArgs sV8Header.CommandBoolFlags = sV7.Header.CommandBoolFlags sV8Header.CommandIntFlags = sV7.Header.CommandIntFlags sV8Header.CommandStringFlags = sV7.Header.CommandStringFlags sV8Header.LastCopied = sV7.Header.LastCopied sV8Header.LastRemoved = sV7.Header.LastRemoved sV8Header.TotalBytes = sV7.Header.TotalBytes sV8Header.TotalObjects = int64(sV7.Header.TotalObjects) // Add insecure flag to the new V8 header sV8Header.GlobalBoolFlags["insecure"] = false qs, e := quick.New(sV8Header) fatalIf(probe.NewError(e).Trace(sid), "Unable to initialize quick config for session '8' header.") e = qs.Save(sessionFile) fatalIf(probe.NewError(e).Trace(sid, sessionFile), "Unable to migrate session from '7' to '8'.") console.Println("Successfully migrated ‘" + sessionFile + "’ from version ‘" + sV7.Header.Version + "’ to " + "‘" + sV8Header.Version + "’.") } }