Lsyncd - 实时文件同步工具(精译)

原文: http://axkibe.github.io/lsyncd/

描述

Lsyncd监视本地目录树事件监视器接口(inotify或fsevents)。它聚集并组合事件几秒钟,然后生成一个(或多个)进程(es)来同步这些更改。默认情况下,这是rsync因此Lsyncd是一个轻量级的实时镜像解决方案,相对而言易于安装,不需要新的文件系统或块设备,也不会影响本地文件系统的性能。

Rsync + ssh是一种高级操作配置,它使用SSH来操作文件和目录,直接在目标上移动,而不是通过线路重新传输移动目标。

细粒度的定制可以通过配置文件来实现。自定义操作配置甚至可以从层级层次(从shell脚本到用Lua语言编写的代码)从头开始编写这样可以实现简单,强大和灵活的配置。

Lsyncd 2.2.1在所有源计算机和目标计算机上都需要rsync> = 3.1。

许可证:GPLv2或任何后续的GPL版本。

何时使用

Lsyncd旨在将本地目录树与对远程镜像的预期更改的低配置文件进行同步。Lsyncd特别适用于将数据从安全区域同步到不太安全的区域。

其他同步工具

DRBD在块设备级别上运行。这对同步负载较重的系统很有用。另一方面,Lsyncd不要求您更改块设备和/或挂载点,允许您更改传输文件的uid / gid,通过rsync的单向性质分隔接收器。如果您要同步数据库,DRBD可能是更好的选择。

GlusterFSBindFS使用FUSE-Filesystem来插入内核/用户空间文件系统事件。

镜像是一种异步同步工具,它使用类似Lsyncd的inotify通知。主要区别在于:它是专门为master-master开发的,因此在两个系统上运行守护进程,使用自己的传输层而不是rsync,而使用Java代替Lsyncd的C核和Lua脚本。

Lsyncd使用示例

lsyncd -rsync /home remotehost.org::share/

这将监视并rsyncs本地目录/ home与所有子目录,并使用rsync-share'share'将它们传输到'remotehost'。

lsyncd -rsyncssh /home remotehost.org backup-home/

这也将rsync / watch'/ home',但它使用ssh连接在远程主机上进行本地移动,而不是通过网络重新传输移动的文件。

放弃

除了许可证中通常的免责声明之外,我们还要特别强调,作者或任何与作者相关的组织都不能并且将对因Lsyncd可能出现的故障而导致的数据丢失负责。

 

编译

要求

Lua> = 5.2

Lsyncd依赖于Lua 5.2或更高版本; 即5.2或5.3。对于大多数发行版,您需要安装liblua ??,liblua ?? - dev和lua ?? 包,用?? 作为相应的Lua版本。

cmake> = 2.8

要将Lsyncd配置到您的系统,需要cmake> = 2.8

rsync> = 3.1

在运行期间,Lsyncd需要在源系统和目标系统上同时安装rsync> 3.1。

编译

满足这些要求Lsyncd应该是一个直接的过程。解压下载的tar.gz文件并运行:

cmake .
make
sudo make install


调用

作为大多数Unix工具,Lsyncd将在用-help调用时打印其命令行选项的摘要。

lsyncd --help
lsyncd -help

Lsyncd中的两个连字符是冗余的。它没有短的一个字母选项,并且一个连字符总是与指定两个相同。

也像大多数Unix工具一样,--version或者-version让Lsyncd打印它的版本号。

lsyncd -version

Lsyncd 2.1被设计为主要通过配置文件进行配置(见下文)。配置文件因此可以是唯一的命令行选项。

lsyncd CONFIGFILE

尽管对于标准使用或快速测试,它可以通过命令行选项进行光标配置。以下内容将使用rsync保持本地源和目标目录同步:

lsyncd -rsync /home/USER/src /home/USER/dst

目标可以是Rsync可以识别的任何东西。

lsyncd -rsync /home/USER/src remotehost:dst

