From 818c31afdd80b1f6ed58e07290875b49450c905b Mon Sep 17 00:00:00 2001
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Tue, 11 Jun 2019 15:44:29 +0200
Subject: [PATCH] gluon-mesh-vpn-core: move common VPN config to gluon UCI
 package

We now keep the VPN enable state, bandwidth limit enable and actual limits
in the core config to avoid having to recover "user intent" from different
config files when the used VPN packages change.

Fixes #1736
---
 .../config-mode/wizard/0300-mesh-vpn.lua      | 45 +++------
 .../luasrc/lib/gluon/mesh-vpn/update-config   | 48 +++++++++
 .../luasrc/lib/gluon/upgrade/500-mesh-vpn     | 99 ++++++++++---------
 3 files changed, 116 insertions(+), 76 deletions(-)
 create mode 100755 package/gluon-mesh-vpn-core/luasrc/lib/gluon/mesh-vpn/update-config

diff --git a/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
index db753f763..d10f2ea4f 100644
--- a/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
+++ b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
@@ -24,54 +24,39 @@ return function(form, uci)
 	local o
 
 	local meshvpn = s:option(Flag, "meshvpn", pkg_i18n.translate("Use internet connection (mesh VPN)"))
-	meshvpn.default = uci:get_bool("fastd", "mesh_vpn", "enabled") or uci:get_bool("tunneldigger", "mesh_vpn", "enabled")
+	meshvpn.default = uci:get_bool("gluon", "mesh_vpn", "enabled")
 	function meshvpn:write(data)
-		if has_fastd then
-			uci:set("fastd", "mesh_vpn", "enabled", data)
-		end
-		if has_tunneldigger then
-			uci:set("tunneldigger", "mesh_vpn", "enabled", data)
-		end
+		uci:set("gluon", "mesh_vpn", "enabled", data)
 	end
 
 	local limit = s:option(Flag, "limit_enabled", pkg_i18n.translate("Limit bandwidth"))
 	limit:depends(meshvpn, true)
-	limit.default = uci:get_bool("simple-tc", "mesh_vpn", "enabled")
+	limit.default = uci:get_bool("gluon", "mesh_vpn", "limit_enabled")
 	function limit:write(data)
-		uci:set("simple-tc", "mesh_vpn", "interface")
-		uci:set("simple-tc", "mesh_vpn", "enabled", data)
-		uci:set("simple-tc", "mesh_vpn", "ifname", "mesh-vpn")
-		if not data and has_tunneldigger then
-			uci:delete("tunneldigger", "mesh_vpn", "limit_bw_down")
-		end
+		uci:set("gluon", "mesh_vpn", "limit_enabled", data)
 	end
 
 	o = s:option(Value, "limit_ingress", pkg_i18n.translate("Downstream (kbit/s)"))
 	o:depends(limit, true)
-	o.default = uci:get("simple-tc", "mesh_vpn", "limit_ingress")
-	if has_tunneldigger then
-		-- Check if limit_bw_down exists. If not, take the value from limit_ingress
-		local limit_bw_down = uci:get("tunneldigger", "mesh_vpn", "limit_bw_down")
-		if limit_bw_down ~= nil then
-			o.default = limit_bw_down
-		end
-	end
+	o.default = uci:get("gluon", "mesh_vpn", "limit_ingress")
 	o.datatype = "uinteger"
 	function o:write(data)
-		if has_tunneldigger then
-			uci:set("tunneldigger", "mesh_vpn", "limit_bw_down", data)
-		else
-			uci:set("simple-tc", "mesh_vpn", "limit_ingress", data)
-		end
+		uci:set("gluon", "mesh_vpn", "limit_ingress", data)
 	end
 
 	o = s:option(Value, "limit_egress", pkg_i18n.translate("Upstream (kbit/s)"))
 	o:depends(limit, true)
-	o.default = uci:get("simple-tc", "mesh_vpn", "limit_egress")
+	o.default = uci:get("gluon", "mesh_vpn", "limit_egress")
 	o.datatype = "uinteger"
 	function o:write(data)
