Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add domain specific configs to gluon #1216

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/site-example/site.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
-- 32 bytes of random data, encoded in hexadecimal
-- Must be the same for all nodes in one mesh domain
-- Can be generated using: echo $(hexdump -v -n 32 -e '1/1 "%02x"' </dev/urandom)
site_seed = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
domain_seed = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',

-- Prefixes used within the mesh.
-- prefix6 is required, prefix4 can be omitted if next_node.ip4
Expand Down
2 changes: 1 addition & 1 deletion docs/user/site.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ site_code
The code of your community. It is good practice to use the TLD of
your community here.

site_seed
domain_seed
32 bytes of random data, encoded in hexadecimal, used to seed other random
values specific to the mesh domain. It must be the same for all nodes of one
mesh, but should be different for firmwares that are not supposed to mesh with
Expand Down
2 changes: 1 addition & 1 deletion package/gluon-authorized-keys/check_site.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
need_string_array 'authorized_keys'
need_string_array(in_site('authorized_keys'))
12 changes: 6 additions & 6 deletions package/gluon-autoupdater/check_site.lua
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
need_string 'autoupdater.branch'
need_string(in_site('autoupdater.branch'))

local function check_branch(k, _)
assert_uci_name(k)
local function check_branch(k, conf_name)
assert_uci_name(k, conf_name)

local prefix = string.format('autoupdater.branches[%q].', k)

need_string(prefix .. 'name')
need_string(in_site(prefix .. 'name'))
need_string_array_match(prefix .. 'mirrors', '^http://')
need_number(prefix .. 'good_signatures')
need_string_array_match(prefix .. 'pubkeys', '^%x+$')
need_number(in_site(prefix .. 'good_signatures'))
need_string_array_match(in_site(prefix .. 'pubkeys'), '^%x+$')
end

