How can I upload more than one file with vagrant file provisioning?
Solution 1
You would need a separate config.vim.provision
section for each file. You can add multiple of those sections to your Vagrantfile
, like this:
config.vm.provision :file do |file|
file.source = "/etc/file1.txt"
file.destination = "/tmp/1.txt"
end
config.vm.provision :file do |file|
file.source = "/etc/file2.txt"
file.destination = "/tmp/2.txt"
end
Output:
[default] Running provisioner: file...
[default] Running provisioner: file...
You see it is executing both provisioning actions. You can verify the file presence inside the virtual machine:
vagrant ssh -- ls -al /tmp/{1,2}.txt
-rw-r--r-- 1 vagrant vagrant 4 Aug 27 08:22 /tmp/1.txt
-rw-rw-r-- 1 vagrant vagrant 4 Aug 27 08:22 /tmp/2.txt
Solution 2
Folder content uploads seem to work as well (I've only tried it with files, not nested folders):
config.vm.provision :file, source: '../folder', destination: "/tmp/folder"
Solution 3
In case anybody else just needs a quick and dirty hack to copy a directory structure from the host to the guest, this is how I finally did it:
require 'pathname' # at the beginning of the Vagrantfile
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# more configuration here
r = Pathname.new 'root'
Dir.glob(File.join("root", File.join("**","*"))) do |f|
if !File.directory?(f) then
s = Pathname.new f
t = s.relative_path_from r
config.vm.provision "file" do |fp|
fp.source = s.to_s
fp.destination = "/tmp/root/" + t.to_s
end
end
end
# more configuration here
end
Thanks to @hek2mgl for getting me on the right track.
Solution 4
You can use file provisioner, as others had mentioned but it's still worth noting that it's possible to use a synced folder functionality with type set to rsync: http://docs.vagrantup.com/v2/synced-folders/rsync.html:
Vagrant can use rsync as a mechanism to sync a folder to the guest machine. This synced folder type is useful primarily in situations where other synced folder mechanisms are not available, such as when NFS or VirtualBox shared folders aren't available in the guest machine.
The rsync synced folder does a one-time one-way sync from the machine running to the machine being started by Vagrant.
On the first vagrant up
syncing happens before provisioners are executed. Sample configuration in Vagrantfile would look like this:
config.vm.synced_folder "upload/", "/home/vagrant", type: "rsync"
Giacomo Tesio
I'm able to rapidly identify the independent variables that govern complex problems and to plan a strategy to avoid (or at least to solve) them through the use of the proper tools. Whenever the current technological offer does not match to my requirements, I can design and develop the missing tools or hack into existing ones. During the last 5 years, I've gained some experience with Domain Driven design and supporting architecture and I'm building Epic as a "DDD software factory" that aims to make DDD much more cheaper than it is now. I've also contributed to various opensource projects with patches and bugfixes.
Updated on June 05, 2022Comments
-
Giacomo Tesio almost 2 years
In a Vagrant setup, I have to upload a couple of files from the host to the guest during the provisioning phase.
In https://docs.vagrantup.com/v2/provisioning/file.html I can see how to upload a single file, from a source to a destination, but how can I upload multiple files or a folder structure?
NOTE: I know I can do that using the shell provisioner, but in this particular case a set of file uploads would be more appropriate.
-
Giacomo Tesio over 9 yearsLooks exactly what I was looking for... Any tip for entire folder structures?
-
hek2mgl over 9 years@GiacomoTesio When you want to make a whole folder accessible, use
config.vm.synced_folder
-
Giacomo Tesio over 9 yearsthat's not what I need. For example I have a few files to be moved into /etc/apt/source.list.d/ from the host machine. I tried with tar in the shell provisioner (something like (cd root/ && tar cf - *) | (cd / && tar xf - --keep-old-files) ), but it doesn't works.
-
hek2mgl over 9 yearsThen you need to iterate over the folder with ruby and create the
config.vm.provision
entries dynamically. -
zifot over 8 yearsYep, that seems to be working just fine. Also with nested folders.
-
Steve over 8 yearsi had trouble with this. source:'../one/two', destination: '/destination' works as expected the first time, with all the files in /destination. Run vagrant provision again and you get all the files in /destination/two
-
Giacomo1968 about 8 years-1: As presented this config is quite dangerous and destructive to basic Vagrant functionality. I am using Vagrant 1.8.1 on Mac OS X 10.10.5 (Yosemite). By setting the source to
upload/
and the destination to/home/vagrant
the Rsync process will overwrite/home/vagrant
which means the Vagrant user’s.ssh
directory will be wiped out so they can no longer login to this machine via SSH after this command is run. The destination should be/home/vagrant/upload/
so the config should be,config.vm.synced_folder "upload/", "/home/vagrant/upload/", type: "rsync"
. -
Giacomo1968 about 8 yearsWhile this is an older answer, the synced folder with Rsync option explained in this other answer conceptually works; just as the presented it’s dangerous. Setting a line like this in your Vagrantfile should work fine:
config.vm.synced_folder "upload/", "/home/vagrant/upload/", type: "rsync"
. -
Giacomo1968 about 8 yearsWhile this appears to work, the problem is a nested folder issue. In this case
/tmp/
gets flushed with each restart of the Vagrant box so you won’t see it. But if you used this command with the following destination that’s persistent between restarts:/home/vagrant/folder/
. The first time the Vagrant box is started you get/home/vagrant/folder/
. The next time the Vagrant box is started you would get/home/vagrant/folder/folder/
. And the next after that?/home/vagrant/folder/folder/folder/
.config.vm.synced_folder
withtype: "rsync"
works better. Using Vagrant 1.8.1.