func convertConsulError(err error) error { switch err.(type) { case consuladapter.KeyNotFoundError: return models.NewError(models.Error_ResourceNotFound, err.Error()) case consuladapter.PrefixNotFoundError: return models.NewError(models.Error_ResourceNotFound, err.Error()) default: return models.NewError(models.Error_UnknownError, err.Error()) } }
func (db *ETCDDB) createActualLRP(logger lager.Logger, desiredLRP *models.DesiredLRP, index int32) error { logger = logger.Session("create-actual-lrp") var err error if index >= desiredLRP.Instances { err = models.NewError(models.Error_InvalidRecord, "Index too large") logger.Error("actual-lrp-index-too-large", err, lager.Data{"actual_index": index, "desired_instances": desiredLRP.Instances}) return err } guid, err := uuid.NewV4() if err != nil { return err } actualLRP := &models.ActualLRP{ ActualLRPKey: models.NewActualLRPKey( desiredLRP.ProcessGuid, index, desiredLRP.Domain, ), State: models.ActualLRPStateUnclaimed, Since: db.clock.Now().UnixNano(), ModificationTag: models.ModificationTag{ Epoch: guid.String(), Index: 0, }, } err = db.createRawActualLRP(logger, actualLRP) if err != nil { return err } return nil }
func parseRequestForDesireDesiredLRP_r0(logger lager.Logger, req *http.Request, request *models.DesireLRPRequest) error { data, err := ioutil.ReadAll(req.Body) if err != nil { logger.Error("failed-to-read-body", err) return models.ErrUnknownError } err = request.Unmarshal(data) if err != nil { logger.Error("failed-to-parse-request-body", err) return models.ErrBadRequest } request.DesiredLrp.Action.SetTimeoutMsFromDeprecatedTimeoutNs() request.DesiredLrp.Setup.SetTimeoutMsFromDeprecatedTimeoutNs() request.DesiredLrp.Monitor.SetTimeoutMsFromDeprecatedTimeoutNs() request.DesiredLrp.StartTimeoutMs = int64(request.DesiredLrp.DeprecatedStartTimeoutS * 1000) if err := request.Validate(); err != nil { logger.Error("invalid-request", err) return models.NewError(models.Error_InvalidRequest, err.Error()) } return nil }
func (db *ETCDDB) deserializeModel(logger lager.Logger, node *etcdclient.Node, model format.Versioner) error { // this is the number of desired instances err := db.serializer.Unmarshal(logger, []byte(node.Value), model) if err != nil { logger.Error("failed-to-deserialize-model", err) return models.NewError(models.Error_InvalidRecord, err.Error()) } return nil }
func (db *ETCDDB) serializeModel(logger lager.Logger, model format.Versioner) ([]byte, error) { encodedPayload, err := db.serializer.Marshal(logger, db.format, model) if err != nil { logger.Error("failed-to-serialize-model", err) return nil, models.NewError(models.Error_InvalidRecord, err.Error()) } return encodedPayload, nil }
func (db *SQLDB) deserializeModel(logger lager.Logger, data []byte, model format.Versioner) error { err := db.serializer.Unmarshal(logger, data, model) if err != nil { logger.Error("failed-to-deserialize-model", err) return models.NewError(models.Error_InvalidRecord, err.Error()) } return nil }
func (db *ETCDDB) unclaimActualLRPWithIndex( logger lager.Logger, lrp *models.ActualLRP, storeIndex uint64, actualLRPKey *models.ActualLRPKey, actualLRPInstanceKey *models.ActualLRPInstanceKey, ) (change stateChange, err error) { logger = logger.Session("unclaim-actual-lrp-with-index") defer func() { logger.Debug("complete", lager.Data{"stateChange": change, "error": err}) }() if !lrp.ActualLRPKey.Equal(actualLRPKey) { logger.Error("failed-actual-lrp-key-differs", models.ErrActualLRPCannotBeUnclaimed) return stateDidNotChange, models.ErrActualLRPCannotBeUnclaimed } if lrp.State == models.ActualLRPStateUnclaimed { logger.Info("already-unclaimed") return stateDidNotChange, nil } if !lrp.ActualLRPInstanceKey.Equal(actualLRPInstanceKey) { logger.Error("failed-actual-lrp-instance-key-differs", models.ErrActualLRPCannotBeUnclaimed) return stateDidNotChange, models.ErrActualLRPCannotBeUnclaimed } lrp.Since = db.clock.Now().UnixNano() lrp.State = models.ActualLRPStateUnclaimed lrp.ActualLRPInstanceKey = models.ActualLRPInstanceKey{} lrp.ActualLRPNetInfo = models.EmptyActualLRPNetInfo() lrp.ModificationTag.Increment() err = lrp.Validate() if err != nil { logger.Error("failed-to-validate-unclaimed-lrp", err) return stateDidNotChange, models.NewError(models.Error_InvalidRecord, err.Error()) } lrpData, serialErr := db.serializeModel(logger, lrp) if serialErr != nil { logger.Error("failed-to-marshal-unclaimed-lrp", serialErr) return stateDidNotChange, serialErr } _, err = db.client.CompareAndSwap(ActualLRPSchemaPath(actualLRPKey.ProcessGuid, actualLRPKey.Index), lrpData, 0, storeIndex) if err != nil { logger.Error("failed-to-compare-and-swap", err) return stateDidNotChange, models.ErrActualLRPCannotBeUnclaimed } logger.Debug("changed-to-unclaimed") return stateDidChange, nil }
func (db *serviceClient) CellById(logger lager.Logger, cellId string) (*models.CellPresence, error) { value, err := db.getAcquiredValue(CellSchemaPath(cellId)) if err != nil { return nil, convertConsulError(err) } presence := new(models.CellPresence) err = models.FromJSON(value, presence) if err != nil { return nil, models.NewError(models.Error_InvalidJSON, err.Error()) } return presence, nil }
func (db *ETCDDB) ClaimActualLRP(logger lager.Logger, processGuid string, index int32, instanceKey *models.ActualLRPInstanceKey) (*models.ActualLRPGroup, *models.ActualLRPGroup, error) { logger = logger.WithData(lager.Data{"process_guid": processGuid, "index": index, "actual_lrp_instance_key": instanceKey}) logger.Info("starting") lrp, prevIndex, err := db.rawActualLRPByProcessGuidAndIndex(logger, processGuid, index) if err != nil { logger.Error("failed", err) return nil, nil, err } beforeActualLRP := *lrp if !lrp.AllowsTransitionTo(&lrp.ActualLRPKey, instanceKey, models.ActualLRPStateClaimed) { return nil, nil, models.ErrActualLRPCannotBeClaimed } if lrp.State == models.ActualLRPStateClaimed && lrp.ActualLRPInstanceKey.Equal(instanceKey) { return &models.ActualLRPGroup{Instance: &beforeActualLRP}, &models.ActualLRPGroup{Instance: lrp}, nil } lrp.PlacementError = "" lrp.State = models.ActualLRPStateClaimed lrp.ActualLRPInstanceKey = *instanceKey lrp.ActualLRPNetInfo = models.ActualLRPNetInfo{} lrp.ModificationTag.Increment() lrp.Since = db.clock.Now().UnixNano() err = lrp.Validate() if err != nil { logger.Error("failed", err) return nil, nil, models.NewError(models.Error_InvalidRecord, err.Error()) } lrpData, serializeErr := db.serializeModel(logger, lrp) if serializeErr != nil { return nil, nil, serializeErr } _, err = db.client.CompareAndSwap(ActualLRPSchemaPath(processGuid, index), lrpData, 0, prevIndex) if err != nil { logger.Error("compare-and-swap-failed", err) return nil, nil, models.ErrActualLRPCannotBeClaimed } logger.Info("succeeded") return &models.ActualLRPGroup{Instance: &beforeActualLRP}, &models.ActualLRPGroup{Instance: lrp}, nil }
func parseRequest(logger lager.Logger, req *http.Request, request MessageValidator) error { data, err := ioutil.ReadAll(req.Body) if err != nil { logger.Error("failed-to-read-body", err) return models.ErrUnknownError } err = request.Unmarshal(data) if err != nil { logger.Error("failed-to-parse-request-body", err) return models.ErrBadRequest } if err := request.Validate(); err != nil { logger.Error("invalid-request", err) return models.NewError(models.Error_InvalidRequest, err.Error()) } return nil }
func (db *ETCDDB) ClaimActualLRP(logger lager.Logger, processGuid string, index int32, instanceKey *models.ActualLRPInstanceKey) error { logger = logger.Session("claim-actual-lrp", lager.Data{"process_guid": processGuid, "index": index, "actual_lrp_instance-key": instanceKey}) logger.Info("starting") lrp, prevIndex, err := db.rawActuaLLRPByProcessGuidAndIndex(logger, processGuid, index) if err != nil { logger.Error("failed", err) return err } if !lrp.AllowsTransitionTo(&lrp.ActualLRPKey, instanceKey, models.ActualLRPStateClaimed) { return models.ErrActualLRPCannotBeClaimed } lrp.PlacementError = "" lrp.State = models.ActualLRPStateClaimed lrp.ActualLRPInstanceKey = *instanceKey lrp.ActualLRPNetInfo = models.ActualLRPNetInfo{} lrp.ModificationTag.Increment() err = lrp.Validate() if err != nil { logger.Error("failed", err) return models.NewError(models.Error_InvalidRecord, err.Error()) } lrpData, serializeErr := db.serializeModel(logger, lrp) if serializeErr != nil { return serializeErr } _, err = db.client.CompareAndSwap(ActualLRPSchemaPath(processGuid, index), lrpData, 0, prevIndex) if err != nil { logger.Error("compare-and-swap-failed", err) return models.ErrActualLRPCannotBeClaimed } logger.Info("succeeded") return nil }
Context("when the task has a completion callback URL", func() { BeforeEach(func() { Expect(taskDB.ResolvingTaskCallCount()).To(Equal(0)) }) It("marks the task as resolving", func() { statusCodes <- 200 Eventually(taskDB.ResolvingTaskCallCount).Should(Equal(1)) _, actualGuid := taskDB.ResolvingTaskArgsForCall(0) Expect(actualGuid).To(Equal("the-task-guid")) }) Context("when marking the task as resolving fails", func() { BeforeEach(func() { taskDB.ResolvingTaskReturns(models.NewError(models.Error_UnknownError, "failed to resolve task")) }) It("does not make a request to the task's callback URL", func() { Consistently(fakeServer.ReceivedRequests, 0.25).Should(BeEmpty()) }) }) Context("when marking the task as resolving succeeds", func() { It("POSTs to the task's callback URL", func() { statusCodes <- 200 Eventually(fakeServer.ReceivedRequests).Should(HaveLen(1)) }) Context("when the request succeeds", func() { BeforeEach(func() {
It("creates a task on Diego", func() { Expect(fakeDiegoClient.DesireTaskCallCount()).To(Equal(1)) _, _, resultingTaskDef := fakeDiegoClient.DesireTaskArgsForCall(0) Expect(resultingTaskDef).To(Equal(fakeTaskDef)) }) Context("when creating the task succeeds", func() { It("does not send a staging failure response", func() { Expect(fakeCcClient.StagingCompleteCallCount()).To(Equal(0)) }) }) Context("when the task has already been created", func() { BeforeEach(func() { fakeDiegoClient.DesireTaskReturns(models.NewError(models.Error_ResourceExists, "ok, this task already exists")) }) It("does not log a failure", func() { Expect(logger).NotTo(gbytes.Say("staging-failed")) }) }) Context("create task fails for any other reason", func() { var desireError error BeforeEach(func() { desireError = errors.New("some task create error") fakeDiegoClient.DesireTaskReturns(desireError) })
}) It("propagates the error", func() { Eventually(logger.TestSink.Buffer).Should(gbytes.Say(`sync.not-bumping-freshness-because-of","log_level":2,"data":{"error":"our-specific-test-error"`)) }) }) }) Context("when updating the desired lrp fails", func() { BeforeEach(func() { bbsClient.UpdateDesiredLRPReturns(errors.New("boom")) }) Context("because the desired lrp is invalid", func() { BeforeEach(func() { validationError := models.NewError(models.Error_InvalidRequest, "some-validation-error") bbsClient.UpdateDesiredLRPReturns(validationError.ToError()) }) It("updates the domain", func() { Eventually(bbsClient.UpsertDomainCallCount).Should(Equal(1)) }) It("correctly emits the total number of invalid LRPs found while bulking", func() { Eventually(func() fake.Metric { return metricSender.GetValue("NsyncInvalidDesiredLRPsFound") }).Should(Equal(fake.Metric{Value: 2, Unit: "Metric"})) }) }) It("does not update the domain", func() {
expectedSessionName = sessionPrefix + "process-reserved-container" container.State = executor.StateReserved }) It("claims the actualLRP in the bbs", func() { Expect(bbsClient.ClaimActualLRPCallCount()).To(Equal(1)) processGuid, index, instanceKey := bbsClient.ClaimActualLRPArgsForCall(0) Expect(processGuid).To(Equal(expectedLrpKey.ProcessGuid)) Expect(int32(index)).To(Equal(expectedLrpKey.Index)) Expect(*instanceKey).To(Equal(expectedInstanceKey)) }) Context("when claiming fails because ErrActualLRPCannotBeClaimed", func() { BeforeEach(func() { bbsClient.ClaimActualLRPReturns(models.NewError( models.Error_ActualLRPCannotBeClaimed, "something-broke?", )) }) It("deletes the container", func() { Expect(containerDelegate.DeleteContainerCallCount()).To(Equal(1)) delegateLogger, containerGuid := containerDelegate.DeleteContainerArgsForCall(0) Expect(containerGuid).To(Equal(container.Guid)) Expect(delegateLogger.SessionName()).To(Equal(expectedSessionName)) }) It("does not try to run the container", func() { Expect(containerDelegate.RunContainerCallCount()).To(Equal(0)) }) })