gluon-{config,web}-*: show "save & apply" button during runtime

If the user has left the setup mode and starts a uhttpd instance to
serve the config mode during normal runtime of the gluon node, this
change is helpful. Instead of the "Save" or "Save & reboot" button,
now a "Save & apply" button is presented. If this button is pressed,
"gluon-reload" including a "gluon-reconfigure" is invoked internally
causing the node to regenerate and reload its configuration
immediately.

Currently such an uhttpd instance is not running by default, but a
user can start such an instance manually and access it via ssh port
forwarding.
This commit is contained in:
Leonardo Mörlein 2021-04-22 23:38:07 +02:00
parent b72588a014
commit 04848dbd36
41 changed files with 223 additions and 13 deletions

View File

@ -13,6 +13,9 @@ msgstr ""
msgid "Save & restart"
msgstr "Speichern & Neustarten"
msgid "Save & apply"
msgstr "Speichern & Anwenden"
msgid "Welcome!"
msgstr "Willkommen!"

View File

@ -13,6 +13,9 @@ msgstr ""
msgid "Save & restart"
msgstr "Enregistrer & Redémarer"
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"
msgid "Welcome!"
msgstr "Bienvenue!"

View File

@ -4,6 +4,9 @@ msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Save & restart"
msgstr ""
msgid "Save & apply"
msgstr ""
msgid "Welcome!"
msgstr ""

View File

@ -11,7 +11,12 @@ for _, entry in ipairs(util.glob('/lib/gluon/config-mode/wizard/*')) do
end
local f = Form(translate("Welcome!"))
f.submit = translate('Save & restart')
if util.in_setup_mode() then
f.submit = translate('Save & restart')
else
f.submit = translate('Save & apply')
end
f.reset = false
local s = f:section(Section)
@ -48,20 +53,25 @@ function f:write()
r()
end
f.template = "wizard/reboot"
f.package = "gluon-config-mode-core"
f.hidenav = true
if unistd.fork() == 0 then
-- Replace stdout with /dev/null
local null = fcntl.open('/dev/null', fcntl.O_WRONLY)
unistd.dup2(null, unistd.STDOUT_FILENO)
if util.in_setup_mode() then
f.template = "wizard/reboot"
f.hidenav = true
-- Sleep a little so the browser can fetch everything required to
-- display the reboot page, then reboot the device.
unistd.sleep(1)
if unistd.fork() == 0 then
-- Replace stdout with /dev/null
local null = fcntl.open('/dev/null', fcntl.O_WRONLY)
unistd.dup2(null, unistd.STDOUT_FILENO)
unistd.execp('reboot', {[0] = 'reboot'})
-- Sleep a little so the browser can fetch everything required to
-- display the reboot page, then reboot the device.
unistd.sleep(1)
unistd.execp('reboot', {[0] = 'reboot'})
end
else
util.reconfigure_asynchronously()
end
end

View File

@ -54,7 +54,7 @@ return function(form, uci)
function o:write(data)
if data ~= selected_domain then
domain_changed = true
uci:set('gluon', 'core', 'domain', data)
uci:set('gluon', 'core', 'switch_domain', data)
end
end

View File

@ -32,5 +32,11 @@ return function(form, uci)
pretty_hostname.set(uci, data or default_hostname)
end
return {'system'}
local function reload_hostname()
local hostname_file = io.open('/proc/sys/kernel/hostname', 'w')
hostname_file:write(o.data or default_hostname)
hostname_file:close()
end
return {'system', reload_hostname}
end

View File

@ -1,9 +1,12 @@
local bit = require 'bit'
local posix_glob = require 'posix.glob'
local posix_syslog = require 'posix.syslog'
local posix_stat = require 'posix.sys.stat'
local hash = require 'hash'
local sysconfig = require 'gluon.sysconfig'
local site = require 'gluon.site'
local fcntl = require 'posix.fcntl'
local unistd = require 'posix.unistd'
local M = {}
@ -188,4 +191,28 @@ function M.log(message, verbose)
posix_syslog.syslog(posix_syslog.LOG_INFO, message)
end
function M.in_setup_mode()
return (posix_stat.stat('/var/gluon/setup-mode') ~= nil)
end
function M.reconfigure_asynchronously()
local uci = require('simple-uci').cursor()
uci:set('gluon', 'core', 'reconfigure', true)
uci:save('gluon')
uci:commit('gluon')
-- as this may take a while, we fork here.
if unistd.fork() == 0 then
-- Replace stdout with /dev/null
local null = fcntl.open('/dev/null', fcntl.O_WRONLY)
unistd.dup2(null, unistd.STDOUT_FILENO)
-- Sleep a little so the browser can fetch everything required to
-- display the reboot page, then reboot the device.
unistd.sleep(1)
unistd.execp('gluon-reload', {[0] = 'gluon-reload'})
end
end
return M

