From 40eaef08b79d6c170c8b41c417f45b943a8c2583 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 10 Aug 2017 15:49:47 -0700 Subject: [PATCH] (#8603) Ensure remote folder exists prior to scp in file provisioner Prior to this commit, if a file provisioner block was ran twice with a folder on a remote host, due to how scp works, it would first copy over that folder, and then on the second action it would copy an identical folder nested within the first one. While this is 'intended' behavior with scp, it is unexpected behavior for the file provisioner. This commit updates the file provisioner to first ensure that the directory to be copied exists on the remote host prior to copying, and then the destination dir has been changed to the directory that the destination will be copied to, rather than the exact directly that includes the folder from the host to prevent the nested folder behavior. --- plugins/provisioners/file/provisioner.rb | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/provisioners/file/provisioner.rb b/plugins/provisioners/file/provisioner.rb index 7b997a7dc..3c8081fce 100644 --- a/plugins/provisioners/file/provisioner.rb +++ b/plugins/provisioners/file/provisioner.rb @@ -3,14 +3,30 @@ module VagrantPlugins class Provisioner < Vagrant.plugin("2", :provisioner) def provision @machine.communicate.tap do |comm| + source = File.expand_path(config.source) destination = expand_guest_path(config.destination) + # if source is a directory, make it then trim destination with dirname # Make sure the remote path exists - command = "mkdir -p %s" % File.dirname(destination) + if File.directory?(source) + # We need to make sure the actual destination folder + # also exists before uploading, otherwise + # you will get nested folders. We also need to append + # a './' to the source folder so we copy the contents + # rather than the folder itself, in case a users destination + # folder differs from its source. + # + # https://serverfault.com/questions/538368/make-scp-always-overwrite-or-create-directory + # https://unix.stackexchange.com/questions/292641/get-scp-path-behave-like-rsync-path/292732 + command = "mkdir -p %s" % destination + source << "/." + else + command = "mkdir -p %s" % File.dirname(destination) + end comm.execute(command) # now upload the file - comm.upload(File.expand_path(config.source), destination) + comm.upload(source, destination) end end