--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- default-direct.lua -- -- Keeps two directories with /bin/cp, /bin/rm and /bin/mv in sync. -- Startup still uses rsync tough. -- -- A (Layer 1) configuration. -- -- Note: -- this is infact just a configuration using Layer 1 configuration -- like any other. It only gets compiled into the binary by default. -- You can simply use a modified one, by copying everything into a -- config file of yours and name it differently. -- -- License: GPLv2 (see COPYING) or any later version -- Authors: Axel Kittenberger -- --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if not default then error('default not loaded'); end if not default.rsync then error('default-direct (currently) needs default.rsync loaded'); end if default.direct then error('default-direct already loaded'); end default.direct = { ----- -- Spawns rsync for a list of events -- action = function(inlet) -- gets all events ready for syncing local event, event2 = inlet.getEvent() if event.etype == 'Create' then if event.isdir then spawn( event, '/bin/mkdir', '-p', event.targetPath ) else spawn( event, '/bin/cp', '-t', event.targetPathdir, event.sourcePath ) end elseif event.etype == 'Modify' then if event.isdir then error("Do not know how to handle 'Modify' on dirs") end spawn(event, '/bin/cp', '-t', event.targetPathdir, event.sourcePath ) elseif event.etype == 'Delete' then local tp = event.targetPath -- extra security check if tp == '' or tp == '/' or not tp then error('Refusing to erase your harddisk!') end spawn(event, '/bin/rm', '-rf', tp) elseif event.etype == 'Move' then local tp = event.targetPath -- extra security check if tp == '' or tp == '/' or not tp then error('Refusing to erase your harddisk!') end spawnShell( event, '/bin/mv $1 $2 || /bin/rm -rf $1', event.targetPath, event2.targetPath) else log('Warn', 'ignored an event of type "',event.etype, '"') inlet.discardEvent(event) end end, ----- -- Called when collecting a finished child process -- 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 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 end -- everything else is just as it is, -- there is no network to retry something. return end, ----- -- Spawns the recursive startup sync -- (currently) identical to default rsync. -- init = default.rsync.init, ----- -- Checks the configuration. -- prepare = function(config) if not config.target then error('default.direct needs "target".', 4) end if config.rsyncOps then error('did you mean rsyncOpts with "t"?', 4) end end, ----- -- Default delay is very short. -- delay = 1, ------ -- Let the core not split move events. -- onMove = true, ----- -- The rsync binary called. -- rsyncBinary = '/usr/bin/rsync', ----- -- For startup sync -- rsyncOpts = '-lts', ----- -- rsync exit codes -- rsyncExitCodes = default.rsyncExitCodes, ----- -- On many system multiple disk operations just rather slow down -- than speed up. maxProcesses = 1, }