なおかつ・ArchLinux インストール覚書

# 能書き

[ArchLinux インストール覚書](http://qiita.com/katz_engineer/items/f032a24cb273c4eb6669)より始めた自宅サーバ構築ですが、[やりたい・1](http://qiita.com/katz_engineer/items/f032a24cb273c4eb6669#やりたい1)として考えていた事は[超軽量仮想環境 cage ](http://qiita.com/katz_engineer/items/d0404a896f2faa267fb8)という形にまとめるという事で、方向性が固まってきました。

それとは別に、ネットワーク越しの遠隔操作と、設定ファイルを含む様々なファイル群のバージョン管理を導入したい。仮想環境を作ってその中に置く事を考えていたのですが、ホスト環境に直接導入しておいた方が色々と都合が良さそうだと考え直しました。

という訳で。ここでsshとSubversionを導入して設定します。まずはSubversionから。

ちなみにバージョン管理に関しては私はSubversion派です。分散バージョン管理を利用した開発フローも近々勉強の予定ですが、最終的にはその開発フローをSubversion上で実現したいと考えている不埒者です:stuck_out_tongue_winking_eye:

Subversionはバイナリファイルを管理対象に出来るとか、日本語ファイル名も（それなりに）受け付けてくれるとか、そういう点に長所を感じています。ついでに言うと、リポジトリが差分の積み重ねなのもポイント高いです。というかリポジトリは差分にするべきってのは大前提だと私は思ってたんですよ。どうもGitはそうではないらしいですね〜。昔、手動でバージョン管理してた時代に、とんでもないディスク容量を食い潰して苦労したトラウマがですね…:sweat:

余談ですが、FacebookもSubversionで管理してるんでしたよね確か。今はMercurialになったのかな？

# iSCSIストレージの用意

[重ね重ね・ArchLinux インストール覚書でiSCSIストレージを外しておきました](http://qiita.com/katz_engineer/items/3c4bafd3aeb32aa2eaf0#iscsiストレージのサブボリューム構造)が、Subversionリポジトリの置き場所としてiSCSIストレージを設定します。

Subversionリポジトリの場所については推奨とか一般的な慣習とか一切無さそうですね。皆さんそれぞれ好き勝手やってるようです。FHSの薦める所というのもこういう場合は若干微妙なようですが、それでも /var/svn/repos が良いのではないかという意見が散見されます。

以上を踏まえて、私の環境ではSubversionリポジトリは /var/svn/repos に決めました。リポジトリ以外の関連データを含められるように /var/svn をiSCSIストレージのマウントポイントとします。

私の環境は現在、[起動時にiSCSIターゲットに自動ログイン](http://qiita.com/katz_engineer/items/8408fe4ddbd9111a5d08#iscsiターゲットにログイン)するようになっています。iSCSIのログインなどの操作は、現段階では不要です。従って主な作業は /etc/fstab に追記してマウントするだけですね。

ちなみにストレージのuuidは、```blkid```コマンドもしくは /dev/disk/by-uuid を```ls```する事でわかるようです。これはちょっと面白いです。

```
# ls -l /dev/disk/by-uuid
total 0
lrwxrwxrwx 1 root root 9 Jun 25 21:48 4b90bf6a-14f1-459f-901a-8362193ef822 -> ../../sdc
lrwxrwxrwx 1 root root 9 Jun 24 18:50 54dea161-4730-40ea-b66d-d1bfb10b2f00 -> ../../sdb
```

私の今の環境では、この /dev/sdc がiSCSIターゲットです。[btrfsにしてある](http://qiita.com/katz_engineer/items/2dcc4f3e0a3dd7b828f8)ので、Subversionデータ用サブボリュームを作成します。

```
# mount /dev/sdc /mnt
# btrfs subvolume create /mnt/@svn
Create volume '/mnt/@svn'
# btrfs subvolume list -p /mnt
ID 257 gen 33 parent 5 top level 5 path @svn
# umount /mnt
```

/etc/fstab に追記。そうそう、viに慣れていない方の為に耳寄り情報を一つ。編集モードで :r! の後に続けてコマンドを書くと、コマンドの出力結果が編集画面に取り込まれます。この機能を利用すれば、uuidみたいな無意味な数字の羅列なんかも誤り無く記述できるでしょう。

```
# mv /etc/fstab /etc/fstab.org
# cp /etc/fstab.org /etc/fstab
# vi /etc/fstab
# diff -U0 /etc/fstab{.org,}
--- /etc/fstab.org      2017-05-21 23:12:15.739160315 +0900
+++ /etc/fstab  2017-06-25 21:58:29.581039985 +0900
@@ -6,0 +7 @@
+UUID=4b90bf6a-14f1-459f-901a-8362193ef822      /var/svn        btrfs   _netdev,rw,relatime,space_cache,subvol=@svn     0 0
# rm /etc/fstab.org
```

マウントポイントを作ってマウント。

```
# mkdir /var/svn
# mount /dev/sdc
```

念のため確認します。

```
# mount | grep /dev/sdc
/dev/sdc on /var/svn type btrfs (rw,relatime,ssd,space_cache,subvolid=257,subvol=/@svn)
```

# Subversion

私がFreeNAS jailに作ったSubversionサーバと同様の設定で用意します。

* [Subversion だけでお手軽にサーバ構築](http://qiita.com/katz_engineer/items/09c6dd4e8bde642d627b)
* [Svnserve のセットアップ - Subversion - ArchWiki](https://wiki.archlinuxjp.org/index.php/Subversion#Svnserve_.E3.81.AE.E3.82.BB.E3.83.83.E3.83.88.E3.82.A2.E3.83.83.E3.83.97)

## 導入

```
# pacman -S svn
```

ふむ…Subversionも今は1.9の時代ですか…

ユーザはsvn、リポジトリの場所は上述の通り /var/svn/repos とします。

```
# useradd -c "Subversion service" -r -s /usr/bin/nologin svn
# cd /var/svn
# mkdir repos
```

これに合わせてsystemd用の設定ファイルを用意します。参照: [サーバーデーモンの起動 - Subversion - ArchWiki](https://wiki.archlinuxjp.org/index.php/Subversion#.E3.82.B5.E3.83.BC.E3.83.90.E3.83.BC.E3.83.87.E3.83.BC.E3.83.A2.E3.83.B3.E3.81.AE.E8.B5.B7.E5.8B.95)

```
# echo 'SVNSERVE_ARGS="-r /var/svn/repos"' >/etc/conf.d/svnserve
# mkdir /etc/systemd/system/svnserve.service.d
# cat - <<___ >/etc/systemd/system/svnserve.service.d/50-custom.conf
> [Service]
> User=svn
> ___
```

組み込みのユーザ認証を設定します。ここに記述されるパスワードは平文で、スペースや記号も許されます。とりあえず実験用のユーザとパスワードを一つ。

```
# cd /var/svn
# mkdir conf
# cat - <<___ >conf/passwd
> [users]
> taro = This is 1 pen.
> ___
```

プライベートの場合は権限の制限は無くて、プロジェクトのディレクトリツリーは全員すべて読み書き可能にする事が多いでしょう。これを共有のファイルとしておきます。そうでない場合はそれなりに設定してください。

```
# cat - <<___ >conf/default-authz
> [/]
> * = rw
> ___
```

リポジトリを用意…する為のスクリプトを作ります。滅多にしない操作を忘れないように。

```
# vi createprj.sh
# cat createprj.sh
#!/bin/bash
if [ "$1" == "" ]; then
        echo "usage: ¥${0#*/} <projectname>"
        exit
fi
svnadmin create repos/$1
ret=$?
test $ret -ne 0 && exit $ret

cat - <<___ >repos/$1/conf/svnserve.conf
        [general]
        anon-access = none
        auth-access = write
        password-db = ../../../conf/passwd
        authz-db = ../../../conf/default-authz
        realm = Project $1
___
chown -R svn:svn repos/$1

echo "Edit svnserve.conf and authz in the directory repos/$1/conf as needed."
echo "The file passwd is in the directory ./conf, edit it as needed, too."
# chmod 755 createprj.sh
```

ここまで出来たら、ファイルとディレクトリの所有者を svn にしておきます。

```
# chown -R svn:svn .
```

## 起動

```
# systemctl start svnserve
# ps -aux | grep svnserve
svn      2920  0.0  0.0  82884  2988 ?        Ss  00:58  0:00 /usr/bin/svnserve --daemon -r /var/svn/repos
root     2968  0.0  0.0   9024   968 tty1     S+  01:07  0.00 grep  svnserve
```

## 確認

実験用のプロジェクトを作成し、一部設定を書き換えます。

```
# ./createprj.sh test
Edit svnserve.conf and authz in the directory repos/test/conf as needed.
The file passwd is in the directory ./conf, edit it as needed, too.
```

実際にcommitまでやってみます。

```
# cd
# pw=$(sed -ne"s/^taro =[[:space:]]*¥(.*¥)[[:space:]]*$/¥1/p" /var/svn/conf/passwd)
# svn ls --username taro --password "$pw" svn://localhost/test/

----------------------------------------------------------------------
ATTENTION!  Your password for authentication realm:

   <svn://localhost:3690> Project test

can only be stored to disk unencrypted!  You are advised to configure
your system so that Subversion can store passwords encrypted, if
possible.  See the documentation for details.

You can avoid future appearances of this warning by setting the value
of the 'store-plaintext-passwords' option to either 'yes' or 'no' in
'/root/.subversion/servers'.
----------------------------------------------------------------------
Store password unencrypted (yes/no)?
```

ここでyesを入力します。その後は何も表示されません、まだ何もcommitしていないので。

余談ですけど、このプロンプトは消せないようです。```yes | svn``` みたいな事をやると、プロンプトは消えるけどパスワードのローカル保存もされません。これではテストの自動化が出来ません。困ったものです。何かやり方がありますかね？御存知の方教えて下さい:bow:

で、パスワードは ~/.subversion に保存されたとして、確認を続けます。

```
# svn co svn://localhost/test/
Checked out revision 0.
# cd test
# echo Subversion test >document.txt
# svn add document.txt
A         document.txt
# svn ci -m"first document"
Adding         document.txt
Transmitting file data .done
Committing transaction...
Committed revision 1.
```

読み出しも書き込みも成功！

## 片付

動作確認も完了したので片付けます。
 
```
# cd
# rm -r test .subversion /var/svn/repos/test
```

# etc-manager

要するに /etc などのバージョン管理です。[FreeNAS 9.3 jail の /etc などをバージョン管理](http://qiita.com/katz_engineer/items/c0f9ce266d6015d46786)でもやろうとしましたが、そういう事です。

```
# cd /var/svn
# ./createprj.sh etc-manager
Edit svnserve.conf and authz in the directory repos/etc-manager/conf as needed.
The file passwd is in the directory ./conf, edit it as needed, too.
```

そうそう、/var/svn/conf/passwd は適当に修正して、rootユーザを登録しておきます。すぐにsshとの連携をするつもりですので、ここでの登録はすぐに使われなくなる予定です。

```
# cd
# svn co svn://localhost/etc-manager/
```

ここでrootのパスワードを入力し、パスワードのローカル保存にyesします。

```
# cd etc-manager
# mkdir etc usr_local_etc
# cat - <<___ >prepare.sh
> #!/bin/bash
> mount -rv --bind /etc etc
> mount -rv --bind /usr/local/etc usr_local_etc
> ___
# chmod 755 prepare.sh
# svn add *
# svn ci -m"first commit"
Adding         etc
Adding         prepare.sh
Adding         usr_local_etc
Transmitting file data .done
Committing transaction...
Committed revision 1.
# ./prepare.sh
mount: /etc bound on /root/etc-manager/etc.
mount: /usr/local/etc bound on /root/etc-manager/usr_local_etc.
# svn add etc/* usr_local_etc/*
    《表示省略》
# svn ci -m"initial etc"
    《表示省略》
Committed revision 2.
# umount etc usr_local_etc
```

完了！:thumbsup: