在Vagrantfile中,我附加手动创建的db.vdi
磁盘:
vb.customize [
'storageattach', :id,
'--storagectl', 'SATA Controller',
'--port', 1, '--device', 0,
'--type', 'hdd',
'--medium', 'db.vdi'
]
它工作得很好,但是当我销毁流浪者盒子时,这个文件被删除了。我试图修复那个修复流浪者的触发器。 before :destroy
before :halt
不起作用,我收到驱动器不可热插拔的错误。 after :halt
根本不起作用:
config.trigger.after :halt do
run "VBoxManage storageattach '#{@machine.id}'" +
" --storagectl 'SATA Controller' --port 1 --device 0 --type hdd --medium none"
end
我想要做的是,当我运行vagrant destroy
时,我想优雅地停止机器,取消附加vdi文件,这样流浪者不会删除它,摧毁其他所有内容。
有可能吗?
编辑:
看起来可以使用插件挂钩https://github.com/kusnier/vagrant-persistent-storage/blob/master/lib/vagrant-persistent-storage/plugin.rb - 看看对Action.detach_storage
的引用,但我不知道如何在Vagrantfile中使用它
请参阅@FrédéricHenri - 分离很快就会触发:
==> default: Running triggers before destroy...
==> default: dettach drive
==> !!! TOO SOON !!!
==> default: Executing command "VBoxManage storageattach d0132b78-11ea-41cf-b003-dac15536520c --storagectl SATAController --port 1 --device 0 --type hdd --medium none"...
==> default: Command execution finished.
default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Forcing shutdown of VM...
==> !!! THIS IS WHERE I SHOULD DETACH THE DRIVE !!!
==> default: Destroying VM and associated drives...
答案 0 :(得分:1)
我找到了这个插件https://github.com/kusnier/vagrant-persistent-storage
它看起来像我需要但不幸的是只有一个磁盘选项
答案 1 :(得分:1)
我认为你是正确的,就好像你看一下示例插件一样,它们在halt命令之后和destroy之前挂钩。
问题在于您运行命令的方式run "VBoxManage storageattach '#{@machine.id}'" ..
将返回空machine.id
; Vagrantfile脚本中的vagrant不知道它正在构建的计算机,因此您会收到一条错误,指出它找不到具有空ID /名称的引用VM,并且该命令无法成功执行。
您需要的是获取VirtualBox VM Id,以便将其传递给命令;此ID保存在文件.vagrant/machines/<name>/<provider>/id
中,假设您没有为VM设置特定名称,它将是:
config.trigger.before :destroy do
info "dettach drive"
machineId = File.read(".vagrant/machines/default/virtualbox/id")
run "VBoxManage storageattach '#{machineId}'" +
" --storagectl 'SATA Controller' --port 1 --device 0 --type hdd --medium none"
end
在销毁VM时弹出驱动器时出现对于 hotpluggable pat,您需要确保文件在连接时确实是可热插拔的,以便在VM仍在运行时(即在销毁之前)拔出它
您可以在连接硬盘时从Vagrantfile进行此配置
vb.customize [
'storageattach', :id,
'--storagectl', 'SATAController',
'--port', 1, '--device', 0,
'--type', 'hdd',
'--medium', 'db.vdi',
'--hotpluggable', 'on'
]
为此VM运行destroy
命令时,您将获得
fhenri:~/project/vagrant/drive$ vagrant destroy
==> default: Running triggers before destroy...
==> default: dettach drive
==> default: Executing command "VBoxManage storageattach d0132b78-11ea-41cf-b003-dac15536520c --storagectl SATAController --port 1 --device 0 --type hdd --medium none"...
==> default: Command execution finished.
default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Forcing shutdown of VM...
==> default: Destroying VM and associated drives...
所以你可以清楚地看到命令被正确执行并且驱动器被取消了,我可以看到驱动器仍然在我的本地硬盘上,然后我可以回答是以销毁VM文件
就我而言,它也可以在停止
触发器挂钩后与一样好用: 来自Vagrantfile的
config.trigger.after :halt do
info "dettach drive"
machineId = File.read(".vagrant/machines/default/virtualbox/id")
run "VBoxManage storageattach '#{machineId}'" +
" --storagectl 'SATAController' --port 1 --device 0 --type hdd --medium none"
end
将运行
fhenri:~/project/vagrant/drive$ vagrant halt
==> default: Attempting graceful shutdown of VM...
==> default: Running triggers after halt...
==> default: dettach drive
==> default: Executing command "VBoxManage storageattach 74274ab6-173e-4934-9864-33e09be26214 --storagectl SATAController --port 1 --device 0 --type hdd --medium none"...
==> default: Command execution finished.
剩下的问题是确保在这种情况下不要调用 destroy ,因为destroy不会停止VM,它只是销毁它所以它不会调用halt命令并绕过停止触发器,你可以使用额外的detroy插件,但它将意味着你不想要的热插拔的东西
您可以查看vboxmanage showvminfo <uuid>
并查看 storagecontrollerportcount0
你可以在之前的销毁触发器中翻译它
config.trigger.before :destroy do
vm_info = `vboxmanage showvminfo #{@machine.id} --machinereadable | grep storagecontrollerportcount0`
value = Integer(vm_info.split("=")[1].gsub('"','').chomp())
raise Vagrant::Errors::VagrantError.new, "drive attached - cannot be destroyed" if value > 1
end
如果连接了多个驱动器并且不会继续执行destroy命令
,则会引发错误答案 2 :(得分:0)
我已经在Windows7主机上,带有fedora guest(奇怪的是有一个IDE控制器)的流浪汉2.1.1(2.1.2触发中断)上对其进行了测试。
因此,我的解决方案可能是愚蠢的,如下所示:
Thread.sleep(1000)
因此,基本上,当您在“ before”之前调用trigger destroy时,它首先停止机器(“ halt”之后为触发器),分离磁盘,然后调用destroy。它既可以在运行的计算机上运行,也可以在停止的计算机上运行。这样的永久磁盘。
P.S。它可能需要一些保护措施