Class: Nifty::Backends::Utils::Opennebula::ImageHandler

Inherits:
Handler
  • Object
show all
Defined in:
lib/nifty/backends/utils/opennebula/image_handler.rb

Overview

Handler for OpenNebula ImagePool

Author:

  • Michal Kimle

Constant Summary collapse

IMAGE_STATE_READY =
'READY'
IMAGE_STATE_DISABLED =
'DISABLED'
IMAGE_STATE_USED =
'USED'
IMAGE_STATE_ERROR =
'ERROR'
TIME_FORMAT =
'%Y%m%d%H%M%S'
ATTRIBUTE_EXPIRATION =
'NIFTY_EXPIRATION'
ATTRIBUTE_OUTDATED =
'NIFTY_OUTDATED'
ATTRIBUTE_APPLIANCE_VERSION =
'NIFTY_APPLIANCE_VERSION'

Constants inherited from Handler

Handler::API_POLLING_WAIT, Handler::ATTRIBUTE_APPLIANCE_ID, Handler::LEAVE_AS_IS, Handler::ONEADMIN_ID, Handler::OWNER_OCTET

Instance Attribute Summary

Attributes inherited from Handler

#client, #pool

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Handler

chmod, chown, #reload!

Constructor Details

#initialize(client) ⇒ ImageHandler

Constructor

See Also:



22
23
24
25
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 22

def initialize(client)
  super(client)
  @pool = OpenNebula::ImagePool.new(client)
end

Class Method Details

.prepare_template(template_dir, data) ⇒ String

Prepares a template for an image

Parameters:

  • template_dir (String)

    directory with templates

  • data (Hash)

    used while populating a template

Returns:

  • (String)

    final template for an image



201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 201

def self.prepare_template(template_dir, data)
  template_location = File.join(template_dir, "image.erb")
  fail Nifty::Errors::ArgumentError, "Missing file 'image.erb' in template directory '#{template_dir}'" unless File.exist?(template_location)

  template = Tilt::ERBTemplate.new(template_location)
  template_content = template.render(Object.new, data)

  template = Tilt::ERBTemplate.new(File.join(Nifty::GEM_DIR, 'templates', 'image.erb'))
  nifty_template_content = template.render(Object.new, data)

  whole_template_content = template_content + nifty_template_content
  logger.debug "Populated image template:\n#{whole_template_content}"
  whole_template_content
end

Instance Method Details

#delete_image(image) ⇒ Object

Deletes image

Parameters:

  • image (OpenNebula::Image)

Raises:



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 72

def delete_image(image)
  id = image.id

  if image.state_str == IMAGE_STATE_USED
    logger.warn("Image with id #{id.inspect} cannot be removed, still in use")
    return
  end

  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.info! }
  logger.debug("Deleting image with id #{id.inspect}")
  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.delete }

  Timeout::timeout(Nifty::Backends::Utils::Opennebula::Handler.api_call_timeout) do
    while(image_exist?(id))
      sleep(Nifty::Backends::Utils::Opennebula::Handler::API_POLLING_WAIT)
    end
  end
rescue Timeout::Error
  fail Nifty::Errors::ApiCallTimeoutError, "Image with id #{id.inspect} was not deleted within timeout"
end

#disable_image(image) ⇒ Object

Disables image

Parameters:

  • image (OpenNebula::Image)

Raises:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 97

def disable_image(image)
  image_state = image.state_str
  id = image.id

  if image_state == IMAGE_STATE_DISABLED
    logger.debug("Image with id #{id.inspect} is already disabled, skipping")
    return
  end

  unless image_state == IMAGE_STATE_READY || image_state == IMAGE_STATE_ERROR
    logger.warn("Image with id #{id.inspect} cannot be disabled")
    return
  end

  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.disable }

  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.info! }
  Timeout::timeout(Nifty::Backends::Utils::Opennebula::Handler.api_call_timeout) do
    until(image.state_str == IMAGE_STATE_DISABLED)
      sleep(Nifty::Backends::Utils::Opennebula::Handler::API_POLLING_WAIT)
      Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.info! }
    end
  end
