Sync folders after provision script has ran? - vagrant

Is it possible to have vagrant sync a folder after the provision script is ran?
I need to sync a guest folder, with the host folder, but the host folder must be empty for the provision script to work. The user and group also need to exist. Non of which can exist until the provision script has ran. My provision script creates the user, and group.
The synced folder is a Magento theme. Magento first needs to install before I can sync the directories as Magento will not install into a non empty directory.
Here is my Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-18.04"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.provision "shell", path: "provision.sh"
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.synced_folder "app/design/frontend",
"/var/www/mage/app/design/frontend",
create: false,
owner: "mage",
group: "www-data"
config.vm.provider "virtualbox" do |vb|
vb.memory = "3000"
end
end
I've taken a look at triggers, but I can figure out how to use config.vm.synced_folder within a trigger.
Any advice?

I've found a solution.
In the Vagrantfile set config.vm.synced_folder to be false like so (also works for nfs):
config.vm.synced_folder "app/design/frontend",
"/var/www/mage/app/design/frontend",
type: "rsync",
disabled: false,
owner: "mage",
group: "www-data"
Now run vagrant up. Once the server provisioning is complete change disabled to true like so:
config.vm.synced_folder "app/design/frontend",
"/var/www/mage/app/design/frontend",
type: "rsync",
disabled: true,
owner: "mage",
group: "www-data"
Now run vagrant reload and the folder will be synced.
The docs say
disabled (boolean) - If true, this synced folder will be disabled and
will not be setup. This can be used to disable a previously defined
synced folder or to conditionally disable a definition based on some
external factor.
Which makes me believe this may be one of the intended ways to solve my problem.
There is a feature request to mount folders post-provision which seems to be closed and not resolved so I don't think there's any other way to this: https://github.com/hashicorp/vagrant/issues/936

Related

Include a directory of config files for a Vagrantfile

I have a Vagrantfile that has the following semi-standard setup:
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network :forwarded_port, guest: 80, host: 8080, auto_correct: true
config.vm.network "private_network", ip: "192.168.56.40"
config.vm.hostname = "development.local"
config.vm.boot_timeout = 600
config.vm.provider "virtualbox" do |v|
v.name = "development.local"
v.memory = "1024"
v.check_guest_additions = true
end
config.vm.provision :shell, path: "bootstrap.sh"
end
My aim is to auto include files within a folder that configure the site on vagrant up.
For apache settings, I have managed to create a nice bash script that parses a folder and sets up sites-enabled for all the configs within a folder.
I would like to also share these folders inside the Vagrantfile without having to modify the core, much like apache parses the sites-enabled folder. This would mean I can easily share this box with others, without having to change the Vagrantfile every time I spin up a test environment and want to share a new folder.
The usual syntax is:
config.vm.synced_folder "../some-folder/", "/var/www/some-folder", owner: "www-data"
Using pseudocode, this is what I'm aiming for:
foreach([$files_in_$folder] as $synced_folder) {
require $synced_folder_config_file;
// ^ this would be a small config file
}
Note that the advantage of the small config file is that other things could be specified on a per-file bases (such as different owners/permissions etc).
Key things to do:
parse over folder contents
ensure that this config is executed as part of the vagrant up
I've barely touched ruby, so apologies if this is obvious.
Thanks
After some research and a lot of reprovisions and up/down/destroy:
Create appropriate files in the /synced-folders/, each consisting of something like:
config.vm.synced_folder "../development.local/", "/var/www/development.local", owner: "www-data"
Then, in your Vagrantfile:
Dir[File.dirname(__FILE__) + '/synced-folders/*.rb'].each {|file| eval File.read(file) }
This parses over the directory, and evals them.

Vagrant synced folder causes contents to be erased

