class Nifty::Backends::Utils::Opennebula::ImageHandler

Handler for OpenNebula ImagePool

@author Michal Kimle

Constants

ATTRIBUTE_APPLIANCE_VERSION
ATTRIBUTE_EXPIRATION
ATTRIBUTE_OUTDATED
IMAGE_STATE_DISABLED
IMAGE_STATE_ERROR
IMAGE_STATE_READY
IMAGE_STATE_USED
TIME_FORMAT

Public Class Methods

new(client) click to toggle source

Constructor

@see Nifty::Backends::Utils::Opennebula::Handler#initialize

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 22
def initialize(client)
  super(client)
  @pool = OpenNebula::ImagePool.new(client)
end
prepare_template(template_dir, data) click to toggle source

Prepares a template for an image

@param [String] template_dir directory with templates @param [Hash] data used while populating a template @return [String] final template for an image

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 205
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

Public Instance Methods

delete_image(image) click to toggle source

Deletes image

@param [OpenNebula::Image] image @raise [Nifty::Errors::ApiCallTimeoutError] if image isn't deleted within a timeout

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 76
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) click to toggle source

Disables image

@param [OpenNebula::Image] image @raise [Nifty::Errors::ApiCallTimeoutError] if image isn't disabled within a timeout

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 101
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) click to toggle source

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

@param [OpenNebula::Image] image

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 130
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_images() click to toggle source

Returns all expired images (have attribute NIFTY_EXPIRATION)

@return [Array] array of expired images

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 42
def expired_images()
  reload!

  pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_EXPIRATION}"] }
end
image_exist?(id) click to toggle source

Returns image with given id if exists

@param [Fixnum] id @return [OpenNebula::Image] image with given id

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 66
def image_exist?(id)
  reload!

  pool.find { |image| image.id == id }
end
images(appliance_id, users = []) click to toggle source

Returns all images for given appliance id

@param [String] appliance_id @return [Array] array of images

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 31
def images(appliance_id, users = [])
  reload!

  return pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_APPLIANCE_ID}"] == appliance_id && users.include?(image['UNAME']) } unless users.blank?

  pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_APPLIANCE_ID}"] == appliance_id }
end
images_by_version(version, users = []) click to toggle source
# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 54
def images_by_version(version, users = [])
  reload!

  return pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_APPLIANCE_VERSION}"] == version && users.include?(image['UNAME']) } unless users.blank?

  pool.find_all { |image| image["TEMPLATE/#{ATTRIBUTE_APPLIANCE_VERSION}"] == version }
end
outdate_image(image) click to toggle source

Outdates image Adds atribute marking the image is outdated

@param [OpenNebula::Image] image

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 154
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) click to toggle source

Registers a new image

@param [String] template template for image @param [OpenNebula::Datastore] datastore datastore to register image to @raise [Nifty::Errors::ApiCallTimeoutError] if image isn't ready within a timeout

# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 176
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_images() click to toggle source
# File lib/nifty/backends/utils/opennebula/image_handler.rb, line 48
def unmanaged_images()
  reload!

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