def categories(self, user, password): sw_name = self.dispatcher.call_sync('system.info.version').split( '-')[0].lower() try: r = requests.post( 'https://%s/%s/api/v1.0/categories' % (ADDRESS, sw_name), data=json.dumps({ 'user': user, 'password': password, }), headers={'Content-Type': 'application/json'}, timeout=10, ) data = r.json() except simplejson.JSONDecodeError as e: logger.debug('Failed to decode ticket attachment response: %s', r.text) raise RpcException(errno.EINVAL, 'Failed to decode ticket response') except requests.ConnectionError as e: raise RpcException(errno.ENOTCONN, 'Connection failed: {0}'.format(str(e))) except requests.Timeout as e: raise RpcException(errno.ETIMEDOUT, 'Connection timed out: {0}'.format(str(e))) if 'error' in data: raise RpcException(errno.EINVAL, data['message']) return data
def unregister_schema(self, name, sender): if name not in self.schemas.keys(): raise RpcException(errno.ENOENT, 'Schema not found') conn = self.schemas[name] if conn != sender: raise RpcException(errno.EPERM, 'Permission denied') self.__dispatcher.unregister_schema_definition(name)
def resume_service(self, name, sender): if name not in self.services.keys(): raise RpcException(errno.ENOENT, 'Service not found') svc = self.services[name] if svc.connection != sender: raise RpcException(errno.EPERM, 'Permission denied') svc.resumed.set()
def join_subtasks(self, subtask_ids, sender): task = self.__balancer.get_task_by_sender(sender) if not task: raise RpcException(errno.EPERM, 'Not authorized') subtasks = map(self.__balancer.get_task, subtask_ids) self.__dispatcher.balancer.join_subtasks(*subtasks) for i in subtasks: if i.state != TaskState.FINISHED: raise RpcException(errno.EFAULT, 'Subtask failed: {0}'.format(i.error['message']))
def release(self, identifier, sender): if identifier not in transactions: raise RpcException(errno.ENOENT, 'Transaction not found') t = transactions[identifier] s = first_or_default(lambda s: s.sid == sender.session_id, t) if not s: raise RpcException(errno.EINVAL, 'Transaction is not held by current session') t.purge(s)
def emit(self, alert): alertprops = registered_alerts.get(alert['name']) if alertprops is None: raise RpcException( errno.ENOENT, "Alert {0} not registered".format(alert['name'])) # Try to find the first matching namespace emitters = None dot = alert['name'].split('.') for i in xrange(len(dot), 0, -1): namespace = '.'.join(dot[0:i]) afilter = self.datastore.get_one( 'alerts-filters', ('name', '=', namespace), ('severity', '=', alert['severity']), ) if afilter: emitters = afilter['emitters'] # If there are no filters configured, set default emitters if emitters is None: if alert['severity'] == 'CRITICAL': emitters = ['UI', 'EMAIL'] else: emitters = ['UI'] if 'UI' in emitters: self.datastore.insert('alerts', alert)
def get_service_config(self, service): svc = self.datastore.get_one('service_definitions', ('name', '=', service)) if not svc: raise RpcException(errno.EINVAL, 'Invalid service name') node = ConfigNode('service.{0}'.format(service), self.configstore) return node
def vdev_by_guid(self, pool, guid): try: zfs = libzfs.ZFS() pool = zfs.get(pool) return pool.vdev_by_guid(int(guid)).__getstate__() except libzfs.ZFSException, err: raise RpcException(errno.EFAULT, str(err))
def get_disks(self, name): try: zfs = libzfs.ZFS() pool = zfs.get(name) return pool.disks except libzfs.ZFSException, err: raise RpcException(errno.EFAULT, str(err))
def run_subtask(self, name, args, sender): task = self.__balancer.get_task_by_sender(sender) if not task: raise RpcException(errno.EPERM, 'Not authorized') ret = self.__dispatcher.balancer.run_subtask(task, name, args) return ret.id
def unregister_service(self, name, sender): if name not in self.services.keys(): raise RpcException(errno.ENOENT, 'Service not found') svc = self.services[name] if svc.connection != sender: raise RpcException(errno.EPERM, 'Permission denied') self.__dispatcher.rpc.unregister_service(name) self.__dispatcher.dispatch_event('plugin.service_unregistered', { 'address': sender.ws.handler.client_address, 'service-name': name, 'description': "Service {0} unregistered".format(name) }) del self.services[name]
def wait(self, id): task = self.__balancer.get_task(id) if task: task.ended.wait() return raise RpcException(errno.ENOENT, 'No such task')
def resolve_path(self, path): volname, _, rest = path.partition(':') volume = self.query([('name', '=', volname)], {'single': True}) if not volume: raise RpcException(errno.ENOENT, 'Volume {0} not found'.format(volname)) return os.path.join(volume['mountpoint'], rest)
def query(self, filter=None, params=None): try: zfs = libzfs.ZFS() result = map(lambda o: o.__getstate__(recursive=False), list(zfs.datasets)) return wrap(result).query(*(filter or []), **(params or {})) except libzfs.ZFSException, err: raise RpcException(errno.EFAULT, str(err))
def kick_session(self, session_id, sender): session = first_or_default( lambda s: s.session_id == session_id, self.dispatcher.ws_server.connections) if not session: raise RpcException(errno.ENOENT, 'Session {0} not found'.format(session_id)) session.logout('Kicked out by {0}'.format(sender.user.name))
def obtain_changelog(self): temp_changelog = update_cache.get('changelog', timeout=1) if temp_changelog is not None: return temp_changelog elif update_cache.is_valid('changelog'): return temp_changelog else: raise RpcException( errno.EBUSY, ('Changelog list is invalidated, an Update Check ' 'might be underway. Try again in some time.'))
def get_partition_config(self, part_name): for name, disk in diskinfo_cache.itervalid(): for part in disk['partitions']: if part_name in part['paths']: result = part.copy() result['disk'] = disk['path'] return result raise RpcException(errno.ENOENT, "Partition {0} not found".format(part_name))
def is_update_available(self): temp_updateAvailable = update_cache.get('updateAvailable', timeout=1) if temp_updateAvailable is not None: return temp_updateAvailable elif update_cache.is_valid('updateAvailable'): return temp_updateAvailable else: raise RpcException( errno.EBUSY, ('Update Availability flag is invalidated, an Update Check' ' might be underway. Try again in some time.'))
def get_update_ops(self): temp_updateOperations = update_cache.get('updateOperations', timeout=1) if temp_updateOperations is not None: return temp_updateOperations elif update_cache.is_valid('updateOperations'): return temp_updateOperations else: raise RpcException( errno.EBUSY, ('Update Operations Dict is invalidated, an Update Check ' 'might be underway. Try again in some time.'))
def request_directory(self, name): path = os.path.join(SYSTEM_DIR, name) if os.path.exists(path): if os.path.isdir(path): return path raise RpcException(errno.EPERM, 'Cannot grant directory {0}'.format(name)) os.mkdir(path) return path
def decode_path(self, path): path = os.path.normpath(path)[1:] tokens = path.split(os.sep) if tokens[0] != 'volumes': raise RpcException(errno.EINVAL, 'Invalid path') volname = tokens[1] config = self.get_config(volname) datasets = map(lambda d: d['name'], flatten_datasets(config['root_dataset'])) n = len(tokens) while n > 0: fragment = '/'.join(tokens[1:n]) if fragment in datasets: return volname, fragment, '/'.join(tokens[n:]) n -= 1 raise RpcException(errno.ENOENT, 'Cannot look up path')
def next_gid(self): start_gid, end_gid = self.dispatcher.configstore.get( 'accounts.local_gid_range') gid = None for i in range(start_gid, end_gid): if not self.datastore.exists('groups', ('id', '=', i)): gid = i break if not gid: raise RpcException(errno.ENOSPC, 'No free GIDs available') return gid
def ensure_resilvered(self, name): try: zfs = libzfs.ZFS() pool = zfs.get(name) self.dispatcher.test_or_wait_for_event( 'fs.zfs.resilver.finished', lambda args: args['guid'] == str(pool.guid), lambda: pool.scrub.state == libzfs.ScanState.SCANNING and pool. scrub.function == libzfs.ScanFunction.RESILVER) except libzfs.ZFSException, err: raise RpcException(errno.EFAULT, str(err))
def ensure_stopped(self, service): # XXX launchd! svc = self.datastore.get_one('service_definitions', ('name', '=', service)) if not svc: raise RpcException(errno.ENOENT, 'Service {0} not found'.format(service)) rc_scripts = svc['rcng']['rc-scripts'] try: if type(rc_scripts) is unicode: system("/usr/sbin/service", rc_scripts, 'onestop') if type(rc_scripts) is list: for i in rc_scripts: system("/usr/sbin/service", i, 'onestop') except SubprocessException, e: pass
def update_info(self): if not update_cache.is_valid('updateAvailable'): raise RpcException( errno.EBUSY, ('Update Availability flag is invalidated, an Update Check' ' might be underway. Try again in some time.')) updateAvailable = update_cache.get('updateAvailable', timeout=1) if not updateAvailable: return None updateOperations = update_cache.get('updateOperations', timeout=1) updateNotes = update_cache.get('updateNotes', timeout=1) updateNotice = update_cache.get('updateNotice', timeout=1) changelog = update_cache.get('changelog', timeout=1) return { 'changelog': changelog, 'notes': updateNotes, 'notice': updateNotice, 'operations': updateOperations, }
def acquire(self, identifier, timeout, sender): t = transactions.setdefault(identifier, Transaction(self.dispatcher, identifier)) s = first_or_default(lambda s: s.sid == sender.session_id, t) if s: raise RpcException( errno.EBUSY, 'Transaction is already held by current session') s = Session(timeout, sender.user.name, sender.session_id) t.sessions.append(s) gevent.spawn(t.purge, s) self.dispatcher.dispatch_event( 'ui.transaction.acquired', { 'identifier': identifier, 'sid': sender.session_id, 'user': sender.user.name })
def restart(self, service): svc = self.datastore.get_one('service_definitions', ('name', '=', service)) status = self.query([('name', '=', service)], {'single': True}) if not svc: raise RpcException(errno.ENOENT, 'Service {0} not found'.format(service)) rc_scripts = svc['rcng']['rc-scripts'] if status['state'] != 'running': return try: if type(rc_scripts) is unicode: system("/usr/sbin/service", rc_scripts, 'onerestart') if type(rc_scripts) is list: for i in rc_scripts: system("/usr/sbin/service", i, 'onerestart') except SubprocessException, e: pass
def list_dir(self, path): result = [] if not os.path.isdir(path): raise RpcException(errno.ENOENT, 'Path {0} is not a directory'.format(path)) for i in os.listdir(path): try: st = os.stat(os.path.join(path, i)) except OSError: continue item = { 'name': i, 'type': get_type(st), 'size': st.st_size, 'modified': st.st_mtime } result.append(item) return result
def stat(self, path): try: st = os.stat(path) except OSError, err: raise RpcException(err.errno, str(err))
def get_disk_config(self, name): disk = get_disk_by_path(name) if not disk: raise RpcException(errno.ENOENT, "Disk {0} not found".format(name)) return disk