]> git.e2factory.org Git - e2factory.git/commitdiff
Extend e2lib.ssh_remote_cmd() to capture and return stdout
authorTobias Ulmer <tu@emlix.com>
Mon, 25 Nov 2013 18:34:28 +0000 (19:34 +0100)
committerTobias Ulmer <tu@emlix.com>
Wed, 16 Nov 2016 14:41:17 +0000 (15:41 +0100)
Easy with the new callcmd()

Signed-off-by: Tobias Ulmer <tu@emlix.com>
generic/e2lib.lua

index ce6a3b2cd3c57f2627aac02f66fb2b09c99aae84..e47de98b4d2067f7ee943169803201e13ca5f0e9 100644 (file)
@@ -2104,38 +2104,94 @@ end
 -- @param argv Command vector to run on the remote server.
 -- @return True on success, false on error.
 -- @return Error object on failure.
+-- @return Captured standard output of the command as a string.
 function e2lib.ssh_remote_cmd(u, argv)
-    local v, command
+    local command, rc, re, e, flags, args, stdout, stderr, devnull, fdctv
+
+    command, re = tools.get_tool("ssh")
+    if not command then
+        return false, re
+    end
+
+    command = { command }
+
+    flags, re = tools.get_tool_flags("ssh")
+    if not flags then
+        return false, re
+    end
+
+    for _,flag in ipairs(flags) do
+        table.insert(command, flag)
+    end
 
     if u.pass then
         return false, err.new("ssh_remote_cmd does not support password URL's")
     end
 
-    v = {}
     if u.port then
-        table.insert(v, "-p")
-        table.insert(v, u.port)
+        table.insert(command, "-p")
+        table.insert(command, u.port)
     end
 
     if u.user then
-        table.insert(v, "-l")
-        table.insert(v, u.user)
+        table.insert(command, "-l")
+        table.insert(command, u.user)
     end
 
     if not u.servername then
         return false,
             err.new("ssh_remote_cmd: no server name in URL %q", u.url)
     end
-    table.insert(v, u.servername)
+    table.insert(command, u.servername)
 
-    command = {}
+    args = {}
     for i, arg in ipairs(argv) do
-        table.insert(command, e2lib.shquote(arg))
+        table.insert(args, e2lib.shquote(arg))
+    end
+    table.insert(command, table.concat(args, " "))
+
+    stdout = {}
+    stderr = {}
+    local function capture_stdout(data)
+        table.insert(stdout, data)
+    end
+
+    local function capture_stderr(data)
+        table.insert(stderr, data)
+    end
+
+    devnull, re = eio.fopen("/dev/null", "r")
+    if not devnull then
+        return false, re
     end
 
-    table.insert(v, table.concat(command, " "))
+    fdctv = {
+        { dup = eio.STDIN, istype = "readfo", file = devnull },
+        { dup = eio.STDOUT, istype = "writefunc",
+            linebuffer = true, callfn = capture_stdout },
+        { dup = eio.STDERR, istype = "writefunc",
+            linebuffer = true, callfn = capture_stderr },
+    }
+
+    rc, re = e2lib.callcmd(command, fdctv)
+    eio.fclose(devnull)
+    if not rc then
+        return false, re
+    end
+
+    if rc ~= 0 then
+        e = err.new("%q returned with exit code %d:",
+            table.concat(command, " "), rc)
+        for i = #stderr-3,#stderr do
+            if stderr[i] then
+                e:append("%s", stderr[i])
+            end
+        end
+
+        return false, e
+    end
 
-    return e2lib.call_tool_argv("ssh", v)
+    return true, nil, table.concat(stdout)
 end
 
 --- call the scp command