From: Tobias Ulmer Date: Mon, 18 Jul 2022 23:25:54 +0000 (+0200) Subject: rsync new-style args X-Git-Tag: e2factory-2.3.18p1~2 X-Git-Url: https://git.e2factory.org/?a=commitdiff_plain;h=f069d3512d9c4c15bd08c6bdecb2d29586650a47;p=e2factory.git rsync new-style args Signed-off-by: Tobias Ulmer --- diff --git a/generic/tools.lua b/generic/tools.lua index 494ad70..dc2208e 100644 --- a/generic/tools.lua +++ b/generic/tools.lua @@ -239,9 +239,10 @@ end -- @param optional Whether the tool is required (true) or optional (false). -- @param enable Whether the tool should be used or not. -- Only makes sense if optional. Defaults to true if not optional. +-- @param detection Special function for feature/variant detection (optional). -- @return True on success, false on error. -- @return Error object on failure. -function tools.add_tool(name, value, flags, optional, enable) +function tools.add_tool(name, value, flags, optional, enable, detection) if type(name) ~= "string" or (value ~= nil and type(value) ~= "string") or (flags ~= nil and type(flags) ~= "string") or @@ -283,6 +284,8 @@ function tools.add_tool(name, value, flags, optional, enable) -- flagstbl, optional = optional, enable = enable, + variant = nil, + detection = detection, } local t = toollist[name] @@ -292,6 +295,81 @@ function tools.add_tool(name, value, flags, optional, enable) return true end +local function rsync_version_detect(name) + local rc, re + local out, cmd, m + out = {} + + local function capture(msg) + if #out < 1 then + -- we care only about the first line + table.insert(out, msg) + end + end + + assert(type(toollist[name].path) == "string") + cmd = { toollist[name].path, "--version" } + + + rc, re = e2lib.callcmd_capture(cmd, capture) + if not rc then + return false, re + elseif rc ~= 0 then + return false, err.new("rsync --version returned error code") + end + + out = table.concat(out) + e2lib.logf(4, "rsync --version returned: %q", out) + + local major, minor, patch = + out:match("rsync%s+version%s+v?(%d+)%.(%d+)%.?(%d*)") + local proto = out:match("protocol%s+version%s+(%d+)") + + if major == nil then + major = 3 + minor = 2 + patch = 4 + e2lib.logf(3, "could not match rsync version, defaulting to 3.2.4") + else + major = tonumber(major) + minor = tonumber(minor) + -- not sure patch has ever been optional, + -- but fake something just in case. + if patch ~= "" then + patch = tonumber(patch) + else + patch = 0 + end + end + + if proto == nil then + e2lib.logf(3, "could not detect rsync protocol version, " .. + "defaulting to version 3.2.4") + proto = 31 + else + proto = tonumber(proto) + end + + -- argument parser change in 3.2.4 + -- https://download.samba.org/pub/rsync/NEWS#3.2.4 + + local newargs = true + if (major < 3) or (major == 3 and minor < 2) + or (major == 3 and minor == 2 and patch < 4) then + newargs = false + end + e2lib.logf(4, "rsync: newstyle args detected: %s", tostring(newargs)) + + toollist[name].variant = { + newargs = newargs, + major = major, + minor = minor, + patch = patch, + proto = proto, + } + return true +end + --- Populate the tools module with the default tools. function tools.add_default_tools() local rc, re @@ -299,7 +377,9 @@ function tools.add_default_tools() curl = { name = "curl", flags = "", optional = false }, ssh = { name = "ssh", flags = "", optional = false }, scp = { name = "scp", flags = "", optional = false }, - rsync = { name = "rsync", flags = "", optional = false }, + rsync = { name = "rsync", flags = "", optional = false, + detection = rsync_version_detect, + }, git = { name = "git", flags = "", optional = false }, cvs = { name = "cvs", flags = "", optional = true }, svn = { name = "svn", flags = "", optional = true }, @@ -316,7 +396,8 @@ function tools.add_default_tools() } for name, t in pairs(defaults) do - rc, re = tools.add_tool(name, t.name, t.flags, t.optional, t.enable) + rc, re = tools.add_tool(name, t.name, t.flags, t.optional, t.enable, + t.detection) if not rc then e2lib.abort(re) end @@ -362,11 +443,33 @@ function tools.check_tool(name) end toollist[name].path = p + + if toollist[name].detection then + rc, re = toollist[name].detection(name) + if not rc then + return false, + err.new("tool '%s': special detection failed", name):cat(re) + end + end end return true end +--- Special per tool information e.g. the installed version +-- @param name Tool name +-- @return False on error, defaults to empty table. +-- @return Error object on failure. +function tools.variant(name) + local rc, re + + if not toollist[name] then + return false, err.new("tool '%s' is not registered in tool list", name) + end + + return toollist[name].variant or {} +end + --- Query whether an optional tool is enabled or not. -- @param name Tool name. -- @return True if enabled, false on error or if not enabled. diff --git a/generic/transport.lua b/generic/transport.lua index 4779820..7f3c078 100644 --- a/generic/transport.lua +++ b/generic/transport.lua @@ -83,6 +83,8 @@ local function rsync_quote_remote(user, server, dir) assert(user == nil or type(user) == "string") assert(type(server) == "string") assert(type(dir) == "string") + local v = tools.variant("rsync") + assert(v, "tools.variant(rsync) failed") if user then user = string.format("%s@", user) @@ -90,7 +92,11 @@ local function rsync_quote_remote(user, server, dir) user = "" end - return string.format("%s%s:%s", user, server, e2lib.shquote(dir)) + if v.newargs then + return string.format("%s%s:%s", user, server, dir) + else + return string.format("%s%s:%s", user, server, e2lib.shquote(dir)) + end end --- create a remote directory by copying an empty directory using rsync