-		uci:set("simple-tc", "mesh_vpn", "limit_egress", data)
+		uci:set("gluon", "mesh_vpn", "limit_egress", data)
+	end
+
+	function s:handle()
+		Section.handle(s)
+		uci:save('gluon')
+		os.execute('exec /lib/gluon/mesh-vpn/update-config')
 	end
 
-	return {'fastd', 'tunneldigger', 'simple-tc'}
+	return {'gluon', 'fastd', 'tunneldigger', 'simple-tc'}
 end
diff --git a/package/gluon-mesh-vpn-core/luasrc/lib/gluon/mesh-vpn/update-config b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/mesh-vpn/update-config
new file mode 100755
index 000000000..45ecc2d5e
--- /dev/null
+++ b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/mesh-vpn/update-config
@@ -0,0 +1,48 @@
+#!/usr/bin/lua
+
+local uci = require('simple-uci').cursor()
+local unistd = require 'posix.unistd'
+
+local vpn
+if unistd.access('/lib/gluon/mesh-vpn/fastd') then
+	vpn = 'fastd'
+elseif unistd.access('/lib/gluon/mesh-vpn/tunneldigger') then
+	vpn = 'tunneldigger'
+end
+
+local vpn_config = {
+	enabled = uci:get_bool('gluon', 'mesh_vpn', 'enabled'),
+	limit_enabled = uci:get_bool('gluon', 'mesh_vpn', 'limit_enabled'),
+	limit_egress = uci:get('gluon', 'mesh_vpn', 'limit_egress'),
+	limit_ingress = uci:get('gluon', 'mesh_vpn', 'limit_ingress'),
+}
+
+uci:delete('simple-tc', 'mesh_vpn')
+uci:section('simple-tc', 'interface', 'mesh_vpn', {
+	ifname = 'mesh-vpn',
+	enabled = vpn_config.limit_enabled,
+	limit_egress = vpn_config.limit_egress,
+})
+
+if vpn == 'fastd' then
+	uci:set('fastd', 'mesh_vpn', 'enabled', vpn_config.enabled)
+	uci:set('simple-tc', 'mesh_vpn', 'limit_ingress', vpn_config.limit_ingress)
+else
+	uci:set('fastd', 'mesh_vpn', 'enabled', false)
+end
+uci:save('fastd')
+
+if vpn == 'tunneldigger' then
+	uci:set('tunneldigger', 'mesh_vpn', 'enabled', vpn_config.enabled)
+
+	if vpn_config.limit_enabled then
+		uci:set('tunneldigger', 'mesh_vpn', 'limit_bw_down', vpn_config.limit_ingress)
+	else
+		uci:delete('tunneldigger', 'mesh_vpn', 'limit_bw_down')
+	end
+else
+	uci:set('tunneldigger', 'mesh_vpn', 'enabled', false)
+end
+uci:save('tunneldigger')
+
+uci:save('simple-tc')
diff --git a/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
index 0933d67be..89c28ee86 100755
--- a/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
+++ b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
@@ -24,16 +24,6 @@ if unistd.access('/etc/config/gluon-simple-tc') then
 	os.rename('/etc/config/gluon-simple-tc', '/etc/config/simple-tc')
 end
 
-if not uci:get('simple-tc', 'mesh_vpn') then
-	uci:section('simple-tc', 'interface', 'mesh_vpn', {
-		ifname = 'mesh-vpn',
-		enabled = site.mesh_vpn.bandwidth_limit.enabled(false),
-		limit_ingress = site.mesh_vpn.bandwidth_limit.ingress(),
-		limit_egress = site.mesh_vpn.bandwidth_limit.egress(),
-	})
-	uci:save('simple-tc')
-end
-
 
 -- The previously used user and group are removed, we now have a generic group
 users.remove_user('gluon-fastd')
@@ -49,42 +39,59 @@ uci:save('firewall')
 
 
 -- VPN migration
