def create_instance(credentials, image_id, opts)
vsphere = new_client(credentials)
safely do
if opts[:hwp_cpu]
raise "Invalid CPU value. Must be in integer format" unless valid_cpu_value?(opts[:hwp_cpu])
end
rootFolder = vsphere.serviceInstance.content.rootFolder
vm = find_vm(credentials, opts[:image_id])
raise "ERROR: Could not find the image in given datacenter" unless vm[:instance]
if opts and opts[:realm_id]
resourcePool = find_resource_pool(credentials, opts[:realm_id])
datastore = find_datastore(credentials, opts[:realm_id])
else
resourcePool = find_resource_pool(credentials, vm[:datastore])
datastore = find_datastore(credentials, vm[:datastore])
end
relocate = { :pool => resourcePool, :datastore => datastore }
relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec(relocate)
raise "ERROR: Memory must be multiple of 4" unless valid_memory_value?(opts[:hwp_memory])
machine_config = {
:memoryMB => opts[:hwp_memory],
:numCPUs => opts[:hwp_cpu],
:extraConfig => [
{ :key => 'template_id', :value => image_id },
]
}
if (opts[:user_data] and not opts[:user_data].empty?) and (opts[:user_iso] and not opts[:user_iso].empty?)
raise "ERROR: You cannot use user_data and user_iso features together"
end
if opts[:user_data] and not opts[:user_data].empty?
device = vm[:instance].config.hardware.device.select { |hw| hw.class == RbVmomi::VIM::VirtualCdrom }.first
if device
VSphere::FileManager::user_data!(datastore, opts[:user_data], "#{opts[:name]}.iso")
machine_config[:extraConfig] << {
:key => 'user_data_file', :value => "#{opts[:name]}.iso"
}
device.connectable.startConnected = true
device.backing = RbVmomi::VIM.VirtualCdromIsoBackingInfo(:fileName => "[#{opts[:realm_id] || vm[:datastore]}] "+
"/#{VSphere::FileManager::DIRECTORY_PATH}/#{opts[:name]}.iso")
machine_config.merge!({
:deviceChange => [{
:operation => :edit,
:device => device
}]
})
else
raise "Failed to inject data to device because there is no CD-ROM drive defined in given template"
end
end
if opts[:user_iso] and not opts[:user_iso].empty?
device = vm[:instance].config.hardware.device.select { |hw| hw.class == RbVmomi::VIM::VirtualCdrom }.first
if device
VSphere::FileManager::store_iso!(datastore, opts[:user_iso], "#{opts[:name]}.iso")
machine_config[:extraConfig] << {
:key => 'user_iso_file', :value => "#{opts[:name]}.iso"
}
device.connectable.startConnected = true
device.backing = RbVmomi::VIM.VirtualCdromIsoBackingInfo(:fileName => "[#{opts[:realm_id] || vm[:datastore]}] "+
"/#{VSphere::FileManager::DIRECTORY_PATH}/#{opts[:name]}.iso")
machine_config.merge!({
:deviceChange => [{
:operation => :edit,
:device => device
}]
})
else
raise "Failed to inject data to device because there is no CD-ROM drive defined in given template"
end
end
spec = RbVmomi::VIM.VirtualMachineCloneSpec(
:location => relocateSpec,
:powerOn => true,
:template => false,
:config => RbVmomi::VIM.VirtualMachineConfigSpec(machine_config)
)
instance_profile = InstanceProfile::new('default', :hwp_memory => opts[:hwp_memory], :hwp_cpu => opts[:hwp_cpu])
task = vm[:instance].CloneVM_Task(:folder => vm[:instance].parent, :name => opts[:name], :spec => spec)
new_instance = Instance::new(
:id => opts[:name],
:name => opts[:name],
:description => opts[:name],
:owner_id => credentials.user,
:image_id => opts[:image_id],
:realm_id => opts[:realm_id] || vm[:datastore],
:state => 'PENDING',
:public_addresses => [],
:private_addresses => [],
:instance_profile => instance_profile,
:actions => instance_actions_for( 'PENDING' ),
:create_image => false
)
map_task_to_instance(datastore, task.info.key, new_instance)
end
end