summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2015-02-22 00:08:53 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2015-02-22 01:51:30 +0200
commit1e4cb26264f67b5fe8e3e55e17d1ad785c137f24 (patch)
tree0f91b39518c6ba6ffd2f97d386ca8b0c5add3b41
parent30ea327005ed2f45e19b2314b8caaae3c7edd894 (diff)
downloadaconf-1e4cb26264f67b5fe8e3e55e17d1ad785c137f24.tar.bz2
aconf-1e4cb26264f67b5fe8e3e55e17d1ad785c137f24.tar.xz
model: scattered lists
-rw-r--r--aconf/model/node.lua47
-rw-r--r--aconf/modules/network.lua30
-rw-r--r--aconf/transaction/base.lua33
3 files changed, 85 insertions, 25 deletions
diff --git a/aconf/model/node.lua b/aconf/model/node.lua
index 735e7df..d1e1037 100644
--- a/aconf/model/node.lua
+++ b/aconf/model/node.lua
@@ -33,15 +33,21 @@ M.BoundMember = class()
function M.BoundMember:init(parent, name, field)
local pmt = getmetatable(parent)
- local addr = field.addr or address.escape(name)
- if type(addr) == 'function' then addr = addr(pmt.path, name) end
+ if pmt.maddr and name ~= address.wildcard then self.addr = pmt.maddr(name)
+ else
+ self.addr = field.addr or address.escape(name)
+ if type(self.addr) == 'function' then
+ self.addr = self.addr(pmt.path, name)
+ end
+ self.addr = address.to_absolute(self.addr, pmt.addr)
+ end
local context = {
txn=pmt.txn,
privileged=pmt.privileged,
parent=parent,
path=pth.join(pmt.path, name),
- addr=address.to_absolute(addr, pmt.addr)
+ addr=self.addr
}
local mt = {}
@@ -268,9 +274,9 @@ function M.Collection:init(context, params)
self.init = nil
local mt = getmetatable(self)
- local field = M.BoundMember(self, pth.wildcard, params.field)
+ mt.field = M.BoundMember(self, pth.wildcard, params.field)
- function mt.topology() return field:topology() end
+ function mt.topology() return mt.field:topology() end
function mt.member(name)
return M.BoundMember(self, name, params.field)
@@ -287,7 +293,7 @@ function M.Collection:init(context, params)
meta,
{
editable=params.editable and mt.has_permission('create'),
- members=field:meta(),
+ members=mt.field:meta(),
required=params.required,
['ui-member']=params.ui_member or meta['ui-name']:gsub('s$', ''),
widget=params.layout
@@ -364,8 +370,35 @@ function M.List:init(context, params)
super(self, M.List):init(context, setdefaults(params, {dtype='list'}))
local mt = getmetatable(self)
- local tmt = getmetatable(mt.escalate)
+ if not mt.txn then return end
+
+ local function expand() return mt.txn:expand(mt.field.addr) end
+
+ function mt.maddr(i)
+ local addrs = expand()
+
+ if not addrs[1] then
+ addrs[1] = address.join(
+ '/',
+ table.unpack(
+ util.map(
+ function(c) return c == address.wildcard and 1 or c end,
+ address.split(mt.field.addr)
+ )
+ )
+ )
+ end
+ if addrs[i] then return addrs[i] end
+
+ local comps = address.split(addrs[#addrs])
+ comps[#comps] = comps[#comps] + i - #addrs
+ return address.join('/', table.unpack(comps))
+ end
+
+ function mt.members() return util.keys(expand()) end
+
+ local tmt = getmetatable(mt.escalate)
mt._save = mt.save
local function check_index(i, max)
diff --git a/aconf/modules/network.lua b/aconf/modules/network.lua
index 82a83ef..8c985ff 100644
--- a/aconf/modules/network.lua
+++ b/aconf/modules/network.lua
@@ -92,12 +92,6 @@ end
function Interface:is_removable() return self.class == 'logical' end
-function Interface:auto_set()
- for _, set in ipairs(self:fetch('../../enabled-ifaces')) do
- if M.node.contains(set, self) then return set end
- end
-end
-
function Interface:auto_vlan_tag()
local name = M.node.name(self)
local _, tag = name:match(vlan_pattern)
@@ -106,13 +100,14 @@ function Interface:auto_vlan_tag()
end
Interface.enabled = M.Boolean{
- compute=function(iface) return iface:auto_set() and true or false end,
+ compute=function(iface)
+ return M.node.contains(iface:fetch('../../enabled-ifaces'), iface)
+ end,
store=function(iface, value)
- local set = iface:auto_set()
- if value and not set then
- M.node.insert(iface:fetch('../../enabled-ifaces/1'), iface)
- elseif not value and set then set[iface] = nil end
- end
+ local set = iface:fetch('../../enabled-ifaces')
+ if value then M.node.insert(set, iface)
+ else set[iface] = nil end
+ end
}
Interface.class = M.String{
@@ -251,10 +246,13 @@ Net.resolver = M.Model{
model=Resolv, addr='/augeas/etc/resolv.conf', ui_name='DNS resolver'
}
-Net.enabled_ifaces = M.List{
- type=M.Set{type=M.Reference{scope='../../interfaces', on_delete='set-null'}},
- visible=false,
- addr=iface_aug_addr..'/auto/#'
+Net.enabled_ifaces = M.Set{
+ type=M.Reference{
+ scope='../interfaces',
+ addr=iface_aug_addr..'/auto/#/*/*',
+ on_delete='set-null'
+ },
+ visible=false
}
Net.interfaces = M.Collection{
type=Interface, addr=iface_aug_addr..'/iface/@', widget='inline'
diff --git a/aconf/transaction/base.lua b/aconf/transaction/base.lua
index f40dcca..1886fd9 100644
--- a/aconf/transaction/base.lua
+++ b/aconf/transaction/base.lua
@@ -11,7 +11,7 @@ local object = require('aconf.object')
local class = object.class
local address = require('aconf.path.address')
-local copy = require('aconf.util').copy
+local util = require('aconf.util')
-- TODO each transaction backend (i.e. persistence manager or
-- transaction proper) should be implemented as a thread or have its
@@ -107,7 +107,7 @@ function M.Transaction:get(path)
if self.deleted[path] then return nil, self.mod_time[path] end
for _, tbl in ipairs{self.added, self.modified} do
if tbl[path] ~= nil then
- return copy(tbl[path]), self.mod_time[path]
+ return util.copy(tbl[path]), self.mod_time[path]
end
end
@@ -116,6 +116,35 @@ function M.Transaction:get(path)
return value, timestamp
end
+function M.Transaction:expand(path)
+ local prefix = {}
+ path = address.split(path)
+
+ while path[1] do
+ local comp = path[1]
+ table.remove(path, 1)
+
+ if comp == address.wildcard then
+ local p = address.join('/', table.unpack(prefix))
+ local res = {}
+
+ local children = self:get(p) or {}
+ table.sort(children)
+ for _, child in ipairs(children) do
+ util.extend(
+ res, self:expand(address.join(p, child, table.unpack(path)))
+ )
+ end
+
+ return res
+ end
+
+ table.insert(prefix, comp)
+ end
+
+ return {address.join('/', table.unpack(prefix))}
+end
+
function M.Transaction:_set_multiple(mods)
local function set(path, value, new)