-local has_fastd = unistd.access('/lib/gluon/mesh-vpn/fastd')
-local fastd_enabled = uci:get('fastd', 'mesh_vpn', 'enabled')
-
-local has_tunneldigger = (not has_fastd) and unistd.access('/lib/gluon/mesh-vpn/tunneldigger')
-local tunneldigger_enabled = uci:get('tunneldigger', 'mesh_vpn', 'enabled')
-
-local enabled
-
--- If the installed VPN package has its enabled state set, keep the value
-if has_fastd and fastd_enabled then
-	enabled = fastd_enabled == '1'
-elseif has_tunneldigger and tunneldigger_enabled then
-	enabled = tunneldigger_enabled == '1'
--- Otherwise, migrate the other package's value if any is set
-elseif fastd_enabled or tunneldigger_enabled then
-	enabled = fastd_enabled == '1' or tunneldigger_enabled == '1'
--- If nothing is set, use the default
-else
-	enabled = site.mesh_vpn.enabled(false)
-end
+if not uci:get('gluon', 'mesh_vpn') then
+	local vpn
+	if unistd.access('/lib/gluon/mesh-vpn/fastd') then
+		vpn = 'fastd'
+	elseif unistd.access('/lib/gluon/mesh-vpn/tunneldigger') then
+		vpn = 'tunneldigger'
+	end
 
-if has_fastd then
-	uci:set('fastd', 'mesh_vpn', 'enabled', enabled)
-else
-	uci:delete('fastd', 'mesh_vpn')
-end
-uci:save('fastd')
-
-if has_tunneldigger then
-	uci:set('tunneldigger', 'mesh_vpn', 'enabled', enabled)
-	if site.mesh_vpn.bandwidth_limit.enabled(false) then
-		uci:set('tunneldigger', 'mesh_vpn', 'limit_bw_down', site.mesh_vpn.bandwidth_limit.ingress())
-		uci:set('simple-tc', 'mesh_vpn', 'limit_ingress', 0)
-		uci:save('simple-tc')
+	local fastd_enabled = uci:get('fastd', 'mesh_vpn', 'enabled')
+	local tunneldigger_enabled = uci:get('tunneldigger', 'mesh_vpn', 'enabled')
+
+	local enabled
+
+	-- If the installed VPN package has its enabled state set, keep the value
+	if vpn == 'fastd' and fastd_enabled then
+		enabled = fastd_enabled == '1'
+	elseif vpn == 'tunneldigger' and tunneldigger_enabled then
+		enabled = tunneldigger_enabled == '1'
+	-- Otherwise, migrate the other package's value if any is set
+	elseif fastd_enabled or tunneldigger_enabled then
+		enabled = fastd_enabled == '1' or tunneldigger_enabled == '1'
+	-- If nothing is set, use the default
+	else
+		enabled = site.mesh_vpn.enabled(false)
+	end
+
+
+	local limit_enabled = tonumber((uci:get('simple-tc', 'mesh_vpn', 'enabled')))
+	if limit_enabled == nil then
+		limit_enabled = site.mesh_vpn.bandwidth_limit.enabled(false)
 	end
-else
-	uci:delete('tunneldigger', 'mesh_vpn')
+
+	local limit_ingress = tonumber((uci:get('tunneldigger', 'mesh_vpn', 'limit_bw_down')))
+	if limit_ingress == nil then
+		limit_ingress = tonumber((uci:get('simple-tc', 'mesh_vpn', 'limit_ingress')))
+	end
+	if limit_ingress == nil then
+		limit_ingress = site.mesh_vpn.bandwidth_limit.ingress()
+	end
+
+	local limit_egress = tonumber((uci:get('simple-tc', 'mesh_vpn', 'limit_egress')))
+	if limit_egress == nil then
+		limit_egress = site.mesh_vpn.bandwidth_limit.egress()
+	end
+
+
+	uci:section('gluon', 'mesh_vpn', 'mesh_vpn', {
+		enabled = enabled,
+		limit_enabled = limit_enabled,
+		limit_ingress = limit_ingress,
+		limit_egress = limit_egress,
+	})
+	uci:save('gluon')
 end
-uci:save('tunneldigger')
+
+os.execute('exec /lib/gluon/mesh-vpn/update-config')
-- 
GitLab