169 lines
3.8 KiB
Lua
169 lines
3.8 KiB
Lua
local vcomponent = require "vcomponent"
|
|
local serial = require "serialization"
|
|
local rpc = require "rpc"
|
|
local wgd = {}
|
|
wgd.rescanTime = 60*5
|
|
wgd.allowTypes = {filesystem=true}
|
|
wgd.hosts = {}
|
|
wgd.components = {}
|
|
wgd.ignore = {computer.tmpAddress()}
|
|
local cImported = {}
|
|
local hostStat = {}
|
|
|
|
local function loadConfig()
|
|
local f = io.open("/boot/cfg/workgroup.cfg")
|
|
if not f then return false end
|
|
local cfg = serial.unserialize(f:read("*a"))
|
|
f:close()
|
|
for k,v in pairs(cfg) do
|
|
wgd[k] = v
|
|
end
|
|
end
|
|
local function saveConfig()
|
|
local wt = {
|
|
allowTypes=wgd.allowTypes,
|
|
hosts=wgd.hosts,
|
|
ignore=wgd.ignore,
|
|
rescanTime=wgd.rescanTime,
|
|
}
|
|
local f = io.open("/boot/cfg/workgroup.cfg","wb")
|
|
if not f then return false end
|
|
f:write(serial.serialize(wt))
|
|
f:close()
|
|
end
|
|
|
|
local function getComponents()
|
|
return wgd.components
|
|
end
|
|
|
|
local function exportComponent(a,norescan)
|
|
local p = component.proxy(a)
|
|
if p and wgd.allowTypes[p.type] and not cImported[a] and not wgd.ignore[a] then
|
|
for k,v in pairs(p) do
|
|
--[[
|
|
if type(v) == "function" or (type(v) == "table" and v.address == a and v.name == k) then
|
|
rpc.register(string.format("wg_%s_%s",a,k),v)
|
|
end
|
|
]]
|
|
rpc.register(string.format("wg_%s_%s",a,k),v)
|
|
wgd.components[a] = p.type
|
|
end
|
|
if norescan then return true end
|
|
for k,v in ipairs(wgd.hosts) do
|
|
rpc.call(v, "wg_rescan", os.getenv("HOSTNAME"))
|
|
end
|
|
end
|
|
end
|
|
local function unexportComponent(a)
|
|
if wgd.components[a] then
|
|
wgd.components[a] = nil
|
|
for k,v in ipairs(rpcf) do
|
|
if k:match("^wg_"..a:gsub("%-","%%-").."_") then
|
|
rpcf[k] = nil
|
|
end
|
|
end
|
|
for k,v in ipairs(hosts) do
|
|
rpc.call(v, "wg_rescan", os.getenv("HOSTNAME"))
|
|
end
|
|
end
|
|
end
|
|
|
|
local function hostUp(name,clist)
|
|
syslog("Host "..name.." is up, scanning components.")
|
|
for a,t in pairs(clist) do
|
|
syslog("Found "..a:sub(1,8).." ("..t..") on host "..name)
|
|
local px = rpc.proxy(name, "wg_"..a:gsub("%-","%%-").."_")
|
|
if type(px) == "table" then
|
|
if t == "filesystem" then
|
|
px.fstype = wg_mtfs
|
|
local olabel = px.getLabel
|
|
function px.getLabel()
|
|
local rl = olabel() or a:sub(1,3)
|
|
return string.format("/net/%s/%s",name,rl)
|
|
end
|
|
end
|
|
cImported[a] = name
|
|
vcomponent.register(a, t, px)
|
|
syslog("Attached "..a:sub(1,8).." ("..t..") on host "..name)
|
|
service.fsmanager.mount(a)
|
|
end
|
|
end
|
|
end
|
|
local function hostDown(name)
|
|
for ca,ha in pairs(cImported) do
|
|
if ha == name then
|
|
vcomponent.unregister(ca)
|
|
cImported[ca] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
function wgd.addHost(name)
|
|
wgd.removeHost(name)
|
|
wgd.hosts[#wgd.hosts+1] = name
|
|
saveConfig()
|
|
wgd.rescan(name)
|
|
end
|
|
function wgd.removeHost(name)
|
|
for i = #wgd.hosts, 1, -1 do
|
|
if wgd.hosts[i] == name then
|
|
print(table.remove(wgd.hosts, i))
|
|
end
|
|
end
|
|
saveConfig()
|
|
hostDown(name)
|
|
end
|
|
|
|
function wgd.rescan(name)
|
|
local targets = {name}
|
|
targets = #targets > 0 and targets or wgd.hosts
|
|
for _,n in ipairs(targets) do
|
|
os.spawn(function()
|
|
local clist = rpc.call(n, "wg_components")
|
|
if clist then
|
|
hostUp(n,clist)
|
|
else
|
|
hostDown(n)
|
|
end
|
|
end,"wgd worker: "..n)
|
|
coroutine.yield()
|
|
end
|
|
end
|
|
|
|
local run
|
|
function wgd.start()
|
|
if run then return end
|
|
run = true
|
|
return os.spawn(function()
|
|
loadConfig()
|
|
rpc.register("wg_components",getComponents)
|
|
rpc.register("wg_rescan",wgd.rescan)
|
|
local rst = computer.uptime() + 5
|
|
for a,t in component.list() do
|
|
exportComponent(a,true)
|
|
end
|
|
|
|
for k,v in ipairs(wgd.hosts) do
|
|
rpc.call(v, "wg_rescan", os.getenv("HOSTNAME"))
|
|
end
|
|
|
|
while run do
|
|
local tE = {coroutine.yield()}
|
|
if tE[1] == "component_added" then
|
|
exportComponent(tE[2])
|
|
elseif tE[1] == "component_removed" then
|
|
unexportComponent(tE[2])
|
|
end
|
|
if computer.uptime() > rst then
|
|
wgd.rescan()
|
|
rst = computer.uptime() + wgd.rescanTime
|
|
end
|
|
end
|
|
end, "workgroupd")
|
|
end
|
|
function wgd.stop()
|
|
run = false
|
|
end
|
|
|
|
return wgd
|