自宅サーバー構築譚：Subversionをインストールして /etc をバージョン管理

# 序

[自宅サーバー構築譚：基本構想](https://qiita.com/katz_engineer/items/cb592be44daa28a51d9b)に基づく自宅サーバー構築の続き。```/etc```をバージョン管理します。但し私の個人的な好みで、GitではなくSubversionを使います。

# 準備

[前回](https://qiita.com/katz_engineer/items/43bfd7ca82c941b33dc3)の続きなので、実機のコンソールにrootでログインします。

## システムのアップデート

何はともあれスナップショット。これを気軽に実行できるのが zfs （及び btrfs ）の素晴らしい点です。そしてシステム全体のスナップショットを撮っておけば、何かあってもすぐに復旧できます。

ちなみに、システム関連なので対象は ```tank/main``` だけです。```tank/sub0``` 以下については除外します。

```console
zfs snapshot tank/main/ubuntu@$(date +%Y%m%d_%H%M%S)_before_universe
```

しかし[前回](https://qiita.com/katz_engineer/items/43bfd7ca82c941b33dc3)のままでは```apt-add-repository```コマンドも使えない模様。そんな時には下記コマンド、だそうです。

参考文献： [Ubuntu Linuxで、add-apt-repositoryしようとして「コマンドがない」って言われたら - CLOVER](https://kazuhira-r.hatenablog.com/entry/20160116/1452933387)

```console
apt install software-properties-common
apt update
```

リポジトリuniverseを追加します。

```console
apt-add-repository universe
```

パッケージ関連の更新など。

```console
apt update
apt upgrade
```

## パッケージインストール前のスナップショット

スナップショットはガンガン撮りまくりましょう！HDDの逼迫は心配無用。内部的には差分管理と同じ形になっているので、そんなに消費しません。それでも問題になったら、その時に古いのを削除すればいいんです。

```console
zfs snapshot tank/main/ubuntu@$(date +%Y%m%d_%H%M%S)_before_Subversion
```

スナップショットを確認します。さっきのアップデート前の物も一緒に見てみます。

```console
zfs list -t snapshot -S name -r tank/main | head -n3
```

オプション```-S```（Sは大文字）でスナップショット名の逆順を指定しているのがミソ。名前に日時を付けているので、新しい順に表示されます。説明記事を書いたりエビデンスを揃えたりする場合に便利です。

```console
# zfs list -t snapshot -S name -r tank/main | head -n3
NAME                                                 USED  AVAIL     REFER  MOUNTPOINT
tank/main/ubuntu@20220313_162206_before_Subversion    80K      -      774M  -
tank/main/ubuntu@20220313_161618_before_update      2.94M      -      678M  -
```

# Subversionインストール

## パッケージ

svnパッケージをインストール。

```console
apt install subversion
```

インストールできたか確認します。

```console
svn --version | head -n2
```

表示内容は、例えば下記のようになります。

```console
# svn --version | head -n2
svn, version 1.13.0 (r1876053)
   compiled Mar 24 2020, 12:33:36 on x86_64-pc-linux-gnu
```

Subversion のバージョンは 1.13.0 ですか。何が変わったんでしょうね。少なくともレッドブックは…役に立たないとは言わないけど、細かい部分でかなり変わったんじゃないかと思うんだけど。思うんだけど！この手順では```man svn``` も ```info svn``` も表示されない… :sweat:

そして公式ページでは、ユーザーマニュアルはレッドブックでした。それもかなり古い。

実験的な機能は使わない方が良さそうだからまあいいか（バージョンアップで操作性や機能などが頻繁に変わるっぽい）

なお、失敗した場合には、下記コマンドの実行と```reboot```で「svnパッケージのインストール前」に戻ります。何度でもやり直せます。（```zfs list```のオプション```-S```のSは大文字）

```console
zfs list -t snapshot -o name -S name -H tank/main/ubuntu | head -n1 | xargs -t zfs rollback
```

## リポジトリ

今回はとにかく```/etc```のバージョン管理を開始するのが目標ですので、汎用的なプロジェクト用の設定は後日とします。

- 専用ユーザは作成しません。```/etc```バージョン管理はrootが行います。
- 汎用リポジトリの場所も用意しません。

汎用ではなく```/etc```の為のリポジトリの場所は、```/etc/.svn_repo```とします。

当然、svnの管理対象外とする設定を忘れてはなりません。その手順は後述。

```console
mkdir /etc/.svn_repo
svnadmin create /etc/.svn_repo
```

# ```/etc```を作業コピーにする

```console
cd /tmp
mkdir etc
svn import etc file:///etc/.svn_repo/ -m "create project"
rmdir etc
svn co file:///etc/.svn_repo/ /etc
```

ちゃんと出来たか確認。

```console
ls -dl /etc/.svn
```

```/etc/.svn```ディレクトリが出来ていればOKです。例えば下記のように表示されればOK。

```console
# ls -dl /etc/.svn
drwxr-xr-x 4 root root 8 Mar 13 16:57 /etc/.svn
```

# バージョン管理

## 最初の一歩

```console
cd /etc
svn add *
```

```console
ls *- | xargs -rt svn revert
```

```svn revert```の結果は下記のように表示されます。

```console
# ls *- | xargs -rt svn revert
svn revert group- gshadow- passwd- shadow-
Reverted 'group-'
Reverted 'gshadow-'
Reverted 'passwd-'
Reverted 'shadow-'
```

Subversion管理から外したファイルを確認してみます。

```console
# svn st --no-ignore | grep -E "^(\?|I)"
?       .pwd.lock
?       .svn_repo
?       group-
?       gshadow-
?       passwd-
?       shadow-
```

```.pwd.lock``` については[以前調べました](https://qiita.com/katz_engineer/items/c9afdcb0e2355ed67ede#etc-%E7%AE%A1%E7%90%86%E9%96%8B%E5%A7%8B)。バージョン管理は不要です。どうも更新時に設定されるロックファイルらしい。という訳で無視します。

参考文献: [Re: What is /etc/.pwd.lock for ? - debian-user Jul 2005 by thread](https://lists.debian.org/debian-user/2005/07/msg02949.html)

さて、最初のcommitです。コミットメッセージは何でも良いんですが。

```console
svn ci -m "first commit"
```

どういう訳か部分的にリビジョン不一致を起こす模様。そのため下記コマンドも実行します。

```console
svn up /etc
```

## 確認

ログを表示させてみます。

```console
# svn log /etc
------------------------------------------------------------------------
r1 | root | 2022-03-13 17:20:00 +0900 (Sun, 13 Mar 2022) | 1 line

first commit
------------------------------------------------------------------------
```

余談ですが、```xmllint```コマンドがあれば、```--xml```オプションと組み合わせて色んな値を抽出する事が出来ます。```head```とか```sed```とかを組み合わせてビクビクしながら調整する必要はありません。が、現状ではインストールされていませんので、参考文献を示すだけにしておきます。

参考文献1: [俺様サーバー構築記 - Subversionサーバーの構築@デスクトップパソコン](https://qiita.com/katz_engineer/items/b893316b4d1bb7731e87)
参考文献2: [俺様サーバー構築記 - Subversionをインストールして /etc をバージョン管理@全機](https://qiita.com/katz_engineer/items/29bb4672f69e70944a80)

## 無視ファイル

現時点でSubversion管理下に無いファイルは、すべて無視ファイルとして登録します。

```console
svn propset svn:ignore -F <(svn st | cut -b9-) .
```

状態を確認します。

```console
# cd /etc
# svn st
 M      .
# svn di
Index: .
=================================================
--- .       (revision 1)
+++ .       (working copy)

Property changes on: .
_________________________________________________
Added: svn:ignore
## -0,0 +1,6 ##
+.pwd.lock
+.svn_repo
+group-
+gshadow-
+passwd-
+shadow-
```

これも```/etc```の変更ですのでcommitします。

```console
svn ci -m"set svn:ignore"
```

# 結

これで```/etc```をバージョン管理できるようになりました。個人的な好みでSubversionですが、これからガンガンいきます！
やったね:thumbsup_tone1: