我想根据另一个 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>