Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature to mount folders post-provisioning? #936

Closed
tmotley opened this issue May 17, 2012 · 77 comments
Closed

Add feature to mount folders post-provisioning? #936

tmotley opened this issue May 17, 2012 · 77 comments

Comments

@tmotley
Copy link

tmotley commented May 17, 2012

I don't think this feature or config setting exists having perused the docs and support. My Vagrant file mounts shared folders, and assigns them a group and user ownership. However, if the case of a new box, the user and group I assign the mounted folder ownership do not exist until the chef provisioning is done on the box. I tried to control the order of provisioning and mounting, but the mounting is always attempted first, which obviously breaks if the provisioning has not occurred yet.

For example:

config.vm.define :dpils_slave_1, :primary => false do |cfg|
cfg.vm.forward_port 8080, 8081
#cfg.vm.network :hostonly, "1.1.1.11"
cfg.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["chef/cookbooks", "chef/site-cookbooks", "chef/site-cookbooks-tk"]
chef.roles_path = ["chef/roles-tk"]
chef.add_role "jboss"
# chef.log_level = :debug
end

cfg.vm.share_folder 'crx_node_2', '/foo/bar/dpils_repository/dpils_whq_02/crx', 'foo/bar/crx_node_2', :owner => "jboss", :group => "jboss", :create => true

end

Which gives this error on a clean vagrant load:

[dpils_slave_1] -- v-csr-4: /tmp/vagrant-chef-1/chef-solo-4/roles
[dpils_slave_1] -- v-csc-1: /tmp/vagrant-chef-1/chef-solo-1/cookbooks
[dpils_slave_1] -- v-csc-2: /tmp/vagrant-chef-1/chef-solo-2/cookbooks
[dpils_slave_1] -- v-csc-3: /tmp/vagrant-chef-1/chef-solo-3/cookbooks
[dpils_slave_1] -- crx_node_2: /nike/vault/dpils_repository/dpils_whq_02/crx
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

mount -t vboxsf -o uid=id -u jboss,gid=id -g jboss crx_node_2 /nike/vault/dpils_repository/dpils_whq_02/crx

@dominis
Copy link

dominis commented Jul 23, 2012

I've had the same problem, here is a workaround worked for me:

config.vm.share_folder "ganja", "/test", "/test"
config.vm.provision :shell do |shell|
  shell.inline = "sudo mount -t vboxsf -o uid=`id -u apache`,gid=`id -g apache` test /test"
end

@mitchellh
Copy link
Contributor

If you omit the guest path, it won't auto-mount. Also, the @dominis workaround is quite good. I think this is rare enough that this is satisfactory for now since this would require significant change. Sorry!

@jcushman
Copy link

jcushman commented Mar 2, 2014

+1 for this feature, if you ever reconsider. My use case is to mount a host folder under the mysql user, so I can keep the mysql data folder outside the VM.

@drpebcak
Copy link

drpebcak commented Mar 2, 2014

You can also mount a folder as a user who doesn't exist yet, if you use their uid.

@jcushman
Copy link

jcushman commented Mar 2, 2014

Thanks! The uid method is nice and clean:

  MYSQL_UID = 106
  MYSQL_GID = 111
  config.vm.synced_folder "local/path", "/mysql_data", owner: MYSQL_UID, group: MYSQL_GID

Then presumably I'd want to manually create the mysql user before any other provisioning, so the ID stays consistent regardless of changes to the build order.

@jess-sol
Copy link

+1, I'm going to have to disagree with you, @mitchellh, I run into this issue all the time.

This becomes a much bigger issue when you want to use NFS. NFS doesn't support auto-creating directories, so for example if I wanted to sync the directory www to /var/www/vhosts/site/httpdocs I'd first need to provision, then enable the nfs sync by manually editing the Vagrantfile, then reload the vagrant box. I can't think of another way to accomplish this (short of modifying the base box), am I missing something?

Do hope this gets reconsidered, I can definitely see the option :mount_after_provision => true being useful.

@ms-ati
Copy link

ms-ati commented Jul 26, 2014

👍 I like @ben-rosio idea for :mount_after_provision => true

In the meantime, I had been requiring a vagrant reload, and signaling that user creation had completed during provisioning by touch .vagrantprovision/user_created, and not mounting the directory until that existed.

I will try the @dominis workaround, so that only one vagrant up is required

