Ejemplo n.º 1
0
// 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()
}
Ejemplo n.º 2
0
// 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()
}
Ejemplo n.º 3
0
// 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)
	}
}
Ejemplo n.º 4
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
}
Ejemplo n.º 5
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
}