code beautifications

This commit is contained in:
Axel Kittenberger 2012-10-03 17:37:49 +02:00
parent 698c5c3e4d
commit 899077ccd7
1 changed files with 356 additions and 164 deletions

View File

@ -5,6 +5,8 @@
-- It works closely together with the Lsyncd core in lsyncd.c. This means it -- It works closely together with the Lsyncd core in lsyncd.c. This means it
-- cannot be runned directly from the standard lua interpreter. -- cannot be runned directly from the standard lua interpreter.
-- --
-- This code assumes your editor is at least 100 chars wide.
--
-- License: GPLv2 (see COPYING) or any later version -- License: GPLv2 (see COPYING) or any later version
-- Authors: Axel Kittenberger <axkibe@gmail.com> -- Authors: Axel Kittenberger <axkibe@gmail.com>
-- --
@ -18,10 +20,16 @@
-- The core will exit if version ids mismatch. -- The core will exit if version ids mismatch.
-- --
if lsyncd_version then if lsyncd_version then
-- checks if the runner is being loaded twice
lsyncd.log('Error', 'You cannot use the lsyncd runner as configuration file!') -- ensures the runner is not being loaded twice
lsyncd.terminate(-1) -- ERRNO lsyncd.log(
'Error',
'You cannot use the lsyncd runner as configuration file!'
)
lsyncd.terminate( -1 )
end end
lsyncd_version = '2.0.7' lsyncd_version = '2.0.7'
-- --
@ -1352,7 +1360,7 @@ local Excludes = ( function( )
err err
) )
terminate(-1) -- ERRNO terminate( -1 )
end end
for line in f:lines() do for line in f:lines() do
@ -1521,7 +1529,7 @@ local Sync = ( function( )
if rc == 'die' then if rc == 'die' then
log( 'Error', 'Critical exitcode.' ); log( 'Error', 'Critical exitcode.' );
terminate( -1 ) --ERRNO terminate( -1 )
end end
if rc ~= 'again' then if rc ~= 'again' then
@ -1562,7 +1570,7 @@ local Sync = ( function( )
if rc == 'die' then if rc == 'die' then
log( 'Error', 'Critical exitcode.' ); log( 'Error', 'Critical exitcode.' );
terminate( -1 ) --ERRNO terminate( -1 )
end end
if rc == 'again' then if rc == 'again' then
@ -2188,7 +2196,7 @@ local Syncs = ( function( )
info.short_src,':', info.short_src,':',
info.currentline,': source missing from sync.' info.currentline,': source missing from sync.'
) )
terminate( -1 ) -- ERRNO terminate( -1 )
end end
-- absolute path of source -- absolute path of source
@ -2200,7 +2208,7 @@ local Syncs = ( function( )
'Cannot access source directory: ', 'Cannot access source directory: ',
config.source config.source
) )
terminate( -1 ) -- ERRNO terminate( -1 )
end end
config._source = config.source config._source = config.source
@ -2222,7 +2230,7 @@ local Syncs = ( function( )
': no actions specified, use e.g. "config = default.rsync".' ': no actions specified, use e.g. "config = default.rsync".'
) )
terminate( -1 ) -- ERRNO terminate( -1 )
end end
-- loads a default value for an option if not existent -- loads a default value for an option if not existent
@ -2265,7 +2273,7 @@ local Syncs = ( function( )
'" unknown.' '" unknown.'
) )
terminate( -1 ) -- ERRNO terminate( -1 )
end end
--- creates the new sync --- creates the new sync
@ -3257,7 +3265,7 @@ function runner.callError( message )
local info = debug.getinfo( level, 'Sl' ) local info = debug.getinfo( level, 'Sl' )
if not info then if not info then
terminate( -1 ) -- ERRNO terminate( -1 )
end end
log( log(
@ -3403,7 +3411,7 @@ SEE:
-- -monitor NAME Uses operating systems event montior NAME -- -monitor NAME Uses operating systems event montior NAME
-- (inotify/fanotify/fsevents) -- (inotify/fanotify/fsevents)
os.exit(-1) -- ERRNO os.exit( -1 )
end end
@ -3427,12 +3435,15 @@ function runner.configure( args, monitors )
-- a list of all valid options -- a list of all valid options
-- --
-- first paramter is the number of parameters an option takes -- first paramter is the number of parameters an option takes
-- if < 0 the function checks existance -- TODO what? -- if < 0 the called function has to check the presence of
-- optional arguments.
-- --
-- second paramter is the function to call -- second paramter is the function to call
-- --
local options = { local options = {
-- log is handled by core already. -- log is handled by core already.
delay = delay =
{ {
1, 1,
@ -3455,7 +3466,7 @@ function runner.configure( args, monitors )
nil nil
}, },
logfile = logfile =
{ {
1, 1,
function( file ) function( file )
@ -3468,14 +3479,16 @@ function runner.configure( args, monitors )
-1, -1,
function( monitor ) function( monitor )
if not monitor then if not monitor then
io.stdout:write('This Lsyncd supports these monitors:\n') io.stdout:write( 'This Lsyncd supports these monitors:\n' )
for _, v in ipairs(Monitors.list) do for _, v in ipairs(Monitors.list) do
io.stdout:write(' ',v,'\n') io.stdout:write(' ',v,'\n')
end end
io.stdout:write('\n');
lsyncd.terminate(-1); -- ERRNO io.stdout:write('\n')
lsyncd.terminate(-1)
else else
clSettings.monitor=monitor clSettings.monitor = monitor
end end
end end
}, },
@ -3488,7 +3501,7 @@ function runner.configure( args, monitors )
end end
}, },
pidfile = pidfile =
{ {
1, 1,
function( file ) function( file )
@ -3532,7 +3545,7 @@ function runner.configure( args, monitors )
end end
}, },
version = version =
{ {
0, 0,
function( ) function( )
@ -3543,12 +3556,13 @@ function runner.configure( args, monitors )
} }
-- non-opts is filled with all args that were no part dash options -- non-opts is filled with all args that were no part dash options
local nonopts = { } local nonopts = { }
local i =
1 local i = 1
while i <= #args do while i <= #args do
local a = args[i] local a = args[ i ]
if a:sub( 1, 1 ) ~= '-' then if a:sub( 1, 1 ) ~= '-' then
table.insert( nonopts, args[ i ] ) table.insert( nonopts, args[ i ] )
@ -3562,57 +3576,82 @@ function runner.configure( args, monitors )
local o = options[ a ] local o = options[ a ]
if not o then if not o then
log('Error','unknown option command line option ', args[i]) log(
os.exit(-1) -- ERRNO 'Error',
'unknown option command line option ',
args[i]
)
os.exit( -1 )
end end
if o[1] >= 0 and i + o[1] > #args then if o[ 1 ] >= 0 and i + o[ 1 ] > #args then
log('Error',a,' needs ',o[1],' arguments') log( 'Error', a ,' needs ', o[ 1 ],' arguments' )
os.exit(-1) -- ERRNO os.exit( -1 )
elseif o[1] < 0 then elseif o[1] < 0 then
o[1] = -o[1] o[ 1 ] = -o[ 1 ]
end end
if o[2] then
if o[1] == 0 then if o[ 2 ] then
o[2]() if o[ 1 ] == 0 then
elseif o[1] == 1 then o[ 2 ]( )
o[2](args[i + 1]) elseif o[ 1 ] == 1 then
elseif o[1] == 2 then o[ 2 ]( args[i + 1] )
o[2](args[i + 1], args[i + 2]) elseif o[ 1 ] == 2 then
elseif o[1] == 3 then o[ 2 ]( args[i + 1], args[i + 2] )
o[2](args[i + 1], args[i + 2], args[i + 3]) elseif o[ 1 ] == 3 then
o[ 2 ]( args[i + 1], args[i + 2], args[i + 3] )
end end
end end
i = i + o[1] i = i + o[1]
end end
i = i + 1 i = i + 1
end end
if clSettings.syncs then if clSettings.syncs then
if #nonopts ~= 0 then if #nonopts ~= 0 then
log('Error', 'There cannot be command line default syncs with a config file.') log(
os.exit(-1) -- ERRNO 'Error',
'There cannot be command line syncs and config file together.'
)
os.exit( -1 )
end end
else else
if #nonopts == 0 then if #nonopts == 0 then
runner.help(args[0])
runner.help( args[ 0 ] )
elseif #nonopts == 1 then elseif #nonopts == 1 then
return nonopts[1]
return nonopts[ 1 ]
else else
log('Error', 'There can only be one config file in command line.')
os.exit(-1) -- ERRNO -- TODO make this possible
log(
'Error',
'There can only be one config file in command line.'
)
os.exit( -1 )
end end
end end
end end
---- --
-- Called from core on init or restart after user configuration. -- Called from core on init or restart after user configuration.
-- --
-- @firstTime true the first time Lsyncd startup, false on resets -- firstTime:
-- due to HUP signal or monitor queue OVERFLOW. -- true when Lsyncd startups the first time,
-- false on resets, due to HUP signal or monitor queue overflow.
-- --
function runner.initialize(firstTime) function runner.initialize( firstTime )
-- creates settings if user didnt -- creates settings if user didnt
settings = settings or {} settings = settings or {}
@ -3620,74 +3659,109 @@ function runner.initialize(firstTime)
lockGlobals() lockGlobals()
-- copies simple settings with numeric keys to 'key=true' settings. -- copies simple settings with numeric keys to 'key=true' settings.
for k, v in ipairs(settings) do for k, v in ipairs( settings ) do
if settings[v] then
log('Error', 'Double setting "'..v..'"') if settings[ v ] then
os.exit(-1) -- ERRNO log(
'Error',
'Double setting "' .. v.. '"'
)
os.exit( -1 )
end end
settings[v]=true
settings[ v ]= true
end end
-- all command line settings overwrite config file settings -- all command line settings overwrite config file settings
for k, v in pairs(clSettings) do
for k, v in pairs( clSettings ) do
if k ~= 'syncs' then if k ~= 'syncs' then
settings[k]=v settings[ k ] = v
end end
end end
-- implicitly force insist to be true on Lsyncd resets. -- implicitly force 'insist' on Lsyncd resets.
if not firstTime then if not firstTime then
settings.insist = true settings.insist = true
end end
-- adds syncs specified by command line. -- adds syncs specified by command line.
if clSettings.syncs then if clSettings.syncs then
for _, s in ipairs(clSettings.syncs) do
for _, s in ipairs( clSettings.syncs ) do
if s[1] == 'rsync' then if s[1] == 'rsync' then
sync{default.rsync, source=s[2], target=s[3]} sync{
default.rsync,
source = s[ 2 ],
target = s[ 3 ]
}
elseif s[1] == 'rsyncssh' then elseif s[1] == 'rsyncssh' then
sync{default.rsyncssh, source=s[2], host=s[3], targetdir=s[4]} sync{
default.rsyncssh,
source = s[ 2 ],
host = s[ 3 ],
targetdir=s[ 4 ]
}
elseif s[1] == 'direct' then elseif s[1] == 'direct' then
sync{default.direct, source=s[2], target=s[3]} sync{ default.direct, source=s[2], target=s[3]}
end end
end end
end end
if settings.nodaemon then if settings.nodaemon then
lsyncd.configure('nodaemon') lsyncd.configure('nodaemon')
end end
if settings.logfile then if settings.logfile then
lsyncd.configure('logfile', settings.logfile) lsyncd.configure('logfile', settings.logfile)
end end
if settings.logident then if settings.logident then
lsyncd.configure('logident', settings.logident) lsyncd.configure('logident', settings.logident)
end end
if settings.logfacility then if settings.logfacility then
lsyncd.configure('logfacility', settings.logfacility) lsyncd.configure('logfacility', settings.logfacility)
end end
if settings.pidfile then if settings.pidfile then
lsyncd.configure('pidfile', settings.pidfile) lsyncd.configure('pidfile', settings.pidfile)
end end
----- --
-- transfers some defaults to settings -- Transfers some defaults to settings
--
if settings.statusInterval == nil then if settings.statusInterval == nil then
settings.statusInterval = default.statusInterval settings.statusInterval = default.statusInterval
end end
-- makes sure the user gave Lsyncd anything to do -- makes sure the user gave Lsyncd anything to do
if Syncs.size() == 0 then if Syncs.size() == 0 then
log('Error', 'Nothing to watch!')
os.exit(-1) -- ERRNO log(
'Error',
'Nothing to watch!'
)
os.exit( -1 )
end end
-- from now on use logging as configured instead of stdout/err. -- from now on use logging as configured instead of stdout/err.
lsyncdStatus = 'run'; lsyncdStatus = 'run';
lsyncd.configure('running'); lsyncd.configure( 'running' );
local ufuncs = { local ufuncs = {
'onAttrib', 'onCreate', 'onDelete', 'onAttrib',
'onModify', 'onMove', 'onStartup', 'onCreate',
'onDelete',
'onModify',
'onMove',
'onStartup',
} }
-- translates layer 3 scripts -- translates layer 3 scripts
@ -3703,247 +3777,365 @@ function runner.initialize(firstTime)
end end
-- runs through the Syncs created by users -- runs through the Syncs created by users
for _, s in Syncs.iwalk() do for _, s in Syncs.iwalk( ) do
if s.config.monitor == 'inotify' then if s.config.monitor == 'inotify' then
Inotify.addSync(s, s.source) Inotify.addSync( s, s.source )
elseif s.config.monitor == 'fsevents' then elseif s.config.monitor == 'fsevents' then
Fsevents.addSync(s, s.source) Fsevents.addSync( s, s.source )
else else
error('sync '..s.config.name..' has no known event monitor interface.') error(
'sync ' ..
s.config.name ..
' has no known event monitor interface.'
)
end end
-- if the sync has an init function, stacks an init delay
-- that will cause the init function to be called. -- if the sync has an init function, the init delay
-- is stacked which causes the init function to be called.
if s.config.init then if s.config.init then
s:addInitDelay() s:addInitDelay( )
end end
end end
end end
---- --
-- Called by core to query soonest alarm. -- Called by core to query the soonest alarm.
-- --
-- @return false ... no alarm, core can in untimed sleep, or -- @return false ... no alarm, core can in untimed sleep, or
-- true ... immediate action -- true ... immediate action
-- times ... the alarm time (only read if number is 1) -- times ... the alarm time (only read if number is 1)
-- --
function runner.getAlarm() function runner.getAlarm( )
if lsyncdStatus ~= 'run' then if lsyncdStatus ~= 'run' then
return false return false
end end
local alarm = false local alarm = false
----
-- checks if current nearest alarm or a is earlier
-- --
local function checkAlarm(a) -- Checks if 'a' is sooner than the 'alarm' up-value.
--
local function checkAlarm( a )
if a == nil then if a == nil then
error('got nil alarm') error('got nil alarm')
end end
if alarm == true or not a then if alarm == true or not a then
-- already immediate or no new alarm -- 'alarm' is already immediate or
-- a not a new alarm
return return
end end
-- returns the ealier time
-- sets 'alarm' to a if a is sooner
if not alarm or a < alarm then if not alarm or a < alarm then
alarm = a alarm = a
end end
end end
-- checks all syncs for their earliest alarm --
-- checks all syncs for their earliest alarm,
-- but only if the global process limit is not yet reached. -- but only if the global process limit is not yet reached.
if not settings.maxProcesses or processCount < settings.maxProcesses then --
for _, s in Syncs.iwalk() do if
checkAlarm(s:getAlarm()) not settings.maxProcesses or
processCount < settings.maxProcesses
then
for _, s in Syncs.iwalk( ) do
checkAlarm( s:getAlarm ( ))
end end
else else
log('Alarm', 'at global process limit.') log(
'Alarm',
'at global process limit.'
)
end end
-- checks if a statusfile write has been delayed -- checks if a statusfile write has been delayed
checkAlarm(StatusFile.getAlarm()) checkAlarm( StatusFile.getAlarm( ) )
-- checks for an userAlarm
checkAlarm(UserAlarms.getAlarm()) -- checks for an userAlarm
checkAlarm( UserAlarms.getAlarm( ) )
log(
'Alarm',
'runner.getAlarm returns: ',
alarm
)
log('Alarm', 'runner.getAlarm returns: ',alarm)
return alarm return alarm
end end
----- --
-- Called when an inotify event arrived. -- Called when an file system monitor events arrive
-- Simply forwards it directly to the object.
-- --
runner.inotifyEvent = Inotify.event runner.inotifyEvent = Inotify.event
runner.fsEventsEvent = Fsevents.event runner.fsEventsEvent = Fsevents.event
----- --
-- Collector for every child process that finished in startup phase -- Collector for every child process that finished in startup phase
-- --
-- Parameters are pid and exitcode of child process function runner.collector(
-- pid, -- pid of the child process
-- Can return either a new pid if one other child process exitcode -- exitcode of the child process
-- has been spawned as replacement (e.g. retry) or 0 if )
-- finished/ok.
--
function runner.collector(pid, exitcode)
if exitcode ~= 0 then if exitcode ~= 0 then
log('Error', 'Startup process',pid,' failed') log('Error', 'Startup process',pid,' failed')
terminate(-1) -- ERRNO terminate( -1 )
end end
return 0 return 0
end end
----- --
-- Called by core when an overflow happened. -- Called by core when an overflow happened.
-- --
function runner.overflow() function runner.overflow( )
log('Normal', '--- OVERFLOW in event queue ---')
log(
'Normal',
'--- OVERFLOW in event queue ---'
)
lsyncdStatus = 'fade' lsyncdStatus = 'fade'
end end
----- --
-- Called by core on a hup signal. -- Called by core on a hup signal.
-- --
function runner.hup() function runner.hup( )
log('Normal', '--- HUP signal, resetting ---')
log(
'Normal',
'--- HUP signal, resetting ---'
)
lsyncdStatus = 'fade' lsyncdStatus = 'fade'
end end
----- --
-- Called by core on a term signal. -- Called by core on a term signal.
-- --
function runner.term() function runner.term( )
log('Normal', '--- TERM signal, fading ---')
log(
'Normal',
'--- TERM signal, fading ---'
)
lsyncdStatus = 'fade' lsyncdStatus = 'fade'
end end
--============================================================================ --============================================================================
-- Lsyncd user interface -- Lsyncd runner's user interface
--============================================================================ --============================================================================
-----
-- Main utility to create new observations.
-- @returns an Inlet to that sync.
-- --
function sync(opts) -- Main utility to create new observations.
--
-- Returns an Inlet to that sync.
--
function sync( opts )
if lsyncdStatus ~= 'init' then if lsyncdStatus ~= 'init' then
error('Sync can only be created during initialization.', 2) error(
'Sync can only be created during initialization.',
2
)
end end
return Syncs.add(opts).inlet
return Syncs.add( opts ).inlet
end end
----- --
-- Spawns a new child process. -- Spawns a new child process.
-- --
-- @param agent the reason why a process is spawned. function spawn(
-- normally this is a delay/event of a sync. agent, -- the reason why a process is spawned.
-- it will mark the related files as blocked. -- a delay or delay list for a sync
-- @param binary binary to call -- it will mark the related files as blocked.
-- @param ... arguments binary, -- binary to call
-- ... -- arguments
function spawn(agent, binary, ...) )
if agent == nil or type(agent) ~= 'table' then if
error('spawning with an invalid agent', 2) agent == nil or
type( agent ) ~= 'table'
then
error(
'spawning with an invalid agent',
2
)
end end
if lsyncdStatus == 'fade' then if lsyncdStatus == 'fade' then
log('Normal', 'ignored process spawning while fading') log(
'Normal',
'ignored process spawning while fading'
)
return return
end end
if type(binary) ~= 'string' then if type( binary ) ~= 'string' then
error('calling spawn(agent, binary, ...), binary is not a string', 2) error(
'calling spawn(agent, binary, ...): binary is not a string',
2
)
end end
local dol = InletFactory.getDelayOrList(agent) local dol = InletFactory.getDelayOrList( agent )
if not dol then error('spawning with an unknown agent', 2) end
-- checks if spawn is called on already active event if not dol then
error(
'spawning with an unknown agent',
2
)
end
--
-- checks if a spawn is called on an already active event
--
if dol.status then if dol.status then
-- is an event
if dol.status ~= 'wait' then if dol.status ~= 'wait' then
error('spawn() called on an non-waiting event', 2) error('spawn() called on an non-waiting event', 2)
end end
else -- is a list
else
-- is a list
for _, d in ipairs(dol) do for _, d in ipairs(dol) do
if d.status ~= 'wait' and d.status ~= 'block' then if d.status ~= 'wait' and d.status ~= 'block' then
error('spawn() called on an non-waiting event list', 2) error('spawn() called on an non-waiting event list', 2)
end end
end end
end end
local pid = lsyncd.exec(binary, ...) --
-- tries to spawn the process
--
local pid = lsyncd.exec( binary, ... )
if pid and pid > 0 then if pid and pid > 0 then
processCount = processCount + 1 processCount = processCount + 1
if settings.maxProcesses and processCount > settings.maxProcesses then if
error('Spawned too much processes!') settings.maxProcesses and
processCount > settings.maxProcesses
then
error( 'Spawned too much processes!' )
end end
local sync = InletFactory.getSync(agent)
local sync = InletFactory.getSync( agent )
-- delay or list -- delay or list
if dol.status then if dol.status then
-- is a delay -- is a delay
dol.status = 'active' dol.status = 'active'
sync.processes[pid] = dol sync.processes[ pid ] = dol
else else
-- is a list -- is a list
for _, d in ipairs(dol) do for _, d in ipairs( dol ) do
d.status = 'active' d.status = 'active'
end end
sync.processes[pid] = dol sync.processes[ pid ] = dol
end end
end end
end end
----- --
-- Spawns a child process using the default shell. -- Spawns a child process using the default shell.
-- --
function spawnShell(agent, command, ...) function spawnShell(
return spawn(agent, '/bin/sh', '-c', command, '/bin/sh', ...) agent, -- the delay(list) to spawn the command for
command, -- the shell command
... -- additonal arguments
)
return spawn(
agent,
'/bin/sh',
'-c',
command,
'/bin/sh',
...
)
end end
----- -----
-- Observes a filedescriptor -- Observes a filedescriptor
-- --
function observefd(fd, ready, writey) function observefd(
return lsyncd.observe_fd(fd, ready, writey) fd, -- file descriptor
ready, -- called when fd is ready to be read
writey -- called when fd is ready to be written
)
return lsyncd.observe_fd(
fd,
ready,
writey
)
end end
-----
-- Nonobserves a filedescriptor
-- --
function nonobservefd(fd) -- Stops observeing a filedescriptor
return lsyncd.nonobserve_fd(fd) --
function nonobservefd(
fd -- file descriptor
)
return lsyncd.nonobserve_fd( fd )
end end
----- --
-- Calls func at timestamp. -- Calls func at timestamp.
--
-- Use now() to receive current timestamp -- Use now() to receive current timestamp
-- add seconds with '+' to it) -- add seconds with '+' to it
-- --
alarm = UserAlarms.alarm alarm = UserAlarms.alarm
----- --
-- Comfort routine also for user. -- Comfort routine also for user.
-- Returns true if 'String' starts with 'Start' -- Returns true if 'String' starts with 'Start'
-- --
function string.starts(String,Start) function string.starts( String, Start )
return string.sub(String,1,#Start)==Start
return string.sub( String, 1, #Start )==Start
end end
----- --
-- Comfort routine also for user. -- Comfort routine also for user.
-- Returns true if 'String' ends with 'End' -- Returns true if 'String' ends with 'End'
-- --
function string.ends(String,End) function string.ends( String, End )
return End=='' or string.sub(String,-#End)==End
return End == '' or string.sub( String, -#End ) == End
end end
-----
-- provides a default empty settings table.
-- --
settings = {} -- Provides a default empty settings table.
--
settings = { }
----- --
-- Returns the core the runners function interface. -- Returns the core the runners function interface.
-- --
return runner return runner