BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【Rspec・Serverspec】「NoMethodError: private method `select' called for nil:NilClass」を解決する!

はじめに


こんにちは!
株式会社BFT名古屋支店・インフラ女子(?)のやまぐちです。

Windowsの作業PCで開発を進めて早一カ月。開発の環境はLinuxWindowsのとあるフォルダをマウントし、その中の開発資材をGit管理しています。

全体の構成は以下の図の通り。GitのリモートリポジトリにはGCPのCloud Source Repositoriesを使っています。

そんなとき、同じコンテナ、同じ資材を使っているのに私には発生しないエラーが他のメンバーで発生しました。

本日はこちらのエラーの解決について記事を書きます。

「NoMethodError: private method `select' called for nil:NilClass」を解決する!


前提条件

基本的にOSやソフトウェアのバージョンというより、WindowsでGit管理しているフォルダをLinux側でマウント」している時に発生します。

  • Windows
    • Windows 11 Pro, 22H2, OSビルド22621.1265
  • コンテナ
  • Sourcetree
    • version 3.4.10

エラー状況&解決方法

「rake -T」コマンドを実行した際に以下のエラーが表示されました。

[ansibleuser@4177191b7314 src]$ rake -T
rake aborted!
NoMethodError: private method `select' called for nil:NilClass

    res["hosts_childrens"] = dyn_inv.select do |property, value|
                                    ^^^^^^^
/home/ansibleuser/work/ansible/src/rakefile:six:in `<top (required)>'
(See full trace by running task with --trace)

このコンテナではAnsibleとServerspecを連携させる「ansible_spec」を利用し、AsnibleのPlaybookとServerspecのテストを開発しています。「.ansiblespec」ファイルでは読み込むAnsibleのPlaybookとインベントリを指定しており、ここでインベントリとして記載しているhostsに実行権限が付いていることが原因のようです。

[ansibleuser@4177191b7314 src]$ ls -l
total 5
-rwxrwxrwx 1 root root 1923 Feb 22 06:25 Rakefile
-rwxrwxrwx 1 root root  407 Feb 22 06:25 authorized_keys
-rwxrwxrwx 1 root root   44 Feb 22 06:25 hosts ← ★ココ!
drwxrwxrwx 1 root root  512 Feb 22 06:25 roles
-rwxrwxrwx 1 root root  492 Feb 22 06:25 site.yml
drwxrwxrwx 1 root root  512 Feb 22 06:25 spec

このroot:rootのフル権限ついているのを見て驚きました。私の環境とは違うからです。マウントされるWindowsフォルダの、Linuxから見える権限・所有者情報は、SourcetreeでGitのリモートリポジトリにpushしても連携されないことに気づきました。

まずは解決すべく、hostsから実行権限を取り除きます。

[ansibleuser@4177191b7314 src]$ sudo chmod 644 hosts
[ansibleuser@4177191b7314 src]$ 
[ansibleuser@4177191b7314 src]$ ls -l
total 5
-rwxrwxrwx 1 root root 1923 Feb 22 06:25 Rakefile
-rwxrwxrwx 1 root root  407 Feb 22 06:25 authorized_keys
-rw-r--r-- 1 root root   44 Feb 22 06:25 hosts
drwxrwxrwx 1 root root  512 Feb 22 06:25 roles
-rwxrwxrwx 1 root root  492 Feb 22 06:25 site.yml
drwxrwxrwx 1 root root  512 Feb 22 06:25 spec
[ansibleuser@4177191b7314 src]$ 

それではもう一度「rake -T」コマンドを実行します。

[ansibleuser@4177191b7314 src]$ rake -T
rake all                                 # Run serverspec to all test
rake serverspec:Apache_set_OS            # Run serverspec for Apache_set_OS
rake serverspec:Apache_set_httpdconf     # Run serverspec for Apache_set_httpdconf
rake serverspec:OS_Copy_functions        # Run serverspec for OS_Copy_functions
rake serverspec:OS_Set_hostname          # Run serverspec for OS_Set_hostname
rake serverspec:OS_set_userlimit_all     # Run serverspec for OS_set_userlimit_all
rake serverspec:OS_set_userlimit_apache  # Run serverspec for OS_set_userlimit_apache
[ansibleuser@4177191b7314 src]$ 

問題なく「site.yml」に記載されているロール単位で実行できるServerspecの一覧が表示されました。

わかったこと

.gitフォルダ配下に「config」ファイルがあり、そのパラメータに「filemode」があります。開くと「false」になっていました。

[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
[remote "origin"]
    url = ssh://XXX@source.developers.google.com:2022/pXXX/r/ansible
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[user]
    name = XXX@XXX
    email = XXX@XXX

このパラメータを「true」にすることでパーミッションの変更も検知してpushしてくれるようです。

終わりに


もっとわかりやすいエラー文にしてほしい~!!!!と叫びたいところですが、新しいことをすると新しいエラーにぶつかり、それを機にいろいろな仕様を知るキッカケになって嬉しいですね。

以上、ここまで読んでいただき、ありがとうございました~ ^ ^