Verified Commit ccf40af2 authored by Karel Koci's avatar Karel Koci 🤘

Error on content missing and allow ignore

If content is missing (can't be received for what ever reason), we fail
updater run instead of just printing warning and continuing. To not fail
there can be used "content" string in ignore extra field of Package.
parent 5ffe76ae
......@@ -524,6 +524,9 @@ ignore::
Don't report errors of installation in this package as an error
and don't abort the rest of the installation process even if it is
in an early stage.
content::
Don't error on missing content. If it's available from repository
then it is handled as missing.
StoreFlags
~~~~~~~~~~
......
......@@ -152,25 +152,48 @@ we don't know their version without seeing their values from field such as
version.
]]
function get_content_pkgs()
local uris = {}
local errors = {}
for _, pkg in pairs(requests.known_content_packages) do
local ok, data = utils.private(pkg).content_uri:get()
if ok then
local tmpdir = mkdtemp()
local pkg_dir = backend.pkg_unpack(data, tmpdir)
local _, _, _, control = backend.pkg_examine(pkg_dir)
if pkg.name ~= control.Package then
ERROR("Package content specified for package " .. pkg.name .. ", but it contains package " .. control.Package .. ". Ignoring this content.")
return
local content_uri = utils.private(pkg).content_uri
table.insert(uris, content_uri)
local function downloaded(ok, data)
if ok then
local tmpdir = mkdtemp()
local pkg_dir = backend.pkg_unpack(data, tmpdir)
local _, _, _, control = backend.pkg_examine(pkg_dir)
-- Remove unpacked package. Because we might run no far than planning.
-- If it is going to be installed, it will be unpacked again.
utils.cleanup_dirs({pkg_dir, tmpdir})
if pkg.name ~= control.Package then
if utils.arr2set(pkg.ignore or {})["content"] then
ERROR("Package content specified for package " .. pkg.name .. ", but it contains package " .. control.Package .. ". Ignoring as requested.")
else
table.insert(errors, utils.exception("corruption", "Package content specified for package " .. pkg.name .. ", but it contains package " .. control.Package))
end
return
end
pkg.candidate = control
pkg.candidate.data = data
pkg.candidate.pkg = pkg
else
if utils.arr2set(pkg.ignore or {})["content"] then
WARN("Can't get content for package " .. pkg.name .. ", " .. data.reason .. ". Ignoring as requested.")
else
table.insert(errors, utils.exception("unreachable", "Can't get content for package " .. pkg.name .. ": " .. data.reason))
end
end
pkg.candidate = control
pkg.candidate.data = data
pkg.candidate.pkg = pkg
-- Remove unpacked package. Because we might run no far than planning.
-- If it is going to be installed, it will be unpacked again.
utils.cleanup_dirs({pkg_dir, tmpdir})
else
WARN("Can't get content for package " .. pkg.name .. ": " .. data.reason)
end
content_uri:cback(downloaded)
end
-- Download and extract all content
uri.wait(unpack(uris))
-- Check if we encountered some errors
if next(errors) then
local multi = utils.exception('multiple', "Multiple exceptions (" .. #errors .. ")")
multi.errors = errors
error(multi)
end
end
......
......@@ -127,7 +127,11 @@ static int lua_log(lua_State *L) {
size_t sizes[nargs - 2];
const char *strs[nargs - 2];
for (int i = 3; i <= nargs; i ++) {
strs[i - 3] = lua_tostring(L, i);
if (lua_isnil(L, i))
strs[i - 3] = "<nil>";
else if((strs[i - 3] = lua_tostring(L, i)) == NULL)
// If it is not nil nor string or number, it is function or table so too complex just for simple log function
strs[i - 3] = "<complex-type>";
sizes[i - 3] = strlen(strs[i - 3]);
sum += sizes[i - 3];
}
......
......@@ -48,7 +48,7 @@ const char *shared_context[] = { "function xyz() return 1 ; end", "if xyz() ~= 1
const char *survival[] = { "invalid_func();", "local x = 1;", NULL };
const char *library[] = { "next({});", "getfenv();", "string.find('x', 'y');", "math.abs(-1);", "os.clock();", "debug.getregistry()", NULL };
const char *autoloaded[] = { "testing.values();", NULL };
const char *logging[] = { "log('DEBUG', 0, 'test')", "log('INVALID', 0, 'test')", "ERROR('test')", NULL };
const char *logging[] = { "log('DEBUG', 0, 'test')", "log('INVALID', 0, 'test')", "ERROR('test')", "log('DEBUG', 0, nil)", "log('DEBUG', 0, {'table'})", NULL };
const char *pre_require[] = { "local m = require 'testing'; testing.values();", NULL };
const char *uriinter_get[] = { "uri_internal_get('hello_txt')", NULL };
......@@ -68,7 +68,7 @@ struct loading_case loading_cases[] = {
{ "Autoloaded", autoloaded, 1, true },
{ "Not autoloaded", autoloaded, 0, false },
// Check that logging doesn't crash us
{ "Logging", logging, 3, true },
{ "Logging", logging, 5, true },
{ "Missing logging", logging, 2, false },
// Check the loading presets the package.loaded correctly, so further require works.
{ "pre_require", pre_require, 1, true },
......
......@@ -22,6 +22,9 @@ require 'lunit'
local requests = require "requests"
local postprocess = require "postprocess"
local utils = require "utils"
local uri = require "uri"
local dir = (os.getenv("S") .. "/") or ''
module("postprocess-tests", package.seeall, lunit.testcase)
......@@ -180,6 +183,67 @@ function test_get_repos_broken_nonfatal()
}, requests.known_repositories_all)
end
function test_get_content_pkgs()
local context = sandbox.new("Local")
requests.known_content_packages = {{name="updater"}}
utils.private(requests.known_content_packages[1]).content_uri = uri(context, "file://" .. dir .. "tests/data/updater.ipk")
local expect = {
{
name = "updater",
candidate = {
Status = {"install", "user", "installed"},
Package = "updater",
Version = "129",
Depends = "libc, vixie-cron, openssl-util, libatsha204, curl, cert-backup, opkg, bzip2, cznic-cacert-bundle",
Source = "feeds/turrispackages/cznic/updater",
Section = "opt",
Maintainer = "Michal Vaner <michal.vaner@nic.cz>",
Architecture = "mpc85xx",
Description = "updater",
["Installed-Size"] = "14773",
Conffiles = {["/etc/config/updater"] = "b5cf279732a87011eadfe522a0c163b98682bef2919afc4f96330f9f103a3230"},
files = {
["/usr/bin/updater-unstuck.sh"] = true,
["/etc/config/updater"] = true,
["/usr/share/updater/keys/standby.pem"] = true,
["/etc/ssl/updater.pem"] = true,
["/usr/bin/updater.sh"] = true,
["/usr/bin/updater-wipe.sh"] = true,
["/usr/bin/updater-utils.sh"] = true,
["/etc/init.d/updater"] = true,
["/usr/bin/updater-worker.sh"] = true,
["/usr/share/updater/keys/release.pem"] = true,
["/usr/bin/updater-resume.sh"] = true,
}
}
}
}
expect[1].candidate.pkg = expect[1]
postprocess.get_content_pkgs()
-- set data to nil. We can't check that easily enough. Same goes for Installed-time
requests.known_content_packages[1].candidate.data = nil
requests.known_content_packages[1].candidate["Installed-Time"] = nil
assert_table_equal(expect, requests.known_content_packages)
end
-- Lest break things and expect exception
function test_get_content_pkgs_missing()
local context = sandbox.new("Local")
requests.known_content_packages = {{name="updater"}}
utils.private(requests.known_content_packages[1]).content_uri = uri(context, "file://" .. dir .. "tests/data/nonexistent.ipk")
assert_exception(function() postprocess.get_content_pkgs() end, "multiple")
end
-- Lest break things but ignore it
function test_get_content_pkgs_missing_ignore()
local context = sandbox.new("Local")
requests.known_content_packages = {{name="updater", ignore={"content"}}}
utils.private(requests.known_content_packages[1]).content_uri = uri(context, "file://" .. dir .. "tests/data/nonexistent.ipk")
postprocess.get_content_pkgs()
assert_table_equal({{name="updater", ignore={"content"}}}, requests.known_content_packages)
end
function test_pkg_merge()
requests.known_repositories_all = {
{
......
......@@ -20,6 +20,7 @@ along with Updater. If not, see <http://www.gnu.org/licenses/>.
require "lunit"
local uri = require "uri"
local sandbox = require "sandbox"
local dir = (os.getenv("S") .. "/") or ''
module("uri-tests", package.seeall, lunit.testcase)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment