diff --git a/scripts/targetcli b/scripts/targetcli index f11ece4..f00bffc 100755 --- a/scripts/targetcli +++ b/scripts/targetcli @@ -64,6 +64,7 @@ class TargetCLI(ConfigShell): 'max_backup_files': '10', 'auto_add_default_portal': True, 'auto_use_daemon': False, + 'daemon_use_batch_mode': False, } def usage(): @@ -121,7 +122,7 @@ def completer(text, state): except IndexError: return None -def call_daemon(shell, req): +def call_daemon(shell, req, interactive): try: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) except socket.error as err: @@ -139,9 +140,23 @@ def call_daemon(shell, req): "then run '#targetcli --disable-daemon'", 'red')) sys.exit(1) + # Two cases where we want to get pwd: + # 1. Before starting shell in interactive mode, needed for setting terminal + # 2. And only in Interactive mode, having command 'cd' + get_pwd = False + if interactive: + if not req: + req = "pwd" + get_pwd = True + elif "cd " in req: + req += "%pwd" + get_pwd = True + else: + req = "cd /%" + req # Non-interactive modes always consider start at '/' + try: # send request - sock.sendall(req) + sock.sendall(req.encode()) except socket.error as err: shell.con.display(shell.con.render_text(err, 'red')) sys.exit(1) @@ -152,17 +167,31 @@ def call_daemon(shell, req): amount_received = 0 # get the actual data in chunks + output = "" + path = "" while amount_received < amount_expected: data = sock.recv(1024) data = data.decode() amount_received += len(data) - print(data, end ="") + output += data + + if get_pwd: + output_split = output.splitlines() + lines = len(output_split) + for i in range(0, lines): + if i == lines-1: + path = str(output_split[i]) + else: + print(str(output_split[i]), end ="\n") + else: + print(output, end ="") sock.send(b'-END@OF@DATA-') sock.close() - sys.exit(0) -def get_arguments(shell): + return path + +def switch_to_daemon(shell, interactive): readline.set_completer(completer) readline.set_completer_delims('') @@ -173,27 +202,50 @@ def get_arguments(shell): if len(sys.argv) > 1: command = " ".join(sys.argv[1:]) + call_daemon(shell, command, False) + sys.exit(0) + + if interactive: + shell.con.display("targetcli shell version %s\n" + "Entering targetcli interactive mode for daemonized approach.\n" + "Type 'exit' to quit.\n" + % targetcli_version) else: - inputs = [] shell.con.display("targetcli shell version %s\n" - "Entering targetcli batch mode for daemonized approach.\n" - "Enter multiple commands separated by newline and " - "type 'exit' to run them all in one go.\n" - % targetcli_version) - while True: - shell.con.raw_write("/> ") - command = six.moves.input() - if command.lower() == "exit": - break + "Entering targetcli batch mode for daemonized approach.\n" + "Enter multiple commands separated by newline and " + "type 'exit' to run them all in one go.\n" + % targetcli_version) + + prompt_path = "/" + if interactive: + prompt_path = call_daemon(shell, None, interactive) # get the initial path + + inputs = [] + real_exit=False + while True: + command = six.moves.input("%s> " %prompt_path) + if command.lower() == "exit": + real_exit=True + elif not command: + continue + if not interactive: inputs.append(command) - command = '%'.join(inputs) # delimit multiple commands with '%' - - if not command: - sys.exit(1) - - usage_version(command); + if real_exit: + command = '%'.join(inputs) # delimit multiple commands with '%' + call_daemon(shell, command, interactive) + break + else: + if real_exit: + break + path = call_daemon(shell, command, interactive) + if path: + if path[0] == "/": + prompt_path = path + else: + print(path) # Error No Path ... - return command + sys.exit(0) def main(): ''' @@ -225,8 +277,12 @@ def main(): if sys.argv[1] in ("disable-daemon", "--disable-daemon"): disable_daemon=True + interactive_mode = True + if shell.prefs['daemon_use_batch_mode']: + interactive_mode = False + if use_daemon and not disable_daemon: - call_daemon(shell, get_arguments(shell).encode()) + switch_to_daemon(shell, interactive_mode) # does not return try: diff --git a/targetcli/ui_node.py b/targetcli/ui_node.py index 58a70c6..0485950 100644 --- a/targetcli/ui_node.py +++ b/targetcli/ui_node.py @@ -52,6 +52,9 @@ def __init__(self, name, parent=None, shell=None): self.define_config_group_param( 'global', 'auto_use_daemon', 'bool', 'If true, commands will be sent to targetclid.') + self.define_config_group_param( + 'global', 'daemon_use_batch_mode', 'bool', + 'If true, use batch mode for daemonized approach.') def assert_root(self): ''' diff --git a/targetclid.8 b/targetclid.8 index a783091..5760168 100644 --- a/targetclid.8 +++ b/targetclid.8 @@ -30,11 +30,38 @@ $ targetcli set global auto_use_daemon=true .br $ targetcli ls .TP -You can use batch mode for sending multiple commands in one go, +You can use interactive mode, .br $ targetcli .br -targetcli shell version 2.1.50 +targetcli shell version 2.1.51 +.br +Entering targetcli interactive mode for daemonized approach. +.br +Type 'exit' to quit. +.br +/> pwd +.br +/ +.br +/> cd /iscsi +.br +/> pwd +.br +/iscsi +.br +/> exit +.br +.TP +You can also use batch mode for sending multiple commands in one go, +.br +$ targetcli set global daemon_use_batch_mode=true +.br +Parameter daemon_use_batch_mode is now 'true'. +.br +$ targetcli +.br +targetcli shell version 2.1.51 .br Entering targetcli batch mode for daemonized approach. .br