使用 Ansible provisioner 重启 Vagrant 虚拟机时,同步的文件夹丢失。

11
Vagrant 使用 VirtualBox 创建开发环境并使用 Ansible 进行配置。在配置的过程中,Ansible 执行重启操作,并等待 SSH 重新启动。这一步骤按预期工作,但由于 Vagrant 虚拟机不是通过 "vagrant up" 命令启动的,因此当虚拟机从重启中恢复时,同步文件夹未正确挂载。
运行 "vagrant reload" 可以修复虚拟机并再次挂载共享文件夹。
有没有办法告诉 Vagrant 重新加载服务器或完成手动重启后 Vagrant 将执行的所有操作?
直接在 Vagrant box 中通过 SSH 运行 "sudo reboot" 也会产生相同的问题。
5个回答

8

Vagrant无法知道在配置过程中机器正在重启。

如果可能的话,最好完全避免在此处重新启动。例如,构建基础盒子时应已完成内核更新。

另一种简单(但不太方便)的方法是通过日志输出或文档处理,或使用调用vagrant up && vagrant reload的包装脚本来处理。

最后,您可以编写一个插件,在配置完成后将所有所需的挂载等操作注入到Vagrant中间件堆栈中,但仍需要考虑如何让插件知道机器已启动。另一个挑战是这很容易变成特定于提供程序的。


4

您应该能够将文件系统添加到 /etc/fstab 中,在启动时自动挂载。

以下是我的示例:

vagrant /vagrant    vboxsf  defaults    0   0
home_vagrant_src    /home/vagrant/src   vboxsf  defaults    0   0
home_vagrant_presenter-src  /home/vagrant/presenter-src vboxsf  defaults    0   0

你的vagrant目录中应该有一个名为".vagrant"的隐藏目录,在其中你应该能够找到一个指向"同步文件夹"文件的路径(在我的情况下是:/vagrant/.vagrant/machines/default/virtualbox/synced_folders)。
那个文件应该会帮助你弄清楚标签是什么以及它们的挂载点:
{"virtualbox":{"/home/vagrant/src":{"guestpath":"/home/vagrant/src","hostpath":"/home/rkomorn/src","disabled":false,"__vagrantfile":true},"/home/vagrant/presenter-src":{"guestpath":"/home/vagrant/presenter-src","hostpath":"/home/presenter/src","disabled":false,"__vagrantfile":true},"/vagrant":{"guestpath":"/vagrant","hostpath":"/home/rkomorn/vagrant","disabled":false,"__vagrantfile":true}}}

虽然不太容易理解,但用Python的术语来说,标签似乎是内部字典的键,其中 / 被翻译成了 _(例如:/home/vagrant/presenter-src 键变成了 home_vagrant_presenter-src 标签)。

我实际上不确定为什么vagrant不直接使用/etc/fstab进行共享文件夹,但我猜测有一个很好的原因。


2

我有同样的问题。这是我在/etc/fstab中的内容。

#VAGRANT-BEGIN
# The contents below are automatically generated by Vagrant. Do not modify.
vagrant_data /vagrant_data vboxsf uid=1000,gid=1000,_netdev 0 0
vagrant /vagrant vboxsf uid=1000,gid=1000,_netdev 0 0
#VAGRANT-END

如果您看到fstab条目仍然存在,您只需要运行sudo mount -a来触发重新挂载。或者您可以复制这些行。


1
我真的相信这应该是最可接受的答案,你可以轻松运行 sudo mount -a - h q

2

如果有其他人遇到了这个问题并像我一样在这里找到了这个问题,以下是我解决问题的方法:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "..."

  # create a shared folder for the top-level project directory at /vagrant
  # normally already configured but for some reason it isn't on these boxes
  # https://www.vagrantup.com/docs/synced-folders/virtualbox.html#automount
  # http://www.virtualbox.org/manual/ch04.html#sf_mount_auto
  config.vm.synced_folder ".", "/mnt/vagrant", id: "vagrant", automount: true
  config.vm.provision "shell", inline: "usermod -a -G vboxsf vagrant"
  config.vm.provision "shell", inline: "ln -sfT /media/sf_vagrant /vagrant"

  # More settings omitted...
end

这个解决方案有几个部分:
  1. 第一行将具体的id指定为vagrant,并将共享文件夹挂载到/mnt/vagrant,以避免影响其他位置。这很重要,因为VIrtualBox中的自动挂载功能默认使用/mnt/sf_<id>。最好选择一个在所有VM上都存在的更隐蔽的位置或记录不要在那里使用它。
  2. 第三行创建了一个符号链接,将自动挂载位置/mnt/sf_vagrant与用户通常期望找到的共享文件夹位置/vagrant关联。
  3. 第二行将虚拟机中的vagrant用户添加到vboxsf组中。这是必要的,以访问/mnt/sf_vagrant中的文件,因为客户端工具会使用root:vboxsf所有权挂载该文件夹。它们还设置适当的文件和目录模式,因此在实践中可以正常工作,但您确实需要成为vboxsf组的成员。
此解决方案具有以下优点:
  • /mnt/sf_vagrant 挂载点会在虚拟机重启后由虚拟盒子客户端自动挂载,因此 /vagrant 应该始终可用。
  • 它不需要安装插件或使用任何外部工具。

它具有以下缺点:

  • 如果用户找到并使用 /mnt/vagrant 挂载点,则可能导致意外行为。该挂载点仅在通过 vagrant 控制台客户端最近启动/重新启动虚拟机时存在,否则将不存在。
  • 它需要相对较新的 VirtualBox 和 Vagrant 版本。

编辑:添加 -T 选项到 ln 中,以避免出现创建 /vagrant/sf_vagrant 符号链接的极端情况。


1
将您的供应程序分为两个独立的步骤,并在其中使用vagrant-reload插件作为额外的供应程序。
示例Vagrantfile:
  config.vm.provision "Step 1 - requires reboot", type: "shell", path: "scripts/part1.sh"
  config.vm.provision :reload
  config.vm.provision "Step 2 - happens after reboot", type: "shell", path: "scripts/part2.sh"

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