@ghost
Copy link

ghost commented Aug 17, 2014

+1 for @ben-rosio 's :mount_after_provision => true suggestion. If I can set 'owner' and 'group' on a synced folder on a guest machine, then I need to be given the chance to create owner and group (and mount point, as well!). Otherwise it's necessary to use the non-existent UID/GID workaround that @drpebcak suggests (efficacious, yet cludgy).

@powellnathanj
Copy link

One of the big uses for synced_folder is to be able to operate on code on the host that is part of a directory structure on the guest. In the case of Puppet Enterprise this causes the installer to do weird things when it finds a directory structure already present.

@Ghoughpteighbteau
Copy link

I hit this issue as well. Deving a server applet for tomcat, would like to mount the webapps folder so I can do partial compiles from my dev environment, but I can't mount a webapps folder that doesn't exist. Doc's had no answers for me. This is a needed feature.

@delitescere
Copy link

I want to share my host user's ~/.ssh files as the VM vagrant user's ~/.ssh files. The simplest way to do this is to sync the host user's ~/.ssh directory. However, Vagrant needs ~/.ssh to create and manage an authorized_keys file.

A provisioning step I have is to set sshd to use another location for user authorized keys (e.g. /etc/ssh/authorized_keys/%u) and move the vagrant user's authorized_keys file to there (e.g. /etc/ssh/authroized_keys/vagrant). However, the authorized_keys file is destroyed by the folder sync before provisioning has a chance to move it.

@jess-sol
Copy link

Hey @delitescere, just a thought about how you might sidestep the issue in your specific usecase. I don't know if you've already looked at setting guest machine's ssh to enable ssh forward_agent.
You would need an ssh agent locally like Putty's pageant or Mac OS's Keychain (for Leopard and above), and to set config.ssh.forward_agent to true in your Vagrantfile.

After that, all your local ssh keys will be available on the vagrant box! You can even put the ssh.forward_agent config in your user Vagrantfile (located in ~/.vagrant.d/Vagrantfile) so it applies to all your vagrant instances.

@dreynolds
Copy link

@mitchellh Is there any chance you might reconsider this? There's been quite a number of +1s

@Ghoughpteighbteau
Copy link

Even a direct implementation of this feature isn't a requirement.

The +1's here only indicate a problem, that the owner of a folder might be someone who is only created after the provisioning step has happened.

If you compare and contrast a Dockerfile, you see why this isn't a problem for them, they can specify any order they please. Maybe that's the real bug here. Users need more control than the Vagrantfile is offering them.

@jess-sol
Copy link

jess-sol commented Mar 3, 2015

Another interesting solution would be to have sync folders be provisioning
steps, this way they can happen in any order necessary.
On Mar 3, 2015 11:29 AM, "Ghoughpteighbteau" notifications@github.com
wrote:

Even a direct implementation of this feature isn't a requirement.

The +1's here only indicate a problem, that the owner of a folder might be
someone who is only created after the provisioning step has happened.

If you compare and contrast a Dockerfile, you see why this isn't a problem
for them, they can specify any order they please. Maybe that's the real bug
here. Users need more control than the Vagrantfile is offering them.


Reply to this email directly or view it on GitHub
#936 (comment).

@Ghoughpteighbteau
Copy link

@ben-rosio well, that's the hack, right? Adding a post provisiong call in a shell script to mount external folders, and provide an unmounted shared folder at the start so that virtual box knows what to call it.

The problem is it's very non-obvious and strange (and personally I couldn't even get it to work, I ended up just taking advantage of the www-data)

@derek-adair
Copy link

@Ghoughpteighbteau -> nail_on_head.gif. Expecting a Vagrantfile to execute sequentially seems like a far more intuitive UX. I've not run into this yet, but i'm glad i checked this out b/c i'm sure at some point when i start playing with chef I may.

Although, i pre-provision my boxes w/ packer so I feel like this issue may largely avoided by that. It seems like any vagrant provisioning I will ever need will be any experimental packages and will not have any mounting issues. I'm sure i'm missing some edge cases...

Nice to have, but definitely not a show stopper IMHO.

@daithi-coombes
Copy link

I would consider this a bug/blocker from the standalone pov of vagrant and folder syncing. The way I would see it is that 100% of user's created by package installation - such as my jenkins user - are not able to work with vagrants sync_folder 100% of the time.

