def process(self, line): if len(line) == 0: return if line[0] == '!': self.builtin_commands['shell'].run( self.context, [line[1:]], {}, {}) return if line[0] == '/': if line.strip() == '/': self.prev_path = self.path[:] self.path = self.root_path[:] return else: self.start_from_root = True line = line[1:] if line == '..': if len(self.path) > 1: self.prev_path = self.path[:] self.cd_up() return if line == '-': prev = self.prev_path[:] self.prev_path = self.path[:] self.path = prev return try: i = parse(line) self.format_output(self.eval(i)) except SyntaxError, e: output_msg(_('Syntax error: {0}'.format(str(e))))
def on_leave(self): if self.modified: output_msg('Object was modified. ' 'Type either "save" or "discard" to leave') return False return True
def delete(self, name): entity = self.get_one(name) if entity: self.context.submit_task(self.delete_task, entity[self.save_key_name]) else: output_msg("Cannot delete {0}, item does not exist".format(name))
def process(self, line): if len(line) == 0: return if line[0] == '!': self.builtin_commands['shell'].run(self.context, [line[1:]], {}, {}) return if line[0] == '/': if line.strip() == '/': self.prev_path = self.path[:] self.path = self.root_path[:] return else: self.start_from_root = True line = line[1:] if line == '..': if len(self.path) > 1: self.prev_path = self.path[:] self.cd_up() return if line == '-': prev = self.prev_path[:] self.prev_path = self.path[:] self.path = prev return try: i = parse(line) self.format_output(self.eval(i)) except SyntaxError, e: output_msg(_('Syntax error: {0}'.format(str(e))))
def format_output(self, object): if isinstance(object, Object): output_object(object) if isinstance(object, Table): output_table(object) if isinstance(object, (basestring, int, long, bool)): output_msg(object)
def run(self, context, args, kwargs, opargs): if len(args) == 0: context.variables.save() output_msg('Environment Variables Saved to file: {0}'.format( context.variables.save_to_file)) if len(args) == 1: context.variables.save(args[0]) output_msg('Environment Variables Saved to file: {0}'.format( args[0]))
def connection_error(self, event): if event == ClientError.LOGOUT: output_msg('Logged out from server.') self.connection.disconnect() sys.exit(0) if event == ClientError.CONNECTION_CLOSED: time.sleep(1) self.__try_reconnect() return
def run(self, context, args, kwargs, opargs): if len(args) == 0: context.variables.save() output_msg( 'Environment Variables Saved to file: {0}'.format( context.variables.save_to_file)) if len(args) == 1: context.variables.save(args[0]) output_msg( 'Environment Variables Saved to file: {0}'.format(args[0]))
def run(self, context, args, kwargs, opargs): if len(args) < 1: output_msg('Wrong arguments count') return if not self.parent.has_property(args[0]): output_msg('Property {0} not found'.format(args[0])) return entity = self.parent.entity return self.parent.get_property(args[0], entity)
def login(self, user, password): try: self.connection.login_user(user, password) self.connection.subscribe_events(*EVENT_MASKS) self.connection.on_event(self.handle_event) self.connection.on_error(self.connection_error) except RpcException, e: if e.code == errno.EACCES: self.connection.disconnect() output_msg(_("Wrong username od password")) sys.exit(1)
def run(self, context, args, kwargs, opargs): nss = self.target.namespaces() cmds = self.target.commands() # Only display builtin items if in the RootNamespace obj = context.ml.get_relative_object(context.ml.path[-1], args) if obj.__class__.__name__ == 'RootNamespace': output_msg('Builtin items:', attrs=['bold']) output_list(context.ml.builtin_commands.keys()) output_msg('Current namespace items:', attrs=['bold']) out = cmds.keys() out += [ns.get_name() for ns in sorted(nss)] output_list(out)
def run(self, context, args, kwargs, opargs): if not args: output_msg("create-auto requires more arguments.\n" + inspect.getdoc(self)) return name = args.pop(0) disks = args if len(disks) == 0: output_msg("create-auto requires more arguments.\n" + inspect.getdoc(self)) return # The all_disks below is a temporary fix, use this after "select" is working # all_disks = context.connection.call_sync('disks.query', [], {"select":"path"}) all_disks = [disk["path"] for disk in context.connection.call_sync("disks.query")] available_disks = context.connection.call_sync("volumes.get_available_disks") if "alldisks" in disks: disks = available_disks else: for disk in disks: if not re.match("^\/dev\/", disk): disk = "/dev/" + disk if disk not in all_disks: output_msg("Disk " + disk + " does not exist.") return if disk not in available_disks: output_msg("Disk " + disk + " is not usable.") return context.submit_task("volume.create_auto", name, "zfs", disks)
def run(self, context, args, kwargs, opargs): if not args: output_msg("create-auto requires more arguments.\n" + inspect.getdoc(self)) return name = args.pop(0) disks = args if len(disks) == 0: output_msg("create-auto requires more arguments.\n" + inspect.getdoc(self)) return # The all_disks below is a temporary fix, use this after "select" is working # all_disks = context.connection.call_sync('disks.query', [], {"select":"path"}) all_disks = [disk["path"] for disk in context.connection.call_sync("disks.query")] available_disks = context.connection.call_sync('volumes.get_available_disks') if 'alldisks' in disks: disks = available_disks else: for disk in disks: if not re.match("^\/dev\/", disk): disk = "/dev/" + disk if disk not in all_disks: output_msg("Disk " + disk + " does not exist.") return if disk not in available_disks: output_msg("Disk " + disk + " is not usable.") return context.submit_task('volume.create_auto', name, 'zfs', disks)
def run(self, context, args, kwargs, opargs): if len(args) == 0: output_msg(_("Usage: source <filename>")) else: for arg in args: if os.path.isfile(arg): path = context.ml.path[:] context.ml.path = [context.root_ns] try: with open(arg, 'r') as f: for line in f: context.ml.process(line) except UnicodeDecodeError, e: output_msg(_("Incorrect filetype, cannot parse file: {0}".format(str(e)))) finally: context.ml.path = path
def run(self, context, args, kwargs, opargs): output_msg(_("You may try the following URLs to access" " the web user interface:")) my_ips = context.connection.call_sync('network.config.get_my_ips') my_protocols = context.connection.call_sync( 'system.ui.get_config') urls = [] for proto in my_protocols['webui_procotol']: proto_port = my_protocols['webui_{0}_port'.format(proto.lower())] if proto_port is not None: if proto_port in [80, 443]: for x in my_ips: urls.append('{0}://{1}'.format(proto.lower(), x)) else: for x in my_ips: urls.append('{0}://{1}:{2}'.format(proto.lower(), x, proto_port)) output_list(urls, label=_('URLs'))
def run(self, context, args, kwargs, opargs): output_msg( _("You may try the following URLs to access" " the web user interface:")) my_ips = context.connection.call_sync('network.config.get_my_ips') my_protocols = context.connection.call_sync('system.ui.get_config') urls = [] for proto in my_protocols['webui_procotol']: proto_port = my_protocols['webui_{0}_port'.format(proto.lower())] if proto_port is not None: if proto_port in [80, 443]: for x in my_ips: urls.append('{0}://{1}'.format(proto.lower(), x)) else: for x in my_ips: urls.append('{0}://{1}:{2}'.format( proto.lower(), x, proto_port)) output_list(urls, label=_('URLs'))
def run(self, context, args, kwargs, opargs): if len(args) == 0: output_msg(_("Usage: source <filename>")) else: for arg in args: if os.path.isfile(arg): path = context.ml.path[:] context.ml.path = [context.root_ns] try: with open(arg, 'r') as f: for line in f: context.ml.process(line) except UnicodeDecodeError, e: output_msg( _("Incorrect filetype, cannot parse file: {0}". format(str(e)))) finally: context.ml.path = path
def __try_reconnect(self): output_lock.acquire() self.ml.blank_readline() output_msg(_('Connection lost! Trying to reconnect...')) retries = 0 while True: retries += 1 try: time.sleep(2) self.connect() try: if self.hostname == '127.0.0.1': self.connection.login_user(getpass.getuser(), '') else: self.connection.login_token(self.connection.token) self.connection.subscribe_events(*EVENT_MASKS) except RpcException: output_msg( _("Reauthentication failed (most likely token expired or server was restarted)" )) sys.exit(1) break except Exception, e: output_msg(_('Cannot reconnect: {0}'.format(str(e))))
def run(sef, context, args, kwargs, opargs): if len(args) == 0: output_msg("") else: curly_regex = "\$\{([\w]+)\}" echo_output_list = ' '.join(args) echo_output_list = echo_output_list.split('\\n') for x, lst in enumerate(echo_output_list): tmp_lst = lst.split(' ') for y, word in enumerate(tmp_lst): occurences = re.findall(curly_regex, word) for r in occurences: try: value = context.variables.variables[r].__str__() except: output_msg(r + " " + _("No such Environment Variable exists")) return rep = "\$\{" + r + "\}" word = re.sub(rep, value, word) tmp_lst[y] = word if word.startswith('$'): try: tmp_lst[y] = context.variables.variables[word.strip()[1:]].__str__() except KeyError: output_msg(word[1:] + " " + _("No such Environment Variable exists")) return echo_output_list[x] = ' '.join(tmp_lst) map(output_msg, echo_output_list)
def run(sef, context, args, kwargs, opargs): if len(args) == 0: output_msg("") else: curly_regex = "\$\{([\w]+)\}" echo_output_list = ' '.join(args) echo_output_list = echo_output_list.split('\\n') for x, lst in enumerate(echo_output_list): tmp_lst = lst.split(' ') for y, word in enumerate(tmp_lst): occurences = re.findall(curly_regex, word) for r in occurences: try: value = context.variables.variables[r].__str__() except: output_msg( r + " " + _("No such Environment Variable exists")) return rep = "\$\{" + r + "\}" word = re.sub(rep, value, word) tmp_lst[y] = word if word.startswith('$'): try: tmp_lst[y] = context.variables.variables[ word.strip()[1:]].__str__() except KeyError: output_msg( word[1:] + " " + _("No such Environment Variable exists")) return echo_output_list[x] = ' '.join(tmp_lst) map(output_msg, echo_output_list)
def run(self, context, args, kwargs, opargs): ns = EntityNamespace.SingleItemNamespace(None, self.parent) ns.orig_entity = wrap(copy.deepcopy(self.parent.skeleton_entity)) ns.entity = wrap(copy.deepcopy(self.parent.skeleton_entity)) if not args and not kwargs: context.ml.cd(ns) return if len(args) > 0: prop = self.parent.primary_key prop.do_set(ns.entity, args.pop(0)) for k, v in kwargs.items(): if not self.parent.has_property(k): output_msg('Property {0} not found'.format(k)) return for k, v in kwargs.items(): prop = self.parent.get_mapping(k) prop.do_set(ns.entity, v) self.parent.save(ns, new=True)
def load(self, filename): try: with open(filename, 'r') as f: data = json.load(f) except IOError: # The file does not exist lets just default to default env settings # TODO: Should I report this to the user somehow? return except ValueError: # If the data being deserialized is not a valid JSON document, # a ValueError will be raised. output_msg( _("WARNING: The CLI config file: {0} has ".format(filename) + "improper format. Please check the file for errors. " + "Resorting to Default set of Environment Variables.")) return # Now that we know that this file is legit and that it may be different # than the default (DEFAULT_CLI_CONFIGFILE) lets just set this class's # 'save_to_file' variable to this file. self.save_to_file = filename for name, setting in data.iteritems(): self.set(name, setting['value'], ValueType(setting['type']), setting['default'], setting['choices'])
def print_event(self, event, data): if self.event_divert: self.event_queue.put((event, data)) return if event == 'task.progress': return output_lock.acquire() self.ml.blank_readline() translation = events.translate(self, event, data) if translation: output_msg(translation) if 'state' in data: if data['state'] == 'FAILED': status = self.connection.call_sync('task.status', data['id']) output_msg("Task #{0} error: {1}".format( data['id'], status['error']['message'])) sys.stdout.flush() self.ml.restore_readline() output_lock.release()
def print_event(self, event, data): if self.event_divert: self.event_queue.put((event, data)) return if event == 'task.progress': return output_lock.acquire() self.ml.blank_readline() translation = events.translate(self, event, data) if translation: output_msg(translation) if 'state' in data: if data['state'] == 'FAILED': status = self.connection.call_sync('task.status', data['id']) output_msg("Task #{0} error: {1}".format(data['id'], status['error']['message'])) sys.stdout.flush() self.ml.restore_readline() output_lock.release()
def run(self, context, args, kwargs, opargs): if not args: output_msg("attach-disk requires more arguments.\n" + inspect.getdoc(self)) return disk = args.pop(0) # The all_disks below is a temporary fix, use this after "select" is working # all_disks = context.connection.call_sync('disks.query', [], {"select":"path"}) all_disks = [d["path"] for d in context.connection.call_sync("disks.query")] available_disks = context.connection.call_sync('volumes.get_available_disks') if not re.match("^\/dev\/", disk): disk = "/dev/" + disk if disk not in all_disks: output_msg("Disk " + disk + " does not exist.") return if disk not in available_disks: output_msg("Disk " + disk + " is not usable.") return volume = context.call_sync('zfs.pool.get_boot_pool') context.submit_task('boot.attach_disk', volume['groups']['data'][0]['guid'], disk) return
def __try_reconnect(self): output_lock.acquire() self.ml.blank_readline() output_msg(_('Connection lost! Trying to reconnect...')) retries = 0 while True: retries += 1 try: time.sleep(2) self.connect() try: if self.hostname == '127.0.0.1': self.connection.login_user(getpass.getuser(), '') else: self.connection.login_token(self.connection.token) self.connection.subscribe_events(*EVENT_MASKS) except RpcException: output_msg(_("Reauthentication failed (most likely token expired or server was restarted)")) sys.exit(1) break except Exception, e: output_msg(_('Cannot reconnect: {0}'.format(str(e))))
def run(self, context, args, kwargs, opargs): output_msg(context.connection.call_sync('update.get_current_train'))
def run(self, context, args, kwargs, opargs): output_msg(context.connection.call_sync('update.check'))
return try: i = parse(line) self.format_output(self.eval(i)) except SyntaxError, e: output_msg(_('Syntax error: {0}'.format(str(e)))) except CommandException, e: output_msg(_('Error: {0}'.format(str(e)))) if self.context.variables.get('debug'): output_msg(e.stacktrace) except SystemExit: # We do not want to catch a user entered `exit` so... raise except Exception as e: output_msg(_('Unexpected Error: {0}'.format(str(e)))) if self.context.variables.get('debug'): output_msg(traceback.format_exc()) def get_relative_object(self, ns, tokens): ptr = ns while len(tokens) > 0: token = tokens.pop(0) if issubclass(type(ptr), Namespace): nss = ptr.namespaces() for ns in nss: if ns.get_name() == token: ptr = ns break
def run(self, context, args, kwargs, opargs): if len(args) == 0: output_msg("") else: less_output = ' '.join(args) output_less(lambda: output_msg(less_output))
for arg in args: if os.path.isfile(arg): path = context.ml.path[:] context.ml.path = [context.root_ns] try: with open(arg, 'r') as f: for line in f: context.ml.process(line) except UnicodeDecodeError, e: output_msg( _("Incorrect filetype, cannot parse file: {0}". format(str(e)))) finally: context.ml.path = path else: output_msg(_("File " + arg + " does not exist.")) @description("Prints the provided message to the output") class EchoCommand(Command): """ Usage: echo string_to_display The echo utility writes any specified operands, separated by single blank (` ') characters and followed by a newline (`\\n') character, to the standard output. It also has the ability to expand and substitute environment variables in place using the '$' or '${variable_name}' syntax/ Examples: echo Have a nice Day! output: Have a nice Day!
def run(self, context, args, kwargs, opargs): output_msg(_("System going for a shutdown...")) context.submit_task('system.shutdown')
def run(self, context, args, kwargs, opargs): display_props = False if "properties" in args: display_props = True obj = context.ml.get_relative_object(context.ml.path[-1], args) bases = map(lambda x: x.__name__, obj.__class__.__bases__) if display_props: if hasattr(obj, 'property_mappings'): prop_dict_list = [] for prop in obj.property_mappings: prop_dict = { 'propname': prop.name, 'propdescr': prop.descr } prop_dict_list.append(prop_dict) return Table(prop_dict_list, [ Table.Column('Property', 'propname', ValueType.STRING), Table.Column('Description', 'propdescr', ValueType.STRING) ]) else: output_msg( "The current namespace does not have any properties.") return if 'Command' in bases and obj.__doc__: if hasattr(obj, 'parent'): if obj.__class__.__name__ in obj.parent.localdoc: output_msg( textwrap.dedent( obj.parent.localdoc[obj.__class__.__name__])) else: output_msg(inspect.getdoc(obj)) else: output_msg(inspect.getdoc(obj)) if 'PipeCommand' in bases and obj.__doc__: output_msg(inspect.getdoc(obj)) if any(i in ['Namespace', 'EntityNamespace'] for i in bases): # First listing the Current Namespace's commands cmd_dict_list = [] ns_cmds = obj.commands() for key, value in ns_cmds.iteritems(): cmd_dict = { 'cmd': key, 'description': value.description, } cmd_dict_list.append(cmd_dict) # Then listing the namespaces available from this namespace namespaces_dict_list = [] for nss in obj.namespaces(): if not isinstance(nss, EntityNamespace.SingleItemNamespace): namespace_dict = { 'name': nss.name, 'description': nss.description, } namespaces_dict_list.append(namespace_dict) # Finally listing the builtin cmds builtin_cmd_dict_list = [] for key, value in context.ml.builtin_commands.iteritems(): builtin_cmd_dict = { 'cmd': key, 'description': value.description, } builtin_cmd_dict_list.append(builtin_cmd_dict) # Finally printing all this out in unix `LESS(1)` pager style output_call_list = [] if cmd_dict_list: output_call_list.append( Table(cmd_dict_list, [ Table.Column('Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) if namespaces_dict_list: output_call_list.append( Table(namespaces_dict_list, [ Table.Column('Namespace', 'name', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) # Only display the help on builtin commands if in the RootNamespace if obj.__class__.__name__ == 'RootNamespace': output_call_list.append( Table(builtin_cmd_dict_list, [ Table.Column('Builtin Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) output_less(lambda: output_table_list(output_call_list))
def run(self, context, args, kwargs, opargs): output_msg( _("These are the active ips from all the configured" " network interfaces")) output_list(context.connection.call_sync('network.config.get_my_ips'), _("IP Addresses"))
def run(self, context, args, kwargs, opargs): display_props = False if "properties" in args: display_props = True obj = context.ml.get_relative_object(context.ml.path[-1], args) bases = map(lambda x: x.__name__, obj.__class__.__bases__) if display_props: if hasattr(obj, 'property_mappings'): prop_dict_list = [] for prop in obj.property_mappings: prop_dict = { 'propname': prop.name, 'propdescr': prop.descr } prop_dict_list.append(prop_dict) return Table(prop_dict_list, [ Table.Column('Property', 'propname', ValueType.STRING), Table.Column('Description', 'propdescr', ValueType.STRING)]) else: output_msg("The current namespace does not have any properties.") return if 'Command' in bases and obj.__doc__: if hasattr(obj, 'parent'): if obj.__class__.__name__ in obj.parent.localdoc: output_msg(textwrap.dedent(obj.parent.localdoc[obj.__class__.__name__])) else: output_msg(inspect.getdoc(obj)) else: output_msg(inspect.getdoc(obj)) if 'PipeCommand' in bases and obj.__doc__: output_msg(inspect.getdoc(obj)) if any(i in ['Namespace', 'EntityNamespace'] for i in bases): # First listing the Current Namespace's commands cmd_dict_list = [] ns_cmds = obj.commands() for key, value in ns_cmds.iteritems(): cmd_dict = { 'cmd': key, 'description': value.description, } cmd_dict_list.append(cmd_dict) # Then listing the namespaces available from this namespace namespaces_dict_list = [] for nss in obj.namespaces(): if not isinstance(nss, EntityNamespace.SingleItemNamespace): namespace_dict = { 'name': nss.name, 'description': nss.description, } namespaces_dict_list.append(namespace_dict) # Finally listing the builtin cmds builtin_cmd_dict_list = [] for key, value in context.ml.builtin_commands.iteritems(): builtin_cmd_dict = { 'cmd': key, 'description': value.description, } builtin_cmd_dict_list.append(builtin_cmd_dict) # Finally printing all this out in unix `LESS(1)` pager style output_call_list = [] if cmd_dict_list: output_call_list.append( Table(cmd_dict_list, [ Table.Column('Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING)])) if namespaces_dict_list: output_call_list.append( Table(namespaces_dict_list, [ Table.Column('Namespace', 'name', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) # Only display the help on builtin commands if in the RootNamespace if obj.__class__.__name__ == 'RootNamespace': output_call_list.append( Table(builtin_cmd_dict_list, [ Table.Column('Builtin Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) output_less(lambda: output_table_list(output_call_list))
def run(self, context, args, kwargs, opargs): output_msg(_("These are the active ips from all the configured" " network interfaces")) output_list(context.connection.call_sync('network.config.get_my_ips'), _("IP Addresses"))
def run(self, context, args, kwargs, opargs): output_msg(_("System going for a reboot...")) context.submit_task('system.reboot')
def greet(self): output_msg( _("Welcome to FreeNAS CLI! Type '?' for help at any point.")) output_msg("")
class MainLoop(object): builtin_commands = { 'exit': ExitCommand(), 'setenv': SetenvCommand(), 'printenv': PrintenvCommand(), 'saveenv': SaveenvCommand(), 'shell': ShellCommand(), 'eval': EvalCommand(), 'shutdown': ShutdownCommand(), 'reboot': RebootCommand(), 'help': HelpCommand(), 'top': TopCommand(), 'showips': ShowIpsCommand(), 'showurls': ShowUrlsCommand(), 'source': SourceCommand(), 'less': LessCommand(), 'clear': ClearCommand(), 'history': HistoryCommand(), 'echo': EchoCommand(), 'search': SearchPipeCommand(), 'exclude': ExcludePipeCommand(), 'sort': SortPipeCommand(), 'limit': LimitPipeCommand(), 'select': SelectPipeCommand() } def __init__(self, context): self.context = context self.root_path = [self.context.root_ns] self.path = self.root_path[:] self.prev_path = self.path[:] self.start_from_root = False self.namespaces = [] self.connection = None def __get_prompt(self): variables = { 'path': '/'.join([x.get_name() for x in self.path]), 'host': self.context.hostname } return self.context.variables.get('prompt').format(**variables) def greet(self): output_msg( _("Welcome to FreeNAS CLI! Type '?' for help at any point.")) output_msg("") def cd(self, ns): if not self.cwd.on_leave(): return self.path.append(ns) self.cwd.on_enter() def cd_up(self): if not self.cwd.on_leave(): return del self.path[-1] self.cwd.on_enter() @property def cwd(self): return self.path[-1] def repl(self): readline.parse_and_bind('tab: complete') readline.set_completer(self.complete) self.greet() a = ShowUrlsCommand() a.run(self.context, None, None, None) while True: try: line = raw_input(self.__get_prompt()).strip() except EOFError: print return except KeyboardInterrupt: print continue self.process(line) def find_in_scope(self, token): if token in self.builtin_commands.keys(): return self.builtin_commands[token] for ns in self.cwd.namespaces(): if token == ns.get_name(): return ns for name, cmd in self.cwd.commands().items(): if token == name: return cmd return None def convert_literals(self, tokens): for i in tokens: if isinstance(i, Symbol): # Convert symbol to string yield i.name if isinstance(i, Literal): yield i.value if isinstance(i, BinaryExpr): if isinstance(i.right, Literal): yield (i.left, i.op, i.right.value) if isinstance(i.right, Symbol): # Convert symbol to string yield (i.left, i.op, i.right.name) if isinstance(i.right, CommandExpansion): yield (i.left, i.op, self.eval(i.right.expr)) def format_output(self, object): if isinstance(object, Object): output_object(object) if isinstance(object, Table): output_table(object) if isinstance(object, (basestring, int, long, bool)): output_msg(object) def eval(self, tokens): oldpath = self.path[:] if self.start_from_root: self.path = self.root_path[:] self.start_from_root = False command = None pipe_stack = [] args = [] while tokens: token = tokens.pop(0) if isinstance(token, Symbol): item = self.find_in_scope(token.name) if command: args.append(token) continue if isinstance(item, Namespace): self.cd(item) continue if isinstance(item, Command): command = item continue try: raise SyntaxError( "Command or namespace {0} not found".format( token.name)) finally: self.path = oldpath if isinstance(token, CommandExpansion): if not command: try: raise SyntaxError( "Command expansion cannot replace command or namespace name" ) finally: self.path = oldpath result = self.eval(token.expr) if not isinstance(result, basestring): try: raise SyntaxError( "Can only use command expansion with commands returning single value" ) finally: self.path = oldpath args.append(Literal(result, type(result))) continue if isinstance(token, (Literal, BinaryExpr)): args.append(token) continue if isinstance(token, PipeExpr): pipe_stack.append(token.right) tokens += token.left args = list(self.convert_literals(args)) args, kwargs, opargs = sort_args(args) filter_ops = [] filter_params = {} if not command: if len(args) > 0: raise SyntaxError('No command specified') return tmpath = self.path[:] if isinstance(command, FilteringCommand): for p in pipe_stack[:]: pipe_cmd = self.find_in_scope(p[0].name) if not pipe_cmd: try: raise SyntaxError("Pipe command {0} not found".format( p[0].name)) finally: self.path = oldpath pipe_args = self.convert_literals(p[1:]) try: ret = pipe_cmd.serialize_filter(self.context, *sort_args(pipe_args)) if 'filter' in ret: filter_ops += ret['filter'] if 'params' in ret: filter_params.update(ret['params']) except NotImplementedError: continue # If serializing filter succeeded, remove it from pipe stack pipe_stack.remove(p) ret = command.run(self.context, args, kwargs, opargs, filtering={ 'filter': filter_ops, 'params': filter_params }) else: self.path = oldpath ret = command.run(self.context, args, kwargs, opargs) for i in pipe_stack: pipe_cmd = self.find_in_scope(i[0].name) pipe_args = self.convert_literals(i[1:]) try: ret = pipe_cmd.run(self.context, *sort_args(pipe_args), input=ret) except CommandException: raise except Exception as e: raise CommandException( _('Unexpected Error: {0}'.format(str(e)))) finally: self.path = oldpath if self.path != tmpath: # Command must have modified the path return ret self.path = oldpath return ret def process(self, line): if len(line) == 0: return if line[0] == '!': self.builtin_commands['shell'].run(self.context, [line[1:]], {}, {}) return if line[0] == '/': if line.strip() == '/': self.prev_path = self.path[:] self.path = self.root_path[:] return else: self.start_from_root = True line = line[1:] if line == '..': if len(self.path) > 1: self.prev_path = self.path[:] self.cd_up() return if line == '-': prev = self.prev_path[:] self.prev_path = self.path[:] self.path = prev return try: i = parse(line) self.format_output(self.eval(i)) except SyntaxError, e: output_msg(_('Syntax error: {0}'.format(str(e)))) except CommandException, e: output_msg(_('Error: {0}'.format(str(e)))) if self.context.variables.get('debug'): output_msg(e.stacktrace)
output_msg(_("Usage: source <filename>")) else: for arg in args: if os.path.isfile(arg): path = context.ml.path[:] context.ml.path = [context.root_ns] try: with open(arg, 'r') as f: for line in f: context.ml.process(line) except UnicodeDecodeError, e: output_msg(_("Incorrect filetype, cannot parse file: {0}".format(str(e)))) finally: context.ml.path = path else: output_msg(_("File " + arg + " does not exist.")) @description("Prints the provided message to the output") class EchoCommand(Command): """ Usage: echo string_to_display The echo utility writes any specified operands, separated by single blank (` ') characters and followed by a newline (`\\n') character, to the standard output. It also has the ability to expand and substitute environment variables in place using the '$' or '${variable_name}' syntax/ Examples: echo Have a nice Day! output: Have a nice Day!
def run(self, context, args, kwargs, opargs): output_msg("System going for an update now...") context.submit_task('update.update')