Class: RightImageTools::MCI

Inherits:
Object
  • Object
show all
Defined in:
lib/mci.rb

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ MCI

Returns a new instance of MCI.



9
10
11
12
13
# 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

Instance Method Details

#add_image_to_mci(options) ⇒ Object

Adds an image to an mci, if the image is not already attached to the mci

Parameters

image_id(String) cloud_id(Number) mci_name(String)

Return

mci(MultiCloudImageCloudSettingInternal)

new or existing MCI setting

Raises:

  • (ArgumentError)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/mci.rb', line 55

def add_image_to_mci(options)
  cloud_id = options[:cloud_id].to_i 
  image_id = options[:image_id]
  mci_name = options[:name]
  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) not supplied" unless mci_name =~ /./

  image_id = image_id.split("/").last

  if api_version(cloud_id) == "1.0"
    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(cloud_id, mci_name) 
  #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) 

  # Create the MCIs, if they don't exist.

  return mci.href
end


179
180
181
182
# File 'lib/mci.rb', line 179

def add_rightlink_tag(mci)
  tag = "provides:rs_agent_type=right_link"
  add_tag_to_mci(mci, tag)
end

#add_tag_to_mci(mci, tag) ⇒ Object

mci(MultiCloudImageInternal)

the MCI to add the tag to

Tag an mci or raise an error on failure



186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/mci.rb', line 186

def add_tag_to_mci(mci, tag)
  begin
    @logger.info "Adding tag #{tag} to #{mci.href}"
    href = mci.href
    result = Tag.set(href, ["#{tag}"])
    #update_connection_settings(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

#api_version(cloud_id) ⇒ Object



199
200
201
# File 'lib/mci.rb', line 199

def api_version(cloud_id)
  cloud_id.to_i < 50 ? "1.0" : "1.5"
end

#create_cloud_setting(mci, image_id, cloud_id, instance_type = nil) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/mci.rb', line 120

def create_cloud_setting(mci, image_id, cloud_id, instance_type = nil)
  mci_setting = nil
  if api_version(cloud_id) == "1.0"
    # create the setting
    #update_connection_settings(MultiCloudImageInternal)
    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 
    raise NotImplementedError, "API 1.5 not supported yet"
  end
  mci_setting
end

#create_mci(cloud_id, mci_name, description = nil) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/mci.rb', line 165

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 = nil

  #update_connection_settings(MultiCloudImageInternal)
  mci = MultiCloudImageInternal.create(
    :name        => mci_name,
    :description => description)

  raise "Could not create MCI" unless mci
  mci
end

#default_description(mci_name, is_ec2 = false) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 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

#find_cloud_setting(mci, cloud_id) ⇒ Object



91
92
93
94
# File 'lib/mci.rb', line 91

def find_cloud_setting(mci,cloud_id)
  mci_setting = nil
  mci_setting = mci.multi_cloud_image_cloud_settings.select { |setting| setting.cloud_id.to_i == cloud_id.to_i }.first
end

#find_mci(cloud_id, mci_name) ⇒ Object

return MultiCloudImageInternal, or nil



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/mci.rb', line 138

def find_mci(cloud_id, mci_name)
  mcis = []
  if api_version(cloud_id) == "1.0"
    #update_connection_settings(MultiCloudImage)
    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 = MultiCloudImageInternal.find(mcis.first.rs_id.to_i)
    end
  else
    # Double filter, find_with_filter is a wildcard ended match
    # Also revision 0 is HEAD
    #update_connection_settings(McMultiCloudImage)
    mcis = McMultiCloudImage.
      find_with_filter(:name=>mci_name).
      select {|mci| mci.name == mci_name}.
      select {|mci| mci.revision == 0}
    @logger.warn("Found multiple MCIs with name #{mci_name}") if mcis.length > 1
    existing_mci = mcis.first
  end

  @logger.info("Found mci #{existing_mci.rs_id}") if existing_mci
  existing_mci
end

#find_or_create_cloud_setting(mci, image_id, cloud_id) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/mci.rb', line 96

def find_or_create_cloud_setting(mci, image_id, cloud_id)
  mci_setting = nil;
  if api_version(cloud_id) == "1.0"
    mci_setting = find_cloud_setting(mci, cloud_id)
    instance_type = guess_instance_type(mci.name)

    if mci_setting
      unless mci_setting.image_href.include?(image_id)
        @logger.warn("Replacing image for cloud #{cloud_id} for MCI #{mci.rs_id}")
        res = mci_setting.destroy
        raise "Non success code returned #{res.inspect} " if res.code.to_s !~ /^2\d\d$/
        create_cloud_setting(mci, image_id, cloud_id, instance_type)
      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
  else 
    raise NotImplementedError, "API 1.5 not supported yet"
  end
  mci_setting
end

#guess_instance_type(mci_name) ⇒ Object



87
88
89
# File 'lib/mci.rb', line 87

def guess_instance_type(mci_name)
  mci_name =~ /i386/ ? "m1.small" : "m1.large"
end

#validate_mci_name(name) ⇒ Object



84
85
# File 'lib/mci.rb', line 84

def validate_mci_name(name)
end