Skip to content

Commit

Permalink
(QENG-1146) Add vagrant_fusion, vmware_workstation, and vagrant_virtu…
Browse files Browse the repository at this point in the history
…albox providers

Currently the vagrant hypervisor provider just does virtualbox. This
allows the vagrant vmware_fusion and vmware_workstation plugins to be
used instead.
  • Loading branch information
hunner committed Oct 1, 2014
1 parent decdb05 commit fdcbac3
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 33 deletions.
32 changes: 19 additions & 13 deletions lib/beaker/hypervisor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,39 @@ def self.create(type, hosts_to_provision, options)
@logger = options[:logger]
@logger.notify("Beaker::Hypervisor, found some #{type} boxes to create")
hyper_class = case type
when /aix/
when /^aix$/
Beaker::Aixer
when /solaris/
when /^solaris$/
Beaker::Solaris
when /vsphere/
when /^vsphere$/
Beaker::Vsphere
when /fusion/
when /^fusion$/
Beaker::Fusion
when /blimpy/
when /^blimpy$/
Beaker::Blimper
when /ec2/
when /^ec2$/
Beaker::AwsSdk
when /vcloud/
when /^vcloud$/
if options['pooling_api']
Beaker::VcloudPooled
else
Beaker::Vcloud
end
when /vagrant/
when /^vagrant$/
Beaker::Vagrant
when /google/
when /^vagrant_virtualbox$/
Beaker::VagrantVirtualbox
when /^vagrant_fusion$/
Beaker::VagrantFusion
when /^vagrant_workstation$/
Beaker::VagrantWorkstation
when /^google$/
Beaker::GoogleCompute
when /docker/
when /^docker$/
Beaker::Docker
when /openstack/
when /^openstack$/
Beaker::OpenStack
when /none/
when /^none$/
Beaker::Hypervisor
else
# Custom hypervisor
Expand Down Expand Up @@ -110,6 +116,6 @@ def generate_host_name
end
end

[ 'vsphere_helper', 'vagrant', 'fusion', 'blimper', 'aws_sdk', 'vsphere', 'vcloud', 'vcloud_pooled', 'aixer', 'solaris', 'docker', 'google_compute', 'openstack' ].each do |lib|
[ 'vsphere_helper', 'vagrant', 'vagrant_virtualbox', 'vagrant_fusion', 'vagrant_workstation', 'fusion', 'blimper', 'aws_sdk', 'vsphere', 'vcloud', 'vcloud_pooled', 'aixer', 'solaris', 'docker', 'google_compute', 'openstack' ].each do |lib|
require "beaker/hypervisor/#{lib}"
end
27 changes: 9 additions & 18 deletions lib/beaker/hypervisor/vagrant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,28 @@ def make_vfile hosts, options = {}
v_file << " v.vm.base_mac = '#{randmac}'\n"
v_file << " v.vm.network :private_network, ip: \"#{host['ip'].to_s}\", :netmask => \"#{host['netmask'] ||= "255.255.0.0"}\"\n"

if host['disk_path']
v_file << " v.vm.provider :virtualbox do |vb|\n"
v_file << " vb.name = '#{host.name}'\n"
unless File.exist?(host['disk_path'])
host['disk_path'] = File.join(host['disk_path'], "#{host.name}.vmdk")
v_file << " vb.customize ['createhd', '--filename', '#{host['disk_path']}', '--size', #{host['disk_size'] ||= 5 * 1024}, '--format', 'vmdk']\n"
end
v_file << " vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium','#{host['disk_path']}']\n"
v_file << " vb.customize [\"modifyvm\", :id, \"--natdnshostresolver1\", \"#{host['natdns']}\"]\n" unless host['natdns'].nil?
v_file << " vb.customize [\"modifyvm\", :id, \"--natdnsproxy1\", \"#{host['natdns']}\"]\n" unless host['natdns'].nil?
v_file << " end\n"
end

if /windows/i.match(host['platform'])
v_file << " v.vm.network :forwarded_port, guest: 3389, host: 3389\n"
v_file << " v.vm.network :forwarded_port, guest: 5985, host: 5985, id: 'winrm', auto_correct: true\n"
v_file << " v.vm.guest = :windows"
end

v_file << self.class.provider_vfile_section(host, options)

v_file << " end\n"
@logger.debug "created Vagrantfile for VagrantHost #{host.name}"
end
v_file << " c.vm.provider :virtualbox do |vb|\n"
v_file << " vb.customize [\"modifyvm\", :id, \"--memory\", \"#{options['vagrant_memsize'] ||= '1024'}\"]\n"
v_file << " end\n"
v_file << "end\n"
File.open(@vagrant_file, 'w') do |f|
f.write(v_file)
end
end

