func cmdSSLDelete(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } if len(c.Args()) != 1 { stdcli.Usage(c, "delete") return } target := c.Args()[0] parts := strings.Split(target, ":") if len(parts) != 2 { stdcli.Error(fmt.Errorf("target must be process:port")) return } fmt.Printf("Deleting SSL listener %s... ", target) _, err = rackClient(c).DeleteSSL(app, parts[0], parts[1]) if err != nil { stdcli.Error(err) return } fmt.Println("Done.") }
func cmdPsInfo(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } if len(c.Args()) != 1 { stdcli.Usage(c, "info") return } id := c.Args()[0] p, err := rackClient(c).GetProcess(app, id) if err != nil { stdcli.Error(err) return } fmt.Printf("Id %s\n", p.Id) fmt.Printf("Name %s\n", p.Name) fmt.Printf("Release %s\n", p.Release) fmt.Printf("Size %d\n", p.Size) fmt.Printf("CPU %0.2f%%\n", p.Cpu) fmt.Printf("Memory %0.2f%%\n", p.Memory*100) fmt.Printf("Started %s\n", humanizeTime(p.Started)) fmt.Printf("Command %s\n", p.Command) }
func cmdReleasePromote(c *cli.Context) { if len(c.Args()) < 1 { stdcli.Usage(c, "release promote") return } release := c.Args()[0] _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } fmt.Printf("Promoting %s... ", release) _, err = rackClient(c).PromoteRelease(app, release) if err != nil { stdcli.Error(err) return } fmt.Println("UPDATING") }
func cmdInit(c *cli.Context) { wd := "." if len(c.Args()) > 0 { wd = c.Args()[0] } dir, _, err := stdcli.DirApp(c, wd) if err != nil { stdcli.Error(err) return } changed, err := manifest.Init(dir) if err != nil { stdcli.Error(err) return } if len(changed) > 0 { fmt.Printf("Generated: %s\n", strings.Join(changed, ", ")) } }
func cmdPs(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } ps, err := rackClient(c).GetProcesses(app, c.Bool("stats")) if err != nil { stdcli.Error(err) return } if c.Bool("stats") { t := stdcli.NewTable("ID", "NAME", "RELEASE", "SIZE", "CPU", "MEM", "STARTED", "COMMAND") for _, p := range ps { t.AddRow(prettyId(p), p.Name, p.Release, fmt.Sprintf("%d", p.Size), fmt.Sprintf("%0.2f%%", p.Cpu), fmt.Sprintf("%0.2f%%", p.Memory*100), humanizeTime(p.Started), p.Command) } t.Print() } else { t := stdcli.NewTable("ID", "NAME", "RELEASE", "SIZE", "STARTED", "COMMAND") for _, p := range ps { t.AddRow(prettyId(p), p.Name, p.Release, fmt.Sprintf("%d", p.Size), humanizeTime(p.Started), p.Command) } t.Print() } }
func cmdAppCreate(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } if len(c.Args()) > 0 { app = c.Args()[0] } if app == "" { stdcli.Error(fmt.Errorf("must specify an app name")) return } fmt.Printf("Creating app %s... ", app) _, err = rackClient(c).CreateApp(app) if err != nil { stdcli.Error(err) return } fmt.Println("CREATING") }
func cmdPsStop(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } if len(c.Args()) != 1 { stdcli.Usage(c, "stop") return } id := c.Args()[0] fmt.Printf("Stopping %s... ", id) _, err = rackClient(c).StopProcess(app, id) if err != nil { stdcli.Error(err) return } fmt.Println("OK") }
func cmdRackParamsSet(c *cli.Context) { system, err := rackClient(c).GetSystem() if err != nil { stdcli.Error(err) return } params := map[string]string{} for _, arg := range c.Args() { parts := strings.SplitN(arg, "=", 2) if len(parts) != 2 { stdcli.Error(fmt.Errorf("invalid argument: %s", arg)) return } params[parts[0]] = parts[1] } fmt.Print("Updating parameters... ") err = rackClient(c).SetParameters(system.Name, params) if err != nil { stdcli.Error(err) return } fmt.Println("OK") }
func executeBuildDir(c *cli.Context, dir, app, manifest, description string) (string, error) { dir, err := filepath.Abs(dir) if err != nil { return "", err } fmt.Print("Creating tarball... ") tar, err := createTarball(dir) if err != nil { return "", err } fmt.Println("OK") cache := !c.Bool("no-cache") fmt.Print("Uploading... ") build, err := rackClient(c).CreateBuildSource(app, tar, cache, manifest, description) if err != nil { return "", err } fmt.Println("OK") return finishBuild(c, app, build) }
func cmdReleaseInfo(c *cli.Context) { if len(c.Args()) < 1 { stdcli.Usage(c, "release info") return } release := c.Args()[0] _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } r, err := rackClient(c).GetRelease(app, release) if err != nil { stdcli.Error(err) return } fmt.Printf("Id %s\n", r.Id) fmt.Printf("Build %s\n", r.Build) fmt.Printf("Created %s\n", r.Created) fmt.Printf("Env ") fmt.Println(strings.Replace(r.Env, "\n", "\n ", -1)) }
func cmdScale(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } count := c.String("count") memory := c.String("memory") if len(c.Args()) == 0 && count == "" && memory == "" { displayFormation(c, app) return } if len(c.Args()) != 1 || (count == "" && memory == "") { stdcli.Usage(c, "scale") return } process := c.Args()[0] err = rackClient(c).SetFormation(app, process, count, memory) if err != nil { stdcli.Error(err) return } displayFormation(c, app) }
func cmdEnvList(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } if len(c.Args()) > 0 { stdcli.Error(fmt.Errorf("`convox env` does not take arguments. Perhaps you meant `convox env set`?")) } env, err := rackClient(c).GetEnvironment(app) if err != nil { stdcli.Error(err) return } keys := []string{} for key, _ := range env { keys = append(keys, key) } sort.Strings(keys) for _, key := range keys { fmt.Printf("%s=%s\n", key, env[key]) } }
// If user specifies the app's name from command line, then use it; // if not, try to read the app name from .convox/app // otherwise use the current working directory's name func DirApp(c *cli.Context, wd string) (string, string, error) { abs, err := filepath.Abs(wd) if err != nil { return "", "", err } app := c.String("app") if app == "" { app, err = ReadSetting("app") if err != nil { app = "" } } if app == "" { app = path.Base(abs) } app = strings.ToLower(app) return abs, app, nil }
func cmdRackUpdate(c *cli.Context) { versions, err := version.All() if err != nil { stdcli.Error(err) return } specified := "stable" if len(c.Args()) > 0 { specified = c.Args()[0] } version, err := versions.Resolve(specified) if err != nil { stdcli.Error(err) return } system, err := rackClient(c).UpdateSystem(version.Version) if err != nil { stdcli.Error(err) return } fmt.Printf("Name %s\n", system.Name) fmt.Printf("Status %s\n", system.Status) fmt.Printf("Version %s\n", system.Version) fmt.Printf("Count %d\n", system.Count) fmt.Printf("Type %s\n", system.Type) }
func cmdRackReleases(c *cli.Context) { vs, err := version.All() if err != nil { return } selected := version.Versions{} for _, v := range vs { switch { case !v.Published && c.Bool("unpublished"): selected = append(selected, v) case v.Published: selected = append(selected, v) } } sort.Sort(sort.Reverse(selected)) if len(selected) > 20 { selected = selected[0:20] } for _, v := range selected { fmt.Println(v.Version) } }
func cmdServiceInfo(c *cli.Context) { if len(c.Args()) != 1 { stdcli.Usage(c, "info") return } name := c.Args()[0] service, err := rackClient(c).GetService(name) if err != nil { stdcli.Error(err) return } fmt.Printf("Name %s\n", service.Name) fmt.Printf("Status %s\n", service.Status) if service.Status == "failed" { fmt.Printf("Reason %s\n", service.StatusReason) } if len(service.Exports) > 0 { fmt.Printf("Exports\n") for key, value := range service.Exports { fmt.Printf(" %s: %s\n", key, value) } } else if service.URL != "" { // NOTE: this branch is deprecated fmt.Printf("URL %s\n", service.URL) } }
func readCredentials(c *cli.Context) (creds *AwsCredentials, err error) { // read credentials from ENV creds = &AwsCredentials{ Access: os.Getenv("AWS_ACCESS_KEY_ID"), Secret: os.Getenv("AWS_SECRET_ACCESS_KEY"), Session: os.Getenv("AWS_SESSION_TOKEN"), } if os.Getenv("AWS_ENDPOINT_URL") != "" { url := os.Getenv("AWS_ENDPOINT_URL") defaults.DefaultConfig.Endpoint = &url } var inputCreds *AwsCredentials if len(c.Args()) > 0 { fileName := c.Args()[0] inputCreds, err = readCredentialsFromFile(fileName) } else if !terminal.IsTerminal(int(os.Stdin.Fd())) { inputCreds, err = readCredentialsFromSTDIN() } if inputCreds != nil { creds = inputCreds } if err != nil { return nil, err } if creds.Access == "" || creds.Secret == "" { reader := bufio.NewReader(os.Stdin) fmt.Println(CredentialsMessage) fmt.Print("AWS Access Key ID: ") creds.Access, err = reader.ReadString('\n') if err != nil { return creds, err } fmt.Print("AWS Secret Access Key: ") creds.Secret, err = reader.ReadString('\n') if err != nil { return creds, err } fmt.Println("") } creds.Access = strings.TrimSpace(creds.Access) creds.Secret = strings.TrimSpace(creds.Secret) creds.Session = strings.TrimSpace(creds.Session) return }
func cmdProxy(c *cli.Context) { if len(c.Args()) == 0 { stdcli.Usage(c, "proxy") } for _, arg := range c.Args() { parts := strings.SplitN(arg, ":", 3) var host string var port, hostport int switch len(parts) { case 2: host = parts[0] p, err := strconv.Atoi(parts[1]) if err != nil { stdcli.Error(err) return } port = p hostport = p case 3: host = parts[1] p, err := strconv.Atoi(parts[0]) if err != nil { stdcli.Error(err) return } port = p p, err = strconv.Atoi(parts[2]) if err != nil { stdcli.Error(err) return } hostport = p default: stdcli.Error(fmt.Errorf("invalid argument: %s", arg)) return } go proxy(port, host, hostport, rackClient(c)) } // block forever select {} }
func executeBuildUrl(c *cli.Context, url string, app string, config string) (string, error) { cache := !c.Bool("no-cache") build, err := rackClient(c).CreateBuildUrl(app, url, cache, config) if err != nil { return "", err } return finishBuild(c, app, build) }
func executeBuildUrl(c *cli.Context, url, app, manifest, description string) (string, error) { cache := !c.Bool("no-cache") build, err := rackClient(c).CreateBuildUrl(app, url, cache, manifest, description) if err != nil { return "", err } return finishBuild(c, app, build) }
func cmdServiceCreate(c *cli.Context) { // ensure type included if !(len(c.Args()) > 0) { stdcli.Usage(c, "create") return } // ensure everything after type is a flag if len(c.Args()) > 1 && !strings.HasPrefix(c.Args()[1], "--") { stdcli.Usage(c, "create") return } t := c.Args()[0] if t == "help" { stdcli.Usage(c, "create") return } options := stdcli.ParseOpts(c.Args()[1:]) for key, value := range options { if value == "" { options[key] = "true" } } var optionsList []string for key, val := range options { optionsList = append(optionsList, fmt.Sprintf("%s=%q", key, val)) } if options["name"] == "" { options["name"] = fmt.Sprintf("%s-%d", t, (rand.Intn(8999) + 1000)) } fmt.Printf("Creating %s (%s", options["name"], t) if len(optionsList) > 0 { fmt.Printf(": %s", strings.Join(optionsList, " ")) } fmt.Printf(")... ") _, err := rackClient(c).CreateService(t, options) if err != nil { stdcli.Error(err) return } fmt.Println("CREATING") }
func cmdEncrypt(c *cli.Context) { if len(c.Args()) < 1 { Usage(c, "encrypt") return } key := c.Args()[0] var env []byte var err error if len(c.Args()) == 1 { env, err = ioutil.ReadAll(os.Stdin) } else { env, err = ioutil.ReadFile(c.Args()[1]) } if err != nil { panic(err) } cr, err := buildCrypt(c) if err != nil { panic(err) } data, err := cr.Encrypt(key, env) if err != nil { panic(err) } fmt.Print(string(data)) }
func cmdDecrypt(c *cli.Context) { if len(c.Args()) < 1 { Usage(c, "decrypt") return } key := c.Args()[0] var data []byte var err error if len(c.Args()) == 1 { data, err = ioutil.ReadAll(os.Stdin) } else { data, err = ioutil.ReadFile(c.Args()[1]) } if err != nil { panic(err) } cr, err := buildCrypt(c) if err != nil { panic(err) } dec, err := cr.Decrypt(key, data) if err != nil { panic(err) } fmt.Print(string(dec)) }
func cmdRunDetached(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } if len(c.Args()) < 1 { stdcli.Usage(c, "run") return } ps := c.Args()[0] command := "" if len(c.Args()) > 1 { args := c.Args()[1:] command = strings.Join(args, " ") } fmt.Printf("Running `%s` on %s... ", command, ps) err = rackClient(c).RunProcessDetached(app, ps, command) if err != nil { stdcli.Error(err) return } fmt.Println("OK") }
func cmdRegistryAdd(c *cli.Context) { if len(c.Args()) < 1 { stdcli.Usage(c, "add") return } server := c.Args()[0] username := c.String("username") password := c.String("password") email := c.String("email") if username == "" { username = promptForUsername() } if password == "" { password = promptForPassword() } _, err := rackClient(c).AddRegistry(server, username, password, email) if err != nil { stdcli.Error(err) return } fmt.Println("Done.") }
func cmdRun(c *cli.Context) { if c.Bool("detach") { cmdRunDetached(c) return } _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } if len(c.Args()) < 2 { stdcli.Usage(c, "run") return } ps := c.Args()[0] args := strings.Join(c.Args()[1:], " ") code, err := runAttached(c, app, ps, args) if err != nil { stdcli.Error(err) return } os.Exit(code) }
func cmdRackScale(c *cli.Context) { count := 0 typ := "" if c.IsSet("count") { count = c.Int("count") } if c.IsSet("type") { typ = c.String("type") } system, err := rackClient(c).ScaleSystem(count, typ) if err != nil { stdcli.Error(err) return } fmt.Printf("Name %s\n", system.Name) fmt.Printf("Status %s\n", system.Status) fmt.Printf("Version %s\n", system.Version) fmt.Printf("Count %d\n", system.Count) fmt.Printf("Type %s\n", system.Type) }
func executeBuildDirIncremental(c *cli.Context, dir, app, manifest, description string) (string, error) { system, err := rackClient(c).GetSystem() if err != nil { return "", err } // if the rack doesnt support incremental builds then fall back if system.Version < "20160226234213" { return executeBuildDir(c, dir, app, manifest, description) } cache := !c.Bool("no-cache") dir, err = filepath.Abs(dir) if err != nil { return "", err } fmt.Printf("Analyzing source... ") index, err := createIndex(dir) if err != nil { return "", err } fmt.Println("OK") fmt.Printf("Uploading changes... ") err = uploadIndex(c, index) if err != nil { return "", err } fmt.Printf("Starting build... ") build, err := rackClient(c).CreateBuildIndex(app, index, cache, manifest, description) if err != nil { return "", err } fmt.Println("OK") return finishBuild(c, app, build) }
func cmdInstancesTerminate(c *cli.Context) { if len(c.Args()) != 1 { stdcli.Usage(c, "terminate") return } id := c.Args()[0] err := rackClient(c).TerminateInstance(id) if err != nil { stdcli.Error(err) return } fmt.Printf("Successfully sent terminate to instance %q\n", id) }
func executeBuild(c *cli.Context, source, app, manifest, description string) (string, error) { u, _ := url.Parse(source) switch u.Scheme { case "http", "https": return executeBuildUrl(c, source, app, manifest, description) default: if c.Bool("incremental") { return executeBuildDirIncremental(c, source, app, manifest, description) } else { return executeBuildDir(c, source, app, manifest, description) } } return "", fmt.Errorf("unreachable") }