func cleanRun(keen *keen.Client, rollbar *rollbar.Client, args ...string) int { db.GetState() // Do this to ensure we're at the root of the app. contents, _ := ioutil.ReadFile(filepath.Join(".bowery", "state")) if len(contents) > 0 { keen.AddEvent("bowery clean", map[string]string{ "contents": string(contents), }) } err := os.RemoveAll(".bowery") if err != nil { rollbar.Report(err) return 1 } return 0 }
func saveRun(keen *keen.Client, rollbar *rollbar.Client, args ...string) int { if len(args) <= 0 { fmt.Fprintln(os.Stderr, "Usage: bowery "+Cmds["save"].Usage, "\n\n"+Cmds["save"].Short) return 2 } dev, err := getDeveloper() if err != nil { rollbar.Report(err) return 1 } state, err := db.GetState() if err != nil { rollbar.Report(err) return 1 } // Create slices of service names, and find the requested service. var service *schemas.Service services := make([]string, len(state.App.Services)) for i, v := range state.App.Services { services[i] = v.Name if args[0] == v.Name { service = v break } } // Handle no service found. if service == nil { log.Fprintln(os.Stderr, "red", errors.ErrInvalidService, args[0]) log.Println("yellow", "Valid services:", strings.Join(services, ", ")) return 1 } log.Debug("Found service", service.Name, "public addr:", service.PublicAddr) // Get image name log.Println("yellow", "What would you like to call this image?") imageName, err := prompt.Basic("Image Name", true) if err != nil { rollbar.Report(err) return 1 } log.Debug("Collected Image Name", imageName) imageDesc, err := prompt.Basic("Description", true) if err != nil { rollbar.Report(err) return 1 } log.Debug("Collected Description", imageDesc) log.Println("yellow", "A new image is being created and saved to our registry...") log.Println("yellow", "This may take a couple minutes.") err = api.SaveService(state, dev, service.Name, service.PublicAddr, imageName, imageDesc) if err != nil { errmsg := err.Error() if errmsg == imageName+" is an invalid service name" || errmsg == "Image already exists" { log.Println("yellow", err) } else { rollbar.Report(err) } return 1 } log.Println("yellow", imageName+" successfully created.") keen.AddEvent("bowery save", map[string]string{ "serviceName": service.Name, "imageName": imageName, "appId": state.App.ID, }) return 0 }
// Upload sends an upload request to a satellite endpoint, including // a tar upload file if given. func Upload(url, serviceName string, file *os.File) error { var body bytes.Buffer writer := multipart.NewWriter(&body) // Write file to multipart body if given. if file != nil { part, err := writer.CreateFormFile("file", "upload") if err != nil { return errors.NewStackError(err) } _, err = io.Copy(part, file) if err != nil { return err } } // Get current app and add fields for init, build, test, and start. state, err := db.GetState() if err != nil { return err } service := state.Config[serviceName] if service != nil { err = writer.WriteField("init", service.Init) if err == nil { err = writer.WriteField("build", service.Build) } if err == nil { err = writer.WriteField("test", service.Test) } if err == nil { err = writer.WriteField("start", service.Start) } if err == nil { err = writer.WriteField("path", service.Path) } if err == nil && service.Env != nil { envData, err := json.Marshal(service.Env) if err != nil { return err } err = writer.WriteField("env", string(envData)) } } if err == nil { err = writer.Close() } if err != nil { return err } res, err := http.Post("http://"+url, writer.FormDataContentType(), &body) if err != nil { if responses.IsRefusedConn(err) { err = errors.ErrSyncFailed } return errors.NewStackError(err) } defer res.Body.Close() // Decode json response. uploadRes := new(responses.Res) decoder := json.NewDecoder(res.Body) err = decoder.Decode(uploadRes) if err != nil { return errors.NewStackError(err) } // Created, so no error. if uploadRes.Status == "created" { return nil } return errors.NewStackError(uploadRes) }
func restartRun(keen *keen.Client, rollbar *rollbar.Client, args ...string) int { if len(args) <= 0 { fmt.Fprintln(os.Stderr, "Usage: bowery "+Cmds["restart"].Usage, "\n\n"+Cmds["restart"].Short) return 2 } dev, err := getDeveloper() if err != nil { rollbar.Report(err) return 1 } state, err := db.GetState() if err != nil { rollbar.Report(err) return 1 } // Create slices of service names, and find the requested service. var service *schemas.Service services := make([]string, len(state.App.Services)) serviceIdx := -1 for i, v := range state.App.Services { services[i] = v.Name if args[0] == v.Name { service = v serviceIdx = i break } } // Handle no service found. if service == nil { log.Fprintln(os.Stderr, "red", errors.ErrInvalidService, args[0]) log.Println("yellow", "Valid services:", strings.Join(services, ", ")) return 1 } log.Debug("Found service", service.Name) newService, err := api.RestartService(service.DockerID, dev.Token) if err != nil { rollbar.Report(err) return 1 } if newService != nil { state.App.Services[serviceIdx] = newService service = newService err = state.Save() if err != nil { rollbar.Report(err) return 1 } } keen.AddEvent("bowery restart", map[string]string{ "name": service.Name, "appId": state.App.ID, }) return 0 }
// Update updates the given name with the status and path. func Update(url, serviceName, fullPath, name, status string) error { var body bytes.Buffer // Create writer, and write form fields. writer := multipart.NewWriter(&body) err := writer.WriteField("type", status) if err == nil { err = writer.WriteField("path", path.Join(strings.Split(name, string(filepath.Separator))...)) } if err != nil { return errors.NewStackError(err) } // Attach file if update or create. if status == "update" || status == "create" { file, err := os.Open(fullPath) if err != nil { return err } defer file.Close() stat, err := file.Stat() if err != nil { return err } // Add file mode to write with. err = writer.WriteField("mode", strconv.FormatUint(uint64(stat.Mode().Perm()), 10)) if err != nil { return errors.NewStackError(err) } part, err := writer.CreateFormFile("file", "upload") if err != nil { return errors.NewStackError(err) } _, err = io.Copy(part, file) if err != nil { return err } } // Get current app and add fields for init, build, test, and start. state, err := db.GetState() if err != nil { return err } if service := state.Config[serviceName]; service != nil { writer.WriteField("init", service.Init) writer.WriteField("build", service.Build) writer.WriteField("test", service.Test) writer.WriteField("start", service.Start) if service.Env != nil { envData, err := json.Marshal(service.Env) if err != nil { return err } err = writer.WriteField("env", string(envData)) } } if err = writer.Close(); err != nil { return err } req, err := http.NewRequest("PUT", "http://"+url, &body) if err != nil { return errors.NewStackError(err) } req.Header.Set("Content-Type", writer.FormDataContentType()) res, err := http.DefaultClient.Do(req) if err != nil { if responses.IsRefusedConn(err) { err = errors.ErrSyncFailed } return errors.NewStackError(err) } defer res.Body.Close() // Decode json response. uploadRes := new(responses.Res) decoder := json.NewDecoder(res.Body) err = decoder.Decode(uploadRes) if err != nil { return errors.NewStackError(err) } // Created, so no error. if uploadRes.Status == "updated" { return nil } return errors.NewStackError(uploadRes) }