def parent_info(self): """ Get information about a cloned image's parent (if any) :returns: tuple - ``(pool name, image name, snapshot name)`` components of the parent image :raises: :class:`ImageNotFound` if the image doesn't have a parent """ ret = -errno.ERANGE size = 8 while ret == -errno.ERANGE and size <= 4096: pool = create_string_buffer(size) name = create_string_buffer(size) snapname = create_string_buffer(size) ret = self.librbd.rbd_get_parent_info(self.image, byref(pool), c_size_t(size), byref(name), c_size_t(size), byref(snapname), c_size_t(size)) if ret == -errno.ERANGE: size *= 2 if ret != 0: raise make_ex(ret, 'error getting parent info for image %s' % (self.name,)) return (decode_cstr(pool.value), decode_cstr(name.value), decode_cstr(snapname.value))
def __iter__(self): for i in range(self.num_snaps): yield { 'id' : self.snaps[i].id, 'size' : self.snaps[i].size, 'name' : decode_cstr(self.snaps[i].name), }
def list_lockers(self): """ List clients that have locked the image and information about the lock. :returns: dict - contains the following keys: * ``tag`` - the tag associated with the lock (every additional locker must use the same tag) * ``exclusive`` - boolean indicating whether the lock is exclusive or shared * ``lockers`` - a list of (client, cookie, address) tuples """ clients_size = c_size_t(512) cookies_size = c_size_t(512) addrs_size = c_size_t(512) tag_size = c_size_t(512) exclusive = c_int(0) while True: c_clients = create_string_buffer(clients_size.value) c_cookies = create_string_buffer(cookies_size.value) c_addrs = create_string_buffer(addrs_size.value) c_tag = create_string_buffer(tag_size.value) ret = self.librbd.rbd_list_lockers(self.image, byref(exclusive), byref(c_tag), byref(tag_size), byref(c_clients), byref(clients_size), byref(c_cookies), byref(cookies_size), byref(c_addrs), byref(addrs_size)) if ret >= 0: break elif ret != -errno.ERANGE: raise make_ex(ret, 'error listing images') if ret == 0: return [] clients = [client.decode("utf-8") for client in c_clients.raw[:clients_size.value - 1].split(b'\0')] cookies = [cookie.decode("utf-8") for cookie in c_cookies.raw[:cookies_size.value - 1].split(b'\0')] addrs = [addr.decode("utf-8") for addr in c_addrs.raw[:addrs_size.value - 1].split(b'\0')] return { 'tag' : decode_cstr(c_tag), 'exclusive' : exclusive.value == 1, 'lockers' : list(zip(clients, cookies, addrs)), }
def list(self, ioctx): """ List image names. :param ioctx: determines which RADOS pool is read :type ioctx: :class:`rados.Ioctx` :returns: list -- a list of image names """ size = c_size_t(512) while True: c_names = create_string_buffer(size.value) ret = self.librbd.rbd_list(ioctx.io, byref(c_names), byref(size)) if ret >= 0: break elif ret != -errno.ERANGE: raise make_ex(ret, 'error listing images') return [decode_cstr(name) for name in c_names.raw.split(b'\0') if len(name) > 0]
def stat(self): """ Get information about the image. Currently parent pool and parent name are always -1 and ''. :returns: dict - contains the following keys: * ``size`` (int) - the size of the image in bytes * ``obj_size`` (int) - the size of each object that comprises the image * ``num_objs`` (int) - the number of objects in the image * ``order`` (int) - log_2(object_size) * ``block_name_prefix`` (str) - the prefix of the RADOS objects used to store the image * ``parent_pool`` (int) - deprecated * ``parent_name`` (str) - deprecated See also :meth:`format` and :meth:`features`. """ info = rbd_image_info_t() ret = self.librbd.rbd_stat(self.image, byref(info), ctypes.sizeof(info)) if ret != 0: raise make_ex(ret, 'error getting info for image %s' % (self.name,)) return { 'size' : info.size, 'obj_size' : info.obj_size, 'num_objs' : info.num_objs, 'order' : info.order, 'block_name_prefix' : decode_cstr(info.block_name_prefix), 'parent_pool' : info.parent_pool, 'parent_name' : info.parent_name }