Skip to content
Snippets Groups Projects
Commit e73f775b authored by Roman Tsisyk's avatar Roman Tsisyk
Browse files

Add support for remote connection in interactive console

Use require('console').connect(host, port) in interactive mode to
connect console to remote host:

```
./src/tarantool: version 1.6.2-257-g8d89b64
tarantool> box.cfg{primary_port = 3301}
---
...
tarantool> require('console').connect('127.0.0.1', 3301) <!-- connect
---
...
127.0.0.1:3301> remote_command
---
- result
...
127.0.0.1:3301> [CTRL+D] <!-- disconnect from remote
tarantool> local_command
---
- result
...

```

This patch uses CALL(dostring) to execute commands on remote server.
parent 7cbd8c27
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,7 @@
local internal = require('console')
local formatter = require('yaml')
local session = require('session')
local function format(status, ...)
-- When storing a nil in a Lua table, there is no way to
......@@ -25,7 +26,7 @@ local function format(status, ...)
return formatter.encode(res)
end
local function eval(line, ...)
local function local_eval(self, line, ...)
--
-- Attempt to append 'return ' before the chunk: if the chunk is
-- an expression, this pushes results of the expression onto the
......@@ -42,8 +43,50 @@ local function eval(line, ...)
return format(pcall(fun, ...))
end
local function eval(line)
return local_eval(nil, line)
end
local local_mt = {
__index = {
eval = local_eval;
close = function() end;
prompt = function() return 'tarantool' end;
}
}
local function remote_eval(self, line, ...)
--
-- call remote 'console.eval' function using 'dostring' and return result
--
local status, res = pcall(self.conn.call, self.conn, "dostring",
"return require('console').eval(...)", line)
if not status then
-- remote request failed
return format(status, res)
end
-- return formatted output from remote
return res[1][0]
end
local function remote_close(self)
pcall(self.conn.close, self.conn) -- ignore errors
end
local function remote_prompt(self)
return string.format("%s:%s", self.conn.host, self.conn.port)
end
local remote_mt = {
__index = {
eval = remote_eval;
close = remote_close;
prompt = remote_prompt;
}
}
local function read(host)
local delim = require('session').delimiter()
local delim = session.delimiter()
local linenum = 0
local buf = ""
while true do
......@@ -62,23 +105,45 @@ local function read(host)
end
local function repl()
local host = "tarantool"
if session.storage.console ~= nil then
return -- REPL is already enabled
end
session.storage.console = {}
local handlers = {}
table.insert(handlers, setmetatable({}, local_mt))
session.storage.console.handlers = handlers
local line
while true do
while #handlers > 0 do
local handler = handlers[#handlers]
-- read
local line = read(host)
local line = read(handler:prompt())
if line == nil then
break
-- remove handler
io.write("\n")
handler:close()
table.remove(handlers)
else
-- eval
local out = handler:eval(line)
-- print
io.write(out)
internal.add_history(line)
end
-- eval
local out = eval(line)
-- print
io.write(out)
internal.add_history(line)
end
end
local function connect(...)
if not session.storage.console then
error("console.connect() works only in interactive mode")
end
local conn = box.net.box.new(...)
conn:ping() -- test connection
table.insert(session.storage.console.handlers, setmetatable(
{ conn = conn}, remote_mt))
end
return {
repl = repl;
eval = eval;
connect = connect;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment