treewide: convert all LuCI-based packages to gluon-web

This commit is contained in:
Matthias Schiffer 2017-02-08 22:19:24 +01:00
parent e4b74be506
commit 31d3f08f25
No known key found for this signature in database
GPG Key ID: 16EF3F64CB201D9C
110 changed files with 2035 additions and 2818 deletions

View File

@ -99,7 +99,7 @@ config: FORCE
&& scripts/target_config.sh generic \
&& GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/target_config.sh '$(GLUON_TARGET)' \
$(foreach pkg,$(GLUON_PACKAGES_YES),&& echo 'CONFIG_PACKAGE_$(pkg)=y') \
$(foreach lang,$(GLUON_LANGS),&& echo 'CONFIG_LUCI_LANG_$(lang)=y') \
$(foreach lang,$(GLUON_LANGS),&& echo 'CONFIG_GLUON_WEB_LANG_$(lang)=y') \
&& echo 'CONFIG_GLUON_RELEASE="$(GLUON_RELEASE)"' \
&& echo 'CONFIG_GLUON_SITEDIR="$(GLUON_SITEDIR)"' \
&& echo 'CONFIG_GLUON_BRANCH="$(GLUON_BRANCH)"' \

View File

@ -1,7 +1,8 @@
Config Mode
===========
As of 2014.4 `gluon-config-mode` consists of several modules.
The `Config Mode` consists of several modules that provide a range of different
condiguration options:
gluon-config-mode-core
This modules provides the core functionality for the config mode.
@ -22,20 +23,13 @@ gluon-config-mode-geo-location
gluon-config-mode-contact-info
Adds a field where the user can provide contact information.
In order to get a config mode close to the one found in 2014.3.x you may add
these modules to your `site.mk`:
gluon-config-mode-hostname,
gluon-config-mode-autoupdater,
gluon-config-mode-mesh-vpn,
gluon-config-mode-geo-location,
gluon-config-mode-contact-info
Writing Config Mode Modules
Writing Config Mode modules
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Config mode modules are located at `/lib/gluon/config-mode/wizard` and
`/lib/gluon/config-mode/reboot`. Modules are named like `0000-name.lua` and
are executed in lexical order. If you take the standard set of modules, the
Config mode modules are located at ``/lib/gluon/config-mode/wizard`` and
``/lib/gluon/config-mode/reboot``. Modules are named like ``0000-name.lua`` and
are executed in lexical order. In the standard package set, the
order is, for wizard modules:
- 0050-autoupdater-info
@ -44,49 +38,45 @@ order is, for wizard modules:
- 0400-geo-location
- 0500-contact-info
While for reboot modules it is:
The reboot module order is:
- 0100-mesh-vpn
- 0900-msg-reboot
All modules are run in the gluon-web model context and have access to the same
variables as "full" gluon-web modules.
Wizards
-------
Wizard modules return a UCI section. A simple module capable of changing the
hostname might look like this::
Wizard modules must return a function that is provided with the wizard form and an
UCI cursor. The function can create configuration sections in the form:
local cbi = require "luci.cbi"
local uci = luci.model.uci.cursor()
.. code-block:: lua
local M = {}
function M.section(form)
local s = form:section(cbi.SimpleSection, nil, nil)
local o = s:option(cbi.Value, "_hostname", "Hostname")
o.value = uci:get_first("system", "system", "hostname")
o.rmempty = false
return function(form, uci)
local s = form:section(Section)
local o = s:option(Value, "hostname", "Hostname")
o.default = uci:get_first("system", "system", "hostname")
o.datatype = "hostname"
function o:write(data)
uci:set("system", uci:get_first("system", "system"), "hostname", data)
end
return {'system'}
end
function M.handle(data)
uci:set("system", uci:get_first("system", "system"), "hostname", data._hostname)
uci:save("system")
uci:commit("system")
end
return M
The function may return a table of UCI packages to commit after the individual
fields' `write` methods have been executed. This is done to avoid committing the
packages repeatedly when multiple wizard modules modify the same package.
Reboot page
-----------
Reboot modules return a function that will be called when the page is to be
rendered or nil (i.e. the module is skipped)::
Reboot modules are simply executed when the reboot page is
rendered:
if no_hello_world_today then
return nil
else
return function ()
luci.template.render_string("Hello World!")
end
end
.. code-block:: lua
renderer.render_string("Hello World!")

View File

@ -10,53 +10,56 @@ General guidelines
nice-to-have, but not required. If you don't know a language well, rather leave the translation
blank, so it is obvious that there is no proper translation yet.
* Existing expert mode packages should be made translatable as soon as possible.
* The "message IDs" (which are the arguments to the ``translate`` function) should be the
* The "message IDs" (which are the arguments to the *translate* function) should be the
English texts.
i18n support in LuCI
--------------------
i18n support in Gluon
---------------------
Internationalization support can be found in the ``luci.i18n`` package.
Strings are translated using the ``i18n.translate`` and ``i18n.translatef`` functions
(``translate`` for static strings, ``translatef`` for printf-like formatted string).
Internationalization support is available in all components (models, view and
contrllers) of *gluon-web*-based packages. Strings are translated using the *translate*
and *translatef* functions (*translate* for static strings, *translatef*
for printf-like formatted string); in views, the special tags ``<%:...%>`` can
be used to translate the contained string.
Example from the ``gluon-config-mode-geo-location`` package::
Example from the *gluon-config-mode-geo-location* package:
local i18n = require "luci.i18n"
o = s:option(cbi.Flag, "_location", i18n.translate("Show node on the map"))
.. code-block:: lua
local share_location = s:option(Flag, "location", translate("Show node on the map"))
Adding translation templates to Gluon packages
----------------------------------------------
The i18n support is based on the standard gettext system. For each translatable package,
a translation template with extension ``.pot`` can be created using the ``i18n-scan.pl``
script from the LuCI repository::
a translation template with extension ``.pot`` can be created using the *i18n-scan.pl*
script in the ``contrib`` directory:
cd package/gluon-config-mode-geo-location
.. code-block:: sh
cd package/gluon-web-mesh-vpn-fastd
mkdir i18n
cd i18n
../../../packages/luci/build/i18n-scan.pl ../files > gluon-config-mode-geo-location.pot
../../../contrib/i18n-scan.pl ../files ../luasrc > gluon-web-mesh-vpn-fastd.pot
The entries in the template can be reordered after the generation if desirable. Lots of standard
translations like "Cancel" are already available in the LuCI base translation file (see
``packages/luci/po/templates/base.pot``) and can be removed from the template.
The same command can be run again to update the template.
In addition, some additions to the Makefile must be made. Instead of OpenWrt's default ``package.mk``,
the Gluon version ``$(GLUONDIR)/include/package.mk`` must be used. The i18n files must be installed
In addition, some additions to the Makefile must be made. Instead of LEDE's default *package.mk*,
the Gluon version (``../gluon.mk`` for core packages) must be used. The i18n files must be installed
and PKG_CONFIG_DEPENDS must be added::
...
include $(GLUONDIR)/include/package.mk
include ../gluon.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
...
define Build/Compile
$(call GluonBuildI18N,gluon-config-mode-geo-location,i18n)
$(call GluonBuildI18N,gluon-web-mesh-vpn-fastd,i18n)
endef
define Package/gluon-config-mode-geo-location/install
define Package/gluon-web-mesh-vpn-fastd/install
...
$(call GluonInstallI18N,gluon-config-mode-geo-location,$(1))
$(call GluonInstallI18N,gluon-web-mesh-vpn-fastd,$(1))
endef
...
@ -64,29 +67,29 @@ and PKG_CONFIG_DEPENDS must be added::
Adding translations
-------------------
A new translation file for a template can be added using the ``msginit`` command::
A new translation file for a template can be added using the *msginit* command:
cd package/gluon-config-mode-geo-location/i18n
.. code-block:: sh
cd package/gluon-web-mesh-vpn-fastd/i18n
msginit -l de
This will create the file ``de.po`` in which the translations can be added.
This will create the file *de.po* in which the translations can be added.
The translation file can be updated to a new template version using the ``msgmerge`` command::
The translation file can be updated to a new template version using the *msgmerge* command:
msgmerge -U de.po gluon-config-mode-geo-location.pot
.. code-block:: sh
msgmerge -U de.po gluon-web-mesh-vpn-fastd.pot
After the merge, the translation file should be checked for "fuzzy matched" entries where
the original English texts have changed. All entries from the translation file should be
translated in the ``.po`` file (or removed from it, so the original English texts are displayed
translated in the *.po* file (or removed from it, so the original English texts are displayed
instead).
Adding support for new languages
--------------------------------
A list of all languages supported by LuCI can be found in the ``packages/luci/luci.mk`` file after
Gluon's dependencies have been downloaded using ``make update``. Adding translations for these
languages is straightforward using the ``msginit`` command.
For other languages, support must be added to LuCI first, which constitutes completely translating
the ``base.pot``. Please contact the upstream LuCI maintainers at https://github.com/openwrt/luci/
if you'd like to do this.
A list of all languages supported by *gluon-web* can be found in ``package/gluon.mk``.
New languages just need to be added to *GLUON_SUPPORTED_LANGS*, after a human-readable
language name has been defined in the same file.

View File

@ -16,7 +16,7 @@ Best practices
--------------
* Most upgrade scripts are written in Lua. This allows using lots of helper functions provided
by LuCi and Gluon, e.g. to access the site configuration or edit UCI configuration files.
by Gluon, e.g. to access the site configuration or edit UCI configuration files.
* Whenever possible, scripts shouldn't check if they are running for the first time, but just edit configuration
files to achive a valid configuration (without overwriting configuration changes made by the user where desirable).

View File

@ -4,7 +4,7 @@ Private WLAN
It is possible to set up a private WLAN that bridges the WAN port and is seperated from the mesh network.
Please note that you should not enable ``mesh_on_wan`` simultaneously.
The private WLAN can be enabled through the config mode if the package ``gluon-luci-private-wifi`` is installed.
The private WLAN can be enabled through the config mode if the package ``gluon-web-private-wifi`` is installed.
You may also enable a private WLAN using the command line::
uci set wireless.wan_radio0=wifi-iface

View File

@ -18,13 +18,13 @@ For this the section ``roles`` in ``site.conf`` is needed::
},
},
The strings to display in the LuCI interface are configured per language in the
The strings to display in the web interface are configured per language in the
``i18n/en.po``, ``i18n/de.po``, etc. files of the site repository using message IDs like
``gluon-luci-node-role:role:node`` and ``gluon-luci-node-role:role:backbone``.
``gluon-web-node-role:role:node`` and ``gluon-web-node-role:role:backbone``.
The value of ``default`` is the role every node will initially own. This value should be part of ``list`` as well.
If you want node owners to change the defined roles via config-mode you can add the package
``gluon-luci-node-role`` to your ``site.mk``.
``gluon-web-node-role`` to your ``site.mk``.
The role is saved in ``gluon-node-info.system.role``. To change the role using command line do::

View File

@ -19,7 +19,7 @@ Configuration
~~~~~~~~~~~~~
Both Mesh-on-WAN and Mesh-on-LAN can be configured on the "Network" page
of the *Advanced settings* (if the package ``gluon-luci-portconfig`` is installed).
of the *Advanced settings* (if the package ``gluon-web-network`` is installed).
It is also possible to enable Mesh-on-WAN and Mesh-on-LAN by default by
adding ``mesh_on_wan = true`` and ``mesh_on_lan = true`` to ``site.conf``.

View File

@ -15,10 +15,10 @@ GLUON_SITE_PACKAGES := \
gluon-config-mode-mesh-vpn \
gluon-ebtables-filter-multicast \
gluon-ebtables-filter-ra-dhcp \
gluon-luci-admin \
gluon-luci-autoupdater \
gluon-luci-portconfig \
gluon-luci-wifi-config \
gluon-web-admin \
gluon-web-autoupdater \
gluon-web-network \
gluon-web-wifi-config \
gluon-mesh-batman-adv-15 \
gluon-mesh-vpn-fastd \
gluon-radvd \

View File

