Пример #1
0
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")
}
Пример #2
0
func cmdExec(c *cli.Context) {
	fd := os.Stdin.Fd()
	stdinState, err := terminal.GetState(int(fd))
	defer terminal.Restore(int(fd), stdinState)

	_, app, err := stdcli.DirApp(c, ".")

	if err != nil {
		stdcli.Error(err)
		return
	}

	if len(c.Args()) < 2 {
		stdcli.Usage(c, "exec")
		return
	}

	ps := c.Args()[0]

	code, err := rackClient(c).ExecProcessAttached(app, ps, strings.Join(c.Args()[1:], " "), os.Stdin, os.Stdout)
	terminal.Restore(int(fd), stdinState)

	if err != nil {
		stdcli.Error(err)
		return
	}

	os.Exit(code)
}
Пример #3
0
Файл: env.go Проект: convox/rack
func cmdEnvList(c *cli.Context) error {
	_, app, err := stdcli.DirApp(c, ".")
	if err != nil {
		return stdcli.Error(err)
	}

	if len(c.Args()) > 0 {
		return stdcli.Error(fmt.Errorf("`convox env` does not take arguments. Perhaps you meant `convox env set`?"))
	}

	if c.Bool("help") {
		stdcli.Usage(c, "")
		return nil
	}

	env, err := rackClient(c).GetEnvironment(app)
	if err != nil {
		return stdcli.Error(err)
	}

	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])
	}

	return nil
}
Пример #4
0
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.")
}
Пример #5
0
func cmdRackScale(c *cli.Context) error {
	// initialize to invalid values that indicate no change
	count := -1
	typ := ""

	if c.IsSet("count") {
		count = c.Int("count")
	}

	if c.IsSet("type") {
		typ = c.String("type")
	}

	// validate no argument
	switch len(c.Args()) {
	case 0:
		if count == -1 && typ == "" {
			displaySystem(c)
			return nil
		}
		// fall through to scale API call
	default:
		stdcli.Usage(c, "scale")
		return nil
	}

	_, err := rackClient(c).ScaleSystem(count, typ)
	if err != nil {
		return stdcli.ExitError(err)
	}

	displaySystem(c)
	return nil
}
Пример #6
0
Файл: run.go Проект: convox/rack
func cmdRun(c *cli.Context) error {
	if c.Bool("detach") {
		return cmdRunDetached(c)
	}

	_, app, err := stdcli.DirApp(c, ".")
	if err != nil {
		return stdcli.Error(err)
	}

	if len(c.Args()) < 2 {
		stdcli.Usage(c, "run")
		return nil
	}

	ps := c.Args()[0]
	err = validateProcessId(c, app, ps)
	if err != nil {
		return stdcli.Error(err)
	}

	args := strings.Join(c.Args()[1:], " ")

	release := c.String("release")

	code, err := runAttached(c, app, ps, args, release)
	if err != nil {
		return stdcli.Error(err)
	}

	return cli.NewExitError("", code)
}
Пример #7
0
func cmdBuildsInfo(c *cli.Context) error {
	_, app, err := stdcli.DirApp(c, ".")
	if err != nil {
		return stdcli.Error(err)
	}

	if len(c.Args()) != 1 {
		stdcli.Usage(c, "info")
		return nil
	}

	build := c.Args()[0]

	b, err := rackClient(c).GetBuild(app, build)
	if err != nil {
		return stdcli.Error(err)
	}

	fmt.Printf("Build        %s\n", b.Id)
	fmt.Printf("Status       %s\n", b.Status)
	fmt.Printf("Release      %s\n", b.Release)
	fmt.Printf("Description  %s\n", b.Description)
	fmt.Printf("Started      %s\n", humanizeTime(b.Started))
	fmt.Printf("Elapsed      %s\n", stdcli.Duration(b.Started, b.Ended))

	return nil
}
Пример #8
0
func cmdServiceURL(c *cli.Context) error {
	if len(c.Args()) != 1 {
		stdcli.Usage(c, "url")
		return nil
	}

	name := c.Args()[0]

	service, err := rackClient(c).GetService(name)
	if err != nil {
		return stdcli.ExitError(err)
	}

	if service.Status == "failed" {
		return stdcli.ExitError(fmt.Errorf("Service failure for %s", service.StatusReason))
	}

	if service.URL == "" {
		return stdcli.ExitError(fmt.Errorf("URL does not exist for %s", service.Name))
	}

	fmt.Printf("%s\n", service.URL)

	return nil
}
Пример #9
0
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
	}

	port := c.Args()[0]

	fmt.Printf("Deleting SSL listener on port %s... ", port)

	_, err = rackClient(c).DeleteSSL(app, port)

	if err != nil {
		stdcli.Error(err)
		return
	}

	fmt.Println("Done.")
}
Пример #10
0
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))
}
Пример #11
0
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)
}
Пример #12
0
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")
}
Пример #13
0
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")
}
Пример #14
0
func cmdSSLList(c *cli.Context) error {
	_, app, err := stdcli.DirApp(c, ".")
	if err != nil {
		return stdcli.ExitError(err)
	}

	if len(c.Args()) > 0 {
		return stdcli.ExitError(fmt.Errorf("`convox ssl` does not take arguments. Perhaps you meant `convox ssl update`?"))
	}

	if c.Bool("help") {
		stdcli.Usage(c, "")
		return nil
	}

	ssls, err := rackClient(c).ListSSL(app)
	if err != nil {
		return stdcli.ExitError(err)
	}

	t := stdcli.NewTable("TARGET", "CERTIFICATE", "DOMAIN", "EXPIRES")

	for _, ssl := range *ssls {
		t.AddRow(fmt.Sprintf("%s:%d", ssl.Process, ssl.Port), ssl.Certificate, ssl.Domain, humanizeTime(ssl.Expiration))
	}

	t.Print()
	return nil
}
Пример #15
0
func cmdExec(c *cli.Context) {
	_, app, err := stdcli.DirApp(c, ".")

	if err != nil {
		stdcli.Error(err)
		return
	}

	if len(c.Args()) < 1 {
		stdcli.Usage(c, "exec")
		return
	}

	ps := c.Args()[0]

	command := ""

	if len(c.Args()) > 1 {
		args := c.Args()[1:]
		command = strings.Join(args, " ")
	}

	err = stdcli.Run("docker", "exec", "-it", fmt.Sprintf("%s-%s", app, ps), "sh", "-c", command)

	if err != nil {
		stdcli.Error(err)
		return
	}
}
Пример #16
0
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")
}
Пример #17
0
func cmdReleasePromote(c *cli.Context) error {
	if len(c.Args()) < 1 {
		stdcli.Usage(c, "releases promote")
		return nil
	}

	release := c.Args()[0]

	_, app, err := stdcli.DirApp(c, ".")
	if err != nil {
		return stdcli.ExitError(err)
	}

	fmt.Printf("Promoting %s... ", release)

	_, err = rackClient(c).PromoteRelease(app, release)
	if err != nil {
		return stdcli.ExitError(err)
	}

	fmt.Println("UPDATING")

	if c.Bool("wait") {
		fmt.Printf("Waiting for stabilization... ")

		if err := waitForReleasePromotion(c, app, release); err != nil {
			return stdcli.ExitError(err)
		}

		fmt.Println("OK")
	}

	return nil
}
Пример #18
0
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.")
}
Пример #19
0
func cmdInstancesList(c *cli.Context) error {
	if len(c.Args()) > 0 {
		return stdcli.ExitError(fmt.Errorf("`convox instances` does not take arguments. Perhaps you meant `convox instances ssh`?"))
	}

	if c.Bool("help") {
		stdcli.Usage(c, "")
		return nil
	}

	instances, err := rackClient(c).GetInstances()
	if err != nil {
		return stdcli.ExitError(err)
	}

	t := stdcli.NewTable("ID", "AGENT", "STATUS", "STARTED", "PS", "CPU", "MEM")

	for _, i := range instances {
		agent := "off"
		if i.Agent {
			agent = "on"
		}

		t.AddRow(i.Id, agent, i.Status,
			humanizeTime(i.Started),
			strconv.Itoa(i.Processes),
			fmt.Sprintf("%0.2f%%", i.Cpu*100),
			fmt.Sprintf("%0.2f%%", i.Memory*100))
	}

	t.Print()
	return nil
}
Пример #20
0
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)
}
Пример #21
0
func cmdServiceCreate(c *cli.Context) {
	if len(c.Args()) != 2 {
		stdcli.Usage(c, "create")
		return
	}

	t := c.Args()[0]
	name := c.Args()[1]

	fmt.Printf("Creating %s (%s)... ", name, t)

	service, err := rackClient(c).CreateService(t, name)

	if err != nil {
		stdcli.Error(err)
		return
	}

	for {
		s, err := rackClient(c).GetService(service.Name)

		if err != nil {
			stdcli.Error(err)
			return
		}

		if s.Status == "running" {
			break
		}

		time.Sleep(3 * time.Second)
	}

	fmt.Println("OK")
}
Пример #22
0
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)
}
Пример #23
0
func cmdSSLUpdate(c *cli.Context) error {
	_, app, err := stdcli.DirApp(c, ".")
	if err != nil {
		return stdcli.ExitError(err)
	}

	if len(c.Args()) < 2 {
		stdcli.Usage(c, "update")
		return nil
	}

	target := c.Args()[0]

	parts := strings.Split(target, ":")

	if len(parts) != 2 {
		return stdcli.ExitError(fmt.Errorf("target must be process:port"))
	}

	fmt.Printf("Updating certificate... ")

	_, err = rackClient(c).UpdateSSL(app, parts[0], parts[1], c.Args()[1])
	if err != nil {
		return stdcli.ExitError(err)
	}

	fmt.Println("OK")
	return nil
}
Пример #24
0
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)
	}
}
Пример #25
0
func cmdApi(c *cli.Context) error {
	if len(c.Args()) > 0 {
		return cli.NewExitError("ERROR: `convox api` does not take arguments. Perhaps you meant `convox api get`?", 1)
	}

	stdcli.Usage(c, "")
	return nil
}
Пример #26
0
func cmdServiceProxy(c *cli.Context) error {
	if len(c.Args()) != 1 {
		stdcli.Usage(c, "info")
		return nil
	}

	name := c.Args()[0]

	service, err := rackClient(c).GetService(name)
	if err != nil {
		return stdcli.ExitError(err)
	}

	export, ok := service.Exports["URL"]
	if !ok {
		return stdcli.ExitError(fmt.Errorf("%s does not expose a URL", name))
	}

	u, err := url.Parse(export)
	if err != nil {
		return stdcli.ExitError(err)
	}

	remotehost, remoteport, err := net.SplitHostPort(u.Host)
	if err != nil {
		return stdcli.ExitError(err)
	}

	localhost := "127.0.0.1"
	localport := remoteport

	if listen := c.String("listen"); listen != "" {
		parts := strings.Split(listen, ":")

		switch len(parts) {
		case 1:
			localport = parts[0]
		case 2:
			localhost = parts[0]
			localport = parts[1]
		}
	}

	lp, err := strconv.Atoi(localport)
	if err != nil {
		return stdcli.ExitError(err)
	}

	rp, err := strconv.Atoi(remoteport)
	if err != nil {
		return stdcli.ExitError(err)
	}

	proxy(localhost, lp, remotehost, rp, rackClient(c))
	return nil
}
Пример #27
0
func cmdServiceUpdate(c *cli.Context) {
	// ensure name included
	if !(len(c.Args()) > 0) {
		stdcli.Usage(c, "update")
		return
	}

	name := c.Args()[0]

	// ensure everything after type is a flag
	if len(c.Args()) > 1 && !strings.HasPrefix(c.Args()[1], "--") {
		stdcli.Usage(c, "update")
		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 len(optionsList) == 0 {
		stdcli.Usage(c, "update")
		return
	}

	fmt.Printf("Updating %s (%s)...", name, strings.Join(optionsList, " "))

	_, err := rackClient(c).UpdateService(name, options)

	if err != nil {
		stdcli.Error(err)
		return
	}

	fmt.Println("UPDATING")
}
Пример #28
0
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 {}
}
Пример #29
0
func cmdBuildsCopy(c *cli.Context) {
	_, app, err := stdcli.DirApp(c, ".")

	if err != nil {
		stdcli.Error(err)
		return
	}

	if len(c.Args()) != 2 {
		stdcli.Usage(c, "copy")
		return
	}

	build := c.Args()[0]
	destApp := c.Args()[1]

	fmt.Print("Copying build... ")

	b, err := rackClient(c).CopyBuild(app, build, destApp)
	if err != nil {
		stdcli.Error(err)
		return
	}

	fmt.Println("OK")

	releaseId, err := finishBuild(c, destApp, b)
	if err != nil {
		stdcli.Error(err)
		return
	}

	if releaseId != "" {
		if c.Bool("promote") {
			fmt.Printf("Promoting %s %s... ", destApp, releaseId)

			_, err = rackClient(c).PromoteRelease(destApp, releaseId)

			if err != nil {
				stdcli.Error(err)
				return
			}

			fmt.Println("OK")
		} else {
			fmt.Printf("To deploy this copy run `convox releases promote %s --app %s`\n", releaseId, destApp)
		}
	}
}
Пример #30
0
func cmdInstancesTerminate(c *cli.Context) error {
	if len(c.Args()) != 1 {
		stdcli.Usage(c, "terminate")
		return nil
	}

	id := c.Args()[0]

	err := rackClient(c).TerminateInstance(id)
	if err != nil {
		return stdcli.ExitError(err)
	}

	fmt.Printf("Successfully sent terminate to instance %q\n", id)
	return nil
}