need_table('autoupdater.branches', check_branch)
8 changes: 4 additions & 4 deletions package/gluon-client-bridge/check_site.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
need_string_match('next_node.mac', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$', false)
need_string_match(in_domain('next_node.mac'), '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$', false)

if need_string_match('next_node.ip4', '^%d+.%d+.%d+.%d+$', false) then
need_string_match('prefix4', '^%d+.%d+.%d+.%d+/%d+$')
if need_string_match(in_domain('next_node.ip4'), '^%d+.%d+.%d+.%d+$', false) then
need_string_match(in_domain('prefix4'), '^%d+.%d+.%d+.%d+/%d+$')
end

need_string_match('next_node.ip6', '^[%x:]+$', false)
need_string_match(in_domain('next_node.ip6'), '^[%x:]+$', false)


for _, config in ipairs({'wifi24', 'wifi5'}) do
Expand Down
4 changes: 2 additions & 2 deletions package/gluon-config-mode-contact-info/check_site.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
if need_table('config_mode', nil, false) and need_table('config_mode.owner', nil, false) then
need_boolean('config_mode.owner.obligatory', false)
if need_table(in_site('config_mode'), nil, false) and need_table(in_site('config_mode.owner'), nil, false) then
need_boolean(in_site('config_mode.owner.obligatory'), false)
end
4 changes: 2 additions & 2 deletions package/gluon-config-mode-geo-location/check_site.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
if need_table('config_mode', nil, false) and need_table('config_mode.geo_location', nil, false) then
need_boolean('config_mode.geo_location.show_altitude', false)
if need_table(in_site('config_mode'), nil, false) and need_table(in_site('config_mode.geo_location'), nil, false) then
need_boolean(in_site('config_mode.geo_location.show_altitude'), false)
end
56 changes: 35 additions & 21 deletions package/gluon-core/check_site.lua
Original file line number Diff line number Diff line change
@@ -1,36 +1,50 @@
need_string 'site_code'
need_string 'site_name'
need_string_match('site_seed', '^' .. ('%x'):rep(64) .. '$')
need_string(in_site('site_code'))
need_string(in_site('site_name'))
need_string_match(in_domain('domain_seed'), '^' .. ('%x'):rep(64) .. '$')

need_string(in_site('default_domain_code'))

need_string(in_domain('domain_name'))

function check_alias(k, conf_name)
assert_uci_name(k, conf_name)

local path = string.format('domain_aliases[%q]', k)
need_string(in_domain(path))
end

need_table(in_domain('domain_aliases'), check_alias, false)

if need_table('opkg', nil, false) then
need_string('opkg.lede', false)

function check_repo(k, _)
function check_repo(k, conf_name)
-- this is not actually a uci name, but using the same naming rules here is fine
assert_uci_name(k)
assert_uci_name(k, conf_name)

need_string(string.format('opkg.extra[%q]', k))
local path = string.format('opkg.extra[%q]', k)
need_string(path)
end

need_table('opkg.extra', check_repo, false)
end

need_string('hostname_prefix', false)
need_string 'timezone'
need_string(in_site('hostname_prefix'), false)
need_string(in_site('timezone'))

need_string_array('ntp_servers', false)

need_string_match('prefix6', '^[%x:]+/64$')
need_string_match(in_domain('prefix6'), '^[%x:]+/64$')


for _, config in ipairs({'wifi24', 'wifi5'}) do
if need_table(config, nil, false) then
need_string('regdom') -- regdom is only required when wifi24 or wifi5 is configured
need_string(in_site('regdom')) -- regdom is only required when wifi24 or wifi5 is configured

need_number(config .. '.channel')

local rates = {1000, 2000, 5500, 6000, 9000, 11000, 12000, 18000, 24000, 36000, 48000, 54000}
local supported_rates = need_array_of(config .. '.supported_rates', rates, false)
local supported_rates = need_array_of(in_site(config .. '.supported_rates'), rates, false)
if supported_rates then
need_array_of(config .. '.basic_rate', supported_rates, true)
else
Expand All @@ -39,36 +53,36 @@ for _, config in ipairs({'wifi24', 'wifi5'}) do
end
end

need_boolean('poe_passthrough', false)
need_boolean(in_site('poe_passthrough'), false)
if need_table('dns', nil, false) then
need_number('dns.cacheentries', false)
need_string_array_match('dns.servers', '^[%x:]+$', true)
end

if need_table('next_node', nil, false) then
need_string_match('next_node.ip6', '^[%x:]+$', false)
need_string_match('next_node.ip4', '^%d+.%d+.%d+.%d+$', false)
need_string_match(in_domain('next_node.ip6'), '^[%x:]+$', false)
need_string_match(in_domain('next_node.ip4'), '^%d+.%d+.%d+.%d+$', false)
end

for _, config in ipairs({'wifi24', 'wifi5'}) do
local rates = {1000, 2000, 5500, 6000, 9000, 11000, 12000, 18000, 24000, 36000, 48000, 54000}
rates = need_array_of(config .. '.supported_rates', rates, false) or rates
rates = need_array_of(in_site(config .. '.supported_rates'), rates, false) or rates

if need_table(config .. '.ibss', nil, false) then
need_string(config .. '.ibss.ssid')
need_string_match(config .. '.ibss.bssid', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$')
need_string(in_domain(config .. '.ibss.ssid'))
need_string_match(in_domain(config .. '.ibss.bssid'), '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$')
need_one_of(config .. '.ibss.mcast_rate', rates, false)
need_number(config .. '.ibss.vlan', false)
need_boolean(config .. '.ibss.disabled', false)
end

if need_table(config .. '.mesh', nil, false) then
need_string(config .. '.mesh.id')
need_string(in_domain(config .. '.mesh.id'))
need_one_of(config .. '.mesh.mcast_rate', rates, false)
need_boolean(config .. '.mesh.disabled', false)
end
end

need_boolean('mesh_on_wan', false)
need_boolean('mesh_on_lan', false)
need_boolean('single_as_lan', false)
need_boolean(in_site('mesh_on_wan'), false)
need_boolean(in_site('mesh_on_lan'), false)
need_boolean(in_site('single_as_lan'), false)
1 change: 1 addition & 0 deletions package/gluon-core/files/etc/config/gluon
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config system system
Copy link
Contributor

@kb-light kb-light Oct 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not using /etc/config/gluon-core which is already supplied by gluon-core?
EDIT: never mind, it is already answered here.

Copy link
Member

@neocturne neocturne Dec 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think calling the section 'core' would make sense, as this config is handled by gluon-core (and we generally store config for package gluon-X in section gluon.X).

The commit title is not accurate, the top level of the UCI structure is called "package", so this would add a package "gluon" and a section "gluon.system" (or "gluon.core") to UCI.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I plan to pick up this commit first (with my suggested changes), so the rest of Gluon can start using it. This PR will need to be adjusted to the changed section name.

10 changes: 10 additions & 0 deletions package/gluon-core/files/lib/gluon/domain_changed.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

domain_code=$(uci get gluon.system.domain_code)

[ -f /lib/gluon/domains/${domain_code}.json ] || (echo "file not found: /lib/gluon/domains/${domain_code}.json" >&2; exit 1) || exit 1

for s in /lib/gluon/upgrade/*; do
echo -n ${s}:
(${s} && echo " ok") || echo " error"
done
2 changes: 1 addition & 1 deletion package/gluon-core/files/lib/netifd/proto/gluon_wired.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ proto_gluon_wired_setup() {
json_add_string tunlink "$config"
json_add_string ip6addr "$(interface_linklocal "$ifname")"
json_add_string peer6addr 'ff02::15c'
json_add_int vid "$(lua -lgluon.util -e 'print(tonumber(gluon.util.site_seed_bytes("gluon-mesh-vxlan", 3), 16))')"
json_add_int vid "$(lua -lgluon.util -e 'print(tonumber(gluon.util.domain_seed_bytes("gluon-mesh-vxlan", 3), 16))')"
json_close_object
ubus call network add_dynamic "$(json_dump)"
fi
Expand Down
5 changes: 5 additions & 0 deletions package/gluon-core/luasrc/usr/bin/gluon-print-site
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/lua
local jsonc = require 'luci.jsonc'
local site = require 'gluon.site'

print(jsonc.stringify(site(), true))
38 changes: 33 additions & 5 deletions package/gluon-core/luasrc/usr/lib/lua/gluon/site.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
local site = (function()
local config = '/lib/gluon/site.json'
local function read_json(path)

local json = require 'luci.jsonc'
local decoder = json.new()
local sink = decoder:sink()

local file = assert(io.open(config))
local file = assert(io.open(path))

while true do
local chunk = file:read(2048)
Expand All @@ -16,11 +15,40 @@ local site = (function()
file:close()

return assert(decoder:get())
end)()
end

local site = read_json('/lib/gluon/site.json')
local domain = (function(site)
local uci = require('simple-uci').cursor()
local fs = require "nixio.fs"
local sname = uci:get_first('gluon', 'system')

local dc = uci:get('gluon', sname, 'domain_code') or ''

if fs.stat('/lib/gluon/domains/'..dc..'.json', 'type')~='reg' then
dc = site['default_domain_code']
end

local domain = read_json('/lib/gluon/domains/'..dc..'.json')
if domain['domain_aliases'] and domain['domain_aliases'][dc] then
domain['domain_name'] = domain['domain_aliases'][dc]
end
return domain
end)(site)


local wrap

local function merge(t1, t2)
for k, v in pairs(t2) do
if (type(v) == "table") and (type(t1[k] or false) == "table") then
merge(t1[k], t2[k])
else
t1[k] = v
end
end
return t1
end

local function index(t, k)
local v = getmetatable(t).value
Expand Down Expand Up @@ -58,4 +86,4 @@ end

module 'gluon.site'

return wrap(site, _M)
return wrap(merge(site, domain), _M)
4 changes: 2 additions & 2 deletions package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ function node_id()
return string.gsub(sysconfig.primary_mac, ':', '')
end

function site_seed_bytes(key, length)
function domain_seed_bytes(key, length)
local ret = ''
local v = ''
local i = 0
Expand All @@ -131,7 +131,7 @@ function site_seed_bytes(key, length)
-- cryptographic strength
while ret:len() < 2*length do
i = i + 1
v = hash.md5(v .. key .. site.site_seed():lower() .. i)
v = hash.md5(v .. key .. site.domain_seed():lower() .. i)
ret = ret .. v
end

Expand Down
4 changes: 2 additions & 2 deletions package/gluon-ebtables-source-filter/check_site.lua
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
need_string_match('prefix4', '^%d+.%d+.%d+.%d+/%d+$', false)
need_string_array_match('extra_prefixes6', '^[%x:]+/%d+$', false)
need_string_match(in_domain('prefix4'), '^%d+.%d+.%d+.%d+/%d+$', false)
need_string_array_match(in_domain('extra_prefixes6'), '^[%x:]+/%d+$', false)
14 changes: 7 additions & 7 deletions package/gluon-mesh-vpn-fastd/check_site.lua
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
local fastd_methods = {'salsa2012+gmac', 'salsa2012+umac', 'null+salsa2012+gmac', 'null+salsa2012+umac', 'null'}
need_array_of('mesh_vpn.fastd.methods', fastd_methods)
need_boolean('mesh_vpn.fastd.configurable', false)
need_boolean(in_site('mesh_vpn.fastd.configurable'), false)

need_one_of('mesh_vpn.fastd.syslog_level', {'error', 'warn', 'info', 'verbose', 'debug', 'debug2'}, false)
need_one_of(in_site('mesh_vpn.fastd.syslog_level'), {'error', 'warn', 'info', 'verbose', 'debug', 'debug2'}, false)

local function check_peer(prefix)
return function(k, _)
assert_uci_name(k)
return function(k, conf_name)
assert_uci_name(k, conf_name)

local table = string.format('%s[%q].', prefix, k)

need_string_match(table .. 'key', '^%x+$')
need_string_array(table .. 'remotes')
need_string_array(in_domain(table .. 'remotes'))
end
end

local function check_group(prefix)
return function(k, _)
assert_uci_name(k)
return function(k, conf_name)
assert_uci_name(k, conf_name)

local table = string.format('%s[%q].', prefix, k)

Expand Down
2 changes: 1 addition & 1 deletion package/gluon-node-info/check_site.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
need_string('roles.default', false)
need_string(in_site('roles.default'), false)
6 changes: 6 additions & 0 deletions package/gluon-respondd/src/respondd.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ static struct json_object * get_site_code(void) {
return ret;
}

static struct json_object * get_domain_code(void) {
char * domain_code = gluonutil_get_selected_domain_code(NULL);
return gluonutil_wrap_and_free_string(domain_code);
}

static struct json_object * get_hostname(void) {
struct json_object *ret = NULL;

Expand Down Expand Up @@ -122,6 +127,7 @@ static struct json_object * respondd_provider_nodeinfo(void) {

struct json_object *system = json_object_new_object();
json_object_object_add(system, "site_code", get_site_code());
json_object_object_add(system, "domain_code", get_domain_code());
json_object_object_add(ret, "system", system);

return ret;
Expand Down
3 changes: 1 addition & 2 deletions package/gluon-setup-mode/check_site.lua
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
need_boolean('setup_mode.skip', false)

need_boolean(in_site('setup_mode.skip'), false)
17 changes: 16 additions & 1 deletion package/gluon-site/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PKG_VERSION:=$(if $(DUMP),x,$(GLUON_SITE_VERSION))


PKG_CONFIG_DEPENDS := CONFIG_GLUON_RELEASE CONFIG_GLUON_SITEDIR
PKG_FILE_DEPENDS := $(GLUON_SITEDIR)/site.conf $(GLUON_SITEDIR)/i18n/
PKG_FILE_DEPENDS := $(GLUON_SITEDIR)/site.conf $(GLUON_SITEDIR)/domains/ $(GLUON_SITEDIR)/i18n/
PKG_BUILD_DEPENDS := lua-cjson/host

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
Expand Down Expand Up @@ -38,19 +38,34 @@ endef

define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
mkdir -p $(PKG_BUILD_DIR)/domains
endef

define Build/Configure
endef

define Build/Compile
GLUON_SITEDIR='$(call qstrip,$(CONFIG_GLUON_SITEDIR))' lua -e 'print(require("cjson").encode(assert(dofile("../../scripts/site_config.lua"))))' > $(PKG_BUILD_DIR)/site.json
ls $(call qstrip,$(CONFIG_GLUON_SITEDIR))/domains/*.conf > /dev/null # at least one domain cfg has to exist
GLUON_SITEDIR='$(call qstrip,$(CONFIG_GLUON_SITEDIR))' lua -e 'print(assert(dofile("../../scripts/site_config.lua")).default_domain_code)' > $(PKG_BUILD_DIR)/default_domain_code
ls '$(call qstrip,$(CONFIG_GLUON_SITEDIR))'/domains/$$$$(cat $(PKG_BUILD_DIR)/default_domain_code).conf # ensure default_domain_code exists
rm -f $(PKG_BUILD_DIR)/domains/*.json
for domain_cfg in `find $(call qstrip,$(CONFIG_GLUON_SITEDIR))/domains/ -iname \*.conf -printf "%f\n"`; do \
dc=$$$${domain_cfg%.conf}; \
GLUON_SITEDIR='$(call qstrip,$(CONFIG_GLUON_SITEDIR))' lua -e 'print(require("cjson").encode(assert(dofile("../../scripts/domain_config.lua")("'$$$${dc}'"))))' > $(PKG_BUILD_DIR)/domains/$$$${dc}.json; \
aliases=$$$$(GLUON_SITEDIR='$(call qstrip,$(CONFIG_GLUON_SITEDIR))' lua -e 'for alias_name, _ in pairs(dofile("../../scripts/domain_config.lua")("'$$$${dc}'")["domain_aliases"] or {}) do print(alias_name.." ") end'); \
for alias in $$$${aliases}; do \
ln -s $$$${dc}.json $(PKG_BUILD_DIR)/domains/$$$${alias}.json; \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace ln -s with ln -sf here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to use rm -r to clean the whole directory domains/ before entering the for loop, so the whole process should be a little more idempotent. Deleting a domain in site repo hat no effect before this additionional rm.

done; \
done
$(call GluonBuildI18N,gluon-site,$(GLUON_SITEDIR)/i18n)
endef

define Package/gluon-site/install
$(INSTALL_DIR) $(1)/lib/gluon
$(INSTALL_DATA) $(PKG_BUILD_DIR)/site.json $(1)/lib/gluon/
$(INSTALL_DIR) $(1)/lib/gluon/domains
$(CP) $(PKG_BUILD_DIR)/domains/*.json $(1)/lib/gluon/domains/
echo '$(GLUON_SITE_VERSION)' > $(1)/lib/gluon/site-version
echo '$(call qstrip,$(CONFIG_GLUON_RELEASE))' > $(1)/lib/gluon/release

Expand Down
Loading