インストールパッケージ一覧として、数千ものファイル名が載った納品物が世の中には存在する。
数千もの細かなファイル名の羅列を見ても、何がインストールされているのかよくわからない。
管理すべきはOS名とパッケージ名と、そのバージョンとリビジョンである。
前提として、CPUアーキテクチャも必要だが。
例えばnginxのRedHetEL9.xのx86_64版のリリースxxというだけで、構成ファイル一覧を取得できる。
使うのはパッケージ管理ツールyum(dnf)だ。
yumにhistoryオプションを指定すると、インストールやアップデートの実施日時と概要がわかる。
概要一覧の先頭のIDを指定して、「yum history info <ID>」を実施すると、コマンドと引数の履歴がわかる。
さらには、依存関係を解決して実際にインストールされた複数のrpmファイルの一覧が表示される。
ここで有用なのは、rpmファイルの一覧ではなく、yum の操作ログなのである。
インストールやアップデートしたパッケージ名さえあれば、前提ファイルの類は意識しなくても済む。
OS以外が準備した、remiやepelなどのリポジトリを指定する場合も同じ。
表示される一覧に、リポジトリの詳細もついてくる。
サーバ更改で新システムのOSを最新に上げる場合、必要なのは現行システムの構成ファイル一覧ではなく、
実際に操作したyumの履歴のほうである。せいぜい20行程度のハズなので。
では、yumを使わずにrpmで直にインストールしたパッケージはどうするか。
yumの履歴には無いが、実際には存在しているパッケージだ。
実は、rpmにも履歴管理オプションはある。「rpm -qa --last」などである。
依存関係の管理はされていないが、ファイルの更新日時の記録が取れるので、
yumの履歴と突き合わせれば差分がわかる。
ソースから直に野良ビルドしていない以上、比較的簡単に正確な作業ができる。
ここで問題になるのは、インターネットに繋がっていないサーバ群だ。
方法は、ざっくり2つ。
1.インストールやアップデートの時だけ、各リポジトリとの通信経路を確保する
2.各リポジトリのミラーサーバをLAN内に配置する
1は、更新時にルータの電源の入/切などの運用で実現する。
2は、WSUSサーバのようなものを構築する方法だ。
いずれにせよ、この運用形態が確立しないまま、rpmファイルを手作業でインストール
していると、せっかくのパッケージ管理の恩恵を失うことになる。
Linuxで再帰的に全検索するには、調べたいディレクトリに移動して、
grep -riIn 文字列
ってやると、指定ディレクトリ以下の文字列を全検索してくれる。
ファイル名を探すには、調べたいディレクトリに移動して、
find . -name ファイル名 -print
ってやると、指定ディレクトリ以下のファイルを全検索してくれる。
ファイル名の前後に*を付けたりしてワイルドカードを使ってもOK(OSによるけど)。
Linux、UNIXであればここらへんが使えるから楽だけど、Windowsの場合も何とかなる方法がある。
Gitが入っていればGit bashで使える可能性が高い。
どこに何があるのかわからないとき、眠くなる前に、働いているフリをしよう!
パスワード管理のサーバが複数存在しているとき、状態を取得したり単純な操作を実施したりするのにログインが煩わしい。
操作ミスも怖い。
じゃあ自動化
古いタイプの人間だからexpectを選ぶ。
とりあえず、expectと入力してみてエラーになるなら dnf install expect か apt install expectする。
まずここでexpectの動作確認。
vi test
-----
#!/bin/bash
expect -c "
set timeout 3
spawn ssh ユーザ名@ホスト名
expect \"assword:\" <- Pが大文字だったり小文字だったりするので省く
send \"パスワード\n\"
interact
"
-----
testに実行権限を与える。
chmod +x test
./test
自動ログイン出来たら環境は出来ているから次のステップ。
まず、ログイン情報とシェルコマンドを定義するファイルを準備する。
crawler.csv
-----
ユーザ名1@サーバ名1,パスワード1,コマンド1
ユーザ名2@サーバ名2,パスワード2,コマンド2
ユーザ名3@サーバ名3,パスワード3,コマンド3
-----
コマンドは、ls -lとかps axとかdf -hなどをセットすればよい。
ではこのデータを順に読み込む動作確認。
test2
-----
#!/bin/bash
CSVDATA=crawler.csv
while read LINE
do
column1=$(echo $LINE | cut -d , -f 1)
column2=$(echo $LINE | cut -d , -f 2)
column3=$(echo $LINE | cut -d , -f 3)
echo $column1,$column2,$column3
echo "----- ----- ----- ----- ----- -----"
done < $CSVDATA
-----
test2に実行権限を与える。
chmod +x test2
./test2
ここまで動作確認できたらガッチャンコ。
crawler
-----
#!/bin/bash
CSVDATA=crawler.csv
while read LINE
do
column1=$(echo $LINE | cut -d , -f 1)
column2=$(echo $LINE | cut -d , -f 2)
column3=$(echo $LINE | cut -d , -f 3)
br="\n"
expect -c "
set timeout 2
spawn ssh $column1
expect \"assword:\"
send $column2$br
expect \"$|#\"
"
echo $column3
$column3
echo "----- ----- ----- ----- ----- -----"
done < $CSVDATA
-----
crawlerに実行権限を与える。
chmod +x crawler
./crawler