0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

俺様サーバー構築記 - Subversionをインストールして /etc をバージョン管理@全機

Last updated at Posted at 2020-07-05

俺様サーバー構築記 - 基本方針」に基づく作業の続き。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 svninfo svn も、諸々の話題はレッドブックで見つかるよ〜と書いてある…:sweat:

そして公式ページでも、ユーザーマニュアルはレッドブックでした。英語版ですが。

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

なお、失敗した場合には、下記コマンドの実行で「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にしましょう。

/etc/.svn_repo/autocommit.sh
#!/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

/usr/share/libalpm/hooks/etcmgr-pre-install.hook
# 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
/usr/share/libalpm/hooks/etcmgr-post-install.hook
# 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ですが、これからガンガンいきます!
やったね:thumbsup_tone1:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?