通过调用两次(或多次)-rsync配置两个(或更多)目标。

lsyncd -rsync /home/USER/src remotehost1:dst -rsync /home/USER/src remotehost2:dst 

Rsync同步的一个缺点是,通常目录和文件移动会导致移动源的删除和导线移动目标的重新传输。但是,Lsyncd 2可以使用ssh命令在目标上本地移动目录和文件。-rsyncssh在本地源目录,远程主机和目标目录之后使用此用法REMOTEHOST可以包含一个用户me@remotehost.com

lsyncd -rsyncssh /home/USER/src REMOTEHOST TARGETDIR

测试Lsyncd配置时-nodaemon是一个非常方便的标志。使用此选项,Lsyncd不会分离,并且不会成为守护进程。所有日志消息都是在控制台上打印的配置日志记录工具(stdoutstderr)之外的。

lsyncd -nodaemon CONFIGFILE

使用-nodaemon运行时的行为有所不同。Lsyncd不会/像它在成为守护程序时那样将其工作目录更改为。因此,相对目标./target会起作用,-nodaemon但必须指定绝对路径才能在守护进程模式下工作。源目录也将由Lsyncd转换为绝对路径。源代码不解析为绝对路径的原因是因为Lsyncd本身并不关心目标说明符的格式,该目标说明符也可以是远程主机,rsyncd模块等。它不透明地传递给rsync。它关心观察到的目录。

所有日志消息按类别排序。默认情况下,Lsyncd缺少日志消息。通过指定,您可以将Lsyncd转换为motormouth -log all

lsyncd -log all CONFIGFILE

这可能很容易变得太多。一个特别有用的类别是“Exec”,它将记录Lsyncd产生的所有进程的命令行。

lsyncd -log Exec CONFIGFILE

当默认初始启动同步失败时,Lsyncd将以错误消息终止。它是这样设计的,所以配置故障可见地报告给可能的初始用户。但是,在生产过程中可能会完成远程目标,但是您希望Lsyncd始终启动并不断尝试同步到远程目标,直到它启动。

lsyncd -insist -rsync /home/USER/src remotehost:dst

在生产模式下,建议坚持。它也可以在配置文件中的settings {}命令中指定。

配置文件

Lsyncd配置文件是有效的Lua语法它的设计简单而有力。虽然丰富的配置和简单性本身并不是对立的,但一些折衷是不可避免的。为了尽可能实现这两个目标,Lsyncd配置可以在不同的层完成。较低的层次增加了适应性,而界面变得更有吸引力。

设置

对于所有图层的脚本,settings可以使用调用来更改守护程序范围的配置。

例如,以下代码将指示Lsyncd登录/tmp/lsyncd.log,定期/tmp/lsyncd.status使用其状态更新该文件,并且不会将其作为守护程序分离。

settings {
   logfile    = "/tmp/lsyncd.log",
   statusFile = "/tmp/lsyncd.status",
   nodaemon   = true,
}