def self.provider_vfile_section host, options
# Backwards compatibility; default to virtualbox
Beaker::VagrantVirtualbox.provider_vfile_section(host, options)
end

def set_ssh_config host, user
f = Tempfile.new("#{host.name}")
ssh_config = Dir.chdir(@vagrant_path) do
Expand Down Expand Up @@ -113,7 +104,7 @@ def initialize(vagrant_hosts, options)

end

def provision
def provision(provider = nil)
if !@options[:provision] and !File.file?(@vagrant_file)
raise "Beaker is configured with provision = false but no vagrant file was found at #{@vagrant_file}. You need to enable provision"
end
Expand All @@ -124,7 +115,7 @@ def provision

make_vfile @hosts, @options

vagrant_cmd("up")
vagrant_cmd("up#{" --provider #{provider}" if provider}")
else #set host ip of already up boxes
@hosts.each do |host|
host[:ip] = get_ip_from_vagrant_file(host.name)
Expand Down
17 changes: 17 additions & 0 deletions lib/beaker/hypervisor/vagrant_fusion.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require 'beaker/hypervisor/vagrant'

class Beaker::VagrantFusion < Beaker::Vagrant
def provision(provider = 'vmware_fusion')
# By default vmware_fusion creates a .vagrant directory relative to the
# Vagrantfile path. That means beaker tries to scp the VM to itself unless
# we move the VM files elsewhere.
ENV['VAGRANT_VMWARE_CLONE_DIRECTORY'] = '~/.vagrant/vmware_fusion'
super
end

def self.provider_vfile_section(host, options)
" v.vm.provider :vmware_fusion do |v|\n" +
" v.vmx['memsize'] = '#{options['vagrant_memsize'] ||= '1024'}'\n" +
" end\n"
end
end
26 changes: 26 additions & 0 deletions lib/beaker/hypervisor/vagrant_virtualbox.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'beaker/hypervisor/vagrant'

class Beaker::VagrantVirtualbox < Beaker::Vagrant
def provision(provider = 'virtualbox')
super
end

def self.provider_vfile_section(host, options)
provider_section = ""
provider_section << " v.vm.provider :virtualbox do |vb|\n"
provider_section << " vb.customize ['modifyvm', :id, '--memory', '#{options['vagrant_memsize'] ||= '1024'}']\n"
if host['disk_path']
unless File.exist?(host['disk_path'])
host['disk_path'] = File.join(host['disk_path'], "#{host.name}.vmdk")
provider_section << " vb.customize ['createhd', '--filename', '#{host['disk_path']}', '--size', #{host['disk_size'] ||= 5 * 1024}, '--format', 'vmdk']\n"
end
provider_section << " vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium','#{host['disk_path']}']\n"
provider_section << " vb.customize [\"modifyvm\", :id, \"--natdnshostresolver1\", \"#{host['natdns']}\"]\n" unless host['natdns'].nil?
provider_section << " vb.customize [\"modifyvm\", :id, \"--natdnsproxy1\", \"#{host['natdns']}\"]\n" unless host['natdns'].nil?
provider_section << " end\n"
end
provider_section << " end\n"

provider_section
end
end
13 changes: 13 additions & 0 deletions lib/beaker/hypervisor/vagrant_workstation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'beaker/hypervisor/vagrant'

class Beaker::VagrantWorkstation < Beaker::Vagrant
def provision(provider = 'vmware_workstation')
super
end

def self.provider_vfile_section(host, options)
" v.vm.provider :vmware_workstation do |v|\n" +
" v.vmx['memsize'] = '#{options['vagrant_memsize'] ||= '1024'}'\n" +
" end\n"
end
end
14 changes: 14 additions & 0 deletions spec/beaker/hypervisor/hypervisor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ module Beaker
expect( hypervisor.create( 'vagrant', [], make_opts() ) ).to be === vagrant
end

it "creates a vagrant_fusion hypervisor for vagrant vmware fusion hosts" do
vagrant = double( 'vagrant_fusion' )
vagrant.stub( :provision ).and_return( true )
VagrantFusion.should_receive( :new ).once.and_return( vagrant )
expect( hypervisor.create( 'vagrant_fusion', [], make_opts() ) ).to be === vagrant
end

it "creates a vagrant_virtualbox hypervisor for vagrant virtualbox hosts" do
vagrant = double( 'vagrant_virtualbox' )
vagrant.stub( :provision ).and_return( true )
VagrantVirtualbox.should_receive( :new ).once.and_return( vagrant )
expect( hypervisor.create( 'vagrant_virtualbox', [], make_opts() ) ).to be === vagrant
end

it "creates a blimpy hypervisor for blimpy hosts" do
blimpy = double( 'blimpy' )
blimpy.stub( :provision ).and_return( true )
Expand Down
34 changes: 34 additions & 0 deletions spec/beaker/hypervisor/vagrant_fusion_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'spec_helper'

describe Beaker::VagrantFusion do
let( :options ) { make_opts.merge({ :hosts_file => 'sample.cfg', 'logger' => double().as_null_object }) }
let( :vagrant ) { Beaker::VagrantFusion.new( @hosts, options ) }

before :each do
@hosts = make_hosts()
end

it "uses the vmware_fusion provider for provisioning" do
@hosts.each do |host|
host_prev_name = host['user']
vagrant.should_receive( :set_ssh_config ).with( host, 'vagrant' ).once
vagrant.should_receive( :copy_ssh_to_root ).with( host, options ).once
vagrant.should_receive( :set_ssh_config ).with( host, host_prev_name ).once
end
vagrant.should_receive( :hack_etc_hosts ).with( @hosts, options ).once
FakeFS.activate!
vagrant.should_receive( :vagrant_cmd ).with( "up --provider vmware_fusion" ).once
vagrant.provision
end

it "can make a Vagranfile for a set of hosts" do
FakeFS.activate!
path = vagrant.instance_variable_get( :@vagrant_path )
vagrant.stub( :randmac ).and_return( "0123456789" )

vagrant.make_vfile( @hosts )

vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
expect( vagrantfile ).to include( %Q{ v.vm.provider :vmware_fusion do |v|\n v.vmx['memsize'] = '1024'\n end})
end
end
41 changes: 39 additions & 2 deletions spec/beaker/hypervisor/vagrant_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,44 @@ module Beaker

vagrant.make_vfile( @hosts )

expect( File.read( File.expand_path( File.join( path, "Vagrantfile") ) ) ).to be === "Vagrant.configure(\"2\") do |c|\n c.vm.define 'vm1' do |v|\n v.vm.hostname = 'vm1'\n v.vm.box = 'vm1_of_my_box'\n v.vm.box_url = 'http://address.for.my.box.vm1'\n v.vm.box_check_update = 'true'\n v.vm.base_mac = '0123456789'\n v.vm.network :private_network, ip: \"ip.address.for.vm1\", :netmask => \"255.255.0.0\"\n end\n c.vm.define 'vm2' do |v|\n v.vm.hostname = 'vm2'\n v.vm.box = 'vm2_of_my_box'\n v.vm.box_url = 'http://address.for.my.box.vm2'\n v.vm.box_check_update = 'true'\n v.vm.base_mac = '0123456789'\n v.vm.network :private_network, ip: \"ip.address.for.vm2\", :netmask => \"255.255.0.0\"\n end\n c.vm.define 'vm3' do |v|\n v.vm.hostname = 'vm3'\n v.vm.box = 'vm3_of_my_box'\n v.vm.box_url = 'http://address.for.my.box.vm3'\n v.vm.box_check_update = 'true'\n v.vm.base_mac = '0123456789'\n v.vm.network :private_network, ip: \"ip.address.for.vm3\", :netmask => \"255.255.0.0\"\n end\n c.vm.provider :virtualbox do |vb|\n vb.customize [\"modifyvm\", :id, \"--memory\", \"1024\"]\n end\nend\n"
vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
expect( vagrantfile ).to be === <<-EOF
Vagrant.configure("2") do |c|
c.vm.define 'vm1' do |v|
v.vm.hostname = 'vm1'
v.vm.box = 'vm1_of_my_box'
v.vm.box_url = 'http://address.for.my.box.vm1'
v.vm.box_check_update = 'true'
v.vm.base_mac = '0123456789'
v.vm.network :private_network, ip: "ip.address.for.vm1", :netmask => "255.255.0.0"
v.vm.provider :virtualbox do |vb|
vb.customize ['modifyvm', :id, '--memory', '1024']
end
end
c.vm.define 'vm2' do |v|
v.vm.hostname = 'vm2'
v.vm.box = 'vm2_of_my_box'
v.vm.box_url = 'http://address.for.my.box.vm2'
v.vm.box_check_update = 'true'
v.vm.base_mac = '0123456789'
v.vm.network :private_network, ip: "ip.address.for.vm2", :netmask => "255.255.0.0"
v.vm.provider :virtualbox do |vb|
vb.customize ['modifyvm', :id, '--memory', '1024']
end
end
c.vm.define 'vm3' do |v|
v.vm.hostname = 'vm3'
v.vm.box = 'vm3_of_my_box'
v.vm.box_url = 'http://address.for.my.box.vm3'
v.vm.box_check_update = 'true'
v.vm.base_mac = '0123456789'
v.vm.network :private_network, ip: "ip.address.for.vm3", :netmask => "255.255.0.0"
v.vm.provider :virtualbox do |vb|
vb.customize ['modifyvm', :id, '--memory', '1024']
end
end
end
EOF
end

it "generates a valid windows config" do
Expand Down Expand Up @@ -59,7 +96,7 @@ module Beaker

generated_file = File.read( File.expand_path( File.join( path, "Vagrantfile") ) )

match = generated_file.match(/vb.customize \["modifyvm", :id, "--memory", "hello!"\]/)
match = generated_file.match(/vb.customize \['modifyvm', :id, '--memory', 'hello!'\]/)

expect( match ).to_not be nil

Expand Down
34 changes: 34 additions & 0 deletions spec/beaker/hypervisor/vagrant_virtualbox_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'spec_helper'

describe Beaker::VagrantVirtualbox do
let( :options ) { make_opts.merge({ :hosts_file => 'sample.cfg', 'logger' => double().as_null_object }) }
let( :vagrant ) { Beaker::VagrantVirtualbox.new( @hosts, options ) }

before :each do
@hosts = make_hosts()
end

it "uses the virtualbox provider for provisioning" do
@hosts.each do |host|
host_prev_name = host['user']
vagrant.should_receive( :set_ssh_config ).with( host, 'vagrant' ).once
vagrant.should_receive( :copy_ssh_to_root ).with( host, options ).once
vagrant.should_receive( :set_ssh_config ).with( host, host_prev_name ).once
end
vagrant.should_receive( :hack_etc_hosts ).with( @hosts, options ).once
FakeFS.activate!
vagrant.should_receive( :vagrant_cmd ).with( "up --provider virtualbox" ).once
vagrant.provision
end

it "can make a Vagranfile for a set of hosts" do
FakeFS.activate!
path = vagrant.instance_variable_get( :@vagrant_path )
vagrant.stub( :randmac ).and_return( "0123456789" )

vagrant.make_vfile( @hosts )

vagrantfile = File.read( File.expand_path( File.join( path, 'Vagrantfile' )))
expect( vagrantfile ).to include( %Q{ v.vm.provider :virtualbox do |vb|\n vb.customize ['modifyvm', :id, '--memory', '1024']\n end})
end
end
34 changes: 34 additions & 0 deletions spec/beaker/hypervisor/vagrant_workstation_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'spec_helper'

describe Beaker::VagrantWorkstation do
let( :options ) { make_opts.merge({ :hosts_file => 'sample.cfg', 'logger' => double().as_null_object }) }
let( :vagrant ) { Beaker::VagrantWorkstation.new( @hosts, options ) }

before :each do
@hosts = make_hosts()
end

it "uses the vmware_workstation provider for provisioning" do
@hosts.each do |host|
host_prev_name = host['user']
vagrant.should_receive( :set_ssh_config ).with( host, 'vagrant' ).once
vagrant.should_receive( :copy_ssh_to_root ).with( host, options ).once
vagrant.should_receive( :set_ssh_config ).with( host, host_prev_name ).once
end
vagrant.should_receive( :hack_etc_hosts ).with( @hosts, options ).once
FakeFS.activate!
vagrant.should_receive( :vagrant_cmd ).with( "up --provider vmware_workstation" ).once
vagrant.provision
end

it "can make a Vagranfile for a set of hosts" do
FakeFS.activate!
path = vagrant.instance_variable_get( :@vagrant_path )
vagrant.stub( :randmac ).and_return( "0123456789" )

vagrant.make_vfile( @hosts )

vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
expect( vagrantfile ).to include( %Q{ v.vm.provider :vmware_workstation do |v|\n v.vmx['memsize'] = '1024'\n end})
end
end

1 comment on commit fdcbac3

@adamjk-dev
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be sweet if this added a vagrant_aws provider as well. The new hypervisor type would use the vagrant-aws plugin and allow setting VPCs, IP addresses, security groups, etc.

Please sign in to comment.