add gluon-hoodselector: Integrate geolocation mode
This MR includs only the VPN MODE of the hoodselector whitch simply set hoods base on their geopositions. Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> check_site.lua: fix language syntax muss -> must rage -> range at lease -> at least coordiantes -> coordinates realaise -> realised gluon-hoodselector: fix language syntax in hoodselector can not -> can't routers -> router's continure -> continue to next -> to the next TMP -> temporary for current -> for the current continure -> continue with next -> with the next thier -> there provides -> provide possition -> position therfore -> therefore gluon-hoodselector: fix language syntax in util.lua realaise -> realised gluon-hoodselector: fix language syntax and use autoupdate lock mechanism. gluon-hoodselector: fix spelling/grammar gluon-hoodselector: automatically set SECTION and CATEGORY for Gluon packages gluon-hoodselector-add-VPN-MODE: add micrond & libjson-c dependency gluon-hoodselector-add-VPN-MODE: check running hoodselector before loading lua gluon-hoodselector-add-VPN-MODE: remove nixio dependency from hoodselector util Revert "gluon-hoodselector-add-VPN-MODE: check running hoodselector before loading lua" This reverts commit 535b0a1b2fb73e563bf6a44b568a796440bd307f. add luaposix and luabitop to pakage dependency sbin/hoodselector: remove nixio requiemend sbin/hoodselector: load hoods only if necessary gluon-hoodselector: use VPN abstraction layer. the hoodselectore does not need to know about all individual VPN protocols. gluon-hoodselector: Makefile add gluon-mesh-vpn-core as dependency gluon-hoodselector: apply changes of mesh vpn lib gluon-hoodselector: remove outdated comments package/gluon-hoodselector: check_site.lua rm domain seed check thus its already checked by gluon-core package/gluon-hoodselector: util.lua code cleanup and refactoring package/gluon-hoodselector: hoodselector code cleanup and refactoring gluon-hoodselector: util.lua, use taps instead of spaces. Use posix.unistd.access instead of io.open Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> gluon-hoodselector: hoodselector, use taps instead of spaces. Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> gluon-hoodselector: check_site.lua: replace hood with domain Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> gluon-hoodselector: drop VPN mode and rename hood to domain. Furthermore implement geolocator mode as neorayder way Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: rm duplicated print output Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector util: fix wrong function signature Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> small typo fixes small typo fixes Update util.lua processes are really restarted now. new (old) problem: nodes will not forget their former ipv6-addresses. watchdog could here with that. gluon-hoodselector util.lua: replace i iterator with _ Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> Update util.lua now polygons with holes are recognized correctly. also a mix of nested polygons and boxes should be possible as shapes[] package/gluon-hoodselector: hoodselector use gluon-reload for daemon restarts/reloads Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: util.lua use math-polygon lib and rm restart_services function. Rectengles will be converted into polygons now Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: Makefile rewrite description update depends list Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: check_site.lua reduce complexity Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: use : for gluon_version Val Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: fix if equal syntax Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> luasrc/usr/lib/lua/hoodselector/util.lua: check_site.lua simplify checksite script and fix if logic Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: set space after comma, rm unnecessary error handling Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: use only brackes on require function no mixup Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: check_site.lua rm unuse variables and fix non std global function Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: util.lua rm unuse include Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: rm comment return nil in function get_geolocation() Signed-off-by: Jan-Tarek Butt <tarek@ring0.de> package/gluon-hoodselector: Makefile refactor pkg description Signed-off-by: Jan-Tarek Butt <tarek@ring0.de>
This commit is contained in:
parent
6ebb721ebc
commit
90baebc2b7
24
package/gluon-hoodselector/Makefile
Normal file
24
package/gluon-hoodselector/Makefile
Normal file
@ -0,0 +1,24 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gluon-hoodselector
|
||||
|
||||
GLUON_VERSION:=3
|
||||
PKG_VERSION:=2
|
||||
|
||||
include ../gluon.mk
|
||||
|
||||
define Package/gluon-hoodselector
|
||||
TITLE:=Automatically migrate nodes between domains.
|
||||
DEPENDS:=+luaposix +libgluonutil +lua-math-polygon +libjson-c +gluon-site +micrond +luabitop @GLUON_MULTIDOMAIN
|
||||
CONFLICTS:=+gluon-config-mode-domain-select
|
||||
endef
|
||||
|
||||
define Package/gluon-hoodselector/description
|
||||
Hoodselector automatically detects in which domain the node is
|
||||
located based on its geolocation settings. Domains require
|
||||
bounding boxes defined as polygons or rectangles. Hoodselector
|
||||
selects a domain from the list of known domains and migrate
|
||||
towards it without requiring a reboot.
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackageGluon,gluon-hoodselector))
|
26
package/gluon-hoodselector/check_site.lua
Normal file
26
package/gluon-hoodselector/check_site.lua
Normal file
@ -0,0 +1,26 @@
|
||||
local function check_lat_lon_range(pos, range, label)
|
||||
need({'hoodselector', 'shapes'}, function()
|
||||
if (type(pos) ~= "number") then
|
||||
return false
|
||||
end
|
||||
if pos > range or pos < -range then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end, true, label.." must match a range +/-"..range)
|
||||
end
|
||||
|
||||
if this_domain() ~= need_string(in_site({'default_domain'})) then
|
||||
for _, shape in pairs(need_table(in_domain({'hoodselector', 'shapes'}))) do
|
||||
need({'hoodselector', 'shapes'}, function()
|
||||
if #shape < 2 then
|
||||
return false
|
||||
end
|
||||
for _, v in ipairs(shape) do
|
||||
check_lat_lon_range(v.lat, 90.0, "lat")
|
||||
check_lat_lon_range(v.lon, 180.0, "lon")
|
||||
end
|
||||
return true
|
||||
end, true, "needs to have at least 2 coordinates for rectangular shapes.")
|
||||
end
|
||||
end
|
@ -0,0 +1 @@
|
||||
*/2 * * * * /usr/sbin/hoodselector
|
@ -0,0 +1,79 @@
|
||||
local util = require ('gluon.util')
|
||||
local math_polygon = require('math-polygon')
|
||||
local json = require ('jsonc')
|
||||
local uci = require('simple-uci').cursor()
|
||||
local site = require ('gluon.site')
|
||||
local logger = require('posix.syslog')
|
||||
local M = {}
|
||||
|
||||
function M.log(msg)
|
||||
io.stdout:write(msg..'\n')
|
||||
logger.openlog(msg, logger.LOG_PID)
|
||||
end
|
||||
|
||||
function M.get_domains()
|
||||
local list = {}
|
||||
for _, domain_path in ipairs(util.glob('/lib/gluon/domains/*.json')) do
|
||||
table.insert(list, {
|
||||
domain_code = domain_path:match('([^/]+)%.json$'),
|
||||
domain = assert(json.load(domain_path)),
|
||||
})
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
-- Return the default domain from the domain list.
|
||||
-- This method can return the following data:
|
||||
-- * default domain
|
||||
function M.get_default_domain(jdomains)
|
||||
for _, domain in pairs(jdomains) do
|
||||
if domain.domain_code == site.default_domain() then
|
||||
return domain
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Get Geoposition.
|
||||
-- This method can return the following data:
|
||||
-- * table {lat, lon}
|
||||
function M.get_geolocation()
|
||||
return {
|
||||
lat = tonumber(uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'latitude')),
|
||||
lon = tonumber(uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'longitude'))
|
||||
}
|
||||
end
|
||||
|
||||
-- Return domain from the domain list based on geo position or nil if no geo based domain could be
|
||||
-- determined.
|
||||
function M.get_domain_by_geo(jdomains, geo)
|
||||
for _, domain in pairs(jdomains) do
|
||||
if domain.domain_code ~= site.default_domain() then
|
||||
-- Keep record of how many nested shapes we are in, e.g. a polyon with holes.
|
||||
local nesting = 1
|
||||
for _, area in pairs(domain.domain.hoodselector.shapes) do
|
||||
-- Convert rectangle, defined by to points, into polygon
|
||||
if #area == 2 then
|
||||
area = math_polygon.two_point_rec_to_poly(area)
|
||||
end
|
||||
if (math_polygon.point_in_polygon(area, geo) == 1) then
|
||||
nesting = nesting * (-1)
|
||||
end
|
||||
end
|
||||
if nesting == -1 then return domain end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function M.set_domain_config(domain)
|
||||
if uci:get('gluon', 'core', 'domain') ~= domain.domain_code then
|
||||
uci:set('gluon', 'core', 'domain', domain.domain_code)
|
||||
uci:commit('gluon')
|
||||
os.execute('gluon-reconfigure')
|
||||
M.log('Set domain "'..domain.domain.domain_names[domain.domain_code]..'"')
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return M
|
56
package/gluon-hoodselector/luasrc/usr/sbin/hoodselector
Executable file
56
package/gluon-hoodselector/luasrc/usr/sbin/hoodselector
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local bit = require('bit')
|
||||
local unistd = require('posix.unistd')
|
||||
local fcntl = require('posix.fcntl')
|
||||
local hoodutil = require('hoodselector.util')
|
||||
|
||||
-- PID file to ensure the hoodselector isn't running parallel
|
||||
local lockfile = '/var/lock/hoodselector.lock'
|
||||
local lockfd, err = fcntl.open(lockfile, bit.bor(fcntl.O_WRONLY, fcntl.O_CREAT), 384) -- mode 0600
|
||||
|
||||
if not lockfd then
|
||||
hoodutil.log(err, '\n')
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
local ok, _ = fcntl.fcntl(lockfd, fcntl.F_SETLK, {
|
||||
l_start = 0,
|
||||
l_len = 0,
|
||||
l_type = fcntl.F_WRLCK,
|
||||
l_whence = unistd.SEEK_SET,
|
||||
})
|
||||
|
||||
if not ok then
|
||||
io.stderr:write(string.format(
|
||||
"Unable to lock file %s. Make sure there is no other instance of the hoodselector running.\n",
|
||||
lockfile
|
||||
))
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- geolocation mode
|
||||
-- If we have a location we will try to select the domain corresponding to this location.
|
||||
-- If no domain for the location has been defined or if we can't determine the node's location,
|
||||
-- we will select the default domain as last fallback instance.
|
||||
local geo = hoodutil.get_geolocation()
|
||||
if geo.lat ~= nil and geo.lon ~= nil then
|
||||
io.stdout:write('Position found. Enter "geolocation mode" ...\n')
|
||||
local jdomains = hoodutil.get_domains()
|
||||
local geo_base_domain = hoodutil.get_domain_by_geo(jdomains, geo)
|
||||
if geo_base_domain ~= nil then
|
||||
if hoodutil.set_domain_config(geo_base_domain) then
|
||||
os.execute("gluon-reload")
|
||||
hoodutil.log('Domain set by geolocation mode.\n')
|
||||
end
|
||||
return
|
||||
end
|
||||
io.stdout:write('No domain has been defined for the current position. Continue with default domain mode\n')
|
||||
else
|
||||
io.stdout:write('No position found. Continue with default domain mode\n')
|
||||
end
|
||||
|
||||
-- default domain mode
|
||||
if hoodutil.set_domain_config(hoodutil.get_default_domain(hoodutil.get_domains())) then
|
||||
os.execute("gluon-reload")
|
||||
end
|
Loading…
Reference in New Issue
Block a user