Beispiel #1
0
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())
	}
}
Beispiel #2
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
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
}
Beispiel #7
0
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
}
Beispiel #8
0
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
}
Beispiel #9
0
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
}
Beispiel #10
0
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
}
Beispiel #11
0
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
}
Beispiel #12
0
		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)
					})
Beispiel #14
0
				})

				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))
					})
				})