如何基于 .bin 或 .vdi 文件生成新的 Vagrant 框?

如何基于 .bin 或 .vdi 文件生成新的 Vagrant 框?

我想根据另一个 Vagrant box 的输出创建一个 Vagrant box。第一个 Vagrant box 会生成一个 .bin 文件。理想情况下,我想根据这个文件创建一个新的 Vagrant box。例如

$ mkdir node2 ; cd node2
$ vagrant init node2 ../build/qMp_3.2.1-Clearance_VirtualBox_x86_factory_20170406-2203.bin --minimal
$ vagrant up

但是它给出了一个错误

bsdtar.EXE:打开存档时出错:无法识别的存档格式

我可以从 .bin 转换为 .vdi,但这仍然不足以创建 Vagrant 盒子。

vboxmanage convertfromraw --format vdi qMp_3.2.1-Clearance_VirtualBox_x86_factory_20180325-0702.bin qmp-nycmesh-3.2.1.vdi

它仍然显示“打开存档时出错”消息。如何从 VirtualBox 磁盘映像创建 Vagrant 框?

答案1

我意识到 Vagrantfile 只是 Ruby,所以我只使用 Ruby 生成 VDI,并使用 Vagrant 将 VDI 附加到盒子上。唯一的问题是它需要一个虚拟占位符盒子,并且在更换存储介质后,它永远不会删除占位符磁盘映像!我不知道如何解决这个问题。

Vagrant.configure("2") do |config|
  latest_bin = `ls -t ../build/*.bin | head -1`.strip
  #latest_bin = Dir.glob('../build/*.bin').sort{ |a,b| File.new(a).stat <=> File.new(b).stat }.last
  vdi_file = 'nycmesh-qmp-openwrt.vdi'
  system "vboxmanage convertfromraw --format vdi #{latest_bin} #{vdi_file}" unless File.exist?(vdi_file)
  config.vm.box = "centos/7" # dummy box
  config.vm.provider "virtualbox" do |vb|
    # add the newly created build disk firmware
    vb.customize ['storageattach', :id, '--storagectl', 'IDE', '--port', 0, '--device', 0, '--type', 'hdd', '--medium', "nycmesh-qmp-openwrt.vdi"]
  end

答案2

我不知道如何从现有的 .vdi 创建新的 vagrant 环境,但您可以将 vagrant 环境与现有的 Vbox 机器关联,然后从 vagrant VM 生成一个盒子:

进入 vagrant 项目目录,然后使用 VM UUID 在正确的位置创建一个文件名 id:

$ cd <vagrant-project-folder> && \
$ echo -n \
$ `VBoxManage list vms \
$  | grep <vm-short-name> \
$  | sed 's/.*{\(.*\)}[^{]*$/\1/'` \
$ > .vagrant/machines/<vm-short-name>/virtualbox/id

如果项目只有一个虚拟机那么应该等于default

它直接将 grep 结果行中 { } 之间的任何内容注入到文件中,不带换行符。

VM 必须在 Virtualbox 中启动才能VBoxManage list vms运行

检查是否考虑到了更改:

$ vagrant status \
> | grep -qE '<vm-short-name>.*not created'

如果 vagrant status 返回一行带有 our 和 “not created” 的内容,则表示它没有工作,否则没问题,然后您可以运行vagrant up <vm-short-name>进入虚拟机并对其进行测试、调整、清理等...

然后就可以打包放进盒子里了:

$ vagrant package --output <box-name>.box

将其添加到框本地存储库:

$ vagrant box add <box-name> <box-name>.box

清理vagrant destroy并 rm 工作目录。

然后像任何框一样初始化一个新项目:

$ vagrant init -m <box-name>

相关内容