func (a *AuctionCellRep) lrpsToAllocationRequest(lrps []rep.LRP) ([]executor.AllocationRequest, map[string]*rep.LRP, []rep.LRP) { requests := make([]executor.AllocationRequest, 0, len(lrps)) untranslatedLRPs := make([]rep.LRP, 0) lrpMap := make(map[string]*rep.LRP, len(lrps)) for i := range lrps { lrp := &lrps[i] tags := executor.Tags{} instanceGuid, err := a.generateInstanceGuid() if err != nil { untranslatedLRPs = append(untranslatedLRPs, *lrp) continue } tags[rep.DomainTag] = lrp.Domain tags[rep.ProcessGuidTag] = lrp.ProcessGuid tags[rep.ProcessIndexTag] = strconv.Itoa(int(lrp.Index)) tags[rep.LifecycleTag] = rep.LRPLifecycle tags[rep.InstanceGuidTag] = instanceGuid rootFSPath, err := PathForRootFS(lrp.RootFs, a.stackPathMap) if err != nil { untranslatedLRPs = append(untranslatedLRPs, *lrp) continue } containerGuid := rep.LRPContainerGuid(lrp.ProcessGuid, instanceGuid) lrpMap[containerGuid] = lrp resource := executor.NewResource(int(lrp.MemoryMB), int(lrp.DiskMB), rootFSPath) requests = append(requests, executor.NewAllocationRequest(containerGuid, &resource, tags)) } return requests, lrpMap, untranslatedLRPs }
func (h StopLRPInstanceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { processGuid := r.FormValue(":process_guid") instanceGuid := r.FormValue(":instance_guid") logger := h.logger.Session("handling-stop-lrp-instance", lager.Data{ "process-guid": processGuid, "instance-guid": instanceGuid, }) if processGuid == "" { err := errors.New("process_guid missing from request") logger.Error("missing-process-guid", err) w.WriteHeader(http.StatusBadRequest) return } if instanceGuid == "" { err := errors.New("instance_guid missing from request") logger.Error("missing-instance-guid", err) w.WriteHeader(http.StatusBadRequest) return } err := h.client.StopContainer(logger, rep.LRPContainerGuid(processGuid, instanceGuid)) if err != nil { w.WriteHeader(http.StatusInternalServerError) logger.Error("failed-to-stop-container", err) return } w.WriteHeader(http.StatusAccepted) }
func (stopper *lrpStopper) StopInstance(processGuid, instanceGuid string) error { stopLog := stopper.logger.Session("stop", lager.Data{ "process-guid": processGuid, "instance-guid": instanceGuid, }) stopLog.Info("stopping") defer stopLog.Info("finished") return stopper.client.StopContainer(rep.LRPContainerGuid(processGuid, instanceGuid)) }
func (o *ResidualEvacuatingLRPOperation) Execute() { logger := o.logger.Session("executing-residual-evacuating-lrp-operation", lager.Data{ "lrp-key": o.ActualLRPKey, "lrp-instance-key": o.ActualLRPInstanceKey, }) logger.Info("starting") defer logger.Info("finished") _, exists := o.containerDelegate.GetContainer(logger, rep.LRPContainerGuid(o.GetProcessGuid(), o.GetInstanceGuid())) if exists { logger.Info("skipped-because-container-exists") return } o.bbsClient.RemoveEvacuatingActualLRP(&o.ActualLRPKey, &o.ActualLRPInstanceKey) }
func (o *ResidualJointLRPOperation) Execute() { logger := o.logger.Session("executing-residual-joint-lrp-operation", lager.Data{ "lrp-key": o.ActualLRPKey, "lrp-instance-key": o.ActualLRPInstanceKey, }) logger.Info("starting") defer logger.Info("finished") _, exists := o.containerDelegate.GetContainer(logger, rep.LRPContainerGuid(o.GetProcessGuid(), o.GetInstanceGuid())) if exists { logger.Info("skipped-because-container-exists") return } actualLRPKey := models.NewActualLRPKey(o.ProcessGuid, int32(o.Index), o.Domain) actualLRPInstanceKey := models.NewActualLRPInstanceKey(o.InstanceGuid, o.CellId) o.bbsClient.RemoveActualLRP(o.ProcessGuid, int(o.Index)) o.bbsClient.RemoveEvacuatingActualLRP(&actualLRPKey, &actualLRPInstanceKey) }
func newLRPContainer(lrpKey models.ActualLRPKey, instanceKey models.ActualLRPInstanceKey, netInfo models.ActualLRPNetInfo) executor.Container { ports := []executor.PortMapping{} for _, portMap := range netInfo.Ports { ports = append(ports, executor.PortMapping{ ContainerPort: uint16(portMap.ContainerPort), HostPort: uint16(portMap.HostPort), }) } return executor.Container{ Guid: rep.LRPContainerGuid(lrpKey.ProcessGuid, instanceKey.InstanceGuid), RunInfo: executor.RunInfo{ Action: models.WrapAction(&models.RunAction{Path: "true"}), Ports: ports, }, ExternalIP: netInfo.Address, Tags: executor.Tags{ rep.ProcessGuidTag: lrpKey.ProcessGuid, rep.InstanceGuidTag: instanceKey.InstanceGuid, rep.ProcessIndexTag: strconv.Itoa(int(lrpKey.Index)), rep.DomainTag: lrpKey.Domain, }, } }
instanceKey := models.NewActualLRPInstanceKey("some-instance-guid", cellID) err = bbsClient.ClaimActualLRP(desiredLRP.ProcessGuid, index, &instanceKey) Expect(err).NotTo(HaveOccurred()) }) It("eventually reaps actual LRPs with no corresponding container", func() { Eventually(getActualLRPGroups, 5*pollingInterval).Should(BeEmpty()) }) }) Describe("when a StopLRPInstance request comes in", func() { const processGuid = "process-guid" const instanceGuid = "some-instance-guid" var runningLRP *models.ActualLRP var containerGuid = rep.LRPContainerGuid(processGuid, instanceGuid) var expectedDestroyRoute = "/containers/" + containerGuid JustBeforeEach(func() { fakeGarden.RouteToHandler("DELETE", expectedDestroyRoute, ghttp.RespondWithJSONEncoded(http.StatusOK, &struct{}{}), ) // ensure the container remains after being stopped fakeGarden.RouteToHandler("GET", "/containers", ghttp.RespondWithJSONEncoded(http.StatusOK, map[string][]string{ "handles": []string{containerGuid}, }), ) containerInfo := garden.ContainerInfo{
const ( instanceGuidContainerOnly = "guid-container-only" instanceGuidContainerForInstanceLRP = "guid-container-for-instance-lrp" instanceGuidContainerForEvacuatingLRP = "guid-container-for-evacuating-lrp" guidContainerForTask = "guid-container-for-task" instanceGuidInstanceLRPOnly = "guid-instance-lrp-only" instanceGuidEvacuatingLRPOnly = "guid-evacuating-lrp-only" instanceGuidInstanceAndEvacuatingLRPsOnly = "guid-instance-and-evacuating-lrps-only" guidTaskOnly = "guid-task-only" processGuid = "process-guid" ) BeforeEach(func() { containers := []executor.Container{ {Guid: rep.LRPContainerGuid(processGuid, instanceGuidContainerOnly)}, {Guid: rep.LRPContainerGuid(processGuid, instanceGuidContainerForInstanceLRP)}, {Guid: rep.LRPContainerGuid(processGuid, instanceGuidContainerForEvacuatingLRP)}, {Guid: guidContainerForTask}, } actualLRPKey := models.ActualLRPKey{ProcessGuid: processGuid} containerOnlyLRP := models.ActualLRP{ActualLRPKey: actualLRPKey, ActualLRPInstanceKey: models.NewActualLRPInstanceKey(instanceGuidContainerForInstanceLRP, cellID)} instanceOnlyLRP := models.ActualLRP{ActualLRPKey: actualLRPKey, ActualLRPInstanceKey: models.NewActualLRPInstanceKey(instanceGuidInstanceLRPOnly, cellID)} containerForEvacuatingLRP := models.ActualLRP{ActualLRPKey: actualLRPKey, ActualLRPInstanceKey: models.NewActualLRPInstanceKey(instanceGuidContainerForEvacuatingLRP, cellID)} evacuatingOnlyLRP := models.ActualLRP{ActualLRPKey: actualLRPKey, ActualLRPInstanceKey: models.NewActualLRPInstanceKey(instanceGuidEvacuatingLRPOnly, cellID)} instanceAndEvacuatingLRP := models.ActualLRP{ActualLRPKey: actualLRPKey, ActualLRPInstanceKey: models.NewActualLRPInstanceKey(instanceGuidInstanceAndEvacuatingLRPsOnly, cellID)}
var ( containerDelegate *fake_internal.FakeContainerDelegate residualLRPOperation *generator.ResidualInstanceLRPOperation lrpKey models.ActualLRPKey instanceKey models.ActualLRPInstanceKey expectedContainerGuid string ) BeforeEach(func() { lrpKey = models.NewActualLRPKey("the-process-guid", 0, "the-domain") instanceKey = models.NewActualLRPInstanceKey("the-instance-guid", "the-cell-id") containerDelegate = new(fake_internal.FakeContainerDelegate) residualLRPOperation = generator.NewResidualInstanceLRPOperation(logger, fakeBBS, containerDelegate, lrpKey, instanceKey) expectedContainerGuid = rep.LRPContainerGuid(lrpKey.GetProcessGuid(), instanceKey.GetInstanceGuid()) }) Describe("Key", func() { It("returns the InstanceGuid", func() { Expect(residualLRPOperation.Key()).To(Equal("the-instance-guid")) }) }) Describe("Execute", func() { const sessionName = "test.executing-residual-instance-lrp-operation" JustBeforeEach(func() { residualLRPOperation.Execute() })
func (g *generator) BatchOperations(logger lager.Logger) (map[string]operationq.Operation, error) { logger = logger.Session("batch-operations") logger.Info("started") containers := make(map[string]executor.Container) instanceLRPs := make(map[string]models.ActualLRP) evacuatingLRPs := make(map[string]models.ActualLRP) tasks := make(map[string]*models.Task) errChan := make(chan error, 3) logger.Info("getting-containers-lrps-and-tasks") go func() { foundContainers, err := g.executorClient.ListContainers(nil) if err != nil { logger.Error("failed-to-list-containers", err) err = fmt.Errorf("failed to list containers: %s", err.Error()) } for _, c := range foundContainers { containers[c.Guid] = c } errChan <- err }() go func() { filter := models.ActualLRPFilter{CellID: g.cellID} groups, err := g.bbs.ActualLRPGroups(filter) if err != nil { logger.Error("failed-to-retrieve-lrp-groups", err) err = fmt.Errorf("failed to retrieve lrps: %s", err.Error()) } for _, group := range groups { if group.Instance != nil { instanceLRPs[rep.LRPContainerGuid(group.Instance.GetProcessGuid(), group.Instance.GetInstanceGuid())] = *group.Instance } if group.Evacuating != nil { evacuatingLRPs[rep.LRPContainerGuid(group.Evacuating.GetProcessGuid(), group.Evacuating.GetInstanceGuid())] = *group.Evacuating } } errChan <- err }() go func() { foundTasks, err := g.bbs.TasksByCellID(g.cellID) if err != nil { logger.Error("failed-to-retrieve-tasks", err) err = fmt.Errorf("failed to retrieve tasks: %s", err.Error()) } for _, task := range foundTasks { tasks[task.TaskGuid] = task } errChan <- err }() var err error for i := 0; i < 3; i++ { e := <-errChan if err == nil && e != nil { err = e } } if err != nil { logger.Error("failed-getting-containers-lrps-and-tasks", err) return nil, err } logger.Info("succeeded-getting-containers-lrps-and-tasks") batch := make(map[string]operationq.Operation) // create operations for processes with containers for guid, _ := range containers { batch[guid] = g.operationFromContainer(logger, guid) } // create operations for instance lrps with no containers for guid, lrp := range instanceLRPs { if _, foundContainer := batch[guid]; foundContainer { continue } if _, foundEvacuatingLRP := evacuatingLRPs[guid]; foundEvacuatingLRP { batch[guid] = NewResidualJointLRPOperation(logger, g.bbs, g.containerDelegate, lrp.ActualLRPKey, lrp.ActualLRPInstanceKey) } else { batch[guid] = NewResidualInstanceLRPOperation(logger, g.bbs, g.containerDelegate, lrp.ActualLRPKey, lrp.ActualLRPInstanceKey) } } // create operations for evacuating lrps with no containers for guid, lrp := range evacuatingLRPs { _, found := batch[guid] if !found { batch[guid] = NewResidualEvacuatingLRPOperation(logger, g.bbs, g.containerDelegate, lrp.ActualLRPKey, lrp.ActualLRPInstanceKey) } } // create operations for tasks with no containers for guid, _ := range tasks { _, found := batch[guid] if !found { batch[guid] = NewResidualTaskOperation(logger, guid, g.bbs, g.containerDelegate) } } logger.Info("succeeded", lager.Data{"batch-size": len(batch)}) return batch, nil }
processGuid = "process-guid" desiredLRP = models.DesiredLRP{ Domain: "domain", ProcessGuid: processGuid, Instances: 1, RootFs: "some-rootfs", Action: models.WrapAction(&models.RunAction{ Path: "/bin/true", }), } instanceGuid = "instance-guid" index = 0 container = executor.Container{ Guid: rep.LRPContainerGuid(desiredLRP.ProcessGuid, instanceGuid), Tags: executor.Tags{ rep.LifecycleTag: rep.LRPLifecycle, rep.DomainTag: desiredLRP.Domain, rep.ProcessGuidTag: desiredLRP.ProcessGuid, rep.InstanceGuidTag: instanceGuid, rep.ProcessIndexTag: strconv.Itoa(index), }, } lrpKey = models.NewActualLRPKey(processGuid, int32(index), desiredLRP.Domain) lrpInstanceKey = models.NewActualLRPInstanceKey(instanceGuid, localCellID) }) JustBeforeEach(func() { lrpProcessor.Process(logger, container)
BeforeEach(func() { lrpAuctionOne.RootFs = linuxRootFSURL lrpAuctionTwo.RootFs = "unsupported-arbitrary://still-goes-through" }) It("makes the correct allocation requests for all LRP Auctions", func() { _, err := cellRep.Perform(rep.Work{ LRPs: []rep.LRP{lrpAuctionOne, lrpAuctionTwo}, }) Expect(err).NotTo(HaveOccurred()) Expect(client.AllocateContainersCallCount()).To(Equal(1)) _, arg := client.AllocateContainersArgsForCall(0) Expect(arg).To(ConsistOf( executor.AllocationRequest{ Guid: rep.LRPContainerGuid(lrpAuctionOne.ProcessGuid, expectedGuidOne), Tags: executor.Tags{ rep.LifecycleTag: rep.LRPLifecycle, rep.DomainTag: lrpAuctionOne.Domain, rep.ProcessGuidTag: lrpAuctionOne.ProcessGuid, rep.InstanceGuidTag: expectedGuidOne, rep.ProcessIndexTag: expectedIndexOneString, }, Resource: executor.NewResource(int(lrpAuctionOne.MemoryMB), int(lrpAuctionOne.DiskMB), linuxPath), }, executor.AllocationRequest{ Guid: rep.LRPContainerGuid(lrpAuctionTwo.ProcessGuid, expectedGuidTwo), Tags: executor.Tags{ rep.LifecycleTag: rep.LRPLifecycle, rep.DomainTag: lrpAuctionTwo.Domain, rep.ProcessGuidTag: lrpAuctionTwo.ProcessGuid,