View File

@ -133,3 +133,6 @@ msgstr "Hier kannst du ein manuelles Firmwareupdate durchführen."
msgid "You can provide your SSH keys here (one per line):"
msgstr ""
"Hier hast du die Möglichkeit, SSH-Keys zu hinterlegen (einen pro Zeile):"
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -133,3 +133,6 @@ msgstr "Ici vous pouvez changer manuellement votre firmware."
msgid "You can provide your SSH keys here (one per line):"
msgstr "Ici vous pouvez entrer vos clés SSH (une par ligne):"
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"

View File

@ -115,3 +115,6 @@ msgstr ""
msgid "You can provide your SSH keys here (one per line):"
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -18,6 +18,11 @@ local unistd = require 'posix.unistd'
local wait = require 'posix.sys.wait'
local f_keys = Form(translate("SSH keys"), translate("You can provide your SSH keys here (one per line):"), 'keys')
if not util.in_setup_mode() then
f_keys.submit = translate('Save & apply')
end
local s = f_keys:section(Section)
local keys = s:option(TextValue, "keys")
keys.wrap = "off"
@ -33,6 +38,10 @@ function keys:write(value)
else
unistd.unlink("/etc/dropbear/authorized_keys")
end
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
local config = site.config_mode.remote_login
@ -57,6 +66,10 @@ local f_password = Form(translate("Password"), translate(
)
f_password.reset = false
if not util.in_setup_mode() then
f_password.submit = translate('Save & apply')
end
s = f_password:section(Section)
local pw1 = s:option(Value, "pw1", translate("Password"))
@ -126,6 +139,10 @@ function f_password:write()
os.execute('passwd -l root >/dev/null')
f_password.message = translate("Password removed.")
end
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
return f_keys, f_password

View File

@ -18,3 +18,6 @@ msgstr "Branch"
msgid "Enable"
msgstr "Aktivieren"
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -18,3 +18,6 @@ msgstr "Branche"
msgid "Enable"
msgstr "Activer"
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"

View File

@ -9,3 +9,6 @@ msgstr ""
msgid "Enable"
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -10,8 +10,14 @@ You may obtain a copy of the License at
local uci = require("simple-uci").cursor()
local autoupdater = uci:get_first("autoupdater", "autoupdater")
local util = require 'gluon.util'
local f = Form(translate("Automatic updates"))
if not util.in_setup_mode() then
f.submit = translate('Save & apply')
end
local s = f:section(Section)
local o
@ -41,6 +47,10 @@ end
function f:write()
uci:commit("autoupdater")
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
return f

View File

@ -22,3 +22,6 @@ msgstr "Logging"
msgid "Port"
msgstr ""
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -18,3 +18,6 @@ msgstr ""
msgid "Port"
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -1,11 +1,17 @@
local uci = require('simple-uci').cursor()
local system = uci:get_first('system', 'system')
local util = require 'gluon.util'
local f = Form(translate('Logging'), translate(
"If you want to use a remote syslog server, you can set it up here. "
.. "Please keep in mind that the data is not encrypted, which may cause "
.. "individual-related data to be transmitted unencrypted over the internet."
))
if not util.in_setup_mode() then
f.submit = translate('Save & apply')
end
local s = f:section(Section)
local enable = s:option(Flag, 'log_remote', translate('Enable'))
@ -36,6 +42,10 @@ end
function f:write()
uci:commit('system')
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
return f

View File

@ -36,3 +36,6 @@ msgstr "Hohe Geschwindigkeit"
msgid "Security mode"
msgstr "Hohe Sicherheit"
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -36,3 +36,6 @@ msgstr "Mode performance"
msgid "Security mode"
msgstr "Mode sécurité"
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"

View File

@ -21,3 +21,6 @@ msgstr ""
msgid "Security mode"
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -3,6 +3,10 @@ local util = require 'gluon.util'
local f = Form(translate('Mesh VPN'))
if not util.in_setup_mode() then
f.submit = translate('Save & apply')
end
local s = f:section(Section)
local mode = s:option(Value, 'mode')
@ -37,6 +41,10 @@ function mode:write(data)
uci:save('fastd')
uci:commit('fastd')
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
return f

View File

@ -15,3 +15,6 @@ msgstr "Zurücksetzen"
msgid "Save"
msgstr "Speichern"
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -15,3 +15,6 @@ msgstr "Remise à zéro"
msgid "Save"
msgstr "Soumettre"
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"

View File

@ -6,3 +6,6 @@ msgstr ""
msgid "Save"
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -60,3 +60,6 @@ msgstr "Statische DNS-Server"
msgid "WAN connection"
msgstr "WAN-Verbindung"
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -60,3 +60,6 @@ msgstr "Adresse DNS statique"
msgid "WAN connection"
msgstr "Connexion WAN"
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"

View File

@ -51,3 +51,6 @@ msgstr ""
msgid "WAN connection"
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -18,6 +18,10 @@ local dns_static = uci:get_first("gluon-wan-dnsmasq", "static")
local f = Form(translate("WAN connection"))
if not util.in_setup_mode() then
f.submit = translate('Save & apply')
end
local s = f:section(Section)
local ipv4 = s:option(ListValue, "ipv4", translate("IPv4"))
@ -163,6 +167,10 @@ function f:write()
uci:commit("network")
uci:commit('system')
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
return f

View File

@ -25,3 +25,6 @@ msgstr "Verwendungszweck"
msgid "Role"
msgstr "Rolle"
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -25,3 +25,6 @@ msgstr "Rôle du nœud"
msgid "Role"
msgstr "Rôle"
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"

View File

@ -12,3 +12,6 @@ msgstr ""
msgid "Role"
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -2,6 +2,7 @@ local f, s, o
local site = require 'gluon.site'
local site_i18n = i18n 'gluon-site'
local uci = require("simple-uci").cursor()
local util = require 'gluon.util'
local config = 'gluon-node-info'
-- where to read the configuration from
@ -9,6 +10,10 @@ local role = uci:get(config, uci:get_first(config, "system"), "role")
f = Form(translate("Node role"))
if not util.in_setup_mode() then
f.submit = translate('Save & apply')
end
s = f:section(Section, nil, translate(
"If this node has a special role within the mesh network you can specify this role here. "
.. "Please find out about the available roles and their impact first. "
@ -24,6 +29,10 @@ end
function o:write(data)
uci:set(config, uci:get_first(config, "system"), "role", data)
uci:commit(config)
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
return f

View File

@ -60,3 +60,6 @@ msgstr ""
"Funktionalität ist völlig unabhängig von den Mesh-Funktionen des Knotens. "
"Beachte, dass du nicht gleichzeitig das Meshen über den WAN-Port aktiviert "
"haben solltest."
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -59,3 +59,6 @@ msgstr ""
"Fi séparé. Cette fonction est complètement indépendante de les fonctions de "
"MESH. Il ne faut pas activer la fonction de MESH et de Wi-Fi privé en même "
"temps."
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"

View File

@ -46,3 +46,6 @@ msgid ""
"the mesh functionality. Please note that the private WLAN and meshing on the "
"WAN interface should not be enabled at the same time."
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -1,12 +1,17 @@
local uci = require("simple-uci").cursor()
local platform = require 'gluon.platform'
local wireless = require 'gluon.wireless'
local util = require 'gluon.util'
-- where to read the configuration from
local primary_iface = 'wan_radio0'
local f = Form(translate("Private WLAN"))
if not util.in_setup_mode() then
f.submit = translate('Save & apply')
end
local s = f:section(Section, nil, translate(
'Your node can additionally extend your private network by bridging the WAN interface '
.. 'with a separate WLAN. This feature is completely independent of the mesh functionality. '
@ -77,6 +82,10 @@ function f:write()
end)
uci:commit('wireless')
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
return f

View File

@ -77,3 +77,6 @@ msgstr ""
"werden. Wenn möglich, ist in den Werten der Sendeleistung der Antennengewinn "
"enthalten; diese Werte sind allerdings für viele Geräte nicht verfügbar oder "
"fehlerhaft."
msgid "Save & apply"
msgstr "Speichern & Anwenden"

View File

@ -71,3 +71,6 @@ msgstr ""
"d'émmission se votre Wi-Fi. Prenez note que les valeurs fournies pour la "
"puissance de transmission prennent en compte les gains fournis par "
"l'antenne, et que ces valeurs ne sont pas toujours disponibles ou exactes."
msgid "Save & apply"
msgstr "Enregistrer & Appliquer"

View File

@ -47,3 +47,6 @@ msgid ""
"values include the antenna gain where available, but there are many devices "
"for which the gain is unavailable or inaccurate."
msgstr ""
msgid "Save & apply"
msgstr ""

View File

@ -1,6 +1,7 @@
local iwinfo = require 'iwinfo'
local uci = require("simple-uci").cursor()
local site = require 'gluon.site'
local util = require 'gluon.util'
local wireless = require 'gluon.wireless'
@ -38,6 +39,10 @@ end
local f = Form(translate("WLAN"))
if not util.in_setup_mode() then
f.submit = translate('Save & apply')
end
f:section(Section, nil, translate(
"You can enable or disable your node's client and mesh network "
.. "SSIDs here. Please don't disable the mesh network without "
@ -201,6 +206,10 @@ function f:write()
os.execute('/lib/gluon/upgrade/200-wireless')
uci:commit('network')
uci:commit('wireless')
if not util.in_setup_mode() then
util.reconfigure_asynchronously()
end
end
return f