homehome

Vagrant rsync 奮闘記

Published

Vagrantのrsyncについて調べてみた。手探りゆえ間違ったことを書いている可能性あり。

通常同期(Virtualbox)

まずrsyncの前に通常同期(basic)に触れる。

通常同期のとき同期するファイル・ディレクトリのユーザ/グループ及びパーミッションは以下のように設定できる。

## 例1 ##
config.vm.synced_folder "../workspace", "/home/vagrant/html", 
mount_options: ['dmode=775','fmode=644'], owner: "apache", group: "apache" 

rsync

rsyncにはrsync__chonwというオプションがあり、これが割と曲者。

値となるture, falseで違いを見ていく。

rsync(rsync__chown: true)

通常rsync__chownはtrueになっており、一括chown(chown -R)が行われ、Vagrant:Vagrantで上書きされる。 パーミッションはホストから独立しているので、自由に設定できる。

## 例2 ##
config.vm.synced_folder "../workspace", "/home/vagrant/html",
type: "rsync",
rsync__exclude: [".git/", "vendor/"],
rsync__chown: true

rsyncには記載されていないが、ownergroupオプションはなぜか使える。ただし、mount_optionsは使えない模様。

このオプションを使うと、同期ファイルのユーザとグループが指定できる。

## 例3 ##
config.vm.synced_folder "../workspace", "/home/vagrant/html",
type: "rsync",
rsync__exclude: [".git/", "vendor/"],
owner: "apache",
group: "apache",
rsync__chown: true

更に通常同期のように同期ファイルのパーミッションを設定したいというときは、rsync__argsの引数に--chmodを与えると設定ができる。

## 例4 ##
config.vm.synced_folder "../workspace", "/home/vagrant/html",
type: "rsync",
rsync__exclude: [".git/", "vendor/"],
owner: "apache",
group: "apache",
rsync__args: [
    "--compress", "--verbose", "--archive", "--delete", "--copy-links",
    "--chmod=Du=rwx,Dgo=rx,Fu=rw,Fog=r", # D755 F644
],
rsync__chown: true

尚、--chmodを指定するときは、--perms, -pを指定しないと無視されてしまうので注意。

上は--archive_-rlptgoD と同義_を設定しているため問題はない。

-r, --recursive: ディレクトリを再帰的にコピー -l, --links: シンボリックリンクを作り直す -p, --perms: コピー先のパーミッションをコピー元と同じにする -t, --times: 修正時間情報も転送する -g, --group: 所有者のグループを送信元と同じにする -o, --owner: 所有者を送信元と同じにする -D: デバイスファイルを維持

rsync(rsync__chown: false)

同期時にchown -Rを止めるオプション。

## 例5 ##
config.vm.synced_folder "../workspace", "/home/vagrant/html",
type: "rsync",
rsync__exclude: [".git/", "vendor/"],
rsync__chown: false,

この場合、ホストから新規で追加されるファイルはroot:rootとなる。 また、既存ファイルは作成されたときのままのオーナー:グループとなっていた。 勿論、rsync__falseの場合でも先のようにrsync__argsの各オプションは設定可能。

## 例6 ##
config.vm.synced_folder "../workspace", "/home/vagrant/html",
type: "rsync",
rsync__exclude: [".git/", "vendor/"],
rsync__args: [
    "--verbose", "--archive", "--delete", "-z", "--copy-links",
    "--chmod=Du=rwx,Dgo=rx,Fu=rw,Fog=r", # D755 F644
    "--owner", "--group", # required for the following command
    "--usermap=*:apache", "--groupmap=*:apache"
],
rsync__chown: false

例6の解説になるが、rsync__argsの第1,2引数は前回と同じ。

第4引数の--usermap--gruopmapは、同期時にオーナーとグループをマッピングする機能。 これらのオプションを指定するには、第3引数の--owner--groupの設定_--archive-o-gは含まれているはずだが、自分の環境では明示的に記述しないと機能しなかった_が必要。

また--usermapと同じ機能を持つオプションとして、--chown=USER:GRUOPというものもある。 これは内部的には--owner--groupを使っているため、--chown--usermapを混合させることはできない。

つまり--chown=foo:barは、--usermap=*:foo --gruopmap=*:varと同義。

この機能はマップされるユーザが同期元と先で異なる場合に役立つ。

そして、例6は結局のところ例4と同じ同期状態を提供することになる。

一部オプションを使うとエラーになる場合

上に書いた例を試してエラーになる場合は、rsyncのバージョンを疑うといい。

通常、rsyncはホスト/ゲストともに入れる必要がある。Windowsの場合はCygwinを使うことがほとんどだと思うので、最新のrsyncが導入される。問題はゲスト側。

ゲストにrsyncコマンドが導入されていない場合は、Vagrantでマシン立ち上げ時に自動でインストール_yum -y install rsync_が行われているが、標準のリポジトリのrsyncは古い。

例えばCentOS 6.8_--enablerepo=base_だとver 3.0.6がインストールされたが、3.0.6だと上に書いたusermapなんかは使えない。

最新バージョンをインストール

以下、トラブったときのためにboxのバックアップをとってからやるべし。

Vagrantfileから共有フォルダの設定部分をコメントアウトしマシンを起動する。

vagrant reload
vagrant ssh
su -
yum remove rsync
wget https://www.samba.org/ftp/rsync/src/rsync-3.1.2.tar.gz
tar xzvf rsync-3.1.2.tar.gz
rm -f rsync-3.1.2.tar.gz
cd rsync-3.1.2
./configure
make
make install
reboot -h now
rsync --version
rsync  version 3.1.2  protocol version 31

バイナリから入れると、/usr/local/bin/rsyncに配置された。 そして、新しいrsyncを入れた場合はその位置をrsync__rsync_pathで指定する必要がある。

つまり例6を元に書くと、こんな感じになる。

config.vm.synced_folder "../workspace", "/home/vagrant/html",
type: "rsync",
rsync__exclude: [".git/", "vendor/"],
rsync__args: [
    "--compress", "--verbose", "--archive", "--delete", "--copy-links",
    "--chmod=Du=rwx,Dgo=rx,Fu=rw,Fog=r", # D755 F644
    "--owner", "--group", # required for the following command
    "--usermap=*:apache", "--groupmap=*:apache"
],
rsync__chown: false,
rsync__rsync_path: "sudo /usr/local/bin/rsync"

パスにsudoが入っているけども、自分の環境の場合つけないと赤文字が出るのでこうしている。

以上、rsyncで1週間半ほど躓いた内容の一部をまとめてみました。