mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-13 14:43:09 +00:00
introducing checkgauge, code beautifications
This commit is contained in:
parent
1bf1d13eaa
commit
6a862d6b8f
@ -28,6 +28,64 @@ end
|
|||||||
|
|
||||||
default.rsync = { }
|
default.rsync = { }
|
||||||
local rsync = default.rsync
|
local rsync = default.rsync
|
||||||
|
-- uses default collect
|
||||||
|
|
||||||
|
--
|
||||||
|
-- used to ensure there aren't typos in the keys
|
||||||
|
--
|
||||||
|
rsync.checkgauge = {
|
||||||
|
|
||||||
|
default.checkgauge,
|
||||||
|
|
||||||
|
-- unsets default user action handlers
|
||||||
|
onCreate = false,
|
||||||
|
onModify = false,
|
||||||
|
onDelete = false,
|
||||||
|
onStartup = false,
|
||||||
|
onMove = false,
|
||||||
|
|
||||||
|
delete = true,
|
||||||
|
exclude = true,
|
||||||
|
source = true,
|
||||||
|
target = true,
|
||||||
|
|
||||||
|
rsync = {
|
||||||
|
-- rsync binary
|
||||||
|
binary = true,
|
||||||
|
|
||||||
|
-- rsync shortflags
|
||||||
|
verbose = true,
|
||||||
|
quiet = true,
|
||||||
|
checksum = true,
|
||||||
|
update = true,
|
||||||
|
links = true,
|
||||||
|
copy_links = true,
|
||||||
|
hard_links = true,
|
||||||
|
perms = true,
|
||||||
|
executability = true,
|
||||||
|
acls = true,
|
||||||
|
xattrs = true,
|
||||||
|
owner = true,
|
||||||
|
group = true,
|
||||||
|
times = true,
|
||||||
|
sparse = true,
|
||||||
|
dry_run = true,
|
||||||
|
whole_file = true,
|
||||||
|
one_file_system = true,
|
||||||
|
prune_empty_dirs = true,
|
||||||
|
ignore_times = true,
|
||||||
|
compress = true,
|
||||||
|
cvs_exclude = true,
|
||||||
|
protect_args = true,
|
||||||
|
ipv4 = true,
|
||||||
|
ipv6 = true,
|
||||||
|
|
||||||
|
-- further rsync options
|
||||||
|
rsh = true,
|
||||||
|
rsync_path = true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Spawns rsync for a list of events
|
-- Spawns rsync for a list of events
|
||||||
@ -163,10 +221,19 @@ end
|
|||||||
--
|
--
|
||||||
rsync.init = function(event)
|
rsync.init = function(event)
|
||||||
|
|
||||||
local config = event.config
|
local config = event.config
|
||||||
local inlet = event.inlet
|
local inlet = event.inlet
|
||||||
local excludes = inlet.getExcludes( )
|
local excludes = inlet.getExcludes( )
|
||||||
local delete = nil
|
local delete = nil
|
||||||
|
local target = config.target
|
||||||
|
|
||||||
|
if not target then
|
||||||
|
if not config.host then
|
||||||
|
error('Internal fail, Neither target nor host is configured')
|
||||||
|
end
|
||||||
|
|
||||||
|
target = config.host .. ':' .. config.targetdir
|
||||||
|
end
|
||||||
|
|
||||||
if config.delete then
|
if config.delete then
|
||||||
delete = { '--delete', '--ignore-errors' }
|
delete = { '--delete', '--ignore-errors' }
|
||||||
@ -179,7 +246,7 @@ rsync.init = function(event)
|
|||||||
'recursive startup rsync: ',
|
'recursive startup rsync: ',
|
||||||
config.source,
|
config.source,
|
||||||
' -> ',
|
' -> ',
|
||||||
config.target
|
target
|
||||||
)
|
)
|
||||||
|
|
||||||
spawn(
|
spawn(
|
||||||
@ -189,7 +256,7 @@ rsync.init = function(event)
|
|||||||
config.rsync._computed,
|
config.rsync._computed,
|
||||||
'-r',
|
'-r',
|
||||||
config.source,
|
config.source,
|
||||||
config.target
|
target
|
||||||
)
|
)
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -202,7 +269,7 @@ rsync.init = function(event)
|
|||||||
'recursive startup rsync: ',
|
'recursive startup rsync: ',
|
||||||
config.source,
|
config.source,
|
||||||
' -> ',
|
' -> ',
|
||||||
config.target,
|
target,
|
||||||
' excluding\n',
|
' excluding\n',
|
||||||
exS
|
exS
|
||||||
)
|
)
|
||||||
@ -216,7 +283,7 @@ rsync.init = function(event)
|
|||||||
config.rsync._computed,
|
config.rsync._computed,
|
||||||
'-r',
|
'-r',
|
||||||
config.source,
|
config.source,
|
||||||
config.target
|
target
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -225,19 +292,30 @@ end
|
|||||||
--
|
--
|
||||||
-- Prepares and checks a syncs configuration on startup.
|
-- Prepares and checks a syncs configuration on startup.
|
||||||
--
|
--
|
||||||
rsync.prepare = function( config )
|
rsync.prepare = function(
|
||||||
|
config, -- the configuration
|
||||||
|
level, -- additional error level for inherited use ( by rsyncssh )
|
||||||
|
skipTarget -- used by rsyncssh, do not check for target
|
||||||
|
)
|
||||||
|
|
||||||
if not config.target then
|
level = level or 4
|
||||||
|
|
||||||
|
--
|
||||||
|
-- First let default.prepare test the checkgauge
|
||||||
|
--
|
||||||
|
default.prepare( config, level + 6 )
|
||||||
|
|
||||||
|
if not skipTarget and not config.target then
|
||||||
error(
|
error(
|
||||||
'default.rsync needs "target" configured',
|
'default.rsync needs "target" configured',
|
||||||
4
|
level
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
if config.rsyncOps then
|
if config.rsyncOps then
|
||||||
error(
|
error(
|
||||||
'"rsyncOps" is outdated please use the new rsync = { ... } syntax.',
|
'"rsyncOps" is outdated please use the new rsync = { ... } syntax.',
|
||||||
4
|
level
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -246,7 +324,7 @@ rsync.prepare = function( config )
|
|||||||
'"rsyncOpts" is outdated in favor of the new rsync = { ... } syntax\n"' +
|
'"rsyncOpts" is outdated in favor of the new rsync = { ... } syntax\n"' +
|
||||||
'for which you provided the _extra attribute as well.\n"' +
|
'for which you provided the _extra attribute as well.\n"' +
|
||||||
'Please remove rsyncOpts from your config.',
|
'Please remove rsyncOpts from your config.',
|
||||||
4
|
level
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -265,7 +343,7 @@ rsync.prepare = function( config )
|
|||||||
'"rsyncBinary is outdated in favor of the new rsync = { ... } syntax\n"'+
|
'"rsyncBinary is outdated in favor of the new rsync = { ... } syntax\n"'+
|
||||||
'for which you provided the binary attribute as well.\n"' +
|
'for which you provided the binary attribute as well.\n"' +
|
||||||
"Please remove rsyncBinary from your config.'",
|
"Please remove rsyncBinary from your config.'",
|
||||||
4
|
level
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -283,75 +361,108 @@ rsync.prepare = function( config )
|
|||||||
if config.rsync._computed then
|
if config.rsync._computed then
|
||||||
error(
|
error(
|
||||||
'please do not use the internal rsync._computed parameter',
|
'please do not use the internal rsync._computed parameter',
|
||||||
4
|
level
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- computes the rsync arguments into one list
|
-- computes the rsync arguments into one list
|
||||||
local rsync = config.rsync;
|
local rsync = config.rsync;
|
||||||
|
|
||||||
rsync._computed = { true }
|
rsync._computed = { true }
|
||||||
local computed = rsync._computed
|
local computed = rsync._computed
|
||||||
|
local computedN = 1
|
||||||
|
|
||||||
|
local shortFlags = {
|
||||||
|
verbose = 'v',
|
||||||
|
quiet = 'q',
|
||||||
|
checksum = 'c',
|
||||||
|
update = 'u',
|
||||||
|
links = 'l',
|
||||||
|
copy_links = 'L',
|
||||||
|
hard_links = 'H',
|
||||||
|
perms = 'p',
|
||||||
|
executability = 'E',
|
||||||
|
acls = 'A',
|
||||||
|
xattrs = 'X',
|
||||||
|
owner = 'o',
|
||||||
|
group = 'g',
|
||||||
|
times = 't',
|
||||||
|
sparse = 'S',
|
||||||
|
dry_run = 'n',
|
||||||
|
whole_file = 'W',
|
||||||
|
one_file_system = 'x',
|
||||||
|
prune_empty_dirs = 'm',
|
||||||
|
ignore_times = 'I',
|
||||||
|
compress = 'z',
|
||||||
|
cvs_exclude = 'C',
|
||||||
|
protect_args = 's',
|
||||||
|
ipv4 = '4',
|
||||||
|
ipv6 = '6'
|
||||||
|
}
|
||||||
|
|
||||||
local shorts = { '-' }
|
local shorts = { '-' }
|
||||||
|
local shortsN = 2
|
||||||
|
|
||||||
if config.rsync._extra then
|
if config.rsync._extra then
|
||||||
for k, v in ipairs( config.rsync._extra ) do
|
for k, v in ipairs( config.rsync._extra ) do
|
||||||
computed[ k + 1 ] = v
|
computed[ computedN ] = v
|
||||||
|
computedN = computedN + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if rsync.links then
|
for k, flag in pairs( shortFlags ) do
|
||||||
shorts[ #shorts + 1 ] = 'l'
|
if config.rsync[k] then
|
||||||
|
shorts[ shortsN ] = flag
|
||||||
|
shortsN = shortsN + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if rsync.times then
|
if config.rsync.rsh then
|
||||||
shorts[ #shorts + 1 ] = 't'
|
computed[ computedN ] = '--rsh=' + config.rsync.rsh
|
||||||
|
computedN = computedN + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if rsync.protectArgs then
|
if config.rsync.rsync_path then
|
||||||
shorts[ #shorts + 1 ] = 's'
|
computed[ computedN ] = '--rsync-path=' + config.rsync.rsync_path
|
||||||
|
computedN = computedN + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if #shorts ~= 1 then
|
if shortsN ~= 2 then
|
||||||
computed[ 1 ] = table.concat( shorts, '' )
|
computed[ 1 ] = table.concat( shorts, '' )
|
||||||
else
|
else
|
||||||
computed[ 1 ] = { }
|
computed[ 1 ] = { }
|
||||||
end
|
end
|
||||||
|
|
||||||
-- appends a / to target if not present
|
-- appends a / to target if not present
|
||||||
if string.sub(config.target, -1) ~= '/' then
|
if not skipTarget and string.sub(config.target, -1) ~= '/' then
|
||||||
config.target = config.target..'/'
|
config.target = config.target..'/'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
-- rsync uses default collect
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- By default do deletes.
|
-- By default do deletes.
|
||||||
--
|
--
|
||||||
rsync.delete = true
|
rsync.delete = true
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Rsyncd exitcodes
|
||||||
|
--
|
||||||
|
rsync.exitcodes = default.rsyncExitCodes
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Calls rsync with this default options
|
-- Calls rsync with this default options
|
||||||
--
|
--
|
||||||
rsync.rsync = {
|
rsync.rsync = {
|
||||||
-- The rsync binary to be called.
|
-- The rsync binary to be called.
|
||||||
binary = '/usr/bin/rsync',
|
binary = '/usr/bin/rsync',
|
||||||
links = true,
|
links = true,
|
||||||
times = true,
|
times = true,
|
||||||
protectArgs = true
|
protect_args = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Exit codes for rsync.
|
|
||||||
--
|
|
||||||
rsync.exitcodes = default.rsyncExitCodes
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Default delay
|
-- Default delay
|
||||||
--
|
--
|
||||||
|
@ -16,344 +16,340 @@
|
|||||||
--
|
--
|
||||||
|
|
||||||
if not default then
|
if not default then
|
||||||
error('default not loaded');
|
error( 'default not loaded' );
|
||||||
|
end
|
||||||
|
|
||||||
|
if not default.rsync then
|
||||||
|
error( 'default.rsync not loaded' );
|
||||||
end
|
end
|
||||||
|
|
||||||
if default.rsyncssh then
|
if default.rsyncssh then
|
||||||
error('default-rsyncssh already loaded');
|
error( 'default-rsyncssh already loaded' );
|
||||||
end
|
end
|
||||||
|
|
||||||
default.rsyncssh = {
|
--
|
||||||
|
-- rsyncssh extends default.rsync
|
||||||
|
--
|
||||||
|
local rsyncssh = { default.rsync }
|
||||||
|
default.rsyncssh = rsyncssh
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Spawns rsync for a list of events
|
-- used to ensure there aren't typos in the keys
|
||||||
--
|
--
|
||||||
action = function(inlet)
|
rsyncssh.checkgauge = {
|
||||||
|
|
||||||
local event, event2 = inlet.getEvent()
|
-- unsets the inherited value of from default.rsync
|
||||||
local config = inlet.getConfig()
|
target = false,
|
||||||
|
onMove = true,
|
||||||
|
|
||||||
-- makes move local on host
|
-- rsyncssh users host and targetdir
|
||||||
-- if fails deletes the source...
|
host = true,
|
||||||
if event.etype == 'Move' then
|
targetdir = true,
|
||||||
log('Normal', 'Moving ',event.path,' -> ',event2.path)
|
|
||||||
spawn(event, '/usr/bin/ssh',
|
-- ssh settings
|
||||||
config.host,
|
ssh = {
|
||||||
'mv',
|
binary = true,
|
||||||
'\"' .. config.targetdir .. event.path .. '\"',
|
port = true,
|
||||||
'\"' .. config.targetdir .. event2.path .. '\"',
|
_extra = true
|
||||||
'||', 'rm', '-rf',
|
},
|
||||||
'\"' .. config.targetdir .. event.path .. '\"')
|
|
||||||
|
-- xargs settings
|
||||||
|
xargs = {
|
||||||
|
binary = true,
|
||||||
|
delimiter = true,
|
||||||
|
_extra = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Spawns rsync for a list of events
|
||||||
|
--
|
||||||
|
rsyncssh.action = function( inlet )
|
||||||
|
|
||||||
|
local event, event2 = inlet.getEvent()
|
||||||
|
local config = inlet.getConfig()
|
||||||
|
|
||||||
|
-- makes move local on target host
|
||||||
|
-- if the move fails, it deletes the source
|
||||||
|
if event.etype == 'Move' then
|
||||||
|
log('Normal', 'Moving ',event.path,' -> ',event2.path)
|
||||||
|
|
||||||
|
spawn(
|
||||||
|
event,
|
||||||
|
config.ssh.binary,
|
||||||
|
-- config.ssh._computed, TODO XXX
|
||||||
|
config.host,
|
||||||
|
'mv',
|
||||||
|
'\"' .. config.targetdir .. event.path .. '\"',
|
||||||
|
'\"' .. config.targetdir .. event2.path .. '\"',
|
||||||
|
'||', 'rm', '-rf',
|
||||||
|
'\"' .. config.targetdir .. event.path .. '\"')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- uses ssh to delete files on remote host
|
||||||
|
-- instead of constructing rsync filters
|
||||||
|
|
||||||
|
if event.etype == 'Delete' then
|
||||||
|
if not config.delete then
|
||||||
|
inlet.discardEvent(event)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- uses ssh to delete files on remote host
|
-- gets all other deletes ready to be
|
||||||
-- instead of constructing rsync filters
|
-- executed
|
||||||
|
|
||||||
if event.etype == 'Delete' then
|
|
||||||
|
|
||||||
if not config.delete then
|
|
||||||
inlet.discardEvent(event)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local elist = inlet.getEvents(
|
|
||||||
function(e)
|
|
||||||
return e.etype == 'Delete'
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
local paths = elist.getPaths(
|
|
||||||
function(etype, path1, path2)
|
|
||||||
if path2 then
|
|
||||||
return config.targetdir..path1, config.targetdir..path2
|
|
||||||
else
|
|
||||||
return config.targetdir..path1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
for _, v in pairs(paths) do
|
|
||||||
if string.match(v, '^%s*/+%s*$') then
|
|
||||||
log('Error', 'refusing to `rm -rf /` the target!')
|
|
||||||
terminate(-1) -- ERRNO
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
log('Normal', 'Deleting list\n', table.concat(paths, '\n'))
|
|
||||||
|
|
||||||
local params = {}
|
|
||||||
|
|
||||||
if config.port then
|
|
||||||
params[#params + 1] = 'p'
|
|
||||||
params[#params + 1] = config.port
|
|
||||||
end
|
|
||||||
|
|
||||||
spawn(
|
|
||||||
elist,
|
|
||||||
config.ssh.binary,
|
|
||||||
'<', table.concat(paths, config.xargs.delimiter),
|
|
||||||
params,
|
|
||||||
config.ssh._extra,
|
|
||||||
config.host,
|
|
||||||
config.xargs.binary,
|
|
||||||
config.xargs._extra
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- for everything else spawn a rsync
|
|
||||||
local elist = inlet.getEvents(
|
local elist = inlet.getEvents(
|
||||||
function(e)
|
function( e )
|
||||||
-- TODO use a table
|
return e.etype == 'Delete'
|
||||||
return e.etype ~= 'Move' and
|
|
||||||
e.etype ~= 'Delete' and
|
|
||||||
e.etype ~= 'Init' and
|
|
||||||
e.etype ~= 'Blanket'
|
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
local paths = elist.getPaths()
|
-- returns the paths of the delete list
|
||||||
|
local paths = elist.getPaths(
|
||||||
|
function( etype, path1, path2 )
|
||||||
|
if path2 then
|
||||||
|
return config.targetdir..path1, config.targetdir..path2
|
||||||
|
else
|
||||||
|
return config.targetdir..path1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
-- removes trailing slashes from dirs.
|
-- ensures none of the paths is '/'
|
||||||
for k, v in ipairs(paths) do
|
for _, v in pairs( paths ) do
|
||||||
if string.byte(v, -1) == 47 then
|
if string.match(v, '^%s*/+%s*$') then
|
||||||
paths[k] = string.sub(v, 1, -2)
|
log('Error', 'refusing to `rm -rf /` the target!')
|
||||||
|
terminate(-1) -- ERRNO
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local sPaths = table.concat(paths, '\n')
|
log(
|
||||||
local zPaths = table.concat(paths, '\000')
|
'Normal',
|
||||||
log('Normal', 'Rsyncing list\n', sPaths)
|
'Deleting list\n',
|
||||||
|
table.concat( paths, '\n' )
|
||||||
|
)
|
||||||
|
|
||||||
|
local params = { }
|
||||||
|
|
||||||
spawn(
|
spawn(
|
||||||
elist,
|
elist,
|
||||||
config.rsyncBinary,
|
config.ssh.binary,
|
||||||
'<', zPaths,
|
'<', table.concat(paths, config.xargs.delimiter),
|
||||||
config.rsyncOpts,
|
params,
|
||||||
'--from0',
|
-- config.ssh._computed, TODO XXX
|
||||||
'--files-from=-',
|
config.host,
|
||||||
config.source,
|
config.xargs.binary,
|
||||||
config.host .. ':' .. config.targetdir
|
config.xargs._extra
|
||||||
)
|
)
|
||||||
end,
|
|
||||||
|
|
||||||
-----
|
return
|
||||||
-- Called when collecting a finished child process
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
collect = function(agent, exitcode)
|
-- for everything else a rsync is spawned
|
||||||
|
--
|
||||||
|
local elist = inlet.getEvents(
|
||||||
|
function(e)
|
||||||
|
-- TODO use a table
|
||||||
|
return e.etype ~= 'Move' and
|
||||||
|
e.etype ~= 'Delete' and
|
||||||
|
e.etype ~= 'Init' and
|
||||||
|
e.etype ~= 'Blanket'
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
local config = agent.config
|
local paths = elist.getPaths( )
|
||||||
|
|
||||||
if not agent.isList and agent.etype == 'Init' then
|
|
||||||
|
|
||||||
local rc = config.rsyncExitCodes[exitcode]
|
|
||||||
|
|
||||||
if rc == 'ok' then
|
|
||||||
log('Normal', 'Startup of "',agent.source,'" finished: ', exitcode)
|
|
||||||
elseif rc == 'again' then
|
|
||||||
if settings.insist then
|
|
||||||
log('Normal', 'Retrying startup of "',agent.source,'": ', exitcode)
|
|
||||||
else
|
|
||||||
log('Error', 'Temporary or permanent failure on startup of "',
|
|
||||||
agent.source, '". Terminating since "insist" is not set.');
|
|
||||||
terminate(-1) -- ERRNO
|
|
||||||
end
|
|
||||||
elseif rc == 'die' then
|
|
||||||
log('Error', 'Failure on startup of "',agent.source,'": ', exitcode)
|
|
||||||
else
|
|
||||||
log('Error', 'Unknown exitcode on startup of "', agent.source,': "',exitcode)
|
|
||||||
rc = 'die'
|
|
||||||
end
|
|
||||||
|
|
||||||
return rc
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- removes trailing slashes from dirs.
|
||||||
|
--
|
||||||
|
for k, v in ipairs( paths ) do
|
||||||
|
if string.byte(v, -1) == 47 then
|
||||||
|
paths[k] = string.sub(v, 1, -2)
|
||||||
end
|
end
|
||||||
|
|
||||||
if agent.isList then
|
end
|
||||||
|
|
||||||
local rc = config.rsyncExitCodes[exitcode]
|
local sPaths = table.concat(paths, '\n')
|
||||||
|
local zPaths = table.concat(paths, '\000')
|
||||||
|
|
||||||
if rc == 'ok' then
|
log('Normal', 'Rsyncing list\n', sPaths)
|
||||||
log('Normal', 'Finished (list): ',exitcode)
|
|
||||||
elseif rc == 'again' then
|
spawn(
|
||||||
log('Normal', 'Retrying (list): ',exitcode)
|
elist,
|
||||||
elseif rc == 'die' then
|
config.rsync.binary,
|
||||||
log('Error', 'Failure (list): ', exitcode)
|
'<', zPaths,
|
||||||
|
config.rsync._computed,
|
||||||
|
'--from0',
|
||||||
|
'--files-from=-',
|
||||||
|
config.source,
|
||||||
|
config.host .. ':' .. config.targetdir
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- Called when collecting a finished child process
|
||||||
|
--
|
||||||
|
rsyncssh.collect = function( agent, exitcode )
|
||||||
|
|
||||||
|
local config = agent.config
|
||||||
|
|
||||||
|
if not agent.isList and agent.etype == 'Init' then
|
||||||
|
local rc = config.rsyncExitCodes[exitcode]
|
||||||
|
|
||||||
|
if rc == 'ok' then
|
||||||
|
log('Normal', 'Startup of "',agent.source,'" finished: ', exitcode)
|
||||||
|
elseif rc == 'again' then
|
||||||
|
if settings.insist then
|
||||||
|
log('Normal', 'Retrying startup of "',agent.source,'": ', exitcode)
|
||||||
else
|
else
|
||||||
log('Error', 'Unknown exitcode (list): ',exitcode)
|
log('Error', 'Temporary or permanent failure on startup of "',
|
||||||
rc = 'die'
|
agent.source, '". Terminating since "insist" is not set.');
|
||||||
|
terminate(-1) -- ERRNO
|
||||||
end
|
end
|
||||||
|
|
||||||
return rc
|
elseif rc == 'die' then
|
||||||
|
log('Error', 'Failure on startup of "',agent.source,'": ', exitcode)
|
||||||
else
|
else
|
||||||
|
log('Error', 'Unknown exitcode on startup of "', agent.source,': "',exitcode)
|
||||||
local rc = config.sshExitCodes[exitcode]
|
rc = 'die'
|
||||||
|
|
||||||
if rc == 'ok' then
|
|
||||||
log('Normal', 'Finished ',agent.etype,' ',agent.sourcePath,': ',exitcode)
|
|
||||||
elseif rc == 'again' then
|
|
||||||
log('Normal', 'Retrying ',agent.etype,' ',agent.sourcePath,': ',exitcode)
|
|
||||||
elseif rc == 'die' then
|
|
||||||
log('Normal', 'Failure ',agent.etype,' ',agent.sourcePath,': ',exitcode)
|
|
||||||
else
|
|
||||||
log('Error', 'Unknown exitcode ',agent.etype,' ',agent.sourcePath,': ',exitcode)
|
|
||||||
rc = 'die'
|
|
||||||
end
|
|
||||||
|
|
||||||
return rc
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
return rc
|
||||||
|
|
||||||
--
|
end
|
||||||
-- spawns the recursive startup sync
|
|
||||||
--
|
|
||||||
init = function(event)
|
|
||||||
|
|
||||||
local config = event.config
|
if agent.isList then
|
||||||
local inlet = event.inlet
|
local rc = config.rsyncExitCodes[exitcode]
|
||||||
local excludes = inlet.getExcludes()
|
if rc == 'ok' then
|
||||||
local target = config.host .. ':' .. config.targetdir
|
log('Normal', 'Finished (list): ',exitcode)
|
||||||
local delete = nil
|
elseif rc == 'again' then
|
||||||
|
log('Normal', 'Retrying (list): ',exitcode)
|
||||||
if config.delete then
|
elseif rc == 'die' then
|
||||||
delete = { '--delete', '--ignore-errors' };
|
log('Error', 'Failure (list): ', exitcode)
|
||||||
end
|
|
||||||
|
|
||||||
if #excludes == 0 then
|
|
||||||
log('Normal', 'Recursive startup rsync: ',config.source,' -> ',target)
|
|
||||||
spawn(
|
|
||||||
event, config.rsyncBinary,
|
|
||||||
delete,
|
|
||||||
'-r',
|
|
||||||
config.rsyncOpts,
|
|
||||||
config.source,
|
|
||||||
target
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
local exS = table.concat(excludes, '\n')
|
log('Error', 'Unknown exitcode (list): ',exitcode)
|
||||||
log('Normal', 'Recursive startup rsync: ',config.source,
|
rc = 'die'
|
||||||
' -> ',target,' with excludes.')
|
|
||||||
spawn(
|
|
||||||
event, config.rsyncBinary,
|
|
||||||
'<', exS,
|
|
||||||
'--exclude-from=-',
|
|
||||||
delete,
|
|
||||||
'-r',
|
|
||||||
config.rsyncOpts,
|
|
||||||
config.source,
|
|
||||||
target
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end,
|
return rc
|
||||||
|
else
|
||||||
|
local rc = config.sshExitCodes[exitcode]
|
||||||
|
|
||||||
--
|
if rc == 'ok' then
|
||||||
-- checks the configuration.
|
log('Normal', 'Finished ',agent.etype,' ',agent.sourcePath,': ',exitcode)
|
||||||
--
|
elseif rc == 'again' then
|
||||||
prepare = function(config)
|
log('Normal', 'Retrying ',agent.etype,' ',agent.sourcePath,': ',exitcode)
|
||||||
|
elseif rc == 'die' then
|
||||||
if not config.host then
|
log('Normal', 'Failure ',agent.etype,' ',agent.sourcePath,': ',exitcode)
|
||||||
error('default.rsyncssh needs "host" configured', 4)
|
else
|
||||||
|
log('Error', 'Unknown exitcode ',agent.etype,' ',agent.sourcePath,': ',exitcode)
|
||||||
|
rc = 'die'
|
||||||
end
|
end
|
||||||
|
|
||||||
if not config.targetdir then
|
return rc
|
||||||
error('default.rsyncssh needs "targetdir" configured', 4)
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if config.rsyncOps then
|
end
|
||||||
error('did you mean rsyncOpts with "t"?', 4)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- appends a slash to the targetdir if missing
|
--
|
||||||
if string.sub(config.targetdir, -1) ~= '/' then
|
-- checks the configuration.
|
||||||
config.targetdir = config.targetdir .. '/'
|
--
|
||||||
end
|
rsyncssh.prepare = function( config )
|
||||||
end,
|
|
||||||
|
|
||||||
--
|
default.rsync.prepare( config, 5, true )
|
||||||
-- the rsync binary called
|
|
||||||
--
|
|
||||||
rsyncBinary = '/usr/bin/rsync',
|
|
||||||
|
|
||||||
--
|
if not config.host then
|
||||||
-- calls rsync with this default short opts
|
error('default.rsyncssh needs "host" configured', 4)
|
||||||
--
|
end
|
||||||
rsyncOpts = '-lts',
|
|
||||||
|
|
||||||
--
|
if not config.targetdir then
|
||||||
-- allow processes
|
error('default.rsyncssh needs "targetdir" configured', 4)
|
||||||
--
|
end
|
||||||
maxProcesses = 1,
|
|
||||||
|
|
||||||
--
|
if config.rsyncOps then
|
||||||
-- The core should not split move events
|
error('did you mean rsyncOpts with "t"?', 4)
|
||||||
--
|
end
|
||||||
onMove = true,
|
|
||||||
|
|
||||||
--
|
-- appends a slash to the targetdir if missing
|
||||||
-- default delay
|
if string.sub(config.targetdir, -1) ~= '/' then
|
||||||
--
|
config.targetdir = config.targetdir .. '/'
|
||||||
delay = 15,
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- allow processes
|
||||||
|
--
|
||||||
|
rsyncssh.maxProcesses = 1
|
||||||
|
|
||||||
|
--
|
||||||
|
-- The core should not split move events
|
||||||
|
--
|
||||||
|
rsyncssh.onMove = true
|
||||||
|
|
||||||
|
--
|
||||||
|
-- default delay
|
||||||
|
--
|
||||||
|
rsyncssh.delay = 15
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- by default do deletes
|
-- no default exit codes
|
||||||
--
|
--
|
||||||
delete = true,
|
rsyncssh.exitcodes = false
|
||||||
|
|
||||||
|
--
|
||||||
|
-- rsync exit codes
|
||||||
|
--
|
||||||
|
rsyncssh.rsyncExitCodes = default.rsyncExitCodes
|
||||||
|
|
||||||
|
--
|
||||||
|
-- ssh exit codes
|
||||||
|
--
|
||||||
|
rsyncssh.sshExitCodes = default.sshExitCodes
|
||||||
|
|
||||||
|
--
|
||||||
|
-- xargs calls configuration
|
||||||
|
--
|
||||||
|
-- xargs is used to delete multiple remote files, when ssh access is
|
||||||
|
-- available this is simpler than to build filters for rsync for this.
|
||||||
|
--
|
||||||
|
rsyncssh.xargs = {
|
||||||
|
|
||||||
--
|
--
|
||||||
-- rsync exit codes
|
-- the binary called (on target host)
|
||||||
--
|
binary = '/usr/bin/xargs',
|
||||||
rsyncExitCodes = default.rsyncExitCodes,
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- ssh exit codes
|
-- delimiter, uses null by default, you might want to override this for older
|
||||||
--
|
-- by for example '\n'
|
||||||
sshExitCodes = default.sshExitCodes,
|
delimiter = '\000',
|
||||||
|
|
||||||
--
|
--
|
||||||
-- xargs calls configuration
|
-- extra parameters
|
||||||
--
|
_extra = { '-0', 'rm -rf' }
|
||||||
-- xargs is used to delete multiple remote files, when ssh access is
|
|
||||||
-- available this is simpler than to build filters for rsync for this.
|
|
||||||
--
|
|
||||||
xargs = {
|
|
||||||
|
|
||||||
--
|
|
||||||
-- the binary called (on target host)
|
|
||||||
binary = '/usr/bin/xargs',
|
|
||||||
|
|
||||||
--
|
|
||||||
-- delimiter, uses null by default, you might want to override this for older
|
|
||||||
-- by for example '\n'
|
|
||||||
delimiter = '\000',
|
|
||||||
|
|
||||||
--
|
|
||||||
-- extra parameters
|
|
||||||
_extra = { '-0', 'rm -rf' }
|
|
||||||
},
|
|
||||||
|
|
||||||
--
|
|
||||||
-- ssh calls configuration
|
|
||||||
--
|
|
||||||
-- ssh is used to move and delete files on the target host
|
|
||||||
--
|
|
||||||
ssh = {
|
|
||||||
--
|
|
||||||
-- the binary called
|
|
||||||
binary = '/usr/bin/ssh',
|
|
||||||
|
|
||||||
--
|
|
||||||
-- if set connect to this port
|
|
||||||
port = nil,
|
|
||||||
|
|
||||||
--
|
|
||||||
-- extra parameters
|
|
||||||
_extra = { }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
-- ssh calls configuration
|
||||||
|
--
|
||||||
|
-- ssh is used to move and delete files on the target host
|
||||||
|
--
|
||||||
|
rsyncssh.ssh = {
|
||||||
|
|
||||||
|
--
|
||||||
|
-- the binary called
|
||||||
|
--
|
||||||
|
binary = '/usr/bin/ssh',
|
||||||
|
|
||||||
|
--
|
||||||
|
-- if set connect to this port
|
||||||
|
--
|
||||||
|
port = nil,
|
||||||
|
|
||||||
|
--
|
||||||
|
-- extra parameters
|
||||||
|
--
|
||||||
|
_extra = { }
|
||||||
|
}
|
||||||
|
|
||||||
|
499
default.lua
499
default.lua
@ -9,237 +9,332 @@
|
|||||||
--============================================================================
|
--============================================================================
|
||||||
|
|
||||||
if default then
|
if default then
|
||||||
error('default already loaded')
|
error( 'default already loaded' )
|
||||||
end
|
end
|
||||||
|
|
||||||
default = {
|
default = { }
|
||||||
-----
|
|
||||||
-- Default action calls user scripts on**** functions.
|
|
||||||
--
|
|
||||||
action = function(inlet)
|
|
||||||
-- in case of moves getEvent returns the origin and dest of the move
|
|
||||||
local event, event2 = inlet.getEvent()
|
|
||||||
local config = inlet.getConfig()
|
|
||||||
local func = config['on'.. event.etype]
|
|
||||||
if func then
|
|
||||||
func(event, event2)
|
|
||||||
end
|
|
||||||
-- if function didnt change the wait status its not interested
|
|
||||||
-- in this event -> drop it.
|
|
||||||
if event.status == 'wait' then
|
|
||||||
inlet.discardEvent(event)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
|
|
||||||
-----
|
--
|
||||||
-- Default collector.
|
-- used to ensure there aren't typos in the keys
|
||||||
--
|
--
|
||||||
-- Called when collecting a finished child process
|
default.checkgauge = {
|
||||||
--
|
action = true,
|
||||||
collect = function(agent, exitcode)
|
checkgauge = true,
|
||||||
|
collect = true,
|
||||||
|
delay = true,
|
||||||
|
exitcodes = true,
|
||||||
|
init = true,
|
||||||
|
maxDelays = true,
|
||||||
|
maxProcesses = true,
|
||||||
|
onCreate = true,
|
||||||
|
onModify = true,
|
||||||
|
onDelete = true,
|
||||||
|
onStartup = true,
|
||||||
|
onMove = true,
|
||||||
|
prepare = true,
|
||||||
|
rsyncExitCodes = true, -- TODO
|
||||||
|
sshExitCodes = true -- TODO
|
||||||
|
}
|
||||||
|
|
||||||
local config = agent.config
|
--
|
||||||
local rc
|
-- On default action the user's on*** scripts are called.
|
||||||
|
--
|
||||||
|
default.action = function( inlet )
|
||||||
|
|
||||||
if config.exitcodes then
|
-- in case of moves getEvent returns the origin and dest of the move
|
||||||
rc = config.exitcodes[exitcode]
|
local event, event2 = inlet.getEvent( )
|
||||||
elseif exitcode == 0 then
|
local config = inlet.getConfig( )
|
||||||
rc = 'ok'
|
|
||||||
else
|
|
||||||
rc = 'die'
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO synchronize with similar code before
|
local func = config[ 'on'.. event.etype ]
|
||||||
if not agent.isList and agent.etype == 'Init' then
|
|
||||||
if rc == 'ok' then
|
|
||||||
log('Normal', 'Startup of "',agent.source,'" finished.')
|
|
||||||
return 'ok'
|
|
||||||
elseif rc == 'again' then
|
|
||||||
if settings.insist then
|
|
||||||
log(
|
|
||||||
'Normal',
|
|
||||||
'Retrying startup of "',
|
|
||||||
agent.source,
|
|
||||||
'": ',
|
|
||||||
exitcode
|
|
||||||
)
|
|
||||||
|
|
||||||
return 'again'
|
if func then
|
||||||
else
|
func( event, event2 )
|
||||||
log(
|
end
|
||||||
'Error',
|
|
||||||
'Temporary or permanent failure on startup of "',
|
|
||||||
agent.source,
|
|
||||||
'". Terminating since "insist" is not set.'
|
|
||||||
)
|
|
||||||
|
|
||||||
terminate( -1 )
|
-- if function didnt change the wait status its not interested
|
||||||
end
|
-- in this event -> drop it.
|
||||||
elseif rc == 'die' then
|
if event.status == 'wait' then
|
||||||
|
inlet.discardEvent( event )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Default collector.
|
||||||
|
--
|
||||||
|
-- Called when collecting a finished child process
|
||||||
|
--
|
||||||
|
default.collect = function( agent, exitcode )
|
||||||
|
|
||||||
|
local config = agent.config
|
||||||
|
local rc
|
||||||
|
|
||||||
|
if config.exitcodes then
|
||||||
|
rc = config.exitcodes[exitcode]
|
||||||
|
elseif exitcode == 0 then
|
||||||
|
rc = 'ok'
|
||||||
|
else
|
||||||
|
rc = 'die'
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO synchronize with similar code before
|
||||||
|
if not agent.isList and agent.etype == 'Init' then
|
||||||
|
if rc == 'ok' then
|
||||||
|
log('Normal', 'Startup of "',agent.source,'" finished.')
|
||||||
|
return 'ok'
|
||||||
|
elseif rc == 'again' then
|
||||||
|
if settings.insist then
|
||||||
|
log(
|
||||||
|
'Normal',
|
||||||
|
'Retrying startup of "',
|
||||||
|
agent.source,
|
||||||
|
'": ',
|
||||||
|
exitcode
|
||||||
|
)
|
||||||
|
|
||||||
|
return 'again'
|
||||||
|
else
|
||||||
log(
|
log(
|
||||||
'Error',
|
'Error',
|
||||||
'Failure on startup of "',
|
'Temporary or permanent failure on startup of "',
|
||||||
agent.source,
|
agent.source,
|
||||||
'".'
|
'". Terminating since "insist" is not set.'
|
||||||
)
|
)
|
||||||
|
|
||||||
terminate( -1 )
|
terminate( -1 )
|
||||||
else
|
|
||||||
log(
|
|
||||||
'Error',
|
|
||||||
'Unknown exitcode "',
|
|
||||||
exitcode,
|
|
||||||
'" on startup of "',
|
|
||||||
agent.source,
|
|
||||||
'".'
|
|
||||||
)
|
|
||||||
return 'die'
|
|
||||||
end
|
end
|
||||||
end
|
elseif rc == 'die' then
|
||||||
|
log(
|
||||||
|
'Error',
|
||||||
|
'Failure on startup of "',
|
||||||
|
agent.source,
|
||||||
|
'".'
|
||||||
|
)
|
||||||
|
|
||||||
if agent.isList then
|
terminate( -1 )
|
||||||
if rc == 'ok' then
|
|
||||||
log(
|
|
||||||
'Normal',
|
|
||||||
'Finished a list after exitcode: ',
|
|
||||||
exitcode
|
|
||||||
)
|
|
||||||
elseif rc == 'again' then
|
|
||||||
log(
|
|
||||||
'Normal',
|
|
||||||
'Retrying a list after exitcode = ',
|
|
||||||
exitcode
|
|
||||||
)
|
|
||||||
elseif rc == 'die' then
|
|
||||||
log(
|
|
||||||
'Error',
|
|
||||||
'Failure with a list width exitcode = ',
|
|
||||||
exitcode
|
|
||||||
)
|
|
||||||
else
|
|
||||||
log(
|
|
||||||
'Error',
|
|
||||||
'Unknown exitcode "',exitcode,'" with a list'
|
|
||||||
)
|
|
||||||
|
|
||||||
rc = 'die'
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
if rc == 'ok' then
|
log(
|
||||||
log('Normal', 'Retrying ',agent.etype,' on ',agent.sourcePath,' = ',exitcode)
|
'Error',
|
||||||
elseif rc == 'again' then
|
'Unknown exitcode "',
|
||||||
log('Normal', 'Finished ',agent.etype,' on ',agent.sourcePath,' = ',exitcode)
|
exitcode,
|
||||||
elseif rc == 'die' then
|
'" on startup of "',
|
||||||
log('Error', 'Failure with ',agent.etype,' on ',agent.sourcePath,' = ',exitcode)
|
agent.source,
|
||||||
else
|
'".'
|
||||||
log('Normal', 'Unknown exitcode "',exitcode,'" with ', agent.etype,
|
)
|
||||||
' on ',agent.sourcePath,' = ',exitcode)
|
return 'die'
|
||||||
rc = 'die'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return rc
|
if agent.isList then
|
||||||
end,
|
if rc == 'ok' then
|
||||||
|
log(
|
||||||
|
'Normal',
|
||||||
|
'Finished a list after exitcode: ',
|
||||||
|
exitcode
|
||||||
|
)
|
||||||
|
elseif rc == 'again' then
|
||||||
|
log(
|
||||||
|
'Normal',
|
||||||
|
'Retrying a list after exitcode = ',
|
||||||
|
exitcode
|
||||||
|
)
|
||||||
|
elseif rc == 'die' then
|
||||||
|
log(
|
||||||
|
'Error',
|
||||||
|
'Failure with a list width exitcode = ',
|
||||||
|
exitcode
|
||||||
|
)
|
||||||
|
else
|
||||||
|
log(
|
||||||
|
'Error',
|
||||||
|
'Unknown exitcode "',exitcode,'" with a list'
|
||||||
|
)
|
||||||
|
|
||||||
-----
|
rc = 'die'
|
||||||
-- called on (re)initialization of Lsyncd.
|
|
||||||
--
|
|
||||||
init = function(event)
|
|
||||||
local config = event.config
|
|
||||||
local inlet = event.inlet
|
|
||||||
-- user functions
|
|
||||||
-- calls a startup if given by user script.
|
|
||||||
if type(config.onStartup) == 'function' then
|
|
||||||
local startup = config.onStartup(event)
|
|
||||||
-- TODO honor some return codes of startup like "warmstart".
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
if event.status == 'wait' then
|
if rc == 'ok' then
|
||||||
-- user script did not spawn anything
|
log('Normal', 'Retrying ',agent.etype,' on ',agent.sourcePath,' = ',exitcode)
|
||||||
-- thus the blanket event is deleted again.
|
elseif rc == 'again' then
|
||||||
inlet.discardEvent(event)
|
log('Normal', 'Finished ',agent.etype,' on ',agent.sourcePath,' = ',exitcode)
|
||||||
|
elseif rc == 'die' then
|
||||||
|
log('Error', 'Failure with ',agent.etype,' on ',agent.sourcePath,' = ',exitcode)
|
||||||
|
else
|
||||||
|
log('Normal', 'Unknown exitcode "',exitcode,'" with ', agent.etype,
|
||||||
|
' on ',agent.sourcePath,' = ',exitcode)
|
||||||
|
rc = 'die'
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
|
|
||||||
|
return rc
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Called on the Init event sent
|
||||||
|
-- on (re)initialization of Lsyncd for every sync
|
||||||
|
--
|
||||||
|
default.init = function(event)
|
||||||
|
local config = event.config
|
||||||
|
local inlet = event.inlet
|
||||||
|
|
||||||
|
-- user functions
|
||||||
|
-- calls a startup if given by user script.
|
||||||
|
if type(config.onStartup) == 'function' then
|
||||||
|
local startup = config.onStartup(event)
|
||||||
|
-- TODO honor some return codes of startup like "warmstart".
|
||||||
|
end
|
||||||
|
|
||||||
|
if event.status == 'wait' then
|
||||||
|
-- user script did not spawn anything
|
||||||
|
-- thus the blanket event is deleted again.
|
||||||
|
inlet.discardEvent(event)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- The maximum number of processes Lsyncd will
|
||||||
|
-- simultanously spawn for this sync.
|
||||||
|
--
|
||||||
|
default.maxProcesses = 1
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- The collapsor tries not to have more than these delays.
|
||||||
|
-- So it dealy stack does not grow too large,
|
||||||
|
-- since calculation for stacking events is n*log(n) (or so)
|
||||||
|
--
|
||||||
|
default.maxDelays = 1000
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
-- a default configuration using /bin/cp|rm|mv.
|
||||||
|
-- TODO huh?
|
||||||
|
--
|
||||||
|
default.direct = default_direct
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Exitcodes of rsync and what to do.
|
||||||
|
-- TODO move to rsync
|
||||||
|
--
|
||||||
|
default.rsyncExitCodes = {
|
||||||
|
|
||||||
-----
|
|
||||||
-- The maximum number of processes Lsyncd will spawn simultanously for
|
|
||||||
-- one sync.
|
|
||||||
--
|
--
|
||||||
maxProcesses = 1,
|
-- if another config provides the same table
|
||||||
|
-- this will not be inherited (merged) into that one
|
||||||
-----
|
|
||||||
-- Try not to have more than these delays.
|
|
||||||
-- not too large, since total calculation for stacking
|
|
||||||
-- events is n*log(n) or so..
|
|
||||||
--
|
--
|
||||||
maxDelays = 1000,
|
-- if it does not, integer keys are to be copied
|
||||||
|
-- verbatim
|
||||||
-----
|
|
||||||
-- a default configuration using /bin/cp|rm|mv.
|
|
||||||
--
|
--
|
||||||
direct = default_direct,
|
_merge = false,
|
||||||
|
_verbatim = true,
|
||||||
|
|
||||||
------
|
[ 0 ] = 'ok',
|
||||||
-- Exitcodes of rsync and what to do.
|
[ 1 ] = 'die',
|
||||||
--
|
[ 2 ] = 'die',
|
||||||
rsyncExitCodes = {
|
[ 3 ] = 'again',
|
||||||
|
[ 4 ] = 'die',
|
||||||
|
[ 5 ] = 'again',
|
||||||
|
[ 6 ] = 'again',
|
||||||
|
[ 10 ] = 'again',
|
||||||
|
[ 11 ] = 'again',
|
||||||
|
[ 12 ] = 'again',
|
||||||
|
[ 14 ] = 'again',
|
||||||
|
[ 20 ] = 'again',
|
||||||
|
[ 21 ] = 'again',
|
||||||
|
[ 22 ] = 'again',
|
||||||
|
|
||||||
--
|
-- partial transfers are ok, since Lsyncd has registered the event that
|
||||||
-- if another config provides the same table
|
-- caused the transfer to be partial and will recall rsync.
|
||||||
-- this will not be inherited (merged) into that one
|
[ 23 ] = 'ok',
|
||||||
--
|
[ 24 ] = 'ok',
|
||||||
-- if it does not, integer keys are to be copied
|
|
||||||
-- verbatim
|
|
||||||
--
|
|
||||||
_merge = false,
|
|
||||||
_verbatim = true,
|
|
||||||
|
|
||||||
[ 0 ] = 'ok',
|
[ 25 ] = 'die',
|
||||||
[ 1 ] = 'die',
|
[ 30 ] = 'again',
|
||||||
[ 2 ] = 'die',
|
[ 35 ] = 'again',
|
||||||
[ 3 ] = 'again',
|
|
||||||
[ 4 ] = 'die',
|
|
||||||
[ 5 ] = 'again',
|
|
||||||
[ 6 ] = 'again',
|
|
||||||
[ 10 ] = 'again',
|
|
||||||
[ 11 ] = 'again',
|
|
||||||
[ 12 ] = 'again',
|
|
||||||
[ 14 ] = 'again',
|
|
||||||
[ 20 ] = 'again',
|
|
||||||
[ 21 ] = 'again',
|
|
||||||
[ 22 ] = 'again',
|
|
||||||
-- partial transfers are ok, since Lsyncd has registered the event that
|
|
||||||
-- caused the transfer to be partial and will recall rsync.
|
|
||||||
[ 23 ] = 'ok',
|
|
||||||
[ 24 ] = 'ok',
|
|
||||||
[ 25 ] = 'die',
|
|
||||||
[ 30 ] = 'again',
|
|
||||||
[ 35 ] = 'again',
|
|
||||||
[ 255 ] = 'again',
|
|
||||||
},
|
|
||||||
|
|
||||||
-----
|
[ 255 ] = 'again',
|
||||||
-- Exitcodes of ssh and what to do.
|
|
||||||
--
|
|
||||||
sshExitCodes = {
|
|
||||||
|
|
||||||
--
|
|
||||||
-- if another config provides the same table
|
|
||||||
-- this will not be inherited (merged) into that one
|
|
||||||
--
|
|
||||||
-- if it does not, integer keys are to be copied
|
|
||||||
-- verbatim
|
|
||||||
--
|
|
||||||
_merge = false,
|
|
||||||
_verbatim = true,
|
|
||||||
|
|
||||||
[ 0 ] = 'ok',
|
|
||||||
[ 255 ] = 'again',
|
|
||||||
},
|
|
||||||
|
|
||||||
-----
|
|
||||||
-- Minimum seconds between two writes of a status file.
|
|
||||||
--
|
|
||||||
statusInterval = 10,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Exitcodes of ssh and what to do.
|
||||||
|
--
|
||||||
|
default.sshExitCodes = {
|
||||||
|
|
||||||
|
--
|
||||||
|
-- if another config provides the same table
|
||||||
|
-- this will not be inherited (merged) into that one
|
||||||
|
--
|
||||||
|
-- if it does not, integer keys are to be copied
|
||||||
|
-- verbatim
|
||||||
|
--
|
||||||
|
_merge = false,
|
||||||
|
_verbatim = true,
|
||||||
|
|
||||||
|
[ 0 ] = 'ok',
|
||||||
|
[ 255 ] = 'again',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Minimum seconds between two writes of a status file.
|
||||||
|
--
|
||||||
|
default.statusInterval = 10
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- checks all keys to be in the checkgauge
|
||||||
|
--
|
||||||
|
|
||||||
|
local function check(
|
||||||
|
config,
|
||||||
|
gauge,
|
||||||
|
level
|
||||||
|
)
|
||||||
|
for k, v in pairs( config ) do
|
||||||
|
|
||||||
|
if not gauge[k] then
|
||||||
|
error(
|
||||||
|
'Parameter "'
|
||||||
|
.. k
|
||||||
|
.. '" unknown.'
|
||||||
|
.. ' (if this is not a typo add it to checkgauge)',
|
||||||
|
level
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if type( gauge [ k ] ) == 'table' then
|
||||||
|
|
||||||
|
if type( v ) ~= 'table' then
|
||||||
|
|
||||||
|
error(
|
||||||
|
'Parameter "'
|
||||||
|
.. k
|
||||||
|
.. '" must be a table.',
|
||||||
|
level
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
check( config[ k ], gauge[ k ], level + 1 )
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
default.prepare = function( config, level )
|
||||||
|
|
||||||
|
local gauge = config.checkgauge
|
||||||
|
|
||||||
|
if not gauge then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
check( config, gauge, level or 2 )
|
||||||
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user