Reputation: 190
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
Upvotes: 10
Views: 10595
Reputation: 12427
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
Upvotes: 2
Reputation: 190
Update:
To fix this issue I used the solution from @mahatmanich listed here
https://stackoverflow.com/questions/31857365/rails-generate-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.
Upvotes: 9