summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurizio Lombardi <mlombard@redhat.com>2020-04-09 12:18:48 +0200
committerGitHub <noreply@github.com>2020-04-09 12:18:48 +0200
commit48fb5a3c692faf91e61138897ce01a581b92c41b (patch)
treeab9db87ac41191aa141449993c4bb28b4a1c30ae
parente09fa8c531b4a4d2972df8e96e0baf0bdd953715 (diff)
parent534c4759fc27e7ef8e1d477b4909485d2ac4bf91 (diff)
downloadtargetcli-48fb5a3c692faf91e61138897ce01a581b92c41b.tar.gz
Merge pull request #167 from pkalever/interactive-mode
daemonized-mode: add interactive shell support
-rwxr-xr-xscripts/targetcli102
-rw-r--r--targetcli/ui_node.py3
-rw-r--r--targetclid.831
3 files changed, 111 insertions, 25 deletions
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 @@ class UINode(ConfigNode):
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 <hit-enter>
.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 <hit-enter>
+.br
+targetcli shell version 2.1.51
.br
Entering targetcli batch mode for daemonized approach.
.br