行ったり来たりで、よく忘れる構築の手順そのものをアプリにしたら、五つのバグが出てきた話
サーバ二台を建てるのに、三つのアプリを行ったり来たりしていた。順番は手順書の中にしかなく、覚えているのは私だけだった。それを工程順に案内するアプリにまとめたら、今まで見えていなかった不具合が五つ出てきた。どれも「動いているように見えて中身が違う」型で、人が目で見て気づけるものではなかった。
三つのアプリを、行ったり来たりしていた
NGW のサーバは二台一組だ。NGWメインとNGWクローン。中身は Ubuntu と MySQL で、それぞれ Mac mini の上の仮想マシンとして載っている。
建てるのに使う道具は三つある。
- NGW保守コンソール — 仮想マシンの中の Linux を扱う
- NGW Mac設定 — Mac 本体だけを扱う(電源設定、無人再起動、イメージのコピー)
- NGWモニター — 別の端末から二台を眺める
役割はきれいに分かれている。分かれているのだが、建てるあいだは、この三つを行ったり来たりする。Mac 設定で電源を仕込んで、保守コンソールでスクリプトを設置して、また Mac 設定でイメージをコピーして、保守コンソールでレプリケーションを組んで、最後にモニターの参照先を書き換える。
この「行ったり来たり」の順番が、どこにも実体として無かった。手順書の Markdown の中にはある。だが手順書は、読んだ人がその通りにやったかどうかを確かめない。順番を覚えているのは私だけである。
私は覚えられない。前にも書いたが、覚えられないものは忘れる。忘れたころに、一台だけ設定が抜けたまま現場へ出てゆく。
だから、順番のほうをアプリにした。
NGW構築ナビ
四本目のアプリを作った。NGW構築ナビという。
誤解のないように書いておくと、三つのアプリを一つに統合したのではない。三つはそのまま残る。まとめたのはアプリではなく手順である。
構築ナビは十一の工程を順番に並べて、それぞれについて
- ここで何をするのか、なぜそれが要るのか
- このアプリから実行できるのか、実機の画面でしかできないのか
- できるなら、押すボタン
- できないなら、どのアプリのどの画面へ行けばいいか
を出す。前の工程が済んでいなければ次は押せない。そして各工程には「確認」の欄があって、機械で読めるものは自動で判定する。
この最後が肝心なところだった。以前は「団体名が新しくなっているか」「レプリケーションが動いているか」を、人がチェックボックスに印を付ける形にしていた。だがそれは、印が付いているという記録だけが残って中身が伴わない。人に読み直させて印を付けさせると、見落とすか、面倒になって全部に印を付けるかのどちらかである。
だから確かめられることは、人に印を付けさせないことにした。団体名はデータベースの定数表から読める。レプリケーションは SHOW REPLICA STATUS で読める。無人運用の登録は launchd の設定ファイルの有無で読める。読めるものは全部、アプリが読んで ✔ か ★ を付ける。
工程ごとに「✔ 12 / ★ 2」のように出る。★ が残っている工程は、済みにしようとすると確認を求められる。
そうしたら、五つ出てきた
構築ナビを実際のサーバに向けて動かし始めたら、今まで見えていなかった不具合が次々に出てきた。
面白いのは、五つとも同じ型だったことである。動いているように見えて、中身が違う。
#1 — バックアップが、居ない団体を探し続けていた
昼の 12時半、バックアップが error で終わった。ログを見たら、こうだった。
mysqldump: Got error: 1049: Unknown database 'xxxx_ngwdb'
[12:30:01] NG xxxx_ngwdb ダンプ失敗 (旧ファイル温存)
xxxx_ngwdb は既存団体のデータベースである。だがこの機体に載っているのは、これから使う団体の yyyy_ngwdb だけだ。設定ファイルに、複製元の団体が直書きされたまま残っていた。
タチが悪いのは、設定ファイルは設置のときに温存されることだった。現地で書き換えた値を消さないための配慮である。そのおかげで、雛形に書かれた団体コードはイメージを複製するたびに、そのまま運ばれてゆく。ログを見に行かない限り、誰も気づかない。
しかも、ついでにもう一つ分かった。操作説明用のデータベースが、ずっとバックアップされていなかった。「暫定的に一団体だけ回す」という設定が、暫定のまま何ヶ月も残っていたためである。
直したのは三つ。雛形から団体コードを追い出して、名前ではなく形(%_ngwdb)で選ぶようにした。対象がゼロ件なら error にした(「毎回動いているのに何も取れていない」が ok で通らないように)。そして設置のたびに、団体コードの直書きがあれば直すようにした。雛形を直しても既に建った機体は直らないからである。
#2 — 一覧が、接続先を見ていなかった
保守コンソールでバックアップするデータベースを選ぼうとしたら、既存の七団体が並んだ。
そのどれも、繋いでいる機体には載っていない。
一覧を設定ファイルの既定値から作っていた。接続先を選べるアプリなのに、接続先を見ていなかったわけである。実在するデータベースは選択肢に出てこない。しかもこの一覧は、復元するときの安全確認にも使われていた。取り違えれば、別団体のデータを書き込むことになる。
機体から読むように直した。設定ファイルは自治体名を引くための辞書としてだけ使う。ついでに、接続を切ったら一覧を捨てるようにもした。持ち越すと、次に別の機体へ繋いだときに前の機体のデータベースが並ぶ。同じ病気である。
#3 — 待機側に、別環境の宛先が残っていた
添付ファイルは、メインからクローンへ五分ごとに送っている。その宛先の設定が、クローン側に残っていた。まったく別の環境を指す IP アドレスだった。
クローンは受け手なので、待機しているあいだは動かない。動かないから、誰も気づかない。だが昇格して送り手になった瞬間、そこへファイルを送り始める。
画面には「この三つのファイルを書き換えます」と出ているのに、実際には二つしか書いていなかった。書き忘れである。
#4 — 宛先が空だと、到達確認が必ず成功していた
#3 を直しながら気づいた。宛先を空にする設計にしたのだが、同期スクリプトはこう書いてあった。
if ! $CLONE_SSH 'true' 2>/dev/null; then
log "clone に SSH 到達不可。中断。"
$CLONE_SSH が空だと、これはローカルで true を実行する。当然、成功する。「到達 OK」と表示して先へ進み、その先のファイル転送は宛先が :パス という壊れた形になる。
宛先の形を先に検査してから動くようにした。
#5 — 点検が、別の場所を見ていた
これが一番タチが悪かった。
構築ナビの点検が、両方の機体で「設定ファイルがありません」と赤く出た。だが実際にはある。今しがた自分で確認したばかりである。
原因は ~ だった。この点検は、データベースに素で繋げない機体では sudo で走り直す。そのとき $HOME は /root になる。実機で確かめたらこうだった。
whoami=root HOME=/root NGW_USER=administrator NGW_HOME=/home/administrator
つまり ~/ngw-backup/設定ファイル ではなく /root/ngw-backup/設定ファイル を見ていた。無くて当然である。
だが誤報だけなら、まだいい。同じ実行で、もっと悪いことが起きていた。
複製元の痕跡を調べる項目が、~/.ssh/id_ngwlinux を見ている。これも /root/.ssh/ を見に行く。そこには無い。だから――
鍵が残っていても「切り離し済み ✔」と出る。
★ の出しすぎは、うるさいだけで気づける。だが見逃しは気づけない。リポジトリへ push できる鍵を持ったまま現場へ出す、ということが起こり得た。
sudo で走っても正しい利用者のホームを引くように直し、~ を書いたら落ちるテストを足した。この罠は以前も一度踏んでいて、二度目だったからである。
手順書とアプリの違い
構築の手順書はある。Marp で書いた、印刷もできるスライドである。
だが手順書は、読んだ人が本当にやったかどうかを確かめない。「クローンのレプリケーションを止める」と書いてあっても、止めたかどうかは書いた側には分からない。分からないまま次の頁へ進む。
アプリは確かめる。止まっていなければ ★ が出る。★ が出たまま次へ進もうとすれば、聞き返す。手順書とアプリの違いは、内容ではなく「確かめるかどうか」だけである。
だから今回、紙に出すのはやめて全部オンラインにした。紙には ★ が出せない。
一発でやる
もう一つ足した。アドレスの付け替えである。
現地へ持ち出すとき、二台の IP アドレスを変える。すると、それを参照している設定が一斉にずれる。今日わかっただけでも、追随させる先はこれだけあった。
- 両機の
promote.conf(サービス IP、メインの IP、クローンの IP、生存確認用 IP) - メインの
watchdog.conf— クローンを見に行く接続先 - メインの
sync.conf— 添付ファイルの送り先 - クローンのレプリケーションの接続元
- NGWモニターの参照先
五箇所。一つ忘れると静かに壊れる。#3 のバグが、まさにその実例だった。
これを一つのボタンにした。押すと、この順に進む。
1. 新しいアドレスで両方の Linux に入れるか ← 駄目ならここで中止
2. メインの設定ファイル三枚
3. クローンの設定ファイル三枚
4. レプリケーションを新しいメインへ張り替え
5. NGWモニターの参照先
手順1が肝心である。新しいアドレスで両方に入れなければ、1バイトも書かずに中止する。片方だけ書き換わった状態が、いちばん厄介だからだ。押す前に「下見」もできる。何が書き換わるかだけを出して、相手は一切変わらない。
Mac 本体の IP アドレスそのものは、このボタンに含めなかった。遠隔で変えると、変えた瞬間に自分の接続が切れる。打ち間違えればその機体には二度と届かず、実機まで行くことになる。そこだけは人がやる。アプリは「変えたあとに追随させる側」を全部引き受ける。
夕方、実際に .201/.202 から .171/.172 へ付け替えた。ボタン一つで通った。
Source_Host : 192.168.0.171
Replica_IO_Running : Yes
Replica_SQL_Running : Yes
Seconds_Behind_Source : 0
それでも、私は間違えた
付け替えの前に、新しいアドレスが空いているかを ping で調べた。両方とも応答があった。
「誰かが使っている」と思ったが、違った。もう変更が終わっていた機体自身が答えていたのである。空き確認は、Mac の IP を変える前にやらなければ意味を成さない。順番を間違えると、自分が自分に ping を打って「使用中」と読む。
これも画面に書き足した。「⓪ 空き確認は、必ず ② の前に」と。
覚えているのは、一つだけでいい
これで、構築のあいだに覚えておくことは一つになった。
構築ナビを起動する。
そのあとは工程が順に並んでいて、どこで何をするか、どのアプリへ行けばいいかが書いてある。実行できるものはボタンになっている。確かめられるものは勝手に確かめる。
残っているのは、写真つきの説明画面である。工程ごとに実際の画面を撮って並べれば、私でなくても建てられるようになる。ファイル名を決めた形で置くだけで画面に出るようにしてあるので、撮ったら終わりだ。
もう一つ、正直に書いておく。イメージのコピーから一組をまっさらに作る道は、まだ一度も通していない。今日確かめたのは主に終盤の工程で、使ったのは半分できた状態の機体である。明日、そこを通す。詰まった箇所が、このアプリに足りないものの正体になる。
老いぼれの頭でも、一つくらいは覚えていられるだろう。
AIとの協働作業での学び
今日は、バグが五つ出た日ではなく、五つ見えるようになった日だった。
五つとも、前から在った。バックアップの設定は数ヶ月前から複製元を指していたし、~ の罠はもっと古い。変わったのは、機械に判定させ始めたことだけである。人が画面を眺めて気づけるものは一つも無かった。バックアップは毎日ちゃんと走っていたし、コンソールにはデータベースの一覧が並んでいたし、点検は「切り離し済み ✔」と出ていた。
その意味で、構築ナビを作った本当の収穫は、構築が楽になったことではない。確かめる場所を作ったことのほうだった。
そして今日は、AI の側にも実害のある失敗があった。
参照先を書き換える処理のテストを書いたのだが、その処理が関数の中から動いているモニター本体へ直接送りつける作りになっていた。テストは一時ファイルを渡したつもりだったが、実際にはこの開発機で動いていた本物のモニターの設定を書き換えた。並び順が入れ替わり、実在しない「デモ機」という監視先が増えた。すぐ元に戻したが、テストが本番を壊すという、あってはならない類である。
直したのは、テストの書き方ではなく処理のほうにした。渡す先を引数にして、テストからは本物へ届きようがない形にした。そして「関数の中から本物を直接指していないか」を検査するテストを足した。次に誰かが元に戻したら、その場で落ちる。
前の日に書いたことの繰り返しになるが――気をつけようで終われば、また踏む。踏めない形にするしかない。それは人間に対しても、AI に対しても同じである。