diff --git a/.editorconfig b/.editorconfig index 23219591..3581b168 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,6 +7,10 @@ insert_final_newline = true indent_style = tab charset = utf-8 +[*.yml] +indent_style = space +indent_size = 2 + [*.py] indent_style = space indent_size = 4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..d079b235 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,29 @@ +name: Lint +on: + push: + pull_request: + types: [opened, synchronize, reopened] +jobs: + lua: + name: Lua + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install Dependencies + run: sudo apt install lua-check + - name: Install example site + run: ln -s ./docs/site-example ./site + - name: Lint Lua code + run: make lint-lua + + sh: + name: Shell + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install Dependencies + run: sudo apt install shellcheck + - name: Install example site + run: ln -s ./docs/site-example ./site + - name: Lint shell code + run: make lint-sh diff --git a/.luacheckrc b/.luacheckrc index 62d839a3..b308748c 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -12,6 +12,7 @@ include_files = { "**/*.lua", "package/**/luasrc/**/*", "targets/*", + "package/features", } exclude_files = { @@ -104,3 +105,11 @@ files["targets/*"] = { "try_config", }, } + +files["package/features"] = { + read_globals = { + "_", + "feature", + "when", + }, +} diff --git a/Makefile b/Makefile index e121d3c8..0d174ac2 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,14 @@ GLUON_RELEASE ?= $(error GLUON_RELEASE not set. GLUON_RELEASE can be set in site GLUON_DEPRECATED ?= $(error GLUON_DEPRECATED not set. Please consult the documentation) +ifneq ($(GLUON_BRANCH),) + $(warning *** Warning: GLUON_BRANCH has been deprecated, please set GLUON_AUTOUPDATER_BRANCH and GLUON_AUTOUPDATER_ENABLED instead.) + GLUON_AUTOUPDATER_BRANCH ?= $(GLUON_BRANCH) + GLUON_AUTOUPDATER_ENABLED ?= 1 +endif + +GLUON_AUTOUPDATER_ENABLED ?= 0 + # initialize (possibly already user set) directory variables GLUON_TMPDIR ?= tmp GLUON_OUTPUTDIR ?= output @@ -58,7 +66,7 @@ endef GLUON_VARS = \ GLUON_RELEASE GLUON_REGION GLUON_MULTIDOMAIN GLUON_AUTOREMOVE GLUON_DEBUG GLUON_MINIFY GLUON_DEPRECATED \ GLUON_DEVICES GLUON_TARGETSDIR GLUON_PATCHESDIR GLUON_TMPDIR GLUON_IMAGEDIR GLUON_PACKAGEDIR GLUON_DEBUGDIR \ - GLUON_SITEDIR GLUON_RELEASE GLUON_BRANCH GLUON_LANGS GLUON_BASE_FEEDS \ + GLUON_SITEDIR GLUON_RELEASE GLUON_AUTOUPDATER_BRANCH GLUON_AUTOUPDATER_ENABLED GLUON_LANGS GLUON_BASE_FEEDS \ GLUON_TARGET BOARD SUBTARGET unexport $(GLUON_VARS) @@ -114,13 +122,6 @@ define CheckTarget fi endef -define CheckExternal - if [ ! -d openwrt ]; then - echo "You don't seem to have obtained the external repositories needed by Gluon; please call \`make update\` first!" - exit 1 - fi -endef - define CheckSite if ! GLUON_SITEDIR='$(GLUON_SITEDIR)' GLUON_SITE_CONFIG='$(1).conf' $(LUA) -e 'assert(dofile("scripts/site_config.lua")(os.getenv("GLUON_SITE_CONFIG")))'; then echo 'Your site configuration ($(1).conf) did not pass validation' @@ -147,7 +148,7 @@ LUA := openwrt/staging_dir/hostpkg/bin/lua $(LUA): +@ - $(CheckExternal) + scripts/module_check.sh [ -e openwrt/.config ] || $(OPENWRTMAKE) defconfig $(OPENWRTMAKE) tools/install @@ -157,7 +158,7 @@ $(LUA): config: $(LUA) FORCE +@ - $(CheckExternal) + scripts/module_check.sh $(CheckTarget) $(foreach conf,site $(patsubst $(GLUON_SITEDIR)/%.conf,%,$(wildcard $(GLUON_SITEDIR)/domains/*.conf)),\ $(call CheckSite,$(conf)); \ @@ -185,23 +186,23 @@ dirclean: FORCE manifest: $(LUA) FORCE @ - [ '$(GLUON_BRANCH)' ] || (echo 'Please set GLUON_BRANCH to create a manifest.'; false) + [ '$(GLUON_AUTOUPDATER_BRANCH)' ] || (echo 'Please set GLUON_AUTOUPDATER_BRANCH to create a manifest.'; false) echo '$(GLUON_PRIORITY)' | grep -qE '^([0-9]*\.)?[0-9]+$$' || (echo 'Please specify a numeric value for GLUON_PRIORITY to create a manifest.'; false) - $(CheckExternal) + scripts/module_check.sh ( export $(GLUON_ENV) - echo 'BRANCH=$(GLUON_BRANCH)' + echo 'BRANCH=$(GLUON_AUTOUPDATER_BRANCH)' echo "DATE=$$($(LUA) scripts/rfc3339date.lua)" echo 'PRIORITY=$(GLUON_PRIORITY)' echo for target in $(GLUON_TARGETS); do $(LUA) scripts/generate_manifest.lua "$$target" done - ) > 'tmp/$(GLUON_BRANCH).manifest.tmp' + ) > 'tmp/$(GLUON_AUTOUPDATER_BRANCH).manifest.tmp' mkdir -p '$(GLUON_IMAGEDIR)/sysupgrade' - mv 'tmp/$(GLUON_BRANCH).manifest.tmp' '$(GLUON_IMAGEDIR)/sysupgrade/$(GLUON_BRANCH).manifest' + mv 'tmp/$(GLUON_AUTOUPDATER_BRANCH).manifest.tmp' '$(GLUON_IMAGEDIR)/sysupgrade/$(GLUON_AUTOUPDATER_BRANCH).manifest' FORCE: ; diff --git a/README.md b/README.md index 8158ae17..0798f4f9 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ the future development of Gluon. Please refrain from using the `master` branch for anything else but development purposes! Use the most recent release instead. You can list all releases by running `git tag` -and switch to one by running `git checkout v2020.1.3 && make update`. +and switch to one by running `git checkout v2020.2.1 && make update`. If you're using the autoupdater, do not autoupdate nodes with anything but releases. If you upgrade using random master commits the nodes *will break* eventually. diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css new file mode 100644 index 00000000..38458950 --- /dev/null +++ b/docs/_static/css/custom.css @@ -0,0 +1,45 @@ +/* + This fixes the vertical position of list markers when the first + element in the
block
+
+ Scrolling inside the block is still working as expected
+*/
+.rst-content pre.literal-block,
+.rst-content div[class^='highlight'] pre {
+ overflow: visible;
+}
+
+
+/*
+ This fixes the bottom margin of paragraphs inside lists, where margins inside
+ a single list item would incorrectly be displayed larger than margins between
+ the list items.
+
+ Upstream fix (not fixed on readthedocs.io yet):
+ https://github.com/readthedocs/sphinx_rtd_theme/commit/ac20ce75d426efeb40fe2af1f89ea9bad285a45b
+*/
+.rst-content .section ol li > p,
+.rst-content .section ol li > p:last-child,
+.rst-content .section ul li > p,
+.rst-content .section ul li > p:last-child {
+ margin-bottom: 12px;
+}
+.rst-content .section ol li > p:only-child,
+.rst-content .section ol li > p:only-child:last-child,
+.rst-content .section ul li > p:only-child,
+.rst-content .section ul li > p:only-child:last-child {
+ margin-bottom: 0rem;
+}
+
+/*
+ This fixes the bottom margin of nested lists
+
+ Based on upstream fix (not on readthedocs.io yet):
+ https://github.com/readthedocs/sphinx_rtd_theme/commit/6f0de13baff93f25204aa2cdf0308aae47d71312
+*/
+.rst-content .section ul li > ul,
+.rst-content .section ul li > ol,
+.rst-content .section ol li > ul,
+.rst-content .section ol li > ol {
+ margin-bottom: 12px;
+}
diff --git a/docs/conf.py b/docs/conf.py
index 4f7e5191..766a07cd 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -24,7 +24,7 @@ copyright = '2015-2020, Project Gluon'
author = 'Project Gluon'
# The short X.Y version
-version = '2020.1+'
+version = '2020.2+'
# The full version, including alpha/beta/rc tags
release = version
@@ -89,7 +89,7 @@ html_theme = 'sphinx_rtd_theme'
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#
-# html_static_path = ['_static']
+html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
@@ -101,6 +101,10 @@ html_theme = 'sphinx_rtd_theme'
#
# html_sidebars = {}
+# These paths are either relative to html_static_path
+# or fully qualified paths (eg. https://...)
+html_css_files = ['css/custom.css']
+
# -- Options for HTMLHelp output ---------------------------------------------
diff --git a/docs/dev/build.rst b/docs/dev/build.rst
index d6b6c384..74b9aa11 100644
--- a/docs/dev/build.rst
+++ b/docs/dev/build.rst
@@ -23,7 +23,7 @@ GLUON_SITE_FEED
List of site feeds; defined in file *modules* in site config
\*_REPO, \*_BRANCH, \*_COMMIT
- Git repository URL, branch and and
+ Git repository URL, branch and
commit ID of the feeds to use. The branch name may be omitted; the default
branch will be used in this case.
@@ -79,7 +79,7 @@ patch.sh
- updating all git submodules
This solution with a temporary clone ensures that the timestamps of checked
- out files are not changed by any intermedidate patch steps, but only when
+ out files are not changed by any intermediate patch steps, but only when
updating the checkout with the final result. This avoids triggering unnecessary
rebuilds.
diff --git a/docs/dev/debugging.rst b/docs/dev/debugging.rst
index 413f1c97..52073428 100644
--- a/docs/dev/debugging.rst
+++ b/docs/dev/debugging.rst
@@ -7,7 +7,7 @@ Debugging
Kernel Oops
-----------
-Sometimes a running Linux kernel detects an error during runtime that canot
+Sometimes a running Linux kernel detects an error during runtime that can't
be corrected.
This usually generates a stack trace that points to the location in the code
that caused the oops.
diff --git a/docs/dev/packages.rst b/docs/dev/packages.rst
index a527aad4..b6032b2e 100644
--- a/docs/dev/packages.rst
+++ b/docs/dev/packages.rst
@@ -71,44 +71,62 @@ Feature flags
=============
Feature flags provide a convenient way to define package selections without
-making it necessary to list each package explicitly.
+making it necessary to list each package explicitly. The list of features to
+enable for a Gluon build is set by the *GLUON_FEATURES* variable in *site.mk*.
The main feature flag definition file is ``package/features``, but each package
feed can provide additional definitions in a file called ``features`` at the root
of the feed repository.
-Each flag *$flag* without any explicit definition will simply include the package
-with the name *gluon-$flag* by default. The feature definition file can modify
-the package selection in two ways:
+Each flag *$flag* will include the package the name *gluon-$flag* by default.
+The feature definition file can modify the package selection by adding or removing
+packages when certain combinations of flags are set.
-* The *nodefault* function suppresses default of including the *gluon-$flag*
- package
-* The *packages* function adds a list of packages (or removes, when package
- names are prepended with minus signs) when a given logical expression
- is satisfied
+Feature definitions use Lua syntax. Two basic functions are defined:
+
+* *feature(name, pkgs)*: Defines a new feature. *feature()* expects a feature
+ (flag) name and a list of packages to add or remove when the feature is
+ enabled.
+
+ * Defining a feature using *feature* replaces the default definition of
+ just including *gluon-$flag*.
+ * A package is removed when the package name is prefixed with a ``-`` (after
+ the opening quotation mark).
+
+* *when(expr, pkgs)*: Adds or removes packages when a given logical expression
+ of feature flags is satisfied.
+
+ * *expr* is a logical expression composed of feature flag names (each prefixed
+ with an underscore before the opening quotation mark), logical operators
+ (*and*, *or*, *not*) and parentheses.
+ * Referencing a feature flag in *expr* has no effect on the default handling
+ of the flag. When no *feature()* entry for a flag exists, it will still
+ add *gluon-$flag* by default.
+ * *pkgs* is handled as for *feature()*.
Example::
- nodefault 'web-wizard'
+ feature('web-wizard', {
+ 'gluon-config-mode-hostname',
+ 'gluon-config-mode-geo-location',
+ 'gluon-config-mode-contact-info',
+ 'gluon-config-mode-outdoor',
+ })
- packages 'web-wizard' \
- 'gluon-config-mode-hostname' \
- 'gluon-config-mode-geo-location' \
- 'gluon-config-mode-contact-info'
+ when(_'web-wizard' and (_'mesh-vpn-fastd' or _'mesh-vpn-tunneldigger'), {
+ 'gluon-config-mode-mesh-vpn',
+ })
+
+ feature('no-radvd', {
+ '-gluon-radvd',
+ })
- packages 'web-wizard & (mesh-vpn-fastd | mesh-vpn-tunneldigger)' \
- 'gluon-config-mode-mesh-vpn'
This will
-* disable the inclusion of a (non-existent) package called *gluon-web-wizard*
-* enable three config mode packages when the *web-wizard* feature is enabled
+* disable the inclusion of the (non-existent) packages *gluon-web-wizard* and *gluon-no-radvd* when their
+ corresponding feature flags appear in *GLUON_FEATURES*
+* enable four additional config mode packages when the *web-wizard* feature is enabled
* enable *gluon-config-mode-mesh-vpn* when both *web-wizard* and one
of *mesh-vpn-fastd* and *mesh-vpn-tunneldigger* are enabled
-
-Supported syntax elements of logical expressions are:
-
-* \& (and)
-* \| (or)
-* \! (not)
-* parentheses
+* disable the *gluon-radvd* package when *gluon-no-radvd* is enabled
diff --git a/docs/dev/wan.rst b/docs/dev/wan.rst
index b992146a..ec9d942b 100644
--- a/docs/dev/wan.rst
+++ b/docs/dev/wan.rst
@@ -13,7 +13,7 @@ the mesh's DNS servers and use these for all other name resolution.
If the device does not feature a WAN port, the LAN port is configured as WAN port.
In case such a device has multiple LAN ports, all these can be used as WAN.
-Devices, which feature a "hybrid" port (labled as WAN/LAN), this port is used as WAN.
+Devices, which feature a "hybrid" port (labelled as WAN/LAN), this port is used as WAN.
This behavior can be reversed using the ``single_as_lan`` site.conf option.
diff --git a/docs/features/autoupdater.rst b/docs/features/autoupdater.rst
index 014ee59f..e0cd9c6c 100644
--- a/docs/features/autoupdater.rst
+++ b/docs/features/autoupdater.rst
@@ -7,8 +7,11 @@ Building Images
---------------
By default, the autoupdater is disabled (as it is usually not helpful to have unexpected updates
-during development), but it can be enabled by setting the variable GLUON_BRANCH when building
-to override the default branch set in the site configuration.
+during development), but it can be enabled by setting the variable ``GLUON_AUTOUPDATER_ENABLED`` to ``1`` when building.
+It is also possible to override the default branch during build using the variable ``GLUON_AUTOUPDATER_BRANCH``.
+
+If a default branch is set neither in *site.conf* nor via ``GLUON_AUTOUPDATER_BRANCH``, the default branch is
+implementation-defined. Currently, the branch with the first name in alphabetical order is chosen.
A manifest file for the updater can be generated with `make manifest`. A signing script (using
``ecdsautils``) can be found in the `contrib` directory. When creating the manifest, the
@@ -32,15 +35,16 @@ Automated nightly builds
A fully automated nightly build could use the following commands:
-::
+.. code-block:: sh
git pull
- (git -C site pull)
+ # git -C site pull
make update
make clean GLUON_TARGET=ar71xx-generic
NUM_CORES_PLUS_ONE=$(expr $(nproc) + 1)
- make -j$NUM_CORES_PLUS_ONE GLUON_TARGET=ar71xx-generic GLUON_BRANCH=experimental GLUON_RELEASE=$GLUON_RELEASE
- make manifest GLUON_BRANCH=experimental GLUON_RELEASE=$GLUON_RELEASE
+ make -j$NUM_CORES_PLUS_ONE GLUON_TARGET=ar71xx-generic GLUON_RELEASE=$GLUON_RELEASE \
+ GLUON_AUTOUPDATER_BRANCH=experimental GLUON_AUTOUPDATER_ENABLED=1
+ make manifest GLUON_RELEASE=$GLUON_RELEASE GLUON_AUTOUPDATER_BRANCH=experimental
contrib/sign.sh $SECRETKEY output/images/sysupgrade/experimental.manifest
rm -rf /where/to/put/this/experimental
diff --git a/docs/features/multidomain.rst b/docs/features/multidomain.rst
index 1f9a729e..7abd59a8 100644
--- a/docs/features/multidomain.rst
+++ b/docs/features/multidomain.rst
@@ -88,18 +88,25 @@ domain of a router, if and only if one of the above conditions matches.
Switching the domain
--------------------
-**via commandline**:
+Via commandline
+^^^^^^^^^^^^^^^
::
- uci set gluon.core.domain="newdomaincode"
- gluon-reconfigure
- reboot
+ gluon-switch-domain 'newdomaincode'
-**via config mode:**
+When the node is not in config mode, ``gluon-switch-domain`` will automatically
+reboot the node by default. This can be suppressed by passing ``--no-reboot``::
-To allow switching the domain via config mode, ``config-mode-domain-select``
-has to be added to GLUON_FEATURES in the site.mk.
+ gluon-switch-domain --no-reboot 'newdomaincode'
+
+Switching the domain without reboot is currently **experimental**.
+
+Via config mode
+^^^^^^^^^^^^^^^
+
+To allow switching the domain via config mode, add ``config-mode-domain-select``
+to GLUON_FEATURES in site.mk.
|image0|
diff --git a/docs/features/vpn.rst b/docs/features/vpn.rst
index 81b6dfce..8697baad 100644
--- a/docs/features/vpn.rst
+++ b/docs/features/vpn.rst
@@ -47,7 +47,7 @@ The resulting firmware will allow users to choose between secure (encrypted) and
.. image:: fastd_mode.gif
**Unix socket:**
-To confirm whether the correct cipher is being used, fastds unix
+To confirm whether the correct cipher is being used, fastd's unix
socket can be interrogated, after installing for example `socat`.
::
diff --git a/docs/features/wlan-configuration.rst b/docs/features/wlan-configuration.rst
index 3807b889..08528196 100644
--- a/docs/features/wlan-configuration.rst
+++ b/docs/features/wlan-configuration.rst
@@ -21,4 +21,6 @@ you can configure this via the uci section ``gluon-core.wireless``::
uci set gluon-core.@wireless[0].preserve_channels='1'
+When channels should be preserved, toggling the outdoor mode will have no effect on the channel settings.
+Therefore, the Outdoor mode settings won't be displayed in config mode.
Keep in mind that nodes running wifi interfaces on custom channels can't mesh with default nodes anymore!
diff --git a/docs/index.rst b/docs/index.rst
index cf767073..adb77584 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -78,6 +78,9 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
:caption: Releases
:maxdepth: 1
+ releases/v2020.2.1
+ releases/v2020.2
+ releases/v2020.1.4
releases/v2020.1.3
releases/v2020.1.2
releases/v2020.1.1
diff --git a/docs/package/gluon-hoodselector.rst b/docs/package/gluon-hoodselector.rst
index 13054924..23fd8f41 100644
--- a/docs/package/gluon-hoodselector.rst
+++ b/docs/package/gluon-hoodselector.rst
@@ -66,7 +66,7 @@ and others which contain shapes.
* **default domain**
-The default domain doesn’t hold any shapes and represents the inverted area of
+The default domain doesn't hold any shapes and represents the inverted area of
all other shapes held by other domains with geo coordinates. It will only be
entered if a node could not be matched to a geo domain. A suggested approach is
to define the "old" network as default domain and gradually migrate nodes from
diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst
index 1e6d3396..2fd694c1 100644
--- a/docs/releases/v2015.1.rst
+++ b/docs/releases/v2015.1.rst
@@ -19,7 +19,7 @@ ar71xx-generic
- DIR-615 (C1)
-* GL-Inet
+* GL.iNet
- 6408A (v1)
- 6416A (v1)
diff --git a/docs/releases/v2018.2.1.rst b/docs/releases/v2018.2.1.rst
index 92c729a1..3f02f888 100644
--- a/docs/releases/v2018.2.1.rst
+++ b/docs/releases/v2018.2.1.rst
@@ -21,7 +21,7 @@ ramips-mt7620
ramips-mt76x8
^^^^^^^^^^^^^
-* Gl.iNet
+* GL.iNet
- MT300N (v2) [#noibss]_
diff --git a/docs/releases/v2020.1.1.rst b/docs/releases/v2020.1.1.rst
index b6ad1831..f18d1133 100644
--- a/docs/releases/v2020.1.1.rst
+++ b/docs/releases/v2020.1.1.rst
@@ -10,7 +10,7 @@ Bugfixes
- Fixed non-working LEDs on TP-Link Archer C5 v1 and Archer C7 v2 after an upgrade to Gluon 2020.1.
- Fixed an issue which leads to AVM FRITZ!WLAN Repeater 450E devices being stuck in failsafe mode
- ater an upgrade to Gluon 2020.1.
+ after an upgrade to Gluon 2020.1.
Other changes
-------------
diff --git a/docs/releases/v2020.1.2.rst b/docs/releases/v2020.1.2.rst
index fa25c655..37adb6a1 100644
--- a/docs/releases/v2020.1.2.rst
+++ b/docs/releases/v2020.1.2.rst
@@ -37,7 +37,7 @@ Other changes
Internals
---------
-- OpenWrt 19.07 introduced the urgnd entropy daemon that serves the same function as the haveged service, which we have been recommending. To not have two redundant entropy daemons in this release we remove urngd in favor of haveged in the v2020.1 release series.
+- OpenWrt 19.07 introduced the urngd entropy daemon that serves the same function as the haveged service, which we have been recommending. To not have two redundant entropy daemons in this release we remove urngd in favor of haveged in the v2020.1 release series.
Known issues
------------
diff --git a/docs/releases/v2020.1.4.rst b/docs/releases/v2020.1.4.rst
new file mode 100644
index 00000000..92a31c6f
--- /dev/null
+++ b/docs/releases/v2020.1.4.rst
@@ -0,0 +1,47 @@
+Gluon 2020.1.4
+==============
+
+Added hardware support
+----------------------
+
+- Added support for TP-Link CPE210 3.20 (`#2080 `_)
+
+Bugfixes
+--------
+
+- Fixed a rare race-condition during mesh interface teardown (`#2057 `_)
+
+- Fixed handling of mesh interfaces together with outdoor mode, site.conf defaults and config mode (`#2049 `_) (`#2054 `_)
+
+Other changes
+-------------
+
+- Linux kernel has been updated to 4.14.193
+- Backports of batman-adv bugfixes
+
+Known issues
+------------
+
+* Upgrading EdgeRouter-X from versions before v2020.1.x may lead to a soft-bricked state due to bad blocks on the
+ NAND flash which the NAND driver before this release does not handle well.
+ (`#1937 `_)
+
+* The integration of the BATMAN_V routing algorithm is incomplete.
+
+ - Mesh neighbors don't appear on the status page. (`#1726 `_)
+ Many tools have the BATMAN_IV metric hardcoded, these need to be updated to account for the new throughput
+ metric.
+ - Throughput values are not correctly acquired for different interface types.
+ (`#1728 `_)
+ This affects virtual interface types like bridges and VXLAN.
+
+* Default TX power on many Ubiquiti devices is too high, correct offsets are unknown
+ (`#94 `_)
+
+ Reducing the TX power in the Advanced Settings is recommended.
+
+* The MAC address of the WAN interface is modified even when Mesh-on-WAN is disabled
+ (`#496 `_)
+
+ This may lead to issues in environments where a fixed MAC address is expected (like VMware when promiscuous mode is
+ disallowed).
diff --git a/docs/releases/v2020.2.1.rst b/docs/releases/v2020.2.1.rst
new file mode 100644
index 00000000..8c3ea5ea
--- /dev/null
+++ b/docs/releases/v2020.2.1.rst
@@ -0,0 +1,47 @@
+Gluon 2020.2.1
+==============
+
+Added hardware support
+----------------------
+
+- Added support for TP-Link CPE210 3.20 (`#2080 `_)
+
+Bugfixes
+--------
+
+- Fixed handling of *mesh_on_lan* enabled in site configuration (`#2090 `_)
+
+- Fixed build issues with lantiq-xrx200 target by removing unsupported DSL modem packages (`#2087 `_)
+
+Other changes
+-------------
+
+- Linux kernel has been updated to 4.14.193
+- Backports of batman-adv bugfixes
+
+Known issues
+------------
+
+* Upgrading EdgeRouter-X from versions before v2020.1.x may lead to a soft-bricked state due to bad blocks on the
+ NAND flash which the NAND driver before this release does not handle well.
+ (`#1937 `_)
+
+* The integration of the BATMAN_V routing algorithm is incomplete.
+
+ - Mesh neighbors don't appear on the status page. (`#1726 `_)
+ Many tools have the BATMAN_IV metric hardcoded, these need to be updated to account for the new throughput
+ metric.
+ - Throughput values are not correctly acquired for different interface types.
+ (`#1728 `_)
+ This affects virtual interface types like bridges and VXLAN.
+
+* Default TX power on many Ubiquiti devices is too high, correct offsets are unknown
+ (`#94 `_)
+
+ Reducing the TX power in the Advanced Settings is recommended.
+
+* In configurations not using VXLAN, the MAC address of the WAN interface is modified even when Mesh-on-WAN is disabled
+ (`#496 `_)
+
+ This may lead to issues in environments where a fixed MAC address is expected (like VMware when promiscuous mode is
+ disallowed).
diff --git a/docs/releases/v2020.2.rst b/docs/releases/v2020.2.rst
new file mode 100644
index 00000000..4d4f3cd7
--- /dev/null
+++ b/docs/releases/v2020.2.rst
@@ -0,0 +1,198 @@
+Gluon 2020.2
+============
+
+Added hardware support
+----------------------
+
+ath79-generic
+~~~~~~~~~~~~~
+
+* GL.iNet
+
+ - GL-AR750S
+
+* TP-Link
+
+ - CPE220 (v3)
+
+ipq40xx-generic
+~~~~~~~~~~~~~~~
+
+* EnGenius
+
+ - ENS620EXT [#outdoor]_
+
+* Linksys
+
+ - EA6350 (v3)
+
+lantiq-xrx200
+~~~~~~~~~~~~~
+
+* TP-Link
+
+ - TD-W8970
+
+lantiq-xway
+~~~~~~~~~~~
+
+* NETGEAR
+
+ - DGN3500B
+
+ramips-mt76x8
+~~~~~~~~~~~~~
+* Cudy
+
+ - WR1000
+
+
+x86-legacy [#newtarget]_
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+* Devices older than the Pentium 4
+
+
+.. [#newtarget]
+ This is a new target.
+
+.. [#outdoor]
+ This device is supposed to be set up outdoors and will therefore have its outdoor mode flag automatically enabled.
+
+
+Major changes
+-------------
+
+Device Classes
+~~~~~~~~~~~~~~
+
+Devices are now categorized into device classes. This device class can determine which features
+as well as packages are installed on the device when building images.
+
+Currently there are two classes used in Gluon, *tiny* and *standard*. All devices with less than 64M of RAM or
+less than 7M of usable firmware space are assigned to the tiny class.
+
+WPA3 support for Private WLAN
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The private WLAN now supports WPA3-SAE key exchange as well as management frame protection (802.11w).
+For this to work, the firmware needs to be built with the *wireless-encryption-wpa3* feature.
+
+OWE on Client Network
+~~~~~~~~~~~~~~~~~~~~~
+
+Gluon now allows to configure a VAP for the client network which supports opportunistic encryption on the
+client network for devices which support the OWE security type (also known as Enhanced Open).
+
+This encrypted VAP can be the only available access point or be configured in addition to an unencrypted VAP.
+In the latter case, the transition mode can be enabled, which enables compatible devices to automatically
+connect to the encrypted VAP while legacy devices continue to use the unencrypted connection.
+
+There are issues with some devices running Android 9 when connecting to a transition mode enabled network. See the site documentation for more information.
+
+SAE Encrypted Mesh Links
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Mesh links can now be operated in an encrypted mode using SAE authentication. For this to work, a common shared secret
+has to be distributed to all participating nodes using the site.conf.
+
+Responsive status page
+~~~~~~~~~~~~~~~~~~~~~~
+
+The status page design is now responsive and reflows better on mobile devices.
+
+Primary domain code
+~~~~~~~~~~~~~~~~~~~
+
+The primary domain code is now visible on the node status page as well as in the respondd information
+emitted by the node.
+
+Logging
+~~~~~~~
+
+The new *gluon-logging* package allows to configure a remote syslog server using the site.conf.
+This package can only be included when *gluon-web-logging* is excluded.
+
+Peer cleanup in fastd
+~~~~~~~~~~~~~~~~~~~~~
+
+fastd peers and groups are now removed on update in case they do not exist in the new site configuration.
+To preserve a custom peer across updates, add the *preserve* key to the peer's UCI configuration and set it to ``1``.
+
+
+Bugfixes
+--------
+
+- The WAN MAC address now matches the one defined in OpenWrt if VXLAN is enabled for the selected domain.
+
+- *gluon-reload* now reloads all relevant services.
+
+- Disabling outdoor mode and enabling meshing in the config mode can now be performed in a single step.
+
+- Fixed section visibility with enabled outdoor mode in config mode.
+
+
+Site changes
+------------
+
+site.mk
+~~~~~~~
+
+Starting with version 19.07 OpenWrt ships the urngd entropy daemon by default.
+It replaces the haveged daemon, for which we removed the support in Gluon. Remove ``haveged`` from your package selection.
+
+
+Internal
+--------
+
+Editorconfig
+~~~~~~~~~~~~
+
+Gluon now ships a *editorconfig* file to allow compatible editors to automatically apply key aspects of Gluon's code style.
+
+Continuous Integration
+~~~~~~~~~~~~~~~~~~~~~~
+
+* Jenkins
+
+ - The CI now has a test stage to verify Gluons runtime functionality.
+
+* GitHub Actions
+
+ - GitHub actions is now enabled for the Gluon project, build-testing all available targets.
+
+Build system
+~~~~~~~~~~~~
+
+- Source code minification can now be skipped by enabling the GLUON_MINIFY flag.
+
+- Enabling the GLUON_AUTOREMOVE flag will remove package build directories after they are built.
+ This reduces space consumption at the expense of subsequent builds being slower.
+
+
+Known issues
+------------
+
+* Upgrading EdgeRouter-X from versions before v2020.1.x may lead to a soft-bricked state due to bad blocks on the
+ NAND flash which the NAND driver before this release does not handle well.
+ (`#1937 `_)
+
+* The integration of the BATMAN_V routing algorithm is incomplete.
+
+ - Mesh neighbors don't appear on the status page. (`#1726 `_)
+ Many tools have the BATMAN_IV metric hardcoded, these need to be updated to account for the new throughput
+ metric.
+ - Throughput values are not correctly acquired for different interface types.
+ (`#1728 `_)
+ This affects virtual interface types like bridges and VXLAN.
+
+* Default TX power on many Ubiquiti devices is too high, correct offsets are unknown
+ (`#94 `_)
+
+ Reducing the TX power in the Advanced Settings is recommended.
+
+* In configurations not using VXLAN, the MAC address of the WAN interface is modified even when Mesh-on-WAN is disabled
+ (`#496 `_)
+
+ This may lead to issues in environments where a fixed MAC address is expected (like VMware when promiscuous mode is
+ disallowed).
diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf
index 22f78502..797a2fa9 100644
--- a/docs/site-example/site.conf
+++ b/docs/site-example/site.conf
@@ -1,4 +1,4 @@
--- This is an example site configuration for Gluon v2020.1.3
+-- This is an example site configuration for Gluon v2020.2.1
--
-- Take a look at the documentation located at
-- https://gluon.readthedocs.io/ for details.
@@ -164,7 +164,8 @@
},
autoupdater = {
- -- Default branch. Don't forget to set GLUON_BRANCH when building!
+ -- Default branch (optional), can be overridden by setting GLUON_AUTOUPDATER_BRANCH when building.
+ -- Set GLUON_AUTOUPDATER_ENABLED to enable the autoupdater by default for newly installed nodes.
branch = 'stable',
-- List of branches. You may define multiple branches.
diff --git a/docs/user/getting_started.rst b/docs/user/getting_started.rst
index 36d9260e..1cf3bc23 100644
--- a/docs/user/getting_started.rst
+++ b/docs/user/getting_started.rst
@@ -8,7 +8,7 @@ Gluon's releases are managed using `Git tags`_. If you are just getting
started with Gluon we recommend to use the latest stable release of Gluon.
Take a look at the `list of gluon releases`_ and notice the latest release,
-e.g. *v2020.1.3*. Always get Gluon using git and don't try to download it
+e.g. *v2020.2.1*. Always get Gluon using git and don't try to download it
as a Zip archive as the archive will be missing version information.
Please keep in mind that there is no "default Gluon" build; a site configuration
@@ -44,7 +44,7 @@ Building the images
-------------------
To build Gluon, first check out the repository. Replace *RELEASE* with the
-version you'd like to checkout, e.g. *v2020.1.3*.
+version you'd like to checkout, e.g. *v2020.2.1*.
::
@@ -171,10 +171,12 @@ usually be set on the command line or in ``site.mk``.
Common variables
................
-GLUON_BRANCH
- Sets the default branch of the autoupdater. If unset, the autoupdater is disabled
- by default. For the ``make manifest`` command, GLUON_BRANCH defines the branch to
- generate a manifest for.
+GLUON_AUTOUPDATER_BRANCH
+ Overrides the default branch of the autoupdater set in ``site.conf``. For the ``make manifest`` command,
+ ``GLUON_AUTOUPDATER_BRANCH`` defines the branch to generate a manifest for.
+
+GLUON_AUTOUPDATER_ENABLED
+ Set to ``1`` to enable the autoupdater by default for newly installed nodes.
GLUON_DEPRECATED
Controls whether images for deprecated devices should be built. The following
@@ -225,7 +227,7 @@ GLUON_DEBUG
similar tools. Requires a device or target with at least 16 MB of flash space, e.g. `x86-64`. Unset by default.
GLUON_MINIFY
- Setting ``GLUON_MINIFY=0`` will omit the minification of scripts during the build process. By
+ Setting ``GLUON_MINIFY=0`` will omit the minification of scripts during the build process. By
default the flag is set to ``1``. Disabling the flag is handy if human readable scripts on the
devices are desired for development purposes. Be aware that this will increase the size of the
resulting images and is therefore not suitable for devices with small flash chips.
diff --git a/docs/user/site.rst b/docs/user/site.rst
index fa14d57f..11004f3b 100644
--- a/docs/user/site.rst
+++ b/docs/user/site.rst
@@ -176,7 +176,7 @@ wifi24 \: optional
.. _user-site-wifi5:
wifi5 \: optional
- Same as `wifi24` but for the 5Ghz radio.
+ Same as `wifi24` but for the 5 GHz radio.
Additionally a range of channels that are safe to use outsides on the 5 GHz band can
be set up through ``outdoor_chanlist``, which allows for a space-separated list of
@@ -326,7 +326,7 @@ mesh_vpn
implementation.
**Note:** It may be interesting to include the package *gluon-iptables-clamp-mss-to-pmtu*
- in the build when using *gluon-mesh-babel* to work around icmp blackholes on the internet.
+ in the build when using *gluon-mesh-babel* to work around ICMP blackholes on the internet.
::
@@ -418,12 +418,16 @@ poe_passthrough \: optional
autoupdater \: package
Configuration for the autoupdater feature of Gluon.
+ Specifying a default branch in *site.conf* is optional. See
+ :doc:`../features/autoupdater` for information how to change the behaviour
+ of the autoupdater during image build.
+
The mirrors are checked in random order until the manifest could be downloaded
successfully or all mirrors have been tried.
::
autoupdater = {
- branch = 'stable',
+ branch = 'stable', -- optional
branches = {
stable = {
name = 'stable',
@@ -464,9 +468,14 @@ config_mode \: optional
The *geo_location.osm* section is only relevant when the *gluon-config-mode-geo-location-osm*
package is used. The *center.lon* and *center.lat* values are mandatory in this case and
define the default center of the map when no position has been picked yet. The *zoom* level
- defaults to 12 in this case. *openlayers_url* allows to override the base URL of the
+ defaults to 12 in this case.
+
+ *openlayers_url* allows to override the base URL of the
*build/ol.js* and *css/ol.css* files (the default is
``https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.2.0``).
+ It is also possible to replace the default tile layer (which is OpenStreetMap)
+ with a custom one using the *tile_layer* section. Only XYZ layers are supported
+ at this point.
The remote login page only shows SSH key configuration by default. A
password form can be displayed by setting *remote_login.show_password_form*
@@ -488,6 +497,11 @@ config_mode \: optional
},
zoom = 13,
-- openlayers_url = 'http://ffac.example.org/openlayer',
+ -- tile_layer = {
+ -- type = 'XYZ',
+ -- url = 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
+ -- attributions = '© OpenStreetMap contributors.',
+ -- },
},
},
remote_login = {
diff --git a/docs/user/supported_devices.rst b/docs/user/supported_devices.rst
index 1b63f56b..4820d9ac 100644
--- a/docs/user/supported_devices.rst
+++ b/docs/user/supported_devices.rst
@@ -44,6 +44,7 @@ ar71xx-generic
- GL-AR150
- GL-AR300M
- GL-AR750
+ - GL-USB150 (Microuter)
* Linksys
@@ -107,9 +108,9 @@ ar71xx-generic
- Nanostation M2/M5 [#device-class-tiny]_
- Nanostation M2/M5 XW
- Picostation M2 [#device-class-tiny]_
- - Rocket M2/M5
- - Rocket M2/M5 Ti
- - Rocket M2/M5 XW
+ - Rocket M2
+ - Rocket M2 Ti
+ - Rocket M2 XW
- UniFi AC Mesh
- UniFi AC Mesh Pro
- UniFi AP
@@ -229,6 +230,7 @@ ipq40xx-generic
* AVM
- FRITZ!Box 4040 [#avmflash]_
+ - FRITZ!Box 7530 [#eva_ramboot]_
- FRITZ!Repeater 1200 [#eva_ramboot]_
* EnGenius
@@ -317,6 +319,11 @@ ramips-mt7620
- GL-MT300N
- GL-MT750
+* NETGEAR
+
+ - EX3700
+ - EX3800
+
* Nexx
- WT3020AD/F/H
diff --git a/modules b/modules
index 5f7923b8..2ed26f02 100644
--- a/modules
+++ b/modules
@@ -2,15 +2,15 @@ GLUON_FEEDS='packages routing gluon'
OPENWRT_REPO=https://github.com/openwrt/openwrt.git
OPENWRT_BRANCH=openwrt-19.07
-OPENWRT_COMMIT=9cafcbe0bdd601d07ed55bee0136f5d8393c37a8
+OPENWRT_COMMIT=29b4104d69bf91db17764dd885e9e111a373f08c
PACKAGES_PACKAGES_REPO=https://github.com/openwrt/packages.git
PACKAGES_PACKAGES_BRANCH=openwrt-19.07
-PACKAGES_PACKAGES_COMMIT=e76090945523c71c2406276f6d42b2e7f078a2d8
+PACKAGES_PACKAGES_COMMIT=03425a0d2f5967639d15a3ef1f0407859768917d
PACKAGES_ROUTING_REPO=https://github.com/openwrt-routing/packages.git
PACKAGES_ROUTING_BRANCH=openwrt-19.07
-PACKAGES_ROUTING_COMMIT=9b42e24a54f03ebb6f58224b49036e8f739b175f
+PACKAGES_ROUTING_COMMIT=b77498bd56d5e45ab4577a1f4ad6ffc55b4a86b7
PACKAGES_GLUON_REPO=https://github.com/freifunk-gluon/packages.git
PACKAGES_GLUON_COMMIT=12e41d0ff07ec54bbd67a31ab50d12ca04f2238c
diff --git a/package/features b/package/features
index a54837c8..72887e3a 100644
--- a/package/features
+++ b/package/features
@@ -1,37 +1,52 @@
-nodefault 'web-wizard'
-
-packages 'web-wizard' \
- 'gluon-config-mode-hostname' \
- 'gluon-config-mode-geo-location' \
- 'gluon-config-mode-contact-info' \
- 'gluon-config-mode-outdoor'
-
-packages 'web-wizard & autoupdater' \
- 'gluon-config-mode-autoupdater'
-
-packages 'web-wizard & (mesh-vpn-fastd | mesh-vpn-tunneldigger)' \
- 'gluon-config-mode-mesh-vpn'
+-- GLUON_FEATURES definition file
+--
+-- See the page `dev/packages` (Developer Documentation / Package development)
+-- in the `docs` directory or on gluon.readthedocs.io for information on the
+-- file format
-nodefault 'web-advanced'
+feature('web-wizard', {
+ 'gluon-config-mode-hostname',
+ 'gluon-config-mode-geo-location',
+ 'gluon-config-mode-contact-info',
+ 'gluon-config-mode-outdoor',
+})
-packages 'web-advanced' \
- 'gluon-web-admin' \
- 'gluon-web-network' \
- 'gluon-web-wifi-config'
+when(_'web-wizard' and _'autoupdater', {
+ 'gluon-config-mode-autoupdater',
+})
-packages 'web-advanced & autoupdater' \
- 'gluon-web-autoupdater'
+when(_'web-wizard' and (_'mesh-vpn-fastd' or _'mesh-vpn-tunneldigger'), {
+ 'gluon-config-mode-mesh-vpn',
+})
-packages 'status-page & mesh-batman-adv-15' \
- 'gluon-status-page-mesh-batman-adv'
-packages 'mesh-batman-adv-15' \
- 'gluon-ebtables-limit-arp' \
- 'gluon-radvd'
+feature('web-advanced', {
+ 'gluon-web-admin',
+ 'gluon-web-network',
+ 'gluon-web-wifi-config',
+})
-packages 'mesh-babel' \
- 'gluon-radvd'
+when(_'web-advanced' and _'autoupdater', {
+ 'gluon-web-autoupdater',
+})
-packages '!wireless-encryption-wpa3' \
- 'hostapd-mini'
+
+when(_'mesh-batman-adv-15', {
+ 'gluon-ebtables-limit-arp',
+ 'gluon-radvd',
+})
+
+when(_'status-page' and _'mesh-batman-adv-15', {
+ 'gluon-status-page-mesh-batman-adv',
+})
+
+
+when(_'mesh-babel', {
+ 'gluon-radvd',
+})
+
+
+when(not _'wireless-encryption-wpa3', {
+ 'hostapd-mini',
+})
diff --git a/package/gluon-autoupdater/Config.in b/package/gluon-autoupdater/Config.in
new file mode 100644
index 00000000..554314c9
--- /dev/null
+++ b/package/gluon-autoupdater/Config.in
@@ -0,0 +1,10 @@
+if PACKAGE_gluon-autoupdater
+
+config GLUON_AUTOUPDATER_BRANCH
+ string "Autoupdater branch"
+ default ""
+
+config GLUON_AUTOUPDATER_ENABLED
+ bool "Enable autoupdater by default"
+
+endif
diff --git a/package/gluon-autoupdater/Makefile b/package/gluon-autoupdater/Makefile
index d6e87499..368dce1b 100644
--- a/package/gluon-autoupdater/Makefile
+++ b/package/gluon-autoupdater/Makefile
@@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-autoupdater
PKG_VERSION:=4
-PKG_CONFIG_DEPENDS := CONFIG_GLUON_BRANCH
+PKG_CONFIG_DEPENDS := CONFIG_GLUON_AUTOUPDATER_BRANCH CONFIG_GLUON_AUTOUPDATER_ENABLED
include ../gluon.mk
@@ -13,19 +13,19 @@ define Package/gluon-autoupdater
endef
define Package/gluon-autoupdater/config
-config GLUON_BRANCH
- string "Gluon autoupdater branch"
- depends on PACKAGE_gluon-autoupdater
- default ""
+ source "$(SOURCE)/Config.in"
endef
define Package/gluon-autoupdater/install
$(Gluon/Build/Install)
-ifneq ($(CONFIG_GLUON_BRANCH),"")
$(INSTALL_DIR) $(1)/lib/gluon/autoupdater
- echo '$(call qstrip,$(CONFIG_GLUON_BRANCH))' > $(1)/lib/gluon/autoupdater/default_branch
-endif
+ ifneq ($(CONFIG_GLUON_AUTOUPDATER_BRANCH),"")
+ echo '$(call qstrip,$(CONFIG_GLUON_AUTOUPDATER_BRANCH))' > $(1)/lib/gluon/autoupdater/default_branch
+ endif
+ ifneq ($(CONFIG_GLUON_AUTOUPDATER_ENABLED),)
+ touch $(1)/lib/gluon/autoupdater/default_enabled
+ endif
endef
$(eval $(call BuildPackageGluon,gluon-autoupdater))
diff --git a/package/gluon-autoupdater/check_site.lua b/package/gluon-autoupdater/check_site.lua
index e247cc5d..eaabf285 100644
--- a/package/gluon-autoupdater/check_site.lua
+++ b/package/gluon-autoupdater/check_site.lua
@@ -1,4 +1,4 @@
-need_string(in_site({'autoupdater', 'branch'}))
+need_string(in_site({'autoupdater', 'branch'}), false)
need_table({'autoupdater', 'branches'}, function(branch)
need_alphanumeric_key(branch)
diff --git a/package/gluon-autoupdater/luasrc/lib/gluon/upgrade/500-autoupdater b/package/gluon-autoupdater/luasrc/lib/gluon/upgrade/500-autoupdater
index 88214a86..6ccd3072 100755
--- a/package/gluon-autoupdater/luasrc/lib/gluon/upgrade/500-autoupdater
+++ b/package/gluon-autoupdater/luasrc/lib/gluon/upgrade/500-autoupdater
@@ -2,8 +2,11 @@
local site = require 'gluon.site'
local uci = require('simple-uci').cursor()
+local unistd = require 'posix.unistd'
+local min_branch
+
for name, config in pairs(site.autoupdater.branches()) do
uci:delete('autoupdater', name)
uci:section('autoupdater', 'branch', name, {
@@ -12,19 +15,26 @@ for name, config in pairs(site.autoupdater.branches()) do
good_signatures = config.good_signatures,
pubkey = config.pubkeys,
})
+
+ if not min_branch or (name < min_branch) then
+ min_branch = name
+ end
end
if not uci:get('autoupdater', 'settings') then
- local enabled = false
- local branch = site.autoupdater.branch()
+ local enabled = unistd.access('/lib/gluon/autoupdater/default_enabled') ~= nil
+ local branch = site.autoupdater.branch(min_branch)
local f = io.open('/lib/gluon/autoupdater/default_branch')
if f then
- enabled = true
branch = f:read('*line')
f:close()
end
+ if not branch then
+ enabled = false
+ end
+
uci:section('autoupdater', 'autoupdater', 'settings', {
enabled = enabled,
branch = branch,
diff --git a/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network
index 0942c724..490325cf 100755
--- a/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network
+++ b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network
@@ -40,9 +40,6 @@ uci:section('network', 'interface', 'client', {
uci:save('network')
--- TODO: remove this line and the next in 2019. Firewall zones have been renamed in 2017.
-uci:delete('firewall', 'client')
-
uci:section('firewall', 'zone', 'drop', {
name = 'drop',
network = {'client'},
@@ -51,9 +48,9 @@ uci:section('firewall', 'zone', 'drop', {
forward = 'DROP',
})
-local networks = uci:get_list('firewall', 'local_client', 'network')
+local networks = uci:get_list('firewall', 'loc_client', 'network')
util.add_to_set(networks, 'local_node')
-uci:set_list('firewall', 'local_client', 'network', networks)
+uci:set_list('firewall', 'loc_client', 'network', networks)
local dnsmasq = uci:get_first('dhcp', 'dnsmasq')
@@ -61,10 +58,6 @@ uci:set('dhcp', dnsmasq, 'boguspriv', false)
uci:set('dhcp', dnsmasq, 'localise_queries', false)
uci:set('dhcp', dnsmasq, 'rebind_protection', false)
--- TODO: remove this line and the next two in 2019 the zones were removed in 2017
-uci:delete('dhcp', 'client')
-uci:delete('firewall', 'local_node')
-
uci:section('dhcp', 'dhcp', 'local_client', {
interface = 'client',
ignore = true,
diff --git a/package/gluon-config-mode-geo-location-osm/check_site.lua b/package/gluon-config-mode-geo-location-osm/check_site.lua
index 8e69ba0a..2b3b0cb1 100644
--- a/package/gluon-config-mode-geo-location-osm/check_site.lua
+++ b/package/gluon-config-mode-geo-location-osm/check_site.lua
@@ -2,3 +2,9 @@ need_number(in_site({'config_mode', 'geo_location', 'osm', 'center', 'lon'}))
need_number(in_site({'config_mode', 'geo_location', 'osm', 'center', 'lat'}))
need_number(in_site({'config_mode', 'geo_location', 'osm', 'zoom'}), false)
need_string(in_site({'config_mode', 'geo_location', 'osm', 'openlayers_url'}), false)
+
+if need_table(in_site({'config_mode', 'geo_location', 'osm', 'tile_layer'}), nil, false) then
+ need_one_of(in_site({'config_mode', 'geo_location', 'osm', 'tile_layer', 'type'}), {'XYZ'})
+ need_string(in_site({'config_mode', 'geo_location', 'osm', 'tile_layer', 'url'}))
+ need_string(in_site({'config_mode', 'geo_location', 'osm', 'tile_layer', 'attributions'}))
+end
diff --git a/package/gluon-config-mode-geo-location-osm/luasrc/usr/lib/lua/gluon/config-mode/geo-location-osm.lua b/package/gluon-config-mode-geo-location-osm/luasrc/usr/lib/lua/gluon/config-mode/geo-location-osm.lua
index 0ae54555..39f968c1 100644
--- a/package/gluon-config-mode-geo-location-osm/luasrc/usr/lib/lua/gluon/config-mode/geo-location-osm.lua
+++ b/package/gluon-config-mode-geo-location-osm/luasrc/usr/lib/lua/gluon/config-mode/geo-location-osm.lua
@@ -19,6 +19,7 @@ function M.options()
return {
openlayers_url = config.openlayers_url(),
+ tile_layer = config.tile_layer(),
zoom = config.zoom(12),
pos = config.center(),
}
diff --git a/package/gluon-config-mode-outdoor/luasrc/lib/gluon/config-mode/wizard/0250-outdoor.lua b/package/gluon-config-mode-outdoor/luasrc/lib/gluon/config-mode/wizard/0250-outdoor.lua
index ffa030dd..6a653df8 100644
--- a/package/gluon-config-mode-outdoor/luasrc/lib/gluon/config-mode/wizard/0250-outdoor.lua
+++ b/package/gluon-config-mode-outdoor/luasrc/lib/gluon/config-mode/wizard/0250-outdoor.lua
@@ -1,11 +1,17 @@
return function(form, uci)
local platform = require 'gluon.platform'
+ local wireless = require 'gluon.wireless'
if not (platform.is_outdoor_device() and platform.device_uses_11a(uci)) then
-- only visible on wizard for outdoor devices
return
end
+ if wireless.preserve_channels(uci) then
+ -- Don't show if channel should be preserved
+ return
+ end
+
local pkg_i18n = i18n 'gluon-config-mode-outdoor'
local section = form:section(Section, nil, pkg_i18n.translate(
diff --git a/package/gluon-config-mode-theme/files/lib/gluon/config-mode/www/static/gluon.css b/package/gluon-config-mode-theme/files/lib/gluon/config-mode/www/static/gluon.css
index 16f213e4..3365f449 100644
--- a/package/gluon-config-mode-theme/files/lib/gluon/config-mode/www/static/gluon.css
+++ b/package/gluon-config-mode-theme/files/lib/gluon/config-mode/www/static/gluon.css
@@ -1 +1 @@
-.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.clear{clear:both}.error{color:#ff0000;background-color:white}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar a:link.topcat,#menubar a:visited.topcat{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link.topcat:hover,#menubar a:link.topcat:focus,#menubar a:visited.topcat:hover,#menubar a:visited.topcat:focus{background:#ffb400;color:black}#menubar a:link.topcat.active,#menubar a:visited.topcat.active{background:#ffb400;color:black;font-weight:bold}#menubar div.hostinfo{position:relative;margin:0;padding:0.5em;flex:1;font-weight:bold;font-size:80%}#menubar div.hostinfo a:link,#menubar div.hostinfo a:visited{text-decoration:none;font-weight:bold;color:white}#menubar div.hostinfo a:link:hover,#menubar div.hostinfo a:link:focus,#menubar div.hostinfo a:visited:hover,#menubar div.hostinfo a:visited:focus{text-decoration:underline}#topmenu{list-style:none;margin:0;padding:0}#topmenu li{display:inline-block}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}#maincontent p{margin-bottom:1em}.gluon-section{margin:0;padding:0;border:none;margin-bottom:1.3em}.gluon-section:last-child{margin-bottom:0.7em}.gluon-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.gluon-section h2{margin:0em 0 0.5em -0.5em !important}.gluon-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.gluon-section-descr{margin-bottom:2em}.gluon-osm-map{width:100%;height:40em;margin-bottom:1em}input:placeholder{color:#aaaaaa}input:-webkit-input-placeholder{color:#aaaaaa}input:-moz-placeholder{color:#aaaaaa}input:-ms-input-placeholder{color:#aaaaaa}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;position:relative;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=radio]{display:none}input[type=radio]+label{display:inline-block;position:relative;width:0.8em;height:0.8em;padding:0.5em;margin:0.2em 0.2em 0.2em 0.1em;border:none;background:#ffe199;vertical-align:middle;border-radius:50%}input[type=radio]:checked+label:after{content:'•';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.4em;width:100%;text-align:center;font-size:2em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em;margin-top:1px;margin-bottom:2px;box-sizing:content-box;outline:0}option{color:#003247;background:#ffe199}input[type=image]{border:none}select,input[type=text],input[type=password]{min-width:20em}input.gluon-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.gluon-button::-moz-focus-inner{padding:0;border:0}input.gluon-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.gluon-button:focus{outline:0}input.gluon-button:hover,input.gluon-button:focus{background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.gluon-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.gluon-button-reset{background-color:#e30;color:#fff}input.gluon-button-submit{background-color:#009ee0;color:#fff}input.gluon-button-submit:active{background:grey}.gluon-input-invalid{background:#e30 !important;color:white}div.gluon-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}.gluon-section .gluon-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.gluon-rowstyle-2{color:#000000}div.gluon-value{display:flex;flex-direction:row;margin-bottom:0.5em}.gluon-section-node .gluon-value:last-child{margin-bottom:0}.gluon-value-title{flex:2;text-align:right;padding-top:0.39em;padding-right:1em;font-weight:bold}div.gluon-value-field{flex:3;position:relative}div.gluon-value-field input,div.gluon-value-field select,div.gluon-value-field input+label{position:relative}div.gluon-value-field-text{flex:3;padding-top:0.39em}div.gluon-value-field-long{flex:10;position:relative;margin-top:0.65em}div.gluon-value-field-long input,div.gluon-value-field-long select,div.gluon-value-field-long input+label{position:relative}div.gluon-value-field-long-after{flex:2}div.gluon-value-description{font-size:8pt}div.gluon-section-create{clear:left;white-space:nowrap;vertical-align:top}div.gluon-section-create .gluon-button{margin:0.25em}input.gluon-section-create-name{margin-right:-0.25em}div.gluon-form-descr{margin-bottom:1em}.gluon-form-descr:empty,.gluon-section-descr:empty{display:none}.gluon-form-descr,.gluon-section-descr,.gluon-page-actions{padding:1em;background:#ececec}.gluon-page-actions{text-align:right;display:flex;flex-flow:row-reverse}div.gluon-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.gluon-section-remove{float:right}.gluon-section-node{clear:both;position:relative;border:none}.gluon-section-node-tabbed{border-top-left-radius:0}div.gluon-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}.gluon-value-error input,.gluon-value-error select{background-color:#ffcccc}.gluon-value-field var{color:#2222FF}.gluon-add:after,.gluon-remove:after{cursor:pointer;display:inline-block;text-align:center;vertical-align:middle;font-size:180%;width:1.2em;height:1em}.gluon-add{color:#008000;position:relative;left:21em}input+.gluon-add{left:0;top:0.04em}.gluon-add:first-child{top:0.53em;left:-0.08em}.gluon-add:after{content:'+'}.gluon-remove{color:#800000;position:relative;top:-0.03em}.gluon-remove:after{content:'–'}.left{text-align:left !important}.right{text-align:right !important}.inline{display:inline}.error500{border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em}
+html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}#maincontent ul{margin-left:2em}.error{color:#ff0000;background-color:white}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar a:link.topcat,#menubar a:visited.topcat{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link.topcat:hover,#menubar a:link.topcat:focus,#menubar a:visited.topcat:hover,#menubar a:visited.topcat:focus{background:#ffb400;color:black}#menubar a:link.topcat.active,#menubar a:visited.topcat.active{background:#ffb400;color:black;font-weight:bold}#menubar .hostinfo{position:relative;margin:0;padding:0.5em;flex:1;font-weight:bold;font-size:80%}#menubar .hostinfo a:link,#menubar .hostinfo a:visited{text-decoration:none;font-weight:bold;color:white}#menubar .hostinfo a:link:hover,#menubar .hostinfo a:link:focus,#menubar .hostinfo a:visited:hover,#menubar .hostinfo a:visited:focus{text-decoration:underline}#topmenu{list-style:none;margin:0;padding:0}#topmenu li{display:inline-block}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}#maincontent p{margin-bottom:1em}.gluon-section{margin:0;padding:0;border:none;margin-bottom:1.3em}.gluon-section:last-child{margin-bottom:0.7em}.gluon-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.gluon-section h2{margin:0em 0 0.5em -0.5em}.gluon-section h3{text-decoration:none;font-weight:bold;color:#555555;margin:0.25em;font-size:100%}.gluon-section-descr{margin-bottom:2em}.gluon-osm-map{width:100%;height:40em;margin-bottom:1em}input::placeholder{color:#aaaaaa}input::-webkit-input-placeholder{color:#aaaaaa}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;position:relative;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label::after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=radio]{display:none}input[type=radio]+label{display:inline-block;position:relative;width:0.8em;height:0.8em;padding:0.5em;margin:0.2em 0.2em 0.2em 0.1em;border:none;background:#ffe199;vertical-align:middle;border-radius:50%}input[type=radio]:checked+label::after{content:'•';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.4em;width:100%;text-align:center;font-size:2em}input[type=submit],input[type=reset],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em;margin-top:1px;margin-bottom:2px;box-sizing:content-box;outline:0}.select-wrapper{position:relative;display:inline-block}.select-wrapper::before{position:absolute;z-index:1;right:0.05em;top:calc(2px + 0.1em);bottom:calc(2px + 0.1em);width:1.4em;border-left:0.05em solid rgba(0,0,0,0.25);pointer-events:none;background:url('data:image/svg+xml;utf8,') center/0.8em 0.5em no-repeat;content:''}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer}option{color:#003247;background:#ffe199}select,input[type=text],input[type=password]{min-width:20em}.gluon-button{display:inline-block;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);background-color:#E6E6E6;border:none;text-decoration:none;border-radius:2px;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}.gluon-button::-moz-focus-inner{padding:0;border:0}.gluon-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}.gluon-button:focus{outline:0}.gluon-button:hover,.gluon-button:focus{background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}.gluon-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}.gluon-button-reset{background-color:#e30;color:#fff}.gluon-button-submit{background-color:#009ee0;color:#fff}.gluon-button-submit:active{background:grey}.gluon-input-invalid{background:#e30 !important;color:white}textarea{margin-left:-1px;margin-bottom:0.5em}.gluon-value{display:flex;flex-direction:row;margin-bottom:0.5em}.gluon-section-node .gluon-value:last-child{margin-bottom:0}.gluon-value-title{flex:2;text-align:right;padding-top:0.39em;padding-right:1em;font-weight:bold}.gluon-value-field{flex:3;position:relative}.gluon-value-field input,.gluon-value-field select,.gluon-value-field input+label{position:relative}.gluon-value-field-text{flex:3;padding-top:0.39em}.gluon-value-field-long{flex:10;position:relative;margin-top:0.65em}.gluon-value-field-long input,.gluon-value-field-long select,.gluon-value-field-long input+label{position:relative}.gluon-value-field-long-after{flex:2}.gluon-value-description{font-size:8pt}.gluon-form-descr{margin-bottom:1em}.gluon-form-descr:empty,.gluon-section-descr:empty{display:none}.gluon-form-descr,.gluon-section-descr,.gluon-page-actions{padding:1em;background:#ececec}.gluon-page-actions{text-align:right;display:flex;flex-flow:row-reverse}.gluon-section-node{clear:both;position:relative;border:none}.gluon-value-error input,.gluon-value-error select{background-color:#ffcccc}.gluon-add::after,.gluon-remove::after{cursor:pointer;display:inline-block;text-align:center;vertical-align:middle;font-size:180%;width:1.2em;height:1em}.gluon-add{color:#008000;position:relative;left:21em}input+.gluon-add{left:0;top:0.04em}.gluon-add:first-child{top:0.53em;left:-0.08em}.gluon-add::after{content:'+'}.gluon-remove{color:#800000;position:relative;top:-0.03em}.gluon-remove::after{content:'–'}.error500{border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em}
diff --git a/package/gluon-config-mode-theme/sass/gluon.scss b/package/gluon-config-mode-theme/sass/gluon.scss
index e1a59560..5e1aeda7 100644
--- a/package/gluon-config-mode-theme/sass/gluon.scss
+++ b/package/gluon-config-mode-theme/sass/gluon.scss
@@ -1,13 +1,13 @@
/*
- ATTENTION: This file is not compiled when building gluon.
- The compiled version is at ../files/lib/gluon/config-mode/www/static/gluon.css
+ ATTENTION: This file is not compiled when building gluon.
+ The compiled version is at ../files/lib/gluon/config-mode/www/static/gluon.css
- Use sass like this to update it:
+ Use sass like this to update it:
- sass --sourcemap=none -C -t compressed sass/gluon.scss files/lib/gluon/config-mode/www/static/gluon.css
+ sass --sourcemap=none -C -t compressed sass/gluon.scss files/lib/gluon/config-mode/www/static/gluon.css
- When commiting changes to this file make sure to commit the respective
- changes to the compilid version within the same commit!
+ When commiting changes to this file make sure to commit the respective
+ changes to the compilid version within the same commit!
*/
@charset "utf-8";
@@ -18,624 +18,530 @@ $ffzusatz: #009ee0;
$red: #ee3300;
@mixin button {
- &::-moz-focus-inner {
- padding: 0;
- border: 0;
- }
+ &::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+ }
- display: inline-block;
- zoom: 1;
- line-height: normal;
- white-space: nowrap;
- vertical-align: baseline;
- text-align: center;
- cursor: pointer;
- user-select: none;
+ display: inline-block;
+ line-height: normal;
+ white-space: nowrap;
+ vertical-align: baseline;
+ text-align: center;
+ cursor: pointer;
+ user-select: none;
- font-size: 100%;
- padding: 0.5em 1em;
- color: rgba(0, 0, 0, 0.80);
- border: none rgba(0, 0, 0, 0);
- background-color: #E6E6E6;
- text-decoration: none;
- border-radius: 2px;
+ font-size: 100%;
+ padding: 0.5em 1em;
+ color: rgba(0, 0, 0, 0.80);
+ background-color: #E6E6E6;
+ border: none;
+ text-decoration: none;
+ border-radius: 2px;
- /* Transitions */
- transition: 0.1s linear box-shadow;
+ /* Transitions */
+ transition: 0.1s linear box-shadow;
- &:active {
- box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset;
- }
+ &:active {
+ box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset;
+ }
- &:focus {
- outline: 0;
- }
+ &:focus {
+ outline: 0;
+ }
- &:hover, &:focus {
- background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
- }
+ &:hover, &:focus {
+ background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
+ }
- &[disabled] {
- border: none;
- background-image: none;
- opacity: 0.40;
- cursor: not-allowed;
- box-shadow: none;
- }
-}
-
-@mixin button-primary {
- background-color: $ffzusatz;
- color: #fff;
-}
-
-.lang_he {
- direction: RTL;
- unicode-bidi: embed;
-}
-
-.hidden {
- display: none;
+ &[disabled] {
+ border: none;
+ background-image: none;
+ opacity: 0.40;
+ cursor: not-allowed;
+ box-shadow: none;
+ }
}
html {
- min-height: 100%;
- height: auto;
- position:relative;
+ min-height: 100%;
+ height: auto;
+ position: relative;
}
body, input, select, option {
- font-family: 'Open Sans', Arial, sans-serif;
- font-size: 12pt;
+ font-family: 'Open Sans', Arial, sans-serif;
+ font-size: 12pt;
}
body {
- color: rgb(77, 78, 83);
- line-height: 1.5em;
- margin: 0;
- display: flex;
- flex-direction: column;
- min-height: 100vh;
- background-color: #f3f3f3;
-}
-
-a img {
- border: none;
- text-decoration: none;
+ color: rgb(77, 78, 83);
+ line-height: 1.5em;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ background-color: #f3f3f3;
}
.tabmenu1 {
- text-align: center;
+ text-align: center;
}
ul.tabmenu {
- list-style: none;
- padding: 0;
- margin: 2em 0;
- display: inline-flex;
+ list-style: none;
+ padding: 0;
+ margin: 2em 0;
+ display: inline-flex;
}
ul.tabmenu li {
- white-space: nowrap;
- margin: 0 0.5em;
- padding: 0;
- text-align: center;
+ white-space: nowrap;
+ margin: 0 0.5em;
+ padding: 0;
+ text-align: center;
- a {
- display: block;
- text-decoration: none;
- padding: 1em;
- margin: 0;
- color: #333;
- border-radius: 2em;
+ a {
+ display: block;
+ text-decoration: none;
+ padding: 1em;
+ margin: 0;
+ color: #333;
+ border-radius: 2em;
- &:hover {
- background: lighten($ffyellow, 35);
- }
- }
+ &:hover {
+ background: lighten($ffyellow, 35);
+ }
+ }
- &.active a {
- font-weight: bold;
- background: white;
- color: #333;
- }
-}
-
-abbr,
-acronym {
- font-style: normal;
- font-variant: normal;
-}
-
-abbr[title],
-acronym[title] {
- border-bottom: 1px dotted;
- cursor: help;
-}
-
-a:link abbr[title],
-a:visited abbr[title],
-a:link acronym[title],
-a:visited acronym[title] {
- cursor: pointer;
-}
-
-code {
- font-family: monospace;
- white-space: pre;
+ &.active a {
+ font-weight: bold;
+ background: white;
+ color: #333;
+ }
}
#maincontent ul {
- margin-left: 2em;
-}
-
-.clear {
- clear: both;
+ margin-left: 2em;
}
.error {
- color: #ff0000;
- background-color: white;
+ color: #ff0000;
+ background-color: white;
}
#menubar {
- display: flex;
- background: $ffmagenta;
- color: #ffffff;
+ display: flex;
+ background: $ffmagenta;
+ color: #ffffff;
}
#menubar a:link.topcat,
#menubar a:visited.topcat {
- position: relative;
- display: block;
- padding: 0.5em;
- text-decoration: none;
- font-size: 80%;
- font-weight: normal;
- color: white;
+ position: relative;
+ display: block;
+ padding: 0.5em;
+ text-decoration: none;
+ font-size: 80%;
+ font-weight: normal;
+ color: white;
- &:hover, &:focus {
- background: $ffyellow;
- color: black;
- }
+ &:hover, &:focus {
+ background: $ffyellow;
+ color: black;
+ }
- &.active {
- background: $ffyellow;
- color: black;
- font-weight: bold;
- }
+ &.active {
+ background: $ffyellow;
+ color: black;
+ font-weight: bold;
+ }
}
-#menubar div.hostinfo {
- position: relative;
- margin: 0;
- padding: 0.5em;
- flex: 1;
- font-weight: bold;
- font-size: 80%;
+#menubar .hostinfo {
+ position: relative;
+ margin: 0;
+ padding: 0.5em;
+ flex: 1;
+ font-weight: bold;
+ font-size: 80%;
}
-#menubar div.hostinfo a {
- &:link, &:visited {
- text-decoration: none;
- font-weight: bold;
- color: white;
+#menubar .hostinfo a {
+ &:link, &:visited {
+ text-decoration: none;
+ font-weight: bold;
+ color: white;
- &:hover, &:focus {
- text-decoration: underline;
- }
- }
+ &:hover, &:focus {
+ text-decoration: underline;
+ }
+ }
}
#topmenu {
- list-style: none;
- margin: 0;
- padding: 0;
+ list-style: none;
+ margin: 0;
+ padding: 0;
}
#topmenu li {
- display: inline-block;
+ display: inline-block;
}
#maincontent {
- padding: 0 1em 2em;
- max-width: 60em;
- min-width: 40em;
- margin: 1em auto;
+ padding: 0 1em 2em;
+ max-width: 60em;
+ min-width: 40em;
+ margin: 1em auto;
}
#maincontent p {
- margin-bottom: 1em;
+ margin-bottom: 1em;
}
.gluon-section {
- margin: 0;
- padding: 0;
- border: none;
- margin-bottom: 1.3em;
+ margin: 0;
+ padding: 0;
+ border: none;
+ margin-bottom: 1.3em;
}
.gluon-section:last-child {
- margin-bottom: 0.7em;
+ margin-bottom: 0.7em;
}
.gluon-section legend {
- font-size: 1.4em;
- font-weight: bold;
- position: relative;
- padding: 0;
- margin-bottom: 0.5em;
+ font-size: 1.4em;
+ font-weight: bold;
+ position: relative;
+ padding: 0;
+ margin-bottom: 0.5em;
}
.gluon-section h2 {
- margin: 0em 0 0.5em -0.5em !important;
+ margin: 0em 0 0.5em -0.5em;
}
.gluon-section h3 {
- text-decoration: none !important;
- font-weight: bold !important;
- color: #555555 !important;
- margin: 0.25em !important;
- font-size: 100% !important;
+ text-decoration: none;
+ font-weight: bold;
+ color: #555555;
+ margin: 0.25em;
+ font-size: 100%;
}
.gluon-section-descr {
- margin-bottom: 2em;
+ margin-bottom: 2em;
}
.gluon-osm-map {
- width: 100%;
- height: 40em;
- margin-bottom: 1em;
+ width: 100%;
+ height: 40em;
+ margin-bottom: 1em;
}
-input:placeholder {
- color: #aaaaaa;
+input::placeholder {
+ color: #aaaaaa;
}
-input:-webkit-input-placeholder {
- color: #aaaaaa;
-}
-
-input:-moz-placeholder {
- color: #aaaaaa;
-}
-
-input:-ms-input-placeholder {
- color: #aaaaaa;
+input::-webkit-input-placeholder {
+ color: #aaaaaa;
}
input[type=checkbox] {
- display: none;
+ display: none;
- & + label {
- display: inline-block;
- position: relative;
- width: 1em;
- height: 1em;
- margin: 0;
- }
+ & + label {
+ display: inline-block;
+ position: relative;
+ width: 1em;
+ height: 1em;
+ margin: 0;
+ }
- &:checked + label:after {
- content: '✔';
- color: $ffmagenta;
- vertical-align: middle;
- position: absolute;
- top: 50%;
- left: 0;
- margin-top: -0.5em;
- width: 100%;
- text-align: center;
- font-size: 1.7em;
- }
+ &:checked + label::after {
+ content: '✔';
+ color: $ffmagenta;
+ vertical-align: middle;
+ position: absolute;
+ top: 50%;
+ left: 0;
+ margin-top: -0.5em;
+ width: 100%;
+ text-align: center;
+ font-size: 1.7em;
+ }
}
input[type=radio] {
- display: none;
+ display: none;
- & + label {
- display: inline-block;
- position: relative;
- width: 0.8em;
- height: 0.8em;
- padding: 0.5em;
- margin: 0.2em 0.2em 0.2em 0.1em;
- border: none;
- background: lighten($ffyellow, 30);
- vertical-align: middle;
- border-radius: 50%;
- }
+ & + label {
+ display: inline-block;
+ position: relative;
+ width: 0.8em;
+ height: 0.8em;
+ padding: 0.5em;
+ margin: 0.2em 0.2em 0.2em 0.1em;
+ border: none;
+ background: lighten($ffyellow, 30);
+ vertical-align: middle;
+ border-radius: 50%;
+ }
- &:checked + label:after {
- content: '•';
- color: $ffmagenta;
- vertical-align: middle;
- position: absolute;
- top: 50%;
- left: 0;
- margin-top: -0.4em;
- width: 100%;
- text-align: center;
- font-size: 2em;
- }
+ &:checked + label::after {
+ content: '•';
+ color: $ffmagenta;
+ vertical-align: middle;
+ position: absolute;
+ top: 50%;
+ left: 0;
+ margin-top: -0.4em;
+ width: 100%;
+ text-align: center;
+ font-size: 2em;
+ }
}
input[type=submit],
input[type=reset],
-input[type=image],
input[type=button] {
- cursor: pointer;
+ cursor: pointer;
}
select,
input,
textarea,
input[type=checkbox] + label {
- color: darken($ffzusatz, 30);
- border: none;
- background: lighten($ffyellow, 30);
- border-radius: 3pt;
- padding: 0.5em;
- margin-top: 1px;
- margin-bottom: 2px;
- box-sizing: content-box;
- outline: 0;
+ color: darken($ffzusatz, 30);
+ border: none;
+ background: lighten($ffyellow, 30);
+ border-radius: 3pt;
+ padding: 0.5em;
+ margin-top: 1px;
+ margin-bottom: 2px;
+ box-sizing: content-box;
+ outline: 0;
+}
+
+.select-wrapper {
+ position: relative;
+ display: inline-block;
+
+ &::before {
+ position: absolute;
+ z-index: 1;
+ right: 0.05em;
+ top: calc(2px + 0.1em);
+ bottom: calc(2px + 0.1em);
+ width: 1.4em;
+ border-left: 0.05em solid rgba(0, 0, 0, 0.25);
+ pointer-events: none;
+ background:
+ url('data:image/svg+xml;utf8,')
+ center / 0.8em 0.5em
+ no-repeat
+ ;
+ content: '';
+ }
+
+ select {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ cursor: pointer;
+ }
}
option {
- color: darken($ffzusatz, 30);
- background: lighten($ffyellow, 30);
-}
-
-input[type=image] {
- border: none;
+ color: darken($ffzusatz, 30);
+ background: lighten($ffyellow, 30);
}
select,
input[type=text],
input[type=password] {
- min-width: 20em;
+ min-width: 20em;
}
-input.gluon-button {
- @include button;
+.gluon-button {
+ @include button;
- margin-left: 0.5em;
- background-repeat: no-repeat;
+ margin-left: 0.5em;
+ background-repeat: no-repeat;
}
-input.gluon-button-reset {
- background-color: $red;
- color: #fff;
-}
-input.gluon-button-submit {
- @include button-primary;
+.gluon-button-reset {
+ background-color: $red;
+ color: #fff;
}
-input.gluon-button-submit:active {
- background: grey;
+.gluon-button-submit {
+ background-color: $ffzusatz;
+ color: #fff;
+}
+.gluon-button-submit:active {
+ background: grey;
}
.gluon-input-invalid {
- background: $red !important;
- color: white;
-}
-
-div.gluon-section-remove input {
- border-bottom: none;
+ background: $red !important;
+ color: white;
}
textarea {
- margin-left: -1px;
- margin-bottom: 0.5em;
+ margin-left: -1px;
+ margin-bottom: 0.5em;
}
-.gluon-section .gluon-rowstyle-1 h3 {
- background-color: #eeeeff;
- color: #555555;
-}
-
-.gluon-rowstyle-2 {
- color: #000000;
-}
-
-div.gluon-value {
- display: flex;
- flex-direction: row;
- margin-bottom: 0.5em;
+.gluon-value {
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 0.5em;
}
.gluon-section-node .gluon-value:last-child {
- margin-bottom: 0;
+ margin-bottom: 0;
}
.gluon-value-title {
- flex: 2;
- text-align: right;
- padding-top: 0.39em;
- padding-right: 1em;
- font-weight: bold;
+ flex: 2;
+ text-align: right;
+ padding-top: 0.39em;
+ padding-right: 1em;
+ font-weight: bold;
}
-div.gluon-value-field {
- flex: 3;
- position: relative;
+.gluon-value-field {
+ flex: 3;
+ position: relative;
- input, select, input + label {
- position: relative;
- }
+ input, select, input + label {
+ position: relative;
+ }
}
-div.gluon-value-field-text {
- flex: 3;
- padding-top: 0.39em;
+.gluon-value-field-text {
+ flex: 3;
+ padding-top: 0.39em;
}
-div.gluon-value-field-long {
- flex: 10;
- position: relative;
- margin-top: 0.65em;
+.gluon-value-field-long {
+ flex: 10;
+ position: relative;
+ margin-top: 0.65em;
- input, select, input + label {
- position: relative;
- }
+ input, select, input + label {
+ position: relative;
+ }
}
-div.gluon-value-field-long-after {
- flex: 2;
+.gluon-value-field-long-after {
+ flex: 2;
}
-div.gluon-value-description {
- font-size: 8pt;
+.gluon-value-description {
+ font-size: 8pt;
}
-div.gluon-section-create {
- clear: left;
- white-space: nowrap;
- vertical-align: top;
-}
-
-div.gluon-section-create .gluon-button {
- margin: 0.25em;
-}
-
-input.gluon-section-create-name {
- margin-right: -0.25em;
-}
-
-div.gluon-form-descr {
- margin-bottom: 1em;
+.gluon-form-descr {
+ margin-bottom: 1em;
}
.gluon-form-descr:empty, .gluon-section-descr:empty {
- display: none;
+ display: none;
}
.gluon-form-descr, .gluon-section-descr, .gluon-page-actions {
- padding: 1em;
- background: #ececec;
+ padding: 1em;
+ background: #ececec;
}
.gluon-page-actions {
- text-align: right;
- display: flex;
- flex-flow: row-reverse;
-}
-
-div.gluon-optionals {
- padding: 0.25em;
- border-bottom: 1px dotted #bbbbbb;
-}
-
-div.gluon-section-remove {
- float: right;
+ text-align: right;
+ display: flex;
+ flex-flow: row-reverse;
}
.gluon-section-node {
- clear: both;
- position: relative;
- border: none;
-}
-
-.gluon-section-node-tabbed {
- border-top-left-radius: 0;
-}
-
-div.gluon-error {
- font-size: 95%;
- font-weight: bold;
- color: #ff0000;
- background-color: #ffffff;
+ clear: both;
+ position: relative;
+ border: none;
}
.gluon-value-error input,
.gluon-value-error select {
- background-color: #ffcccc;
+ background-color: #ffcccc;
}
-.gluon-value-field var {
- color: #2222FF;
-}
-
-.gluon-add:after, .gluon-remove:after {
- cursor: pointer;
- display: inline-block;
- text-align: center;
- vertical-align: middle;
- font-size: 180%;
- width: 1.2em;
- height: 1em;
+.gluon-add::after, .gluon-remove::after {
+ cursor: pointer;
+ display: inline-block;
+ text-align: center;
+ vertical-align: middle;
+ font-size: 180%;
+ width: 1.2em;
+ height: 1em;
}
.gluon-add {
- color: #008000;
+ color: #008000;
- position: relative;
- left: 21em;
+ position: relative;
+ left: 21em;
- input + & {
- left: 0;
- top: 0.04em;
- }
+ input + & {
+ left: 0;
+ top: 0.04em;
+ }
- &:first-child {
- top: 0.53em;
- left: -0.08em;
- }
+ &:first-child {
+ top: 0.53em;
+ left: -0.08em;
+ }
- &:after {
- content: '+';
- }
+ &::after {
+ content: '+';
+ }
}
.gluon-remove {
- color: #800000;
+ color: #800000;
- position: relative;
- top: -0.03em;
+ position: relative;
+ top: -0.03em;
- &:after {
- content: '–';
- }
-}
-
-.left {
- text-align: left !important;
-}
-
-.right {
- text-align: right !important;
-}
-
-.inline {
- display: inline;
+ &::after {
+ content: '–';
+ }
}
.error500 {
- border: 1px dotted #ff0000;
- background-color: #ffffff;
- color: #000000;
- padding: 0.5em;
+ border: 1px dotted #ff0000;
+ background-color: #ffffff;
+ color: #000000;
+ padding: 0.5em;
}
.errorbox {
- border: 1px solid #FF0000;
- background-color: #FFCCCC;
- padding: 5px;
- margin-bottom: 5px;
+ border: 1px solid #FF0000;
+ background-color: #FFCCCC;
+ padding: 5px;
+ margin-bottom: 5px;
}
.errorbox a {
- color: #000000 !important;
+ color: #000000 !important;
}
.the-key {
- text-align: left;
- font-size: 1.4em;
- background: lighten($ffyellow, 35);
- border: 3pt dashed $ffmagenta;
- margin-bottom: 0.5em;
- padding: 0.5em
+ text-align: left;
+ font-size: 1.4em;
+ background: lighten($ffyellow, 35);
+ border: 3pt dashed $ffmagenta;
+ margin-bottom: 0.5em;
+ padding: 0.5em
}
diff --git a/package/gluon-core/files/etc/init.d/gluon-core-reconfigure b/package/gluon-core/files/etc/init.d/gluon-core-reconfigure
new file mode 100755
index 00000000..0a563571
--- /dev/null
+++ b/package/gluon-core/files/etc/init.d/gluon-core-reconfigure
@@ -0,0 +1,12 @@
+#!/bin/sh /etc/rc.common
+
+# Start right after S10boot
+START=10
+
+start() {
+ config_load gluon
+ config_get_bool reconfigure core reconfigure 0
+ if [ "$reconfigure" = 1 ]; then
+ gluon-reconfigure
+ fi
+}
diff --git a/package/gluon-core/files/lib/gluon/reload.d/710-gluon-core-reconfigure-start b/package/gluon-core/files/lib/gluon/reload.d/710-gluon-core-reconfigure-start
new file mode 100755
index 00000000..758bb913
--- /dev/null
+++ b/package/gluon-core/files/lib/gluon/reload.d/710-gluon-core-reconfigure-start
@@ -0,0 +1,2 @@
+#!/bin/sh
+/etc/init.d/gluon-core-reconfigure start
diff --git a/package/gluon-core/files/lib/gluon/upgrade/100-core-reset-sysctl b/package/gluon-core/files/lib/gluon/upgrade/100-core-reset-sysctl
deleted file mode 100755
index 6f6f4316..00000000
--- a/package/gluon-core/files/lib/gluon/upgrade/100-core-reset-sysctl
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-# This script can be removed after Gluon v2018.2
-
-# Check for a random line that always was in /etc/sysctl.conf
-if grep -qxF 'net.ipv4.ip_forward=1' /etc/sysctl.conf; then
- echo '# Defaults are configured in /etc/sysctl.d/* and can be customized in this file' >/etc/sysctl.conf
-fi
diff --git a/package/gluon-core/files/lib/gluon/upgrade/998-commit b/package/gluon-core/files/lib/gluon/upgrade/998-commit
index db578a78..8b4be6a9 100755
--- a/package/gluon-core/files/lib/gluon/upgrade/998-commit
+++ b/package/gluon-core/files/lib/gluon/upgrade/998-commit
@@ -1,3 +1,6 @@
#!/bin/sh
-exec uci commit
+uci -q batch <<-EOF
+ delete gluon.core.reconfigure
+ commit
+EOF
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/005-set-domain b/package/gluon-core/luasrc/lib/gluon/upgrade/005-set-domain
new file mode 100755
index 00000000..680eab23
--- /dev/null
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/005-set-domain
@@ -0,0 +1,48 @@
+#!/usr/bin/lua
+
+local unistd = require 'posix.unistd'
+
+
+if not unistd.access('/lib/gluon/domains/') then
+ return
+end
+
+
+local function domain_exists(domain)
+ return unistd.access('/lib/gluon/domains/' .. domain .. '.json') == 0
+end
+
+
+local uci = require('simple-uci').cursor()
+
+local domain = uci:get('gluon', 'core', 'switch_domain')
+if domain and not domain_exists(domain) then
+ io.stderr:write(
+ string.format("Warning: invalid mesh domain switch to '%s' configured, not switching\n", domain)
+ )
+ domain = nil
+end
+
+if not domain then
+ domain = uci:get('gluon', 'core', 'domain')
+end
+if domain and not domain_exists(domain) then
+ io.stderr:write(
+ string.format("Warning: invalid mesh domain '%s' configured, resetting to default...\n", domain)
+ )
+ domain = nil
+end
+
+if not domain then
+
+ -- We can't use gluon.site yet, as it depends on gluon.core.domain to be set
+ local json = require 'jsonc'
+ local site = assert(json.load('/lib/gluon/site.json'))
+
+ domain = site.default_domain
+
+end
+
+uci:set('gluon', 'core', 'domain', domain)
+uci:delete('gluon', 'core', 'switch_domain')
+uci:save('gluon')
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/005-site-domain b/package/gluon-core/luasrc/lib/gluon/upgrade/005-site-domain
deleted file mode 100755
index 2014dce6..00000000
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/005-site-domain
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/lua
-
-local unistd = require 'posix.unistd'
-
-
-if not unistd.access('/lib/gluon/domains/') then
- return
-end
-
-
-local uci = require('simple-uci').cursor()
-
-local domain = uci:get('gluon', 'core', 'domain')
-if domain and not unistd.access('/lib/gluon/domains/' .. domain .. '.json') then
- io.stderr:write(string.format("Warning: invalid mesh domain '%s' configured, resetting to default...\n", domain))
- domain = nil
-end
-
-if domain then return end
-
-
--- We can't use gluon.site yet, as it depends on gluon.core.domain to be set
-local json = require 'jsonc'
-local site = assert(json.load('/lib/gluon/site.json'))
-
-uci:set('gluon', 'core', 'domain', site.default_domain)
-uci:commit('gluon')
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac b/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
index fd1f1232..813d5374 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
@@ -111,6 +111,7 @@ local primary_addrs = {
'c20i',
'c50',
'tplink,c2-v1',
+ 'ex3700'
}},
{'x86'},
}},
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces b/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces
index 1e101f70..5bb1926d 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces
@@ -11,9 +11,12 @@ end
local platform = require 'gluon.platform'
local site = require 'gluon.site'
+local json = require 'jsonc'
local uci = require('simple-uci').cursor()
local unistd = require 'posix.unistd'
+local board_data = json.load('/etc/board.json')
+local network_data = (board_data or {}).network
local function iface_exists(ifaces)
if not ifaces then return nil end
@@ -26,8 +29,8 @@ local function iface_exists(ifaces)
end
-local lan_ifname = iface_exists(uci:get('network', 'lan', 'ifname'))
-local wan_ifname = iface_exists(uci:get('network', 'wan', 'ifname'))
+local lan_ifname = iface_exists((network_data.lan or {}).ifname)
+local wan_ifname = iface_exists((network_data.wan or {}).ifname)
if platform.match('ar71xx', 'generic', {
'cpe210',
@@ -42,6 +45,16 @@ if platform.match('ar71xx', 'generic', {
'unifiac-pro',
}) then
lan_ifname, wan_ifname = wan_ifname, lan_ifname
+elseif platform.match('lantiq') then
+ local switch_data = board_data.switch or {}
+ local switch0_data = switch_data.switch0 or {}
+ local roles_data = switch0_data.roles or {}
+ for _, role_data in ipairs(roles_data) do
+ if role_data.role == 'wan' then
+ wan_ifname = iface_exists(role_data.device)
+ break
+ end
+ end
end
if wan_ifname and lan_ifname then
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless b/package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless
index 073d0694..9f1121f6 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless
@@ -54,7 +54,7 @@ end
local function get_channel(radio, config)
local channel
- if uci:get_first('gluon-core', 'wireless', 'preserve_channels') then
+ if wireless.preserve_channels(uci) then
-- preserved channel always wins
channel = radio.channel
elseif (radio.hwmode == '11a' or radio.hwmode == '11na') and is_outdoor() then
@@ -82,20 +82,20 @@ local function get_htmode(radio)
end
local function is_disabled(name)
- if uci:get('wireless', name) then
- return uci:get_bool('wireless', name, 'disabled')
- else
+ if not uci:get('wireless', name) then
return nil
end
+
+ return uci:get_bool('wireless', name, 'disabled')
end
-- Returns the first argument that is not nil; don't call without any non-nil arguments!
local function first_non_nil(first, ...)
if first ~= nil then
return first
- else
- return first_non_nil(...)
end
+
+ return first_non_nil(...)
end
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/140-firewall-rules b/package/gluon-core/luasrc/lib/gluon/upgrade/300-firewall-rules
similarity index 84%
rename from package/gluon-core/luasrc/lib/gluon/upgrade/140-firewall-rules
rename to package/gluon-core/luasrc/lib/gluon/upgrade/300-firewall-rules
index e835e2f2..605f6684 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/140-firewall-rules
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/300-firewall-rules
@@ -18,7 +18,7 @@ end
uci:foreach('firewall', 'zone', reject_input_on_wan)
-for _, zone in ipairs({'mesh', 'local_client', 'wired_mesh'}) do
+for _, zone in ipairs({'mesh', 'loc_client', 'wired_mesh'}) do
-- Other packages assign interfaces to these zones
uci:section('firewall', 'zone', zone, {
name = zone,
@@ -52,13 +52,16 @@ for _, zone in ipairs({'mesh', 'local_client', 'wired_mesh'}) do
family = 'ipv6',
target = 'ACCEPT',
})
-
- -- Can be removed soon: was never in a release
- uci:delete('firewall', zone .. '_ICMPv6_out')
end
-uci:section('firewall', 'rule', 'local_client_ICMPv4_in', {
- src = 'local_client',
+-- ToDo Remove in v2022.x
+uci:delete('firewall', 'local_client')
+uci:delete('firewall', 'local_client_ssh')
+uci:delete('firewall', 'local_client_ICMPv4_in')
+uci:delete('firewall', 'local_client_ICMPv6_in')
+
+uci:section('firewall', 'rule', 'loc_client_ICMPv4_in', {
+ src = 'loc_client',
proto = 'icmp',
icmp_type = {
'echo-request',
@@ -67,9 +70,8 @@ uci:section('firewall', 'rule', 'local_client_ICMPv4_in', {
target = 'ACCEPT',
})
-
-- allow inbound SSH from anywhere
-for _, zone in ipairs({ 'wan', 'local_client', 'mesh' }) do
+for _, zone in ipairs({ 'wan', 'loc_client', 'mesh' }) do
uci:section('firewall', 'rule', zone .. '_ssh', {
name = zone .. '_ssh',
src = zone,
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config b/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config
index 18b44d3f..f3fdfbff 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config
@@ -18,7 +18,7 @@ uci:delete('firewall', 'client_dns')
if dns.servers then
-- allow inbound traffic for dns from client zone
uci:section('firewall', 'rule', 'client_dns', {
- src = 'local_client',
+ src = 'loc_client',
dest_port = '53',
proto = 'tcpudp',
target = 'ACCEPT',
diff --git a/package/gluon-core/luasrc/usr/bin/gluon-switch-domain b/package/gluon-core/luasrc/usr/bin/gluon-switch-domain
new file mode 100755
index 00000000..a964bde9
--- /dev/null
+++ b/package/gluon-core/luasrc/usr/bin/gluon-switch-domain
@@ -0,0 +1,56 @@
+#!/usr/bin/lua
+
+local unistd = require 'posix.unistd'
+
+
+local function shift()
+ table.remove(arg, 1)
+end
+
+local reboot = true
+if arg[1] == '--no-reboot' then
+ reboot = false
+ shift()
+end
+
+local setup_mode = unistd.access('/var/gluon/setup-mode') == 0
+
+if #arg ~= 1 then
+ io.stderr:write('Usage: gluon-switch-domain [--no-reboot] \n')
+ os.exit(1)
+end
+local domain = arg[1]
+
+
+if not unistd.access('/lib/gluon/domains/') then
+ io.stderr:write('This Gluon firmware does not support multiple mesh domains.\n')
+ os.exit(1)
+end
+
+
+local function domain_exists(dom)
+ return unistd.access('/lib/gluon/domains/' .. dom .. '.json') == 0
+end
+
+if not domain_exists(domain) then
+ io.stderr:write(string.format("Error: invalid mesh domain '%s'\n", domain))
+ os.exit(1)
+end
+
+
+local uci = require('simple-uci').cursor()
+uci:set('gluon', 'core', 'switch_domain', domain)
+uci:set('gluon', 'core', 'reconfigure', true)
+uci:save('gluon')
+
+local cmd
+if setup_mode then
+ cmd = 'gluon-reconfigure'
+elseif reboot then
+ uci:commit('gluon')
+ cmd = 'reboot'
+else
+ cmd = 'gluon-reload'
+end
+
+unistd.execp(cmd, {[0] = cmd})
diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
index b4fc708b..213eb150 100644
--- a/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
+++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
@@ -66,7 +66,7 @@ end
function M.device_supports_wpa3()
-- rt2x00 crashes when enabling WPA3 personal / OWE VAP
- if M.match('ramips', 'rt305x') or M.match('ramips', 'mt7620') then
+ if M.match('ramips', 'rt305x') then
return false
end
diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/wireless.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/wireless.lua
index 8a2f4ed8..4f2cf088 100644
--- a/package/gluon-core/luasrc/usr/lib/lua/gluon/wireless.lua
+++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/wireless.lua
@@ -96,4 +96,8 @@ function M.foreach_radio(uci, f)
end
end
+function M.preserve_channels(uci)
+ return uci:get_first('gluon-core', 'wireless', 'preserve_channels')
+end
+
return M
diff --git a/package/gluon-ebtables-filter-multicast/luasrc/lib/gluon/ebtables/110-mcast-allow-respondd b/package/gluon-ebtables-filter-multicast/luasrc/lib/gluon/ebtables/110-mcast-allow-respondd
new file mode 100644
index 00000000..7df37ec9
--- /dev/null
+++ b/package/gluon-ebtables-filter-multicast/luasrc/lib/gluon/ebtables/110-mcast-allow-respondd
@@ -0,0 +1 @@
+rule 'MULTICAST_OUT -p IPv6 --ip6-protocol udp --ip6-destination-port 1001 --ip6-dst ff05::2:1001 -j RETURN'
diff --git a/package/gluon-hoodselector/luasrc/usr/lib/lua/hoodselector/util.lua b/package/gluon-hoodselector/luasrc/usr/lib/lua/hoodselector/util.lua
index b93097a6..af079f36 100644
--- a/package/gluon-hoodselector/luasrc/usr/lib/lua/hoodselector/util.lua
+++ b/package/gluon-hoodselector/luasrc/usr/lib/lua/hoodselector/util.lua
@@ -67,9 +67,7 @@ end
function M.set_domain_config(domain)
if uci:get('gluon', 'core', 'domain') ~= domain.domain_code then
- uci:set('gluon', 'core', 'domain', domain.domain_code)
- uci:commit('gluon')
- os.execute('gluon-reconfigure')
+ os.execute(string.format("exec gluon-switch-domain --no-reboot '%s'", domain.domain_code))
M.log('Set domain "'..domain.domain.domain_names[domain.domain_code]..'"')
return true
end
diff --git a/package/gluon-hoodselector/luasrc/usr/sbin/hoodselector b/package/gluon-hoodselector/luasrc/usr/sbin/hoodselector
index 12125da7..03852272 100755
--- a/package/gluon-hoodselector/luasrc/usr/sbin/hoodselector
+++ b/package/gluon-hoodselector/luasrc/usr/sbin/hoodselector
@@ -40,7 +40,6 @@ if geo.lat ~= nil and geo.lon ~= nil then
local geo_base_domain = hoodutil.get_domain_by_geo(jdomains, geo)
if geo_base_domain ~= nil then
if hoodutil.set_domain_config(geo_base_domain) then
- os.execute("gluon-reload")
hoodutil.log('Domain set by geolocation mode.\n')
end
return
@@ -51,6 +50,4 @@ else
end
-- default domain mode
-if hoodutil.set_domain_config(hoodutil.get_default_domain(hoodutil.get_domains())) then
- os.execute("gluon-reload")
-end
+hoodutil.set_domain_config(hoodutil.get_default_domain(hoodutil.get_domains()))
diff --git a/package/gluon-l3roamd/luasrc/lib/gluon/upgrade/150-firewall-l3roamd b/package/gluon-l3roamd/luasrc/lib/gluon/upgrade/320-firewall-l3roamd
similarity index 100%
rename from package/gluon-l3roamd/luasrc/lib/gluon/upgrade/150-firewall-l3roamd
rename to package/gluon-l3roamd/luasrc/lib/gluon/upgrade/320-firewall-l3roamd
diff --git a/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/140-gluon-mesh-babel-firewall b/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/310-gluon-mesh-babel-firewall
similarity index 92%
rename from package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/140-gluon-mesh-babel-firewall
rename to package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/310-gluon-mesh-babel-firewall
index 87433127..5f3a8976 100755
--- a/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/140-gluon-mesh-babel-firewall
+++ b/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/310-gluon-mesh-babel-firewall
@@ -23,18 +23,18 @@ uci:section('firewall', 'zone', 'mmfd', {
-- forwardings and respective rules
uci:section('firewall', 'forwarding', 'fcc', {
- src = 'local_client',
- dest = 'local_client',
+ src = 'loc_client',
+ dest = 'loc_client',
})
uci:section('firewall', 'forwarding', 'fcm', {
- src = 'local_client',
+ src = 'loc_client',
dest = 'mesh',
})
uci:section('firewall', 'forwarding', 'fmc', {
src = 'mesh',
- dest = 'local_client',
+ dest = 'loc_client',
})
uci:section('firewall', 'forwarding', 'fmm', {
@@ -44,11 +44,11 @@ uci:section('firewall', 'forwarding', 'fmm', {
uci:section('firewall', 'forwarding', 'flc', {
src = 'l3roamd',
- dest = 'local_client',
+ dest = 'loc_client',
})
uci:section('firewall', 'forwarding', 'fcl', {
- src = 'local_client',
+ src = 'loc_client',
dest = 'l3roamd',
})
diff --git a/package/gluon-mesh-babel/src/respondd.c b/package/gluon-mesh-babel/src/respondd.c
index 96195d89..94fc3f87 100644
--- a/package/gluon-mesh-babel/src/respondd.c
+++ b/package/gluon-mesh-babel/src/respondd.c
@@ -62,38 +62,40 @@
static struct babelhelper_ctx bhelper_ctx = {};
-static void obtain_if_addr(const char *ifname, char *lladdr) {
+static bool get_linklocal_address(const char *ifname, char lladdr[INET6_ADDRSTRLEN]) {
struct ifaddrs *ifaddr, *ifa;
- int family, n;
+ bool ret = false;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
- exit(EXIT_FAILURE);
+ return false;
}
- for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
- if (ifa->ifa_addr == NULL)
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr)
continue;
- family = ifa->ifa_addr->sa_family;
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
- if ( (family == AF_INET6) && ( ! strncmp(ifname, ifa->ifa_name, strlen(ifname)) ) ) {
- char lhost[INET6_ADDRSTRLEN];
- struct in6_addr *address = &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr;
- if (inet_ntop(AF_INET6, address, lhost, INET6_ADDRSTRLEN) == NULL) {
- fprintf(stderr, "obtain_if_addr: could not convert ip to string\n");
- goto cleanup;
- }
+ if (strcmp(ifname, ifa->ifa_name) != 0)
+ continue;
- if (! strncmp("fe80:", lhost, 5) ) {
- snprintf( lladdr, NI_MAXHOST, "%s", lhost );
- goto cleanup;
- }
+ const struct in6_addr *address = &((const struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
+ if (!IN6_IS_ADDR_LINKLOCAL(address))
+ continue;
+
+ if (!inet_ntop(AF_INET6, address, lladdr, INET6_ADDRSTRLEN)) {
+ perror("inet_ntop");
+ continue;
}
+
+ ret = true;
+ break;
}
-cleanup:
freeifaddrs(ifaddr);
+ return ret;
}
@@ -154,29 +156,32 @@ free:
return retval;
}
-static bool interface_file_exists(const char *ifname, const char *name) {
- const char *format = "/sys/class/net/%s/%s";
- char path[strlen(format) + strlen(ifname) + strlen(name)+1];
- snprintf(path, sizeof(path), format, ifname, name);
-
- return !access(path, F_OK);
-}
-
static void mesh_add_if(const char *ifname, struct json_object *wireless,
struct json_object *tunnel, struct json_object *other) {
- char str_ip[NI_MAXHOST] = {};
+ char str_ip[INET6_ADDRSTRLEN];
- obtain_if_addr(ifname, str_ip);
+ if (!get_linklocal_address(ifname, str_ip))
+ return;
struct json_object *address = json_object_new_string(str_ip);
- if (interface_file_exists(ifname, "wireless"))
- json_object_array_add(wireless, address);
- else if (interface_file_exists(ifname, "tun_flags"))
- json_object_array_add(tunnel, address);
- else
- json_object_array_add(other, address);
+ /* In case of VLAN and bridge interfaces, we want the lower interface
+ * to determine the interface type (but not for the interface address) */
+ char lowername[IF_NAMESIZE];
+ gluonutil_get_interface_lower(lowername, ifname);
+ switch(gluonutil_get_interface_type(lowername)) {
+ case GLUONUTIL_INTERFACE_TYPE_WIRELESS:
+ json_object_array_add(wireless, address);
+ break;
+
+ case GLUONUTIL_INTERFACE_TYPE_TUNNEL:
+ json_object_array_add(tunnel, address);
+ break;
+
+ default:
+ json_object_array_add(other, address);
+ }
}
@@ -193,24 +198,26 @@ static bool handle_neighbour(char **data, void *obj) {
if (data[REACH])
json_object_object_add(neigh, "reachability", json_object_new_double(strtod(data[REACH], NULL)));
- struct json_object *nif = 0;
- if (data[IF] && !json_object_object_get_ex(obj, data[IF], &nif)) {
- char str_ip[NI_MAXHOST] = {};
- obtain_if_addr( (const char*)data[IF], str_ip );
+ if (!data[IF])
+ return true;
+
+ struct json_object *nif;
+ if (!json_object_object_get_ex(obj, data[IF], &nif)) {
+ char str_ip[INET6_ADDRSTRLEN];
nif = json_object_new_object();
- json_object_object_add(nif, "ll-addr", json_object_new_string(str_ip));
+ if (get_linklocal_address(data[IF], str_ip))
+ json_object_object_add(nif, "ll-addr", json_object_new_string(str_ip));
+
json_object_object_add(nif, "protocol", json_object_new_string("babel"));
json_object_object_add(obj, data[IF], nif);
- }
- struct json_object *neighborcollector = 0;
- if (!json_object_object_get_ex(nif, "neighbours", &neighborcollector)) {
- neighborcollector = json_object_new_object();
- json_object_object_add(nif, "neighbours", neighborcollector);
+ json_object_object_add(nif, "neighbours", json_object_new_object());
}
+ struct json_object *neighborcollector;
+ json_object_object_get_ex(nif, "neighbours", &neighborcollector);
json_object_object_add(neighborcollector, data[ADDRESS], neigh);
}
@@ -277,6 +284,13 @@ static void blobmsg_handle_list(struct blob_attr *attr, int len, bool array, str
free(proto);
}
+static void add_if_not_empty(struct json_object *obj, const char *key, struct json_object *val) {
+ if (json_object_array_length(val))
+ json_object_object_add(obj, key, val);
+ else
+ json_object_put(val);
+}
+
static void receive_call_result_data(struct ubus_request *req, int type, struct blob_attr *msg) {
struct json_object *ret = json_object_new_object();
struct json_object *wireless = json_object_new_array();
@@ -298,9 +312,9 @@ static void receive_call_result_data(struct ubus_request *req, int type, struct
blobmsg_handle_list(blobmsg_data(msg), blobmsg_data_len(msg), false, wireless, tunnel, other);
- json_object_object_add(ret, "wireless", wireless);
- json_object_object_add(ret, "tunnel", tunnel);
- json_object_object_add(ret, "other", other);
+ add_if_not_empty(ret, "wireless", wireless);
+ add_if_not_empty(ret, "tunnel", tunnel);
+ add_if_not_empty(ret, "other", other);
*((struct json_object**)(req->priv)) = ret;
}
diff --git a/package/gluon-mesh-batman-adv/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv b/package/gluon-mesh-batman-adv/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv
index a8850f18..d74b1bf7 100755
--- a/package/gluon-mesh-batman-adv/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv
+++ b/package/gluon-mesh-batman-adv/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv
@@ -1,5 +1,5 @@
#!/bin/sh
lock /var/lock/gluon_bat0.lock
-batctl interface del "$IFNAME" 2>/dev/null
+batctl interface -M del "$IFNAME" 2>/dev/null
lock -u /var/lock/gluon_bat0.lock
diff --git a/package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c b/package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c
index 36e330f9..268a3623 100644
--- a/package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c
+++ b/package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c
@@ -131,35 +131,23 @@ static void mesh_add_subif(const char *ifname, struct json_object *wireless,
struct json_object *tunnel, struct json_object *other) {
struct json_object *address = gluonutil_wrap_and_free_string(gluonutil_get_interface_address(ifname));
- char lowername[IFNAMSIZ];
- strncpy(lowername, ifname, sizeof(lowername)-1);
- lowername[sizeof(lowername)-1] = 0;
-
- const char *format = "/sys/class/net/%s/lower_*";
- char pattern[strlen(format) + IFNAMSIZ];
-
/* In case of VLAN and bridge interfaces, we want the lower interface
* to determine the interface type (but not for the interface address) */
- while (true) {
- snprintf(pattern, sizeof(pattern), format, lowername);
- size_t pattern_len = strlen(pattern);
+ char lowername[IF_NAMESIZE];
+ gluonutil_get_interface_lower(lowername, ifname);
- glob_t lower;
- if (glob(pattern, GLOB_NOSORT, NULL, &lower))
- break;
-
- strncpy(lowername, lower.gl_pathv[0] + pattern_len - 1, sizeof(lowername)-1);
-
- globfree(&lower);
- }
-
- if (interface_file_exists(lowername, "wireless"))
+ switch(gluonutil_get_interface_type(lowername)) {
+ case GLUONUTIL_INTERFACE_TYPE_WIRELESS:
json_object_array_add(wireless, address);
- else if (interface_file_exists(lowername, "tun_flags"))
- json_object_array_add(tunnel, address);
- else
- json_object_array_add(other, address);
+ break;
+ case GLUONUTIL_INTERFACE_TYPE_TUNNEL:
+ json_object_array_add(tunnel, address);
+ break;
+
+ default:
+ json_object_array_add(other, address);
+ }
}
static struct json_object * get_mesh_subifs(const char *ifname) {
diff --git a/package/gluon-mesh-wireless-sae/Makefile b/package/gluon-mesh-wireless-sae/Makefile
index 32b867a4..a58823cc 100644
--- a/package/gluon-mesh-wireless-sae/Makefile
+++ b/package/gluon-mesh-wireless-sae/Makefile
@@ -7,7 +7,7 @@ include ../gluon.mk
define Package/gluon-mesh-wireless-sae
TITLE:=Encryption of 802.11s Mesh Links through SAE
- DEPENDS:=+gluon-core +wpa-supplicant-openssl
+ DEPENDS:=+gluon-core +wpa-supplicant-mesh-wolfssl
endef
$(eval $(call BuildPackageGluon,gluon-mesh-wireless-sae))
diff --git a/package/gluon-radv-filterd/src/gluon-radv-filterd.c b/package/gluon-radv-filterd/src/gluon-radv-filterd.c
index ed090c46..b1620cae 100644
--- a/package/gluon-radv-filterd/src/gluon-radv-filterd.c
+++ b/package/gluon-radv-filterd/src/gluon-radv-filterd.c
@@ -559,14 +559,13 @@ static int parse_tt_local(struct nl_msg *msg,
}
static void update_tqs(void) {
+ static const struct ether_addr unspec = {};
struct router *router;
bool update_originators = false;
- struct ether_addr unspec;
struct batadv_nlquery_opts opts;
int ret;
// reset TQs
- memset(&unspec, 0, sizeof(unspec));
foreach(router, G.routers) {
router->tq = 0;
if (ether_addr_equal(router->originator, unspec))
@@ -609,12 +608,12 @@ static void update_tqs(void) {
foreach(router, G.routers) {
if (router->tq == 0) {
if (ether_addr_equal(router->originator, unspec))
- fprintf(stderr,
- "Unable to find router " F_MAC " in transtable_{global,local}\n",
+ DEBUG_MSG(
+ "Unable to find router " F_MAC " in transtable_{global,local}",
F_MAC_VAR(router->src));
else
- fprintf(stderr,
- "Unable to find TQ for originator " F_MAC " (router " F_MAC ")\n",
+ DEBUG_MSG(
+ "Unable to find TQ for originator " F_MAC " (router " F_MAC ")",
F_MAC_VAR(router->originator),
F_MAC_VAR(router->src));
}
diff --git a/package/gluon-radv-filterd/src/mac.h b/package/gluon-radv-filterd/src/mac.h
index cc24d907..eece1105 100644
--- a/package/gluon-radv-filterd/src/mac.h
+++ b/package/gluon-radv-filterd/src/mac.h
@@ -1,4 +1,7 @@
+#pragma once
+
#include
+#include
#include
#define F_MAC "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
diff --git a/package/gluon-respondd/luasrc/lib/gluon/upgrade/400-respondd-firewall b/package/gluon-respondd/luasrc/lib/gluon/upgrade/400-respondd-firewall
index 2419b108..a9d0b43b 100755
--- a/package/gluon-respondd/luasrc/lib/gluon/upgrade/400-respondd-firewall
+++ b/package/gluon-respondd/luasrc/lib/gluon/upgrade/400-respondd-firewall
@@ -18,7 +18,7 @@ uci:section('firewall', 'rule', 'wan_respondd', {
-- Allow respondd-access for local clients
uci:section('firewall', 'rule', 'client_respondd', {
name = 'client_respondd',
- src = 'local_client',
+ src = 'loc_client',
src_ip = 'fe80::/64',
dest_port = '1001',
proto = 'udp',
diff --git a/package/gluon-scheduled-domain-switch/luasrc/usr/bin/gluon-switch-domain b/package/gluon-scheduled-domain-switch/luasrc/lib/gluon/scheduled-domain-switch/switch-domain
similarity index 92%
rename from package/gluon-scheduled-domain-switch/luasrc/usr/bin/gluon-switch-domain
rename to package/gluon-scheduled-domain-switch/luasrc/lib/gluon/scheduled-domain-switch/switch-domain
index 31fcea36..1d7e5898 100755
--- a/package/gluon-scheduled-domain-switch/luasrc/usr/bin/gluon-switch-domain
+++ b/package/gluon-scheduled-domain-switch/luasrc/lib/gluon/scheduled-domain-switch/switch-domain
@@ -60,8 +60,5 @@ if not switch_after_min_reached() and not switch_time_passed() then
os.exit(0)
end
-uci:set("gluon", "core", "domain", target_domain)
-uci:commit("gluon")
-
-os.execute("gluon-reconfigure")
-os.execute("reboot")
+local cmd = {[0] = 'gluon-switch-domain', target_domain}
+unistd.execp(cmd[0], cmd)
diff --git a/package/gluon-scheduled-domain-switch/luasrc/lib/gluon/upgrade/950-gluon-scheduled-domain-switch b/package/gluon-scheduled-domain-switch/luasrc/lib/gluon/upgrade/950-gluon-scheduled-domain-switch
index c221eeda..77803eee 100755
--- a/package/gluon-scheduled-domain-switch/luasrc/lib/gluon/upgrade/950-gluon-scheduled-domain-switch
+++ b/package/gluon-scheduled-domain-switch/luasrc/lib/gluon/upgrade/950-gluon-scheduled-domain-switch
@@ -14,5 +14,5 @@ end
-- Only in case domain switch is scheduled
local f = io.open(cronfile, "w")
f:write("* * * * * /usr/bin/gluon-check-connection\n")
-f:write("*/5 * * * * /usr/bin/gluon-switch-domain\n")
+f:write("*/5 * * * * /lib/gluon/scheduled-domain-switch/switch-domain\n")
f:close()
diff --git a/package/gluon-setup-mode/Makefile b/package/gluon-setup-mode/Makefile
index ff1c730b..dfc1717a 100644
--- a/package/gluon-setup-mode/Makefile
+++ b/package/gluon-setup-mode/Makefile
@@ -17,4 +17,26 @@ define Package/gluon-setup-mode/description
Offline mode to perform basic setup in a secure manner.
endef
+init_links := \
+ K89log \
+ K98boot \
+ K99umount \
+ S00sysfixtime \
+ S10boot \
+ S10gluon-core-reconfigure \
+ S10system \
+ S11sysctl \
+ S12log \
+ S95done
+
+define Package/gluon-setup-mode/install
+ $(Gluon/Build/Install)
+
+ $(LN) S20network $(1)/lib/gluon/setup-mode/rc.d/K90network
+
+ for link in $(init_links); do \
+ $(LN) "/etc/init.d/$$$${link:3}" "$(1)/lib/gluon/setup-mode/rc.d/$$$${link}"; \
+ done
+endef
+
$(eval $(call BuildPackageGluon,gluon-setup-mode))
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K89log b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K89log
deleted file mode 120000
index 1e0c5ac0..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K89log
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/log
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K90network b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K90network
deleted file mode 120000
index 0a43e66b..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K90network
+++ /dev/null
@@ -1 +0,0 @@
-S20network
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K98boot b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K98boot
deleted file mode 120000
index 64aea5e8..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K98boot
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/boot
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K99umount b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K99umount
deleted file mode 120000
index b02f4892..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K99umount
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/umount
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S00sysfixtime b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S00sysfixtime
deleted file mode 120000
index a4fb1d5b..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S00sysfixtime
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/sysfixtime
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S10boot b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S10boot
deleted file mode 120000
index 64aea5e8..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S10boot
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/boot
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S10system b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S10system
deleted file mode 120000
index 81e8836f..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S10system
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/system
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S11sysctl b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S11sysctl
deleted file mode 120000
index b4ac535e..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S11sysctl
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/sysctl
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S12log b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S12log
deleted file mode 120000
index 1e0c5ac0..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S12log
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/log
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S95done b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S95done
deleted file mode 120000
index c9f30277..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S95done
+++ /dev/null
@@ -1 +0,0 @@
-/etc/init.d/done
\ No newline at end of file
diff --git a/package/gluon-setup-mode/files/lib/preinit/90_setup_mode b/package/gluon-setup-mode/files/lib/preinit/90_setup_mode
index c38ac281..b9365be1 100644
--- a/package/gluon-setup-mode/files/lib/preinit/90_setup_mode
+++ b/package/gluon-setup-mode/files/lib/preinit/90_setup_mode
@@ -7,6 +7,10 @@ setup_mode_enable() {
if [ "$enabled" = 1 ] || [ "$configured" != 1 ]; then
echo '/lib/gluon/setup-mode/rc.d' > /tmp/rc_d_path
+
+ # This directory is a marker for scripts to know that we're
+ # in config mode, but it is also used for temporary files
+ mkdir -p /var/gluon/setup-mode
fi
}
diff --git a/package/gluon-site/Makefile b/package/gluon-site/Makefile
index b81ed103..df299c40 100644
--- a/package/gluon-site/Makefile
+++ b/package/gluon-site/Makefile
@@ -49,7 +49,14 @@ define Build/Compile
rm -rf $(PKG_BUILD_DIR)/domains
mkdir -p $(PKG_BUILD_DIR)/domains
$(foreach domain,$(patsubst $(GLUON_SITEDIR)/domains/%.conf,%,$(wildcard $(GLUON_SITEDIR)/domains/*.conf)),
- [ ! -e '$(PKG_BUILD_DIR)/domains/$(domain).json' ]
+ @if [ -e '$(PKG_BUILD_DIR)/domains/$(domain).json' ]; then \
+ link='$(PKG_BUILD_DIR)/domains/$(domain).json'; \
+ other="$$$$(basename $$$$(readlink -f "$$$$link") .json)"; \
+ if [ "$$$$other" ]; then \
+ echo >&2 "Error: Failed to install domain '"'$(domain)'"', name already taken by domain '$$$$other'."; \
+ fi; \
+ exit 1; \
+ fi
$(call GenerateJSON,domains/$(domain))
@lua ../../scripts/domain_aliases.lua '$(PKG_BUILD_DIR)/domains/$(domain).json' | while read alias; do \
[ "$$$${alias}" != '$(domain)' ] || continue; \
@@ -57,7 +64,7 @@ define Build/Compile
if ! ln -s '$(domain).json' "$$$$link"; then \
other="$$$$(basename $$$$(readlink -f "$$$$link") .json)"; \
if [ "$$$$other" ]; then \
- echo >&2 "Failed to alias domain '"'$(domain)'"' as '$$$$alias', name already taken by domain '$$$$other'."; \
+ echo >&2 "Error: Failed to alias domain '"'$(domain)'"' as '$$$$alias', name already taken by domain '$$$$other'."; \
fi; \
exit 1; \
fi; \
diff --git a/package/gluon-status-page/files/lib/gluon/status-page/view/status-page.html b/package/gluon-status-page/files/lib/gluon/status-page/view/status-page.html
index 6e4f3647..09bb6c3e 100644
--- a/package/gluon-status-page/files/lib/gluon/status-page/view/status-page.html
+++ b/package/gluon-status-page/files/lib/gluon/status-page/view/status-page.html
@@ -142,7 +142,13 @@
<%:RAM%> <%= statistics('memory', 'memory') %>
<%:Filesystem%> <%= statistics('rootfs_usage', 'percent') %>
<%:Gateway%> <%= statistics('gateway') %>
<%= statistics('gateway_nexthop', 'neighbour') %>
- <%:Clients%> <%= statistics('clients/total') %>
+
+
+ <%:Clients%>
+
+ <%:Total%> <%= statistics('clients/total') %>
+ <%:Wireless 2.4 GHz%> <%= statistics('clients/wifi24') %>
+ <%:Wireless 5 GHz%> <%= statistics('clients/wifi5') %>
<%:Traffic%>
diff --git a/package/gluon-status-page/i18n/de.po b/package/gluon-status-page/i18n/de.po
index 5caebfde..d979bc37 100644
--- a/package/gluon-status-page/i18n/de.po
+++ b/package/gluon-status-page/i18n/de.po
@@ -55,9 +55,6 @@ msgstr "Weitergeleitet"
msgid "Gateway"
msgstr "Gateway"
-msgid "Gateway Nexthop"
-msgstr "Gateway Nexthop"
-
msgid "IP address"
msgstr "IP-Adresse"
@@ -106,6 +103,9 @@ msgstr "Site"
msgid "Status"
msgstr "Status"
+msgid "Total"
+msgstr "Gesamt"
+
msgid "Traffic"
msgstr ""
@@ -115,6 +115,12 @@ msgstr "Gesendet"
msgid "Uptime"
msgstr "Laufzeit"
+msgid "Wireless 2.4 GHz"
+msgstr ""
+
+msgid "Wireless 5 GHz"
+msgstr ""
+
msgid "connected"
msgstr "verbunden"
@@ -126,3 +132,6 @@ msgstr "aktiviert"
msgid "not connected"
msgstr "nicht verbunden"
+
+#~ msgid "Gateway Nexthop"
+#~ msgstr "Gateway Nexthop"
diff --git a/package/gluon-status-page/i18n/gluon-status-page.pot b/package/gluon-status-page/i18n/gluon-status-page.pot
index e471e878..2aa4b4c4 100644
--- a/package/gluon-status-page/i18n/gluon-status-page.pot
+++ b/package/gluon-status-page/i18n/gluon-status-page.pot
@@ -46,9 +46,6 @@ msgstr ""
msgid "Gateway"
msgstr ""
-msgid "Gateway Nexthop"
-msgstr ""
-
msgid "IP address"
msgstr ""
@@ -97,6 +94,9 @@ msgstr ""
msgid "Status"
msgstr ""
+msgid "Total"
+msgstr ""
+
msgid "Traffic"
msgstr ""
@@ -106,6 +106,12 @@ msgstr ""
msgid "Uptime"
msgstr ""
+msgid "Wireless 2.4 GHz"
+msgstr ""
+
+msgid "Wireless 5 GHz"
+msgstr ""
+
msgid "connected"
msgstr ""
diff --git a/package/gluon-status-page/luasrc/lib/gluon/upgrade/500-status-page b/package/gluon-status-page/luasrc/lib/gluon/upgrade/500-status-page
index 9771a034..b5e7ce44 100755
--- a/package/gluon-status-page/luasrc/lib/gluon/upgrade/500-status-page
+++ b/package/gluon-status-page/luasrc/lib/gluon/upgrade/500-status-page
@@ -27,7 +27,7 @@ uci:section('uhttpd', 'uhttpd', 'main', {
uci:save('uhttpd')
-for _, zone in ipairs({'mesh', 'local_client'}) do
+for _, zone in ipairs({'mesh', 'loc_client'}) do
uci:section('firewall', 'rule', zone .. '_http', {
src = zone,
dest_port = '80',
@@ -35,4 +35,8 @@ for _, zone in ipairs({'mesh', 'local_client'}) do
target = 'ACCEPT',
})
end
+
+-- ToDo remove in v2022.x
+uci:delete('firewall', 'local_client_http')
+
uci:save('firewall')
diff --git a/package/gluon-wan-dnsmasq/files/lib/gluon/wan-dnsmasq/interface.d/050-gluon-wan-dnsmasq b/package/gluon-wan-dnsmasq/files/lib/gluon/wan-dnsmasq/interface.d/050-gluon-wan-dnsmasq
new file mode 100644
index 00000000..585dd7a9
--- /dev/null
+++ b/package/gluon-wan-dnsmasq/files/lib/gluon/wan-dnsmasq/interface.d/050-gluon-wan-dnsmasq
@@ -0,0 +1,2 @@
+wan6
+wan
diff --git a/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua b/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua
index edd33f2c..196a0c2f 100755
--- a/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua
+++ b/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua
@@ -16,6 +16,19 @@ local function append_server(server)
end
+local function handled_interfaces()
+ local interfaces = {}
+
+ for _, path in ipairs(util.glob('/lib/gluon/wan-dnsmasq/interface.d/*')) do
+ for interface in io.lines(path) do
+ table.insert(interfaces, interface)
+ end
+ end
+
+ return interfaces
+end
+
+
local function handle_interface(status)
local ifname = status.device
local servers = status.inactive['dns-server']
@@ -41,8 +54,9 @@ if type(static) == 'table' and #static > 0 then
append_server(server)
end
else
- pcall(append_interface_servers, 'wan6')
- pcall(append_interface_servers, 'wan')
+ for _, interface in ipairs(handled_interfaces()) do
+ pcall(append_interface_servers, interface)
+ end
end
diff --git a/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade.html b/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade.html
index 456b9e5c..31555f16 100644
--- a/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade.html
+++ b/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade.html
@@ -26,7 +26,7 @@ $Id$
<%:Firmware image%>
-
+
@@ -36,13 +36,13 @@ $Id$
-
+
-
+
diff --git a/package/gluon-web-mesh-vpn-fastd/files/lib/gluon/config-mode/view/mesh-vpn-fastd.html b/package/gluon-web-mesh-vpn-fastd/files/lib/gluon/config-mode/view/mesh-vpn-fastd.html
index ed527c8e..5bb5f069 100644
--- a/package/gluon-web-mesh-vpn-fastd/files/lib/gluon/config-mode/view/mesh-vpn-fastd.html
+++ b/package/gluon-web-mesh-vpn-fastd/files/lib/gluon/config-mode/view/mesh-vpn-fastd.html
@@ -1,6 +1,6 @@
- />
+ />
@@ -18,7 +18,7 @@
- />
+ />
diff --git a/package/gluon-web-model/files/lib/gluon/web/view/model/dynlist.html b/package/gluon-web-model/files/lib/gluon/web/view/model/dynlist.html
index 512a194b..b0cd9d0a 100644
--- a/package/gluon-web-model/files/lib/gluon/web/view/model/dynlist.html
+++ b/package/gluon-web-model/files/lib/gluon/web/view/model/dynlist.html
@@ -10,7 +10,7 @@
<%
for i, val in ipairs(self:cfgvalue()) do
%>
- />
diff --git a/package/gluon-web-model/files/lib/gluon/web/view/model/lvalue.html b/package/gluon-web-model/files/lib/gluon/web/view/model/lvalue.html
index 47a2ffd1..e63d33ee 100644
--- a/package/gluon-web-model/files/lib/gluon/web/view/model/lvalue.html
+++ b/package/gluon-web-model/files/lib/gluon/web/view/model/lvalue.html
@@ -4,23 +4,25 @@
%>
<% if self.widget == "select" then %>
-
+
+
+
<% elseif self.widget == "radio" then %>
<% for i, entry in pairs(entries) do %>
@@ -28,7 +30,7 @@
attr("data-index", i) ..
attr("data-depends", self:deplist(entry.deps))
%>>
- style="width: 100%"<% else %> cols="<%=self.size%>"<% end %> data-update="change"<%= attr("name", id) .. attr("id", id) .. attr("rows", self.rows) .. attr("wrap", self.wrap) %>>
+
diff --git a/package/gluon-web-model/files/lib/gluon/web/view/model/value.html b/package/gluon-web-model/files/lib/gluon/web/view/model/value.html
index f14c122e..fc8b8de6 100644
--- a/package/gluon-web-model/files/lib/gluon/web/view/model/value.html
+++ b/package/gluon-web-model/files/lib/gluon/web/view/model/value.html
@@ -2,7 +2,6 @@
attr("id", id) ..
attr("name", id) ..
attr("type", self.password and "password" or "text") ..
- attr("class", self.password and "gluon-input-password" or "gluon-input-text") ..
attr("value", self:cfgvalue()) ..
attr("size", self.size) ..
attr("placeholder", self.placeholder) ..
diff --git a/package/gluon-web-model/files/lib/gluon/web/www/static/gluon-web-model.js b/package/gluon-web-model/files/lib/gluon/web/www/static/gluon-web-model.js
index a826967e..07478cbb 100644
--- a/package/gluon-web-model/files/lib/gluon/web/www/static/gluon-web-model.js
+++ b/package/gluon-web-model/files/lib/gluon/web/www/static/gluon-web-model.js
@@ -1 +1 @@
-!function(){var f={};function a(e){return/^-?\d+$/.test(e)?+e:NaN}function r(e){return/^-?\d*\.?\d+?$/.test(e)?+e:NaN}var u={integer:function(){return!isNaN(a(this))},uinteger:function(){return 0<=a(this)},float:function(){return!isNaN(r(this))},ufloat:function(){return 0<=r(this)},ipaddr:function(){return u.ip4addr.apply(this)||u.ip6addr.apply(this)},ip4addr:function(){var e;return!!(e=this.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/))&&(0<=e[1]&&e[1]<=255&&0<=e[2]&&e[2]<=255&&0<=e[3]&&e[3]<=255&&0<=e[4]&&e[4]<=255)},ip6addr:function(){return this.indexOf("::")<0?null!=this.match(/^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i):!(0<=this.indexOf(":::")||this.match(/::.+::/)||this.match(/^:[^:]/)||this.match(/[^:]:$/))&&(!!this.match(/^(?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}$/i)||(!!this.match(/^(?:[a-f0-9]{1,4}:){7}:$/i)||!!this.match(/^:(?::[a-f0-9]{1,4}){7}$/i)))},wpakey:function(){var e=this;return 64==e.length?null!=e.match(/^[a-f0-9]{64}$/i):8<=e.length&&e.length<=63},range:function(e,t){var n=r(this);return+e<=n&&n<=+t},min:function(e){return r(this)>=+e},max:function(e){return r(this)<=+e},irange:function(e,t){var n=a(this);return+e<=n&&n<=+t},imin:function(e){return a(this)>=+e},imax:function(e){return a(this)<=+e},minlength:function(e){return+e<=(""+this).length},maxlength:function(e){return(""+this).length<=+e}};function o(e){for(var t=0;tn.index);i=i.nextSibling);i?r.insertBefore(n.node,i):r.appendChild(n.node),n.node.dispatchEvent(new Event("gluon-show")),e=!0}r&&r.parentNode&&r.getAttribute("data-optionals")&&(r.parentNode.style.display=r.options.length<=1?"none":"")}e&&v()}function h(e,t,n,a){return e.addEventListener?e.addEventListener(t,n,!!a):e.attachEvent("on"+t,function(){var e=window.event;return!e.target&&e.srcElement&&(e.target=e.srcElement),!!n(e)}),e}function g(l,s){var c=s.prefix;function o(e,t,n){for(var a=[];l.firstChild;){var r=l.firstChild;(i=+r.index)!=n&&("input"==r.nodeName.toLowerCase()?a.push(r.value||""):"select"==r.nodeName.toLowerCase()&&(a[a.length-1]=r.options[r.selectedIndex].value)),l.removeChild(r)}0<=t?(e=t+1,a.splice(t,0,"")):s.optional||0!=a.length||a.push("");for(var i=1;i<=a.length;i++){var o=document.createElement("input");if(o.id=c+"."+i,o.name=c,o.value=a[i-1],o.type="text",o.index=i,o.className="gluon-input-text",s.size&&(o.size=s.size),s.placeholder&&(o.placeholder=s.placeholder),l.appendChild(o),s.type&&m(o,!1,s.type),h(o,"keydown",f),h(o,"keypress",p),i==e)o.focus();else if(-i==e){o.focus();var d=o.value;o.value=" ",o.value=d}if(s.optional||1=+e},max:function(e){return r(this)<=+e},irange:function(e,t){var n=a(this);return+e<=n&&n<=+t},imin:function(e){return a(this)>=+e},imax:function(e){return a(this)<=+e},minlength:function(e){return+e<=(""+this).length},maxlength:function(e){return(""+this).length<=+e}};function o(e){for(var t=0;tn.index);i=i.nextSibling);i?r.insertBefore(n.node,i):r.appendChild(n.node),n.node.dispatchEvent(new Event("gluon-show")),e=!0}r&&r.parentNode&&r.getAttribute("data-optionals")&&(r.parentNode.style.display=r.options.length<=1?"none":"")}e&&h()}function g(e,t,n,a){return e.addEventListener?e.addEventListener(t,n,!!a):e.attachEvent("on"+t,function(){var e=window.event;return!e.target&&e.srcElement&&(e.target=e.srcElement),!!n(e)}),e}function m(l,s){var c=s.prefix;function o(e,t,n){for(var a=[];l.firstChild;){var r=l.firstChild;(i=+r.index)!=n&&("input"==r.nodeName.toLowerCase()?a.push(r.value||""):"select"==r.nodeName.toLowerCase()&&(a[a.length-1]=r.options[r.selectedIndex].value)),l.removeChild(r)}0<=t?(e=t+1,a.splice(t,0,"")):s.optional||0!=a.length||a.push("");for(var i=1;i<=a.length;i++){var o=document.createElement("input");if(o.id=c+"."+i,o.name=c,o.value=a[i-1],o.type="text",o.index=i,s.size&&(o.size=s.size),s.placeholder&&(o.placeholder=s.placeholder),l.appendChild(o),s.type&&y(o,!1,s.type),g(o,"keydown",f),g(o,"keypress",p),i==e)o.focus();else if(-i==e){o.focus();var d=o.value;o.value=" ",o.value=d}if(s.optional||1
}, {once: true});
- initOSM(<%=json(self.openlayers_url)%>, function(createMap) {
+ initOSM(<%=json(self.options)%>, function(createMap) {
elMap.style.display = '';
var pos = <%=json(self:cfgvalue().pos)%>;
diff --git a/package/gluon-web-osm/files/lib/gluon/web/www/static/gluon-web-osm.js b/package/gluon-web-osm/files/lib/gluon/web/www/static/gluon-web-osm.js
index 3d85f6f1..a017a649 100644
--- a/package/gluon-web-osm/files/lib/gluon/web/www/static/gluon-web-osm.js
+++ b/package/gluon-web-osm/files/lib/gluon/web/www/static/gluon-web-osm.js
@@ -1 +1 @@
-"use strict";function initOSM(e,o){var t=document.createElement("link");t.rel="stylesheet",t.type="text/css",t.href=e+"/css/ol.css",document.head.appendChild(t);var n=document.createElement("script"),r=!1;n.onload=n.onreadystatechange=function(){if(!(r||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)){r=!0;var t=new Image;t.onload=function(){var e=new ol.style.Style({image:new ol.style.Icon({img:t,imgSize:[30,45],anchor:[.5,1]})}),c=new ol.Feature;c.setStyle(e),o(function(e,t,o,n,r){var a=new ol.Map({target:e,layers:[new ol.layer.Tile({source:new ol.source.OSM}),new ol.layer.Vector({source:new ol.source.Vector({features:[c]})})],view:new ol.View({center:ol.proj.fromLonLat(t),zoom:o})}),l=function(e){c.setGeometry(new ol.geom.Point(e))};return a.addEventListener("click",function(e){l(e.coordinate),r(ol.proj.toLonLat(e.coordinate))}),n&&l(ol.proj.fromLonLat(t)),a})},t.src="data:image/svg+xml,"+escape('')}},n.src=e+"/build/ol.js",document.head.appendChild(n)}
\ No newline at end of file
+"use strict";function initOSM(o,r){var e=document.createElement("link");e.rel="stylesheet",e.type="text/css",e.href=o.openlayers_url+"/css/ol.css",document.head.appendChild(e);var t=document.createElement("script"),l=!1;t.onload=t.onreadystatechange=function(){if(!(l||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)){l=!0;var t=new Image;t.onload=function(){var i,e=new ol.style.Style({image:new ol.style.Icon({img:t,imgSize:[30,45],anchor:[.5,1]})}),s=new ol.Feature;s.setStyle(e),i=o.tile_layer&&"XYZ"===o.tile_layer.type?new ol.source.XYZ({url:o.tile_layer.url,attributions:o.tile_layer.attributions}):new ol.source.OSM,r(function(e,t,o,r,l){function n(e){s.setGeometry(new ol.geom.Point(e))}var a=new ol.Map({target:e,layers:[new ol.layer.Tile({source:i}),new ol.layer.Vector({source:new ol.source.Vector({features:[s]})})],view:new ol.View({center:ol.proj.fromLonLat(t),zoom:o})});return a.addEventListener("click",function(e){n(e.coordinate),l(ol.proj.toLonLat(e.coordinate))}),r&&n(ol.proj.fromLonLat(t)),a})},t.src="data:image/svg+xml,"+escape('')}},t.src=o.openlayers_url+"/build/ol.js",document.head.appendChild(t)}
\ No newline at end of file
diff --git a/package/gluon-web-osm/javascript/gluon-web-osm.js b/package/gluon-web-osm/javascript/gluon-web-osm.js
index 65b06e26..b4acbf8b 100644
--- a/package/gluon-web-osm/javascript/gluon-web-osm.js
+++ b/package/gluon-web-osm/javascript/gluon-web-osm.js
@@ -6,7 +6,7 @@
'use strict';
-function initOSM(openlayers_url, ready) {
+function initOSM(options, ready) {
var markerSvg = '