Mac にクローンし直したら、Cloudflare への書き込みだけが通らなかった
Mac にクローンし直したら、Cloudflare への書き込みだけが通らなかった
「アカウントの API トークンって、発行すればいいんでしたっけ」と聞いたところからこの日の作業は始まった。
自炊した専門書の図版が1,464枚ある。 それを Cloudflare のオブジェクトストレージに置きたかった。 Windows の母艦では通っていた作業だ。 Mac にリポジトリをクローンし直してから、読み取りは通るのに書き込みだけが弾かれるようになっていた。
トークンを発行するつもりだった
手順は、公式ドキュメントで今の画面を確認させてから教えてもらった。 返ってきた最初の注意が「アカウント単位の API トークンには2種類あるので選び間違えないように」だった。
その一文を読んだ時点で、自分でやるのはやめようと思った。 ダッシュボードを開いて、種類を選んで、権限を選んで、発行して、コピーして、貼り付ける。 一度きりの作業なのに、途中で選択を間違えてもその場では気付かない。
そこで「面倒くさいのでそちらでやってもらいたいんですけど、どこまでできますかね」と聞いた。 全部任せるつもりで聞いたのではない。 ブラウザでの発行とコピーだけは自分に残ると思っていたので、その境目を先に知りたかった。
「どこまでできますか」の答えが想定と違った
切り分けさせたら、境目の話ではない答えが返ってきた。
wrangler は既に入っていて、認証だけが通っていない状態だった。 この CLI は、OAuth のログインさえ済ませればオブジェクトストレージにファイルを置ける。 ダッシュボードでの発行も、コピーも、貼り付けも要らない。
新しいトークンを作らずに済む経路が最初からあったことになる。 教わった手順のほうが要らなくなった。
ログインさせたあと、読み取りが通るか、1ファイルだけ書けるか、と順に確かめてから本番に入った。
1,464枚を8並列で置く
wrangler は1回に1オブジェクトしか扱えない。 1,464回起動することになるので、8並列で回させた。 起動のたびに npx を経由すると待ち時間が積み上がるので、実体のバイナリを先に特定させている。
結果は1,463枚が成功し、1枚だけ失敗した。 その1枚を再送させて全部揃った。
検証は数字で見た。 欠番が1つあったが、そこは元から図の入っていないページで、404が正しい。 ランダムに8枚取って、すべて200が返った。 最後にブラウザで書籍のページを開いて、図が実際に出ているのを見た。
避けていた理由を確かめる
図が出たところで、気になっていたことを聞いた。
これまで wrangler のログインを使ってこなかったのは、付与される権限が広すぎると判断したからではないか。 Windows でログイン済みだった認証が、Mac にクローンし直したことで改めて必要になった。 それを避けて、権限の狭いほうで通そうとして詰まり、結局これまでと同じやり方に戻った。 自分の中では、そういう筋書きになっていた。
記憶で答えると都合のいい話になるからと、移行時の記録に当たらせた。 出てきた答えは違った。 権限の広さを比べて避けたのではなく、そもそも wrangler という選択肢が検討されていなかった。 移行のときの記録にも出てこない。 抜けだった、ということになる。
筋書きとしては自分の推測のほうがよくできていた。 よくできている推測ほど、確かめないまま事実として持ち歩くことになる。
Windows で通って Mac で落ちていた理由
権限の広い狭いではなく、認証がどこに置いてあるかの問題だった。
.env に入っているオブジェクトストレージの認証情報は、図を配信するための読み取り専用だ。
これで書き込みにいくと403で弾かれる。
書き込み側の認証は rclone の設定ファイルの中にあり、これは git にも 1Password にも入っていない。
マシンにローカルな設定なので、クローンしただけの環境には最初から来ない。
Windows の母艦にはそれがある。 Mac には無い。 だから Mac では、図版のアップロードだけが必ず失敗する。 足りなかったのは権限ではなく、認証の置き場所がマシンの中で閉じていたことだった。
2つの案のうち、今日通ったほうを採る
方針を2つ出させた。
A は、rclone の設定があるかどうかで経路を選ぶ。 設定が無ければ wrangler のログインで1枚ずつ置く。 今日そのまま通したやり方を既定にすることになる。
B は、S3 互換の API を直接叩く。 プロセスの起動が消えるので速くなる。 ただし、書き込み権限を持つアクセスキーを別途配る話がついてくる。
A を採った。 B は将来の改善案として残してもらうことにした。 速さのために認証情報を配る話を先に持ってくる理由が今のところ無い。
経路の判定をどこに置くか
「Mac だともう A で行ってしまいませんか」と聞いた。 そのうえで「ソースコード上これが Mac の挙動だっていうのは多分分かるんですよね」とも聞いている。
実装は OS で分岐させていない。 見ているのは、rclone に該当のリモートが登録されているかどうかだけだ。 クローンしただけの環境にはその設定が来ないので、Mac では自動的に wrangler 側へ倒れる。 判定が「Mac かどうか」ではなく「設定があるかどうか」なので、母艦側の設定が将来消えても同じ道を通る。
経路を選ぶところは純粋関数に切り出させて、単体テストを付けた。 既存のテストは今回の変更で壊れるので、元の意図を保ったまま新しい形に追従させている。 10件通ったあと、実環境で2枚だけ再送して、実際に wrangler の経路が選ばれることを確認した。 全体では46件通っている。
この挙動はプロジェクトのドキュメントにも残させた。 次に別のマシンでクローンしたとき、先にログインが要ると分かればいい。
コミットで出てきた、もう一つの移行漏れ
終わったらコミットしてプッシュまで、と頼んでいた。 そこで、Mac への移行漏れがもう1件出た。
このマシンには git のユーザー情報が設定されていなかった。 コミット自体は通ったのだが、ホスト名から組み立てられた実在しないメールアドレスが記録されていた。 過去のコミットに合わせて直させて、あらためてプッシュしている。
移したときに落ちるもの
- 面倒だと感じた作業は、手順を教わる前に「やらずに済む道があるか」を聞いたほうが早い。今回はそれでトークンの発行が丸ごと消えた
- 筋の通った推測ほど、確かめずに事実として持ち歩いてしまう。「権限が広すぎるから避けた」は、自分の中では最後まで筋が通っていた
- マシンを移したときに落ちるのは、リポジトリに入らないもの。書き込み用の認証、git のユーザー情報、ローカルにしかない設定ファイル。どれも動いているうちは見えない