class RightImageTools::MCI
Public Class Methods
# File lib/mci.rb, line 9 def initialize(options = {}) @options = options @logger = (@options.key?(:logger)) ? @options[:logger] : Logger.new(STDOUT) @api_url = Tag.connection.settings[:api_url] end
Public Instance Methods
Adds an image to an mci, if the image is not already attached to the mci
Parameters¶ ↑
image_id(String) - rightscale id of the image to add, which will equal
the ami-id for amazon and the resource_uid for other clouds
cloud_id(Number) - rightscale if of the cloud mci_name(String) - name of the mci to add this image to mci_id(String) - or (optionally) the rightscale id to add this image to instance_type - default instance type of the image, if not supplied
can usually guess
Return¶ ↑
- mci(MultiCloudImageCloudSettingInternal)
-
new or existing
MCI
setting
# File lib/mci.rb, line 59 def add_image_to_mci(options) cloud_id = options[:cloud_id].to_i image_id = options[:image_id].to_s mci_name = options[:name] || options[:mci_name] mci_id = options[:mci_id] || options[:id] description = options[:description] raise ArgumentError, ":cloud_id not supplied" unless cloud_id > 0 raise ArgumentError, ":image_id not supplied" unless image_id =~ /./ raise ArgumentError, "MCI name (:name) or id (:mci_id) not supplied" unless (mci_name =~ /./ || mci_id.to_s =~ /^\d+$/) raise ArgumentError, "MCI (:mci_id) supplied but an integer" if mci_id and mci_id.to_s !~ /^\d+$/ if api_version(cloud_id) == "1.0" image_id = image_id.split("/").last unless image_id =~ /^ami-[0-9a-z]+$/ raise ArgumentError, "image_id #{image_id} doesn't look like an amazon ami" end end mci = find_mci_by_id(cloud_id, mci_id) if mci_id mci = find_mci(cloud_id, mci_name) unless mci #validate_mci_name(mci_name) unless mci mci = create_mci(cloud_id, mci_name, description) unless mci add_rightlink_tag(mci) mci_setting = find_or_create_cloud_setting(mci, image_id, cloud_id, options) return mci.href end
# File lib/mci.rb, line 218 def add_rightlink_tag(mci) tag = "provides:rs_agent_type=right_link" add_tag_to_mci(mci, tag) end
- mci(MultiCloudImageInternal)
-
the
MCI
to add the tag to
Tag an mci or raise an error on failure
# File lib/mci.rb, line 225 def add_tag_to_mci(mci, tag) begin @logger.info "Adding tag #{tag} to #{mci.href}" href = mci.href result = Tag.set(href, ["#{tag}"]) @logger.debug("Successfully tagged MCI. Code: #{result.code}") rescue Exception => e @logger.error("Failed to tag MCI #{mci.name}! #{e.inspect}") raise e end end
# File lib/mci.rb, line 237 def api_version(cloud_id) cloud_id.to_i < 50 ? "1.0" : "1.5" end
# File lib/mci.rb, line 156 def create_cloud_setting(mci, image_id, cloud_id, instance_type) mci_setting = nil if api_version(cloud_id) == "1.0" # create the setting image_href = "#{@api_url}/ec2_images/#{image_id}?cloud_id=#{cloud_id}" mci_setting = MultiCloudImageCloudSettingInternal.create( :multi_cloud_image_href => mci.href, :cloud_id => cloud_id.to_i, :ec2_image_href => image_href, :aws_instance_type => instance_type) else image = McImage.find_all(cloud_id.to_i).find { |img| img.resource_uid.to_s == image_id.to_s } raise "No image found for cloud #{cloud_id} with id #{image_id}" unless image @logger.debug("Found image id #{image_id} with href #{image.href}") mci_id = mci.href.split("/").last # debugger mci_setting = McMultiCloudImageSetting.create(mci_id, :cloud_href => "/api/clouds/#{cloud_id}", :image_href => image.href, :instance_type_href => instance_type) end mci_setting end
Create dummy/destroy dummy settings get around a bug in which we have to replace the (lone) setting for an MCI
but can’t delete it since its the last one left So temporarily add a dummy image to get around the check, then delete it right after
# File lib/mci.rb, line 146 def create_dummy_setting(mci, cloud_id) dummy_cloud_id = cloud_id.to_i == 1 ? 2 : 1 dummy_image_id = dummy_cloud_id == 1 ? "ami-41814f28" : "ami-f45beff5" create_cloud_setting(mci, dummy_image_id, dummy_cloud_id, "m1.small") end
# File lib/mci.rb, line 204 def create_mci(cloud_id, mci_name, description = nil) description ||= default_description(mci_name, api_version(cloud_id) == "1.0") @logger.info("Creating mci #{mci_name}") mci = MultiCloudImageInternal.create( :name => mci_name, :description => description) raise "Could not create MCI" unless mci mci = MultiCloudImage.find(mci.rs_id.to_i) mci.find_and_flatten_settings return mci end
# File lib/mci.rb, line 15 def default_description(mci_name, is_ec2 = false) # 32-Bit Image description # OsName NN.NN Hypervisor with 32-bit architecture (i386) # 64-Bit image description # OsName NN.NN Hypervisor with 64-bit architecture (x64) # os = (mci_name =~ /(centos|ubuntu|windows|rhel)/i) ? $1 : "" os_version = "" unless os.empty? os_version = (mci_name =~ /#{os}[\s_](\d+\.\d+)/) ? $1 : "" end os_arch = (mci_name =~ /(i[3|6]86|x64|x86_64|amd64)/i) ? $1 : "" hypervisor = (mci_name =~ /(xenserver|xen|vmware|esxi|kvm)/i) ? $1 : "" rl_version = (mci_name =~ /v(\d+\.\d+)/) ? $1 : "" description = "Development build:" description << " #{os}" if os description << " #{os_version}" if os_version description << " #{hypervisor}" if !hypervisor.empty? && !is_ec2 if os_arch if os_arch =~ /i[3|6]86/ description << " with 32-bit architecture (#{os_arch})" else description << " with 64-bit architecture (#{os_arch})" end end description << " and RightLink #{rl_version}" if rl_version description << "." end
# File lib/mci.rb, line 152 def destroy_dummy_setting(setting) setting.destroy end
# File lib/mci.rb, line 91 def find_cloud_setting(mci,cloud_id) mci.multi_cloud_image_cloud_settings.find { |s| s.cloud_id.to_i == cloud_id.to_i } end
# File lib/mci.rb, line 189 def find_mci(cloud_id, mci_name) mcis = MultiCloudImage.find_all. select {|n| n.is_head_version && n.name == mci_name } mci_ids = mcis.map { |m| m.rs_id } @logger.warn("Found multiple MCIs with name #{mci_name}: #{mci_ids.join(', ')}") if mcis.length > 1 if mcis.length > 0 existing_mci = mcis.first existing_mci.find_and_flatten_settings @logger.info("Found mci #{existing_mci.rs_id}") if existing_mci return existing_mci else return nil end end
return MultiCloudImageInternal, or nil
# File lib/mci.rb, line 181 def find_mci_by_id(cloud_id, mci_id) existing_mci = MultiCloudImage.find(mci_id.to_i) existing_mci.find_and_flatten_settings raise ArgumentError, "Could not find #{existing_mci.rs_id}" unless existing_mci @logger.info("Using mci #{existing_mci.rs_id} named #{existing_mci.name}") existing_mci end
# File lib/mci.rb, line 107 def find_or_create_cloud_setting(mci, image_id, cloud_id, options = {}) # debugger mci_setting = find_cloud_setting(mci, cloud_id) instance_type = options[:instance_type] || guess_default_instance_type(cloud_id) if mci_setting unless setting_exists?(mci_setting, image_id, cloud_id) @logger.warn("Replacing image for cloud #{cloud_id} for MCI #{mci.rs_id}") dummy_setting = nil if mci.multi_cloud_image_cloud_settings.length <= 1 dummy_setting = create_dummy_setting(mci, cloud_id) end res = mci_setting.destroy raise "Non success code returned #{res.inspect} " if res.code.to_s !~ /^2\d\d$/ mci_setting = create_cloud_setting(mci, image_id, cloud_id, instance_type) destroy_dummy_setting(dummy_setting) if dummy_setting end else @logger.info("Adding cloud images to MCI #{mci.href}") mci_setting = create_cloud_setting(mci, image_id, cloud_id, instance_type) #returns nil end mci_setting end
# File lib/mci.rb, line 95 def guess_default_instance_type(cloud_id) if api_version(cloud_id) == "1.0" return "m1.small" else names = ["small instance", "1gb server", "nano-h-5", "standard.small", "small", "standard", "n1-standard-1-d", "m1.small", "s2", "1g" ] types = McInstanceType.find_all(cloud_id) type = types.find { |t| names.include? t.name.downcase } raise "Could not guess default instance type for cloud #{cloud_id}" unless type return type.href end end
# File lib/mci.rb, line 132 def setting_exists?(mci_setting, image_id, cloud_id) if api_version(cloud_id) == "1.0" return mci_setting.image_href.include?(image_id) else image = McImage.find_all(cloud_id.to_i).find { |img| img.resource_uid.to_s == image_id.to_s } raise "No image found for cloud #{cloud_id} with id #{image_id}" unless image return mci_setting.image == image.href end end
# File lib/mci.rb, line 88 def validate_mci_name(name) end