Getting around Permission Denied when running ChefSpec

You may find that when running ChefSpec on your Chef cookbook, you may hit an error such as the following, spouting Permission denied:
5) cookbook-spectat::piwik When attributes are set downloads the piwik zip from attribute
Failure/Error:
runner = ChefSpec::ServerRunner.new(platform: 'debian', version: '8.7') do |node|
node.automatic['piwik']['artefact_url'] = 'https://piwik/1.2.3.zip'
end
Errno::EACCES:
Permission denied @ rb_sysopen - /opt/chefdk/embedded/lib/ruby/gems/2.3.0/gems/fauxhai-3.10.0/lib/fauxhai/platforms/debian/8.7.json
# ./spec/unit/recipes/piwik_spec.rb:12:in `new'
# ./spec/unit/recipes/piwik_spec.rb:12:in `block (3 levels) in <top (required)>'
# ./spec/unit/recipes/piwik_spec.rb:51:in `block (3 levels) in <top (required)>'
I've previously hit the issue when using the following Chef-DK version:
$ chef -v
Chef Development Kit Version: 1.2.22
chef-client version: 12.18.31
delivery version: master (0b746cafed65a9ea1a79de3cc546e7922de9187c)
berks version: 5.6.0
kitchen version: 1.15.0
However, this issue could occur at any point in time, with any Chef-DK version, and is due to how the Fauxhai gem works.
After investigating, I found that there actually wasn't a platform with that version on my machine:
$ ls -al /opt/chefdk/embedded/lib/ruby/gems/2.3.0/gems/fauxhai-3.10.0/lib/fauxhai/platforms/debian/
total 376
drwxr-xr-x 1 root root 322 Aug 5 21:10 .
drwxr-xr-x 1 root root 326 Aug 5 21:10 ..
-rw-r--r-- 1 root root 7128 Feb 2 2017 6.0.5.json
-rw-r--r-- 1 root root 14769 Feb 2 2017 7.0.json
-rw-r--r-- 1 root root 15855 Feb 2 2017 7.10.json
-rw-r--r-- 1 root root 16254 Feb 2 2017 7.11.json
-rw-r--r-- 1 root root 14769 Feb 2 2017 7.1.json
-rw-r--r-- 1 root root 9082 Feb 2 2017 7.2.json
-rw-r--r-- 1 root root 9539 Feb 2 2017 7.4.json
-rw-r--r-- 1 root root 91931 Feb 2 2017 7.5.json
-rw-r--r-- 1 root root 14691 Feb 2 2017 7.6.json
-rw-r--r-- 1 root root 15812 Feb 2 2017 7.7.json
-rw-r--r-- 1 root root 15824 Feb 2 2017 7.8.json
-rw-r--r-- 1 root root 16541 Feb 2 2017 7.9.json
-rw-r--r-- 1 root root 16576 Feb 2 2017 8.0.json
-rw-r--r-- 1 root root 16575 Feb 2 2017 8.1.json
-rw-r--r-- 1 root root 18542 Feb 2 2017 8.2.json
-rw-r--r-- 1 root root 18477 Feb 2 2017 8.4.json
-rw-r--r-- 1 root root 17951 Feb 2 2017 8.5.json
-rw-r--r-- 1 root root 17944 Feb 2 2017 8.6.json
drwxr-xr-x 1 root root 16 Aug 5 21:10 jessie
drwxr-xr-x 1 root root 16 Aug 5 21:10 stretch
As we can see here, there actually isn't an 8.7.json file there. But that doesn't explain why we'd be getting an EACCES instead of a ENOENT, as the file doesn't exist.
By delving into the source of Fauxhai, I found that when Fauxhai detects you're trying to converge on a platform it doesn't have, it'll try and download it. This means that it'll be trying to save it into the directory mentioned. As it's executing as my user, jamie, it won't have write access, as the user and group of that folder is root. So that explains why we're now hitting an EACCES - it's downloaded the file, but can't actually write it!
In order to fix this, we can perform one of a two sensible options:
sudo chown -R $USER /opt/chefdk/embedded/lib/ruby/gems/2.3.0/gems/fauxhai-3.10.0/lib/fauxhai/platforms/- Make the current user owner of the folder
sudo chgrp -R sudo /opt/chefdk/embedded/lib/ruby/gems/2.3.0/gems/fauxhai-3.10.0/lib/fauxhai/platforms/ && sudo chmod -R g+w /opt/chefdk/embedded/lib/ruby/gems/2.3.0/gems/fauxhai-3.10.0/lib/fauxhai/platforms/- Make the
sudogroup owners of the folder - And then give them the access to actually write changes
- Make the
With this done, next time we need to use a platform we don't have locally, Fauxhai will be able to write to the directory and will be able to spend a moment downloading the file(s) at the start of the test run.