Exemple #1
0
func waitForAppRunning(c *cli.Context, app string) error {
	timeout := time.After(30 * time.Minute)
	tick := time.Tick(5 * time.Second)

	failed := false

	for {
		select {
		case <-tick:
			a, err := rackClient(c).GetApp(app)
			if err != nil {
				return err
			}

			switch a.Status {
			case "failed", "running":
				if failed {
					stdcli.Writef("<ok>DONE</ok>\n")
					return fmt.Errorf("Update rolled back")
				}
				return nil
			case "rollback":
				if !failed {
					failed = true
					stdcli.Writef("<fail>FAILED</fail>\n")
					stdcli.Startf("Rolling back")
				}
			}
		case <-timeout:
			return fmt.Errorf("timeout")
		}
	}

	return nil
}
Exemple #2
0
func diagnose(d Diagnosis) {
	stdcli.Spinner.Stop()
	time.Sleep(100 * time.Millisecond)
	print("\033[K")

	stdcli.Writef(d.String())
	if d.Kind == "fail" {
		os.Exit(1)
	}
}
Exemple #3
0
func cmdRackUpdate(c *cli.Context) error {
	vs, err := version.All()
	if err != nil {
		return stdcli.Error(err)
	}

	target, err := vs.Latest()
	if err != nil {
		return stdcli.Error(err)
	}

	if len(c.Args()) > 0 {
		t, err := vs.Find(c.Args()[0])
		if err != nil {
			return stdcli.Error(err)
		}
		target = t
	}

	system, err := rackClient(c).GetSystem()
	if err != nil {
		return stdcli.Error(err)
	}

	nv, err := vs.Next(system.Version)
	if err != nil && strings.HasSuffix(err.Error(), "is latest") {
		nv = target.Version
	} else if err != nil {
		return stdcli.Error(err)
	}

	next, err := vs.Find(nv)
	if err != nil {
		return stdcli.Error(err)
	}

	// stop at a required release if necessary
	if next.Version < target.Version {
		stdcli.Writef("WARNING: Required update found.\nPlease run `convox rack update` again once this update completes.\n")
		target = next
	}

	stdcli.Startf("Updating to <release>%s</release>", target.Version)

	_, err = rackClient(c).UpdateSystem(target.Version)
	if err != nil {
		return stdcli.Error(err)
	}

	stdcli.Wait("UPDATING")

	if c.Bool("wait") {
		stdcli.Startf("Waiting for completion")

		// give the rack a few seconds to start updating
		time.Sleep(5 * time.Second)

		if err := waitForRackRunning(c); err != nil {
			return stdcli.Error(err)
		}

		stdcli.OK()
	}

	return nil
}
Exemple #4
0
func cmdDoctor(c *cli.Context) error {
	docContext = c
	stdcli.Writef("### Setup\n")
	for _, check := range setupChecks {
		if err := check(); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n### Build: Image\n")
	for _, check := range buildImageChecks {
		if err := check(); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n### Build: Service\n")
	startCheck("<file>docker-compose.yml</file> found")
	_, err := os.Stat("docker-compose.yml")
	if err != nil {
		diagnose(Diagnosis{
			Title:       "<file>docker-compose.yml</file> found",
			Description: "<fail>A docker-compose.yml file is required to define Services</fail>",
			Kind:        "fail",
			DocsLink:    "https://convox.com/guide/services/",
		})
	} else {
		diagnose(Diagnosis{
			Title: "<file>docker-compose.yml</file> found",
			Kind:  "success",
		})
	}

	m, err := manifest.LoadFile("docker-compose.yml")
	checkManifestValid(m, err)
	for _, check := range buildServiceChecks {
		if err := check(m); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n### Build: Environment\n")
	for _, check := range buildEnvironmentChecks {
		if err := check(m); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n### Run: Balancer\n")
	for _, check := range runBalancerChecks {
		if err := check(m); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n### Run: Database\n")
	for _, check := range runDatabaseChecks {
		if err := check(m); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n### Run: Link\n")
	for _, check := range runLinkChecks {
		if err := check(m); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n### Development: Reloading\n")
	for _, check := range runReloadingChecks {
		if err := check(m); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n### Development: Commands\n")
	for _, check := range runCommandChecks {
		if err := check(m); err != nil {
			return stdcli.Error(err)
		}
	}

	stdcli.Writef("\n\n<success>Success:</success> Your app looks ready for development. \nRun it with `convox start`.\n\n")
	return nil
}