예제 #1
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
}
예제 #2
0
			actualLRP2 = models.ActualLRP{
				ActualLRPKey: models.NewActualLRPKey(
					"process-guid-1",
					2,
					"domain-1",
				),
				ActualLRPInstanceKey: models.NewActualLRPInstanceKey(
					"instance-guid-1",
					"cell-id-1",
				),
				State: models.ActualLRPStateClaimed,
				Since: 4444,
			}

			evacuatingLRP2 = actualLRP2
			evacuatingLRP2.State = models.ActualLRPStateRunning
			evacuatingLRP2.Since = 3417
		})

		JustBeforeEach(func() {
			handler.ActualLRPGroups(responseRecorder, request)
		})

		Context("when reading actual lrps from DB succeeds", func() {
			var actualLRPGroups *models.ActualLRPGroups

			BeforeEach(func() {
				actualLRPGroups = &models.ActualLRPGroups{
					[]*models.ActualLRPGroup{
						{Instance: &actualLRP1},
						{Instance: &actualLRP2, Evacuating: &evacuatingLRP2},
예제 #3
0
		actualLRP2 = models.ActualLRP{
			ActualLRPKey: models.NewActualLRPKey(
				"process-guid-1",
				2,
				"domain-1",
			),
			ActualLRPInstanceKey: models.NewActualLRPInstanceKey(
				"instance-guid-1",
				"cell-id-1",
			),
			State: proto.String(models.ActualLRPStateClaimed),
			Since: proto.Int64(4444),
		}

		evacuatingLRP2 = actualLRP2
		evacuatingLRP2.State = proto.String(models.ActualLRPStateRunning)
		evacuatingLRP2.Since = proto.Int64(3417)
	})

	// old before each
	BeforeEach(func() {
		oldActualLRP1 = oldmodels.ActualLRP{
			ActualLRPKey: oldmodels.NewActualLRPKey(
				"process-guid-0",
				1,
				"domain-0",
			),
			ActualLRPInstanceKey: oldmodels.NewActualLRPInstanceKey(
				"instance-guid-0",
				"cell-id-0",
			),
예제 #4
0
					Expect(resolvedLRP).To(Equal(evacuatingLRP))
					Expect(evacuating).To(BeTrue())
				})
			})

			Context("When both the Instance and the Evacuating LRP are set", func() {
				BeforeEach(func() {
					group = models.ActualLRPGroup{
						Evacuating: evacuatingLRP,
						Instance:   instanceLRP,
					}
				})

				Context("When the Instance is UNCLAIMED", func() {
					BeforeEach(func() {
						instanceLRP.State = models.ActualLRPStateUnclaimed
					})

					It("returns the Evacuating LRP", func() {
						Expect(resolvedLRP).To(Equal(evacuatingLRP))
						Expect(evacuating).To(BeTrue())
					})
				})

				Context("When the Instance is CLAIMED", func() {
					BeforeEach(func() {
						instanceLRP.State = models.ActualLRPStateClaimed
					})

					It("returns the Evacuating LRP", func() {
						Expect(resolvedLRP).To(Equal(evacuatingLRP))
예제 #5
0
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Evacuation API", func() {
	BeforeEach(func() {
		bbsRunner = testrunner.New(bbsBinPath, bbsArgs)
		bbsProcess = ginkgomon.Invoke(bbsRunner)
	})

	var actual *models.ActualLRP

	BeforeEach(func() {
		actual = model_helpers.NewValidActualLRP("some-process-guid", 1)
		actual.State = models.ActualLRPStateRunning
		desiredLRP := model_helpers.NewValidDesiredLRP(actual.ProcessGuid)
		desiredLRP.Instances = 2
		err := client.DesireLRP(logger, desiredLRP)
		Expect(err).NotTo(HaveOccurred())
		err = client.ClaimActualLRP(logger, actual.ProcessGuid, 1, &actual.ActualLRPInstanceKey)
		Expect(err).NotTo(HaveOccurred())
	})

	Describe("RemoveEvacuatingActualLRP", func() {
		It("removes the evacuating actual_lrp", func() {
			_, err := client.EvacuateClaimedActualLRP(logger, &actual.ActualLRPKey, &actual.ActualLRPInstanceKey)
			Expect(err).NotTo(HaveOccurred())

			err = client.RemoveEvacuatingActualLRP(logger, &actual.ActualLRPKey, &actual.ActualLRPInstanceKey)
			Expect(err).NotTo(HaveOccurred())
			}

			actualResponse := serialization.ActualLRPProtoToResponse(actualLRP, true)
			Expect(actualResponse).To(Equal(expectedResponse))
		})

		It("maps model states to receptor states", func() {
			expectedStateMap := map[string]receptor.ActualLRPState{
				models.ActualLRPStateUnclaimed: receptor.ActualLRPStateUnclaimed,
				models.ActualLRPStateClaimed:   receptor.ActualLRPStateClaimed,
				models.ActualLRPStateRunning:   receptor.ActualLRPStateRunning,
				models.ActualLRPStateCrashed:   receptor.ActualLRPStateCrashed,
			}

			for modelState, jsonState := range expectedStateMap {
				actualLRP.State = modelState
				Expect(serialization.ActualLRPProtoToResponse(actualLRP, false).State).To(Equal(jsonState))
			}

			actualLRP.State = ""
			Expect(serialization.ActualLRPProtoToResponse(actualLRP, false).State).To(Equal(receptor.ActualLRPStateInvalid))
		})

		Context("when there is placement error", func() {
			BeforeEach(func() {
				actualLRP.State = models.ActualLRPStateUnclaimed
				actualLRP.PlacementError = "some-error"
			})

			It("includes the placement error", func() {
				actualResponse := serialization.ActualLRPProtoToResponse(actualLRP, false)
예제 #7
0
			actual      *models.ActualLRP
			afterActual *models.ActualLRP
			desiredLRP  *models.DesiredLRP
		)

		BeforeEach(func() {
			desiredLRP = model_helpers.NewValidDesiredLRP("the-guid")
			fakeDesiredLRPDB.DesiredLRPByProcessGuidReturns(desiredLRP, nil)

			actual = model_helpers.NewValidActualLRP("process-guid", 1)
			requestBody = &models.EvacuateClaimedActualLRPRequest{
				ActualLrpKey:         &actual.ActualLRPKey,
				ActualLrpInstanceKey: &actual.ActualLRPInstanceKey,
			}
			afterActual = model_helpers.NewValidActualLRP("process-guid", 1)
			afterActual.State = models.ActualLRPStateUnclaimed
			fakeActualLRPDB.ActualLRPGroupByProcessGuidAndIndexReturns(&models.ActualLRPGroup{Evacuating: actual}, nil)
			fakeActualLRPDB.UnclaimActualLRPReturns(&models.ActualLRPGroup{Instance: actual}, &models.ActualLRPGroup{Instance: afterActual}, nil)

			request = newTestRequest(requestBody)
		})

		JustBeforeEach(func() {
			handler.EvacuateClaimedActualLRP(responseRecorder, request)
			Expect(responseRecorder.Code).To(Equal(http.StatusOK))
		})

		It("removes the evacuating actual lrp", func() {
			response := models.EvacuationResponse{}
			err := response.Unmarshal(responseRecorder.Body.Bytes())
			Expect(err).NotTo(HaveOccurred())