I'm trying to add add an additional synced folder besides the default /vagrant.
I've read the documentation which indicates that this should be as simple as:
config.vm.synced_folder "/path/to/somewhere/on/host", "/path/to/guest_directory", create: true
When I add this to my Vagrantfile and then reprovision it, the guest_directory folder shows up in the expected place on the host, but it's empty. And the folder in the guest OS is also empty... which breaks my site because those are the website files. Interestingly, if I remove that from the Vagrantfile and reprovision again, the files reappear in the guest OS where they were originally.
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.33.99"
# NEITHER OF THESE WORK...
# config.vm.synced_folder "/Users/ESL/Sites/project/web__public_web", "/home/vagrant/web__public_web", create: true
# config.vm.synced_folder "./web__public_web", "/home/vagrant/web__public_web", type: "rsync", rsync__args: ["--verbose", "--archive", "--delete", "-z"], create: true
config.vm.provider "virtualbox" do |vb|
vb.memory = "2046"
end
end
You can see that I've tried a two different type: options and got the same wrong result with both. I also tried placing a symlink to the project files inside /vagrant/ and that didn't work either. (The broken symlink showed up in the host os directory instead of the files I want to access)
Here are a couple more details about my setup, just in case they're relevant:
In the guest OS the project files live in /home/vagrant/web__public_web but the document root is /srv/www/... which contains a symlink pointing to the former path.
VirtualBox: Version 5.2.18 r124319 (Qt5.6.3)
Vagrant: v2.1.0
OSX: 10.13.6
What am I doing wrong?
Each mount requires a unique id, if the box is already built you'll need to rebuild it.
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.33.99"
config.vm.synced_folder "/Users/ESL/Sites/project/web__public_web", "/path/where/mounted/on/vm", id: "unique_id_1", type: "rsync", rsync__args: ["--verbose", "--archive", "--delete", "-z"], create: true
config.vm.synced_folder "/home/vagrant/web__public_web", "/path/where/mounted/on/vm2", id: "unique_id_2", type: "rsync", rsync__args: ["--verbose", "--archive", "--delete", "-z"], create: true
config.vm.provider "virtualbox" do |vb|
vb.memory = "2046"
end
end
I answered my own question...
It turns out the sync was working all along. But I misunderstood the directionality of the sync. I was expecting the files in the guest OS to show up in the host directory, but it's the other way around. The empty folder on the host directory was getting synced to the guest and wiping out all the files.
After I manually copied all of the files from the guest to the host directory, the same configurations worked as expected.
Bottom line: if you want to sync an existing guest folder with files in it, you have to manually move it into place on the host OS first.

How to exclude (ignore) certain folders in vagrant rsync?

I wish to run npm install in my vagrant virtual box.
But whenever I ran the npm install command, my rsync will execute. Since my host computer does not have node_modules installed, it simply remove the folder completely for me.
What do I need to do so that my vagrant rsync will ignore the node_modules folder?
I cannot have node_modules being rsynced into the guest machine because my host and guest are two different systems. So far my vagrantfile looks like this.
Vagrant.configure("2") do |config|
config.vm.box = "laravel/homestead"
config.vm.hostname = "localhost"
config.vm.network "forwarded_port", guest: 8000, host: 8000
config.vm.synced_folder "./", "/home/vagrant/app"
config.vm.provider "virtualbox" do |v|
v.name = "web2"
v.memory = "4096"
v.cpus = 2
v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/SHARE_NAME", "1"]
end
config.vm.synced_folder "./", "/home/vagrant/app", type: "rsync", rsync_auto: true, rsync_exclude: ['node_modules*']
config.vm.provision :shell, path: "provision/setup.sh"
end
And I execute vagrant rsync via
vagrant rsync-auto
rsync__exclude as well as rsync__auto takes 2 _
You need to rewrite your line as
config.vm.synced_folder "./", "/home/vagrant/app", type: "rsync", rsync__auto: true, rsync__exclude: ['./node_modules*']
Step 3 on http://perrymitchell.net/article/npm-symlinks-through-vagrant-windows/ worked better for me in the end...
From the page:
The steps are simple:
Delete the node_modules directory if it exists.
Create a directory called, say "node_modules_projectname" in the VM's home directory (~) (Some articles and posts recommend making the
directory in /tmp, but obviously this is cleared on reboot, so it may
not be an optimal experience for this type of thing).
Link a local node_modules dir from within the project's directory
ln -s ~/node_modules_projectname /path/to/your-project/node_modules
Install the packages in the project directory:
npm install

