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:
		
							parent
							
								
									b730daf7fb
								
							
						
					
					
						commit
						0834985205
					
				@ -8,7 +8,7 @@ PKG_VERSION:=$(if $(DUMP),x,$(GLUON_SITE_VERSION))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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_DIR := $(BUILD_DIR)/$(PKG_NAME)
 | 
			
		||||
@ -38,6 +38,7 @@ endef
 | 
			
		||||
 | 
			
		||||
define Build/Prepare
 | 
			
		||||
	mkdir -p $(PKG_BUILD_DIR)
 | 
			
		||||
	mkdir -p $(PKG_BUILD_DIR)/domains
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/Configure
 | 
			
		||||
@ -45,12 +46,16 @@ endef
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
	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)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/gluon-site/install
 | 
			
		||||
	$(INSTALL_DIR) $(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 '$(call qstrip,$(CONFIG_GLUON_RELEASE))' > $(1)/lib/gluon/release
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,24 @@ local site_json = f:read('*a')
 | 
			
		||||
f:close()
 | 
			
		||||
 | 
			
		||||
site = require('cjson').decode(site_json)
 | 
			
		||||
$(shell cat '$(TOPDIR)/../scripts/check_site_lib.lua' '$(1)' | sed -ne '1h; 1!H; $$ {g; s/@/+@/g; s/\n/-@/g; p}')
 | 
			
		||||
 | 
			
		||||
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}')
 | 
			
		||||
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
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,32 @@
 | 
			
		||||
local function loadvar(varname)
 | 
			
		||||
   local ok, val = pcall(assert(loadstring('return site.' .. varname)))
 | 
			
		||||
   if ok then
 | 
			
		||||
      return val
 | 
			
		||||
   local ok, val = pcall(assert(loadstring('return domain.' .. varname)))
 | 
			
		||||
   if ok and val ~= nil then
 | 
			
		||||
      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
 | 
			
		||||
      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
 | 
			
		||||
 | 
			
		||||
@ -32,68 +55,87 @@ local function assert_type(var, t, msg)
 | 
			
		||||
   assert(type(var) == t, msg)
 | 
			
		||||
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
 | 
			
		||||
   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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function need_string(varname, required)
 | 
			
		||||
   local var = loadvar(varname)
 | 
			
		||||
   local var, conf_name = loadvar(varname)
 | 
			
		||||
 | 
			
		||||
   if required == false and var == nil then
 | 
			
		||||
      return nil
 | 
			
		||||
      return nil, conf_name
 | 
			
		||||
   end
 | 
			
		||||
 | 
			
		||||
   assert_type(var, 'string', "site.conf error: expected `" .. varname .. "' to be a string")
 | 
			
		||||
   return var
 | 
			
		||||
   assert_type(var, 'string', conf_name .. " error: expected `" .. varname .. "' to be a string")
 | 
			
		||||
   return var, conf_name
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
      return nil
 | 
			
		||||
   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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function need_number(varname, required)
 | 
			
		||||
   local var = loadvar(varname)
 | 
			
		||||
   local var, conf_name = loadvar(varname)
 | 
			
		||||
 | 
			
		||||
   if required == false and var == nil then
 | 
			
		||||
      return nil
 | 
			
		||||
   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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function need_boolean(varname, required)
 | 
			
		||||
   local var = loadvar(varname)
 | 
			
		||||
   local var, conf_name = loadvar(varname)
 | 
			
		||||
 | 
			
		||||
   if required == false and var == nil then
 | 
			
		||||
      return nil
 | 
			
		||||
   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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function need_array(varname, subcheck, required)
 | 
			
		||||
   local var = loadvar(varname)
 | 
			
		||||
 | 
			
		||||
local function __need_array_from_var(var, varname, subcheck, required, conf_name)
 | 
			
		||||
   if required == false and var == nil then
 | 
			
		||||
      return nil
 | 
			
		||||
   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
 | 
			
		||||
      subcheck(e)
 | 
			
		||||
@ -102,18 +144,27 @@ function need_array(varname, subcheck, required)
 | 
			
		||||
   return var
 | 
			
		||||
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)
 | 
			
		||||
   local var = loadvar(varname)
 | 
			
		||||
   local var, conf_name = loadvar(varname)
 | 
			
		||||
 | 
			
		||||
   if required == false and var == nil then
 | 
			
		||||
      return nil
 | 
			
		||||
   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
 | 
			
		||||
      for k, v in pairs(var) do
 | 
			
		||||
         subcheck(k, v)
 | 
			
		||||
      for k, _ in pairs(keys_merged(dvar, svar)) do
 | 
			
		||||
         subcheck(k, conf_name)
 | 
			
		||||
      end
 | 
			
		||||
   end
 | 
			
		||||
 | 
			
		||||
@ -121,31 +172,44 @@ function need_table(varname, subcheck, required)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function need_one_of(varname, array, required)
 | 
			
		||||
   local var = loadvar(varname)
 | 
			
		||||
   local var, conf_name = loadvar(varname)
 | 
			
		||||
 | 
			
		||||
   if required == false and var == nil then
 | 
			
		||||
      return nil
 | 
			
		||||
   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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function need_string_array(varname, required)
 | 
			
		||||
   local ok, var = pcall(need_array, varname, function(e) assert_type(e, 'string') end, required)
 | 
			
		||||
   assert(ok, "site.conf error: expected `" .. varname .. "' to be a string array")
 | 
			
		||||
   local var, conf_name = loadvar(varname)
 | 
			
		||||
   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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function need_string_array_match(varname, pat, required)
 | 
			
		||||
   local ok, var = pcall(need_array, varname, function(e) assert(e:match(pat)) end, required)
 | 
			
		||||
   assert(ok, "site.conf error: expected `" .. varname .. "' to be a string array matching pattern `" .. pat .. "'")
 | 
			
		||||
   local var, conf_name = loadvar(varname)
 | 
			
		||||
   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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function need_array_of(varname, array, required)
 | 
			
		||||
   local ok, var = pcall(need_array, varname, function(e) assert_one_of(e, array) end,required)
 | 
			
		||||
   assert(ok, "site.conf error: expected `" .. varname .. "' to be a subset of given array: " .. array_to_string(array))
 | 
			
		||||
   local var, conf_name = loadvar(varname)
 | 
			
		||||
   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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								scripts/domain_config.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								scripts/domain_config.lua
									
									
									
									
									
										Normal 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
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user