くりにっき

フルスタックキュアエンジニアです

vagantでgem名とrequireする名前が異なるgemを使う時には注意が必要

タイトルが全て

経緯

https://hub.docker.com/r/sue445/vagrant-aws/ っていうDockerイメージをメンテしてて*1Vagrant 2.2.6が出たタイミングでDockerイメージのビルドがコケるようになりました

https://app.circleci.com/jobs/github/sue445/dockerfile-vagrant-aws/494

Installing the 'vagrant-serverspec' plugin. This can take a few minutes...
Vagrant failed to properly resolve required dependencies. These
errors can commonly be caused by misconfigured plugin installations
or transient network issues. The reported error is:

activesupport requires Ruby version >= 2.5.0.
The command '/bin/sh -c vagrant plugin install vagrant-aws  && vagrant plugin install vagrant-serverspec' returned a non-zero code: 1
Exited with code 1

ビルドコケてる原因はいたってシンプル*2でそれ自体は一瞬で直せました。

github.com

+# FIXME: Remove following when vagrant embed ruby is updated to 2.5+
+#        (vagrant embed ruby is 2.4.9, but activesupport 6.0+ requires ruby 2.5+)
+RUN vagrant plugin install activesupport --plugin-version 5.2.3
+
 RUN vagrant plugin install vagrant-aws \
  && vagrant plugin install vagrant-serverspec

誰だってそーする、俺もそーする。

docker buildも成功してvagrantのコマンドもCI上で一通り叩けることも確認してたんですが*3、実際に使おうとすると下記のようなエラーになってちょっとハマってました

root@b9657e1e1d4a:/# vagrant up
Vagrant failed to initialize at a very early stage:

The plugins failed to load properly. The error message given is
shown below.

cannot load such file -- activesupport

原因

vagrantのソース内の実装までは見つけられてないですが、vagrant plugin install でインストールしたgemは vagrant up などのコマンド実行時に自動的にgem名でrequireされているのが原因でした。(activesupportrequire する時は active_support になるのでエラーになってた)

requireする名前を明示的に指定する方法がないかなと思って探したら vagrant plugin install--entry-point があって、それを使うことで解決できました。

github.com

 # FIXME: Remove following when vagrant embed ruby is updated to 2.5+
 #        (vagrant embed ruby is 2.4.9, but activesupport 6.0+ requires ruby 2.5+)
-RUN vagrant plugin install activesupport --plugin-version 5.2.3
+RUN vagrant plugin install activesupport --plugin-version 5.2.3 --entry-point active_support

*1:vagrant-awsのインストールに数分かかるのでCI用にDockerイメージを作ってる

*2:Dockerイメージにvagrant-awsと一緒についでにvagrant-serverspecをインストールしていて、vagrant-serverspecの依存にactivesupportがいて、activesupport v6がリリースされたタイミングで最新版がRuby 2.5以降必須(vagrantに添付されてるRubyのバージョンが2.4.9)になったのが原因

*3:https://github.com/sue445/dockerfile-vagrant-aws/blob/2.2.6/.circleci/config.yml#L58-L61