func (p *dockerProvisioner) Destroy(app provision.App) error { containers, err := p.listContainersByApp(app.GetName()) if err != nil { log.Errorf("Failed to list app containers: %s", err.Error()) return err } runInContainers(containers, func(c *container, _ chan *container) error { unit := c.asUnit(app) err := app.UnbindUnit(&unit) if err != nil { log.Errorf("Unable to unbind unit %q: %s", c.ID, err) } err = p.removeContainer(c, app) if err != nil { log.Errorf("Unable to destroy container %s: %s", c.ID, err.Error()) } return nil }, nil, true) images, err := listAppImages(app.GetName()) if err != nil { log.Errorf("Failed to get image ids for app %s: %s", app.GetName(), err.Error()) } cluster := p.getCluster() for _, imageId := range images { err := cluster.RemoveImage(imageId) if err != nil { log.Errorf("Failed to remove image %s: %s", imageId, err.Error()) } err = cluster.RemoveFromRegistry(imageId) if err != nil { log.Errorf("Failed to remove image %s from registry: %s", imageId, err.Error()) } } err = deleteAllAppImageNames(app.GetName()) if err != nil { log.Errorf("Failed to remove image names from storage for app %s: %s", app.GetName(), err.Error()) } r, err := getRouterForApp(app) if err != nil { log.Errorf("Failed to get router: %s", err.Error()) return err } err = r.RemoveBackend(app.GetName()) if err != nil { log.Errorf("Failed to remove route backend: %s", err.Error()) return err } return nil }
func (p *dockerProvisioner) RemoveUnits(a provision.App, units uint, processName string, w io.Writer) error { if a == nil { return errors.New("remove units: app should not be nil") } if units == 0 { return errors.New("cannot remove zero units") } var err error if w == nil { w = ioutil.Discard } imgId, err := appCurrentImageName(a.GetName()) if err != nil { return err } _, processName, err = processCmdForImage(processName, imgId) if err != nil { return err } containers, err := p.listContainersByProcess(a.GetName(), processName) if err != nil { return err } if len(containers) < int(units) { return fmt.Errorf("cannot remove %d units from process %q, only %d available", units, processName, len(containers)) } var plural string if units > 1 { plural = "s" } fmt.Fprintf(w, "\n---- Removing %d unit%s ----\n", units, plural) coll := p.collection() defer coll.Close() toRemove := make([]container, 0, units) for i := 0; i < int(units); i++ { var containerID string var c *container containerID, err = p.scheduler.GetRemovableContainer(a.GetName(), processName) if err != nil { fmt.Println("GetRemovableContainer") break } c, err = p.getContainer(containerID) if err != nil { fmt.Println("getContainer") break } err = coll.Remove(bson.M{"id": c.ID}) if err != nil { fmt.Println("remove") break } toRemove = append(toRemove, *c) } if err != nil { for _, c := range toRemove { coll.Insert(c) } return err } runInContainers(toRemove, func(c *container, toRollback chan *container) error { unit := c.asUnit(a) err = a.UnbindUnit(&unit) if err != nil { log.Errorf("Ignored error trying to unbind unit %q: %s", c.ID, err) } err = p.removeContainer(c, a) if err != nil { log.Errorf("Ignored error trying to remove unit %q: %s", c.ID, err) } fmt.Fprintf(w, " ---> Removed unit %s...\n", c.shortID()) return nil }, nil, true) return nil }