ククログ

株式会社クリアコード > ククログ > GitHub Actions上のUbuntuでAlmaLinuxの仮想マシンを動かすときの注意点

GitHub Actions上のUbuntuでAlmaLinuxの仮想マシンを動かすときの注意点

Mroongaのメンテナンスもしている堀本です。 今回はGitHub Actions上でAlmaLinuxの仮想マシンを作って何かする人向けの記事です。

Groongaとその関連プロダクト(PGroongaやMroongaなど)は、様々なOS向けにパッケージを提供しています。 提供するパッケージはGitHub Actions上でビルドしたり、テストしたりしています。 今回は、AlmaLinux向けのパッケージのテストをする環境を作る時に躓いた点があったので、その回避策を紹介しようと思います。

最初にどんな問題が発生したかを紹介し、次にどのように解決したかを紹介します。

では、まずどんな問題が発生したかを紹介します。 MroongaのCIでは、Ubuntu上にIncusをインストールし、それを使って仮想マシンを立ち上げることで AlmaLinuxの環境を用意していますが、この仮想マシンを起動するときに問題が発生しました。

仮想マシンから外部のネットワークに接続できない

MroongaのCIでは、AlmaLinuxの仮想マシンを起動後にdnf updateを実施しますが、このコマンドが失敗しGitHub Actionsの実行が中断されてしまいました。 具体的には以下のエラーが発生していました。

Errors during downloading metadata for repository 'baseos':
  - Curl error (6): Couldn't resolve host name for https://mirrors.almalinux.org/mirrorlist/8/baseos [Could not resolve host: mirrors.almalinux.org]
  - Curl error (6): Couldn't resolve host name for https://mirrors.almalinux.org/mirrorlist/8/baseos?countme=1 [Could not resolve host: mirrors.almalinux.org]
Error: Failed to download metadata for repo 'baseos': Cannot prepare internal mirrorlist: Curl error (6): Couldn't resolve host name for https://mirrors.almalinux.org/mirrorlist/8/baseos [Could not resolve host: mirrors.almalinux.org]

調査の結果、AlmaLinuxの仮想マシンを起動後に数秒待つと外部のネットワークに接続できることがわかりました。 原因は、仮想マシン起動直後にネットワーク関連の機能の初期化を実施していたからでした。 ネットワーク関連の機能の初期化が完了するまでは外部のネットワークに接続できず、dnf updateが失敗するという流れで問題が発生していました。

回避策

AlmaLinuxの仮想マシンを起動後に数秒待つと外部のネットワークに接続できるので、システムが動作可能になるまで待つことで問題は解決できるはずです。 以下では、どうやってシステムが動作可能になるまで待つようにしたのかを紹介します。

システムが動作可能になるまで待つのに最適なコマンドがあります。systemctl is-system-running --waitというコマンドです。 このコマンドを使うことで、システムが動作可能になるまで待つことができます。

AlmaLinux 9では、このコマンドを使うことで期待通り仮想マシン起動後に外部のネットワークに接続できるようになりました。 ところが、AlmaLinux 8では、systemctl is-system-running --waitが期待通り動作しませんでした。 このコマンドを使用してもシステムが動作可能になるまで待ってくれなかったのです。

原因は、AlmaLinux 8のsystemdのバージョンが古いからでした。 systemctl is-system-running --wait--waitをサポートしているのは、systemdのバージョン240以降ですが、 AlmaLinux 8のsystemdのバージョンは239だったのです。

AlmaLinux 8では、systemctl is-system-running --waitが期待通り動作しないことがわかったので、 対応として以下の2つを考えました。

  1. Almalinux 9はsystemctl is-system-running --waitを使い、AlmaLinux 8は固定の秒数sleepする。
  2. Almalinux 8も9も固定の秒数sleepする。

今回はコード内に分岐が増えるのを避けるため2の方法を選択しました。 sleepの秒数は実測値から設定しています。 実測したところおおよそ5秒程度で外部のネットワークに接続可能になることがわかったため、余裕を持って2倍の10秒としました。

実際のコードは、 https://github.com/mroonga/mroonga/blob/v14.12/.github/workflows/linux.yml#L300-L308 で確認できるので 興味のある方は参照してみてください。