// getToken gets the login information for a developer and gets a new token. func getToken(dev *db.Developer) error { var err error i := 0 token := "" // Get email and password up to 5 times, then report the error. for token == "" && i < 5 { validEmail := false email := "" pass := "" for !validEmail { email, err = prompt.Basic("Email", true) if err != nil { return err } _, err = mail.ParseAddress(email) if err == nil { validEmail = true } else { log.Println("yellow", "Try again! Valid email address required.") } } pass, err = prompt.Password("Password") if err != nil { return err } log.Debug("Collected email", email, "pass", pass) token, err = broome.GetTokenByLogin(email, pass) if err != nil { if i < 4 { log.Fprintln(os.Stderr, "red", errors.Newf(errors.ErrLoginRetryTmpl, err)) } i++ } } if err != nil { if err == errors.ErrInvalidLogin { err = errors.ErrTooManyLogins } return err } log.Debug("Got token", token) dev.Token = token return dev.Save() }
// updateDeveloper gets the most up to date dev data and saves it. func updateDeveloper(dev *db.Developer) error { // Get the developer from the devs token. developer, err := broome.GetDeveloper(dev.Token) if err != nil { return err } // Save the developer. log.Debug("Found developer", developer) dev.Developer = developer return dev.Save() }
// Start handles file events and uploads the changes. func (watcher *Watcher) Start(evChan chan *Event, errChan chan error) { if watcher.Path == "" { return } stats := make(map[string]os.FileInfo) found := make([]string, 0) ignores, err := db.GetIgnores(watcher.Path) if err != nil { errChan <- watcher.wrapErr(err) return } // Get initial stats. err = filepath.Walk(watcher.Path, func(path string, info os.FileInfo, err error) error { if err != nil { return err } // Check if ignoring. for _, ignore := range ignores { if ignore == path { if info.IsDir() { return filepath.SkipDir } return nil } } stats[path] = info return nil }) if err != nil { errChan <- watcher.wrapErr(err) return } // Manager updates/creates. walker := func(path string, info os.FileInfo, err error) error { if err != nil { return err } rel, err := filepath.Rel(watcher.Path, path) if err != nil { return err } // Check if ignoring. for _, ignore := range ignores { if ignore == path { for p := range stats { if p == path || strings.Contains(p, path+string(filepath.Separator)) { delete(stats, p) } } if info.IsDir() { return filepath.SkipDir } return nil } } pstat, ok := stats[path] status := "" // Check if created/updated. if ok && (info.ModTime().After(pstat.ModTime()) || info.Mode() != pstat.Mode()) { status = "update" } else if !ok { status = "create" } // Ignore directory changes, and no event status. if info.IsDir() || status == "" { stats[path] = info found = append(found, path) return nil } err = watcher.Update(rel, status) if err != nil { if os.IsNotExist(err) { log.Debug("Ignoring temp file", status, "event", rel) return nil } return err } evChan <- &Event{watcher.Service.Name, status, rel} stats[path] = info found = append(found, path) return nil } for { // Check if we're done. select { case <-watcher.done: return default: } ignores, err = db.GetIgnores(watcher.Path) if err != nil { errChan <- watcher.wrapErr(err) return } err = filepath.Walk(watcher.Path, walker) if err != nil { errChan <- watcher.wrapErr(err) return } // Check for deletes. for path := range stats { skip := false rel, err := filepath.Rel(watcher.Path, path) if err != nil { errChan <- watcher.wrapErr(err) return } for _, f := range found { if f == path { skip = true break } } if skip { continue } delete(stats, path) err = watcher.Update(rel, "delete") if err != nil { errChan <- watcher.wrapErr(err) return } evChan <- &Event{watcher.Service.Name, "delete", rel} } found = make([]string, 0) <-time.After(500 * time.Millisecond) } }
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 }
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 }