func setUnitsStatus(w http.ResponseWriter, r *http.Request, t auth.Token) error { if t.GetAppName() != app.InternalAppName { return &errors.HTTP{Code: http.StatusForbidden, Message: "this token is not allowed to execute this action"} } defer r.Body.Close() var input []map[string]string err := json.NewDecoder(r.Body).Decode(&input) if err != nil { return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()} } units := make(map[string]provision.Status, len(input)) for _, unit := range input { units[unit["ID"]] = provision.Status(unit["Status"]) } result, err := app.UpdateUnitsStatus(units) if err != nil { return err } resp := make([]updateUnitsResponse, 0, len(result)) for unit, found := range result { resp = append(resp, updateUnitsResponse{ID: unit, Found: found}) } w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) return json.NewEncoder(w).Encode(resp) }
// unitFromContainer returns a unit that represents a container. func unitFromContainer(c container) provision.Unit { return provision.Unit{ Name: c.ID, AppName: c.AppName, Type: c.Type, Status: provision.Status(c.Status), Ip: c.HostAddr, } }
func (p *dockerProvisioner) MoveOneContainer(c container.Container, toHost string, errors chan error, wg *sync.WaitGroup, writer io.Writer, locker container.AppLocker) container.Container { if wg != nil { defer wg.Done() } locked := locker.Lock(c.AppName) if !locked { errors <- fmt.Errorf("couldn't move %s, unable to lock %q", c.ID, c.AppName) return container.Container{} } defer locker.Unlock(c.AppName) a, err := app.GetByName(c.AppName) if err != nil { errors <- &tsuruErrors.CompositeError{ Base: err, Message: fmt.Sprintf("error getting app %q for unit %s", c.AppName, c.ID), } return container.Container{} } imageId, err := appCurrentImageName(a.GetName()) if err != nil { errors <- &tsuruErrors.CompositeError{ Base: err, Message: fmt.Sprintf("error getting app %q image name for unit %s", c.AppName, c.ID), } return container.Container{} } var destHosts []string var suffix string if toHost != "" { destHosts = []string{toHost} suffix = " -> " + toHost } if !p.isDryMode { fmt.Fprintf(writer, "Moving unit %s for %q from %s%s...\n", c.ID, c.AppName, c.HostAddr, suffix) } toAdd := map[string]*containersToAdd{c.ProcessName: {Quantity: 1, Status: provision.Status(c.Status)}} addedContainers, err := p.runReplaceUnitsPipeline(nil, a, toAdd, []container.Container{c}, imageId, destHosts...) if err != nil { errors <- &tsuruErrors.CompositeError{ Base: err, Message: fmt.Sprintf("Error moving unit %s", c.ID), } return container.Container{} } prefix := "Moved unit" if p.isDryMode { prefix = "Would move unit" } fmt.Fprintf(writer, "%s %s -> %s for %q from %s -> %s\n", prefix, c.ID, addedContainers[0].ID, c.AppName, c.HostAddr, addedContainers[0].HostAddr) return addedContainers[0] }
func (s *S) TestUnitFromContainer(c *gocheck.C) { cont := container{ ID: "someid", AppName: "someapp", Type: "django", Status: provision.StatusStarted.String(), HostAddr: "10.9.8.7", } expected := provision.Unit{ Name: cont.ID, AppName: cont.AppName, Type: cont.Type, Status: provision.Status(cont.Status), Ip: cont.HostAddr, } c.Assert(unitFromContainer(cont), gocheck.Equals, expected) }
func (p *dockerProvisioner) Units(app provision.App) []provision.Unit { containers, err := listContainersByApp(app.GetName()) if err != nil { return nil } units := []provision.Unit{} for _, container := range containers { unit := provision.Unit{ Name: container.ID, AppName: container.AppName, Type: container.Type, Status: provision.Status(container.Status), Ip: container.HostAddr, } units = append(units, unit) } return units }
func (c *container) asUnit(a provision.App) provision.Unit { status := provision.Status(c.Status) if c.Status == "" { status = provision.StatusBuilding } cType := c.Type if cType == "" { cType = a.GetPlatform() } return provision.Unit{ Name: c.ID, AppName: a.GetName(), Type: cType, Ip: c.HostAddr, Status: status, ProcessName: c.ProcessName, } }
func (s *S) TestContainerExpectedStatus(c *check.C) { c1 := Container{ID: "something-300"} coll := s.p.Collection() defer coll.Close() coll.Insert(c1) c.Assert(c1.ExpectedStatus(), check.Equals, provision.Status("")) err := c1.SetStatus(s.p, provision.StatusStarted, true) c.Assert(err, check.IsNil) c.Assert(c1.ExpectedStatus(), check.Equals, provision.StatusStarted) err = c1.SetStatus(s.p, provision.StatusError, true) c.Assert(err, check.IsNil) c.Assert(c1.ExpectedStatus(), check.Equals, provision.StatusStarted) err = c1.SetStatus(s.p, provision.StatusStopped, true) c.Assert(err, check.IsNil) c.Assert(c1.ExpectedStatus(), check.Equals, provision.StatusStopped) err = c1.SetStatus(s.p, provision.StatusError, true) c.Assert(err, check.IsNil) c.Assert(c1.ExpectedStatus(), check.Equals, provision.StatusStopped) }
func (p *dockerProvisioner) Restart(a provision.App, process string, w io.Writer) error { containers, err := p.listContainersByProcess(a.GetName(), process) if err != nil { return err } imageId, err := appCurrentImageName(a.GetName()) if err != nil { return err } if w == nil { w = ioutil.Discard } writer := io.MultiWriter(w, &app.LogWriter{App: a}) toAdd := make(map[string]*containersToAdd, len(containers)) for _, c := range containers { if _, ok := toAdd[c.ProcessName]; !ok { toAdd[c.ProcessName] = &containersToAdd{Quantity: 0} } toAdd[c.ProcessName].Quantity++ toAdd[c.ProcessName].Status = provision.Status(c.Status) } _, err = p.runReplaceUnitsPipeline(writer, a, toAdd, containers, imageId) return err }
func (s *S) newContainer(opts *newContainerOpts, p *dockerProvisioner) (*container.Container, error) { container := container.Container{ ID: "id", IP: "10.10.10.10", HostPort: "3333", HostAddr: "127.0.0.1", ProcessName: "web", ExposedPort: "8888/tcp", } if p == nil { p = s.p } imageName := "tsuru/python:latest" var customData map[string]interface{} if opts != nil { if opts.Image != "" { imageName = opts.Image } container.AppName = opts.AppName container.ProcessName = opts.ProcessName customData = opts.ImageCustomData if opts.Provisioner != nil { p = opts.Provisioner } container.SetStatus(p, provision.Status(opts.Status), false) } err := s.newFakeImage(p, imageName, customData) if err != nil { return nil, err } if container.AppName == "" { container.AppName = "container" } routertest.FakeRouter.AddBackend(container.AppName) routertest.FakeRouter.AddRoute(container.AppName, container.Address()) ports := map[docker.Port]struct{}{ docker.Port(s.port + "/tcp"): {}, } config := docker.Config{ Image: imageName, Cmd: []string{"ps"}, ExposedPorts: ports, } createOptions := docker.CreateContainerOptions{Config: &config} createOptions.Name = randomString() _, c, err := p.Cluster().CreateContainer(createOptions, net.StreamInactivityTimeout) if err != nil { return nil, err } container.ID = c.ID container.Image = imageName container.Name = createOptions.Name conn, err := db.Conn() if err != nil { return nil, err } defer conn.Close() err = conn.Collection(s.collName).Insert(&container) if err != nil { return nil, err } imageId, err := image.AppCurrentImageName(container.AppName) if err != nil { return nil, err } err = s.newFakeImage(p, imageId, nil) if err != nil { return nil, err } return &container, nil }
func (c *Container) ExpectedStatus() provision.Status { if c.StatusBeforeError != "" { return provision.Status(c.StatusBeforeError) } return provision.Status(c.Status) }
func (u *Unit) GetStatus() provision.Status { return provision.Status(u.State) }