gpt4 book ai didi

Vagrant 在销毁之前分离 .vdi 文件或者只是不删除它

转载 作者:行者123 更新时间:2023-12-03 09:08:18 28 4
gpt4 key购买 nike

在 Vagrantfile 中,我附加手动创建的 db.vdi 磁盘:

vb.customize [
'storageattach', :id,
'--storagectl', 'SATA Controller',
'--port', 1, '--device', 0,
'--type', 'hdd',
'--medium', 'db.vdi'
]

它工作得很好,但是当我销毁 vagrant box 时,这个文件被删除了。我试图修复 Vagrant 触发器。 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文件,这样vagrant就不会删除它,销毁其他所有内容。

可能吗?


编辑:

看起来可以使用插件钩子(Hook) 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...

最佳答案

我认为您是正确的,就像您查看示例插件一样,它们确实在暂停命令之后和销毁之前进行 Hook 。

获取机器Id

问题在于您运行命令 run "VBoxManage storageattach '#{@machine.id}'" .. 的方式将返回一个空 machine.id ; Vagrantfile 脚本中的 vagrant 不知道它正在构建的机器,因此您会收到错误消息,它无法找到具有空 ID/名称的引用虚拟机,并且该命令无法成功执行。

您需要获取 VirtualBox VM Id,以便将其传递给命令;此 ID 保存在文件 .vagrant/machines/<name>/<provider>/id 中,假设您没有为虚拟机设置特定名称,它将是:

使用销毁前触发器

  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

销毁虚拟机时弹出驱动器时出现热插拔错误

对于热插拔模式,您需要确保文件在附加时确实是可热插拔的,以便可以在虚拟机仍在运行时(即销毁之前)将其拔出

您可以在连接硬盘时从 Vagrantfile 进行此配置

vb.customize [
'storageattach', :id,
'--storagectl', 'SATAController',
'--port', 1, '--device', 0,
'--type', 'hdd',
'--medium', 'db.vdi',
'--hotpluggable', 'on'
]

运行 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...

这样你就可以清楚地看到命令正确执行并且驱动器已分离,我可以看到驱动器仍然在我的本地硬盘驱动器上,然后我可以回答"is"来销毁虚拟机文件

使用暂停后触发器

就我而言,它也可以与 afterhalt 触发钩子(Hook)一起使用:

来自 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不会停止虚拟机,它只是销毁它,这样它就不会调用halt命令并绕过halt触发器,您可以使用额外的销毁插件,但这意味着您不想要热插拔的东西

如果连接了驱动器,则防止损坏

您可以通过检查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

如果您连接了超过 1 个驱动器,则会引发错误,并且不会继续执行 destroy 命令

关于Vagrant 在销毁之前分离 .vdi 文件或者只是不删除它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45038248/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com