@ -182,7 +182,7 @@ fastd_mesh_vpn
with the list from the site configuration. Setting `configurable` to `true` will allow the user to
add the method ``null`` to the beginning of the method list or remove ``null`` from it,
and make this change survive updates. Setting `configurable` is necessary for the
package `gluon-luci-mesh-vpn-fastd`, which adds a UI for this configuration.
package `gluon-web-mesh-vpn-fastd`, which adds a UI for this configuration.
In any case, the ``null`` method should always be the first method in the list
if it is supported at all. You should only set `configurable` to `true` if the
@ -288,11 +288,11 @@ roles \: optional
the community which roles to define. See the section below as an example.
``default`` takes the default role which is set initially. This value should be
part of ``list``. If you want node owners to change the role via config mode add
the package ``gluon-luci-node-role`` to ``site.mk``.
the package ``gluon-web-node-role`` to ``site.mk``.
The strings to display in the LuCI interface are configured per language in the
The strings to display in the web interface are configured per language in the
``i18n/en.po``, ``i18n/de.po``, etc. files of the site repository using message IDs like
``gluon-luci-node-role:role:node`` and ``gluon-luci-node-role:role:backbone``.
``gluon-web-node-role:role:node`` and ``gluon-web-node-role:role:backbone``.
::
roles = {

View File

@ -13,14 +13,10 @@ PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-config-mode-autoupdater
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Let the user know whether the autoupdater is enabled or not.
TITLE:=Config Mode: Let the user know whether the autoupdater is enabled or not
DEPENDS:=gluon-config-mode-core-virtual +gluon-autoupdater
endef
define Package/gluon-config-mode-autoupdater/description
Luci based config mode
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef

View File

@ -1,19 +1,8 @@
local cbi = require "luci.cbi"
local i18n = require "luci.i18n"
local uci = require("simple-uci").cursor()
local M = {}
function M.section(form)
local enabled = uci:get_bool("autoupdater", "settings", "enabled")
if enabled then
local s = form:section(cbi.SimpleSection, nil,
i18n.translate('This node will automatically update its firmware when a new version is available.'))
end
return function(form, uci)
if uci:get_bool("autoupdater", "settings", "enabled") then
local s = form:section(
Section, nil,
translate('This node will automatically update its firmware when a new version is available.')
)
end
end
function M.handle(data)
return
end
return M

View File

@ -1,35 +1,27 @@
local cbi = require "luci.cbi"
local i18n = require "luci.i18n"
local uci = require("simple-uci").cursor()
local site = require 'gluon.site_config'
return function(form, uci)
local site = require 'gluon.site_config'
local M = {}
local owner = uci:get_first("gluon-node-info", "owner")
function M.section(form)
local s = form:section(cbi.SimpleSection, nil, i18n.translate(
'Please provide your contact information here to '
.. 'allow others to contact you. Note that '
.. 'this information will be visible <em>publicly</em> '
.. 'on the internet together with your node\'s coordinates.'
)
)
local s = form:section(Section, nil, translate(
'Please provide your contact information here to '
.. 'allow others to contact you. Note that '
.. 'this information will be visible <em>publicly</em> '
.. 'on the internet together with your node\'s coordinates.'
))
local o = s:option(cbi.Value, "_contact", i18n.translate("Contact info"))
o.default = uci:get_first("gluon-node-info", "owner", "contact", "")
o.rmempty = not ((site.config_mode or {}).owner or {}).obligatory
o.datatype = "string"
o.description = i18n.translate("e.g. E-mail or phone number")
o.maxlen = 140
local o = s:option(Value, "contact", translate("Contact info"), translate("e.g. E-mail or phone number"))
o.default = uci:get("gluon-node-info", owner, "contact")
o.optional = not ((site.config_mode or {}).owner or {}).obligatory
-- without a minimal length, an empty string will be accepted even with "optional = false"
o.datatype = "minlength(1)"
function o:write(data)
if data then
uci:set("gluon-node-info", owner, "contact", data)
else
uci:delete("gluon-node-info", owner, "contact")
end
end
return {'gluon-node-info'}
end
function M.handle(data)
if data._contact ~= nil then
uci:set("gluon-node-info", uci:get_first("gluon-node-info", "owner"), "contact", data._contact)
else
uci:delete("gluon-node-info", uci:get_first("gluon-node-info", "owner"), "contact")
end
uci:save("gluon-node-info")
uci:commit("gluon-node-info")
end
return M

View File

@ -16,8 +16,8 @@ PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-config-mode-core
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci based config mode for user friendly setup of new mesh nodes
DEPENDS:=gluon-setup-mode-virtual +gluon-luci-theme +gluon-lock-password +pretty-hostname $(GLUON_I18N_PACKAGES)
TITLE:=Configuration wizard for user friendly setup of new mesh nodes
DEPENDS:=gluon-setup-mode-virtual +gluon-web-theme +gluon-lock-password +pretty-hostname
PROVIDES:=gluon-config-mode-core-virtual
endef

View File

@ -0,0 +1,22 @@
<h2><%:Your node's setup is now complete.%></h2>
<%
local fs = require "nixio.fs"
local util = require "nixio.util"
local parts_dir = "/lib/gluon/config-mode/reboot/"
local files = util.consume(fs.dir(parts_dir) or function() end)
table.sort(files)
local parts = {}
for _, entry in ipairs(files) do
if entry:sub(1, 1) ~= '.' then
local p = assert(loadfile(parts_dir .. entry))
setfenv(p, getfenv())
table.insert(parts, p)
end
end
for _, p in ipairs(parts) do
p()
end
%>

View File

@ -0,0 +1,11 @@
<%-
local sysconfig = require 'gluon.sysconfig'
-%>
<p>
<%=
renderer.render_string(translate('gluon-config-mode:welcome'), {
hostname = hostname,
sysconfig = sysconfig,
})
%>
</p>

View File

@ -1,53 +0,0 @@
<%-
local gluon_luci = require 'gluon.luci'
local sysconfig = require 'gluon.sysconfig'
local i18n = require 'luci.i18n'
local template = require 'luci.template'
-%>
<h2><%:Welcome!%></h2>
<p>
<%= template.render_string(i18n.translate('gluon-config-mode:welcome'), {
hostname = hostname,
sysconfig = sysconfig,
escape = gluon_luci.escape,
urlescape = gluon_luci.urlescape,
}) %>
</p>
<% if not self.embedded then %>
<form method="post" enctype="multipart/form-data" action="<%=REQUEST_URI%>">
<div>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="cbi.submit" value="1" />
</div>
<% end %>
<div class="cbi-map" id="cbi-<%=self.config%>">
<% if self.title and #self.title > 0 then %><h2><a id="content" name="content"><%=self.title%></a></h2><% end %>
<% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
<% self:render_children() %>
<br />
</div>
<%- if self.message then %>
<div><%=self.message%></div>
<%- end %>
<%- if self.errmessage then %>
<div class="error"><%=self.errmessage%></div>
<%- end %>
<% if not self.embedded then %>
<div class="cbi-page-actions">
<%-
if type(self.hidden) == "table" then
for k, v in pairs(self.hidden) do
-%>
<input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" />
<%-
end
end
%>
<input class="cbi-button cbi-button-save" type="submit" value="<%:Save & restart%>" />
<script type="text/javascript">cbi_d_update();</script>
</div>
</form>
<% end %>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><%=escape(hostname)%> is rebooting</title>
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
</head>
<body>
<div id="maincontainer">
<div id="maincontent">
<h2><%:Your node's setup is now complete.%></h2>
<% for k, v in ipairs(parts) do v() end %>
</div>
</div>
</body>
</html>

View File

@ -1,6 +1,4 @@
local i18n = require 'luci.i18n'
local site = require 'gluon.site_config'
local gluon_luci = require 'gluon.luci'
local sysconfig = require 'gluon.sysconfig'
local pretty_hostname = require 'pretty_hostname'
@ -9,15 +7,11 @@ local uci = require("simple-uci").cursor()
local hostname = pretty_hostname.get(uci)
local contact = uci:get_first('gluon-node-info', 'owner', 'contact')
local msg = i18n.translate('gluon-config-mode:reboot')
local msg = translate('gluon-config-mode:reboot')
return function ()
luci.template.render_string(msg, {
hostname = hostname,
site = site,
sysconfig = sysconfig,
contact = contact,
escape = gluon_luci.escape,
urlescape = gluon_luci.urlescape,
})
end
renderer.render_string(msg, {
hostname = hostname,
site = site,
sysconfig = sysconfig,
contact = contact,
})

View File

@ -0,0 +1,2 @@
entry({}, alias("wizard"))
entry({"wizard"}, model("gluon-config-mode/wizard"), _("Wizard"), 5)

View File

@ -0,0 +1,64 @@
local disp = require 'gluon.web.dispatcher'
local fs = require "nixio.fs"
local util = require "gluon.web.util"
local nixio_util = require "nixio.util"
local uci = require("simple-uci").cursor()
local wizard_dir = "/lib/gluon/config-mode/wizard/"
local files = nixio_util.consume(fs.dir(wizard_dir) or function() end)
table.sort(files)
local wizard = {}
for _, entry in ipairs(files) do
if entry:sub(1, 1) ~= '.' then
local f = assert(loadfile(wizard_dir .. entry))
setfenv(f, getfenv())
local w = f()
table.insert(wizard, w)
end
end
local f = Form(translate("Welcome!"))
f.submit = translate('Save & restart')
f.reset = false
local s = f:section(Section)
s.template = "gluon/config-mode/welcome"
local commit = {'gluon-setup-mode'}
for _, w in ipairs(wizard) do
for _, c in ipairs(w(f, uci) or {}) do
if not util.contains(commit, c) then
table.insert(commit, c)
end
end
end
function f:write()
local nixio = require "nixio"
uci:set("gluon-setup-mode", uci:get_first("gluon-setup-mode", "setup_mode"), "configured", true)
for _, c in ipairs(commit) do
uci:commit(c)
end
f.template = "gluon/config-mode/reboot"
f.hidenav = true
if nixio.fork() == 0 then
-- Replace stdout with /dev/null
nixio.dup(nixio.open('/dev/null', 'w'), nixio.stdout)
-- Sleep a little so the browser can fetch everything required to
-- display the reboot page, then reboot the device.
nixio.nanosleep(1)
nixio.execp("reboot")
end
end
return f

View File

@ -1,93 +0,0 @@
--[[
Copyright 2013 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.gluon-config-mode.index", package.seeall)
function index()
local uci_state = luci.model.uci.cursor_state()
if uci_state:get_first("gluon-setup-mode", "setup_mode", "running", "0") == "1" then
local root = node()
if not root.target then
root.target = alias("gluon-config-mode")
root.index = true
end
page = node()
page.lock = true
page.target = alias("gluon-config-mode")
page.subindex = true
page.index = false
page = node("gluon-config-mode")
page.title = _("Wizard")
page.target = alias("gluon-config-mode", "wizard")
page.order = 5
page.sysauth = "root"
page.sysauth_authenticator = function() return "root" end
page.index = true
entry({"gluon-config-mode", "wizard"}, cbi("gluon-config-mode/wizard")).index = true
entry({"gluon-config-mode", "reboot"}, call("action_reboot"))
end
end
function action_reboot()
local uci = luci.model.uci.cursor()
uci:set("gluon-setup-mode", uci:get_first("gluon-setup-mode", "setup_mode"), "configured", "1")
uci:save("gluon-setup-mode")
uci:commit("gluon-setup-mode")
local gluon_luci = require "gluon.luci"
local fs = require "nixio.fs"
local util = require "nixio.util"
local pretty_hostname = require "pretty_hostname"
local parts_dir = "/lib/gluon/config-mode/reboot/"
local files = util.consume(fs.dir(parts_dir))
table.sort(files)
local parts = {}
for _, entry in ipairs(files) do
if entry:sub(1, 1) ~= '.' then
local f = dofile(parts_dir .. '/' .. entry)
if f ~= nil then
table.insert(parts, f)
end
end
end
local hostname = pretty_hostname.get(uci)
luci.template.render("gluon/config-mode/reboot",
{
parts = parts,
hostname = hostname,
escape = gluon_luci.escape,
urlescape = gluon_luci.urlescape,
}
)
if nixio.fork() == 0 then
-- Replace stdout with /dev/null
nixio.dup(nixio.open('/dev/null', 'w'), nixio.stdout)
-- Sleep a little so the browser can fetch everything required to
-- display the reboot page, then reboot the device.
nixio.nanosleep(1)
nixio.execp("reboot")
end
end

View File

@ -1,42 +0,0 @@
local wizard_dir = "/lib/gluon/config-mode/wizard/"
local i18n = luci.i18n
local uci = require("simple-uci").cursor()
local fs = require "nixio.fs"
local util = require "nixio.util"
local f, s
local wizard = {}
local files = {}
if fs.access(wizard_dir) then
files = util.consume(fs.dir(wizard_dir))
table.sort(files)
end
for _, entry in ipairs(files) do
if entry:sub(1, 1) ~= '.' then
table.insert(wizard, dofile(wizard_dir .. '/' .. entry))
end
end
f = SimpleForm("wizard")
f.reset = false
f.template = "gluon/cbi/config-mode"
for _, s in ipairs(wizard) do
s.section(f)
end
function f.handle(self, state, data)
if state == FORM_VALID then
for _, s in ipairs(wizard) do
s.handle(data)
end
luci.http.redirect(luci.dispatcher.build_url("gluon-config-mode", "reboot"))
end
return true
end
return f

View File

@ -1,75 +1,64 @@
local cbi = require "luci.cbi"
local i18n = require "luci.i18n"
local uci = require("simple-uci").cursor()
local site = require 'gluon.site_config'
return function(form, uci)
local site = require 'gluon.site_config'
local M = {}
local location = uci:get_first("gluon-node-info", "location")
local function show_altitude()
if ((site.config_mode or {}).geo_location or {}).show_altitude ~= false then
return true
end
if uci:get_first("gluon-node-info", "location", "altitude") then
return true
end
return false
local function show_altitude()
if ((site.config_mode or {}).geo_location or {}).show_altitude ~= false then
return true
end
return uci:get_bool("gluon-node-info", location, "altitude")
end
local text = translate(
'If you want the location of your node to ' ..
'be displayed on the map, you can enter its coordinates here.'
)
if show_altitude() then
text = text .. ' ' .. translate("gluon-config-mode:altitude-help")
end
local s = form:section(Section, nil, text)
local o
local share_location = s:option(Flag, "location", translate("Show node on the map"))
share_location.default = uci:get_bool("gluon-node-info", location, "share_location")
function share_location:write(data)
uci:set("gluon-node-info", location, "share_location", data)
end
o = s:option(Value, "latitude", translate("Latitude"), translatef("e.g. %s", "53.873621"))
o.default = uci:get("gluon-node-info", location, "latitude")
o:depends(share_location, true)
o.datatype = "float"
function o:write(data)
uci:set("gluon-node-info", location, "latitude", data)
end
o = s:option(Value, "longitude", translate("Longitude"), translatef("e.g. %s", "10.689901"))
o.default = uci:get("gluon-node-info", location, "longitude")
o:depends(share_location, true)
o.datatype = "float"
function o:write(data)
uci:set("gluon-node-info", location, "longitude", data)
end
if show_altitude() then
o = s:option(Value, "altitude", translate("gluon-config-mode:altitude-label"), translatef("e.g. %s", "11.51"))
o.default = uci:get("gluon-node-info", location, "altitude")
o:depends(share_location, true)
o.datatype = "float"
o.optional = true
function o:write(data)
if data then
uci:set("gluon-node-info", location, "altitude", data)
else
uci:delete("gluon-node-info", location, "altitude")
end
end
end
return {'gluon-node-info'}
end
function M.section(form)
local text = i18n.translate('If you want the location of your node to '
.. 'be displayed on the map, you can enter its coordinates here.')
if show_altitude() then
text = text .. ' ' .. i18n.translate("gluon-config-mode:altitude-help")
end
local s = form:section(cbi.SimpleSection, nil, text)
local o
o = s:option(cbi.Flag, "_location", i18n.translate("Show node on the map"))
o.default = uci:get_first("gluon-node-info", "location", "share_location", o.disabled)
o.rmempty = false
o = s:option(cbi.Value, "_latitude", i18n.translate("Latitude"))
o.default = uci:get_first("gluon-node-info", "location", "latitude")
o:depends("_location", "1")
o.rmempty = false
o.datatype = "float"
o.description = i18n.translatef("e.g. %s", "53.873621")
o = s:option(cbi.Value, "_longitude", i18n.translate("Longitude"))
o.default = uci:get_first("gluon-node-info", "location", "longitude")
o:depends("_location", "1")
o.rmempty = false
o.datatype = "float"
o.description = i18n.translatef("e.g. %s", "10.689901")
if show_altitude() then
o = s:option(cbi.Value, "_altitude", i18n.translate("gluon-config-mode:altitude-label"))
o.default = uci:get_first("gluon-node-info", "location", "altitude")
o:depends("_location", "1")
o.rmempty = true
o.datatype = "float"
o.description = i18n.translatef("e.g. %s", "11.51")
end
end
function M.handle(data)
local sname = uci:get_first("gluon-node-info", "location")
uci:set("gluon-node-info", sname, "share_location", data._location)
if data._location and data._latitude ~= nil and data._longitude ~= nil then
uci:set("gluon-node-info", sname, "latitude", data._latitude:trim())
uci:set("gluon-node-info", sname, "longitude", data._longitude:trim())
if data._altitude ~= nil then
uci:set("gluon-node-info", sname, "altitude", data._altitude:trim())
else
uci:delete("gluon-node-info", sname, "altitude")
end
end
uci:save("gluon-node-info")
uci:commit("gluon-node-info")
end
return M

View File

@ -1,20 +1,13 @@
local cbi = require "luci.cbi"
local i18n = require "luci.i18n"
local pretty_hostname = require "pretty_hostname"
local uci = require("simple-uci").cursor()
return function(form, uci)
local pretty_hostname = require "pretty_hostname"
local M = {}
local s = form:section(Section)
local o = s:option(Value, "hostname", translate("Node name"))
o.default = pretty_hostname.get(uci)
function M.section(form)
local s = form:section(cbi.SimpleSection, nil, nil)
local o = s:option(cbi.Value, "_hostname", i18n.translate("Node name"))
o.value = pretty_hostname.get(uci)
o.rmempty = false
function o:write(data)
pretty_hostname.set(uci, data)
end
return {'system'}
end
function M.handle(data)
pretty_hostname.set(uci, data._hostname)
uci:commit("system")
end
return M

View File

@ -2,32 +2,27 @@ local uci = require("simple-uci").cursor()
local meshvpn_enabled = uci:get_bool("fastd", "mesh_vpn", "enabled")
if not meshvpn_enabled then
return nil
else
local i18n = require "luci.i18n"
local util = require "luci.util"
local gluon_luci = require 'gluon.luci'
local site = require 'gluon.site_config'
local sysconfig = require 'gluon.sysconfig'
local pretty_hostname = require 'pretty_hostname'
local pubkey = util.trim(util.exec("/etc/init.d/fastd show_key " .. "mesh_vpn"))
local hostname = pretty_hostname.get(uci)
local contact = uci:get_first("gluon-node-info", "owner", "contact")
local msg = i18n.translate('gluon-config-mode:pubkey')
return function ()
luci.template.render_string(msg, {
pubkey = pubkey,
hostname = hostname,
site = site,
sysconfig = sysconfig,
contact = contact,
escape = gluon_luci.escape,
urlescape = gluon_luci.urlescape,
})
end
return
end
local lutil = require "gluon.web.util"
local site = require 'gluon.site_config'
local sysconfig = require 'gluon.sysconfig'
local util = require "gluon.util"
local pretty_hostname = require 'pretty_hostname'
local pubkey = util.trim(lutil.exec("/etc/init.d/fastd show_key mesh_vpn"))
local hostname = pretty_hostname.get(uci)
local contact = uci:get_first("gluon-node-info", "owner", "contact")
local msg = translate('gluon-config-mode:pubkey')
renderer.render_string(msg, {
pubkey = pubkey,
hostname = hostname,
site = site,
sysconfig = sysconfig,
contact = contact,
})

View File

@ -1,64 +1,47 @@
local cbi = require "luci.cbi"
local i18n = require "luci.i18n"
local uci = require("simple-uci").cursor()
return function(form, uci)
local msg = translate(
'Your internet connection can be used to establish an ' ..
'encrypted connection with other nodes. ' ..
'Enable this option if there are no other nodes reachable ' ..
'over WLAN in your vicinity or you want to make a part of ' ..
'your connection\'s bandwidth available for the network. You can limit how ' ..
'much bandwidth the node will use at most.'
)
local M = {}
local s = form:section(Section, nil, msg)
function M.section(form)
local msg = i18n.translate('Your internet connection can be used to establish an ' ..
'encrypted connection with other nodes. ' ..
'Enable this option if there are no other nodes reachable ' ..
'over WLAN in your vicinity or you want to make a part of ' ..
'your connection\'s bandwidth available for the network. You can limit how ' ..
'much bandwidth the node will use at most.')
local s = form:section(cbi.SimpleSection, nil, msg)
local o
local o
local meshvpn = s:option(Flag, "meshvpn", translate("Use internet connection (mesh VPN)"))
meshvpn.default = uci:get_bool("fastd", "mesh_vpn", "enabled")
function meshvpn:write(data)
uci:set("fastd", "mesh_vpn", "enabled", data)
end
o = s:option(cbi.Flag, "_meshvpn", i18n.translate("Use internet connection (mesh VPN)"))
o.default = uci:get_bool("fastd", "mesh_vpn", "enabled") and o.enabled or o.disabled
o.rmempty = false
local limit = s:option(Flag, "limit_enabled", translate("Limit bandwidth"))
limit:depends(meshvpn, true)
limit.default = uci:get_bool("simple-tc", "mesh_vpn", "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")
end
o = s:option(cbi.Flag, "_limit_enabled", i18n.translate("Limit bandwidth"))
o:depends("_meshvpn", "1")
o.default = uci:get_bool("simple-tc", "mesh_vpn", "enabled") and o.enabled or o.disabled
o.rmempty = false
o = s:option(Value, "limit_ingress", translate("Downstream (kbit/s)"))
o:depends(limit, true)
o.default = uci:get("simple-tc", "mesh_vpn", "limit_ingress")
o.datatype = "uinteger"
function o:write(data)
uci:set("simple-tc", "mesh_vpn", "limit_ingress", data)
end
o = s:option(cbi.Value, "_limit_ingress", i18n.translate("Downstream (kbit/s)"))
o:depends("_limit_enabled", "1")
o.value = uci:get("simple-tc", "mesh_vpn", "limit_ingress")
o.rmempty = false
o.datatype = "uinteger"
o = s:option(Value, "limit_egress", translate("Upstream (kbit/s)"))
o:depends(limit, true)
o.default = uci:get("simple-tc", "mesh_vpn", "limit_egress")
o.datatype = "uinteger"
function o:write(data)
uci:set("simple-tc", "mesh_vpn", "limit_egress", data)
end
o = s:option(cbi.Value, "_limit_egress", i18n.translate("Upstream (kbit/s)"))
o:depends("_limit_enabled", "1")
o.value = uci:get("simple-tc", "mesh_vpn", "limit_egress")
o.rmempty = false
o.datatype = "uinteger"
return {'fastd', 'simple-tc'}
end
function M.handle(data)
uci:set("fastd", "mesh_vpn", "enabled", data._meshvpn)
uci:save("fastd")
uci:commit("fastd")
-- checks for nil needed due to o:depends(...)
if data._limit_enabled ~= nil then
uci:set("simple-tc", "mesh_vpn", "interface")
uci:set("simple-tc", "mesh_vpn", "enabled", data._limit_enabled)
uci:set("simple-tc", "mesh_vpn", "ifname", "mesh-vpn")
if data._limit_ingress ~= nil then
uci:set("simple-tc", "mesh_vpn", "limit_ingress", data._limit_ingress:trim())
end
if data._limit_egress ~= nil then
uci:set("simple-tc", "mesh_vpn", "limit_egress", data._limit_egress:trim())
end
uci:save("simple-tc")
uci:commit("simple-tc")
end
end
return M

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><%:Upgrading firmware%></title>
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
</head>
<body>
<div id="maincontainer">
<div id="maincontent">
<p>
<%:The firmware is currently being upgraded.%>
<strong><%:Don't switch off the device in any circumstance!%></strong>
<%:The upgrade will take a few minutes. When it is finished, your node will reboot automatically.%>
</p>
</div>
</div>
</body>
</html>

View File

@ -1,39 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.admin.index", package.seeall)
function index()
local uci_state = luci.model.uci.cursor_state()
-- Disable gluon-luci-admin when setup mode is not enabled
if uci_state:get_first('gluon-setup-mode', 'setup_mode', 'running', '0') ~= '1' then
return
end
local root = node()
if not root.lock then
root.target = alias("admin")
root.index = true
end
local page = entry({"admin"}, alias("admin", "index"), _("Advanced settings"), 10)
page.sysauth = "root"
page.sysauth_authenticator = function() return "root" end
page.index = true
entry({"admin", "index"}, template("admin/info"), _("Information"), 1)
entry({"admin", "remote"}, cbi("admin/remote"), _("Remote access"), 10)
end

View File

@ -1,139 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.admin.upgrade", package.seeall)
function index()
local has_platform = nixio.fs.access("/lib/upgrade/platform.sh")
if has_platform then
entry({"admin", "upgrade"}, call("action_upgrade"), _("Upgrade firmware"), 90)
entry({"admin", "upgrade", "reboot"}, template("admin/upgrade_reboot"), nil, nil)
end
end
function action_upgrade()
local tmpfile = "/tmp/firmware.img"
-- Install upload handler
local file
luci.http.setfilehandler(
function(meta, chunk, eof)
if not nixio.fs.access(tmpfile) and not file and chunk and #chunk > 0 then
file = io.open(tmpfile, "w")
end
if file and chunk then
file:write(chunk)
end
if file and eof then
file:close()
end
end
)
-- Determine state
local step = tonumber(luci.http.formvalue("step") or 1)
if step ~= 1 and not luci.dispatcher.test_post_security() then
nixio.fs.unlink(tmpfile)
return
end
local has_image = nixio.fs.access(tmpfile)
local has_support = image_supported(tmpfile)
-- Step 1: file upload, error on unsupported image format
if not has_image or not has_support or step == 1 then
-- If there is an image but user has requested step 1
-- or type is not supported, then remove it.
if has_image then
nixio.fs.unlink(tmpfile)
end
luci.template.render("admin/upgrade", {
bad_image=(has_image and not has_support or false)
} )
-- Step 2: present uploaded file, show checksum, confirmation
elseif step == 2 then
luci.template.render("admin/upgrade_confirm", {
checksum=image_checksum(tmpfile),
filesize=nixio.fs.stat(tmpfile).size,
flashsize=storage_size(),
keepconfig=luci.http.formvalue("keepcfg") == "1"
} )
elseif step == 3 then
local keepcfg = luci.http.formvalue("keepcfg") == "1"
fork_exec("/sbin/sysupgrade %s %q" % { keepcfg and "" or "-n", tmpfile })
luci.http.redirect(luci.dispatcher.build_url("admin", "upgrade", "reboot"))
end
end
function fork_exec(command)
local pid = nixio.fork()
if pid > 0 then
return
elseif pid == 0 then
-- change to root dir
nixio.chdir("/")
-- patch stdin, out, err to /dev/null
local null = nixio.open("/dev/null", "w+")
if null then
nixio.dup(null, nixio.stderr)
nixio.dup(null, nixio.stdout)
nixio.dup(null, nixio.stdin)
if null:fileno() > 2 then
null:close()
end
end
-- replace with target command
nixio.exec("/bin/sh", "-c", command)
end
end
function image_supported(tmpfile)
-- XXX: yay...
return ( 0 == os.execute(
"/sbin/sysupgrade -T %q >/dev/null"
% tmpfile
) )
end
function storage_size()
local size = 0
if nixio.fs.access("/proc/mtd") then
for l in io.lines("/proc/mtd") do
local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)"')
if n == "linux" then
size = tonumber(s, 16)
break
end
end
elseif nixio.fs.access("/proc/partitions") then
for l in io.lines("/proc/partitions") do
local x, y, b, n = l:match('^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+)')
if b and n and not n:match('[0-9]') then
size = tonumber(b) * 1024
break
end
end
end
return size
end
function image_checksum(tmpfile)
return (luci.sys.exec("md5sum %q" % tmpfile):match("^([^%s]+)"))
end

View File

@ -1,87 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2011 Jo-Philipp Wich <xm@subsignal.org>
Copyright 2013 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local fs = require "nixio.fs"
local f_keys = SimpleForm('keys', translate("SSH keys"), translate("You can provide your SSH keys here (one per line):"))
f_keys.hidden = { submit_keys = '1' }
local keys
keys = f_keys:field(TextValue, "keys", "")
keys.wrap = "off"
keys.rows = 5
keys.rmempty = true
function keys.cfgvalue()
return fs.readfile("/etc/dropbear/authorized_keys") or ""
end
function keys.write(self, section, value)
if not f_keys:formvalue('submit_keys') then return end
fs.writefile("/etc/dropbear/authorized_keys", value:gsub("\r\n", "\n"):trim() .. "\n")
end
function keys.remove(self, section)
if not f_keys:formvalue('submit_keys') then return end
fs.remove("/etc/dropbear/authorized_keys")
end
local f_password = SimpleForm('password', translate("Password"),
translate(
"Alternatively, you can set a password to access you node. Please choose a secure password you don't use anywhere else.<br /><br />"
.. "If you set an empty password, login via password will be disabled. This is the default."
)
)
f_password.hidden = { submit_password = '1' }
f_password.reset = false
local pw1 = f_password:field(Value, "pw1", translate("Password"))
pw1.password = true
function pw1.cfgvalue()
return ''
end
local pw2 = f_password:field(Value, "pw2", translate("Confirmation"))
pw2.password = true
function pw2.cfgvalue()
return ''
end
function f_password:handle(state, data)
if not f_password:formvalue('submit_password') then return end
if data.pw1 ~= data.pw2 then
f_password.errmessage = translate("The password and the confirmation differ.")
return
end
if data.pw1 and #data.pw1 > 0 then
if luci.sys.user.setpasswd('root', data.pw1) == 0 then
f_password.message = translate("Password changed.")
else
f_password.errmessage = translate("Unable to change the password.")
end
else
-- We don't check the return code here as the error 'password for root is already locked' is normal...
os.execute('passwd -l root >/dev/null')
f_password.message = translate("Password removed.")
end
end
return f_keys, f_password

View File

@ -1,19 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2013 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.admin.autoupdater", package.seeall)
function index()
entry({"admin", "autoupdater"}, cbi("admin/autoupdater"), _("Automatic updates"), 80)
end

View File

@ -1,32 +0,0 @@
<div class="cbi-value">
<div class="cbi-value-title">
<input class="cbi-input-radio" onclick="cbi_d_update(this.id)" onchange="cbi_d_update(this.id)" type="radio" value="security"<%= attr("id", cbid..'1') .. attr("name", cbid) .. ifattr((self:cfgvalue(section) or self.default) == "security", "checked", "checked") %> />
</div>
<div class="cbi-value-field-long">
<label<%= attr("for", cbid..'1') %> class="cbi-value-title"><%:Security mode%></label>
<br />
<%= translate(
'In security mode, the mesh VPN uses an encrypted tunnel to connect to the VPN servers. ' ..
'The encryption ensures that it is impossible for your internet access provider to see what ' ..
'data is exchanged over your node.'
) %>
<br />
</div>
<div class="cbi-value-field-long-after"></div>
</div>
<div class="cbi-value cbi-value-last">
<div class="cbi-value-title">
<input class="cbi-input-radio" onclick="cbi_d_update(this.id)" onchange="cbi_d_update(this.id)" type="radio" value="performance"<%= attr("id", cbid..'2') .. attr("name", cbid) .. ifattr((self:cfgvalue(section) or self.default) == "performance", "checked", "checked") %> />
</div>
<div class="cbi-value-field-long">
<label<%= attr("for", cbid..'2') %> class="cbi-value-title"><%:Performance mode%></label>
<br />
<%= translate(
'In performance mode, no encryption is used. This usually allows for higher throughput, but the data exchanged over your node is not ' ..
'protected against eavesdropping.'
) %>
<br />
</div>
<div class="cbi-value-field-long-after"></div>
</div>

View File

@ -1,5 +0,0 @@
module("luci.controller.admin.mesh_vpn_fastd", package.seeall)
function index()
entry({"admin", "mesh_vpn_fastd"}, cbi("admin/mesh_vpn_fastd"), _("Mesh VPN"), 20)
end

View File

@ -1,40 +0,0 @@
local uci = require("simple-uci").cursor()
local util = luci.util
local f = SimpleForm('mesh_vpn', translate('Mesh VPN'))
local s = f:section(SimpleSection)
local o = s:option(Value, 'mode')
o.template = "gluon/cbi/mesh-vpn-fastd-mode"
local methods = uci:get('fastd', 'mesh_vpn', 'method')
if util.contains(methods, 'null') then
o.default = 'performance'
else
o.default = 'security'
end
function f.handle(self, state, data)
if state == FORM_VALID then
local site = require 'gluon.site_config'
local methods = {}
if data.mode == 'performance' then
table.insert(methods, 'null')
end
for _, method in ipairs(site.fastd_mesh_vpn.methods) do
if method ~= 'null' then
table.insert(methods, method)
end
end
uci:set('fastd', 'mesh_vpn', 'method', methods)
uci:save('fastd')
uci:commit('fastd')
end
end
return f

View File

@ -1,5 +0,0 @@
module("luci.controller.admin.noderole", package.seeall)
function index()
entry({"admin", "noderole"}, cbi("admin/noderole"), "Node role", 20)
end

View File

@ -1,33 +0,0 @@
local f, s, o
local site = require 'gluon.site_config'
local i18n = require "luci.i18n"
local uci = require("simple-uci").cursor()
local config = 'gluon-node-info'
-- where to read the configuration from
local role = uci:get(config, uci:get_first(config, "system"), "role")
f = SimpleForm("role", i18n.translate("Node role"))
s = f:section(SimpleSection, nil, i18n.translate(
"If this node has a special role within the freifunk network you can specify this role here. "
.. "Please find out about the available roles and their impact first. "
.. "Only change the role if you know what you are doing."))
o = s:option(ListValue, "role", i18n.translate("Role"))
o.default = role
o.rmempty = false
for _, role in ipairs(site.roles.list) do
o:value(role, i18n.translate('gluon-luci-node-role:role:' .. role))
end
function f.handle(self, state, data)
if state == FORM_VALID then
uci:set(config, uci:get_first(config, "system"), "role", data.role)
uci:save(config)
uci:commit(config)
end
end
return f

View File

@ -1,19 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2013 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.admin.portconfig", package.seeall)
function index()
entry({"admin", "portconfig"}, cbi("admin/portconfig"), _("Network"), 20)
end

View File

@ -1,167 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2014 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local uci = require("simple-uci").cursor()
local sysconfig = require 'gluon.sysconfig'
local util = require 'gluon.util'
local wan = uci:get_all("network", "wan")
local wan6 = uci:get_all("network", "wan6")
local dns = uci:get_first("gluon-wan-dnsmasq", "static")
local f = SimpleForm("portconfig", translate("WAN connection"))
local s
local o
s = f:section(SimpleSection, nil, nil)
o = s:option(ListValue, "ipv4", translate("IPv4"))
o:value("dhcp", translate("Automatic (DHCP)"))
o:value("static", translate("Static"))
o:value("none", translate("Disabled"))
o.default = wan.proto
o = s:option(Value, "ipv4_addr", translate("IP address"))
o:depends("ipv4", "static")
o.value = wan.ipaddr
o.datatype = "ip4addr"
o.rmempty = false
o = s:option(Value, "ipv4_netmask", translate("Netmask"))
o:depends("ipv4", "static")
o.value = wan.netmask or "255.255.255.0"
o.datatype = "ip4addr"
o.rmempty = false
o = s:option(Value, "ipv4_gateway", translate("Gateway"))
o:depends("ipv4", "static")
o.value = wan.gateway
o.datatype = "ip4addr"
o.rmempty = false
s = f:section(SimpleSection, nil, nil)
o = s:option(ListValue, "ipv6", translate("IPv6"))
o:value("dhcpv6", translate("Automatic (RA/DHCPv6)"))
o:value("static", translate("Static"))
o:value("none", translate("Disabled"))
o.default = wan6.proto
o = s:option(Value, "ipv6_addr", translate("IP address"))
o:depends("ipv6", "static")
o.value = wan6.ip6addr
o.datatype = "ip6addr"
o.rmempty = false
o = s:option(Value, "ipv6_gateway", translate("Gateway"))
o:depends("ipv6", "static")
o.value = wan6.ip6gw
o.datatype = "ip6addr"
o.rmempty = false
if dns then
s = f:section(SimpleSection, nil, nil)
o = s:option(DynamicList, "dns", translate("Static DNS servers"))
o:write(nil, uci:get("gluon-wan-dnsmasq", dns, "server"))
o.datatype = "ipaddr"
end
s = f:section(SimpleSection, nil, nil)
o = s:option(Flag, "mesh_wan", translate("Enable meshing on the WAN interface"))
o.default = uci:get_bool("network", "mesh_wan", "auto") and o.enabled or o.disabled
o.rmempty = false
if sysconfig.lan_ifname then
o = s:option(Flag, "mesh_lan", translate("Enable meshing on the LAN interface"))
o.default = uci:get_bool("network", "mesh_lan", "auto") and o.enabled or o.disabled
o.rmempty = false
end
if uci:get('system', 'gpio_switch_poe_passthrough') then
s = f:section(SimpleSection, nil, nil)
o = s:option(Flag, "poe_passthrough", translate("Enable PoE passthrough"))
o.default = uci:get_bool("system", "gpio_switch_poe_passthrough", "value") and o.enabled or o.disabled
o.rmempty = false
end
function f.handle(self, state, data)
if state == FORM_VALID then
uci:set("network", "wan", "proto", data.ipv4)
if data.ipv4 == "static" then
uci:set("network", "wan", "ipaddr", data.ipv4_addr:trim())
uci:set("network", "wan", "netmask", data.ipv4_netmask:trim())
uci:set("network", "wan", "gateway", data.ipv4_gateway:trim())
else
uci:delete("network", "wan", "ipaddr")
uci:delete("network", "wan", "netmask")
uci:delete("network", "wan", "gateway")
end
uci:set("network", "wan6", "proto", data.ipv6)
if data.ipv6 == "static" then
uci:set("network", "wan6", "ip6addr", data.ipv6_addr:trim())
uci:set("network", "wan6", "ip6gw", data.ipv6_gateway:trim())
else
uci:delete("network", "wan6", "ip6addr")
uci:delete("network", "wan6", "ip6gw")
end
uci:set("network", "mesh_wan", "auto", data.mesh_wan)
if sysconfig.lan_ifname then
uci:set("network", "mesh_lan", "auto", data.mesh_lan)
local interfaces = uci:get_list("network", "client", "ifname")
for lanif in sysconfig.lan_ifname:gmatch('%S+') do
if data.mesh_lan == '1' then
util.remove_from_set(interfaces, lanif)
else
util.add_to_set(interfaces, lanif)
end
end
uci:set_list("network", "client", "ifname", interfaces)
end
uci:save("network")
uci:commit("network")
if uci:get('system', 'gpio_switch_poe_passthrough') then
uci:set('system', 'gpio_switch_poe_passthrough', 'value', data.poe_passthrough)
uci:save('system')
uci:commit('system')
end
if dns then
if #data.dns > 0 then
uci:set("gluon-wan-dnsmasq", dns, "server", data.dns)
else
uci:delete("gluon-wan-dnsmasq", dns, "server")
end
uci:save("gluon-wan-dnsmasq")
uci:commit("gluon-wan-dnsmasq")
end
end
return true
end
return f

View File

@ -1,5 +0,0 @@
module("luci.controller.admin.privatewifi", package.seeall)
function index()
entry({"admin", "privatewifi"}, cbi("admin/privatewifi"), _("Private WLAN"), 10)
end

View File

@ -1,67 +0,0 @@
local uci = require("simple-uci").cursor()
local util = require 'gluon.util'
local f, s, o, ssid
-- where to read the configuration from
local primary_iface = 'wan_radio0'
local ssid = uci:get('wireless', primary_iface, "ssid")
f = SimpleForm("wifi", translate("Private WLAN"))
s = f:section(SimpleSection, 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. '
.. 'Please note that the private WLAN and meshing on the WAN interface should not be enabled '
.. 'at the same time.'
))
o = s:option(Flag, "enabled", translate("Enabled"))
o.default = (ssid and not uci:get_bool('wireless', primary_iface, "disabled")) and o.enabled or o.disabled
o.rmempty = false
o = s:option(Value, "ssid", translate("Name (SSID)"))
o:depends("enabled", '1')
o.datatype = "maxlength(32)"
o.default = ssid
o = s:option(Value, "key", translate("Key"), translate("8-63 characters"))
o:depends("enabled", '1')
o.datatype = "wpakey"
o.default = uci:get('wireless', primary_iface, "key")
function f.handle(self, state, data)
if state == FORM_VALID then
util.iterate_radios(
function(radio, index)
local name = "wan_" .. radio
if data.enabled == '1' then
local macaddr = util.get_wlan_mac(radio, index, 4)
-- set up WAN wifi-iface
uci:section('wireless', "wifi-iface", name,
{
device = radio,
network = "wan",
mode = 'ap',
encryption = 'psk2',
ssid = data.ssid,
key = data.key,
macaddr = macaddr,
disabled = false,
}
)
else
-- disable WAN wifi-iface
uci:set('wireless', name, "disabled", true)
end
end
)
uci:save('wireless')
uci:commit('wireless')
end
end
return f

View File

@ -1,6 +0,0 @@
#!/bin/sh
uci batch <<-EOF
set luci.themes.Gluon=/luci-static/gluon
commit luci
EOF

View File

@ -1,19 +0,0 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
-%>
</div>
</div>
</body>
</html>

View File

@ -1,171 +0,0 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008-2010 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
-%>
<%
local sys = require "luci.sys"
local http = require "luci.http"
local disp = require "luci.dispatcher"
local uci = require("simple-uci").cursor()
local fs = require "nixio.fs"
local gluon_luci = require "gluon.luci"
local pretty_hostname = require "pretty_hostname"
local hostname = pretty_hostname.get(uci)
local release = fs.readfile("/lib/gluon/release")
local request = disp.context.path
local request2 = disp.context.request
local category = request[1]
local cattree = category and disp.node(category)
local leaf = request2[#request2]
local tree = disp.node()
local node = disp.context.dispatched
local categories = disp.node_childs(tree)
local c = tree
local i, r
-- tag all nodes leading to this page
for i, r in ipairs(request) do
if c.nodes and c.nodes[r] then
c = c.nodes[r]
c._menu_selected = true
end
end
http.prepare_content("application/xhtml+xml")
local function nodeurl(prefix, name, query)
local url = controller .. prefix .. name .. "/"
if query then
url = url .. http.build_querystring(query)
end
return pcdata(url)
end
local function subtree(prefix, node, level)
if not level then
level = 1
end
local childs = disp.node_childs(node)
if #childs > 0 then
%>
<div class="tabmenu<%=level%>">
<ul class="tabmenu l<%=level%>">
<%
local selected_node
local selected_name
local i, v
for i, v in ipairs(childs) do
local nnode = node.nodes[v]
if nnode._menu_selected then
selected_node = nnode
selected_name = v
end
%>
<li class="tabmenu-item-<%=v%><% if nnode._menu_selected or (node.leaf and v == leaf) then %> active<% end %>">
<a href="<%=nodeurl(prefix, v, nnode.query)%>"><%=striptags(translate(nnode.title))%></a>
</li>
<%
end
%>
</ul>
<br style="clear:both" />
<%
if selected_node then
subtree(prefix .. selected_name .. "/", selected_node, level + 1)
end
%>
</div>
<%
end
end
-%>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
<% if node and node.css then %><link rel="stylesheet" type="text/css" media="screen" href="<%=resource%>/<%=node.css%>" />
<% end -%>
<% if css then %><style title="text/css">
<%= css %>
</style>
<% end -%>
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<title><%=gluon_luci.escape( hostname .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI</title>
</head>
<body class="lang_<%=luci.i18n.context.lang%>">
<div id="menubar">
<div class="hostinfo">
<%=gluon_luci.escape(hostname)%>
<% if release then %>
/ <%=gluon_luci.escape(release)%>
<% end %>
<span id="xhr_poll_status" style="display:none" onclick="XHR.running() ? XHR.halt() : XHR.run()">
| <%:Auto Refresh%>:
<span id="xhr_poll_status_on"><%:on%></span>
<span id="xhr_poll_status_off" style="display:none"><%:off%></span>
</span>
</div>
<% if #categories > 1 then %>
<ul id="modemenu">
<% for i, r in ipairs(categories) do %>
<li><a<% if request[1] == r then %> class="active"<%end%> href="<%=controller%>/<%=r%>/"><%=striptags(translate(tree.nodes[r].title))%></a></li>
<% end %>
</ul>
<% end %>
<%
if tree.nodes[category] and tree.nodes[category].ucidata then
local ucic = 0
for i, j in pairs(require("simple-uci").cursor():changes()) do
for k, l in pairs(j) do
for m, n in pairs(l) do
ucic = ucic + 1;
end
end
end
-%>
<div id="savemenu">
<% if ucic > 0 then %>
<a class="warning" href="<%=controller%>/<%=category%>/uci/changes/?redir=<%=luci.http.urlencode(luci.http.formvalue("redir") or REQUEST_URI)%>"><%:Unsaved Changes%>: <%=ucic%></a>
<%- else -%>
<a href="#"><%:Changes%>: 0</a>
<% end -%>
</div><% end %>
</div>
<div id="maincontainer">
<% if category then subtree("/" .. category .. "/", cattree) end %>
<div id="maincontent">
<noscript>
<div class="errorbox">
<strong><%:Java Script required!%></strong><br />
<%:You must enable Java Script in your browser or LuCI will not work properly.%>
</div>
</noscript>

File diff suppressed because one or more lines are too long

View File

@ -1,28 +0,0 @@
-- Config mode utility functions
local string = string
module 'gluon.luci'
function escape(s)
return (string.gsub(s, '[<>&"]', {
['<'] = '&lt;',
['>'] = '&gt;',
['&'] = '&amp;',
['"'] = '&quot;',
}))
end
function urlescape(s)
return (string.gsub(s, '[^a-zA-Z0-9%-_%.~]',
function(c)
local ret = ''
for i = 1, string.len(c) do
ret = ret .. string.format('%%%02X', string.byte(c, i, i))
end
return ret
end
))
end

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
module("luci.controller.admin.wifi-config", package.seeall)
function index()
entry({"admin", "wifi-config"}, cbi("admin/wifi-config"), _("WLAN"), 20)
end

View File

@ -1,169 +0,0 @@
local uci = require("simple-uci").cursor()
local fs = require 'nixio.fs'
local iwinfo = require 'iwinfo'
local function find_phy_by_path(path)
for phy in fs.glob("/sys/devices/" .. path .. "/ieee80211/phy*") do
return phy:match("([^/]+)$")
end
end
local function find_phy_by_macaddr(macaddr)
local addr = macaddr:lower()
for file in fs.glob("/sys/class/ieee80211/*/macaddress") do
if luci.util.trim(fs.readfile(file)) == addr then
return file:match("([^/]+)/macaddress$")
end
end
end
local function txpower_list(phy)
local list = iwinfo.nl80211.txpwrlist(phy) or { }
local off = tonumber(iwinfo.nl80211.txpower_offset(phy)) or 0
local new = { }
local prev = -1
local _, val
for _, val in ipairs(list) do
local dbm = val.dbm + off
local mw = math.floor(10 ^ (dbm / 10))
if mw ~= prev then
prev = mw
table.insert(new, {
display_dbm = dbm,
display_mw = mw,
driver_dbm = val.dbm,
})
end
end
return new
end
local f = SimpleForm("wifi", translate("WLAN"))
local s = f:section(SimpleSection, nil, translate(
"You can enable or disable your node's client and mesh network "
.. "SSIDs here. Please don't disable the mesh network without "
.. "a good reason, so other nodes can mesh with yours.<br /><br />"
.. "It is also possible to configure the WLAN adapters transmission power "
.. "here. Please note that the transmission power values include the antenna gain "
.. "where available, but there are many devices for which the gain is unavailable or inaccurate."
))
local radios = {}
-- look for wifi interfaces and add them to the array
uci:foreach('wireless', 'wifi-device',
function(s)
table.insert(radios, s['.name'])
end
)
-- add a client and mesh checkbox for each interface
for _, radio in ipairs(radios) do
local config = uci:get_all('wireless', radio)
local p
if config.hwmode == '11g' or config.hwmode == '11ng' then
p = f:section(SimpleSection, translate("2.4GHz WLAN"))
elseif config.hwmode == '11a' or config.hwmode == '11na' then
p = f:section(SimpleSection, translate("5GHz WLAN"))
end
if p then
local o
if uci:get('wireless', 'client_' .. radio) then
o = p:option(Flag, radio .. '_client_enabled', translate("Enable client network (access point)"))
o.default = uci:get_bool('wireless', 'client_' .. radio, "disabled") and o.disabled or o.enabled
o.rmempty = false
end
if uci:get('wireless', 'mesh_' .. radio) then
o = p:option(Flag, radio .. '_mesh_enabled', translate("Enable mesh network (802.11s)"))
o.default = uci:get_bool('wireless', 'mesh_' .. radio, "disabled") and o.disabled or o.enabled
o.rmempty = false
end
if uci:get('wireless', 'ibss_' .. radio) then
o = p:option(Flag, radio .. '_ibss_enabled', translate("Enable mesh network (IBSS)"))
o.default = uci:get_bool('wireless', 'ibss_' .. radio, "disabled") and o.disabled or o.enabled
o.rmempty = false
end
local phy
if config.path then
phy = find_phy_by_path(config.path)
elseif config.macaddr then
phy = find_phy_by_macaddr(config.macaddr)
end
if phy then
local txpowers = txpower_list(phy)
if #txpowers > 1 then
local tp = p:option(ListValue, radio .. '_txpower', translate("Transmission power"))
tp.rmempty = true
tp.default = uci:get('wireless', radio, 'txpower') or 'default'
tp:value('default', translate("(default)"))
table.sort(txpowers, function(a, b) return a.driver_dbm > b.driver_dbm end)
for _, entry in ipairs(txpowers) do
tp:value(entry.driver_dbm, "%i dBm (%i mW)" % {entry.display_dbm, entry.display_mw})
end
end
end
end
end
--when the save-button is pushed
function f.handle(self, state, data)
if state == FORM_VALID then
for _, radio in ipairs(radios) do
if uci:get('wireless', 'client_' .. radio) then
local disabled = 0
if data[radio .. '_client_enabled'] == '0' then
disabled = 1
end
uci:set('wireless', 'client_' .. radio, "disabled", disabled)
end
if uci:get('wireless', 'mesh_' .. radio) then
local disabled = 0
if data[radio .. '_mesh_enabled'] == '0' then
disabled = 1
end
uci:set('wireless', 'mesh_' .. radio, "disabled", disabled)
end
if uci:get('wireless', 'ibss_' .. radio) then
local disabled = 0
if data[radio .. '_ibss_enabled'] == '0' then
disabled = 1
end
uci:set('wireless', 'ibss_' .. radio, "disabled", disabled)
end
if data[radio .. '_txpower'] then
if data[radio .. '_txpower'] == 'default' then
uci:delete('wireless', radio, 'txpower')
else
uci:set('wireless', radio, 'txpower', data[radio .. '_txpower'])
end
end
end
uci:save('wireless')
uci:commit('wireless')
end
end
return f

View File

@ -15,7 +15,7 @@ define Package/gluon-setup-mode
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Setup mode
DEPENDS:=+gluon-core +luci-base +uhttpd +dnsmasq
DEPENDS:=+gluon-core +gluon-web +ubus +uhttpd +dnsmasq
PROVIDES:=gluon-setup-mode-virtual
endef

View File

@ -10,9 +10,7 @@ boot() {
uci set 'gluon-setup-mode.@setup_mode[0].enabled=0'
uci commit gluon-setup-mode
if [ "$enabled" = 1 -o "$configured" != 1 ]; then
lua -e 'uci_state=require("luci.model.uci").cursor_state(); uci_state:section("gluon-setup-mode", "setup_mode", nil, { running = "1" }); uci_state:save("gluon-setup-mode")'
else
if [ "$enabled" != 1 -a "$configured" = 1 ]; then
# This can happen after an upgrade from a version before the config file was called gluon-setup-mode
# We'll just reboot to return to the normal mode...
/etc/init.d/done boot

View File

@ -9,6 +9,6 @@ UHTTPD_BIN="/usr/sbin/uhttpd"
start_service() {
procd_open_instance
procd_set_param respawn
procd_set_param command "$UHTTPD_BIN" -f -h /lib/gluon/setup-mode/www -x /cgi-bin -A 1 -R -p 0.0.0.0:80
procd_set_param command "$UHTTPD_BIN" -f -h /lib/gluon/web/www -x /cgi-bin -A 1 -R -p 0.0.0.0:80
procd_close_instance
}

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="refresh" content="0; URL=/cgi-bin/luci" />
</head>
<body style="background-color: black">
<a style="color: white; text-decoration: none" href="/cgi-bin/luci">LuCI - Lua Configuration Interface</a>
</body>
</html>

View File

@ -1 +0,0 @@
/www/luci-static

View File

@ -1,5 +0,0 @@
#!/usr/bin/lua
require "luci.cacheloader"
require "luci.sgi.cgi"
luci.dispatcher.indexcache = "/tmp/luci-indexcache"
luci.sgi.cgi.run()

View File

@ -3,7 +3,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-luci-admin
PKG_NAME:=gluon-web-admin
PKG_VERSION:=1
PKG_RELEASE:=1
@ -14,10 +14,10 @@ include ../gluon.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-luci-admin
define Package/gluon-web-admin
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci based simple administration interface for mesh nodes
TITLE:=Web-based simple administration interface for mesh nodes
DEPENDS:=gluon-config-mode-core-virtual +pretty-hostname
endef
@ -29,14 +29,14 @@ define Build/Configure
endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-admin,i18n)
$(call GluonBuildI18N,gluon-web-admin,i18n)
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-admin/install
define Package/gluon-web-admin/install
$(CP) ./files/* $(1)/
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-admin,$(1))
$(call GluonInstallI18N,gluon-web-admin,$(1))
endef
$(eval $(call BuildPackage,gluon-luci-admin))
$(eval $(call BuildPackage,gluon-web-admin))

View File

@ -1,24 +1,23 @@
<%-
local fs = require 'nixio.fs'
local uci = require('simple-uci').cursor()
local util = require 'luci.util'
local i18n = require 'luci.i18n'
local lutil = require 'gluon.web.util'
local pretty_hostname = require 'pretty_hostname'
local gluon_luci = require "gluon.luci"
local site = require 'gluon.site_config'
local sysconfig = require 'gluon.sysconfig'
local platform = require 'gluon.platform'
local util = require "gluon.util"
local keys = {
hostname = i18n.translate('Hostname'),
primary_mac = i18n.translate('MAC address'),
model = i18n.translate('Hardware model'),
version = i18n.translate('Gluon version'),
release = i18n.translate('Firmware release'),
site = i18n.translate('Site'),
pubkey = i18n.translate('Public VPN key'),
hostname = translate('Hostname'),
primary_mac = translate('MAC address'),
model = translate('Hardware model'),
version = translate('Gluon version'),
release = translate('Firmware release'),
site = translate('Site'),
pubkey = translate('Public VPN key'),
}
local values = {
@ -33,7 +32,7 @@
local meshvpn_enabled = uci:get_bool("fastd", "mesh_vpn", "enabled")
if meshvpn_enabled then
local pubkey = util.trim(util.exec('/etc/init.d/fastd show_key mesh_vpn'))
local pubkey = util.trim(lutil.exec('/etc/init.d/fastd show_key mesh_vpn'))
if pubkey ~= '' then
values.pubkey = pubkey
end
@ -41,7 +40,7 @@
-%>
<h2><%:Information%></h2>
<% for _, key in ipairs({'hostname', 'primary_mac', 'model', 'version', 'release', 'site', 'pubkey'}) do %>
<div class="cbi-value">
<div class="cbi-value-title"><%=keys[key]%></div><div class="cbi-value-field"><%=gluon_luci.escape(values[key] or 'n/a')%></div>
<div class="gluon-value">
<div class="gluon-value-title"><%=keys[key]%></div><div class="gluon-value-field"><%=pcdata(values[key] or 'n/a')%></div>
</div>
<% end %>

View File

@ -1,5 +1,4 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008-2009 Jo-Philipp Wich <xm@subsignal.org>
@ -12,44 +11,40 @@ You may obtain a copy of the License at
$Id$
-%>
<%+header%>
<h2><%:Upgrade firmware%></h2>
<form method="post" action="<%=REQUEST_URI%>" enctype="multipart/form-data">
<form method="post" enctype="multipart/form-data" action="<%=url(request)%>">
<p>
<%:You can manually upgrade your firmware here.%>
</p>
<% if bad_image then %>
<p class="error"><%:The provided firmware image is not valid for this device.%></p>
<% end %>
<div class="cbi-section-node">
<div class="cbi-value">
<label class="cbi-value-title">
<div class="gluon-section-node">
<div class="gluon-value">
<label class="gluon-value-title">
<%:Firmware image%>
</label>
<div class="cbi-value-field">
<input class="cbi-input-file" type="file" name="image" />
<div class="gluon-value-field">
<input class="gluon-input-file" type="file" name="image" />
</div>
</div>
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title">
<div class="gluon-value gluon-value-last">
<label class="gluon-value-title">
<%:Keep settings%>
</label>
<div class="cbi-value-field">
<input id="keepcfg" class="cbi-input-checkbox" type="checkbox" name="keepcfg" value="1" checked="checked" />
<div class="gluon-value-field">
<input id="keepcfg" class="gluon-input-checkbox" type="checkbox" name="keepcfg" value="1" checked="checked" />
<label for="keepcfg"></label>
</div>
</div>
</div>
<div class="cbi-page-actions right">
<div class="gluon-page-actions right">
<input type="hidden" name="step" value="2" />
<input type="hidden" name="token" value="<%=token%>" />
<input class="cbi-button cbi-button-apply" type="submit" value="<%:Upload image%>" />
<input class="gluon-button gluon-button-submit" type="submit" value="<%:Upload image%>" />
</div>
</form>
<%+footer%>

View File

@ -1,5 +1,4 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008-2009 Jo-Philipp Wich <xm@subsignal.org>
@ -8,13 +7,8 @@ you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
-%>
<%+header%>
<h2><%:Upgrade firmware%></h2>
<p>
@ -43,7 +37,7 @@ $Id$
write(byte_format(filesize))
if flashsize > 0 then
write(luci.i18n.translatef(
write(translatef(
" (%s available)",
byte_format(flashsize)
))
@ -51,18 +45,17 @@ $Id$
%></li>
</ul>
</p>
<div class="cbi-page-actions">
<form method="post" action="<%=REQUEST_URI%>" style="display:inline">
<div class="gluon-page-actions">
<form method="post" enctype="multipart/form-data" action="<%=url(request)%>" style="display:inline">
<input type="hidden" name="step" value="3" />
<input type="hidden" name="keepcfg" value="<%=keepconfig and "1" or "0"%>" />
<input type="hidden" name="token" value="<%=token%>" />
<input class="cbi-button cbi-button-apply" type="submit" value="<%:Continue%>" />
<input class="gluon-button gluon-button-submit" type="submit" value="<%:Continue%>" />
</form>
<form method="post" action="<%=REQUEST_URI%>" style="display:inline">
<form method="post" enctype="multipart/form-data" action="<%=url(request)%>" style="display:inline">
<input type="hidden" name="step" value="1" />
<input type="hidden" name="keepcfg" value="<%=keepconfig and "1" or "0"%>" />
<input type="hidden" name="token" value="<%=token%>" />
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Cancel%>" />
<input class="gluon-button gluon-button-reset" type="submit" value="<%:Cancel%>" />
</form>
</div>
<%+footer%>

View File

@ -0,0 +1,5 @@
<p>
<%:The firmware is currently being upgraded.%>
<strong><%:Don't switch off the device in any circumstance!%></strong>
<%:The upgrade will take a few minutes. When it is finished, your node will reboot automatically.%>
</p>

View File

@ -10,6 +10,12 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "(%s available)"
msgstr "(%s verfügbar)"
msgid "Advanced settings"
msgstr "Erweiterte Einstellungen"
msgid ""
"Alternatively, you can set a password to access you node. Please choose a "
"secure password you don't use anywhere else.<br /><br />If you set an empty "
@ -20,15 +26,18 @@ msgstr ""
"leeren Passworts wird der Login per Passwort gesperrt (dies ist die Standard-"
"Einstellung)."
msgid "Cancel"
msgstr "Abbrechen"
msgid "Confirmation"
msgstr "Bestätigung"
msgid "Continue"
msgstr "Fortfahren"
msgid "Don't switch off the device in any circumstance!"
msgstr "Unterbrich auf keinen Fall die Stromversorgung!"
msgid "Advanced settings"
msgstr "Erweiterte Einstellungen"
msgid "Firmware image"
msgstr "Firmware-Datei"
@ -41,12 +50,21 @@ msgstr "Gluon-Version"
msgid "Hardware model"
msgstr "Hardware-Modell"
msgid "Hostname"
msgstr "Hostname"
msgid "Information"
msgstr "Info"
msgid "Keep settings"
msgstr "Konfiguration behalten"
msgid "MAC address"
msgstr "MAC-Adresse"
msgid "Password"
msgstr "Passwort"
msgid "Password changed."
msgstr "Passwort geändert."
@ -65,6 +83,9 @@ msgstr "SSH-Schlüssel"
msgid "Site"
msgstr "Site"
msgid "Size"
msgstr "Größe"
msgid ""
"The firmware image has been transmitted. Please ensure the MD5 checksum and "
"image size are correct and click \"continue\"."
@ -97,9 +118,6 @@ msgstr "Das Passwort konnte nicht geändert werden."
msgid "Upgrade firmware"
msgstr "Firmware aktualisieren"
msgid "Upgrading firmware"
msgstr "Firmware wird aktualisiert"
msgid "Upload image"
msgstr "Datei hochladen"

View File

@ -10,6 +10,12 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "(%s available)"
msgstr ""
msgid "Advanced settings"
msgstr "Paramètres avancés"
msgid ""
"Alternatively, you can set a password to access you node. Please choose a "
"secure password you don't use anywhere else.<br /><br />If you set an empty "
@ -21,15 +27,18 @@ msgstr ""
"par mot de passe sera désactivée. La connexion par mot de passe est "
"désactivée par défaut."
msgid "Cancel"
msgstr "Annuler"
msgid "Confirmation"
msgstr "Confirmation"
msgid "Continue"
msgstr "Continuer"
msgid "Don't switch off the device in any circumstance!"
msgstr "N'interrompez en aucun cas l'alimentation!"
msgid "Advanced settings"
msgstr "Paramètres avancés"
msgid "Firmware image"
msgstr "Fichier image"
@ -42,12 +51,21 @@ msgstr "Version de Gluon"
msgid "Hardware model"
msgstr "Modèle du Matériel"
msgid "Hostname"
msgstr "Nom d'hôte"
msgid "Information"
msgstr "Informations"
msgid "Keep settings"
msgstr "Garder le paramètrage"
msgid "MAC address"
msgstr "Adresse MAC"
msgid "Password"
msgstr "Mot de passe"
msgid "Password changed."
msgstr "Mot de passe changé."
@ -66,6 +84,9 @@ msgstr "Clé SSH"
msgid "Site"
msgstr "Site"
msgid "Size"
msgstr "Taille"
msgid ""
"The firmware image has been transmitted. Please ensure the MD5 checksum and "
"image size are correct and click \"continue\"."
@ -98,9 +119,6 @@ msgstr "Le mot de passe n'a pas pu être changé."
msgid "Upgrade firmware"
msgstr "Mettre à jour la firmware"
msgid "Upgrading firmware"
msgstr "Mise à jour de la firmware"
msgid "Upload image"
msgstr "Transférer l'image"

View File

@ -1,21 +1,30 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "(%s available)"
msgstr ""
msgid "Advanced settings"
msgstr ""
msgid ""
"Alternatively, you can set a password to access you node. Please choose a "
"secure password you don't use anywhere else.<br /><br />If you set an empty "
"password, login via password will be disabled. This is the default."
msgstr ""
msgid "Cancel"
msgstr ""
msgid "Confirmation"
msgstr ""
msgid "Continue"
msgstr ""
msgid "Don't switch off the device in any circumstance!"
msgstr ""
msgid "Advanced settings"
msgstr ""
msgid "Firmware image"
msgstr ""
@ -28,12 +37,21 @@ msgstr ""
msgid "Hardware model"
msgstr ""
msgid "Hostname"
msgstr ""
msgid "Information"
msgstr ""
msgid "Keep settings"
msgstr ""
msgid "MAC address"
msgstr ""
msgid "Password"
msgstr ""
msgid "Password changed."
msgstr ""
@ -52,6 +70,9 @@ msgstr ""
msgid "Site"
msgstr ""
msgid "Size"
msgstr ""
msgid ""
"The firmware image has been transmitted. Please ensure the MD5 checksum and "
"image size are correct and click \"continue\"."
@ -80,9 +101,6 @@ msgstr ""
msgid "Upgrade firmware"
msgstr ""
msgid "Upgrading firmware"
msgstr ""
msgid "Upload image"
msgstr ""

View File

@ -0,0 +1,9 @@
local root = node()
if not root.target then
root.target = alias("admin")
end
entry({"admin"}, alias("admin", "info"), _("Advanced settings"), 10)
entry({"admin", "info"}, template("admin/info"), _("Information"), 1)
entry({"admin", "remote"}, model("admin/remote"), _("Remote access"), 10)

View File

@ -0,0 +1,139 @@
--[[
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
]]--
local fs = require 'nixio.fs'
local tmpfile = "/tmp/firmware.img"
local function filehandler(meta, chunk, eof)
if not fs.access(tmpfile) and not file and chunk and #chunk > 0 then
file = io.open(tmpfile, "w")
end
if file and chunk then
file:write(chunk)
end
if file and eof then
file:close()
end
end
local function action_upgrade(http, renderer)
local disp = require 'gluon.web.dispatcher'
local nixio = require 'nixio'
local function fork_exec(...)
local pid = nixio.fork()
if pid > 0 then
return
elseif pid == 0 then
-- change to root dir
nixio.chdir("/")
-- patch stdin, out, err to /dev/null
local null = nixio.open("/dev/null", "w+")
if null then
nixio.dup(null, nixio.stderr)
nixio.dup(null, nixio.stdout)
nixio.dup(null, nixio.stdin)
if null:fileno() > 2 then
null:close()
end
end
-- Sleep a little so the browser can fetch everything required to
-- display the reboot page, then reboot the device.
nixio.nanosleep(1)
-- replace with target command
nixio.exec(...)
end
end
local function image_supported(tmpfile)
-- XXX: yay...
return (os.execute(string.format("/sbin/sysupgrade -T %q >/dev/null", tmpfile)) == 0)
end
local function storage_size()
local size = 0
if fs.access("/proc/mtd") then
for l in io.lines("/proc/mtd") do
local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)"')
if n == "linux" then
size = tonumber(s, 16)
break
end
end
elseif fs.access("/proc/partitions") then
for l in io.lines("/proc/partitions") do
local x, y, b, n = l:match('^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+)')
if b and n and not n:match('[0-9]') then
size = tonumber(b) * 1024
break
end
end
end
return size
end
local function image_checksum(tmpfile)
return (gluon.web.util.exec(string.format("md5sum %q", tmpfile)):match("^([^%s]+)"))
end
-- Determine state
local step = tonumber(http:getenv("REQUEST_METHOD") == "POST" and http:formvalue("step")) or 1
local has_image = fs.access(tmpfile)
local has_support = has_image and image_supported(tmpfile)
-- Step 1: file upload, error on unsupported image format
if step == 1 or not has_support then
-- If there is an image but user has requested step 1
-- or type is not supported, then remove it.
if has_image then
fs.unlink(tmpfile)
end
renderer.render("layout", {
content = "admin/upgrade",
bad_image = has_image and not has_support,
})
-- Step 2: present uploaded file, show checksum, confirmation
elseif step == 2 then
renderer.render("layout", {
content = "admin/upgrade_confirm",
checksum = image_checksum(tmpfile),
filesize = fs.stat(tmpfile).size,
flashsize = storage_size(),
keepconfig = (http:formvalue("keepcfg") == "1"),
})
elseif step == 3 then
if http:formvalue("keepcfg") == "1" then
fork_exec("/sbin/sysupgrade", tmpfile)
else
fork_exec("/sbin/sysupgrade", "-n", tmpfile)
end
renderer.render("layout", {
content = "admin/upgrade_reboot",
hidenav = true,
})
end
end
local has_platform = fs.access("/lib/upgrade/platform.sh")
if has_platform then
local upgrade = entry({"admin", "upgrade"}, call(action_upgrade), _("Upgrade firmware"), 90)
upgrade.filehandler = filehandler
end

View File

@ -0,0 +1,109 @@
--[[
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2011 Jo-Philipp Wich <xm@subsignal.org>
Copyright 2013 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
]]--
local nixio = require "nixio"
local fs = require "nixio.fs"
local util = require "gluon.util"
local f_keys = Form(translate("SSH keys"), translate("You can provide your SSH keys here (one per line):"), 'keys')
local s = f_keys:section(Section)
local keys = s:option(TextValue, "keys")
keys.wrap = "off"
keys.rows = 5
keys.default = fs.readfile("/etc/dropbear/authorized_keys") or ""
function keys:write(value)
value = util.trim(value:gsub("\r", ""))
if value ~= "" then
fs.writefile("/etc/dropbear/authorized_keys", value .. "\n")
else
fs.remove("/etc/dropbear/authorized_keys")
end
end
local f_password = Form(translate("Password"),
translate(
"Alternatively, you can set a password to access you node. Please choose a secure password you don't use anywhere else.<br /><br />"
.. "If you set an empty password, login via password will be disabled. This is the default."
), 'password'
)
f_password.reset = false
local s = f_password:section(Section)
local pw1 = s:option(Value, "pw1", translate("Password"))
pw1.password = true
function pw1.cfgvalue()
return ''
end
local pw2 = s:option(Value, "pw2", translate("Confirmation"))
pw2.password = true
function pw2.cfgvalue()
return ''
end
local function set_password(password)
local inr, inw = nixio.pipe()
local pid = nixio.fork()
if pid < 0 then
return false
elseif pid == 0 then
inw:close()
local null = nixio.open('/dev/null', 'w')
nixio.dup(null, nixio.stderr)
nixio.dup(null, nixio.stdout)
if null:fileno() > 2 then
null:close()
end
nixio.dup(inr, nixio.stdin)
inr:close()
nixio.execp('passwd')
os.exit(127)
end
inr:close()
inw:write(string.format('%s\n%s\n', password, password))
inw:close()
local wpid, status, code = nixio.waitpid(pid)
return wpid and status == 'exited' and code == 0
end
function f_password:write()
if pw1.data ~= pw2.data then
f_password.errmessage = translate("The password and the confirmation differ.")
return
end
local pw = pw1.data
if #pw > 0 then
if set_password(pw) then
f_password.message = translate("Password changed.")
else
f_password.errmessage = translate("Unable to change the password.")
end
else
-- We don't check the return code here as the error 'password for root is already locked' is normal...
os.execute('passwd -l root >/dev/null')
f_password.message = translate("Password removed.")
end
end
return f_keys, f_password

View File

@ -3,7 +3,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-luci-autoupdater
PKG_NAME:=gluon-web-autoupdater
PKG_VERSION:=1
PKG_RELEASE:=1
@ -14,11 +14,11 @@ include ../gluon.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-luci-autoupdater
define Package/gluon-web-autoupdater
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci module for gluon-autoupdater
DEPENDS:=+gluon-luci-admin +gluon-autoupdater
TITLE:=gluon-web module for gluon-autoupdater
DEPENDS:=+gluon-web-admin +gluon-autoupdater
endef
define Build/Prepare
@ -29,13 +29,13 @@ define Build/Configure
endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-autoupdater,i18n)
$(call GluonBuildI18N,gluon-web-autoupdater,i18n)
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-autoupdater/install
define Package/gluon-web-autoupdater/install
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-autoupdater,$(1))
$(call GluonInstallI18N,gluon-web-autoupdater,$(1))
endef
$(eval $(call BuildPackage,gluon-luci-autoupdater))
$(eval $(call BuildPackage,gluon-web-autoupdater))

View File

@ -1,12 +1,12 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2015-05-04 01:55+0200\n"
"Last-Translator: <mschiffer@universe-factory.net>\n"
"Language-Team: German\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@ -15,3 +15,6 @@ msgstr "Automatische Updates"
msgid "Branch"
msgstr "Branch"
msgid "Enable"
msgstr "Aktivieren"

View File

@ -1,12 +1,12 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2015-08-19 20:20+0100\n"
"Last-Translator: Bernot Tobias <tqbs@airmail.cc>\n"
"Language-Team: French\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@ -15,3 +15,6 @@ msgstr "Mise a jour automatique"
msgid "Branch"
msgstr "Branche"
msgid "Enable"
msgstr "Activer"

View File

@ -6,3 +6,6 @@ msgstr ""
msgid "Branch"
msgstr ""
msgid "Enable"
msgstr ""

View File

@ -0,0 +1 @@
entry({"admin", "autoupdater"}, model("admin/autoupdater"), _("Automatic updates"), 80)

View File

@ -1,6 +1,4 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2013 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
@ -8,20 +6,20 @@ you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local uci = require("simple-uci").cursor()
local autoupdater = uci:get_first("autoupdater", "autoupdater")
local f = SimpleForm("autoupdater", translate("Automatic updates"))
local s = f:section(SimpleSection, nil, nil)
local f = Form(translate("Automatic updates"))
local s = f:section(Section)
local o
o = s:option(Flag, "enabled", translate("Enable"))
o.default = uci:get_bool("autoupdater", autoupdater, "enabled") and o.enabled or o.disabled
o.rmempty = false
o.default = uci:get_bool("autoupdater", autoupdater, "enabled")
function o:write(data)
uci:set("autoupdater", autoupdater, "enabled", data)
end
o = s:option(ListValue, "branch", translate("Branch"))
uci:foreach("autoupdater", "branch",
@ -30,16 +28,11 @@ uci:foreach("autoupdater", "branch",
end
)
o.default = uci:get("autoupdater", autoupdater, "branch")
function o:write(data)
uci:set("autoupdater", autoupdater, "branch", data)
end
function f.handle(self, state, data)
if state ~= FORM_VALID then
return
end
uci:set("autoupdater", autoupdater, "enabled", data.enabled)
uci:set("autoupdater", autoupdater, "branch", data.branch)
uci:save("autoupdater")
function f:write()
uci:commit("autoupdater")
end

View File

@ -1,6 +1,6 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-luci-mesh-vpn-fastd
PKG_NAME:=gluon-web-mesh-vpn-fastd
PKG_VERSION:=1
PKG_RELEASE:=1
@ -11,11 +11,11 @@ include ../gluon.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-luci-mesh-vpn-fastd
define Package/gluon-web-mesh-vpn-fastd
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci module to enable and disable encryption for the mesh VPN
DEPENDS:=+gluon-luci-admin +gluon-mesh-vpn-fastd
TITLE:=gluon-web module to enable and disable encryption for the mesh VPN
DEPENDS:=+gluon-web-admin +gluon-mesh-vpn-fastd
endef
define Build/Prepare
@ -30,15 +30,15 @@ define Build/Compile
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-mesh-vpn-fastd/install
define Package/gluon-web-mesh-vpn-fastd/install
$(CP) ./files/* $(1)/
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-mesh-vpn-fastd,$(1))
endef
define Package/gluon-luci-mesh-vpn-fastd/postinst
define Package/gluon-web-mesh-vpn-fastd/postinst
#!/bin/sh
$(call GluonCheckSite,check_site.lua)
endef
$(eval $(call BuildPackage,gluon-luci-mesh-vpn-fastd))
$(eval $(call BuildPackage,gluon-web-mesh-vpn-fastd))

View File

@ -0,0 +1,32 @@
<div class="gluon-value">
<div class="gluon-value-title">
<input class="gluon-input-radio" data-update="change" type="radio" value="security"<%= attr("id", id..'1') .. attr("name", id) .. attr("checked", ((self:cfgvalue() or self.default) == "security") and "checked") %> />
</div>
<div class="gluon-value-field-long">
<label<%= attr("for", id..'1') %> class="gluon-value-title"><%:Security mode%></label>
<br />
<%= translate(
'In security mode, the mesh VPN uses an encrypted tunnel to connect to the VPN servers. ' ..
'The encryption ensures that it is impossible for your internet access provider to see what ' ..
'data is exchanged over your node.'
) %>
<br />
</div>
<div class="gluon-value-field-long-after"></div>
</div>
<div class="gluon-value gluon-value-last">
<div class="gluon-value-title">
<input class="gluon-input-radio" data-update="change" type="radio" value="performance"<%= attr("id", id..'2') .. attr("name", id) .. attr("checked", ((self:cfgvalue() or self.default) == "performance") and "checked") %> />
</div>
<div class="gluon-value-field-long">
<label<%= attr("for", id..'2') %> class="gluon-value-title"><%:Performance mode%></label>
<br />
<%= translate(
'In performance mode, no encryption is used. This usually allows for higher throughput, but the data exchanged over your node is not ' ..
'protected against eavesdropping.'
) %>
<br />
</div>
<div class="gluon-value-field-long-after"></div>
</div>

View File

@ -15,7 +15,7 @@ msgid ""
"throughput, but the data exchanged over your node is not protected against "
"eavesdropping."
msgstr ""
"Im Modus &bdquo;Hohe Geschwindigkeit&ldquo; wird auf Verschlüsselung "
"Im Modus „Hohe Geschwindigkeit“ wird auf Verschlüsselung "
"verzichtet. Dies erlaubt häufig eine höhere Bandbreite als mit "
"Verschlüsselung, aber die Verbindung ist nicht gegen Abhören geschützt."
@ -24,7 +24,7 @@ msgid ""
"VPN servers. The encryption ensures that it is impossible for your internet "
"access provider to see what data is exchanged over your node."
msgstr ""
"Im Modus &bdquo;Hohe Sicherheit&ldquo; wird ein verschlüsselter Tunnel "
"Im Modus „Hohe Sicherheit“ wird ein verschlüsselter Tunnel "
"verwendet. Dies schließt aus, dass dein Internetzugangsprovider herausfinden "
"kann, was für Daten über deinen Knoten übertragen werden."

View File

@ -0,0 +1 @@
entry({"admin", "mesh_vpn_fastd"}, model("admin/mesh_vpn_fastd"), _("Mesh VPN"), 20)

View File

@ -0,0 +1,38 @@
local uci = require("simple-uci").cursor()
local util = gluon.web.util
local f = Form(translate('Mesh VPN'))
local s = f:section(Section)
local mode = s:option(Value, 'mode')
mode.template = "gluon/model/mesh-vpn-fastd"
local methods = uci:get('fastd', 'mesh_vpn', 'method')
if util.contains(methods, 'null') then
mode.default = 'performance'
else
mode.default = 'security'
end
function mode:write(data)
local site = require 'gluon.site_config'
local methods = {}
if data == 'performance' then
table.insert(methods, 'null')
end
for _, method in ipairs(site.fastd_mesh_vpn.methods) do
if method ~= 'null' then
table.insert(methods, method)
end
end
uci:set('fastd', 'mesh_vpn', 'method', methods)
uci:save('fastd')
uci:commit('fastd')
end
return f

View File

@ -3,7 +3,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-luci-portconfig
PKG_NAME:=gluon-web-network
PKG_VERSION:=1
PKG_RELEASE:=1
@ -14,11 +14,11 @@ include ../gluon.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-luci-portconfig
define Package/gluon-web-network
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci module for advanced ethernet port configuration
DEPENDS:=+gluon-luci-admin +gluon-client-bridge
TITLE:=gluon-web module for network port configuration
DEPENDS:=+gluon-web-admin +gluon-client-bridge
endef
define Build/Prepare
@ -29,13 +29,13 @@ define Build/Configure
endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-portconfig,i18n)
$(call GluonBuildI18N,gluon-web-network,i18n)
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-portconfig/install
define Package/gluon-web-network/install
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-portconfig,$(1))
$(call GluonInstallI18N,gluon-web-network,$(1))
endef
$(eval $(call BuildPackage,gluon-luci-portconfig))
$(eval $(call BuildPackage,gluon-web-network))

View File

@ -16,6 +16,9 @@ msgstr "Automatisch (DHCP)"
msgid "Automatic (RA/DHCPv6)"
msgstr "Automatisch (RA/DHCPv6)"
msgid "Disabled"
msgstr "Deaktiviert"
msgid "Enable PoE passthrough"
msgstr "PoE-Passthrough aktivieren"
@ -25,6 +28,24 @@ msgstr "Mesh auf dem LAN-Port aktivieren"
msgid "Enable meshing on the WAN interface"
msgstr "Mesh auf dem WAN-Port aktivieren"
msgid "Gateway"
msgstr "Gateway"
msgid "IP address"
msgstr "IP-Adresse"
msgid "IPv4"
msgstr "IPv4"
msgid "IPv6"
msgstr "IPv6"
msgid "Netmask"
msgstr "Netzmaske"
msgid "Network"
msgstr "Netzwerk"
msgid "Static"
msgstr "Statisch"

View File

@ -16,6 +16,9 @@ msgstr "Automatique (DHCP)"
msgid "Automatic (RA/DHCPv6)"
msgstr "Automatique (RA/DHCPv6)"
msgid "Disabled"
msgstr "Désactivé"
msgid "Enable PoE passthrough"
msgstr ""
@ -25,6 +28,24 @@ msgstr "Activer le réseau MESH sur le port LAN"
msgid "Enable meshing on the WAN interface"
msgstr "Activer le réseau MESH sur les ports WAN"
msgid "Gateway"
msgstr "Passerelle"
msgid "IP address"
msgstr "Adresse IP"
msgid "IPv4"
msgstr "IPv4"
msgid "IPv6"
msgstr "IPv6"
msgid "Netmask"
msgstr "Masque de réseau"
msgid "Network"
msgstr "Réseau"
msgid "Static"
msgstr "Statique"

View File

@ -7,6 +7,9 @@ msgstr ""
msgid "Automatic (RA/DHCPv6)"
msgstr ""
msgid "Disabled"
msgstr ""
msgid "Enable PoE passthrough"
msgstr ""
@ -16,6 +19,24 @@ msgstr ""
msgid "Enable meshing on the WAN interface"
msgstr ""
msgid "Gateway"
msgstr ""
msgid "IP address"
msgstr ""
msgid "IPv4"
msgstr ""
msgid "IPv6"
msgstr ""
msgid "Netmask"
msgstr ""
msgid "Network"
msgstr ""
msgid "Static"
msgstr ""

View File

@ -0,0 +1 @@
entry({"admin", "network"}, model("admin/network"), _("Network"), 20)

View File

@ -0,0 +1,143 @@
--[[
Copyright 2014 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
]]--
local uci = require("simple-uci").cursor()
local sysconfig = require 'gluon.sysconfig'
local util = require 'gluon.util'
local wan = uci:get_all("network", "wan")
local wan6 = uci:get_all("network", "wan6")
local dns_static = uci:get_first("gluon-wan-dnsmasq", "static")
local f = Form(translate("WAN connection"))
local s = f:section(Section)
local ipv4 = s:option(ListValue, "ipv4", translate("IPv4"))
ipv4:value("dhcp", translate("Automatic (DHCP)"))
ipv4:value("static", translate("Static"))
ipv4:value("none", translate("Disabled"))
ipv4.default = wan.proto
local ipv4_addr = s:option(Value, "ipv4_addr", translate("IP address"))
ipv4_addr:depends(ipv4, "static")
ipv4_addr.default = wan.ipaddr
ipv4_addr.datatype = "ip4addr"
local ipv4_netmask = s:option(Value, "ipv4_netmask", translate("Netmask"))
ipv4_netmask:depends(ipv4, "static")
ipv4_netmask.default = wan.netmask or "255.255.255.0"
ipv4_netmask.datatype = "ip4addr"
local ipv4_gateway = s:option(Value, "ipv4_gateway", translate("Gateway"))
ipv4_gateway:depends(ipv4, "static")
ipv4_gateway.default = wan.gateway
ipv4_gateway.datatype = "ip4addr"
local s = f:section(Section)
local ipv6 = s:option(ListValue, "ipv6", translate("IPv6"))
ipv6:value("dhcpv6", translate("Automatic (RA/DHCPv6)"))
ipv6:value("static", translate("Static"))
ipv6:value("none", translate("Disabled"))
ipv6.default = wan6.proto
local ipv6_addr = s:option(Value, "ipv6_addr", translate("IP address"))
ipv6_addr:depends(ipv6, "static")
ipv6_addr.default = wan6.ip6addr
ipv6_addr.datatype = "ip6addr"
local ipv6_gateway = s:option(Value, "ipv6_gateway", translate("Gateway"))
ipv6_gateway:depends(ipv6, "static")
ipv6_gateway.default = wan6.ip6gw
ipv6_gateway.datatype = "ip6addr"
if dns_static then
local s = f:section(Section)
local dns = s:option(DynamicList, "dns", translate("Static DNS servers"))
dns.default = uci:get_list("gluon-wan-dnsmasq", dns_static, "server")
dns.datatype = "ipaddr"
dns.optional = true
function dns:write(data)
uci:set_list("gluon-wan-dnsmasq", dns_static, "server", data)
uci:commit("gluon-wan-dnsmasq")
end
end
local s = f:section(Section)
local mesh_wan = s:option(Flag, "mesh_wan", translate("Enable meshing on the WAN interface"))
mesh_wan.default = uci:get_bool("network", "mesh_wan", "auto")
function mesh_wan:write(data)
uci:set("network", "mesh_wan", "auto", data)
end
if sysconfig.lan_ifname then
local mesh_lan = s:option(Flag, "mesh_lan", translate("Enable meshing on the LAN interface"))
mesh_lan.default = uci:get_bool("network", "mesh_lan", "auto")
function mesh_lan:write(data)
uci:set("network", "mesh_lan", "auto", data)
local interfaces = uci:get_list("network", "client", "ifname")
for lanif in sysconfig.lan_ifname:gmatch('%S+') do
if data then
util.remove_from_set(interfaces, lanif)
else
util.add_to_set(interfaces, lanif)
end
end
uci:set_list("network", "client", "ifname", interfaces)
end
end
if uci:get('system', 'gpio_switch_poe_passthrough') then
local s = f:section(Section)
local poe_passthrough = s:option(Flag, "poe_passthrough", translate("Enable PoE passthrough"))
poe_passthrough.default = uci:get_bool("system", "gpio_switch_poe_passthrough", "value")
function poe_passthrough:write(data)
uci:set('system', 'gpio_switch_poe_passthrough', 'value', data)
end
end
function f:write()
uci:set("network", "wan", "proto", ipv4.data)
if ipv4.data == "static" then
uci:set("network", "wan", "ipaddr", ipv4_addr.data)
uci:set("network", "wan", "netmask", ipv4_netmask.data)
uci:set("network", "wan", "gateway", ipv4_gateway.data)
else
uci:delete("network", "wan", "ipaddr")
uci:delete("network", "wan", "netmask")
uci:delete("network", "wan", "gateway")
end
uci:set("network", "wan6", "proto", ipv6.data)
if ipv6.data == "static" then
uci:set("network", "wan6", "ip6addr", ipv6_addr.data)
uci:set("network", "wan6", "ip6gw", ipv6_gateway.data)
else
uci:delete("network", "wan6", "ip6addr")
uci:delete("network", "wan6", "ip6gw")
end
uci:commit("network")
uci:commit('system')
end
return f

View File

@ -1,6 +1,6 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-luci-node-role
PKG_NAME:=gluon-web-node-role
PKG_VERSION:=0.1
PKG_RELEASE:=1
@ -11,10 +11,10 @@ include ../gluon.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-luci-node-role
define Package/gluon-web-node-role
SECTION:=gluon
CATEGORY:=Gluon
DEPENDS:=+gluon-luci-admin +gluon-node-info
DEPENDS:=+gluon-web-admin +gluon-node-info
TITLE:=UI for specifying node role
endef
@ -26,18 +26,18 @@ define Build/Configure
endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-node-role,i18n)
$(call GluonBuildI18N,gluon-web-node-role,i18n)
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-node-role/install
define Package/gluon-web-node-role/install
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-node-role,$(1))
$(call GluonInstallI18N,gluon-web-node-role,$(1))
endef
define Package/gluon-luci-node-role/postinst
define Package/gluon-web-node-role/postinst
#!/bin/sh
$(call GluonCheckSite,check_site.lua)
endef
$(eval $(call BuildPackage,gluon-luci-node-role))
$(eval $(call BuildPackage,gluon-web-node-role))

View File

@ -0,0 +1 @@
entry({"admin", "noderole"}, model("admin/noderole"), "Node role", 20)

View File

@ -0,0 +1,28 @@
local f, s, o
local site = require 'gluon.site_config'
local uci = require("simple-uci").cursor()
local config = 'gluon-node-info'
-- where to read the configuration from
local role = uci:get(config, uci:get_first(config, "system"), "role")
f = Form(translate("Node role"))
s = f:section(Section, nil, translate(
"If this node has a special role within the freifunk network you can specify this role here. "
.. "Please find out about the available roles and their impact first. "
.. "Only change the role if you know what you are doing."
))
o = s:option(ListValue, "role", translate("Role"))
o.default = role
for _, role in ipairs(site.roles.list) do
o:value(role, translate('gluon-web-node-role:role:' .. role))
end
function o:write(data)
uci:set(config, uci:get_first(config, "system"), "role", data)
uci:commit(config)
end
return f

View File

@ -1,6 +1,6 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-luci-private-wifi
PKG_NAME:=gluon-web-private-wifi
PKG_VERSION:=1
PKG_RELEASE:=1
@ -11,10 +11,10 @@ include ../gluon.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-luci-private-wifi
define Package/gluon-web-private-wifi
SECTION:=gluon
CATEGORY:=Gluon
DEPENDS:=+gluon-luci-admin
DEPENDS:=+gluon-web-admin
TITLE:=UI for activating a private WLAN
endef
@ -26,13 +26,13 @@ define Build/Configure
endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-private-wifi,i18n)
$(call GluonBuildI18N,gluon-web-private-wifi,i18n)
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-private-wifi/install
define Package/gluon-web-private-wifi/install
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-private-wifi,$(1))
$(call GluonInstallI18N,gluon-web-private-wifi,$(1))
endef
$(eval $(call BuildPackage,gluon-luci-private-wifi))
$(eval $(call BuildPackage,gluon-web-private-wifi))

View File

@ -13,6 +13,12 @@ msgstr ""
msgid "8-63 characters"
msgstr "8-63 Zeichen"
msgid "Enabled"
msgstr "Aktiviert"
msgid "Key"
msgstr "Schlüssel"
msgid "Name (SSID)"
msgstr "Name (SSID)"

View File

@ -13,6 +13,12 @@ msgstr ""
msgid "8-63 characters"
msgstr "8-63 charactères"
msgid "Enabled"
msgstr "Activé"
msgid "Key"
msgstr "Clé"
msgid "Name (SSID)"
msgstr "Nom (SSID)"

View File

@ -4,6 +4,12 @@ msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "8-63 characters"
msgstr ""
msgid "Enabled"
msgstr ""
msgid "Key"
msgstr ""
msgid "Name (SSID)"
msgstr ""

View File

@ -0,0 +1 @@
entry({"admin", "privatewifi"}, model("admin/privatewifi"), _("Private WLAN"), 10)

View File

@ -0,0 +1,54 @@
local uci = require("simple-uci").cursor()
local util = require 'gluon.util'
-- where to read the configuration from
local primary_iface = 'wan_radio0'
local f = Form(translate("Private WLAN"))
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. '
.. 'Please note that the private WLAN and meshing on the WAN interface should not be enabled '
.. 'at the same time.'
))
local enabled = s:option(Flag, "enabled", translate("Enabled"))
enabled.default = (ssid and not uci:get_bool('wireless', primary_iface, "disabled"))
local ssid = s:option(Value, "ssid", translate("Name (SSID)"))
ssid:depends(enabled, true)
ssid.datatype = "maxlength(32)"
ssid.default = uci:get('wireless', primary_iface, "ssid")
local key = s:option(Value, "key", translate("Key"), translate("8-63 characters"))
key:depends(enabled, true)
key.datatype = "wpakey"
key.default = uci:get('wireless', primary_iface, "key")
function f:write()
util.iterate_radios(function(radio, index)
local name = "wan_" .. radio
if enabled.data then
local macaddr = util.get_wlan_mac(radio, index, 4)
uci:section('wireless', "wifi-iface", name, {
device = radio,
network = "wan",
mode = 'ap',
encryption = 'psk2',
ssid = ssid.data,
key = key.data,
macaddr = macaddr,
disabled = false,
})
else
uci:set('wireless', name, "disabled", true)
end
end)
uci:commit('wireless')
end
return f

View File

@ -3,7 +3,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-luci-theme
PKG_NAME:=gluon-web-theme
PKG_VERSION:=0.1
PKG_RELEASE:=1
@ -12,17 +12,13 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include ../gluon.mk
define Package/gluon-luci-theme
define Package/gluon-web-theme
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci theme for Gluon
TITLE:=gluon-web theme
DEPENDS:=+pretty-hostname
endef
define Package/gluon-luci-theme/description
Luci based config mode
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
@ -31,12 +27,10 @@ define Build/Configure
endef
define Build/Compile
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-theme/install
define Package/gluon-web-theme/install
$(CP) ./files/* $(1)/
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
$(eval $(call BuildPackage,gluon-luci-theme))
$(eval $(call BuildPackage,gluon-web-theme))

View File

@ -0,0 +1,122 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008-2010 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
-%>
<%
local uci = require("simple-uci").cursor()
local disp = require "gluon.web.dispatcher"
local fs = require "nixio.fs"
local pretty_hostname = require "pretty_hostname"
local hostname = pretty_hostname.get(uci)
local release = fs.readfile("/lib/gluon/release")
local root = node()
local rnode = node(unpack(request))
local category = request[1]
local cattree = category and node(category)
local categories = disp.node_children(root)
http:prepare_content("application/xhtml+xml")
local function append(xs, x)
local r = {unpack(xs)}
r[#r+1] = x
return r
end
local function subtree(prefix, node, name, ...)
if not node then return end
local children = disp.node_children(node)
if #children == 0 then return end
%>
<div class="tabmenu<%=#prefix%>">
<ul class="tabmenu l<%=#prefix%>">
<%
for i, v in ipairs(children) do
local child = node.nodes[v]
local active = (v == name)
%>
<li class="tabmenu-item-<%=v%><% if active then %> active<% end %>">
<a href="<%=url(append(prefix, v))%>"><%=pcdata(translate(child.title))%></a>
</li>
<%
end
%>
</ul>
<br style="clear:both" />
<%
subtree(append(prefix, name), node.nodes[name], ...)
%>
</div>
<%
end
local function menutree(path, ...)
subtree({path}, root.nodes[category], ...)
end
-%>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
<title><%=pcdata( hostname .. ( (rnode and rnode.title) and ' - ' .. translate(rnode.title) or '')) %></title>
</head>
<body>
<div id="menubar">
<div class="hostinfo">
<a href="<%=url({})%>">
<%=pcdata(hostname)%>
<% if release then %>
/ <%=pcdata(release)%>
<% end %>
</a>
</div>
<% if #categories > 1 and not hidenav then %>
<ul id="topmenu">
<% for i, r in ipairs(categories) do %>
<li><a class="topcat<% if request[1] == r then %> active<%end%>" href="<%=url({r})%>"><%=pcdata(translate(root.nodes[r].title))%></a></li>
<% end %>
</ul>
<% end %>
</div>
<div id="maincontainer">
<%
if not hidenav then
menutree(unpack(request))
end
%>
<div id="maincontent">
<noscript>
<div class="errorbox">
<strong><%:JavaScript required!%></strong><br />
<%:You must enable JavaScript in your browser or the web interface will not work properly.%>
</div>
</noscript>
<%
ok, err = pcall(include, content)
if not ok then
renderer.render('error500', {message = err})
end
%>
</div>
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More