def _update(self, name, **kwargs): names = ('uri', 'weight', 'flavor', 'options') fields = common_utils.fields(kwargs, names, pred=lambda x: x is not None, key_transform=lambda x: x[0]) assert fields, ('`weight`, `uri`, `flavor`, ' 'or `options` not found in kwargs') if 'o' in fields: new_options = fields.get('o', None) fields['o'] = self._packer(new_options) pool_key = utils.pools_name_hash_key(name) # (gengchc2): Pipeline ensures atomic inserts. with self._client.pipeline() as pipe: # (gengchc2): If flavor is changed, we need to change.pool key # in pools subset. if 'f' in fields: flavor_old = self._get(name).get('flavor') flavor_new = fields['f'] if flavor_old != flavor_new: if flavor_new is not None: new_subset_key = utils.pools_subset_key(flavor_new) pipe.zadd(new_subset_key, 1, pool_key) # (gengchc2) remove pool from flavor_old.pools subset if flavor_old is not None: old_subset_key = utils.pools_subset_key(flavor_old) pipe.zrem(old_subset_key, pool_key) pipe.hmset(pool_key, fields) pipe.execute()
def _delete(self, name): try: pool = self.get(name) flavor = pool.get("flavor", None) # NOTE(gengchc2): If this is the only pool in the # flavor and it's being used by a flavor, don't allow # it to be deleted. if flavor is not None: flavor1 = {} flavor1['name'] = flavor pools_in_flavor = list( self.get_pools_by_flavor(flavor=flavor1)) if self.flavor_ctl.exists(flavor)\ and len(pools_in_flavor) == 1: raise errors.PoolInUseByFlavor(name, flavor) pool_key = utils.pools_name_hash_key(name) subset_key = utils.pools_subset_key(flavor) set_key = utils.pools_set_key() with self._client.pipeline() as pipe: if flavor is not None: pipe.zrem(subset_key, pool_key) pipe.zrem(set_key, pool_key) pipe.delete(pool_key) pipe.execute() except errors.PoolDoesNotExist: pass
def _delete(self, name): try: pool = self.get(name) flavor = pool.get("flavor", None) # NOTE(gengchc2): If this is the only pool in the # flavor and it's being used by a flavor, don't allow # it to be deleted. if flavor is not None: flavor1 = {} flavor1['name'] = flavor pools_in_flavor = list(self.get_pools_by_flavor( flavor=flavor1)) if self.flavor_ctl.exists(flavor)\ and len(pools_in_flavor) == 1: raise errors.PoolInUseByFlavor(name, flavor) pool_key = utils.pools_name_hash_key(name) subset_key = utils.pools_subset_key(flavor) set_key = utils.pools_set_key() with self._client.pipeline() as pipe: if flavor is not None: pipe.zrem(subset_key, pool_key) pipe.zrem(set_key, pool_key) pipe.delete(pool_key) pipe.execute() except errors.PoolDoesNotExist: pass
def _get(self, name, detailed=False): pool_key = utils.pools_name_hash_key(name) pool = self._client.hgetall(pool_key) if pool is None or len(pool) == 0: raise errors.PoolDoesNotExist(name) return self._normalize(pool, detailed)
def _update(self, name, **kwargs): names = ('uri', 'weight', 'flavor', 'options') fields = common_utils.fields(kwargs, names, pred=lambda x: x is not None, key_transform=lambda x: x[0]) assert fields, ('`weight`, `uri`, `flavor`, ' 'or `options` not found in kwargs') if 'o' in fields: new_options = fields.get('o', None) fields['o'] = self._packer(new_options) pool_key = utils.pools_name_hash_key(name) # (gengchc2): Pipeline ensures atomic inserts. with self._client.pipeline() as pipe: # (gengchc2): If flavor is changed, we need to change.pool key # in pools subset. if 'f' in fields: flavor_old = self._get(name).get('flavor') flavor_new = fields['f'] if flavor_old != flavor_new: if flavor_new is not None: new_subset_key = utils.pools_subset_key(flavor_new) pipe.zadd(new_subset_key, {pool_key: 1}) # (gengchc2) remove pool from flavor_old.pools subset if flavor_old is not None: old_subset_key = utils.pools_subset_key(flavor_old) pipe.zrem(old_subset_key, pool_key) pipe.hmset(pool_key, fields) pipe.execute()
def _create(self, name, weight, uri, group=None, flavor=None, options=None): if group is not None: raise errors.PoolRedisNotSupportGroup flavor = flavor if flavor is not None else None options = {} if options is None else options pool_key = utils.pools_name_hash_key(name) subset_key = utils.pools_subset_key(flavor) set_key = utils.pools_set_key() if self._exists(name): self._update(name, weight=weight, uri=uri, flavor=flavor, options=options) return pool = { 'pl': name, 'u': uri, 'w': weight, 'o': self._packer(options), 'f': flavor } # Pipeline ensures atomic inserts. with self._client.pipeline() as pipe: pipe.zadd(set_key, {pool_key: 1}) if flavor is not None: pipe.zadd(subset_key, {pool_key: 1}) pipe.hmset(pool_key, pool) pipe.execute()
def _list(self, marker=None, limit=10, detailed=False): client = self._client set_key = utils.pools_set_key() marker_key = utils.pools_name_hash_key(marker) rank = client.zrank(set_key, marker_key) start = rank + 1 if rank is not None else 0 cursor = (f for f in client.zrange(set_key, start, start + limit - 1)) marker_next = {} def normalizer(pools): marker_next['next'] = pools['pl'] return self._normalize(pools, detailed=detailed) yield utils.PoolsListCursor(self._client, cursor, normalizer) yield marker_next and marker_next['next']
def _list(self, marker=None, limit=10, detailed=False): client = self._client set_key = utils.pools_set_key() marker_key = utils.pools_name_hash_key(marker) if marker_key: rank = client.zrank(set_key, marker_key) else: rank = None start = rank + 1 if rank is not None else 0 cursor = (f for f in client.zrange(set_key, start, start + limit - 1)) marker_next = {} def normalizer(pools): marker_next['next'] = pools['pl'] return self._normalize(pools, detailed=detailed) yield utils.PoolsListCursor(self._client, cursor, normalizer) yield marker_next and marker_next['next']
def _create(self, name, weight, uri, group=None, flavor=None, options=None): if group is not None: raise errors.PoolRedisNotSupportGroup flavor = flavor if flavor is not None else None options = {} if options is None else options pool_key = utils.pools_name_hash_key(name) subset_key = utils.pools_subset_key(flavor) set_key = utils.pools_set_key() if self._exists(name): self._update(name, weight=weight, uri=uri, flavor=flavor, options=options) return pool = { 'pl': name, 'u': uri, 'w': weight, 'o': self._packer(options), 'f': flavor } # Pipeline ensures atomic inserts. with self._client.pipeline() as pipe: pipe.zadd(set_key, 1, pool_key) if flavor is not None: pipe.zadd(subset_key, 1, pool_key) pipe.hmset(pool_key, pool) pipe.execute()
def _exists(self, name): pool_key = utils.pools_name_hash_key(name) return self._client.exists(pool_key)