简体   繁体   中英

How do I provision a Vagrant box before it's been instantiated?

I would like to create a Vagrant box from the output of another Vagrant box. I'd like to do it from within Vagrant. I would like to run vagrant init or vagrant up and have it do the following steps:

  1. Run this command to convert from .bin to .vdi vboxmanage convertfromraw --format vdi ../build/qMp_3.2.1-Clearance_VirtualBox_x86_factory_20180325-0702.bin qmp-nycmesh-3.2.1.vdi
  2. Create an instance based on that .vdi

I have this Vagrantfile, but 1) it is not executing the shell script before trying to create the box, and 2) it trying to download a box instead of using the VDI given.

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo Hello"
  #config.vm.box = "nycmesh-qmp-openwrt"
  config.vm.network "public_network"
  config.vm.network "private_network", type: "dhcp"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "64"
    vb.customize ['storageattach', :id, '--storagectl', 'IDE Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', "../build/qMp_3.2.1-Clearance_VirtualBox_x86_factory_20170406-2203.vdi"]
    #vb.customize ["modifyvm", :id, "--ostype", "Linux26"]
  end
end

With config.vm.box , it gives

$ vagrant up
==> default: Box 'nycmesh-qmp-openwrt' could not be found. Attempting to find and install...
    default: Downloading: nycmesh-qmp-openwrt
An error occurred while downloading the remote file. ...
Couldn't open file .../nycmesh-qmp-openwrt

And commenting config.vm.box gives

$ vagrant up
vm:
* A box must be specified.

Vagrant 2.0.1

I found I can specify a placeholder box and can just swap it out before it boots, but it still has to copy the gigabyte sized image and when you use vagrant destroy it doesn't delete the placeholder image. This is less than ideal.

I realized the Vagrantfile is just Ruby so I was able to script the VDI creation. I wasn't able to delete the placeholder image because there's no hook to insert yourself between the instance being created and the swapping of the disk image.

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"
  config.vm.network "public_network"
  config.vm.network "private_network", type: "dhcp"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "64"
    # add the newly created build disk firmware
    #vb.customize ['storageattach', :id, '--storagectl', 'IDE', '--port', 0, '--device', 0, '--type', 'hdd', '--medium', "none"]
    vb.customize ['storageattach', :id, '--storagectl', 'IDE', '--port', 0, '--device', 0, '--type', 'hdd', '--medium', "nycmesh-qmp-openwrt.vdi"]
    vb.customize ["modifyvm", :id, "--ostype", "Linux26"]
  end
  config.vm.provision "shell", inline: "" do
    # delete the placeholder dummy hdd image. there should be a better way.
    # NO WAY TO GET THE DUMMY HDD FILE NAME AFTER THE INSTANCE IS CREATED AND BEFORE THE NEW VDI IS INSTALLED!
    # id = File.read(".vagrant/machines/default/virtualbox/id") 
    # hdd_file = `vboxmanage showvminfo #{id}`.split(/\n/).grep(/IDE \(0, 0\): /).first.split(/ /)[3]
    # puts hdd_file
    # File.delete(hdd_file) if hdd_file.index 'centos-7-1-1.x86_64.vmdk'
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM