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:
Jan-Tarek Butt 2018-05-12 17:48:32 +02:00 committed by Martin Weinelt
parent 6ebb721ebc
commit 90baebc2b7
5 changed files with 186 additions and 0 deletions

View 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))

View 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

View File

@ -0,0 +1 @@
*/2 * * * * /usr/sbin/hoodselector

View File

@ -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

View 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