lib/vagrant-vcenter/action/build_vm.rb in vagrant-vcenter-0.3.2 vs lib/vagrant-vcenter/action/build_vm.rb in vagrant-vcenter-0.3.3
- old
+ new
@@ -1,8 +1,5 @@
-require 'securerandom'
-require 'etc'
-
module VagrantPlugins
module VCenter
module Action
# This class builds the VM to be used by Vagrant.
class BuildVM
@@ -13,71 +10,64 @@
def call(env)
# FIXME: we need to find a way to clean things up when a SIGINT get
# called... see env[:interrupted] in the vagrant code
- config = env[:machine].provider_config
+ cfg = env[:machine].provider_config
vm_name = env[:machine].name
- # FIXME: Raise a correct exception
- dc = config.vcenter_cnx.serviceInstance.find_datacenter(
- config.datacenter_name) or abort 'datacenter not found'
-
- if env[:machine].box.name.to_s.include? '/'
- box_file = env[:machine].box.name.rpartition('/').last.to_s
- box_name = env[:machine].box.name.to_s.gsub(/\//, '-')
+ if env[:machine].box.name.include? '/'
+ # box_file = env[:machine].box.name.rpartition('/').last
+ box_name = env[:machine].box.name.gsub(/\//, '-')
else
- box_file = env[:machine].box.name.to_s
+ box_file = env[:machine].box.name
box_name = box_file
end
- if config.template_folder_name.nil?
+ if cfg.template_folder_name.nil?
box_to_search = box_name
else
- box_to_search = config.template_folder_name + '/' +
- box_name
+ box_to_search = cfg.template_folder_name + '/' + box_name
end
- # FIXME: Raise a correct exception
- computer = dc.find_compute_resource(
- config.computer_name) or fail 'Host not found'
-
- if config.resourcepool_name
- rp = computer.resourcePool.resourcePool.find {
- |f| f.name == config.resourcepool_name
+ if cfg.resourcepool_name
+ cfg.compute_rp = compute.resourcePool.resourcePool.find {
+ |f| f.name == cfg.resourcepool_name
}
else
- rp = computer.resourcePool
+ cfg.compute_rp = cfg.compute.resourcePool
end
- # FIXME: Raise a correct exception
- template = dc.find_vm(
- box_to_search) or abort 'VM not found'
+ template = cfg.datacenter.find_vm(box_to_search) or
+ fail Errors::VMNotFound,
+ :vm_name => box_to_search
- if config.linked_clones
+ if cfg.linked_clones
@logger.debug('DOING LINKED CLONE!')
# The API for linked clones is quite strange. We can't create a
# linked straight from any VM. The disks of the VM for which we can
# create a linked clone need to be read-only and thus VC demands
# that the VM we are cloning from uses delta-disks. Only then it
# will allow us to share the base disk.
#
# Thus, this code first create a delta disk on top of the base disk
# for the to-be-cloned VM, if delta disks aren't used already.
disks = template.config.hardware.device.grep(
- RbVmomi::VIM::VirtualDisk)
+ RbVmomi::VIM::VirtualDisk
+ )
+
disks.select { |x| x.backing.parent.nil? }.each do |disk|
spec = {
:deviceChange => [
{
- :operation => :remove,
- :device => disk
+ :operation => :remove,
+ :device => disk
},
{
- :operation => :add,
- :fileOperation => :create,
- :device => disk.dup.tap do |x|
+ :operation => :add,
+ :fileOperation => :create,
+ :device => disk.dup.tap do |x|
x.backing = x.backing.dup
x.backing.fileName = "[#{disk.backing.datastore.name}]"
x.backing.parent = disk.backing
end
}
@@ -85,154 +75,172 @@
}
template.ReconfigVM_Task(:spec => spec).wait_for_completion
end
relocate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(
- :diskMoveType => :moveChildMostDiskBacking,
- :pool => rp)
+ :diskMoveType => :moveChildMostDiskBacking,
+ :pool => cfg.compute_rp
+ )
else
relocate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(
- :pool => rp)
+ :pool => cfg.compute_rp
+ )
end
@logger.debug("Relocate Spec: #{relocate_spec.pretty_inspect}")
spec = RbVmomi::VIM.VirtualMachineCloneSpec(
- :location => relocate_spec,
- :powerOn => false,
- :template => false)
-
- if config.vm_network_name or config.num_cpu or config.memory
+ :location => relocate_spec,
+ :powerOn => false,
+ :template => false
+ )
+
+ if cfg.vm_network_name || cfg.num_cpu || cfg.memory
config_spec = RbVmomi::VIM.VirtualMachineConfigSpec
- config_spec.numCPUs = config.num_cpu if config.num_cpu
- config_spec.memoryMB = config.memory if config.memory
-
- if config.vm_network_name
- # First we must find the specified network
- network = dc.network.find { |f| f.name == config.vm_network_name } or
- abort "Could not find network with name #{config.vm_network_name} to join vm to"
+ config_spec.numCPUs = cfg.num_cpu if cfg.num_cpu
+ config_spec.memoryMB = cfg.memory if cfg.memory
+
+ if cfg.vm_network_name
card = template.config.hardware.device.grep(
- RbVmomi::VIM::VirtualEthernetCard).first or
- abort "could not find network card to customize"
- if config.vm_network_type == "DistributedVirtualSwitchPort"
- switch_port = RbVmomi::VIM.DistributedVirtualSwitchPortConnection(
- :switchUuid => network.config.distributedVirtualSwitch.uuid,
- :portgroupKey => network.key)
+ RbVmomi::VIM::VirtualEthernetCard
+ ).first or abort 'could not find network card to customize'
+
+ if cfg.vm_network_type == 'DistributedVirtualSwitchPort'
+ switch_port =
+ RbVmomi::VIM.DistributedVirtualSwitchPortConnection(
+ :switchUuid => cfg.network.config.distributedVirtualSwitch.uuid,
+ :portgroupKey => cfg.network.key
+ )
card.backing = RbVmomi::VIM.VirtualEthernetCardDistributedVirtualPortBackingInfo(
- :port => switch_port)
- end
- dev_spec = RbVmomi::VIM.VirtualDeviceConfigSpec(:device => card, :operation => "edit")
+ :port => switch_port
+ )
+ end
+
+ dev_spec = RbVmomi::VIM.VirtualDeviceConfigSpec(
+ :device => card,
+ :operation => 'edit'
+ )
config_spec.deviceChange = [dev_spec]
end
spec.config = config_spec
end
- if config.enable_vm_customization
+ if cfg.enable_vm_customization
public_networks = env[:machine].config.vm.networks.select {
- |n| n[0].eql? :public_network
+ |n| n[0].eql? :public_network
}
network_spec = public_networks.first[1] unless public_networks.empty?
@logger.debug("This is our network #{public_networks.inspect}")
if network_spec
-
# Check for sanity and validation of network parameters.
-
- # Specify ip but no netmask
- if network_spec[:ip] && !network_spec[:netmask]
+ if (network_spec[:ip] && !network_spec[:netmask]) ||
+ (!network_spec[:ip] && network_spec[:netmask])
fail Errors::WrongNetworkSpec
end
- # specify netmask but no ip
- if !network_spec[:ip] && network_spec[:netmask]
- fail Errors::WrongNetworkSpec
- end
-
global_ip_settings = RbVmomi::VIM.CustomizationGlobalIPSettings(
- :dnsServerList => network_spec[:dns_server_list],
- :dnsSuffixList => network_spec[:dns_suffix_list])
+ :dnsServerList => network_spec[:dns_server_list],
+ :dnsSuffixList => network_spec[:dns_suffix_list]
+ )
# if no ip and no netmask, let's default to dhcp
if !network_spec[:ip] && !network_spec[:netmask]
adapter = RbVmomi::VIM.CustomizationIPSettings(
- :ip => RbVmomi::VIM.CustomizationDhcpIpGenerator())
+ :ip => RbVmomi::VIM.CustomizationDhcpIpGenerator()
+ )
else
adapter = RbVmomi::VIM.CustomizationIPSettings(
- :gateway => [network_spec[:gateway]],
- :ip => RbVmomi::VIM.CustomizationFixedIp(
- :ipAddress => network_spec[:ip]),
- :subnetMask => network_spec[:netmask])
+ :gateway => [network_spec[:gateway]],
+ :ip => RbVmomi::VIM.CustomizationFixedIp(
+ :ipAddress => network_spec[:ip]
+ ),
+ :subnetMask => network_spec[:netmask]
+ )
end
- nic_map = [RbVmomi::VIM.CustomizationAdapterMapping(
- :adapter => adapter)]
+ nic_map = [
+ RbVmomi::VIM.CustomizationAdapterMapping(:adapter => adapter)
+ ]
end
- if config.prep_type.downcase == 'linux'
+ if cfg.prep_type.downcase == 'linux'
prep = RbVmomi::VIM.CustomizationLinuxPrep(
- :domain => env[:machine].name.to_s.sub(/^[^.]+\./, ''),
- :hostName => RbVmomi::VIM.CustomizationFixedName(
- :name => env[:machine].name.to_s.split('.')[0]))
- elsif config.prep_type.downcase == 'windows'
+ :domain => env[:machine].name.to_s.sub(/^[^.]+\./, ''),
+ :hostName => RbVmomi::VIM.CustomizationFixedName(
+ :name => env[:machine].name.to_s.split('.')[0]
+ )
+ )
+ elsif cfg.prep_type.downcase == 'windows'
prep = RbVmomi::VIM.CustomizationSysprep(
- :guiUnattended => RbVmomi::VIM.CustomizationGuiUnattended(
- :autoLogon => false,
- :autoLogonCount => 0,
- :timeZone => 004
- ),
- :identification => RbVmomi::VIM.CustomizationIdentification(),
- :userData => RbVmomi::VIM.CustomizationUserData(
- :computerName => RbVmomi::VIM.CustomizationFixedName(
- :name => env[:machine].name.to_s.split('.')[0]),
- :fullName => 'Vagrant',
- :orgName => 'Vagrant',
- :productId => 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
- )
+ :guiUnattended => RbVmomi::VIM.CustomizationGuiUnattended(
+ :autoLogon => false,
+ :autoLogonCount => 0,
+ :timeZone => 004
+ ),
+ :identification => RbVmomi::VIM.CustomizationIdentification(),
+ :userData => RbVmomi::VIM.CustomizationUserData(
+ :computerName => RbVmomi::VIM.CustomizationFixedName(
+ :name => env[:machine].name.to_s.split('.')[0]
+ ),
+ :fullName => 'Vagrant',
+ :orgName => 'Vagrant',
+ :productId => 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
+ )
)
- else
- fail "specification type #{config.prep_type} not supported"
+ else
+ fail Errors::GuestCustomNotSupported,
+ :type => cfg.prep_type
end
if prep && network_spec
- # If prep and network specification are present, let's do a full config
+ # If prep and network specification are present,
+ # -> Do a full config
cust_spec = RbVmomi::VIM.CustomizationSpec(
- :globalIPSettings => global_ip_settings,
- :identity => prep,
- :nicSettingMap => nic_map)
+ :globalIPSettings => global_ip_settings,
+ :identity => prep,
+ :nicSettingMap => nic_map
+ )
spec.customization = cust_spec
elsif prep && !network_spec
# If no network specifications, default to dhcp
global_ip_settings = RbVmomi::VIM.CustomizationGlobalIPSettings(
:dnsServerList => [],
- :dnsSuffixList => [])
+ :dnsSuffixList => []
+ )
adapter = RbVmomi::VIM.CustomizationIPSettings(
- :ip => RbVmomi::VIM.CustomizationDhcpIpGenerator())
+ :ip => RbVmomi::VIM.CustomizationDhcpIpGenerator()
+ )
- nic_map = [RbVmomi::VIM.CustomizationAdapterMapping(
- :adapter => adapter)]
+ nic_map = [
+ RbVmomi::VIM.CustomizationAdapterMapping(:adapter => adapter)
+ ]
cust_spec = RbVmomi::VIM.CustomizationSpec(
- :globalIPSettings => global_ip_settings,
- :identity => prep,
- :nicSettingMap => nic_map)
+ :globalIPSettings => global_ip_settings,
+ :identity => prep,
+ :nicSettingMap => nic_map
+ )
spec.customization = cust_spec
end
@logger.debug("Spec: #{spec.pretty_inspect}")
end
- @logger.debug("disable_auto_vm_name: #{config.disable_auto_vm_name}")
+ @logger.debug("disable_auto_vm_name: #{cfg.disable_auto_vm_name}")
- if config.disable_auto_vm_name || config.disable_auto_vm_name == 'true'
- vm_target = vm_name.to_s
+ # Not recommended in a vSphere environment where VM names might
+ # conflict a lot if used in the same vm folder namespace
+ if cfg.disable_auto_vm_name == true
+ vm_target = vm_name
else
vm_target = "Vagrant-#{Etc.getlogin}-" +
"#{vm_name}-#{Socket.gethostname.downcase}-" +
"#{SecureRandom.hex(4)}"
end
@@ -240,46 +248,51 @@
@logger.debug("VM name: #{vm_target}")
# FIXME: vm.parent brings us to the template folder, fix this with
# folder_path.
- root_vm_folder = dc.vmFolder
- vm_folder = root_vm_folder
- unless config.folder_name.nil?
+ vm_folder = cfg.vmfolder
+ unless cfg.folder_name.nil?
begin
# Better ask for forgiveness than permission ;-)
- @logger.debug("Creating folder #{config.folder_name}.")
- vm_folder = root_vm_folder.traverse(config.folder_name,
- RbVmomi::VIM::Folder,
- create = true)
+ @logger.debug("Creating folder #{cfg.folder_name}.")
+ vm_folder = cfg.vmfolder.traverse(
+ cfg.folder_name,
+ RbVmomi::VIM::Folder,
+ create = true
+ )
# FIXME: we should trap the correct exception
rescue RbVmomi::Fault
# if somebody else created the folder already...
- @logger.debug("Folder #{config.folder_name} already exists.")
- vm_folder = root_vm_folder.traverse(config.folder_name,
- RbVmomi::VIM::Folder)
+ @logger.debug("Folder #{cfg.folder_name} already exists.")
+ vm_folder = cfg.vmfolder.traverse(
+ cfg.folder_name,
+ RbVmomi::VIM::Folder
+ )
end
end
@logger.debug("folder for VM: #{vm_folder}")
env[:ui].info('Creating VM...')
template.CloneVM_Task(
- :folder => vm_folder,
- :name => vm_target,
- :spec => spec).wait_for_completion
+ :folder => vm_folder,
+ :name => vm_target,
+ :spec => spec
+ ).wait_for_completion
- if config.folder_name.nil?
- vm_to_search = vm_target
+ if cfg.folder_name.nil?
+ vm_to_search = vm_target.to_s
else
- vm_to_search = config.folder_name + '/' + vm_target
+ vm_to_search = cfg.folder_name + '/' + vm_target.to_s
end
@logger.debug("VM to search: #{vm_to_search}")
- # FIXME: Raise a correct exception
- env[:machine].id = dc.find_vm(
- vm_to_search).config.uuid or abort 'VM not found'
+ env[:machine].id = cfg.datacenter.find_vm(
+ vm_to_search
+ ).config.uuid or fail Errors::VMNotFound,
+ :vm_name => vm_to_search
@app.call env
end
end
end