1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-25 02:50:08 +03:00

feature #2259: Use OpenNebula templates instead of file based erbs

This commit is contained in:
Daniel Molina 2013-10-03 19:38:13 +02:00
parent 8f5a102248
commit 35b2bbbd51
3 changed files with 184 additions and 54 deletions

View File

@ -64,18 +64,26 @@
# default 1
#:datastore_id:
# VM types allowed and its template file (inside templates directory)
:instance_types:
:m1.small:
:template: m1.small.erb
# Include terminated instances in the describe_instances xml
:describe_with_terminated_instances: = true
# Terminated VMs will be included in the list
# till the termination date + TERMINATED_INSTANCES_EXPIRATION_TIME is reached
:terminated_instances_expiration_time: 900
#############################################################
# [DEPRECATED] File based templates
#############################################################
# Use former file based templates for instance types instead
# of OpenNebula templates
:use_file_templates: false
# VM types allowed and its template file (inside templates directory)
:instance_types:
:m1.small:
:template: m1.small.erb
#############################################################
# Elastic IP
#############################################################

View File

@ -54,57 +54,133 @@ module Instance
TERMINATED_INSTANCES_EXPIRATION_TIME = 900
def run_instances(params)
# Get the instance type and path
if params['InstanceType'] != nil
instance_type_name = params['InstanceType']
instance_type = @config[:instance_types][instance_type_name.to_sym]
if instance_type != nil
path = @config[:template_location] + "/#{instance_type[:template]}"
end
# Get the image
img = nil
if params['ImageId'] =~ /ami\-(.+)/
img = $1
else
rc = OpenNebula::Error.new("InvalidAMIID.Malformed #{params['ImageId']}")
rc.ec2_code = "InvalidAMIID.Malformed"
return rc
end
# Get the image
tmp, img = params['ImageId'].split('-')
if @config[:use_file_templates]
# Get the instance type and path
if params['InstanceType'] != nil
instance_type_name = params['InstanceType']
instance_type = @config[:instance_types][instance_type_name.to_sym]
# Build the VM
erb_vm_info = Hash.new
erb_vm_info[:img_id] = img.to_i
erb_vm_info[:ec2_img_id] = params['ImageId']
erb_vm_info[:instance_type] = instance_type_name
erb_vm_info[:template] = path
erb_vm_info[:user_data] = params['UserData']
erb_vm_info[:public_key] = fetch_publickey(params)
erb_vm_info[:key_name] = params['KeyName']
template = ERB.new(File.read(erb_vm_info[:template]))
template_text = template.result(binding)
erb_vms = Array.new
min_count = params['MinCount'] || 1
max_count = params['MaxCount'] || min_count
max_count.to_i.times {
# Start the VM.
instance = VirtualMachine.new(VirtualMachine.build_xml, @client)
rc = instance.allocate(template_text)
if OpenNebula::is_error?(rc)
if erb_vms.size < min_count.to_i
erb_vms.each { |vm|
vm.finalize
}
return rc
if instance_type != nil
path = @config[:template_location] + "/#{instance_type[:template]}"
end
else
instance.info
erb_vms << instance
end
}
# Build the VM
erb_vm_info = Hash.new
erb_vm_info[:img_id] = img.to_i
erb_vm_info[:ec2_img_id] = params['ImageId']
erb_vm_info[:instance_type] = instance_type_name
erb_vm_info[:template] = path
erb_vm_info[:user_data] = params['UserData']
erb_vm_info[:public_key] = fetch_publickey(params)
erb_vm_info[:key_name] = params['KeyName']
template = ERB.new(File.read(erb_vm_info[:template]))
template_text = template.result(binding)
erb_vms = Array.new
min_count = params['MinCount'] || 1
max_count = params['MaxCount'] || min_count
max_count.to_i.times {
# Start the VM.
instance = VirtualMachine.new(VirtualMachine.build_xml, @client)
rc = instance.allocate(template_text)
if OpenNebula::is_error?(rc)
if erb_vms.size < min_count.to_i
erb_vms.each { |vm|
vm.finalize
}
return rc
end
else
instance.info
erb_vms << instance
end
}
else
template_pool = TemplatePool.new(@client)
rc = template_pool.info
if OpenNebula::is_error?(rc)
return rc
end
template_id = template_pool["VMTEMPLATE/TEMPLATE[EC2_INSTANCE_TYPE=\'#{params['InstanceType']}\']/../ID"]
if template_id.nil?
rc.ec2_code = "InvalidInstanceID.NotFound"
return rc
end
template = Template.new(Template.build_xml(template_id), @client)
rc = template.info
if OpenNebula.is_error?(rc)
rc.ec2_code = "InvalidInstanceID.NotFound"
return rc
end
merge_info = {}
merge_info["DISK"] = []
merge_info["DISK"] << {"IMAGE_ID" => img.to_i}
template.each("TEMPLATE/DISK") { |e|
merge_info["DISK"] << e.to_hash["DISK"]
}
merge_info["CONTEXT"] = {}
template.each("TEMPLATE/CONTEXT") { |e|
merge_info["CONTEXT"] = e.to_hash["CONTEXT"]
}
context = merge_info["CONTEXT"]
public_key = fetch_publickey(params)
context["EC2_PUBLIC_KEY"] = public_key if public_key
context["EC2_KEYNAME"] = params['KeyName'] if params['KeyName']
context["EC2_USER_DATA"] = params['UserData'] if params['UserData']
template_str = template_to_str(merge_info)
vm_id =
erb_vms = Array.new
min_count = params['MinCount'] || 1
max_count = params['MaxCount'] || min_count
max_count.to_i.times {
# Start the VM.
rc = template.instantiate("", false, template_str)
if OpenNebula::is_error?(rc)
if erb_vms.size < min_count.to_i
erb_vms.each { |vm|
vm.finalize
}
return rc
end
else
instance = VirtualMachine.new(VirtualMachine.build_xml(rc), @client)
instance.info
erb_vms << instance
end
}
end
erb_user_name = params['AWSAccessKeyId']
erb_version = params['Version']
@ -261,4 +337,50 @@ module Instance
return true
end
def template_to_str(attributes, indent=true)
if indent
ind_enter="\n"
ind_tab=' '
else
ind_enter=''
ind_tab=' '
end
str=attributes.collect do |key, value|
if value
str_line=""
if value.class==Array && !value.empty?
value.each do |value2|
str_line << key.to_s.upcase << "=[" << ind_enter
if value2 && value2.class==Hash
str_line << value2.collect do |key3, value3|
str = ind_tab + key3.to_s.upcase + "="
str += "\"#{value3.to_s}\"" if value3
str
end.compact.join(",\n")
end
str_line << "\n]\n"
end
elsif value.class==Hash && !value.empty?
str_line << key.to_s.upcase << "=[" << ind_enter
str_line << value.collect do |key3, value3|
str = ind_tab + key3.to_s.upcase + "="
str += "\"#{value3.to_s}\"" if value3
str
end.compact.join(",\n")
str_line << "\n]\n"
else
str_line<<key.to_s.upcase << "=" << "\"#{value.to_s}\""
end
str_line
end
end.compact.join("\n")
str
end
end

View File

@ -11,7 +11,7 @@
<% erb_vms.each { |vm| %>
<item>
<%= render_instance_id(vm) %>
<imageId><%= erb_vm_info[:ec2_img_id] %></imageId>
<imageId><%= params['ImageId'] %></imageId>
<instanceState><%= render_state(vm) %></instanceState>
<% if vm.has_elements?("TEMPLATE/NIC/IP") %>
<% ips_str = vm.retrieve_elements("TEMPLATE/NIC/IP").join(', ') %>
@ -25,7 +25,7 @@
<keyName><%= vm['TEMPLATE/CONTEXT/EC2_KEYNAME'] %></keyName>
<% end %>
<amiLaunchIndex><%= vm.id %></amiLaunchIndex>
<instanceType><%= erb_vm_info[:instance_type] %></instanceType>
<instanceType><%= params['InstanceType'] %></instanceType>
<%= render_launch_time(vm) %>
<placement>
<availabilityZone>default</availabilityZone>