Recurring Vagrant error: operation not permitted o

2019-05-04 23:33发布

问题:

I have a vagrant box with chef provisioner. Everything works fine except when there are operation on NFS resources. For example, I have the following synced folders:

"host_path": "/Users/User/devbox/vdd/data",
        "guest_path": "/var/www",
        "type": "nfs"

And in the vagrant file:

 # Synced Folders.
    config_json["vm"]["synced_folders"].each do |folder|
      case folder["type"]
      when "nfs"
        config.vm.synced_folder folder["host_path"], folder["guest_path"], type: "nfs"
        # This uses uid and gid of the user that started vagrant.
        config.nfs.map_uid = Process.uid
        config.nfs.map_gid = Process.gid

and I also have a chef recipe that executes a create action on an nfs resource:

directory "/var/www" do
  owner "vagrant"
  group "vagrant"
end

However, I keep getting the following error:

 default: Error executing action `create` on resource 'directory[/var/www]'
==> default: ================================================================================
==> default: 
==> default: 
==> default: Errno::EPERM
==> default: ------------
==> default: Operation not permitted - /var/www
==> default: 
==> default: 
==> default: Resource Declaration:
==> default: ---------------------
==> default: # In /tmp/vagrant-chef-3/chef-solo-2/cookbooks/vdd/recipes/apache.rb
==> default: 
==> default:   1: directory "/var/www" do
==> default:   2:   owner "vagrant"
==> default:   3:   group "vagrant"
==> default:   4: end
==> default:   5: 
==> default: 
==> default: 
==> default: 
==> default: 
==> default: Compiled Resource:

The only way to get rid of the problem (and keep the nfs) is by the following:

  1. Change nfs to default.

  2. run vagrant reload --provision

  3. change default back to nfs

  4. run vagrant reload

I have search and tried various suggested solution but nothing worked for me thus far.

回答1:

The Operation not permitted problem is common with a lot of questions asked on StackOverflow, and in about every case I looked at, it's because the virtual machine (Vagrant box) is trying to do file permissions operations (chmod, chown, chgrp, etc.) in a directory that is linked (via NFS or something else) to a filesystem on the host OS (your main computer). I don't want to bore you with the details, but this will throw an error for some of the people, some of the time; and be no problem for other people, other times. Your workaround in the comments illustrates this point!

If you're one of those affected by this problem, you have to make sure that your file shares are not needed as anything other than a read-only file structure in the guest OS; and anything that needs to change or write to those files, such as php composer.phar install (or other things that change/set up/write stuff) should take place and be executed directly on the host computer.

As a final note, Vagrant boxes (virtual machines) are meant to be disposable and destroyable on a moment's notice; and the fact that you're running code from the virtual machine to cause files that are probably permanently needed as part of your project defies this strategy at face value.

Alternate Solution:

Alternately, if you need to run code in the virtualized environment (the Vagrant box, if you will) which needs unfettered access to the permissions capabilities of that guest OS, simply do so in a location of its directory tree which is untouched by the local-to-guest "folder source" to "folder target" mapping. You can tell which folders are in this range with the mount command from the Vagrant box, if it's Linux-based.



回答2:

this is more of an important comment than an answer. in my vagrant configuration I 'accidentally (misunderstanding-ly)' ran $ sudo vagrant up before (correctly running $ vagrant destroy dev- this then made some local (host) fileshare changes as # root, when I re-ran $ vagrant up the new couldn't use the folders # root had made"vagrant up" (even though I had no more vm's)

^
|
hard to explain easy to actually understand

TL;DR if you use sudo with vagrant you need to manually remove/chown residual changes on the host as NOT sudo



回答3:

I was able to fix this issue by telling vagrant to mount the nfs resource after the provisioning by passing the after: :provision, option. Here is the line of code in my vagrantfile:

config.bindfs.bind_folder "/var/nfs-#{i}", folder["guest_path"], after: :provision, perms: "u=rwX:g=rwX:o=rD", o: 'nonempty'