But whether its called a bug or enhancement etc - I'd love to see this issue re-opened

@pavelthq
Copy link

Mount synced folder (not all, but some exact) after provision is what I need. How to workaround this?

@Ghoughpteighbteau
Copy link

@AngeIII we've being using www-data as that user/group is often pre-existing in many distributions, and has reasonable security settings.

In some cases this is exactly what we need, in other cases it's a dirty hack.

Mount a third party folder with www-data as the owner, and give your application group access to www-data.

If that's a blocker for you, well then, this needs to be fixed :\

@tuupola
Copy link

tuupola commented Apr 16, 2015

+1 for this feature too. Currently can not do something like below because user and group apache does not exists before provisioning is run. Although as a workaround I can use guid and gid because they are consistent in CentOS.

config.vm.synced_folder "logs", "/vagrant/logs", owner: "apache", group: "apache"

@pavelthq
Copy link

My workaround for this:

config.vm.provider "virtualbox" do |v|
      v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
  end

And in provision.sh

rm -rf /srv/www/web-dev/content/plugins
rm -rf /srv/www/web-master/content/plugins
ln -ds /srv/www/plugins /srv/www/web-dev/content/plugins
ln -ds /srv/www/plugins /srv/www/web-master/content/plugins

Works only if vagrant is up with admin rights (Windows).

My idea is that:
WWW is shared folder
my provison.sh runs and check if
www/web-dev exists. if yes => git pull, else => git clone
mount in web-dev/plugins my second shared folder www/plugins.

Problem is that by using default config.vc.synced_folder it runs before provisioning and I get that www/web-dev/plugins exists and my check in provision.sh fails (so I get empty project with shared folder inside).

@davidski
Copy link

My use case is to have userapp specific data directories on the host available in the guest. The user accounts only exist after provisioning (chef). The hard wired non-existant uid/gid hack doesn't work under vagrant 1.7.2 and vagrant-vmware-workstation 3.2.6 - the mount step tries to do an id against the provided uid/gid, which fails.

There's over three years of comments asking for functionality to address this not-uncommon use case.

@masonmark
Copy link

+1 for @ben-rosio 's :mount_after_provision => true suggestion.

The comments on this issue prove that it is reasonably common to need to mount shared folders after provisioning, so that the user that is supposed to own them can be created first.

Furthermore, the workaround to use the UID/GID doesn't work with the VMWare provider, as @davidski points out.

We are using the VMWare provider and Ansible for provisioning, and the only workaround I could find for us was to configure the synced folder in the usual way:

config.vm.synced_folder "rollerball/", "/rollerball" # (in the Vagrantfile)

That way, it just gets mounted as owned by the vagrant user, and then add steps in our provisioning process to unmount the shared volume, and then mount it again it with the correct ownership:

sudo mount -t vmhgfs -o uid=`id -u rollerball`,gid=`id -g rollerball` .host:/-rollerball /rollerball

Not the end of the world, but not ideal either.

@delitescere
Copy link

I just want to take a moment to point out two things:

  1. all of us who would like this feature are empowered to contribute a solution,
  2. Mitchell does a great job and vagrant saves us all a load of time, so the ways to overcome this obstacle are kludgey but joyful.

@jdoss
Copy link

jdoss commented Feb 2, 2017

+1 to this issue.

Currently Fedora 25's rpcbind package no longer starts on boot and if we could provision before synced_folder runs, I could fix it with two shell commands. Instead I have to either wait for the package to be fixed, roll my own vagrant box image with the fix or let the NFS mount timeout, fix the issue and run the provision manually.

It is pretty clear based on the feedback in this issue that there are a handful of use cases for doing a provision before synced_folder.

@xophere
Copy link

xophere commented Mar 7, 2017

I was wondering if it would be possible for my to precreate my user? As far as I know my installers don't care if the mysql and apache user already exist. So if I could get vagrant to precreate them in the way that it is stuffing in virtual box tools before the mount this would be solved for me. This also create the best case scenario where the install dumps in the default stuff into the directories rather the having something dropped on top of that.

@xophere
Copy link

xophere commented Mar 7, 2017

So this is not ideal but sort of handles it if I do this with a wrapper.

https://github.com/oriceon/vagrant-virtual-machine-for-web-development/wiki/Repack-box-from-existing-one

