func TestLoadNonexistentFile(t *testing.T) { m, err := manifest.LoadFile("/foo/bar/hope/this/doesnt/exist") if assert.Nil(t, m) && assert.NotNil(t, err) { assert.Equal(t, err.Error(), "open /foo/bar/hope/this/doesnt/exist: no such file or directory") } }
func main() { if len(os.Args) != 2 { fmt.Println("usage: build <src>") os.Exit(1) } defer handlePanic() src := os.Args[1] if src == "-" { extractTar() } else { cloneGit(src) } writeDockerAuth() m, err := manifest.LoadFile(fmt.Sprintf("src/%s", manifestPath)) handleError(err) data, err := m.Raw() handleError(err) cwd, err := os.Getwd() handleError(err) output := manifest.NewOutput() str := output.Stream("build") handleError(os.Chdir("./src")) handleError(m.Build(".", app, str, cache)) handleError(os.Chdir(cwd)) handleError(m.Push(str, app, registryAddress, buildId, repository)) _, err = rackClient.UpdateBuild(os.Getenv("APP"), os.Getenv("BUILD"), string(data), "complete", "") handleError(err) }
func checkDockerfile() error { if df := filepath.Join(filepath.Dir(os.Args[0]), "docker-compose.yml"); exists(df) { m, err := manifest.LoadFile("docker-compose.yml") if err != nil { //This will get picked up later in the test suite return nil } checkMissingDockerFiles(m) return nil } title := "Dockerfile found" startCheck(title) //Skip if docker-compose file exists _, err := os.Stat("docker-compose.yml") if err == nil { return nil } _, err = os.Stat("Dockerfile") if err != nil { diagnose(Diagnosis{ Title: title, Description: "<fail>A Dockerfile is required to build an Image</fail>", Kind: "fail", DocsLink: "https://convox.com/guide/build/images", }) } else { diagnose(Diagnosis{ Title: title, Kind: "success", }) } return nil }
func cmdStart(c *cli.Context) error { // go handleResize() id, err := currentId() if err != nil { stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{Error: err}) } err = dockerTest() if err != nil { return stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ValidationError: err}) } dir, app, err := stdcli.DirApp(c, filepath.Dir(c.String("file"))) if err != nil { return stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ValidationError: err}) } appType := detectApplication(dir) m, err := manifest.LoadFile(c.String("file")) if err != nil { return stdcli.ExitError(err) } if err := m.Shift(c.Int("shift")); err != nil { return stdcli.ExitError(err) } if pcc, err := m.PortConflicts(); err != nil || len(pcc) > 0 { if err == nil { err = fmt.Errorf("ports in use: %v", pcc) } stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ ValidationError: err, AppType: appType, }) return stdcli.ExitError(err) } cache := !c.Bool("no-cache") sync := !c.Bool("no-sync") r := m.Run(dir, app, cache, sync) err = r.Start() if err != nil { return stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ ValidationError: err, AppType: appType, }) } stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ AppType: appType, }) go handleInterrupt(r) return r.Wait() }
func cmdStart(c *cli.Context) error { // go handleResize() var service string var command []string if len(c.Args()) > 0 { service = c.Args()[0] } if len(c.Args()) > 1 { command = c.Args()[1:] } id, err := currentId() if err != nil { stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{Error: err}) } err = dockerTest() if err != nil { stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ValidationError: err}) return stdcli.Error(err) } dir, app, err := stdcli.DirApp(c, filepath.Dir(c.String("file"))) if err != nil { stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ValidationError: err}) return stdcli.Error(err) } appType := detectApplication(dir) m, err := manifest.LoadFile(c.String("file")) if err != nil { return stdcli.Error(err) } errs := m.Validate() if len(errs) > 0 { for _, e := range errs[1:] { stdcli.Error(e) } return stdcli.Error(errs[0]) } if service != "" { _, ok := m.Services[service] if !ok { return stdcli.Error(fmt.Errorf("Service %s not found in manifest", service)) } } if err := m.Shift(c.Int("shift")); err != nil { return stdcli.Error(err) } // one-off commands don't need port validation if len(command) == 0 { if pcc, err := m.PortConflicts(); err != nil || len(pcc) > 0 { if err == nil { err = fmt.Errorf("ports in use: %v", pcc) } stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ ValidationError: err, AppType: appType, }) return stdcli.Error(err) } } cache := !c.Bool("no-cache") sync := !c.Bool("no-sync") r := m.Run(dir, app, manifest.RunOptions{ Cache: cache, Sync: sync, Service: service, Command: command, }) err = r.Start() if err != nil { r.Stop() stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ ValidationError: err, AppType: appType, }) return stdcli.Error(err) } stdcli.QOSEventSend("cli-start", id, stdcli.QOSEventProperties{ AppType: appType, }) // Setup the local "cron jobs" for _, entry := range m.Services { labels := entry.LabelsByPrefix("convox.cron") processName := fmt.Sprintf("%s-%s", app, entry.Name) c := cron.New() for key, value := range labels { p, ok := r.Processes[processName] if !ok { continue } cronjob := models.NewCronJobFromLabel(key, value) rs := strings.NewReplacer("cron(", "0 ", ")", "") // cron pkg first field is in seconds so set to 0 trigger := strings.TrimSuffix(rs.Replace(cronjob.Schedule), " *") // and doesn't recognize year so we trim it c.AddFunc(trigger, func() { cronProccesName := fmt.Sprintf("cron-%s-%04d", cronjob.Name, rand.Intn(9000)) // Replace args with cron specific ones cronArgs := p.GenerateArgs(&manifest.ArgOptions{ Command: cronjob.Command, IgnorePorts: true, Name: cronProccesName, }) done := make(chan error) manifest.RunAsync( r.Output.Stream(cronProccesName), manifest.Docker(append([]string{"run"}, cronArgs...)...), done, ) err := <-done if err != nil { fmt.Printf("error running %s: %s\n", cronProccesName, err.Error()) } }) } c.Start() } go handleInterrupt(r) return r.Wait() }
func manifestFixture(name string) (*manifest.Manifest, error) { return manifest.LoadFile(fmt.Sprintf("fixtures/%s.yml", name)) }
func checkBuildDocker() error { title := "Image builds successfully" if df := filepath.Join(filepath.Dir(os.Args[0]), "docker-compose.yml"); exists(df) { m, err := manifest.LoadFile(df) if err != nil { //This will be handled later in the suite return nil } startCheck(title) _, app, err := stdcli.DirApp(docContext, ".") if err != nil { //This will be handled later in the suite return nil } s := make(chan string) output := []string{} go func() { for x := range s { output = append(output, x) } }() err = m.Build(".", app, s, manifest.BuildOptions{ Cache: true, }) if err != nil { message := "" for _, x := range output { message += fmt.Sprintf("<fail>%s</fail>\n", x) } diagnose(Diagnosis{ Title: title, Description: message, Kind: "fail", }) } diagnose(Diagnosis{ Title: title, Kind: "success", }) return nil } startCheck(title) byts, err := exec.Command("docker", "build", ".").CombinedOutput() if err != nil { bytsArr := strings.Split(string(byts), "\n") message := "" for _, x := range bytsArr { message += fmt.Sprintf("<description>%s</description>\n", x) } diagnose(Diagnosis{ Title: title, Description: message, Kind: "fail", }) return nil } diagnose(Diagnosis{ Title: title, Kind: "success", }) return nil }
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 }