func registerBefore(ctx *cli.Context) error { setMcConfigDir(ctx.GlobalString("config")) globalQuietFlag = ctx.GlobalBool("quiet") globalForceFlag = ctx.GlobalBool("force") globalAliasFlag = ctx.GlobalBool("alias") globalDebugFlag = ctx.GlobalBool("debug") globalJSONFlag = ctx.GlobalBool("json") themeName := ctx.GlobalString("theme") if globalDebugFlag { console.NoDebugPrint = false } switch { case console.IsValidTheme(themeName) != true: console.Errorf("Invalid theme, please choose from the following list: %s.\n", console.GetThemeNames()) return errInvalidTheme{Theme: themeName} default: err := console.SetTheme(themeName) if err != nil { console.Errorf("Failed to set theme ‘%s’.", themeName) return err } } // Migrate any old version of config / state files to newer format. migrate() checkConfig() return nil }
func doCastCmdSession(session *sessionV2) { trapCh := signalTrap(os.Interrupt, os.Kill) if !session.HasData() { doPrepareCastURLs(session, trapCh) } // Set up progress bar. var bar barSend if !globalQuietFlag || !globalJSONFlag { bar = newCpBar() bar.Extend(session.Header.TotalBytes) } // Prepare URL scanner from session data file. scanner := bufio.NewScanner(session.NewDataReader()) // isCopied returns true if an object has been already copied // or not. This is useful when we resume from a session. isCopied := isCopiedFactory(session.Header.LastCopied) wg := new(sync.WaitGroup) // Limit numner of cast routines based on available CPU resources. castQueue := make(chan bool, int(math.Max(float64(runtime.NumCPU())-1, 1))) defer close(castQueue) // Status channel for receiveing cast return status. statusCh := make(chan castURLs) // Go routine to monitor doCast status and signal traps. wg.Add(1) go func() { defer wg.Done() for { select { case cURLs, ok := <-statusCh: // Receive status. if !ok { // We are done here. Top level function has returned. bar.Finish() return } if cURLs.Error == nil { session.Header.LastCopied = cURLs.SourceContent.Name } else { console.Errorf("Failed to cast ‘%s’, %s\n", cURLs.SourceContent.Name, NewIodine(cURLs.Error)) } case <-trapCh: // Receive interrupt notification. session.Save() session.Info() os.Exit(0) } } }() // Go routine to perform concurrently casting. wg.Add(1) go func() { defer wg.Done() castWg := new(sync.WaitGroup) defer close(statusCh) for scanner.Scan() { var sURLs castURLs json.Unmarshal([]byte(scanner.Text()), &sURLs) if isCopied(sURLs.SourceContent.Name) { doCastFake(sURLs, &bar) } else { // Wait for other cast routines to // complete. We only have limited CPU // and network resources. castQueue <- true // Account for each cast routines we start. castWg.Add(1) // Do casting in background concurrently. go doCast(sURLs, &bar, castQueue, castWg, statusCh) } } castWg.Wait() }() wg.Wait() }
func main() { // Migrate any old version of config / state files to newer format. migrate() // Enable GOMAXPROCS to default to number of CPUs. runtime.GOMAXPROCS(runtime.NumCPU()) // Register all the commands registerCmd(lsCmd) // List contents of a bucket registerCmd(mbCmd) // make a bucket registerCmd(catCmd) // concantenate an object to standard output registerCmd(cpCmd) // copy objects and files from multiple sources to single destination registerCmd(castCmd) // cast objects and files from single source to multiple destinations registerCmd(sessionCmd) // session handling for resuming copy and cast operations registerCmd(diffCmd) // compare two objects registerCmd(accessCmd) // set permissions [public, private, readonly, authenticated] for buckets and folders. registerCmd(configCmd) // generate configuration "/home/harsha/.mc/config.json" file. registerCmd(updateCmd) // update Check for new software updates // register all the flags registerFlag(configFlag) // path to config folder registerFlag(quietFlag) // suppress console output registerFlag(forceFlag) // force copying data registerFlag(aliasFlag) // OS toolchain mimic registerFlag(themeFlag) // console theme flag registerFlag(jsonFlag) // json formatted output registerFlag(debugFlag) // enable debugging output app := cli.NewApp() app.Usage = "Minio Client for object storage and filesystems" app.Version = getVersion() app.Commands = commands app.Compiled = getVersion() app.Flags = flags app.Author = "Minio.io" app.Before = func(ctx *cli.Context) error { if ctx.GlobalString("config") != "" { setMcConfigDir(ctx.GlobalString("config")) } globalQuietFlag = ctx.GlobalBool("quiet") globalForceFlag = ctx.GlobalBool("force") globalAliasFlag = ctx.GlobalBool("alias") globalDebugFlag = ctx.GlobalBool("debug") globalJSONFlag = ctx.GlobalBool("json") if globalDebugFlag { app.ExtraInfo = getSystemData() console.NoDebugPrint = false } themeName := ctx.GlobalString("theme") switch { case console.IsValidTheme(themeName) != true: console.Errorf("Invalid theme, please choose from the following list: %s.\n", console.GetThemeNames()) return errInvalidTheme{Theme: themeName} default: err := console.SetTheme(themeName) if err != nil { console.Errorf("Failed to set theme ‘%s’.", themeName) return err } } checkConfig() return nil } app.After = func(ctx *cli.Context) error { if !isMcConfigExists() { console.Fatalf("Please run \"mc config generate\". %s\n", errNotConfigured{}) } return nil } app.CustomAppHelpTemplate = `NAME: {{.Name}} - {{.Usage}} USAGE: {{.Name}} {{if .Flags}}[global flags] {{end}}command{{if .Flags}} [command flags]{{end}} [arguments...] COMMANDS: {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} {{end}}{{if .Flags}} GLOBAL FLAGS: {{range .Flags}}{{.}} {{end}}{{end}} VERSION: {{if .Compiled}} {{.Compiled}}{{end}} {{range $key, $value := .ExtraInfo}} {{$key}}: {{$value}} {{end}} ` app.RunAndExitOnError() }