func ExitIfError(context string, err error) { if err != nil { say.Fprintln(os.Stderr, 0, say.Red(context)) say.Fprintln(os.Stderr, 0, say.Red(err.Error())) os.Exit(1) } }
func usageForCommandGroup(commandGroup common.CommandGroup, includeFlags bool) { say.Fprintln(os.Stderr, 0, "%s - %s", say.Cyan(commandGroup.Name), say.LightGray(commandGroup.Description)) say.Fprintln(os.Stderr, 0, strings.Repeat("-", len(commandGroup.Name)+3+len(commandGroup.Description))) for _, command := range commandGroup.Commands { usageForCommand(1, command, includeFlags) } }
func usage(commands []Command) { say.FprintBanner(os.Stderr, "Probe", "=") for _, command := range commands { say.Fprintln(os.Stderr, 0, "%s %s", say.Green(command.Name), say.LightGray(command.Description)) command.FlagSet.PrintDefaults() say.Fprintln(os.Stderr, 0, "") } }
func usageForCommand(indentation int, command common.Command, includeFlags bool) { say.Fprintln(os.Stderr, indentation, "%s %s", say.Green(command.Name), say.LightGray(command.Description)) if includeFlags { buffer := &bytes.Buffer{} command.FlagSet.SetOutput(buffer) command.FlagSet.PrintDefaults() say.Fprintln(os.Stderr, indentation, buffer.String()) } }
func SetDomainCommand() common.Command { var ( bbsConfig config_finder.BBSConfig ) flagSet := flag.NewFlagSet("set-domain", flag.ExitOnError) bbsConfig.PopulateFlags(flagSet) return common.Command{ Name: "set-domain", Description: "domain ttl - updates the domain in the BBS (ttl is a duration)", FlagSet: flagSet, Run: func(args []string) { bbsClient, err := config_finder.NewBBS(bbsConfig) common.ExitIfError("Could not construct BBS", err) if len(args) != 2 { say.Fprintln(os.Stderr, 0, say.Red("Expected domain and ttl")) os.Exit(1) } ttl, err := time.ParseDuration(args[1]) common.ExitIfError("Failed to parse TTL", err) err = set_domain.SetDomain(bbsClient, args[0], ttl) common.ExitIfError("Failed to submit lrp", err) }, } }
func GetDesiredLRPCommand() common.Command { var ( bbsConfig config_finder.BBSConfig ) flagSet := flag.NewFlagSet("get-desired-lrp", flag.ExitOnError) bbsConfig.PopulateFlags(flagSet) return common.Command{ Name: "get-desired-lrp", Description: "<process-guid> - get a DesiredLRP", FlagSet: flagSet, Run: func(args []string) { bbsClient, err := config_finder.NewBBS(bbsConfig) common.ExitIfError("Could not construct BBS", err) if len(args) == 0 { say.Fprintln(os.Stderr, 0, say.Red("missing process-guid")) os.Exit(1) } desiredLRP, err := bbsClient.DesiredLRPByProcessGuid(args[0]) common.ExitIfError("Failed to fetch DesiredLRP", err) preview, _ := json.MarshalIndent(desiredLRP, "", " ") say.Println(0, string(preview)) }, } }
func RemoveLRPCommand() common.Command { var ( bbsConfig config_finder.BBSConfig ) flagSet := flag.NewFlagSet("remove-lrp", flag.ExitOnError) bbsConfig.PopulateFlags(flagSet) return common.Command{ Name: "remove-lrp", Description: "<process-guid> - remove an lrp", FlagSet: flagSet, Run: func(args []string) { bbsClient, err := config_finder.NewBBS(bbsConfig) common.ExitIfError("Could not construct BBS", err) if len(args) == 0 { say.Fprintln(os.Stderr, 0, say.Red("You must specify a process-guid")) os.Exit(1) } else { err := bbsClient.RemoveDesiredLRP(args[0]) common.ExitIfError("Failed to remove lrp", err) } }, } }
func UpdateDesiredLRPCommand() common.Command { var ( bbsConfig config_finder.BBSConfig ) flagSet := flag.NewFlagSet("update-lrp", flag.ExitOnError) bbsConfig.PopulateFlags(flagSet) return common.Command{ Name: "update-lrp", Description: "<process-guid> <path to json file> - update a DesiredLRP", FlagSet: flagSet, Run: func(args []string) { bbsClient, err := config_finder.NewBBS(bbsConfig) common.ExitIfError("Could not construct BBS", err) var raw = []byte{} if len(args) == 0 { say.Fprintln(os.Stderr, 0, say.Red("missing process-guid")) os.Exit(1) } else if len(args) == 1 { say.Fprintln(os.Stderr, 0, "Reading from stdin...") raw, err = ioutil.ReadAll(os.Stdin) common.ExitIfError("Failed to read from stdin", err) } else { raw, err = ioutil.ReadFile(args[1]) common.ExitIfError("Failed to read from file", err) } desiredLRPUpdate := &models.DesiredLRPUpdate{} err = json.Unmarshal(raw, desiredLRPUpdate) common.ExitIfError("Failed to decode DesiredLRPUpdate", err) say.Println(0, "Updating %s:", args[0]) preview, _ := json.MarshalIndent(desiredLRPUpdate, "", " ") say.Println(0, string(preview)) err = bbsClient.UpdateDesiredLRP(args[0], desiredLRPUpdate) common.ExitIfError("Failed to update DesiredLRP", err) }, } }
func usage(commandGroups []common.CommandGroup) { if len(os.Args) > 2 { matcher := strings.ToLower(os.Args[2]) for _, commandGroup := range commandGroups { if strings.HasPrefix(strings.ToLower(commandGroup.Name), matcher) { usageForCommandGroup(commandGroup, true) return } for _, command := range commandGroup.Commands { if strings.HasPrefix(strings.ToLower(command.Name), matcher) { usageForCommand(0, command, true) return } } } say.Fprintln(os.Stderr, 0, say.Red("Unkown command: %s", os.Args[2])) } say.Fprintln(os.Stderr, 0, "%s", say.Cyan("Help and Autocompletion")) say.Fprintln(os.Stderr, 0, strings.Repeat("-", len("Help and Autocompletion"))) say.Fprintln(os.Stderr, 1, "%s %s", say.Green("help"), say.LightGray("[command] - Show this help, or detailed help for the passed in command")) say.Fprintln(os.Stderr, 1, "%s %s", say.Green("completions"), say.LightGray("Generate BASH Completions for veritas")) say.Fprintln(os.Stderr, 0, "") for _, commandGroup := range commandGroups { usageForCommandGroup(commandGroup, false) say.Println(0, "") } }
func GetActualLRPCommand() common.Command { var ( bbsConfig config_finder.BBSConfig ) flagSet := flag.NewFlagSet("get-actual-lrp", flag.ExitOnError) bbsConfig.PopulateFlags(flagSet) return common.Command{ Name: "get-actual-lrp", Description: "<process-guid> <optional: index> - get an ActualLRP", FlagSet: flagSet, Run: func(args []string) { bbsClient, err := config_finder.NewBBS(bbsConfig) common.ExitIfError("Could not construct BBS", err) var index = -1 if len(args) == 0 { say.Fprintln(os.Stderr, 0, say.Red("missing process-guid")) os.Exit(1) } processGuid := args[0] if len(args) == 2 { index, err = strconv.Atoi(args[1]) common.ExitIfError("Could not parse index", err) } if index == -1 { actualLRPGroups, err := bbsClient.ActualLRPGroupsByProcessGuid(processGuid) common.ExitIfError("Could not fetch ActualLRPs", err) for _, actualLRPGroup := range actualLRPGroups { actualLRP, _ := actualLRPGroup.Resolve() preview, _ := json.MarshalIndent(actualLRP, "", " ") say.Println(0, string(preview)) } } else { actualLRPGroup, err := bbsClient.ActualLRPGroupByProcessGuidAndIndex(processGuid, index) common.ExitIfError("Could not fetch ActualLRP", err) actualLRP, _ := actualLRPGroup.Resolve() preview, _ := json.MarshalIndent(actualLRP, "", " ") say.Println(0, string(preview)) } }, } }
func CreateDesiredLRPCommand() common.Command { var ( bbsConfig config_finder.BBSConfig ) flagSet := flag.NewFlagSet("desire-lrp", flag.ExitOnError) bbsConfig.PopulateFlags(flagSet) return common.Command{ Name: "desire-lrp", Description: "<path to json file> - create a DesiredLRP", FlagSet: flagSet, Run: func(args []string) { bbsClient, err := config_finder.NewBBS(bbsConfig) common.ExitIfError("Could not construct BBS", err) var raw = []byte{} if len(args) == 0 { say.Fprintln(os.Stderr, 0, "Reading from stdin...") raw, err = ioutil.ReadAll(os.Stdin) common.ExitIfError("Failed to read from stdin", err) } else { raw, err = ioutil.ReadFile(args[0]) common.ExitIfError("Failed to read from file", err) } desiredLRP := &models.DesiredLRP{} err = json.Unmarshal(raw, desiredLRP) common.ExitIfError("Failed to decode DesiredLRP", err) say.Println(0, "Desiring:") preview, _ := json.MarshalIndent(desiredLRP, "", " ") say.Println(0, string(preview)) err = bbsClient.DesireLRP(desiredLRP) common.ExitIfError("Failed to desire DesiredLRP", err) }, } }
func Autodetect(out io.Writer) error { jobs, err := ioutil.ReadDir("/var/vcap/jobs") if err != nil { return err } vitalsAddrs := []string{} gardenAddr := "" gardenNetwork := "" bbsEndpoint := "" debugRe := regexp.MustCompile(`debugAddr=(\d+.\d+.\d+.\d+:\d+)`) gardenTCPAddrRe := regexp.MustCompile(`gardenAddr=(\d+.\d+.\d+.\d+:\d+)`) gardenUnixAddrRe := regexp.MustCompile(`gardenAddr=([/\-\w+\.\d]+)`) bbsEndpointRe := regexp.MustCompile(`bbsAddress=([:/\-\w+\.\d]+)`) for _, job := range jobs { jobDir := filepath.Join("/var/vcap/jobs", job.Name(), "bin") ctls, err := ioutil.ReadDir(jobDir) if err != nil { return err } for _, ctl := range ctls { if ctl.IsDir() { continue } if strings.HasSuffix(ctl.Name(), "_ctl") { name := strings.TrimSuffix(ctl.Name(), "_ctl") path := filepath.Join(jobDir, ctl.Name()) data, err := ioutil.ReadFile(path) if err != nil { return err } if debugRe.Match(data) { addr := string(debugRe.FindSubmatch(data)[1]) vitalsAddrs = append(vitalsAddrs, fmt.Sprintf("%s:%s", name, addr)) } if name == "rep" { if gardenTCPAddrRe.Match(data) { gardenAddr = string(gardenTCPAddrRe.FindSubmatch(data)[1]) gardenNetwork = "tcp" } else if gardenUnixAddrRe.Match(data) { gardenAddr = string(gardenUnixAddrRe.FindSubmatch(data)[1]) gardenNetwork = "unix" } if bbsEndpointRe.Match(data) { bbsEndpoint = string(bbsEndpointRe.FindSubmatch(data)[1]) } } } } } if len(vitalsAddrs) > 0 { say.Fprintln(out, 0, "export VITALS_ADDRS=%s", strings.Join(vitalsAddrs, ",")) } if gardenAddr != "" { say.Fprintln(out, 0, "export GARDEN_ADDR=%s", gardenAddr) say.Fprintln(out, 0, "export GARDEN_NETWORK=%s", gardenNetwork) } if bbsEndpoint != "" { say.Fprintln(out, 0, "export BBS_ENDPOINT=%s", bbsEndpoint) } return nil }
func printContainer(out io.Writer, containerInfo ContainerInfo) { info := containerInfo.Info metrics := containerInfo.Metrics say.Fprintln(out, 0, "%s - %s @ %s", say.Green(containerInfo.Handle), info.State, info.ContainerPath, ) say.Fprintln(out, 1, "Memory: %.3f MB", float64(metrics.MemoryStat.TotalRss+metrics.MemoryStat.TotalCache-metrics.MemoryStat.TotalInactiveFile)/1024.0/1024.0, ) say.Fprintln(out, 1, "Disk: Total:%.3f MB %d Inodes, Exclusive:%.3f MB %d Inodes", float64(metrics.DiskStat.TotalBytesUsed)/1024.0/1024.0, metrics.DiskStat.TotalInodesUsed, float64(metrics.DiskStat.ExclusiveBytesUsed)/1024.0/1024.0, metrics.DiskStat.ExclusiveInodesUsed, ) ports := []string{} for _, portMapping := range info.MappedPorts { ports = append(ports, fmt.Sprintf("%d:%d", portMapping.HostPort, portMapping.ContainerPort)) } say.Fprintln(out, 1, "%s=>%s: %s", say.Green(info.HostIP), say.Green(containerInfo.Handle), strings.Join(ports, ","), ) if len(info.Events) > 0 { say.Fprintln(out, 1, "Events: %s", strings.Join(info.Events, ","), ) } if len(info.ProcessIDs) > 0 { say.Fprintln(out, 1, "Running: %d processes", len(info.ProcessIDs), ) } if len(info.Properties) > 0 { say.Fprintln(out, 1, "Properties:", ) for key, value := range info.Properties { say.Fprintln(out, 2, "%s: %s", key, value, ) } } }