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