def get(self, **kwargs): """Retrieve objects from DSS.""" res = POINTER(self.wrapped_class)() res_cnt = c_int() # transform the family attribute into a string try: kwargs['family'] = str(kwargs['family']) except KeyError: pass # rename keys that need a specific operation to be correctly parsed # by the dss filter kwargs = self.convert_kwargs('tags', 'tags__jexist', **kwargs) kwargs = self.convert_kwargs('pattern', 'oid__regexp', **kwargs) kwargs = self.convert_kwargs('metadata', 'user_md__jkeyval', **kwargs) filt = dss_filter(self.wrapped_ident, **kwargs) if filt is not None: fref = byref(filt) else: fref = None try: rc = self._dss_get(byref(self.client.handle), fref, byref(res), byref(res_cnt)) finally: LIBPHOBOS.dss_filter_free(fref) if rc: raise EnvironmentError(rc, "Cannot issue get request") ret_items = DSSResult(res, res_cnt.value) return ret_items
def set_callback(self, callback): """Set a python callable as a log handling callback to the C library.""" if callback is None: set_cb = cast(None, self.LogCBType) else: set_cb = self.LogCBType(callback) LIBPHOBOS.pho_log_callback_set(set_cb) self._cb_ref = set_cb
def attrs_as_dict(attrs): """Return a python dictionary containing the attributes""" def inner_attrs_mapper(key, val, c_data): """ Not for direct use. Add attribute of a PhoAttr structure into a python dict. """ data = cast(c_data, POINTER(py_object)).contents.value data[key] = val return 0 res = {} cb = AttrsForeachCBType(inner_attrs_mapper) c_res = cast(pointer(py_object(res)), c_void_p) LIBPHOBOS.pho_attrs_foreach(byref(attrs), cb, c_res) return res
def put(self, xfer_descriptors, compl_cb): xfer = self.xfer_desc_convert(xfer_descriptors) n = len(xfer_descriptors) self._put_cb = self.compl_cb_convert(compl_cb) rc = LIBPHOBOS.phobos_put(xfer, n, self._put_cb, None) self.xfer_desc_release(xfer) return rc
def dss_filter(obj_type, **kwargs): """Convert a k/v filter into a CDSS-compatible list of criteria.""" if len(kwargs) == 0: return None filt = JSONFilter() criteria = [] for key, val in kwargs.iteritems(): key, comp = key_convert(obj_type, key) if comp is None: # Implicit equal criteria.append({key: val}) else: criteria.append({comp: {key: val}}) assert len(criteria) > 0 if len(criteria) == 1: filt_str = json.dumps(criteria[0]) else: filt_str = json.dumps({'$AND': criteria}) rc = LIBPHOBOS.dss_filter_build(byref(filt), filt_str) if rc: raise EnvironmentError(rc, "Invalid filter criteria") return filt
def ldm_device_query(dev_type, dev_path): """Retrieve device information at LDM level.""" adapter = DevAdapter() rc = LIBPHOBOS.get_dev_adapter(dev_type, byref(adapter)) if rc: raise EnvironmentError(rc, "Cannot get device adapter for %r" % dev_type) real_path = os.path.realpath(dev_path) state = DevState() rc = LIBPHOBOS.ldm_dev_query(byref(adapter), real_path, byref(state)) if rc: raise EnvironmentError(rc, "Cannot query device %r" % real_path) return state
def connect(self, **kwargs): """ Establish a fresh connection or renew a stalled one if needed.""" if self.handle is not None: self.disconnect() self.handle = DSSHandle() rc = LIBPHOBOS.dss_init(byref(self.handle)) if rc: raise EnvironmentError(rc, 'DSS initialization failed')
def xfer_desc_convert(self, xfer_descriptors): """ Internal conversion method to turn a python list into an array of struct xfer_descriptor as expected by phobos_{get,put} functions. """ XferArrayType = XferDescriptor * len(xfer_descriptors) xfr = XferArrayType() for i, x in enumerate(xfer_descriptors): xfr[i].xd_objid = x[0] xfr[i].xd_fpath = x[1] xfr[i].xd_flags = x[3] if x[2]: attrs = PhoAttrs() for k, v in x[2].iteritems(): LIBPHOBOS.pho_attr_set(byref(attrs), str(k), str(v)) xfr[i].xd_attrs = pointer(attrs) xfr[i].xd_tags = Tags(x[4]) return xfr
def get(self, **kwargs): """Retrieve objects from DSS.""" res = POINTER(self.wrapped_class)() res_cnt = c_int() filt = dss_filter(self.wrapped_ident, **kwargs) if filt is not None: fref = byref(filt) else: fref = None try: rc = self._dss_get(byref(self.client.handle), fref, byref(res), byref(res_cnt)) finally: LIBPHOBOS.dss_filter_free(fref) if rc: raise EnvironmentError(rc, "Cannot issue get request") ret_items = DSSResult(res, res_cnt.value) return ret_items
def lrs_fs_format(dss, medium_id, fs_type, unlock=False): """Format a medium though the LRS layer.""" fs_type = fs_type.lower() if fs_type == 'ltfs': dev_type = PHO_DEV_TAPE fs_type_enum = PHO_FS_LTFS elif fs_type == 'posix': dev_type = PHO_DEV_DIR fs_type_enum = PHO_FS_POSIX else: raise EnvironmentError(errno.EOPNOTSUPP, "Unknown filesystem type '%s'" % fs_type) mstruct = MediaId(dev_type, medium_id) lrs = LRS() rc = LIBPHOBOS.lrs_init(byref(lrs), byref(dss.handle)) if rc: raise EnvironmentError(rc, "Cannot initialize LRS") rc = LIBPHOBOS.lrs_format(byref(lrs), byref(mstruct), fs_type_enum, unlock) LIBPHOBOS.lrs_fini(byref(lrs)) if rc: raise EnvironmentError(rc, "Cannot format medium '%s'" % medium_id)
def get_val(section, name, default=RAISE_ERROR): """Return the value of a property in a given section or an optional default value. Raise KeyError if the value has not been found in configuration and no default value has been provided. """ cfg_value = c_char_p() ret = LIBPHOBOS.pho_cfg_get_val(section, name, byref(cfg_value)) if ret != 0: if default is RAISE_ERROR: raise KeyError("No value in conf for section '%s', key '%s'" % (section, name)) else: return default return cfg_value.value
def __del__(self): LIBPHOBOS.dss_res_free(self._native_res, self._n_elts)
def load_file(path=None): """Load a configuration file from path""" ret = LIBPHOBOS.pho_cfg_init_local(path) if ret != 0: ret = abs(ret) raise IOError(ret, path, os.strerror(ret))
def disconnect(self): """Disconnect from DSS and reset handle.""" if self.handle is not None: LIBPHOBOS.dss_fini(byref(self.handle)) self.handle = None
def set_level(self, lvl): """Set the library logging level.""" LIBPHOBOS.pho_log_level_set(self.level_py2pho(lvl))
def _dss_set(self, hdl, obj, obj_cnt, opcode): """Invoke media-specific DSS set method.""" return LIBPHOBOS.dss_media_set(hdl, obj, obj_cnt, opcode)
def __init__(self, lib_type, lib_dev_path): LIBPHOBOS.get_lib_adapter.errcheck = pho_rc_check LIBPHOBOS.get_lib_adapter(lib_type, byref(self)) if self._lib_open is not None: self._lib_open(byref(self._lib_hdl), lib_dev_path)
def _dss_set(self, hdl, obj, obj_cnt, opcode): """Invoke device-specific DSS set method.""" return LIBPHOBOS.dss_device_set(hdl, obj, obj_cnt, opcode)
def _dss_get(self, hdl, qry_filter, res, res_cnt): """Invoke media-specific DSS get method.""" return LIBPHOBOS.dss_media_get(hdl, qry_filter, res, res_cnt)
def _dss_get(self, hdl, qry_filter, res, res_cnt): """Invoke device-specific DSS get method.""" return LIBPHOBOS.dss_device_get(hdl, qry_filter, res, res_cnt)
def xfer_desc_release(self, xfer): """Release memory associated to xfer_descriptors.""" for xd in xfer: if xd.xd_attrs: LIBPHOBOS.pho_attrs_free(xd.xd_attrs) xd.xd_tags.free()
def attrs_from_dict(dct): """Fill up from a python dictionary""" attrs = PhoAttrs() for k, v in dvt.iteritems(): LIBPHOBOS.pho_attr_set(byref(attrs), str(k), str(v)) return attrs
def __init__(self, lib_type, lib_dev_path): super().__init__() LIBPHOBOS.get_lib_adapter.errcheck = pho_rc_check LIBPHOBOS.get_lib_adapter(lib_type, byref(self)) if self._lib_open is not None: self._lib_open(byref(self._lib_hdl), lib_dev_path.encode('utf-8'))
def __del__(self): """Free allocated memory on garbage collection""" LIBPHOBOS.ldm_dev_state_fini(byref(self))