// GetSite is @@@ func (c *CLI) GetSite(ctx *cli.Context) *gondor.Site { var err error var siteName string var resourceGroup *gondor.ResourceGroup api := c.GetAPIClient(ctx) siteFlag := ctx.GlobalString("site") if siteFlag != "" { if strings.Count(siteFlag, "/") == 1 { parts := strings.Split(siteFlag, "/") resourceGroup, err = api.ResourceGroups.GetByName(parts[0]) if err != nil { fatal(err.Error()) } siteName = parts[1] } else { resourceGroup = c.GetResourceGroup(ctx) siteName = siteFlag } } else { LoadSiteConfig() resourceGroup = c.GetResourceGroup(ctx) _, siteName = parseSiteIdentifier(siteCfg.Identifier) } site, err := api.Sites.Get(siteName, &*resourceGroup.URL) if err != nil { fatal(err.Error()) } return site }
// mkCommandFunc executes the "mk" command. func mkCommandFunc(c *cli.Context, ki client.KeysAPI) { if len(c.Args()) == 0 { handleError(c, ExitBadArgs, errors.New("key required")) } key := c.Args()[0] value, err := argOrStdin(c.Args(), os.Stdin, 1) if err != nil { handleError(c, ExitBadArgs, errors.New("value required")) } ttl := c.Int("ttl") inorder := c.Bool("in-order") var resp *client.Response ctx, cancel := contextWithTotalTimeout(c) if !inorder { // Since PrevNoExist means that the Node must not exist previously, // this Set method always creates a new key. Therefore, mk command // succeeds only if the key did not previously exist, and the command // prevents one from overwriting values accidentally. resp, err = ki.Set(ctx, key, value, &client.SetOptions{TTL: time.Duration(ttl) * time.Second, PrevExist: client.PrevNoExist}) } else { // If in-order flag is specified then create an inorder key under // the directory identified by the key argument. resp, err = ki.CreateInOrder(ctx, key, value, &client.CreateInOrderOptions{TTL: time.Duration(ttl) * time.Second}) } cancel() if err != nil { handleError(c, ExitServerError, err) } printResponseKey(resp, c.GlobalString("output")) }
// GetResourceGroup is @@@ func (c *CLI) GetResourceGroup(ctx *cli.Context) *gondor.ResourceGroup { api := c.GetAPIClient(ctx) if ctx.GlobalString("resource-group") != "" { resourceGroup, err := api.ResourceGroups.GetByName(ctx.GlobalString("resource-group")) if err != nil { fatal(err.Error()) } return resourceGroup } if err := LoadSiteConfig(); err == nil { resourceGroupName, _ := parseSiteIdentifier(siteCfg.Identifier) resourceGroup, err := api.ResourceGroups.GetByName(resourceGroupName) if err != nil { fatal(err.Error()) } return resourceGroup } else if _, ok := err.(ErrConfigNotFound); !ok { fatal(fmt.Sprintf("failed to load gondor.yml\n%s", err.Error())) } user, err := api.AuthenticatedUser() if err != nil { fatal(err.Error()) } if user.ResourceGroup == nil { fatal("you do not have a personal resource group.") } return user.ResourceGroup }
func cmdSearch(c *cli.Context) error { conf, err := config.Open(c.GlobalString("config")) if err != nil { Logger.Fatalf("Cannot load configuration: %v", err) return nil } needle := c.Args()[0] found := []*config.Host{} for _, host := range conf.Hosts.SortedList() { if host.Matches(needle) { found = append(found, host) } } if len(found) == 0 { fmt.Println("no results found.") return nil } fmt.Printf("Listing results for %s:\n", needle) for _, host := range found { fmt.Printf(" %s -> %s\n", host.Name(), host.Prototype()) } return nil }
func getGossConfig(c *cli.Context) GossConfig { // handle stdin var fh *os.File var err error var path, source string specFile := c.GlobalString("gossfile") if specFile == "-" { source = "STDIN" fh = os.Stdin } else { source = specFile path = filepath.Dir(specFile) fh, err = os.Open(specFile) if err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } } data, err := ioutil.ReadAll(fh) if err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } gossConfig := mergeJSONData(ReadJSONData(data), 0, path) if len(gossConfig.Resources()) == 0 { fmt.Printf("Error: found 0 tests, source: %v\n", source) os.Exit(1) } return gossConfig }
func newClient(c *cli.Context) (client.Client, error) { eps, err := getEndpoints(c) if err != nil { return nil, err } tr, err := getTransport(c) if err != nil { return nil, err } cfg := client.Config{ Transport: tr, Endpoints: eps, HeaderTimeoutPerRequest: c.GlobalDuration("timeout"), } uFlag := c.GlobalString("username") if uFlag == "" { uFlag = os.Getenv("ETCDCTL_USERNAME") } if uFlag != "" { username, password, err := getUsernamePasswordFromFlag(uFlag) if err != nil { return nil, err } cfg.Username = username cfg.Password = password } return client.New(cfg) }
// getConfigFilename gets the absolute filename of the config file specified by // the ConfigFilename flag, and whether it exists. // // If the ConfigFilename exists, then it is returned as an absolute path. // If neither of those exist, the absolute ConfigFilename is returned. func getConfigFilename(context *cli.Context) (string, bool) { cf := context.GlobalString("config-filename") if filepath.IsAbs(cf) { // Absolute path specified; user knows what they want. _, err := os.Stat(cf) return cf, err == nil } absCF, err := filepath.Abs(cf) if err != nil { // syscall failure; treat as if file doesn't exist. return cf, false } if _, err := os.Stat(absCF); err == nil { // File exists on relative path. return absCF, true } // Check for config file on path relative to executable. exeFile := os.Args[0] exeDir := filepath.Dir(exeFile) absCF = filepath.Join(exeDir, cf) if _, err := os.Stat(absCF); err == nil { return absCF, true } // This is probably what the user expects if it wasn't found anywhere else. return absCF, false }
func newCache(c *cli.Context, client *doarama.Client) (doaramacache.ActivityCreator, error) { dataSourceName := c.GlobalString("cache") if dataSourceName == "" { return client, nil } return doaramacache.NewSQLite3(dataSourceName, client) }
func startNATSServer(context *cli.Context) (e *stand.StanServer, err error) { eventsURL, err := url.Parse(context.GlobalString("events-address")) if err != nil { return nil, err } no := stand.DefaultNatsServerOptions nOpts := &no nOpts.NoSigs = true parts := strings.Split(eventsURL.Host, ":") nOpts.Host = parts[0] if len(parts) == 2 { nOpts.Port, err = strconv.Atoi(parts[1]) } else { nOpts.Port = nats.DefaultPort } defer func() { if r := recover(); r != nil { e = nil if _, ok := r.(error); !ok { err = fmt.Errorf("failed to start NATS server: %v", r) } else { err = r.(error) } } }() s := stand.RunServerWithOpts(nil, nOpts) return s, nil }
func cmdInfo(c *cli.Context) error { conf, err := config.Open(c.GlobalString("config")) if err != nil { Logger.Fatalf("Cannot load configuration: %v", err) return nil } fmt.Printf("Debug mode (client): %v\n", os.Getenv("ASSH_DEBUG") == "1") cliPath, _ := osext.Executable() fmt.Printf("CLI Path: %s\n", cliPath) fmt.Printf("Go version: %s\n", runtime.Version()) fmt.Printf("OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH) fmt.Println("") fmt.Printf("RC files:\n") homeDir := utils.GetHomeDir() for _, filename := range conf.IncludedFiles() { relativeFilename := strings.Replace(filename, homeDir, "~", -1) fmt.Printf("- %s\n", relativeFilename) } fmt.Println("") fmt.Println("Statistics:") fmt.Printf("- %d hosts\n", len(conf.Hosts)) fmt.Printf("- %d templates\n", len(conf.Templates)) fmt.Printf("- %d included files\n", len(conf.IncludedFiles())) // FIXME: print info about connections/running processes // FIXME: print info about current config file version return nil }
// getConfigFilename gets the absolute filename of the config file specified by // the ConfigFilename flag, and whether it exists. // // If the (relative or absolute) ConfigFilename exists, then it is returned. // If the ConfigFilename exists in a valid XDG path, then it is returned. // If neither of those exist, the (relative or absolute) ConfigFilename is returned. func getConfigFilename(context *cli.Context) (string, bool) { cf := context.GlobalString("config-filename") if filepath.IsAbs(cf) { // Absolute path specified; user knows what they want. _, err := os.Stat(cf) return cf, err == nil } absCF, err := filepath.Abs(cf) if err != nil { // syscall failure; treat as if file doesn't exist. return cf, false } if _, err := os.Stat(absCF); err == nil { // File exists on relative path. return absCF, true } if xdgCF, err := xdg.Config.Find(cf); err == nil { // File exists in an XDG directory. return xdgCF, true } // Default to relative path. This is probably what the user expects if // it wasn't found anywhere else. return absCF, false }
func cmdWrapper(c *cli.Context) error { if len(c.Args()) < 1 { Logger.Fatalf("Missing <target> argument. See usage with 'assh wrapper %s -h'.", c.Command.Name) } // prepare variables target := c.Args()[0] command := c.Args()[1:] options := []string{} for _, flag := range config.SSHBoolFlags { if c.Bool(flag) { options = append(options, fmt.Sprintf("-%s", flag)) } } for _, flag := range config.SSHStringFlags { if val := c.String(flag); val != "" { options = append(options, fmt.Sprintf("-%s", flag)) options = append(options, val) } } args := []string{c.Command.Name} args = append(args, options...) args = append(args, target) args = append(args, command...) bin, err := exec.LookPath(c.Command.Name) if err != nil { Logger.Fatalf("Cannot find %q in $PATH", c.Command.Name) } Logger.Debugf("Wrapper called with bin=%v target=%v command=%v options=%v, args=%v", bin, target, command, options, args) // check if config is up-to-date conf, err := config.Open(c.GlobalString("config")) if err != nil { Logger.Fatalf("Cannot open configuration file: %v", err) } if err = conf.LoadKnownHosts(); err != nil { Logger.Debugf("Failed to load assh known_hosts: %v", err) } // check if .ssh/config is outdated isOutdated, err := conf.IsConfigOutdated(target) if err != nil { Logger.Error(err) } if isOutdated { Logger.Debugf("The configuration file is outdated, rebuilding it before calling %s", c.Command.Name) if err = conf.SaveSSHConfig(); err != nil { Logger.Error(err) } } // Execute Binary syscall.Exec(bin, args, os.Environ()) return nil }
func (summary *CatalogEntitySummary) Display(c *cli.Context) (err error) { if json := c.GlobalString("json"); json != "" { displayAsJson(summary, json) } else { summary.displayAsTable() } return err }
func before(c *cli.Context) error { if client == nil { var err error client, err = tmspcli.NewClient(c.GlobalString("address"), c.GlobalString("tmsp"), false) if err != nil { Exit(err.Error()) } } return nil }
func before(context *cli.Context) error { logLevelString := context.GlobalString("log-level") logLevel, err := logrus.ParseLevel(logLevelString) if err != nil { logrus.Fatalf(err.Error()) } logrus.SetLevel(logLevel) return nil }
func parseWriter(c *cli.Context) io.Writer { outputFilename := c.GlobalString("output") if outputFilename != "" { f, err := os.Create(outputFilename) exitOnError(err) return f } return os.Stdout }
func getDiscoveryDomain(c *cli.Context) (domainstr string, insecure bool) { domainstr = c.GlobalString("discovery-srv") // Use an environment variable if nothing was supplied on the // command line if domainstr == "" { domainstr = os.Getenv("ETCDCTL_DISCOVERY_SRV") } insecure = c.GlobalBool("insecure-discovery") || (os.Getenv("ETCDCTL_INSECURE_DISCOVERY") != "") return domainstr, insecure }
// Populate updates the specified project context based on command line arguments and subcommands. func Populate(context *project.Context, c *cli.Context) { context.ComposeFiles = c.GlobalStringSlice("file") if len(context.ComposeFiles) == 0 { context.ComposeFiles = []string{"docker-compose.yml"} if _, err := os.Stat("docker-compose.override.yml"); err == nil { context.ComposeFiles = append(context.ComposeFiles, "docker-compose.override.yml") } } context.ProjectName = c.GlobalString("project-name") }
func getContainers(context *cli.Context) ([]containerState, error) { factory, err := loadFactory(context) if err != nil { return nil, err } root := context.GlobalString("root") absRoot, err := filepath.Abs(root) if err != nil { return nil, err } list, err := ioutil.ReadDir(absRoot) if err != nil { fatal(err) } var s []containerState for _, item := range list { if item.IsDir() { container, err := factory.Load(item.Name()) if err != nil { fmt.Fprintf(os.Stderr, "load container %s: %v\n", item.Name(), err) continue } containerStatus, err := container.Status() if err != nil { fmt.Fprintf(os.Stderr, "status for %s: %v\n", item.Name(), err) continue } state, err := container.State() if err != nil { fmt.Fprintf(os.Stderr, "state for %s: %v\n", item.Name(), err) continue } pid := state.BaseState.InitProcessPid if containerStatus == libcontainer.Stopped { pid = 0 } bundle, annotations := utils.Annotations(state.Config.Labels) s = append(s, containerState{ Version: state.BaseState.Config.Version, ID: state.BaseState.ID, InitProcessPid: pid, Status: containerStatus.String(), Bundle: bundle, Rootfs: state.BaseState.Config.Rootfs, Created: state.BaseState.Created, Annotations: annotations, }) } } return s, nil }
func getNATSPublisher(context *cli.Context) (*nats.EncodedConn, error) { nc, err := nats.Connect(context.GlobalString("events-address")) if err != nil { return nil, err } nec, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER) if err != nil { nc.Close() return nil, err } return nec, nil }
// printLs writes a response out in a manner similar to the `ls` command in unix. // Non-empty directories list their contents and files list their name. func printLs(c *cli.Context, resp *client.Response) { if c.GlobalString("output") == "simple" { if !resp.Node.Dir { fmt.Println(resp.Node.Key) } for _, node := range resp.Node.Nodes { rPrint(c, node) } } else { // user wants JSON or extended output printResponseKey(resp, c.GlobalString("output")) } }
// NewAuthenticatedDoaramaOptions returns the doaram.Options for an // authenticated doarama.Client from c. func NewAuthenticatedDoaramaOptions(c *cli.Context) ([]doarama.Option, error) { options := BaseDoaramaOptions(c) userID := c.GlobalString("userid") userKey := c.GlobalString("userkey") switch { case userID != "" && userKey == "": options = append(options, doarama.Anonymous(userID)) case userID == "" && userKey != "": options = append(options, doarama.Delegate(userKey)) default: return nil, errors.New("exactly one of -userid and -userkey must be specified") } return options, nil }
func getClientConn(ctx *cli.Context) *grpc.ClientConn { // TODO(roasbeef): macaroon based auth // * http://www.grpc.io/docs/guides/auth.html // * http://research.google.com/pubs/pub41892.html // * https://github.com/go-macaroon/macaroon opts := []grpc.DialOption{grpc.WithInsecure()} conn, err := grpc.Dial(ctx.GlobalString("rpcserver"), opts...) if err != nil { fatal(err) } return conn }
// loadFactory returns the configured factory instance for execing containers. func loadFactory(context *cli.Context) (libcontainer.Factory, error) { root := context.GlobalString("root") abs, err := filepath.Abs(root) if err != nil { return nil, err } cgroupManager := libcontainer.Cgroupfs if context.GlobalBool("systemd-cgroup") { if systemd.UseSystemd() { cgroupManager = libcontainer.SystemdCgroups } else { return nil, fmt.Errorf("systemd cgroup flag passed, but systemd support for managing cgroups is not available") } } return libcontainer.New(abs, cgroupManager, libcontainer.CriuPath(context.GlobalString("criu"))) }
// updatedirCommandFunc executes the "updatedir" command. func updatedirCommandFunc(c *cli.Context, ki client.KeysAPI) { if len(c.Args()) == 0 { handleError(c, ExitBadArgs, errors.New("key required")) } key := c.Args()[0] ttl := c.Int("ttl") ctx, cancel := contextWithTotalTimeout(c) resp, err := ki.Set(ctx, key, "", &client.SetOptions{TTL: time.Duration(ttl) * time.Second, Dir: true, PrevExist: client.PrevExist}) cancel() if err != nil { handleError(c, ExitServerError, err) } if c.GlobalString("output") != "simple" { printResponseKey(resp, c.GlobalString("output")) } }
// detectPackage adds the correct package creation function to a System struct func (sys *System) detectPackage(c *cli.Context) { p := c.GlobalString("package") if p != "deb" && p != "apk" && p != "pacman" && p != "rpm" { p = DetectPackageManager() } switch p { case "deb": sys.NewPackage = NewDebPackage case "apk": sys.NewPackage = NewAlpinePackage case "pacman": sys.NewPackage = NewPacmanPackage default: sys.NewPackage = NewRpmPackage } }
// rmdirCommandFunc executes the "rmdir" command. func rmdirCommandFunc(c *cli.Context, ki client.KeysAPI) { if len(c.Args()) == 0 { handleError(ExitBadArgs, errors.New("key required")) } key := c.Args()[0] ctx, cancel := contextWithTotalTimeout(c) resp, err := ki.Delete(ctx, key, &client.DeleteOptions{Dir: true}) cancel() if err != nil { handleError(ExitServerError, err) } if !resp.Node.Dir { printResponseKey(resp, c.GlobalString("output")) } }
func handleError(c *cli.Context, code int, err error) { if c.GlobalString("output") == "json" { if err, ok := err.(*client.Error); ok { b, err := json.Marshal(err) if err != nil { panic(err) } fmt.Fprintln(os.Stderr, string(b)) os.Exit(code) } } fmt.Fprintln(os.Stderr, "Error: ", err) if cerr, ok := err.(*client.ClusterError); ok { fmt.Fprintln(os.Stderr, cerr.Detail()) } os.Exit(code) }
func parseQuery(c *cli.Context) (string, error) { filename := c.GlobalString("file") if filename != "" { query, err := ioutil.ReadFile(filename) return string(query), err } command := c.GlobalString("command") if command != "" { return command, nil } if !termutil.Isatty(os.Stdin.Fd()) { query, err := ioutil.ReadAll(os.Stdin) return string(query), err } return "", errors.New("You need to specify a SQL query.") }
func getContainers(context *cli.Context) ([]containerState, error) { factory, err := loadFactory(context) if err != nil { return nil, err } root := context.GlobalString("root") absRoot, err := filepath.Abs(root) if err != nil { return nil, err } list, err := ioutil.ReadDir(absRoot) if err != nil { fatal(err) } var s []containerState for _, item := range list { if item.IsDir() { container, err := factory.Load(item.Name()) if err != nil { return nil, err } containerStatus, err := container.Status() if err != nil { return nil, err } state, err := container.State() if err != nil { return nil, err } bundle, annotations := utils.Annotations(state.Config.Labels) s = append(s, containerState{ ID: state.BaseState.ID, InitProcessPid: state.BaseState.InitProcessPid, Status: containerStatus.String(), Bundle: bundle, Created: state.BaseState.Created, Annotations: annotations, }) } } return s, nil }