func main() { getopt.ListVarLong(&configPaths, "config", 'c', "REQUIRED: Path to configuration file (can be used multiple times)", "PATH") getopt.BoolVarLong(&verbose, "verbose", 'v', "Verbose progress indicators and messages") help := getopt.BoolLong("help", 'h', "Show this help message and exit") getopt.SetParameters("") getopt.Parse() if *help { getopt.Usage() os.Exit(0) } if len(configPaths) == 0 { log.Printf("no configuration (-c/--config) found") getopt.Usage() os.Exit(1) } log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) // set parallelism (automatic in Go 1.6+) if runtime.GOMAXPROCS(0) < runtime.NumCPU() { runtime.GOMAXPROCS(runtime.NumCPU()) log.Printf("setting GOMAXPROCS = NumCPU = %d\n", runtime.NumCPU()) } for _, configPath := range configPaths { cfg, err := config.NewConfiguration(configPath) if err != nil { log.Fatal(err) continue } idx, err := index.NewIndex(cfg) if err != nil { log.Print(err) return } if err := idx.Update(); err != nil { log.Print(err) return } if err := idx.WriteOut(); err != nil { log.Print(err) return } } }
func GetOptions() ([]string, string) { var files []string // parse option, move outside main optDebug = getopt.Bool('d', "debug", "Display debug info") optEcho = getopt.Bool('e', "echo", "Display processing in stdout") optHelp := getopt.Bool('h', "help", "Help") optAll = getopt.Bool('a', "all", "Process all parameters") optVersion := getopt.BoolLong("version", 'v', "Show version, then exit.") optCfgfile := getopt.StringLong("config", 'c', fileconfig, "Name of the configuration file to use.") // optCycleMesure := getopt.StringLong("cycle_mesure", 'm', "", "Name of cycle_mesure") optFiles := getopt.StringLong("files", 'f', "", "files to process ex: data/fr25*.cnv") // parse options line argument getopt.Parse() // process bloc when option is set if *optHelp { getopt.Usage() os.Exit(0) } if *optVersion { fmt.Println(cfg.Progname + ": v" + cfg.Progversion) fmt.Printf("Environnement variable OCEANO2OCEANSITES: %s\n", os.Getenv("OCEANO2OCEANSITES")) fmt.Printf("Environnement variable ROSCOP: %s\n", os.Getenv("ROSCOP")) fmt.Printf("Configuration file: %s\n", fileconfig) fmt.Printf("Code ROSCOP file: %s\n", cfg.Roscopfile) fmt.Printf("GOPATH: %s\n", os.Getenv("GOPATH")) fmt.Printf("GOBIN: %s\n", os.Getenv("GOBIN")) os.Exit(0) } if *optDebug { debug = os.Stdout } if *optEcho { echo = os.Stdout } if *optAll { prefixAll = "-all" } // get files list from argument line // Args returns the non-option arguments. // see https://code.google.com/p/getopt/source/browse/set.go#27 if *optFiles == "" { files = getopt.Args() } else { files, _ = filepath.Glob(*optFiles) } // if no files supplied for arg list, test if files is empty if len(files) == 0 { getopt.Usage() fmt.Println("\nPlease, specify files to process or define --files options") os.Exit(0) } // if *optCycleMesure != "" { // fmt.Println(*optCycleMesure) // nc.Attributes["cycle_mesure"] = *optCycleMesure // } fmt.Fprintln(debug, "Arg files list: ", files) return files, *optCfgfile }
// main program func main() { // local variables var err error // parse commandline argiments getopt.Parse() // show help screen and exit in case of -h or --help option if *fHelp { getopt.Usage() os.Exit(1) } // look for mandatory positional arguments if getopt.NArgs() < 1 { log.Fatal("Nothing to do. Use -h for help.") } // by default, read server list from stdin ServerListFile := os.Stdin // read server names from file if a file name is supplied if *fFile != "" { ServerListFile, err = os.Open(*fFile) if err != nil { log.Fatal(fmt.Sprintf("ServerListFile: Error: %v", err)) } defer ServerListFile.Close() } AddrPadding, ServerList := LoadServerList(ServerListFile) // command to run on servers fCommand = getopt.Arg(0) // make new group group := &SshGroup{ Active: 0, Total: len(ServerList), Complete: 0, } // no point to display more processes than if *fProcs > group.Total { *fProcs = group.Total } // print heading text fmt.Fprintln(os.Stderr, "gssh - group ssh, ver. 0.6") fmt.Fprintln(os.Stderr, "(c)2014 Bozhin Zafirov <*****@*****.**>") fmt.Fprintln(os.Stderr) fmt.Fprintf(os.Stderr, " [*] read (%d) hosts from the list\n", group.Total) fmt.Fprintf(os.Stderr, " [*] executing '%s' as user '%s'\n", fCommand, *fUser) fmt.Fprintf(os.Stderr, " [*] spawning %d parallel ssh sessions\n\n", *fProcs) // spawn ssh processes for i, Server := range ServerList { ssh := &SshServer{ Username: *fUser, Address: Server, } group.Servers = append(group.Servers, ssh) // run command group.mu.Lock() group.Active++ group.mu.Unlock() go group.Command(ssh, AddrPadding, fCommand) // show progless after new process spawn group.UpdateProgress() if i < group.Total { // time delay and max procs wait between spawn time.Sleep(time.Duration(*fDelay) * time.Millisecond) group.Wait(*fProcs) } } // wait for ssh processes to exit group.Wait(0) group.mu.Lock() group.ClearProgress() group.mu.Unlock() // calculate stats var StdoutServersCount int var StderrServersCount int var AllServersCount int var StdoutLinesCount int var StderrLinesCount int var AllLinesCount int for _, ssh := range group.Servers { if ssh.StdoutLineCount > 0 { StdoutLinesCount += ssh.StdoutLineCount StdoutServersCount++ } if ssh.StderrLineCount > 0 { StderrLinesCount += ssh.StderrLineCount StderrServersCount++ } if ssh.StdoutLineCount > 0 || ssh.StderrLineCount > 0 { AllLinesCount += ssh.StdoutLineCount + ssh.StderrLineCount AllServersCount++ } } fmt.Fprintln(os.Stderr) fmt.Fprintf(os.Stderr, " Done. Processed: %d / Output: %d (%d) / \033[01;32m->\033[0m %d (%d) / \033[01;31m=>\033[0m %d (%d)\n", group.Total, AllServersCount, AllLinesCount, StdoutServersCount, StdoutLinesCount, StderrServersCount, StderrLinesCount, ) }