check_site_lib: merge site & domain and provide restricting feature

- provide in_domain() and in_site() functions to restrict usage:

need_string('foo.bar') -- allowed in both domain and site config
need_string(in_site('foo.bar')) -- only allowed in site config
need_string(in_domain('foo.bar')) -- only allowed in domain config

- need_* merge the domain and site configs while prefering the domain
  values
This commit is contained in:
lemoer 2017-10-28 17:05:53 +02:00
parent b730daf7fb
commit 0834985205
4 changed files with 133 additions and 34 deletions

View File

@ -8,7 +8,7 @@ PKG_VERSION:=$(if $(DUMP),x,$(GLUON_SITE_VERSION))
PKG_CONFIG_DEPENDS := CONFIG_GLUON_RELEASE CONFIG_GLUON_SITEDIR PKG_CONFIG_DEPENDS := CONFIG_GLUON_RELEASE CONFIG_GLUON_SITEDIR
PKG_FILE_DEPENDS := $(GLUON_SITEDIR)/site.conf $(GLUON_SITEDIR)/i18n/ PKG_FILE_DEPENDS := $(GLUON_SITEDIR)/site.conf $(GLUON_SITEDIR)/domains/ $(GLUON_SITEDIR)/i18n/
PKG_BUILD_DEPENDS := lua-cjson/host PKG_BUILD_DEPENDS := lua-cjson/host
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
@ -38,6 +38,7 @@ endef
define Build/Prepare define Build/Prepare
mkdir -p $(PKG_BUILD_DIR) mkdir -p $(PKG_BUILD_DIR)
mkdir -p $(PKG_BUILD_DIR)/domains
endef endef
define Build/Configure define Build/Configure
@ -45,12 +46,16 @@ endef
define Build/Compile define Build/Compile
GLUON_SITEDIR='$(call qstrip,$(CONFIG_GLUON_SITEDIR))' lua -e 'print(require("cjson").encode(assert(dofile("../../scripts/site_config.lua"))))' > $(PKG_BUILD_DIR)/site.json GLUON_SITEDIR='$(call qstrip,$(CONFIG_GLUON_SITEDIR))' lua -e 'print(require("cjson").encode(assert(dofile("../../scripts/site_config.lua"))))' > $(PKG_BUILD_DIR)/site.json
ls $(call qstrip,$(CONFIG_GLUON_SITEDIR))/domains/*.conf > /dev/null # at least one domain cfg has to exist
for domain_cfg in `find $(call qstrip,$(CONFIG_GLUON_SITEDIR))/domains/ -iname \*.conf -printf "%f\n"`; do dc=$$$${domain_cfg%.conf}; GLUON_SITEDIR='$(call qstrip,$(CONFIG_GLUON_SITEDIR))' lua -e 'print(require("cjson").encode(assert(dofile("../../scripts/domain_config.lua")("'$$$${dc}'"))))' > $(PKG_BUILD_DIR)/domains/$$$${dc}.json; done
$(call GluonBuildI18N,gluon-site,$(GLUON_SITEDIR)/i18n) $(call GluonBuildI18N,gluon-site,$(GLUON_SITEDIR)/i18n)
endef endef
define Package/gluon-site/install define Package/gluon-site/install
$(INSTALL_DIR) $(1)/lib/gluon $(INSTALL_DIR) $(1)/lib/gluon
$(INSTALL_DATA) $(PKG_BUILD_DIR)/site.json $(1)/lib/gluon/ $(INSTALL_DATA) $(PKG_BUILD_DIR)/site.json $(1)/lib/gluon/
$(INSTALL_DIR) $(1)/lib/gluon/domains
$(CP) $(PKG_BUILD_DIR)/domains/*.json $(1)/lib/gluon/domains/
echo '$(GLUON_SITE_VERSION)' > $(1)/lib/gluon/site-version echo '$(GLUON_SITE_VERSION)' > $(1)/lib/gluon/site-version
echo '$(call qstrip,$(CONFIG_GLUON_RELEASE))' > $(1)/lib/gluon/release echo '$(call qstrip,$(CONFIG_GLUON_RELEASE))' > $(1)/lib/gluon/release

View File

@ -11,7 +11,24 @@ local site_json = f:read('*a')
f:close() f:close()
site = require('cjson').decode(site_json) site = require('cjson').decode(site_json)
function check_domain(domain_code, domain)
$(shell cat '$(TOPDIR)/../scripts/check_site_lib.lua' '$(1)' | sed -ne '1h; 1!H; $$ {g; s/@/+@/g; s/\n/-@/g; p}') $(shell cat '$(TOPDIR)/../scripts/check_site_lib.lua' '$(1)' | sed -ne '1h; 1!H; $$ {g; s/@/+@/g; s/\n/-@/g; p}')
end
local dir = os.getenv('IPKG_INSTROOT') .. '/lib/gluon/domains/'
local pfile = io.popen('find '..dir..' -iname \\*.json')
for domain_path in pfile:lines() do
local domain_code = string.gmatch(domain_path, '([^/]+).json$$')()
local f = assert(io.open(domain_path))
local domain_json = f:read('*a')
f:close()
domain = require('cjson').decode(domain_json)
check_domain(domain_code, domain)
end
pfile:close()
END__GLUON__CHECK__SITE END__GLUON__CHECK__SITE
endef endef

View File

@ -1,9 +1,32 @@
local function loadvar(varname) local function loadvar(varname)
local ok, val = pcall(assert(loadstring('return site.' .. varname))) local ok, val = pcall(assert(loadstring('return domain.' .. varname)))
if ok then if ok and val ~= nil then
return val return val, 'domains/'..domain_code..'.conf'
end
ok, val = pcall(assert(loadstring('return site.' .. varname)))
if ok and val ~= nil then
return val, 'site.conf'
else else
return nil return nil, 'site.conf or domains/'..domain_code..'.conf'
end
end
local function loadvar_domain(varname)
local ok, val = pcall(assert(loadstring('return domain.' .. varname)))
if ok then
return val, 'domains/'..domain_code..'.conf'
else
return nil, 'domains/'..domain_code..'.conf'
end
end
local function loadvar_site(varname)
ok, val = pcall(assert(loadstring('return site.' .. varname)))
if ok then
return val, 'site.conf'
else
return nil, 'site.conf'
end end
end end
@ -32,68 +55,87 @@ local function assert_type(var, t, msg)
assert(type(var) == t, msg) assert(type(var) == t, msg)
end end
-- returns an unique keys in keys of returned table
function keys_merged(a, b)
keys_table = {}
for k, _ in pairs(a or {}) do
keys_table[k] = 1
end
for k, _ in pairs(b or {}) do
keys_table[k] = 1
end
return keys_table
end
function assert_uci_name(var) function forbid_in_domain(varname)
local ok, val = pcall(assert(loadstring('return domain.' .. varname)))
assert(not ok or val == nil, "domains/"..domain_code..".conf error: `"..varname.."` is not allowed in domain specific config.")
end
function forbid_in_site(varname)
local ok, val = pcall(assert(loadstring('return site.' .. varname)))
assert(not ok or val == nil, "site.conf error: `"..varname.."` is not allowed in site config.")
end
function assert_uci_name(var, conf_name)
-- We don't use character classes like %w here to be independent of the locale -- We don't use character classes like %w here to be independent of the locale
assert(var:match('^[0-9a-zA-Z_]+$'), "site.conf error: `" .. var .. "' is not a valid config section name (only alphanumeric characters and the underscore are allowed)") assert(var:match('^[0-9a-zA-Z_]+$'), conf_name.." error: `" .. var .. "' is not a valid config section name (only alphanumeric characters and the underscore are allowed)")
end end
function need_string(varname, required) function need_string(varname, required)
local var = loadvar(varname) local var, conf_name = loadvar(varname)
if required == false and var == nil then if required == false and var == nil then
return nil return nil, conf_name
end end
assert_type(var, 'string', "site.conf error: expected `" .. varname .. "' to be a string") assert_type(var, 'string', conf_name .. " error: expected `" .. varname .. "' to be a string")
return var return var, conf_name
end end
function need_string_match(varname, pat, required) function need_string_match(varname, pat, required)
local var = need_string(varname, required) local var, conf_name = need_string(varname, required)
if not var then if not var then
return nil return nil
end end
assert(var:match(pat), "site.conf error: expected `" .. varname .. "' to match pattern `" .. pat .. "'") assert(var:match(pat), conf_name.." error: expected `" .. varname .. "' to match pattern `" .. pat .. "'")
return var return var
end end
function need_number(varname, required) function need_number(varname, required)
local var = loadvar(varname) local var, conf_name = loadvar(varname)
if required == false and var == nil then if required == false and var == nil then
return nil return nil
end end
assert_type(var, 'number', "site.conf error: expected `" .. varname .. "' to be a number") assert_type(var, 'number', conf_name.." error: expected `" .. varname .. "' to be a number")
return var return var
end end
function need_boolean(varname, required) function need_boolean(varname, required)
local var = loadvar(varname) local var, conf_name = loadvar(varname)
if required == false and var == nil then if required == false and var == nil then
return nil return nil
end end
assert_type(var, 'boolean', "site.conf error: expected `" .. varname .. "' to be a boolean") assert_type(var, 'boolean', conf_name.." error: expected `" .. varname .. "' to be a boolean")
return var return var
end end
function need_array(varname, subcheck, required) local function __need_array_from_var(var, varname, subcheck, required, conf_name)
local var = loadvar(varname)
if required == false and var == nil then if required == false and var == nil then
return nil return nil
end end
assert_type(var, 'table', "site.conf error: expected `" .. varname .. "' to be an array") assert_type(var, 'table', conf_name.." error: expected `" .. varname .. "' to be an array")
for _, e in ipairs(var) do for _, e in ipairs(var) do
subcheck(e) subcheck(e)
@ -102,18 +144,27 @@ function need_array(varname, subcheck, required)
return var return var
end end
function need_array(varname, subcheck, required)
local var, conf_name = loadvar(varname)
return __need_array_from_var(var, varname, subcheck, required, conf_name)
end
function need_table(varname, subcheck, required) function need_table(varname, subcheck, required)
local var = loadvar(varname) local var, conf_name = loadvar(varname)
if required == false and var == nil then if required == false and var == nil then
return nil return nil
end end
assert_type(var, 'table', "site.conf error: expected `" .. varname .. "' to be a table") assert_type(var, 'table', conf_name.." error: expected `" .. varname .. "' to be a table")
local dvar = loadvar_domain(varname)
local svar = loadvar_site(varname)
if subcheck then if subcheck then
for k, v in pairs(var) do for k, _ in pairs(keys_merged(dvar, svar)) do
subcheck(k, v) subcheck(k, conf_name)
end end
end end
@ -121,31 +172,44 @@ function need_table(varname, subcheck, required)
end end
function need_one_of(varname, array, required) function need_one_of(varname, array, required)
local var = loadvar(varname) local var, conf_name = loadvar(varname)
if required == false and var == nil then if required == false and var == nil then
return nil return nil
end end
assert_one_of(var, array, "site.conf error: expected `" .. varname .. "' to be one of given array: " .. array_to_string(array)) assert_one_of(var, array, conf_name.." error: expected `" .. varname .. "' to be one of given array: " .. array_to_string(array))
return var return var
end end
function need_string_array(varname, required) function need_string_array(varname, required)
local ok, var = pcall(need_array, varname, function(e) assert_type(e, 'string') end, required) local var, conf_name = loadvar(varname)
assert(ok, "site.conf error: expected `" .. varname .. "' to be a string array") local ok, var = pcall(__need_array_from_var, var, varname, function(e) assert_type(e, 'string') end, required, conf_name)
assert(ok, conf_name.." error: expected `" .. varname .. "' to be a string array")
return var return var
end end
function need_string_array_match(varname, pat, required) function need_string_array_match(varname, pat, required)
local ok, var = pcall(need_array, varname, function(e) assert(e:match(pat)) end, required) local var, conf_name = loadvar(varname)
assert(ok, "site.conf error: expected `" .. varname .. "' to be a string array matching pattern `" .. pat .. "'") local ok, var = pcall(__need_array_from_var, var, varname, function(e) assert(e:match(pat)) end, required, conf_name)
assert(ok, conf_name.." error: expected `" .. varname .. "' to be a string array matching pattern `" .. pat .. "'")
return var return var
end end
function need_array_of(varname, array, required) function need_array_of(varname, array, required)
local ok, var = pcall(need_array, varname, function(e) assert_one_of(e, array) end,required) local var, conf_name = loadvar(varname)
assert(ok, "site.conf error: expected `" .. varname .. "' to be a subset of given array: " .. array_to_string(array)) local ok, var = pcall(__need_array_from_var, var, varname, function(e) assert_one_of(e, array) end, required, conf_name)
assert(ok, conf_name.." error: expected `" .. varname .. "' to be a subset of given array: " .. array_to_string(array))
return var
end
function in_domain(var)
forbid_in_site(var)
return var
end
function in_site(var)
forbid_in_domain(var)
return var return var
end end

13
scripts/domain_config.lua Normal file
View File

@ -0,0 +1,13 @@
local function load_domain(domain_code)
local config = os.getenv('GLUON_SITEDIR')
local function loader()
coroutine.yield('return ')
coroutine.yield(io.open(config .. '/domains/' .. domain_code .. '.conf'):read('*a'))
end
-- setfenv doesn't work with Lua 5.2 anymore, but we're using 5.1
return setfenv(assert(load(coroutine.wrap(loader), 'domains/' .. domain_code .. '.conf')), {})()
end
return load_domain