diff --git a/admin/autoupdater/files/usr/lib/lua/autoupdater/util.lua b/admin/autoupdater/files/usr/lib/lua/autoupdater/util.lua index d5dd67e..b1d8c58 100644 --- a/admin/autoupdater/files/usr/lib/lua/autoupdater/util.lua +++ b/admin/autoupdater/files/usr/lib/lua/autoupdater/util.lua @@ -7,14 +7,29 @@ module('autoupdater.util', package.seeall) -- Executes a command in the background, without parsing the command through a shell (in contrast to os.execute) -function exec(...) +function exec(timeout, ...) local pid, errno, error = nixio.fork() if pid == 0 then nixio.execp(...) os.exit(127) elseif pid > 0 then - local wpid, status, code = nixio.waitpid(pid) - return wpid and status == 'exited' and code + if timeout then + local starttime = os.time() + while true do + if os.difftime(os.time(), starttime) > timeout then + nixio.kill(pid, nixio.const.SIGTERM) + end + + local wpid, status, code = nixio.waitpid(pid, 'nohang') + if wpid then + return wpid and status == 'exited' and code + end + nixio.nanosleep(1) + end + else + local wpid, status, code = nixio.waitpid(pid) + return wpid and status == 'exited' and code + end else return pid, errno, error end @@ -69,7 +84,7 @@ function run_dir(dir) for _, entry in ipairs(files) do if is_ok(entry) then - exec(dir .. '/' .. entry) + exec(nil, dir .. '/' .. entry) end end end diff --git a/admin/autoupdater/files/usr/sbin/autoupdater b/admin/autoupdater/files/usr/sbin/autoupdater index bb54ee5..1b9112e 100755 --- a/admin/autoupdater/files/usr/sbin/autoupdater +++ b/admin/autoupdater/files/usr/sbin/autoupdater @@ -129,9 +129,21 @@ local function read_manifest(mirror) -- Remove potential trailing slash mirror = mirror:gsub('/$', '') + + local starttime = os.time() + local manifest_loader = io.popen(string.format("exec wget -T 120 -O- '%s/%s.manifest'", mirror, branch.name), 'r') + -- Read all lines from the manifest - -- The upper part is saves to lines, the lower part to sigs - for line in io.popen(string.format("exec wget -T 120 -O- '%s/%s.manifest'", mirror, branch.name), 'r'):lines() do + -- The upper part is saved to lines, the lower part to sigs + for line in manifest_loader:lines() do + -- If the manifest download takes more than 5 minutes, we don't really + -- have a chance to download a whole image + if os.difftime(os.time(), starttime) > 300 then + io.stderr:write("Timeout while reading manifest.\n") + manifest_loader:close() + return nil + end + if not sep then if line == '---' then sep = true @@ -194,7 +206,8 @@ end -- Downloads the firmware image from a mirror to a given output file local function fetch_firmware(mirror, filename, output) - if autoupdater_util.exec('wget', '-T', '120', '-O', output, mirror .. '/' .. filename) ~= 0 then + -- Let's give the image download 30 minutes, hopefully more than enough + if autoupdater_util.exec(1800, 'wget', '-T', '120', '-O', output, mirror .. '/' .. filename) ~= 0 then io.stderr:write('Error downloading the image from ' .. mirror .. '\n') return false end