警告 如果你从2.0.x升级,请注意它settings是一个变量的函数,所以你必须删除settings之间的等号'=' {

有效的设置键是:

logfile = FILENAME logs into this file
pidfile = FILENAME logs PID into this file
nodaemon = BOOL does not detach
statusFile = FILENAME periodically writes a status report to this file
statusInterval = NUMBER writes the status file at shortest after this number of seconds has passed (default: 10)
logfacility = STRING syslog facility, default "user"
logident = STRING syslog identification (tag), default "lsyncd"
insist = BOOL keep running at startup although one or more targets failed due to not being reachable.
inotifyMode = STRING Specifies on inotify systems what kind of changes to listen to. Can be "Modify", "CloseWrite" (default) or "CloseWrite or Modify".
maxProcesses = NUMBER Lysncd will not spawn more than these number of processes. This adds across all sync{}s.

此外,还可以配置一些参数,这些参数由所有Syncs继承(请参阅第3层)

maxDelays = 当这个延迟事件的数量排队时,动作将被产生,甚至低于延迟计时器。
 

配置第4层:默认配置

您可以简单地从三个默认实现中选择:rsyncrsyncsshdirect

要使用默认的rsync行为来同步本地目录,只需将其添加到配置文件即可:

sync {
   default.rsync,
   source = "DIRNAME",
   target = "DIRNAME"
}

论点的顺序并不重要。如果target是本地目录,请注意它是绝对路径名。您可以通过这种方式添加多个同步。源目录可能相同或不同,没有问题。source是每个同步必须给出的通用参数。所有其他sync参数可能因所选行为而异。或者,您可以覆盖默认或设置值maxDelaysmaxProcesses每次同步

也可以通过将默认init功能设置为false来跳过初始rsync过程

sync {
    default.rsync,
    source = "DIRNAME",
    target = "DIRNAME",
    init   = false
}

这是一个危险的优化; 因此,请仅在确定源和目标在Lsyncd启动时同步的情况下使用它。

您可以选择的默认行为如下:

default.rsync

默认的rsync配置会将事件聚合到delay秒或1000个独立的不可折叠事件,这些事件首先发生。然后它会产生一个Rsync,并带有所有已更改文件的过滤器。过滤器列表通过管道传输到Rsync。从Lsyncd到Rsync的调用将如下所示:

/usr/bin/rsync -ltsd --delete --include-from=- --exclude=* SOURCE TARGET

您可以更改调用Rsync的选项以及与rsync参数调用的Rsync二进制文件

例:

sync {
    default.rsync,
    source    = "/home/user/src/",
    target    = "foohost.com:~/trg/",
    delay     = 15, 
    rsync     = {
        binary   = "/usr/local/bin/rsync",
        archive  = true,
        compress = true
    }
}

以下是rsync参数选项的表格请查看Rsync文档以获得深入的解释。

parameter = TYPE default value comment
acls = BOOL false  
append = BOOL false (Lsyncd >= 2.2.0)
append-verify = BOOL false (Lsyncd >= 2.2.0)
archive = BOOL false  
backup = BOOL false (Lsyncd >= 2.2.0)
backup_dir = DIR false (Lsyncd >= 2.2.0)
binary = FILENAME "/usr/bin/rsync" Lsyncd calls this binary as rsync
checksum = BOOL false  
chmod = STRING   (Lsyncd >= 2.2.0)
chown = USER:GROUP   (Lsyncd >= 2.2.0)
compress = BOOL false  
copy_dirlinks = BOOL false (Lsyncd >= 2.2.0)
copy_links = BOOL false  
cvs_exclude = BOOL  
dry_run = BOOL false  
exclude = PATTERN   TABLE of PATTERNs also allowed
excludeFrom = FILENAME    
executability = BOOL false  
existing = BOOL false (Lsyncd >= 2.2.0)
group = BOOL false  
groupmap = STRING   (Lsyncd >= 2.2.0)
hard_links = BOOL false  
ignore_times = BOOL false  
inplace = BOOL false (Lsyncd >= 2.1.6)
ipv4 = BOOL false  
ipv6 = BOOL false  
links = BOOL true  
one_file_system = BOOL false  
owner = BOOL false  
password_file = FILENAME   (Lsyncd >= 2.1.2)
perms = BOOL false  
protect_args = BOOL true  
prune_empty_dirs = BOOL false  
quiet = BOOL false  
rsh = COMMAND    
rsync_path = PATH   (path to rsync on remote host)
sparse = BOOL false  
suffix = SUFFIX   (Lsyncd >= 2.2.0)
temp_dir = DIR    
times = BOOL true  
update = BOOL false  
usermap = STRING   (Lsyncd >= 2.2.0)
verbose = BOOL false  
whole_file = BOOL false  
xattrs = BOOL false  
_extra = TABLE of STRINGS.   如果绝对需要,可以将其他参数指定为STRINGS表(例如:{“--omit-dir-times”,“--omit-link-times”})。请注意,下划线将此解释为解决方法。如果您需要上述选项未涵盖的内容,请通过项目网站上的功能请求申请。最值得注意的是,不要添加-r递归或-a这意味着递归,因为Lsyncd会自己处理它。另外,不要为相对添加-R,这会破坏Lsyncd < - > Rsync通信。

default.rsyncssh

此配置不同于标准rsync配置,因为它使用ssh命令在目标主机本地移动文件或目录,而不是再次删除和传输。这种配置产生了类似于default.rsync的Rsync进程,但是会产生/usr/bin/ssh HOST mv ORIGIN DESTINATION命令。

与default.rsync不同,它不需要统一的target参数,但需要hosttargetdir分开。

Rsync的选项可以通过rsync上面所描述的default.rsync中参数进行更改

除此之外,可以通过ssh参数配置ssh 

binary = FILENAME Lsyncd calls this binary as ssh (default: /usr/bin/ssh)
identityFile = FILE Uses this file to identify for public key authentication.
options = TABLE A table of addition extended options to pass to ssh's -o option.
port = PORT Adds --port=PORT to the ssh call.
_extra = STRING TABLE Similar to rsync._extra this can be used as quick workaround if absolutely needed.

例:

settings {
    logfile = "/var/log/lsyncd.log",
    statusFile = "/var/log/lsyncd-status.log",
    statusInterval = 20
}

sync {
   default.rsyncssh,
   source="/srcdir",
   host="remotehost",
   excludeFrom="/etc/lsyncd.exclude",
   targetdir="/dstdir",
   rsync = {
     archive = true,
     compress = false,
     whole_file = false
   },
   ssh = {
     port = 1234
   }
}

请注意rsync参数集和ssh参数集之间的逗号

警告 如果你从2.0.x升级,请注意它settings是一个变量的函数,所以你必须删除settings之间的等号'=' {

Lsyncd将调用xargs远程主机来处理单个连接中的多个任务。Xargs选项可以由xargs参数指定。

binary = FILENAME Lsyncd calls this binary as xargs on the remote host (default: /usr/bin/xargs)
delimiter = DELIMITER delimiting character to separate filenames. By default the 0 character is used. Very old holds may need newline instead.
_extra = STRING TABLE By default { '-0', 'rm -rf' }. Remove the -0 if you chose newline delimiter instead. Otherwise leave it as is.


sync
{例:

    default.rsyncssh,
    source    = "/home/user/src/",
    host      = "foohost.com",
    targetdir = "~/trg/",
}

default.direct

Default.direct可以用来保持两个本地目录同步,比使用default.rsync更好的性能。Default.direct在启动时使用(就像default.rsync一样)rsync来初始化目标目录与源目录的同步。但是,在正常操作期间,default.direct使用/ bin / cp,/ bin / rm和/ bin / mv来保持同步。所有参数就像default.rsync一样。

例:

sync {
    default.direct,
    source  = "/home/user/src/",
    target  = "/home/user/trg/"
}

排除

可以指定两个附加参数来同步{}:

excludeFrom = FILENAME loads exclusion rules from this file, on rule per line
exclude = LIST loads exclusion rules from this list of strings

排除规则在rsync的排除模式之后建模,但稍微简单一些。Lsyncd支持这些功能:

  • 通常,如果某个事件的路径名的任何部分(参见第3层以下)与文本匹配,则将其排除。例如文件“/ bin / foo / bar”匹配规则“foo”。
  • 如果规则以斜杠开始,则只会在路径名的开头匹配
  • 如果规则以斜线结尾,则只会在路径名的末尾匹配
  • 匹配不是斜杠的任何字符。
  • * 匹配零个或多个不是斜线的字符
  • ** 匹配零个或多个字符,这可以是斜杠。

例:

sync {
    default.rsync,
    source    = "/home/user/src/",
    targetdir = "/home/user/dst/",
    exclude = { '*.bak' , '*.tmp' }
}

缺失

默认情况下,Lsyncd将删除目标上不存在的文件,因为这是保持目标与源同步的基本部分。但是,由于各种原因,许多用户请求例外,因此所有默认实现都delete作为附加参数。

有效值为delete

delete = true Default. Lsyncd will delete on the target whatever is not in the source. At startup and what's being deleted during normal operation.
delete = false Lsyncd will not delete any files on the target. Not on startup nor on normal operation. (Overwrites are possible though)
delete = 'startup' Lsyncd will delete files on the target when it starts up but not on normal operation.
delete = 'running' Lsyncd will not delete files on the target when it starts up but will delete those that are removed during normal operation.

配置第3层:简单的onAction

简单的行动

在这一层中,可以创建自定义配置。这个例子将使用bash命令来保持本地目录同步。

bash = {
    delay = 5,
    maxProcesses = 3,
    onCreate = "cp -r ^sourcePathname ^targetPathname",
    onModify = "cp -r ^sourcePathname ^targetPathname",
    onDelete = "rm -rf ^targetPathname",
    onMove   = "mv ^o.targetPathname ^d.targetPathname",
    onStartup = '[[ if [ "$(ls -A ^source)" ]; then cp -r ^source* ^target; fi]]',
}

这个例子一步一步解释。从技术上讲,任何Lsyncd配置都是一个填充了一组键的Lua表。因此,它首先创建一个名为变量的变量bash并为其分配一个= {...}的表格。

bash = {
  ...
}

现在表格中充满了条目。每个条目都有一个等号的左键和它的右值。如果没有指定延迟,这意味着对Lsyncd的即时操作。这个例子想要将更改汇总5秒,因此下一个条目是:

    delay = 5,

自从标记条目结束以来,需要逗号。

操作

操作由6个键指定:

onAttrib called when only attributes changed
onCreate called on a new file or directory
onModify called when a file has changed
onDelete called when a file or directory has been deleted
onMove called when a file or directory has been moved within the observed directory tree
onStartup called on the start of Lsyncd

要采取的动作被指定为Lua字符串。因此,动作可以用Lua允许的任何内容进行分隔,这些是onStartup上面示例中使用的'TEXT','TEXT'或'[[TEXT]] 。当没有onMove或移动进出观察的目录树时,它被分成onDelete移动起点和onCreate移动目的地的一个。那就是如果任一个在观察目录树内。onStartup将始终阻止此Sync的所有其他操作直至完成。

任何以“/”开始的动作都会指示Lsyncd在开始时直接调用二进制文件,而不是产生额外的shell。例如

   onCreate = "/usr/bin/zip /usr/var/all.zip ^sourcePath"
   onModify = "/usr/bin/zip /usr/var/all.zip ^sourcePath"

将使用绝对路径名将所有新创建和修改的文件添加到/usr/var/all.zip。任何不以“/”开始的操作都会导致Lsyncd产生一个shell来执行命令。

变量

变量参数用插入符号^指定。它已经被选择超过$或其他符号,与标准的shell约定冲突较少。

请注意,变量将始终用双引号隐式引用,因此如果您希望它们成为另一个双引号字符串的一部分,则必须更深入一层,例如

    onCreate   = '[[ su user -c "/usr/bin/zip /usr/var/all.zip ^o.sourcePath " ]],

将扩大到su user -c "/usr/bin/zip /usr/var/all.zip "source""哪个是不正确的,并将打破。你必须将上面的叙述更深一层地重写

  onCreate = function(event)
    spawnShell('[[ su user -c "/usr/bin/zip /usr/var/all.zip \"$1\"" ]], event.sourcePath)
  end

所有可能的变量

^source the absolute path of the observed source directory
^target the "target" attribute of the config
^path the relative path of the file or directory to the observed directory; directories have a slash at the end.
^pathname the relative path of the file or directory to the observed directory; directories have no slash at the end.
^sourcePath the absolute path of the observed source directory and the relative path of the file or directory; this equals the absolute local path of the file or directory. Directories have a slash at the end.
^sourcePathname same as ^sourcePath, but directories have no slash at the end.
^targetPath The "target" attributed of the config appended by the relative path of the file or directory. Directories have a slash at the end.
^targetPathname same as ^targetPath, but directories have no slash at the end.

从上面的示例中,它将移动目标目录中的文件或目录。对于onMoves一个和或者d。可以预置为path,pathname,sourcePath sourcePathname,targetPath和targetPathname以指定移动起始位置或目标位置。没有任何变量指的是移动的起源。

    onMove   = "mv ^o.targetPathname ^d.targetPathname",

执行控制(退出代码)

关于示例启动的几句话。它看起来有点复杂,但它只是一些bash脚本,没有什么特别的Lsyncd。它只是将源的递归副本做到目标,但首先测试源文件中是否有任何东西。否则,该命令会返回一个非零的错误代码。

    onStartup = '[[if [ "$(ls -A ^source)" ]; then cp -r ^source* ^target; fi]],

默认情况下,Lsyncd忽略除了onStartup之外的所有退出代码,它必须返回0才能继续。您可以通过添加一个exitcodes来改变这种行为

    exitcodes = {[0] = "ok", [1] = "again", [2] = "die"}

这些键为退出代码指定了所需操作的字符串。

 

again respawns the action after seconds, or 1 second if delay is immediate
die lets Lsyncd terminate.

所有其他值让Lsyncd正常继续。

 

 

配置第2层:高级onAction

虽然第4层和第3层感觉像正常的配置文件,但第2层和第1层进入编码领域。因此,假设您在使用第2层或第1层时有一些编码知识。

而不是像第3层那样将动作指定为字符串Lua函数可以用于在Lsyncd中执行一些小脚本。

这个例子会将任何带有在目录中创建的“.ps”后缀的文件转换为PDF。

autopdf = {
    onCreate = function(event)
        log("Normal", "got an onCreate Event")
        if string.ends(event.pathname, ".ps") then
            spawn(event, "/usr/bin/ps2pdf", event.sourcePath)
        end
    end
}

该函数可以使用任何有效的Lua代码。

Lsyncd提供了一组用于用户脚本的函数。

日志(类别,...)

将一条消息记录到文件/ stdout / syslog中。第一个参数是日志记录类别,其他都是要记录的字符串。日志记录类别必须以大写字母开头。“正常”和“错误”是日志消息的标准类别。所有其他都是用于调试的类别。

产卵(事件,二进制,...)

产生与事件(或事件列表,参见下文)相关的新进程作为第一个参数。第二个参数指定要调用的二进制文件。所有其他人都是二进制文件的参数。

如果第三个参数是“<”,那么第四个参数将不会作为参数传递给二进制文件。第四个参数是一个字符串,它将通过stdin传递给二进制文件。

不要使用Lua os.execute,而要使用Lsyncd,spawn()它会阻塞整个Lsyncd守护进程,直到命令完成。另一方面,Lsyncd spawn在子进程运行时立即返回。

spawnShell(Event,Command,...)

和spawn()一样,只有它会调用一个shell。任何参数在命令中都被称为$ 1,$ 2,$ 3等等。

顺便说一句,这是spawnShell的简单实现:

function spawnShell(agent, command, ...)
    return spawn(agent, "/bin/sh", "-c", command, "/bin/sh", ...)
end

终止(退出码)

让Lsyncd终止exitcode

事件

这些行为的变量由事件字段给出它有以下领域。

领域 含义
event.config 使用sync {}调用的配置
event.inlet 请参阅第1层关于入口
event.etype 事件类型。可以是'ATTRIB','CREATE','MODIFY','DELETE','MOVE'
event.status 事件的状态。当它准备好产生时'等待',如果有与该事件相关的进程正在运行,则'等待'
event.isdir 如果事件与目录相关,则为true
event.name 文件名,目录以斜杠结尾
event.basename 文件名,目录不以斜杠结尾
event.path 请参阅第3层的 ^路径
event.pathname 请参阅第3层的 ^路径名
event.source 请参阅第3层的 ^源
event.sourcePath 请参阅第3层的 ^ sourcePath
event.sourcePathname 请参阅第3层的 ^ sourcePathname
event.target 请参阅第3层的 ^目标
event.targetPath 请参阅第3层的 ^ targetPath
event.targetPathname 请参阅第3层的 ^ targetPathname

onMove操作有两个事件作为参数,移动的起点和终点。

这个例子会在观察到的目录树中讨论所有的移动。

tattleMove = {
    onMove = function(oEvent, dEvent)
        log("Normal", "A moved happened from ",
            oEvent.pathname, " to ",  dEvent.pathname)
    end,
}

行动功能必须简短而快速。他们正在Lsyncd的唯一主线程中运行。如果您不得不再花费更多时间计算spawn {}子进程。

只能有一个与事件关联的子进程。

第3层就是Lsyncd在初始化时自动为您写入第2层功能。-log FWrite使用第3层配置启动Lsyncd 以查看它为您动态写入和加载的功能。因此第3层和第2层也可以随意混合。

 

配置第1层:入口

第2层允许您为每个事件创建一个进程。但是,与默认的rsync行为一样,您可能需要为多个事件调用一个进程。这可以通过入口完成。当任何事件准备就绪时,Lsyncd action使用inletas参数调用条目inlet可以用来准备抢单的事件或事件列表。

例如,这是default.rsync使用的操作:

action = function( inlet )
   local elist = inlet.getEvents( )
   local config = inlet.getConfig( )
   local paths = elist.getPaths( )
   log( "Normal", "rsyncing list\n", table.concat( paths, '\n' ) )
   spawn(elist, '/usr/bin/rsync',
       '<', table.concat( paths, '\000' ),
       '--delete',
       config.rsync._computed,
       '--from0',
       '--include-from=-',
       '--exclude=*',
       config.source,
       config.target
   )
end

入口功能是:

功能 描述
inlet.getEvent() event在第2层配置中检索下一个多次调用getEvent()将返回相同的事件,除非它已经产生了一个动作。
inlet.getEvents(测试) 返回已准备好的所有事件的列表。test对于每个事件都要调用的函数来测试它是否应该包含在列表中是可选的。它有一个参数,event如果应该包含事件,则返回true。如果没有任何准备好的活动将被列入清单
inlet.discardEvent() 丢弃一个事件。下一次调用getEvent将会收到另一个事件,即使这个事件没有产生任何动作
inlet.getConfig() 返回相同event.config同步{}的配置
inlet.addExclude() 向此同步添加排除模式(请参阅排除)
inlet.rmExclude() 从此同步中移除排除模式
inlet.createBlanketEvent() 放在event延迟FIFO的顶部,阻止所有事件并被所有事件阻塞。这用于onStartup。

getEvents返回的列表可以作为代理传递给spawn {} 以及单数事件。

列表具有以下功能

功能 描述
elist.getPaths(分隔符) 返回路径的字符串(如在event.path由分离delimiter。缺省情况下\ n被用作分隔符。
elist.getSourcePaths(分隔符) 返回sourcePaths的字符串(如在event.sourcePath由分离delimiter。缺省情况下\ n被用作分隔符。

请小心调用getEvents()及其函数,因为根据事件的数量,它们会导致相当多的CPU负载。

如果用户脚本本身没有提供,那么第2层功能就是在默认情况下加载的第1层操作。

-----
-- Default action calls user scripts on**** functions.
--
action = function( inlet )
    -- in case of moves getEvent returns the origin and destination 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,

如果在配置中找不到“onMove”字段,Lsyncd将自动将Move事件拆分为Create和Delete事件。在处理第1层action函数中的移动时,只需将“onMove”设置为“true”即可。

除了初始化时的每个同步的actionLsyncd调用init这是在用户脚本没有的情况下加载的默认init函数。它为第2层和第3层提供onStartup()功能。

-----
-- called on (re)initalizing of lsyncd.
--
init = function( inlet )
    local config = inlet.getConfig( )
    -- calls a startup if provided by user script.
    if type( config.onStartup ) == "function"
    then
        local event = inlet.createBlanketEvent( )
        config.onStartup( event )
        if event.status == 'wait'
	then
            -- user script did not spawn anything
            -- thus the blanket event is deleted again.
            inlet.discardEvent( event )
        end 
    end 
end,

作为另一个例子,这是init的init default.rsync作为专业,它改变了配置,因为它已经添加了一个斜线。

-----
-- Spawns the recursive startup sync
-- 
init = function( inlet )
    local config = inlet.getConfig( )
    local event = inlet.createBlanketEvent( )
    if string.sub(config.target, -1) ~= "/"
    then
        config.target = config.target .. "/"
    end
    
    log("Normal", "recursive startup rsync: ", config.source,
        " -> ", config.target)
	
    spawn(event,
        "/usr/bin/rsync",
        "--delete",
        config.rsync._computed .. "r",
        config.source,
        config.target
    )
end,

当子进程完成并收集其僵尸进程时,Lsyncd调用该collect入口的函数当收回“再次”时,代理(事件或事件列表)的状态将再次设置为“等待”,并且将在delay数秒内(或者如果更小,则为1秒)准备就绪

默认收集函数在exitcodes []表中查找退出代码的条目。否则,大多数不幸的更长的代码不会做任何事情,但会做出好的日志消息

-----
-- Called when collecting a finished child process
--
collect = function(agent, exitcode)
	local config = agent.config

	if not agent.isList and agent.etype == "Blanket" then
		if exitcode == 0
		then
			log("Normal", "Startup of '",agent.source,"' finished.")
		elseif config.exitcodes and
		       config.exitcodes[exitcode] == "again"
		then
			log("Normal",
				"Retrying startup of '",agent.source,"'.")
			return "again"
		else
			log("Error", "Failure on startup of '",agent.source,"'.")
			terminate(-1) -- ERRNO
		end
		return
	end

	local rc = config.exitcodes and config.exitcodes[exitcode]
	if rc == "die"
	then
		return rc
	end

	if agent.isList
	then
		if rc == "again"
		then
			log("Normal", "Retrying a list on exitcode = ",exitcode)
		else
			log("Normal", "Finished a list = ",exitcode)
		end
	else
		if rc == "again"
		then
			log("Normal", "Retrying ",agent.etype,
				" on ",agent.sourcePath," = ",exitcode)
		else
			log("Normal", "Finished ",agent.etype,
				" on ",agent.sourcePath," = ",exitcode)
		end
	end
	return rc
end,


Examples

Layer 4 Examples

bash sync:

sync{bash, source="/home/lonewolf/teste1", target="/home/lonewolf/teste2"}

rsyncssh option:

sync{default.rsyncssh,
        source="/var/www/live_site_resources",
        host="192.168.129.90",
        targetdir="/var/www/live_site_resources",
        delete="running",
        exclude={ ".*", "*.tmp" },
        rsync = {
                compress = false,
                checksums = false,
                _extra = {"--bwlimit=50000"},
        }
}

Layer 3 Examples

  • GForce: forces a local directory tree to be read/writable by a group.

Layer 2 Examples

Layer 1 Examples

  • Auto Image Magic: creates a “magic” directory in which all images placed into will be converted to other file formats

 

原文: http://axkibe.github.io/lsyncd/

谋胆并重
上一篇:UNIX环境高级编程笔记之高级I/O


下一篇:阿里云明确生态边界:不做SaaS、被集成