Amazon Linuxでのnginx rebuild とエラーデバッグ時の思考回路
謎のプレッシャーがすごい。(挨拶)
こんにちは。tshibaと申します。そろそろ隠居を考えている今日この頃ですが頑張っていきたいと思います。
新しい技術のやってみた系は次の歴史をつくる若者たちに任せて、私は泥臭いトラブルシューティングについて書きたいと思います。
答えをざっと書いてしまうと数行で終わってしまってつまらないので、エラーを見たときにどう思ったかや、問題解決までの私の思考も書きたいと思います。
検証環境
本記事の検証環境は以下の通りです
- Amazon Linux 2
- nginx-1.20.0-2.amzn2.0.4
Amazon Linuxでのnginx rebuild
ある日、私はとあるシステムをオンプレミス環境からAWSへ移行するために検証をしていました。
そのシステムは単純な nginx
と php
で構成されており、楽勝やん!引退間近でもこれくらいできるぞ!と調子に乗っていました。
検証用の EC2 を 1台起動し、慣れた手付きでコマンド叩きました
$ sudo amazon-linux-extras install nginx $ #(旧サーバーからconfigを移す) $ sudo nginx -t
結果
$ sudo nginx -t nginx: [emerg] unknown directive set_from_accept_language in /etc/nginx/nginx.conf:xx nginx: configuration file /etc/nginx/nginx.conf test failed $
えぇ… set_from_accept_language
ってなんだよ…
- とりあえず
nginx set_from_accept_language
でぐぐる - 一番上に公式のページがひっかかる。ラッキー
- localeを取得するモジュールか。はいはい。
- インストールの仕方を調べる
Installation
1. Download the module source from Github
2. Unpack, and then compile NGINX with:$ ./configure –add-module=path/to/nginx_accept_language_module
出典: Accetp Language モジュール
ふむ…ソースから入れ直さないといけないのか…
ソースファイル
から入れるのは管理上良くないので、rebuildしてパッケージを作り直す戦略でいきます。
でもその前に…一旦心を落ち着かせるためにお菓子を食べる!
nginx を rebuld するための準備
お菓子を食べたら rebuild のための準備します。
$ sudo yum -y install git.x86_64 $ sudo yum -y install rpmdevtools // rpmbuild をインストール $ $ # 以下は必須ではないけど、このユーザーつくると rpmbuild実行時の warning がでなくなる $ sudo useradd -s /sbin/nologin mockbuild $ sudo useradd -s /sbin/nologin mock
必要なパッケージをインストールして
$ rpmdev-setuptree
を実行します。 よく rpmbuild を紹介しているブログ等をみると
$ mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
として、rpmbuild のためのディレクトリを作成する方法を紹介していますが、 rpmdev-setuptree
を打つと上記のコマンドと同じことをしてくれます。まぁ別に大したことはしてません。どっちでもいいです。
続いて追加する nginx のモジュールと nginx の src.rpm
をダウンロードします。
$ git clone https://github.com/giom/nginx_accept_language_module.git /tmp/nginx_accept_language_module
$ yumdownloader --source nginx
ダウンロードした src.rpm
をインストールします。
$ rpm -ivh nginx-1.20.0-2.amzn2.0.4.src.rpm
問題なくインストールできていれば ~/rpmbuild/SPECS
配下に nginx.spec
ファイルが生成されています。
nginx_accept_language_module
を組み込むために spec
ファイルを編集します
$ vi rpmbuild/SPECS/nginx.spec
nginx.spec
の build
セクションで ./configure
を定義しているところがあるので
--add-module=/tmp/nginx_accept_language_module \
の一行を追記します。これで rebuild の準備が整いました。
エラーその1 (雑魚戦)
rpmbuild
コマンドを実行して rpm
を作成します。
$ rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec
$ rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec エラー: ビルド依存性の失敗: gcc は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています gperftools-devel は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています openssl11-devel は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています pcre-devel は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています zlib-devel は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています GeoIP-devel は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています gd-devel は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています perl-devel は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています perl-generators は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています perl(ExtUtils::Embed) は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています libxslt-devel は nginx-1:1.20.0-2.amzn2.0.4.x86_64 に必要とされています $
- うん…いいね(謎
- 依存するパッケージが足りないだけだね
- 基本
yum search [pkg]
->yum install [pkg]
を繰り返すだけでok
$ sudo yum -y install gcc.x86_64 $ sudo yum -y install gperftools-devel pcre-devel zlib-devel gd-devel GeoIP-devel perl-ExtUtils-Embed libxslt-devel $ sudo yum -y install openssl11-devel.x86_64
順調… あとは perl-generators
だけ…
$ yum search perl-generators 読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd 警告: 一致するものが見つかりません: perl-generators No matches found $
- ない!
- え…なぜない…
- “amazon linux perl-generators” でぐぐる
- 一番上は CentOS用のパッケージ だね
- 却下
- ぐぐった結果の2つ目あたりは Amazon Linux2022用のパッケージ のリリースノート…
- バージョンは2022じゃないけど… All packages って書いてある…
perl-generators
でページ内検索すると……ある!あるね- え、あるの…
- ある……あるけど yum にはでてこない…ないけどある………そっか、
epel
だ(探偵が閃くエフェクト
$ sudo amazon-linux-extras install epel -y $ yum search perl-generators 読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd 218 packages excluded due to repository priority protections ===== N/S matched: perl-generators ======================= perl-generators.noarch : RPM Perl dependencies generators Name and summary matches only, use "search all" for everything. $
- あぁあったあった
- 余裕やん
$ sudo yum install -y perl-generators
perl-generators
をインストールして もう一回 rpmbuild
$ rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec 実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.v7hoki + umask 022 + cd /home/ec2-user/rpmbuild/BUILD + cat /home/ec2-user/rpmbuild/SOURCES/maxim.key /home/ec2-user/rpmbuild/SOURCES/mdounin.key /home/ec2-user/rpmbuild/SOURCES/sb.key + /usr/lib/rpm/redhat/gpgverify --keyring=/home/ec2-user/rpmbuild/BUILD/nginx.gpg --signature=/home/ec2-user/rpmbuild/SOURCES/nginx-1.20.0.tar.gz.asc --data=/home/ec2-user/rpmbuild/SOURCES/nginx-1.20.0.tar.gz /var/tmp/rpm-tmp.v7hoki: line 30: /usr/lib/rpm/redhat/gpgverify: No such file or directory エラー: /var/tmp/rpm-tmp.v7hoki の不正な終了ステータス (%prep) RPM ビルドのエラー: /var/tmp/rpm-tmp.v7hoki の不正な終了ステータス (%prep) $
- メゲるわ……
- コーヒー入れよ…
エラーその2 (ボス戦)
コーヒーを飲んで心を落ち着かせた後にエラーを見直してみる。
- この手のエラーの原因は
ファイルが読み込めていない
かパーミッションエラー
が9割(偏見) - なのでキーワードとして
No such file or directory
やPermission denied
を探す
今回のエラーは
/usr/lib/rpm/redhat/gpgverify: No such file or directory
ここだね
- やばい…嫌な予感しかしない
/usr/lib/rpm/redhat
なんて特殊なディレクトリは普段使わない
- “rpmbuild gpgverify” でぐぐってみる
- パッとみ有効な情報がない!
- なんかハマりそうな気がしてきた
- 社内の slack で全文検索してみる
- ない!
- 社内のドキュメントシステムを全文検索してみる
- ない!
- どこにもノウハウがない情報なら ブログのネタになるな とか呑気なことを考える
- 心を落ち着かせるためにベットでゴロゴロする
- リモートワークの醍醐味
原因の特定
(10年後)
エラーになってる spec
ファイルを改めて見てみる
# Combine all keys from upstream into one file cat %{S:2} %{S:3} %{S:4} > %{_builddir}/%{name}.gpg %{gpgverify} --keyring=%{_builddir}/%{name}.gpg --signature=%{SOURCE1} --data=%{SOURCE0}
- ふむ…ここの
gpgverify
がない verify
だから鍵の検証をしてるだけだと思うけど…パッとみ何やってるかわからないなぁ- ………わからないものをいくら考えても仕方ない。ここを調べるのは後だ
もう一度 今度は “gpgverify” だけでぐぐってみる
- fedora の pull-req が引っかかる
- あ…
- fedoraなのが若干気になるけど…issueになってるエラー内容は似てる
Files Changed
をみるとgpgverify
を追加してる!- あ!これただのシェルスクリプトだ
- ここでやっと中身がわかった
- 最悪これコピーしたら良さそう
- ちょっと気持ちが楽になる - そのまま
main
ブランチ見てみると…gpgverifyがあるね
-History
みてみるとlast commit
が2年前(2022年現在)
- (これだけ更新されてないなら)ますますもうこれでいいんじゃないかって思いはじめる
Amazon Linuxにはこの redhat-rpm-config
ってのがあるのか調べる
$ yum search redhat-rpm-config 読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd 218 packages excluded due to repository priority protections ========== 一致: redhat-rpm-config =============================== system-rpm-config.noarch : Amazon Linux specific rpm configuration files $
あっt…いや、ちがう! system-rpm-config.noarch
だねこれ。
$ rpm -qa | grep system-rpm-config system-rpm-config-9.1.0-76.amzn2.0.13.noarch $
すでにインストール済だった。 gpgverifyが含まれているか調べる
$ rpm -ql system-rpm-config-9.1.0-76.amzn2.0.13.noarch | grep gpgverify $
いや、gpgverify
はないよね。ないんだよね。
てことは
OS | rpm configuration files | gpgverify |
---|---|---|
fedora | redhat-rpm-config | 含まれる |
Amazon Linux2 | system-rpm-config | 含まれない |
ていう構図になってるということですね。とりあえず エラーになる原因がわかった
gpgverifyを入れてエラーを解消する
あとはなんとかして gpgverify をインストールできないか…だけを気にする。
でも この感じだと gpgverify
は 他のrpmで提供してそうだな…
- “gpgverify rpm” でぐぐる
- epel-rpm-macros なるもを見つける
Files
に/usr/lib/rpm/gpgverify
を見つける- これやん
- でもなんかパスが違う
- …………でもこれが
fedora
のと同じものならこれでいいか。どうせこれシェルスクリプトだし
epel-rpm-macros
をインストールする
$ sudo yum -y install epel-rpm-macros.noarch
- ふむ…gpgverify が
/usr/lib/rpm/gpgverify
に入った- fedoraのものと見比べると…
- なんか微妙に違うなw
- あ、でも差分はコメントアウトの部分だけだ
- よしこれでいこう!
cp
してもいいけど…後でわからなくなりそうだからシンボリックリンクしとこ(好み
$ sudo ln -s /usr/lib/rpm/gpgverify /usr/lib/rpm/redhat/gpgverify
うん、いいね…これで rpmbuild
をもう一回打つ
$ rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec 実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.SaUNUJ + umask 022 + cd /home/ec2-user/rpmbuild/BUILD + cat /home/ec2-user/rpmbuild/SOURCES/maxim.key /home/ec2-user/rpmbuild/SOURCES/mdounin.key /home/ec2-user/rpmbuild/SOURCES/sb.key + /usr/lib/rpm/redhat/gpgverify --keyring=/home/ec2-user/rpmbuild/BUILD/nginx.gpg --signature=/home/ec2-user/rpmbuild/SOURCES/nginx-1.20.0.tar.gz.asc --data=/home/ec2-user/rpmbuild/SOURCES/nginx-1.20.0.tar.gz gpgv: Signature made Tue Apr 20 14:39:52 2021 UTC using RSA key ID A1C052F8 gpgv: Good signature from "Maxim Dounin <mdounin@mdounin.ru>" ...(省略)... + cd /home/ec2-user/rpmbuild/BUILD + cd nginx-1.20.0 + /usr/bin/rm -rf /home/ec2-user/rpmbuild/BUILDROOT/nginx-1.20.0-2.amzn2.0.4.x86_64 + exit 0
できたあああああああああああああああああ
$ ls -1 rpmbuild/RPMS/x86_64/ nginx-1.20.0-2.amzn2.0.4.x86_64.rpm nginx-debuginfo-1.20.0-2.amzn2.0.4.x86_64.rpm nginx-mod-http-geoip-1.20.0-2.amzn2.0.4.x86_64.rpm nginx-mod-http-image-filter-1.20.0-2.amzn2.0.4.x86_64.rpm nginx-mod-http-perl-1.20.0-2.amzn2.0.4.x86_64.rpm nginx-mod-http-xslt-filter-1.20.0-2.amzn2.0.4.x86_64.rpm nginx-mod-mail-1.20.0-2.amzn2.0.4.x86_64.rpm nginx-mod-stream-1.20.0-2.amzn2.0.4.x86_64.rpm $
これだ…これがほしかったんや…
最後に今入ってるやつと入れ替えて終わり
$ sudo yum remove nginx $ sudo yum install -y ~/rpmbuild/RPMS/x86_64/nginx-1.20.0-2.amzn2.0.4.x86_64.rpm $ sudo cp -ip /etc/nginx/nginx.conf.rpmsave /etc/nginx/nginx.conf // removeしたときにbkが取られる $ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful $
できた!
事の顛末
落ち着いた後に少しだけ調査してみました。
gpgverify について
gpgverify
は一体何なのかなんですが、度々参照しているスクリプトの中身をみると
gpgverify is a wrapper around gpgv designed for easy and safe scripting.
と書かれており、 gpqv
のラッパーであることがわかります。
gpqv
は OpenPGP署名のチェックツールです。
gpgverify
内で実行されているコマンドは以下の通りですが、
# Decode any ASCII armor on the keyring. This is harmless if the keyring isn't # ASCII-armored. gpg2 --homedir="${workdir}" --yes --output="${workring}" --dearmor "${keyring}" check_status 'Decoding the keyring' $? # Verify the signature using the decoded keyring. gpgv2 --homedir="${workdir}" --keyring="${workring}" "${signature}" "${data}" check_status 'Signature verification' $?
gpg2
も gpgv2
も初めからインストールされているコマンドですので、gpgverify
はただの便利スクリプトであることがわかります。
ですので、シンボリックリンク貼っただけの今回の対応で問題ないでしょう。
(詳細はコメントアウトを参照)
おわりに
ぐぐっても答えがでてこないニッチな問題についてまとめてみました。
gpgverifyにお困りなニッチな人々の助けになれば幸いです。
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitter希望に満ちていた若者もアラフォーになりました。もうちょっとだけがんばります。
Recommends
こちらもおすすめ
-
gulp+babelでのフロントエンド開発について – 3. bootstrapのビルド
2015.12.18
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28
AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16