如何使用Vagrant文件预配上传多个文件?

14
在Vagrant设置中,我需要在配置阶段从主机上传一些文件到宾客机。在https://docs.vagrantup.com/v2/provisioning/file.html中,我可以看到如何上传单个文件,从源到目标,但是如何上传多个文件或文件夹结构?注意:我知道可以使用shell provisioner完成此操作,但在这种特殊情况下,一组文件上传更合适。
6个回答

12
你需要为每个文件单独创建一个config.vim.provision部分。你可以像这样在Vagrantfile中添加多个这样的部分:

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

输出:

[default] Running provisioner: file...
[default] Running provisioner: file...

你会看到它正在执行两个配置操作。您可以在虚拟机内验证文件是否存在:

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

看起来正是我想要的...有没有关于整个文件夹结构的提示? - Giacomo Tesio
@GiacomoTesio 当您想要使整个文件夹可访问时,请使用config.vm.synced_folder - hek2mgl
这不是我需要的。例如,我有几个文件需要从主机移动到 /etc/apt/source.list.d/。我尝试使用 shell provisioner 中的 tar(类似于(cd root/ && tar cf - *) | (cd / && tar xf - --keep-old-files)),但它无法正常工作。 - Giacomo Tesio
然后,您需要使用Ruby迭代文件夹并动态创建config.vm.provision条目。 - hek2mgl

12

文件夹内容上传似乎也可以正常工作(我只试过文件,未试过嵌套文件夹):

config.vm.provision :file, source: '../folder', destination: "/tmp/folder"

1
是的,这似乎完全正常。还包括嵌套文件夹。 - zifot
我在这方面遇到了麻烦。第一次使用源路径'../one/two'和目标路径'/destination'时,所有文件都按预期放置在/destination中。再次运行vagrant provision后,您会发现所有文件都被放置在/destination/two中。 - Steve
2
虽然这似乎可以工作,但问题是嵌套文件夹的问题。在这种情况下,/tmp/每次重新启动Vagrant box时都会被清除,因此您看不到它。但是,如果您将此命令与以下目标一起使用,该目标在重新启动之间是持久的:/home/vagrant/folder/。第一次启动Vagrant box时,您会得到/home/vagrant/folder/。下一次启动Vagrant box时,您将获得/home/vagrant/folder/folder/。接下来呢?/home/vagrant/folder/folder/folder/。使用config.vm.synced_foldertype: "rsync"更好。使用Vagrant 1.8.1。 - Giacomo1968

4

如果有人只需要快速简单地复制主机上的目录结构到客户机上,我最终是通过以下方式实现的:

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

感谢@hek2mgl帮我找到了正确的方向


虽然这是一个较旧的答案,但在此其他答案中解释的使用Rsync选项同步文件夹的概念上可以工作;正如所呈现的那样,它是危险的。在您的Vagrantfile中设置以下行应该可以正常工作:config.vm.synced_folder "upload/", "/home/vagrant/upload/", type: "rsync" - Giacomo1968

1
您可以使用文件提供程序,正如其他人所提到的,但值得注意的是,还可以使用类型设置为rsync的同步文件夹功能:http://docs.vagrantup.com/v2/synced-folders/rsync.html
引用: Vagrant可以使用rsync作为将文件夹同步到虚拟机的机制。这种同步文件夹类型主要在其他同步文件夹机制不可用的情况下使用,例如当NFS或VirtualBox共享文件夹在虚拟机中不可用时。 rsync同步文件夹从运行机器一次性单向同步到由Vagrant启动的机器。
第一次vagrant up会在执行提供程序之前进行同步。 Vagrantfile中的示例配置如下:
config.vm.synced_folder "upload/", "/home/vagrant", type: "rsync"

-1:按照目前的配置,这相当危险且会破坏基本的Vagrant功能。我正在使用Mac OS X 10.10.5(Yosemite)上的Vagrant 1.8.1。通过将源设置为“upload/”,将目标设置为“/home/vagrant”,Rsync进程将覆盖“/home/vagrant”,这意味着Vagrant用户的“.ssh”目录将被清除,因此他们无法再通过SSH登录到此机器。运行此命令后。目标应该是“/home/vagrant/upload/”,因此配置应为config.vm.synced_folder "upload/", "/home/vagrant/upload/", type: "rsync" - Giacomo1968

1
这对我有效,进入您的vagrant然后运行。
vagrant up
vagrant ssh

vagrant@yourvagrant: sudo chown -R testuser:testuser /var/www/ or whatever folder you want to upload your files

在你的 Vagrantfile 中添加以下内容。
# we create add script to upload folder to a vagrant guest from local file
config.vm.provision :file, source: '/wamp/www/ian_loans', destination:  "/var/www/solidbond"

只需将文件目录更改为您的需求。退出并不要忘记在您的vagrant目录中运行。

vagrant provision

最后进入您的Ubuntu目录,查看您要上传的文件是否存在。
vagrant@yourvagrant: cd /var/your file directory

0

这可能有点老了,但我会在这里为使用PowerShell的Windows用户提供整个目录结构的另一个答案。

首先,创建一个PowerShell脚本,从共享文件夹复制整个文件夹结构。

#Check if the directory you're copying already exists on the VM
$foldercheck = "path\to\folder\on\vm"
if (test-path $foldercheck)
{
    Write-Host "Folder 'path\to\folder\on\vm' already exists..."
}
else {
    #Create the new directory
    New-Item -ItemType Directory -Force -Path "path\to\folder\on\vm"

    #Copy over contents to the directory
    Copy-Item "\\VBOXSRV\<share_name>\path\to\folder\to\copy\*" -Destination "path\to\folder\on\vm" -recurse
}

然后,配置您的Vagrantfile以自动挂载共享文件夹,复制PowerShell脚本,然后按指定顺序运行它们。

Vagrant.configure(2) do |config|
    config.vm.provider "virtualbox" do |vb|
        # Other settings
        # ...
        # Add shared folders
        vb.customize ["sharedfolder", "add", :id, "--name", "<share_name>", "--hostpath", "path/to/host/folder/location", "--automount"]
    end
    # =================================================================
    # PROVISIONING
    # =================================================================
    # Load up the files to the Guest environment for use by PowerShell
    config.vm.provision "file", source: "path/to/provisioning/files/powershellfile.ps1", destination: "path/to/temporary/location/powershellfile.ps1"
    # Rinse/repeat for additional provisioning files

    # Now provision files in the order they are specified
    config.vm.provision "shell", inline: "path/to/temporary/location/powershellfile.ps1"
    # Rinse/repeat to run PowerShell scripts
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接