Using SaltStack grains file with Vagrant

I would like to use minion.d/*.conf to provision a vagrant machine.
Here is my Vagrant configuration:
Vagrant.configure("2") do |config|
## Choose your base box
config.vm.box = "precise64"
## For masterless, mount your salt file root
config.vm.synced_folder "salt/roots/", "/srv/salt/"
## Use all the defaults:
config.vm.provision :salt do |salt|
salt.minion_config = "salt/minion"
salt.run_highstate = true
salt.grains_config = "salt/minion.d/vagrant.conf"
end
end
After provisioning the Vagrant machine, I have errors with rendering SLS files since the minion.d/*.conf files are not being copied to the guest machine under :
/etc/salt/minion.d/
Should I make a sync config in the Vagrant configuration to co ?
Have you just tried mounting a synced folder to /etc/salt/grains?
## For masterless, mount your salt file root
config.vm.synced_folder "salt/roots/", "/srv/salt/"
config.vm.synced_folder "salt/grains.d/", "/etc/salt/grains.d/"
#Utah_Dave's solution will work just fine, or you can do the following (which is how I run it).
Filesystem:
/dev
Vagrantfile
salt-minion.conf
salt/
top.sls
my-awesome-state/init.sls
pillar/
top.sls
my-awesome-pillar.sls
Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = "mafro/jessie64-au-salt"
# salt config directory & shared dir in /tmp
config.vm.synced_folder ".", "/srv/salt"
# setup the salt-minion
config.vm.provision :salt do |salt|
salt.minion_config = "salt-minion.conf"
end
end
salt-minion.conf
file_client: local
id: awesome
file_roots:
base:
- /srv/salt/salt
pillar_roots:
base:
- /srv/salt/pillar
Vagrant's implementation of salt.grains_config doesn't copy the file to the /etc/salt/minion.d folder as you might expect. Instead it copies the file to /etc/salt/grains.
To get the salt-minion to read this new grains file, you just need to add the following to your minion configuration:
/etc/salt/minion
include:
- /etc/salt/grains

config.vm.share_folder setting not found

I am getting this error with this line in my Vagrantfile during vagrant up, until I comment it out.
The setting is documented here:
http://docs-v1.vagrantup.com/v1/docs/config/vm/share_folder.html
Not sure why the following documented paramenter causes an error
config.vm.share_folder "puppetdir", "/etc/puppet", "/vagrant/mypuppetdir"
Bringing machine 'default' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:
vm:
* The following settings don't exist: share_folder
The latest virtualbox and latest vagrant. everything else works fine.
On Vagrant 1.1+ you should use config.vm.synced_folder, the docs you are looking at are for older versions. Please refer to the updated documentation for more info: http://docs.vagrantup.com/v2/synced-folders/basic_usage.html
Shared Folders has been renamed to Synded Folder since 1.1.
In your Vagrantfile you should be using the following
config.vm.synced_folder "../data", "/vagrant_data"
# by default enabled, uncomment to disable
# config.vm.synced_folder ".", "/vagrant", disabled: true
NOTE: By default, Vagrant will share your project directory (the directory where Vagrantfile resides) to /vagrant.
config.vm.synced_folder ".", "/vagrant", disabled: true
More flexible example
vagrant_data = File.expand_path("../vagrant_data", __FILE__)
Dir::mkdir(vagrant_data) unless FileTest::directory?(vagrant_data)
config.vm.synced_folder "vagrant_data", "/vagrant_data"
Take a look at this for more information => shared folders VS synced folders
Extending from https://github.com/mitchellh/vagrant/issues/936#issuecomment-7179034
if you need to mount a volume as a user that doesn't exist when the vm boots you can get there like so:
# Vagrantfile line
config.vm.synced_folder "host_folder", "/svr/fake_mount_folder", id: "whatever_name"
# ...
config.vm.provision "shell", inline: <<-SHELL
# ...
# In my case a package installed a user with UID 110, GID 116
mount -t vboxsf -o uid=110,gid=116 whatever_name /media/actual_mounted_folder
# ...
SHELL

Resources