예제 #1
0
func (c *ConsulClient) GASNewSecLabelID(basePath string, baseID uint32, secCtxLabels *labels.SecCtxLabel) error {

	setID2Label := func(lockPair *consulAPI.KVPair) error {
		defer c.KV().Release(lockPair, nil)
		secCtxLabels.ID = baseID
		keyPath := path.Join(basePath, strconv.FormatUint(uint64(secCtxLabels.ID), 10))
		if err := c.SetValue(keyPath, secCtxLabels); err != nil {
			return err
		}
		return c.setMaxLabelID(baseID + 1)
	}

	session, _, err := c.Session().CreateNoChecks(nil, nil)
	if err != nil {
		return err
	}

	beginning := baseID
	for {
		log.Debugf("Trying to acquire a new free ID %d", baseID)
		keyPath := path.Join(basePath, strconv.FormatUint(uint64(baseID), 10))

		lockPair := &consulAPI.KVPair{Key: GetLockPath(keyPath), Session: session}
		acq, _, err := c.KV().Acquire(lockPair, nil)
		if err != nil {
			return err
		}

		if acq {
			lblKey, _, err := c.KV().Get(keyPath, nil)
			if err != nil {
				c.KV().Release(lockPair, nil)
				return err
			}
			if lblKey == nil {
				return setID2Label(lockPair)
			}
			var consulLabels labels.SecCtxLabel
			if err := json.Unmarshal(lblKey.Value, &consulLabels); err != nil {
				c.KV().Release(lockPair, nil)
				return err
			}
			if consulLabels.RefCount() == 0 {
				log.Infof("Recycling ID %d", baseID)
				return setID2Label(lockPair)
			}
			c.KV().Release(lockPair, nil)
		}
		baseID++
		if baseID > common.MaxSetOfLabels {
			baseID = common.FirstFreeLabelID
		}
		if beginning == baseID {
			return fmt.Errorf("reached maximum set of labels available.")
		}
	}
}
예제 #2
0
파일: etcd.go 프로젝트: cilium-team/cilium
// GASNewSecLabelID gets the next available LabelID and sets it in secCtxLabels. After
// assigning the LabelID to secCtxLabels it sets the LabelID + 1 in
// common.LastFreeLabelIDKeyPath path.
func (e *EtcdClient) GASNewSecLabelID(basePath string, baseID uint32, secCtxLabels *labels.SecCtxLabel) error {
	setID2Label := func(id uint32) error {
		secCtxLabels.ID = id
		keyPath := path.Join(basePath, strconv.FormatUint(uint64(secCtxLabels.ID), 10))
		if err := e.SetValue(keyPath, secCtxLabels); err != nil {
			return err
		}
		return e.setMaxLabelID(id + 1)
	}

	acquireFreeID := func(firstID uint32, incID *uint32) (bool, error) {
		log.Debugf("Trying to acquire a new free ID %d", *incID)
		keyPath := path.Join(basePath, strconv.FormatUint(uint64(*incID), 10))

		locker, err := e.LockPath(GetLockPath(keyPath))
		if err != nil {
			return false, err
		}
		defer locker.Unlock()

		value, err := e.GetValue(keyPath)
		if err != nil {
			return false, err
		}
		if value == nil {
			return false, setID2Label(*incID)
		}
		var consulLabels labels.SecCtxLabel
		if err := json.Unmarshal(value, &consulLabels); err != nil {
			return false, err
		}
		if consulLabels.RefCount() == 0 {
			log.Infof("Recycling ID %d", *incID)
			return false, setID2Label(*incID)
		}

		*incID++
		if *incID > common.MaxSetOfLabels {
			*incID = common.FirstFreeLabelID
		}
		if firstID == *incID {
			return false, fmt.Errorf("reached maximum set of labels available.")
		}
		return true, nil
	}

	beginning := baseID
	for {
		retry, err := acquireFreeID(beginning, &baseID)
		if err != nil {
			return err
		} else if !retry {
			return nil
		}
	}
}
예제 #3
0
// GetLabelsBySHA256 returns the SecCtxLabels that have the given SHA256SUM.
func (d *Daemon) GetLabelsBySHA256(sha256sum string) (*labels.SecCtxLabel, error) {
	path := path.Join(common.LabelsKeyPath, sha256sum)
	rmsg, err := d.kvClient.GetValue(path)
	if err != nil {
		return nil, err
	}
	if rmsg == nil {
		return nil, nil
	}
	var secCtxLabels labels.SecCtxLabel
	if err := json.Unmarshal(rmsg, &secCtxLabels); err != nil {
		return nil, err
	}
	if secCtxLabels.RefCount() == 0 {
		return nil, nil
	}
	return &secCtxLabels, nil
}
예제 #4
0
// GetLabels returns the SecCtxLabels that belongs to the given id.
func (d *Daemon) GetLabels(id uint32) (*labels.SecCtxLabel, error) {
	if id > 0 && id < common.FirstFreeLabelID {
		key := labels.ReservedID(id).String()
		if key == "" {
			return nil, nil
		}

		lbl := labels.NewLabel(
			key, "", common.ReservedLabelSource,
		)
		secLbl := labels.NewSecCtxLabel()
		secLbl.AddOrUpdateContainer(lbl.String())
		secLbl.ID = id
		secLbl.Labels = labels.Labels{
			common.ReservedLabelSource: lbl,
		}

		return secLbl, nil
	}

	strID := strconv.FormatUint(uint64(id), 10)
	rmsg, err := d.kvClient.GetValue(path.Join(common.LabelIDKeyPath, strID))
	if err != nil {
		return nil, err
	}
	if rmsg == nil {
		return nil, nil
	}

	var secCtxLabels labels.SecCtxLabel
	if err := json.Unmarshal(rmsg, &secCtxLabels); err != nil {
		return nil, err
	}
	if secCtxLabels.RefCount() == 0 {
		return nil, nil
	}
	return &secCtxLabels, nil
}
예제 #5
0
// DeleteLabelsBySHA256 deletes the SecCtxLabels that belong to the labels' sha256Sum.
func (d *Daemon) DeleteLabelsBySHA256(sha256Sum string, contID string) error {
	if sha256Sum == "" {
		return nil
	}
	lblPath := path.Join(common.LabelsKeyPath, sha256Sum)
	// Lock that sha256Sum
	lockKey, err := d.kvClient.LockPath(lblPath)
	if err != nil {
		return err
	}
	defer lockKey.Unlock()

	// After lock complete, get label's path
	rmsg, err := d.kvClient.GetValue(lblPath)
	if err != nil {
		return err
	}
	if rmsg == nil {
		return nil
	}

	var dbSecCtxLbls labels.SecCtxLabel
	if err := json.Unmarshal(rmsg, &dbSecCtxLbls); err != nil {
		return err
	}
	dbSecCtxLbls.DelContainer(contID)

	// update the value in the kvstore
	if err := d.updateSecLabelIDRef(dbSecCtxLbls); err != nil {
		return err
	}

	if dbSecCtxLbls.RefCount() == 0 {
		d.DeleteUINode(dbSecCtxLbls.ID)
	} else {
		d.AddOrUpdateUINode(dbSecCtxLbls.ID, dbSecCtxLbls.Labels.ToSlice(), dbSecCtxLbls.RefCount())
	}

	log.Debugf("Decremented label %d ref-count to %d\n", dbSecCtxLbls.ID, dbSecCtxLbls.RefCount())

	return d.kvClient.SetValue(lblPath, dbSecCtxLbls)
}