序
「俺様サーバー構築記 - 基本方針」に基づく作業の続き。LTS版Linuxカーネルの使用を決心してから、私の手持ちで生きているマシンをすべてフォーマットし直しました。
参考文献1: 俺様サーバー構築記 - ZFSをarchisoに埋め込む(linux-lts)@VirtualBox(UEFI)
参考文献2: 俺様サーバー構築記 - ZFS の上に Arch Linux をインストール; やり直し(Linux-LTS)@ノートパソコン(BIOS)
参考文献3: 俺様サーバー構築記 - ZFS の上に Arch Linux と無線LANをインストール; やり直し(Linux-LTS)@ノートパソコン(UEFI+wifi)
参考文献4: 俺様サーバー構築記 - ZFS の上に Arch Linux をインストール; やり直し(Linux-LTS)@デスクトップパソコン(BIOS)
折角なので、気になっていた細かい点を修正してしまいます。
まずは /etc
のバージョン管理。Subversion を使うのは相変わらずですが、そのリポジトリはローカルに作成します。ArchLinuxのアップデート事故などでzfs rollback
した時に、リポジトリも一緒に巻き戻ってくれないと、結構面倒だったのでした。これはまず最初に仕込んでおきたいですな。
参考文献5: 俺様サーバー構築記 - Subversionサーバーの構築@デスクトップパソコン
参考文献6: 俺様サーバー構築記 - Subversion による /etc のバージョン管理@ノートパソコン
参考文献7: 俺様サーバー構築記 - Subversion による /etc のバージョン管理@デスクトップパソコン
準備
システムのアップデート
何はともあれスナップショット。これを気軽に実行できるのが zfs (及び btrfs )の素晴らしい点です。そしてシステム全体のスナップショットを撮っておけば、何かあってもすぐに復旧できます。
ちなみに、システム関連なので対象は tank/main
だけです。tank/sub0
以下については除外します。
# zfs snapshot tank/main@$(date +%Y%m%d_%H%M%S)_before_update
心置きなくアップデート。
# pacman -Syy --noprogress
:: Synchronizing package databases...
downloading core.db...
downloading extra.db...
downloading community.db...
downloading archzfs.db...
# pacman -Syu
〈省略; 内容は毎回異なる〉
パッケージインストール前のスナップショット
スナップショットはガンガン撮りまくりましょう!HDDの逼迫は心配無用。内部的には差分管理と同じ形になっているので、そんなに消費しません。それでも問題になったら、その時に古いのを削除すればいいんです。
# zfs snapshot tank/main@$(date +%Y%m%d_%H%M%S)_before_svn
スナップショットを確認します。さっきのアップデート前の物も一緒に見てみます。
オプション-S
(Sは大文字)でスナップショット名の逆順を指定しているのがミソ。名前に日時を付けているので、新しい順に表示されます。説明記事を書いたりエビデンスを揃えたりする場合に便利です。
# zfs list -t snapshot -S name | head -n3
NAME USED AVAIL REFER MOUNTPOINT
tank/main@20200705_212415_before_svn 208K - 1.88G -
tank/main@20200705_211551_before_update 1.98M - 1.88G -
Subversionインストール
パッケージ
svnパッケージをインストール。
# pacman -S svn
〈省略〉
# svn --version | head -n2
svn, version 1.14.0 (r1876290)
compiled Jun 21 2020, 16:29:49 on x86_64-pc-linux-gnu
Subversion のバージョンは 1.14.0 ですか。何が変わったんでしょうね。少なくともレッドブックは…役に立たないとは言わないけど、細かい部分でかなり変わったんじゃないかと思うんだけど。思うんだけど!man svn
も info svn
も、諸々の話題はレッドブックで見つかるよ〜と書いてある…
そして公式ページでも、ユーザーマニュアルはレッドブックでした。英語版ですが。
実験的な機能は使わない方が良さそうだから、まあいいか(バージョンアップで操作性や機能などが頻繁に変わるっぽい)
なお、失敗した場合には、下記コマンドの実行で「svnパッケージのインストール前」に戻ります。何度でもやり直せます。(zfs list
のオプション-s
のsは小文字)
# zfs list -t snapshot -o name -s name | tail -n1 | xargs -t zfs rollback
zfs rollback tank/main@20200705_212415_before_svn
# reboot
リポジトリ
今回はとにかく/etc
のバージョン管理を開始するのが目標ですので、汎用的なプロジェクト用の設定は後日とします。
- 専用ユーザは作成しません。
/etc
バージョン管理はrootが行います。 - 汎用リポジトリの場所も用意しません。
汎用ではなく/etc
の為のリポジトリの場所は、/etc/.svn_repo
とします。
当然、svnの管理対象外とする設定を忘れてはなりません。その手順は後述。
# mkdir /etc/.svn_repo
# svnadmin create /etc/.svn_repo
/etc
を作業コピーにする
# cd /tmp
# mkdir etc
# svn import etc file:///etc/.svn_repo/ -m "create project"
# rmdir etc
# svn co file:///etc/.svn_repo/ /etc
Checked out revision 0.
ちゃんと出来たか確認。/etc/.svn
ディレクトリが出来ていればOKです。
# ls -dl /etc/.svn
drwxr-xr-x 4 root root 8 Jul 5 23:13 /etc/.svn
バージョン管理
最初の一歩
# cd /etc
# svn add *
〈省略〉
# ls *- | xargs -rt svn revert
svn revert group- gshadow- passwd- shadow-
Reverted 'group-'
Reverted 'gshadow-'
Reverted 'passwd-'
Reverted 'shadow-'
Subversion管理から外したファイルを確認してみます。
# svn st --no-ignore | grep -E "^(\?|I)"
? .pwd.lock
? .svn_repo
? .updated
? group-
? gshadow-
? pacman.d/gnupg/S.gpg-agent
? pacman.d/gnupg/S.gpg-agent.browser
? pacman.d/gnupg/S.gpg-agent.extra
? pacman.d/gnupg/S.gpg-agent.ssh
I pacman.d/gnupg/pubring.gpg~
? passwd-
? shadow-
これらの内でpacman.d/gnupg/S.gpg-agent*
がなぜ外れたのかがわからなくて調べてみました。
# ls -l pacman.d/gnupg/S.gpg-agent*
srwx------ 1 root root 0 Jun 28 21:07 pacman.d/gnupg/S.gpg-agent
srwx------ 1 root root 0 Jun 28 21:07 pacman.d/gnupg/S.gpg-agent.browser
srwx------ 1 root root 0 Jun 28 21:07 pacman.d/gnupg/S.gpg-agent.extra
srwx------ 1 root root 0 Jun 28 21:07 pacman.d/gnupg/S.gpg-agent.ssh
最初が「s」つまりソケットだったのでした。こんなものはバージョン管理対象外!なんですけど、どうしてソケットなんかを/etc
に置いたんでしょう。確かに、他に置く場所も無いのかも知れないけど。納得いきませんな。
なお.pwd.lock
と .updated
については以前調べました。バージョン管理は不要です。どうも更新時に設定されるロックファイル等で、特に後者は ArchLinux に特有のファイルっぽい。という訳で無視します。
参考文献1: Re: What is /etc/.pwd.lock for ? - debian-user Jul 2005 by thread
参考文献2: karol 2014-07-31 00:12:19 - [SOLVED] /etc/.updated? - System Administration - ArchLinux Forums
さて、最初のcommitです。
# svn ci -m "first commit"
〈省略〉
Committing transaction...
Committed revision 1.
確認
ログを表示させてみます。
なぜかリビジョンを指定しないと何も表示されないんですが… 原因不明。
(2020/07/11 修正ここから)
どうやら部分的にリビジョンが不一致を起こしているっぽい。知らんけど。
という訳でsvn update
すると直ります。
# svn up
Updating '.':
At revision 1.
# svn log
------------------------------------------------------------------------
r1 | root | 2020-07-05 23:37:52 +0900 (Sun, 05 Jul 2020) | 1 line
first commit
------------------------------------------------------------------------
(2020/07/11 修正ここまで)
余談ですが、--xml
オプションを指定してxmllint
コマンドと組み合わせれば、色んな値を抽出する事が出来ます。head
とかsed
とかを組み合わせてビクビクしながら調整する必要はありません。
参考文献: 俺様サーバー構築記 - Subversionサーバーの構築@デスクトップパソコン
# svn log -r0:HEAD --xml | xmllint --xpath "/log/logentry/date/text()" -
2020-07-05T14:37:52.9106912
# svn log -r0:HEAD --xml | xmllint --xpath "string(/log/logentry[1]/@revision)" -
1
無視ファイル
現時点でSubversion管理下に無いファイルは、すべて無視ファイルとして登録します。
# svn propset svn:ignore -F <(svn st | cut -b9- | grep -v /) .
property 'svn:ignore' set on '.'
# cd pacman.d/gnupg
# svn propset svn:ignore -F <(svn st | cut -b9-) .
状態を確認します。
# cd /etc
# svn st
M .
M pacman.d/gnupg
# svn di
Index: pacman.d/gnupg
=================================================
---pacman.d/gnupg (revision 1)
+++pacman.d/gnupg (working copy)
Property changes on: pacman.d/gnupg
_________________________________________________
Added: svn:ignore
## -0,0 +1,4 ##
+S.gpg-agent
+S.gpg-agent.browser
+S.gpg-agent.extra
+S.gpg-agent.ssh
Index: .
=================================================
--- . (revision 0)
+++ . (working copy)
Property changes on: .
_________________________________________________
Added: svn:ignore
## -0,0 +1,7 ##
+.pwd.lock
+.svn_repo
+.updated
+group-
+gshadow-
+passwd-
+shadow-
これも/etc
の変更ですのでcommitします。
# svn ci -m"set svn:ignore"
Sending .
svn: E155011: Commit failed (details follow)
svn: E155011: Directory '/etc' is out of date
svn: E160028: Directory '/' is out of date
あれれ、良くわかりませんが変なエラーが… このエラー(out of date)の場合はsvn update
すると直ります。
# svn update
Updating '.':
At revision 1.
# svn ci -m"set svn:ignore"
Sending .
Sending pacman.d/gnupg
Committing transaction...
Committed revision 2.
pacman フック
pacmanでパッケージを更新した時に、自動的にcommitされるようにします。パッケージのインストールや削除の際には手動でcommitしましょう。適切なコメントを残す必要もありますので。
設定
自動commitの為のシェルスクリプトを作成して、置き場所は/etc/.svn_repo
にしましょう。
#!/bin/bash
ETC_DIR="$1"
if [[ -z "$ETC_DIR" ]]; then
echo "$(basename $0) <dirname>"
exit 1
fi
exec &> >(tee >(systemd-cat -t etcmgr))
cd "$ETC_DIR"
SVN_STATUS=$(svn st)
if [[ -z "$SVN_STATUS" ]]; then exit; fi
echo "auto commit $ETC_DIR when done pacman command${2+: }$2"
echo "$SVN_STATUS" | grep "^?" | cut -b9- | xargs -I{} find {} -type f -or -type d -or -type l | xargs -r svn add
echo "$SVN_STATUS" | grep "^!" | cut -b9- | xargs -r svn rm
svn ci -m "auto commit when done pacman command${2+: }$2"
実行権限を忘れずに。
# chmod u+x /etc/.svn_repo/autocommit.sh
そしてpacmanのフックを作成します。
参考文献:2.2 フック - 2 設定 - pacman - ArchWiki
# etcmgr pre-install hook
[Trigger]
# Operation = Install
Operation = Upgrade
# Operation = Remove
Type = File
Target = etc/*
[Action]
Description = etcmgr: pre-transaction commit
When = PreTransaction
Exec = /etc/.svn_repo/autocommit.sh /etc pre-transaction
AbortOnFail
# etcmgr post-install hook
[Trigger]
# Operation = Install
Operation = Upgrade
# Operation = Remove
Type = File
Target = etc/*
[Action]
Description = etcmgr: post-transaction commit
When = PostTransaction
Exec = /etc/.svn_repo/autocommit.sh /etc post-transaction
確認
数日経過してからpacman -Syu
を実行します。そうしないとパッケージが更新されないので。しかし/etc
の変更を伴う更新って、そう頻繁に発生するのかな?実際に発生した場合の表示は、過去の記事を参照。
参考文献1: 俺様サーバー構築記 - Subversion による /etc のバージョン管理@ノートパソコン
参考文献2: 俺様サーバー構築記 - Subversion による /etc のバージョン管理@デスクトップパソコン
(2020/07/13 修正ここから)
後日、パッケージを更新したら/etc
が修正されたので、それを記しておきます。
# pacman -Syu
〈省略〉
:: Running pre-transaction hooks...
(1/1) etcmgr: pre-transaction commit
〈省略〉
(5/6) etcmgr: post-transaction commit
auto commit /etc when done pacman command: post-transaction
A keyutils
Adding keyutils
Sending services
Committing transaction...
Committed revision 3.
〈省略〉
# svn log /etc -rhead
Updating '/etc':
At revision 3.
------------------------------------------------------------------------
r3 | root | 2020-07-12 15:26:50 +0900 (Sun, 12 Jul 2020) | 1 line
auto commit when done pacman command: post-transaction
------------------------------------------------------------------------
(2020/07/13 修正ここまで)
結
これで/etc
をバージョン管理できるようになりました。個人的な好みでSubversionですが、これからガンガンいきます!
やったね