示例#1
0
func (db *ETCDDB) EvacuateActualLRP(
	logger lager.Logger,
	lrpKey *models.ActualLRPKey,
	instanceKey *models.ActualLRPInstanceKey,
	netInfo *models.ActualLRPNetInfo,
	ttl uint64,
) (*models.ActualLRPGroup, error) {
	logger = logger.Session("evacuate-actual-lrp", lager.Data{"process_guid": lrpKey.ProcessGuid, "index": lrpKey.Index})

	logger.Debug("starting")
	defer logger.Debug("complete")

	node, err := db.fetchRaw(logger, EvacuatingActualLRPSchemaPath(lrpKey.ProcessGuid, lrpKey.Index))
	bbsErr := models.ConvertError(err)
	if bbsErr != nil {
		if bbsErr.Type == models.Error_ResourceNotFound {
			return db.createEvacuatingActualLRP(logger, lrpKey, instanceKey, netInfo, ttl)
		}
		return nil, bbsErr
	}

	lrp := models.ActualLRP{}
	err = db.deserializeModel(logger, node, &lrp)
	if err != nil {
		return nil, err
	}

	if lrp.ActualLRPKey.Equal(lrpKey) &&
		lrp.ActualLRPInstanceKey.Equal(instanceKey) &&
		reflect.DeepEqual(lrp.ActualLRPNetInfo, *netInfo) {
		return &models.ActualLRPGroup{Evacuating: &lrp}, nil
	}

	lrp.ActualLRPNetInfo = *netInfo
	lrp.ActualLRPKey = *lrpKey
	lrp.ActualLRPInstanceKey = *instanceKey
	lrp.Since = db.clock.Now().UnixNano()
	lrp.ModificationTag.Increment()

	data, err := db.serializeModel(logger, &lrp)
	if err != nil {
		logger.Error("failed-serializing", err)
		return nil, err
	}

	_, err = db.client.CompareAndSwap(EvacuatingActualLRPSchemaPath(lrp.ProcessGuid, lrp.Index), data, ttl, node.ModifiedIndex)
	if err != nil {
		return nil, ErrorFromEtcdError(logger, err)
	}

	return &models.ActualLRPGroup{Evacuating: &lrp}, nil
}
示例#2
0
func itValidatesPresenceOfTheLRPKey(lrp *models.ActualLRP) {
	Context("when the lrp key is set", func() {
		BeforeEach(func() {
			lrp.ActualLRPKey = models.NewActualLRPKey("some-guid", 1, "domain")
		})

		It("validate does not return an error", func() {
			Expect(lrp.Validate()).NotTo(HaveOccurred())
		})
	})

	Context("when the lrp key is not set", func() {
		BeforeEach(func() {
			lrp.ActualLRPKey = models.ActualLRPKey{}
		})

		It("validate returns an error", func() {
			err := lrp.Validate()
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(ContainSubstring("process_guid"))
		})
	})
}
示例#3
0
func (db *SQLDB) EvacuateActualLRP(
	logger lager.Logger,
	lrpKey *models.ActualLRPKey,
	instanceKey *models.ActualLRPInstanceKey,
	netInfo *models.ActualLRPNetInfo,
	ttl uint64,
) (*models.ActualLRPGroup, error) {
	logger = logger.Session("evacuate-lrp-sqldb", lager.Data{"lrp_key": lrpKey, "instance_key": instanceKey, "net_info": netInfo})
	logger.Debug("starting")
	defer logger.Debug("complete")

	var actualLRP *models.ActualLRP

	err := db.transact(logger, func(logger lager.Logger, tx *sql.Tx) error {
		var err error
		processGuid := lrpKey.ProcessGuid
		index := lrpKey.Index

		actualLRP, err = db.fetchActualLRPForUpdate(logger, processGuid, index, true, tx)
		if err == models.ErrResourceNotFound {
			logger.Debug("creating-evacuating-lrp")
			actualLRP, err = db.createEvacuatingActualLRP(logger, lrpKey, instanceKey, netInfo, ttl, tx)
			return err
		}

		if err != nil {
			logger.Error("failed-locking-lrp", err)
			return err
		}

		if actualLRP.ActualLRPKey.Equal(lrpKey) &&
			actualLRP.ActualLRPInstanceKey.Equal(instanceKey) &&
			reflect.DeepEqual(actualLRP.ActualLRPNetInfo, *netInfo) {
			logger.Debug("evacuating-lrp-already-exists")
			return nil
		}

		now := db.clock.Now().UnixNano()
		actualLRP.ModificationTag.Increment()
		actualLRP.ActualLRPKey = *lrpKey
		actualLRP.ActualLRPInstanceKey = *instanceKey
		actualLRP.Since = now
		actualLRP.ActualLRPNetInfo = *netInfo

		netInfoData, err := db.serializeModel(logger, netInfo)
		if err != nil {
			logger.Error("failed-serializing-net-info", err)
			return err
		}

		_, err = db.update(logger, tx, "actual_lrps",
			SQLAttributes{
				"domain":                 actualLRP.Domain,
				"instance_guid":          actualLRP.InstanceGuid,
				"cell_id":                actualLRP.CellId,
				"net_info":               netInfoData,
				"state":                  actualLRP.State,
				"since":                  actualLRP.Since,
				"modification_tag_index": actualLRP.ModificationTag.Index,
			},
			"process_guid = ? AND instance_index = ? AND evacuating = ?",
			actualLRP.ProcessGuid, actualLRP.Index, true,
		)
		if err != nil {
			logger.Error("failed-update-evacuating-lrp", err)
			return db.convertSQLError(err)
		}

		return nil
	})

	return &models.ActualLRPGroup{Evacuating: actualLRP}, err
}