treewide: convert all LuCI-based packages to gluon-web
This commit is contained in:
parent
e4b74be506
commit
31d3f08f25
2
Makefile
2
Makefile
@ -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)"' \
|
||||
|
@ -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
|
||||
|
||||
function M.handle(data)
|
||||
uci:set("system", uci:get_first("system", "system"), "hostname", data._hostname)
|
||||
uci:save("system")
|
||||
uci:commit("system")
|
||||
return {'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!")
|
||||
|
@ -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.
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
@ -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::
|
||||
|
||||
|
@ -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``.
|
||||
|
@ -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 \
|
||||
|
@ -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 = {
|
||||
|
@ -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
|
||||
|
@ -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.'))
|
||||
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
|
||||
|
@ -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(
|
||||
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
|
||||
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)
|
||||
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", uci:get_first("gluon-node-info", "owner"), "contact")
|
||||
uci:delete("gluon-node-info", owner, "contact")
|
||||
end
|
||||
end
|
||||
uci:save("gluon-node-info")
|
||||
uci:commit("gluon-node-info")
|
||||
end
|
||||
|
||||
return M
|
||||
return {'gluon-node-info'}
|
||||
end
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
%>
|
@ -0,0 +1,11 @@
|
||||
<%-
|
||||
local sysconfig = require 'gluon.sysconfig'
|
||||
-%>
|
||||
<p>
|
||||
<%=
|
||||
renderer.render_string(translate('gluon-config-mode:welcome'), {
|
||||
hostname = hostname,
|
||||
sysconfig = sysconfig,
|
||||
})
|
||||
%>
|
||||
</p>
|
@ -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 %>
|
@ -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>
|
@ -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, {
|
||||
renderer.render_string(msg, {
|
||||
hostname = hostname,
|
||||
site = site,
|
||||
sysconfig = sysconfig,
|
||||
contact = contact,
|
||||
escape = gluon_luci.escape,
|
||||
urlescape = gluon_luci.urlescape,
|
||||
})
|
||||
end
|
||||
})
|
||||
|
@ -0,0 +1,2 @@
|
||||
entry({}, alias("wizard"))
|
||||
entry({"wizard"}, model("gluon-config-mode/wizard"), _("Wizard"), 5)
|
@ -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
|
@ -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
|
@ -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
|
@ -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()
|
||||
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
|
||||
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.')
|
||||
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 .. ' ' .. i18n.translate("gluon-config-mode:altitude-help")
|
||||
text = text .. ' ' .. translate("gluon-config-mode:altitude-help")
|
||||
end
|
||||
local s = form:section(cbi.SimpleSection, nil, text)
|
||||
|
||||
local s = form:section(Section, 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
|
||||
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(cbi.Value, "_latitude", i18n.translate("Latitude"))
|
||||
o.default = uci:get_first("gluon-node-info", "location", "latitude")
|
||||
o:depends("_location", "1")
|
||||
o.rmempty = false
|
||||
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"
|
||||
o.description = i18n.translatef("e.g. %s", "53.873621")
|
||||
function o:write(data)
|
||||
uci:set("gluon-node-info", location, "latitude", data)
|
||||
end
|
||||
|
||||
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 = 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"
|
||||
o.description = i18n.translatef("e.g. %s", "10.689901")
|
||||
function o:write(data)
|
||||
uci:set("gluon-node-info", location, "longitude", data)
|
||||
end
|
||||
|
||||
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 = 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.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())
|
||||
o.optional = true
|
||||
function o:write(data)
|
||||
if data then
|
||||
uci:set("gluon-node-info", location, "altitude", data)
|
||||
else
|
||||
uci:delete("gluon-node-info", sname, "altitude")
|
||||
uci:delete("gluon-node-info", location, "altitude")
|
||||
end
|
||||
end
|
||||
end
|
||||
uci:save("gluon-node-info")
|
||||
uci:commit("gluon-node-info")
|
||||
end
|
||||
|
||||
return M
|
||||
return {'gluon-node-info'}
|
||||
end
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
return
|
||||
end
|
||||
|
||||
local gluon_luci = require 'gluon.luci'
|
||||
local site = require 'gluon.site_config'
|
||||
local sysconfig = require 'gluon.sysconfig'
|
||||
local lutil = require "gluon.web.util"
|
||||
|
||||
local pretty_hostname = require 'pretty_hostname'
|
||||
local site = require 'gluon.site_config'
|
||||
local sysconfig = require 'gluon.sysconfig'
|
||||
local util = require "gluon.util"
|
||||
|
||||
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 pretty_hostname = require 'pretty_hostname'
|
||||
|
||||
local msg = i18n.translate('gluon-config-mode:pubkey')
|
||||
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")
|
||||
|
||||
return function ()
|
||||
luci.template.render_string(msg, {
|
||||
local msg = translate('gluon-config-mode:pubkey')
|
||||
|
||||
renderer.render_string(msg, {
|
||||
pubkey = pubkey,
|
||||
hostname = hostname,
|
||||
site = site,
|
||||
sysconfig = sysconfig,
|
||||
contact = contact,
|
||||
escape = gluon_luci.escape,
|
||||
urlescape = gluon_luci.urlescape,
|
||||
})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
@ -1,64 +1,47 @@
|
||||
local cbi = require "luci.cbi"
|
||||
local i18n = require "luci.i18n"
|
||||
local uci = require("simple-uci").cursor()
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.section(form)
|
||||
local msg = i18n.translate('Your internet connection can be used to establish an ' ..
|
||||
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 s = form:section(cbi.SimpleSection, nil, msg)
|
||||
'much bandwidth the node will use at most.'
|
||||
)
|
||||
|
||||
local s = form:section(Section, nil, msg)
|
||||
|
||||
local o
|
||||
|
||||
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 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, "_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(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(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"
|
||||
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
|
||||
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._limit_enabled)
|
||||
uci:set("simple-tc", "mesh_vpn", "enabled", data)
|
||||
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())
|
||||
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
|
||||
|
||||
uci:save("simple-tc")
|
||||
uci:commit("simple-tc")
|
||||
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
|
||||
|
||||
return {'fastd', 'simple-tc'}
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -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>
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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>
|
@ -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
|
@ -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
|
@ -1,5 +0,0 @@
|
||||
module("luci.controller.admin.noderole", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "noderole"}, cbi("admin/noderole"), "Node role", 20)
|
||||
end
|
@ -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
|
@ -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
|
@ -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
|
@ -1,5 +0,0 @@
|
||||
module("luci.controller.admin.privatewifi", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "privatewifi"}, cbi("admin/privatewifi"), _("Private WLAN"), 10)
|
||||
end
|
@ -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
|
@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
uci batch <<-EOF
|
||||
set luci.themes.Gluon=/luci-static/gluon
|
||||
commit luci
|
||||
EOF
|
||||
|
@ -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>
|
@ -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
@ -1,28 +0,0 @@
|
||||
-- Config mode utility functions
|
||||
|
||||
local string = string
|
||||
|
||||
module 'gluon.luci'
|
||||
|
||||
function escape(s)
|
||||
return (string.gsub(s, '[<>&"]', {
|
||||
['<'] = '<',
|
||||
['>'] = '>',
|
||||
['&'] = '&',
|
||||
['"'] = '"',
|
||||
}))
|
||||
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
@ -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
|
@ -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
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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>
|
@ -1 +0,0 @@
|
||||
/www/luci-static
|
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/lua
|
||||
require "luci.cacheloader"
|
||||
require "luci.sgi.cgi"
|
||||
luci.dispatcher.indexcache = "/tmp/luci-indexcache"
|
||||
luci.sgi.cgi.run()
|
@ -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))
|
@ -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 %>
|
@ -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%>
|
@ -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%>
|
@ -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>
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 ""
|
||||
|
@ -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)
|
@ -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
|
@ -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
|
@ -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))
|
@ -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"
|
@ -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"
|
@ -6,3 +6,6 @@ msgstr ""
|
||||
|
||||
msgid "Branch"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable"
|
||||
msgstr ""
|
@ -0,0 +1 @@
|
||||
entry({"admin", "autoupdater"}, model("admin/autoupdater"), _("Automatic updates"), 80)
|
@ -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
|
||||
|
@ -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))
|
@ -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>
|
@ -15,7 +15,7 @@ msgid ""
|
||||
"throughput, but the data exchanged over your node is not protected against "
|
||||
"eavesdropping."
|
||||
msgstr ""
|
||||
"Im Modus „Hohe Geschwindigkeit“ 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 „Hohe Sicherheit“ 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."
|
||||
|
@ -0,0 +1 @@
|
||||
entry({"admin", "mesh_vpn_fastd"}, model("admin/mesh_vpn_fastd"), _("Mesh VPN"), 20)
|
@ -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
|
@ -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))
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 ""
|
||||
|
@ -0,0 +1 @@
|
||||
entry({"admin", "network"}, model("admin/network"), _("Network"), 20)
|
@ -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
|
@ -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))
|
@ -0,0 +1 @@
|
||||
entry({"admin", "noderole"}, model("admin/noderole"), "Node role", 20)
|
@ -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
|
@ -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))
|
@ -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)"
|
||||
|
@ -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)"
|
||||
|
@ -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 ""
|
||||
|
@ -0,0 +1 @@
|
||||
entry({"admin", "privatewifi"}, model("admin/privatewifi"), _("Private WLAN"), 10)
|
@ -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
|
@ -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))
|
@ -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
Loading…
Reference in New Issue
Block a user