end

#expire_image(image) ⇒ Object

Expires image Renames image and add attribute NIFTY_EXPIRATION to image with timestamp as a value

Parameters:

  • image (OpenNebula::Image)


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 126

def expire_image(image)
  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.info! }
  id = image.id

  if image["TEMPLATE/#{ATTRIBUTE_EXPIRATION}"]
    logger.debug("Image with id #{id.inspect} is already expired, skipping")
    return
  end

  disable_image(image)

  logger.debug("Expiring image with id #{id.inspect}")

  expiration_time = Time.now.strftime(TIME_FORMAT)
  expiration_attribute = "#{ATTRIBUTE_EXPIRATION} = \"#{expiration_time}\""

  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.rename("EXPIRED_#{expiration_time}_#{image.name}") }
  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.update(expiration_attribute, true) }
end

#expired_imagesArray

Returns all expired images (have attribute NIFTY_EXPIRATION)

Returns:

  • (Array)

    array of expired images



40
41
42
43
44
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 40

def expired_images()
  reload!

  pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_EXPIRATION}"] }
end

#image_exist?(id) ⇒ OpenNebula::Image

Returns image with given id if exists

Parameters:

  • id (Fixnum)

Returns:

  • (OpenNebula::Image)

    image with given id



62
63
64
65
66
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 62

def image_exist?(id)
  reload!

  pool.find { |image| image.id == id }
end

#images(appliance_id) ⇒ Array

Returns all images for given appliance id

Parameters:

  • appliance_id (String)

Returns:

  • (Array)

    array of images



31
32
33
34
35
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 31

def images(appliance_id)
  reload!

  pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_APPLIANCE_ID}"] == appliance_id }
end

#images_by_version(version) ⇒ Object



52
53
54
55
56
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 52

def images_by_version(version)
  reload!

  pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_APPLIANCE_VERSION}"] == version }
end

#outdate_image(image) ⇒ Object

Outdates image Adds atribute marking the image is outdated

Parameters:

  • image (OpenNebula::Image)


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 150

def outdate_image(image)
  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.info! }

  id = image.id

  if image["TEMPLATE/#{ATTRIBUTE_OUTDATED}"]
    logger.debug("Image with id #{id.inspect} is already outdated, skipping")
    return
  end

  logger.debug("Outdating image with id #{id.inspect}")

  outdate_time = Time.now.strftime(TIME_FORMAT)
  outdate_attribute = "#{ATTRIBUTE_OUTDATED} = \"#{outdate_time}\""
  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.update(outdate_attribute, true) }
end

#register_image(template, datastore) ⇒ Object

Registers a new image

Parameters:

  • template (String)

    template for image

  • datastore (OpenNebula::Datastore)

    datastore to register image to

Raises:



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 172

def register_image(template, datastore)
  image_alloc = ::OpenNebula::Image.build_xml
  image = ::OpenNebula::Image.new(image_alloc, client)

  logger.debug("Registering image with template\n#{template}")
  Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.allocate(template, datastore.id) }

  begin
    Timeout::timeout(Nifty::Backends::Utils::Opennebula::Handler.api_call_timeout) do
      Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.info! }

      until(image.state_str == IMAGE_STATE_READY)
        sleep(Nifty::Backends::Utils::Opennebula::Handler::API_POLLING_WAIT)
        Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.info! }
      end
    end

    image
  rescue Timeout::Error
    image.delete
    fail Nifty::Errors::ApiCallTimeoutError, "Image with id #{image.id.inspect} didn't become ready within timeout"
  end
end

#unmanaged_imagesObject



46
47
48
49
50
# File 'lib/nifty/backends/utils/opennebula/image_handler.rb', line 46

def unmanaged_images()
  reload!

  pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_APPLIANCE_ID}"].nil? && image["TEMPLATE/#{Nifty::Backends::Opennebula::VMCATCHER_APPLIANCE_ID}"] }
end