How to fix "Function not implemented - Failed to initialize inotify (Errno::ENOSYS)" in rails
Asked Answered
F

2

9

So I'm running the new Apple M1 Pro chipset, and the original M1 chip on another machine, and when I attempt to create new RSpec tests in ruby I get the following error.

Function not implemented - Failed to initialize inotify (Errno::ENOSYS)

the full stack dump looks like this

/var/lib/gems/2.7.0/gems/rb-inotify-0.10.1/lib/rb-inotify/notifier.rb:69:in `initialize': Function not implemented - Failed to initialize inotify (Errno::ENOSYS)
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/adapter/linux.rb:31:in `new'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/adapter/linux.rb:31:in `_configure'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/adapter/base.rb:45:in `block in configure'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/adapter/base.rb:40:in `each'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/adapter/base.rb:40:in `configure'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/adapter/base.rb:63:in `start'
        from /usr/lib/ruby/2.7.0/forwardable.rb:235:in `start'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/listener.rb:68:in `block in <class:Listener>'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/fsm.rb:121:in `instance_eval'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/fsm.rb:121:in `call'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/fsm.rb:91:in `transition_with_callbacks!'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/fsm.rb:57:in `transition'
        from /var/lib/gems/2.7.0/gems/listen-3.1.5/lib/listen/listener.rb:91:in `start'
        from /var/lib/gems/2.7.0/gems/spring-watcher-listen-2.0.1/lib/spring/watcher/listen.rb:27:in `start'
        from /var/lib/gems/2.7.0/gems/spring-2.1.1/lib/spring/application.rb:80:in `start_watcher'
        from /var/lib/gems/2.7.0/gems/spring-2.1.1/lib/spring/application.rb:89:in `preload'
        from /var/lib/gems/2.7.0/gems/spring-2.1.1/lib/spring/application.rb:157:in `serve'
        from /var/lib/gems/2.7.0/gems/spring-2.1.1/lib/spring/application.rb:145:in `block in run'
        from /var/lib/gems/2.7.0/gems/spring-2.1.1/lib/spring/application.rb:139:in `loop'
        from /var/lib/gems/2.7.0/gems/spring-2.1.1/lib/spring/application.rb:139:in `run'
        from /var/lib/gems/2.7.0/gems/spring-2.1.1/lib/spring/application/boot.rb:19:in `<top (required)>'
        from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
        from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
        from -e:1:in `<main>'

rails is running from a docker container, and I have tried following the solution that is listed below but not such luck. I'm fairly new to ruby and rails so any help would be greatly appreciated!

https://github.com/evilmartians/terraforming-rails/issues/34

Fetching answered 29/10, 2021 at 18:7 Comment(0)
F
8

Update: To fix this issue I used the solution from @mahatmanich listed here https://mcmap.net/q/258933/-39-rails-generate-39-commands-hang-when-trying-to-create-a-model'

Essentially, we need to delete the bin directory and then re-create it using rake app:update:bin

Since rails 5 some 'rake' commands are encapsulated within the 'rails' command. However when one deletes 'bin/' directory one is also removeing the 'rails' command itself, thus one needs to go back to 'rake' for the reset since 'rails' is not available any longer but 'rake' still is.

Fetching answered 31/10, 2021 at 17:41 Comment(1)
This is the only thing that worked for me. Thank you for this!Sonya
S
2

Problem

The error message is complaining that the inotify dependency of the underlying system failed to be invoked (initialized). The dependency is likely not present in the system, where the system here was reported to be a docker container.

To provide the inotify API, you can specify an OS/architecture that is compatible with the Apple M1 chip.

Failure Repro:

Using a simple script to invoke the inotify API with Ruby:

file_watcher.rb

notifier = INotify::Notifier.new

notifier.watch('./test/', :create) { |event|
    puts "#{event.name} created in ./test/ directory!"
}

FileUtils.rm_f('./test/new_file.txt')
File.new('./test/new_file.txt', 'w')

notifier.process

Without the --platform specified (which defaults to linux/amd64):

% docker run --rm -it -v "$(pwd):/test" ruby:2.7.2 bash -c "gem install rb-inotify && ls test/ && ruby -r rb-inotify -r fileutils test/file_watcher.rb"

Output

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
Fetching rb-inotify-0.10.1.gem
Fetching ffi-1.15.5.gem
Building native extensions. This could take a while...
Successfully installed ffi-1.15.5
Successfully installed rb-inotify-0.10.1
2 gems installed
Dockerfile  file_watcher.rb
Traceback (most recent call last):
    2: from test/file_watcher.rb:1:in `<main>'
    1: from test/file_watcher.rb:1:in `new'
/usr/local/bundle/gems/rb-inotify-0.10.1/lib/rb-inotify/notifier.rb:69:in `initialize': Function not implemented - Failed to initialize inotify (Errno::ENOSYS)

Solution:

To provide the inotify API, you can specify an OS/architecture that is compatible with the Apple M1 chip.

Solution Demo:

Use the same file_watcher.rb script above, and provide and OS/architecture that will satisfy the inotify dependency.

With the --platform specified (a compatible arch of linux/arm64/v8):

% docker run --rm -it --platform linux/arm64/v8 -v "$(pwd):/test" ruby:2.7.2 bash -c "gem install rb-inotify && ls test/ && ruby -r rb-inotify -r fileutils test/file_watcher.rb"

Output

Fetching rb-inotify-0.10.1.gem
Fetching ffi-1.15.5.gem
Building native extensions. This could take a while...
Successfully installed ffi-1.15.5
Successfully installed rb-inotify-0.10.1
2 gems installed
Dockerfile  file_watcher.rb  new_file.txt
new_file.txt created in ./test/ directory!

You can provide the platform flag in a Dockerfile or docker-compose file, as well as with the docker run CLI as demonstrate above.

References:

https://github.com/docker/for-mac/issues/6174#issuecomment-1048928733

https://github.com/docker/for-mac/issues/5321#issuecomment-823637003

Spiracle answered 6/1, 2023 at 23:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.