But it forces me to hide the vagrant work in a wrapper script for the developer.

@mikenerone
Copy link

I have a solution to running something post-mounts that's been working for me. I'm using the "always" provisioning feature (I'm not sure when that was added):

Vagrant.configure('2') do |config|
    ...
    config.vm.provision :shell, path: './my_real_provisioning_script.sh'
    config.vm.provision :shell, run: 'always', path: './my_after_mounts_every_boot_script.sh'
    ...

I hope this helps someone out.

@cecilemuller
Copy link

cecilemuller commented Mar 21, 2017

Personally I was using this trick to detect first run in the Vagrantfile:

if File.exist?(".vagrant/machines/YOUR_BOX_ID/virtualbox/action_provision")
	#
	# Already provisioned, it's now safe to use "config.vm.synced_folder" statements
	# and additional scripts that require the users exist
	#
else
	#
	# Not yet provisioned, only run the script that creates the required users
	#
end

The one downside is that you have to do this once:

vagrant up
vagrant reload

Also, if you want the additional scripts run only once (like provision scripts are meant to), use vagrant reload --provision instead of just vagrant reload. Otherwise, the additional scripts need to use run:always mentioned in the previous comment.

@quixand
Copy link

quixand commented May 5, 2017

This is rubbish, please fix.

vagnerr added a commit to vagnerr/vagrant_recipes that referenced this issue Jul 5, 2017
@snfnwgi
Copy link

snfnwgi commented Sep 28, 2017

Vagrant attempted to execute the capability 'mount_nfs_folder'
on the detect guest OS 'windows', but the guest doesn't
support that capability. This capability is required for your
configuration of Vagrant. Please either reconfigure Vagrant to
avoid this capability or fix the issue by creating the capability.

@xophere
Copy link

xophere commented Sep 28, 2017 via email

@snfnwgi
Copy link

snfnwgi commented Sep 28, 2017

I installed windows on the windows, I would like to use NFS way to connect WINDOWS

@xophere
Copy link

xophere commented Sep 28, 2017 via email

@snfnwgi
Copy link

snfnwgi commented Sep 28, 2017

@xophere
boot error! Sorry, my English is not good!
==> default: Forwarding ports...
default: 5985 (guest) => 55985 (host) (adapter 1)
default: 5986 (guest) => 55986 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: WinRM address: 127.0.0.1:55985
default: WinRM username: IEUser
default: WinRM execution_time_limit: PT2H
default: WinRM transport: plaintext
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Exporting NFS shared folders...
==> default: Preparing to edit /etc/exports. Administrator privileges will be required...
==> default: Mounting NFS shared folders...
Vagrant attempted to execute the capability 'mount_nfs_folder'
on the detect guest OS 'windows', but the guest doesn't
support that capability. This capability is required for your
configuration of Vagrant. Please either reconfigure Vagrant to
avoid this capability or fix the issue by creating the capability.

@xophere
Copy link

xophere commented Sep 28, 2017 via email

@snfnwgi
Copy link

snfnwgi commented Sep 28, 2017

@xophere I use the MAC OS, I want to work in the MAC installed windows7, the default way to visit very slow, so I would like to use nfs

@xophere
Copy link

xophere commented Sep 28, 2017 via email

@snfnwgi
Copy link

snfnwgi commented Sep 28, 2017

@xophere Thank you, there are ways to support nfs? I have tried to use SMB and also reported some errors

@snfnwgi
Copy link

snfnwgi commented Sep 28, 2017

@xophere smb error;
➜ modernie-winrm git:(master) ✗ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
SMB shared folders are only available when Vagrant is running
on Windows. The guest machine can be running non-Windows. Please use
another synced folder type.

@xophere
Copy link

xophere commented Sep 28, 2017 via email

@snfnwgi
Copy link

snfnwgi commented Sep 28, 2017

@xophere here: #9008 thank you!

@snfnwgi
Copy link

snfnwgi commented Sep 28, 2017

@xophere You give me a message, I want to rest, very late, tomorrow to work, thanks, cheers

@egnikitin
Copy link

egnikitin commented May 30, 2018

https://github.com/gael-ian/vagrant-bindfs helps mount after provision

@najamelan
Copy link

Currently fedora does not support vboxfs out of the box. So if one wants to use synced_folder, it's necessary to run a partial provision first which installs akmod-VirtualBox from rpmfusion.

For now the only solution is to comment out stuff in Vagrantfile, maybe create a snapshot after partial provision and then modify Vagrantfile, and run vagrant provision to have it do the rest of the provisioning. That's not a very unattended workflow.

Or write a vagrant plugin I supppose...

It can be argued that synced folders are probably not needed very often before provisioning (except by plugins), so allowing to create a synced folder as a provisioning step would make alot of sense to me.

@najamelan
Copy link

najamelan commented Jan 16, 2019

Ok,

Im going to find a workaround for this. So far I have found some tools that can help:

  • vagrant reload plugin: allows to reload between provisioning steps (although there seem to be alot of issues with this plugin). as an alternative, maybe run halt in the guest and do vagrant up && vagrant provision
  • vagrant trigger: run code before or after vagrant commands
  • ruby code in Vagrantfile can detect environment variables, or run shell commands with the vagrant-host-shell plugin, or test for the existance of files on the host etc...
  • detect whether a machine has been provisioned as described here

Idea:

  • have the synced folder in conditional code
  • after vagrant up, set an indicator on the host (touch a file or an env variable)
  • after first provision step, reload
  • now detect first provision has been done
  • before vagrant destroy, remove the indicator file

@d4rkd0s
Copy link

d4rkd0s commented Feb 28, 2019

If you omit the guest path, it won't auto-mount. Also, the @dominis workaround is quite good. I think this is rare enough that this is satisfactory for now since this would require significant change. Sorry!

@mitchellh
Does the solution @dominis provides cover VMWare? I see vboxsf in there, and I get wondering. What would this "solution" look like for VMWare?

config.vm.share_folder "ganja", "/test", "/test"
config.vm.provision :shell do |shell|
  shell.inline = "sudo mount -t vboxsf -o uid=`id -u apache`,gid=`id -g apache` test /test"
end

@d4rkd0s
Copy link

d4rkd0s commented Feb 28, 2019

I found the GID UID works. If anyone is interested in that solution.

Just make sure you create your user's in your provisioning with the optional uid and gid for the group. I use Ansible so for example it's this for my wildfly user and group:

- name: Create wilfdly group
  group:
    name: wildfly
    gid: 1001
    state: present

- name: Create wildfly user
  user:
    name: wildfly
    uid: 1001
    comment: Created by ansible
    group: wildfly
    home: /home/wildfly

And then in my Vagrantfile:

WILDFLY_UID = 1001
WILDFLY_GID = 1001
api.vm.synced_folder "C:/work/war", "/opt/api/deployments", type: "rsync", rsync__auto: true, create: true, owner: WILDFLY_UID, group: WILDFLY_GID

If you are using Shell provisioning or just running bash it would be this:
useradd -u 1001 -g 1001 wildfly

@cbj4074
Copy link

cbj4074 commented Oct 9, 2019

7.5 years later, I'm wondering if there is a new/better "solution" to this problem than those discussed previously.

I've read every comment and my use-case is most similar to the scenario @jdoss describes in #936 (comment) and @najamelan describes in #936 (comment) .

In short, the problem I face is not that the user as whom the share(s) should be mounted does not yet exist; rather, the problem is that the networking configuration required to facilitate the sharing is not in place by the time Vagrant tries to auto-mount the shares.

Specifically, I need to assign a static IP address in the VM, and Vagrant does not support this capability the Hyper-V provider (see both https://www.vagrantup.com/docs/hyperv/limitations.html and #8384 ).

In terms of possible workarounds/solutions to this problem, the "manual" mount command that @dominis describes in #936 (comment) would be different for Hyper-V machines (i.e., it would not use -t vboxfs); I mention this only to underscore the fact that this particular "solution" is provider-specific and therefore less than ideal.

The approach that @cecilemuller describes in #936 (comment) is promising, but it has two significant drawbacks: a) it's box-name specific, and b) it requires vagrant up && vagrant reload to be fully-provisioned.

In essence, I'd really love to be able to defer shared folder mounting until after Vagrant has run an arbitrary provisioner script in which I'm able to do whatever is needed within the guest OS to configure the static IP address.

Ultimately, I'm curious if anybody has found a better way to do this recently... thanks in advance!

@ghost
Copy link

ghost commented Jan 28, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Jan 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests