Lsyncd

更新日: 2021-06-04 (金) 21:29:22 (8d)

Lsyncd

  • ファイルやディレクトリの変更を検知し知らせてくれるinotifyやfsevents APIを使ったファイルやディレクトリレベルでの同期を可能にするツール。
  • C言語とLua言語で書かれている。
  • 基本的には、リモートサーバへの同期はrsyncやsshコマンドを実行して同期を実行する。
  • 同期の設定はLua言語でありLuaのシンタックスに倣う。
  • デフォルトの動作を拡張したり複雑なイベント処理を実行したい場合、独自のLua関数を定義したり、シェルやプロセスをspawnして実行させたりすることも可能である。

インストール

sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum --enablerepo=epel install -y rsync lsyncd

AWS EC2でのインストール

Amazon Linux 2を前提とする。
NATがなくインターネットに接続できない場合、S3にパッケージをアップロードしてインストールする。

# curl -L https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/l/lsyncd-2.2.2-1.el7.x86_64.rpm -O
aws s3 cp s3://mybucket/lsyncd-2.2.2-1.el7.x86_64.rpm .
sudo rpm -ivh lsyncd-2.2.2-1.el7.x86_64.rpm

URL https://pkgs.org/search/?q=lsyncd

実行

systemdでdaemonを起動する。

sudo systemctl start lsyncd
sudo systemctl enable lsyncd
sudo journalctl -u lsyncd

ソースからのビルド

Linuxの場合は以下のとおり。

Linux CentOS

sudo yum install -y gcc-c++ cmake lua lua-devel
git clone https://github.com/axkibe/lsyncd.git
cd lsyncd
cmake .
make
sudo make install

Configの設定

簡単な設定で実行するレベルからイベントAPIに近い設定を記述子実行するレベルまで柔軟な定義が可能となっている。マニュアルでは、Config Layer 4(抽象度高い)からConfig Layer 1(抽象度低い)と表現されている。Layer 4が最も抽象化されたレベルとなっており、Lua言語で宣言的な設定を行なう形となっている。

設定ファイルは、/etc/lsyncd.confに記述する。
私が試した環境だと、デフォルトでは以下のような設定ファイルが配置されている。

ファイル /etc/lsyncd.conf

----
-- User configuration file for lsyncd.
--
-- Simple example for default rsync, but executing moves through on the target.
--
-- For more examples, see /usr/share/doc/lsyncd*/examples/
-- 
sync{default.rsyncssh, source="/var/www/html", host="localhost", targetdir="/tmp/htmlcopy/"}

ローカルホスト上で/var/www/html/tmp/htmlcopyにrsyncでsshコマンドで複製する、という設定となっている。このように、sync{}というブロックに、コピー元とコピー先を記述するのが基本的な書き方である。なお、syncブロックは複数定義できる。

settings

Layer全体で共通となる設定を記述する。
詳細は公式ドキュメントを参照のこと。

ファイル /etc/lsyncd.conf

settings {
  -- ログファイル
  logfile    = "/var/log/lsyncd/lsyncd.log",
  -- ステータスレポートファイル
  statusFile = "/var/log/lsyncd/lsyncd.status",
  -- デーモン起動しない
  nodaemon = true,
  -- ステータスレポート更新間隔秒
  statusInterval = 10,
  -- 起動時に同期プロセスが異常終了しても継続する、例えばリモートに繋がらないなど
  insist = true,
   -- syslog設定
  logfacility = "user",
  logident = "lsyncd",
  -- Modify | CloseWrite | CloseWrite or Modify
  inotifyMode = "CloseWrite",
  -- spawn可能な最大プロセス数、全てのsync{}に適用される
  -- maxProcesses = 1
}

参照 https://axkibe.github.io/lsyncd/manual/config/file/

同期メソッドの実行(Config Layer 4)

rsync

設定例 /var/www/htmlのリソースをrsyncで同期する

sync {
  default.rsync,
  source    = "/var/www/html/",
  target    = "target-host:/var/www/html/",
  delay     = 15,
  rsync     = {
    archive  = true,
    compress = true
  }
}

rsyncはオプションが多く複雑なので、manも一緒に参照しながら正しい設定を確認した方が良い。

参考

設定例 /var/www/htmlのリソースをrsyncで同期する、sudoで実行する

sync {
  default.rsync,
  source    = "/var/www/html/",
  target    = "target-host:/var/www/html/",
  delay     = 15,
  rsync     = {
    rsync_path = "sudo /usr/bin/rsync",
    rsh        = "/usr/bin/ssh -l rsync-user -i /home/rsync-user/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
    archive  = true,
    compress = true
  }
}

実行されるコマンドイメージは以下のようになる。

/usr/bin/rsync -gzsolptD --rsh="/usr/bin/ssh -l ec2-user -i /home/rsync-user/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --rsync-path="sudo /usr/bin/rsync" -r --delete --ignore-errors --force --from0 --include-from=- --exclude="*" /var/www/html/ target-host:/home/ec2-user/html/

rsyncssh

rsyncの改良系であり、rsyncコマンドのオプションを継承したものである。
違いは、ターゲットホスト上でsshコマンド経由でmvが実行される。

moveで実行されるコマンドのイメージは以下のとおり。

spawn /usr/bin/ssh HOST mv ORIGIN DESTINATION || rm -rf ORIGIN 

参考 https://github.com/axkibe/lsyncd/default-rsyncssh.lua

設定例 /home/vagrant/srcのリソースをsshで同期する

sync {
    default.rsyncssh,
    source = "/home/rsync-user/src",
    targetdir = "/home/ec2-user/dst/",
    host = "ec2-user@target-host",
    rsync = {
        rsync_path = "sudo /usr/bin/rsync",
        rsh = "/usr/bin/ssh -l ec2-user -i /home/rsync-user/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
        archive  = true,
        compress = true
    },
    ssh = {
      identityFile = "/home/rsync-user/.ssh/id_rsa"
    }
}

ただ、これだとMove以外のイベントで以下のようなコマンドになってしまい上手くいかない。--rsh=sshのオプションが固定で指定されてしまう。

 /usr/bin/rsync --delete --ignore-errors -gzsolptD --rsh="/usr/bin/ssh -l ec2-user -i /home/rsync-user/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/nul"l --rsync-path="sudo /usr/bin/rsync" --rsh=ssh -i /home/rsync-user/.ssh/id_rsa -r /home/rsync-user/src/ ec2-user@target-host:/home/ec2-user/dst/

苦肉ではあるが、以下のようにすると期待の動きにはなるが、かなり冗長にはなってしまう。
ssh_configに書くとスッキリするだろう。

sync {
    default.rsyncssh, 
    source = "/home/rsync-user/src",
    targetdir = "/home/ec2-user/dst/",
    host = "ec2-user@target-host",
    rsync = {
        rsync_path = "sudo /usr/bin/rsync",
        rsh = "/usr/bin/ssh -l ec2-user -i /home/rsync-user/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
        archive  = true,
        compress = true
    },
    ssh = {
       _extra = {"-l ec2-user", "-i /home/rsync-user/.ssh/id_rsa", "-o StrictHostKeyChecking=no", "-o UserKnownHostsFile=/dev/null"}
    }
}

direct

mkdircpmvrmなどのローカルコマンドを実行して同期する。
起動時はrsyncコマンドで同期が実行される。

sync {
  default.direct,
  source  = "/home/vagrant/cp_src/",
  target  = "/home/vagrant/cp_dst/"
}

途中でファイルの権限を変更した場合は、以下のような警告が出るので、削除して追加した方が良いのかもしれない。

Warn: ignored an event of type "Attrib"

カスタムConfig(Config Layer 3)

syncブロックで設定を定義していたが、独自の設定を記述することもできる。
この場合は、少し低いレイヤーのAPIを使用する。
基本的には、ファイルやディレクトリの変更を検知したイベントに対するハンドラを記述する形である。

以下がポイントである。

  • sourceやtargetはプレースホルダーを書く
  • onXXと言うハンドラに処理を書く
  • 'TEXT'"TEXT"[[TEXT]]という記述方法が可能、これはLuaのシンタックス
  • onMoveについて、プレースホルダの前にo.とするとorigin、d.とするとdestinationを示す
    指定がない場合はoriginに解釈される

例を見てみよう。

変数を出力するためだけのダミー設定

bash = {
  delay = 0,
  maxProcesses = 1,

  onStartup = "echo onStartup && echo ^sourcePath ^targetPath",
  onCreate = "echo onCreate && echo ^sourcePathname",
  onModify = "echo onModify && echo ^source ^target ^path ^pathname ^sourcePath ^sourcePathname ^targetPath ^targetPathname",
  onDelete = "echo onDelete && echo ^sourcePath",
  onMove = "echo onMove && echo ^sourcePath"
}
sync {bash, source = "/home/vagrant/bash_src", target = "/home/vagrant/bash_target/" }

コマンドを実行してログにechoで出力された結果は以下のとおり。
コマンドは#で書いた部分。

Fri Jun  4 11:58:11 2021 Normal: Event Init spawns shell "echo onStartup && echo /home/vagrant/bash_src/ /home/vagrant/bash_target/"
Fri Jun  4 11:58:11 2021 Normal: Startup of /home/vagrant/bash_src/ -> /home/vagrant/bash_target/ finished.
# touch /home/vagrant/bash_src/file1
Fri Jun  4 11:58:17 2021 Normal: Event Create spawns shell "echo onCreate && echo /home/vagrant/bash_src//file1"
Fri Jun  4 11:58:17 2021 Normal: Finished Create on /home/vagrant/bash_src//file1 = 0
Fri Jun  4 11:58:17 2021 Normal: Event Modify spawns shell "echo onModify && echo /home/vagrant/bash_src/ /home/vagrant/bash_target/ file1 file1 /home/vagrant/bash_src//file1 /home/vagrant/bash_src//file1 /home/vagrant/bash_target//file1 /home/vagrant/bash_target//file1"
Fri Jun  4 11:58:17 2021 Normal: Finished Modify on /home/vagrant/bash_src//file1 = 0
# mkdir /home/vagrant/bash_src/dir1
Fri Jun  4 11:59:42 2021 Normal: Event Create spawns shell "echo onCreate && echo /home/vagrant/bash_src//dir1"
Fri Jun  4 11:59:42 2021 Normal: Finished Create on /home/vagrant/bash_src//dir1/ = 0
# mv /home/vagrant/bash_src/file1  /home/vagrant/bash_src/file2
Fri Jun  4 12:00:23 2021 Normal: Event Move spawns shell "echo onMove && echo /home/vagrant/bash_src//file1"
Fri Jun  4 12:00:23 2021 Normal: Finished Move on /home/vagrant/bash_src//file1 = 0
# rm /home/vagrant/bash_src/file2
Fri Jun  4 12:02:48 2021 Normal: Event Delete spawns shell "echo onDelete && echo /home/vagrant/bash_src//file2"
Fri Jun  4 12:02:48 2021 Normal: Finished Delete on /home/vagrant/bash_src//file2 = 0

参考 https://axkibe.github.io/lsyncd/manual/config/layer3/

slashがダブルになっているがこれは以下のissueで触れられている。

https://github.com/axkibe/lsyncd/issues/364

アクションの実行(Config Layer 2)

このレイヤーはLua関数を使って処理を呼び出すような記述になる。

Inlets(Config Layer 1)

このレイヤーは、イベントレベルで制御ができる。

参考リンク


トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
目次
TOP | 閉じる | ダブルクリックで閉じる