func (r *actualLRPRetirer) RetireActualLRP(logger lager.Logger, processGuid string, index int32) error { var err error var cell *models.CellPresence logger = logger.Session("retire-actual-lrp", lager.Data{"process_guid": processGuid, "index": index}) for retryCount := 0; retryCount < models.RetireActualLRPRetryAttempts; retryCount++ { var lrpGroup *models.ActualLRPGroup lrpGroup, err = r.db.ActualLRPGroupByProcessGuidAndIndex(logger, processGuid, index) if err != nil { return err } lrp := lrpGroup.Instance if lrp == nil { return models.ErrResourceNotFound } switch lrp.State { case models.ActualLRPStateUnclaimed, models.ActualLRPStateCrashed: err = r.db.RemoveActualLRP(logger, lrp.ProcessGuid, lrp.Index, &lrp.ActualLRPInstanceKey) if err == nil { go r.actualHub.Emit(models.NewActualLRPRemovedEvent(lrpGroup)) } case models.ActualLRPStateClaimed, models.ActualLRPStateRunning: cell, err = r.serviceClient.CellById(logger, lrp.CellId) if err != nil { bbsErr := models.ConvertError(err) if bbsErr.Type == models.Error_ResourceNotFound { err = r.db.RemoveActualLRP(logger, lrp.ProcessGuid, lrp.Index, &lrp.ActualLRPInstanceKey) if err == nil { go r.actualHub.Emit(models.NewActualLRPRemovedEvent(lrpGroup)) } } return err } var client rep.Client client, err = r.repClientFactory.CreateClient(cell.RepAddress, cell.RepUrl) if err != nil { logger.Error("create-rep-client-failed", err) return err } err = client.StopLRPInstance(lrp.ActualLRPKey, lrp.ActualLRPInstanceKey) } if err == nil { return nil } logger.Error("retrying-failed-retire-of-actual-lrp", err, lager.Data{"attempt": retryCount + 1}) } return err }
func (h *EvacuationHandler) EvacuateStoppedActualLRP(logger lager.Logger, w http.ResponseWriter, req *http.Request) { logger = logger.Session("evacuate-stopped-actual-lrp") request := &models.EvacuateStoppedActualLRPRequest{} response := &models.EvacuationResponse{} var bbsErr *models.Error defer func() { exitIfUnrecoverable(logger, h.exitChan, bbsErr) }() defer writeResponse(w, response) err := parseRequest(logger, req, request) if err != nil { logger.Error("failed-to-parse-request", err) bbsErr = models.ConvertError(err) response.Error = bbsErr return } guid := request.ActualLrpKey.ProcessGuid index := request.ActualLrpKey.Index group, err := h.actualLRPDB.ActualLRPGroupByProcessGuidAndIndex(logger, guid, index) if err != nil { logger.Error("failed-fetching-actual-lrp-group", err) bbsErr = models.ConvertError(err) response.Error = bbsErr return } err = h.db.RemoveEvacuatingActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey) if err != nil { logger.Error("failed-removing-evacuating-actual-lrp", err) bbsErr = models.ConvertError(err) } else if group.Evacuating != nil { go h.actualHub.Emit(models.NewActualLRPRemovedEvent(&models.ActualLRPGroup{Evacuating: group.Evacuating})) } if group.Instance == nil || !group.Instance.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey) { logger.Debug("cannot-remove-actual-lrp") response.Error = models.ErrActualLRPCannotBeRemoved return } err = h.actualLRPDB.RemoveActualLRP(logger, guid, index, request.ActualLrpInstanceKey) if err != nil { logger.Error("failed-to-remove-actual-lrp", err) bbsErr = models.ConvertError(err) response.Error = bbsErr return } else { go h.actualHub.Emit(models.NewActualLRPRemovedEvent(&models.ActualLRPGroup{Instance: group.Instance})) } }
func (h *ActualLRPLifecycleHandler) RemoveActualLRP(logger lager.Logger, w http.ResponseWriter, req *http.Request) { var err error logger = logger.Session("remove-actual-lrp") request := &models.RemoveActualLRPRequest{} response := &models.ActualLRPLifecycleResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err = parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } beforeActualLRPGroup, err := h.db.ActualLRPGroupByProcessGuidAndIndex(logger, request.ProcessGuid, request.Index) if err != nil { response.Error = models.ConvertError(err) return } err = h.db.RemoveActualLRP(logger, request.ProcessGuid, request.Index, request.ActualLrpInstanceKey) if err != nil { response.Error = models.ConvertError(err) return } go h.actualHub.Emit(models.NewActualLRPRemovedEvent(beforeActualLRPGroup)) }
func (h *EvacuationHandler) EvacuateClaimedActualLRP(logger lager.Logger, w http.ResponseWriter, req *http.Request) { logger = logger.Session("evacuate-claimed-actual-lrp") logger.Info("started") defer logger.Info("completed") request := &models.EvacuateClaimedActualLRPRequest{} response := &models.EvacuationResponse{} defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) err := parseRequest(logger, req, request) if err != nil { logger.Error("failed-parsing-request", err) response.Error = models.ConvertError(err) response.KeepContainer = true return } beforeActualLRPGroup, err := h.actualLRPDB.ActualLRPGroupByProcessGuidAndIndex(logger, request.ActualLrpKey.ProcessGuid, request.ActualLrpKey.Index) if err == nil { err = h.db.RemoveEvacuatingActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey) if err != nil { logger.Error("failed-removing-evacuating-actual-lrp", err) exitIfUnrecoverable(logger, h.exitChan, models.ConvertError(err)) } else { go h.actualHub.Emit(models.NewActualLRPRemovedEvent(beforeActualLRPGroup)) } } err = h.unclaimAndRequestAuction(logger, request.ActualLrpKey) bbsErr := models.ConvertError(err) if bbsErr != nil && bbsErr.Type != models.Error_ResourceNotFound { response.Error = bbsErr response.KeepContainer = true return } }
It("returns the event", func() { event, err := eventSource.Next() Expect(err).NotTo(HaveOccurred()) actualLRPChangedEvent, ok := event.(*models.ActualLRPChangedEvent) Expect(ok).To(BeTrue()) Expect(actualLRPChangedEvent).To(Equal(expectedEvent)) }) }) Context("when receiving a ActualLRPRemovedEvent", func() { var expectedEvent *models.ActualLRPRemovedEvent BeforeEach(func() { expectedEvent = models.NewActualLRPRemovedEvent(actualLRPGroup) payload, err := proto.Marshal(expectedEvent) Expect(err).NotTo(HaveOccurred()) payload = []byte(base64.StdEncoding.EncodeToString(payload)) fakeRawEventSource.NextReturns( sse.Event{ ID: "sup", Name: string(expectedEvent.EventType()), Data: payload, }, nil, ) }) It("returns the event", func() {
func (h *EvacuationHandler) EvacuateRunningActualLRP(logger lager.Logger, w http.ResponseWriter, req *http.Request) { logger = logger.Session("evacuate-running-actual-lrp") response := &models.EvacuationResponse{} response.KeepContainer = true defer func() { exitIfUnrecoverable(logger, h.exitChan, response.Error) }() defer writeResponse(w, response) request := &models.EvacuateRunningActualLRPRequest{} err := parseRequest(logger, req, request) if err != nil { response.Error = models.ConvertError(err) return } guid := request.ActualLrpKey.ProcessGuid index := request.ActualLrpKey.Index actualLRPGroup, err := h.actualLRPDB.ActualLRPGroupByProcessGuidAndIndex(logger, guid, index) if err != nil { if err == models.ErrResourceNotFound { response.KeepContainer = false return } logger.Error("failed-fetching-lrp-group", err) response.Error = models.ConvertError(err) return } instance := actualLRPGroup.Instance evacuating := actualLRPGroup.Evacuating // If the instance is not there, clean up the corresponding evacuating LRP, if one exists. if instance == nil { err = h.db.RemoveEvacuatingActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey) if err != nil { if err == models.ErrActualLRPCannotBeRemoved { logger.Debug("remove-evacuating-actual-lrp-failed") response.KeepContainer = false return } logger.Error("failed-removing-evacuating-actual-lrp", err) response.Error = models.ConvertError(err) return } go h.actualHub.Emit(models.NewActualLRPRemovedEvent(&models.ActualLRPGroup{Evacuating: evacuating})) response.KeepContainer = false return } if (instance.State == models.ActualLRPStateUnclaimed && instance.PlacementError == "") || (instance.State == models.ActualLRPStateClaimed && !instance.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey)) { if evacuating != nil && !evacuating.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey) { logger.Error("already-evacuated-by-different-cell", err) response.KeepContainer = false return } group, err := h.db.EvacuateActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey, request.ActualLrpNetInfo, request.Ttl) if err == models.ErrActualLRPCannotBeEvacuated { logger.Error("cannot-evacuate-actual-lrp", err) response.KeepContainer = false return } response.KeepContainer = true if err != nil { logger.Error("failed-evacuating-actual-lrp", err) response.Error = models.ConvertError(err) } else { go h.actualHub.Emit(models.NewActualLRPCreatedEvent(group)) } return } if (instance.State == models.ActualLRPStateUnclaimed && instance.PlacementError != "") || (instance.State == models.ActualLRPStateRunning && !instance.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey)) || instance.State == models.ActualLRPStateCrashed { response.KeepContainer = false err = h.db.RemoveEvacuatingActualLRP(logger, &evacuating.ActualLRPKey, &evacuating.ActualLRPInstanceKey) if err == nil { go h.actualHub.Emit(models.NewActualLRPRemovedEvent(&models.ActualLRPGroup{Evacuating: evacuating})) } if err != nil && err != models.ErrActualLRPCannotBeRemoved { response.KeepContainer = true response.Error = models.ConvertError(err) } return } if (instance.State == models.ActualLRPStateClaimed || instance.State == models.ActualLRPStateRunning) && instance.ActualLRPInstanceKey.Equal(request.ActualLrpInstanceKey) { group, err := h.db.EvacuateActualLRP(logger, request.ActualLrpKey, request.ActualLrpInstanceKey, request.ActualLrpNetInfo, request.Ttl) if err != nil { response.Error = models.ConvertError(err) return } go h.actualHub.Emit(models.NewActualLRPCreatedEvent(group)) err = h.unclaimAndRequestAuction(logger, request.ActualLrpKey) if err != nil { response.Error = models.ConvertError(err) return } } }