class Nifty::Backends::Opennebula

OpenNebula backend

Constants

VMCATCHER_APPLIANCE_DESCRIPTION
VMCATCHER_APPLIANCE_ID
VMCATCHER_APPLIANCE_OS_ARCH
VMCATCHER_APPLIANCE_OS_DISTRIBUTION
VMCATCHER_APPLIANCE_OS_VERSION
VMCATCHER_APPLIANCE_TITLE
VMCATCHER_APPLIANCE_VERSION
VMCATCHER_PREFIX

Public Class Methods

backend?() click to toggle source

@see Nifty::Backend#backend?

# File lib/nifty/backends/opennebula.rb, line 18
def backend?
  true
end
create_event(event_class, appliance, transfer_method, parameters) click to toggle source

@see Nifty::Backend#create_event @param [Hash] parameters @option parameters [String] secret OpenNebula's secret @option parameters [String] endpoint OpenNebula's endpoint @option parameters [Array] datastores array of datastore names @option parameters [String] template-dir path to dir with image and template templates

# File lib/nifty/backends/opennebula.rb, line 112
def create_event(event_class, appliance, transfer_method, parameters)
  client = Nifty::Backends::Utils::Opennebula::Helper.client(parameters[:secret], parameters[:endpoint])
  datastores = Nifty::Backends::Utils::Opennebula::DatastoreHandler.new(client).datastores(parameters[:datastores])
  event_class.new(appliance, transfer_method, client, datastores, parameters)
rescue Nifty::Errors::Backends::OpennebulaError => ex
  fail Nifty::Errors::BackendError, ex
end
description() click to toggle source

@see Nifty::Backend#description

# File lib/nifty/backends/opennebula.rb, line 23
def description
  "OpenNebula backend"
end
migrate(parameters) click to toggle source
# File lib/nifty/backends/opennebula.rb, line 120
def migrate(parameters)
  client = Nifty::Backends::Utils::Opennebula::Helper.client(parameters[:secret], parameters[:endpoint])
  image_handler = Nifty::Backends::Utils::Opennebula::ImageHandler.new(client)
  template_handler = Nifty::Backends::Utils::Opennebula::TemplateHandler.new(client)

  image_handler.unmanaged_images.each do |image|
    image_name = image.name
    logger.debug "Processing image #{image_name}"

    os = Cloud::Appliance::Descriptor::Os.new
    os.arch = image["TEMPLATE/#{VMCATCHER_APPLIANCE_OS_ARCH}"]
    os.version = image["TEMPLATE/#{VMCATCHER_APPLIANCE_OS_VERSION}"]
    os.distribution = image["TEMPLATE/#{VMCATCHER_APPLIANCE_OS_DISTRIBUTION}"]

    appliance = Cloud::Appliance::Descriptor::Appliance.new os: os
    appliance.identifier = image["TEMPLATE/#{VMCATCHER_APPLIANCE_ID}"]
    appliance.version = image["TEMPLATE/#{VMCATCHER_APPLIANCE_VERSION}"]
    appliance.title = image["TEMPLATE/#{VMCATCHER_APPLIANCE_TITLE}"]
    appliance.description = image["TEMPLATE/#{VMCATCHER_APPLIANCE_DESCRIPTION}"]

    vmcatcher_attributes = {}
    image.to_hash['IMAGE']['TEMPLATE'].each_pair { |k,v| vmcatcher_attributes[k] = v if k.start_with? VMCATCHER_PREFIX }

    image_template = Tilt::ERBTemplate.new(File.join(Nifty::GEM_DIR, 'templates', 'image.erb'))
    image_template_update = image_template.render(Object.new, {name: image_name, appliance: appliance})
    logger.debug("Updating image template for image #{image_name}")
    Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { image.update(image_template_update, true) }

    appliance.attributes = vmcatcher_attributes

    logger.debug("Looking for templates with image #{image_name}...")
    template_handler.unmanaged_templates_with_image(image_name).each do |template|
      template_name = template.name
      logger.debug "Processing template #{template_name}"
      template_template = Tilt::ERBTemplate.new(File.join(Nifty::GEM_DIR, 'templates', 'template.erb'))
      template_template_update = template_template.render(Object.new, {name: template_name, appliance: appliance})
      logger.debug("Updating template template for template #{template_name}")
      Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { template.update(template_template_update, true) }
    end
  end

  Nifty::ExitCodes::NO_ERROR_EXIT_CODE
rescue Nifty::Errors::Backends::OpennebulaError => ex
  logger.error "Migration error: #{ex.message}"
  Nifty::ExitCodes::MIGRATION_ERROR_EXIT_CODE
end
migrate_options() click to toggle source

@see Nifty::Backend#migrate_options

# File lib/nifty/backends/opennebula.rb, line 83
def migrate_options
  { :secret => {
      :type => :string,
      :desc => 'Pair of username and password in form of \'username:password\' for accessing OpenNebula'
    },
    :endpoint => {
      :type => :string,
      :desc => 'OpenNebula\'s XML RPC endpoint'
    },
    :"api-call-timeout" => {
      :required => true,
      :type => :string,
      :desc => 'How long will NIFTY wait for image/template operations to finish in OpenNebula'
    }
  }
end
options() click to toggle source

@see Nifty::Backend#options

# File lib/nifty/backends/opennebula.rb, line 28
def options
  { :secret => {
      :type => :string,
      :desc => 'Pair of username and password in form of \'username:password\' for accessing OpenNebula'
    },
    :endpoint => {
      :type => :string,
      :desc => 'OpenNebula\'s XML RPC endpoint'
    },
    :"expiration-interval" => {
      :required => true,
      :type => :string,
      :desc => 'How long should expired images be kept in OpenNebula befor removal, 0 means don\'t remove'
    },
    :"api-call-timeout" => {
      :required => true,
      :type => :string,
      :desc => 'How long will NIFTY wait for image/template operations to finish in OpenNebula'
    },
    :datastores => {
      :required => true,
      :type => :array,
      :aliases => '-d',
      :desc => 'Names of OpenNebula datastores images will be uploaded to'
    },
    :"template-dir" => {
      :default => File.join(Nifty::GEM_DIR, 'config', 'templates'),
      :type => :string,
      :desc => 'If set, templates within this directory are used to construct images and templates in OpenNebula'
    },
    :"description-naming" => {
      :type => :boolean,
      :desc => 'If true, uses identifier and version from appliance description as template/image name instead of generated uuids'
    },
    :"disk-expiration" => {
      :type => :boolean,
      :desc => 'Will expire old disks before the new one is registered'
    },
    :permissions => {
      :required => true,
      :type => :string,
      :desc => 'UNIX-like image and template permissions in OpenNebula'
    },
    :groups => {
      :type => :array,
      :desc => 'Names of groups appliances will be registred to in OpenNebula'
    },
    :users => {
      :type => :array,
      :desc => 'Handle only images/templates of specified users'
    }
  }
end
pre(parameters) click to toggle source

@see Nifty::Backend#pre

# File lib/nifty/backends/opennebula.rb, line 101
def pre(parameters)
  Nifty::Backends::Utils::Opennebula::Handler.api_call_timeout = ChronicDuration.parse(parameters[:'api-call-timeout'], keep_zero: true)
  expiration_check(parameters)
end

Private Class Methods

expiration_check(parameters) click to toggle source

Checks whether there are expired images that should be removed

@param [Hash] parameters @option parameters [String] expiration-interval expiration interval in human readable form @option parameters [String] secret OpenNebula's secret @option parameters [String] endpoint OpenNebula's endpoint

# File lib/nifty/backends/opennebula.rb, line 175
def expiration_check(parameters)
  interval = ChronicDuration.parse(parameters[:'expiration-interval'].to_s)
  return unless interval

  client = Nifty::Backends::Utils::Opennebula::Helper.client(parameters[:secret], parameters[:endpoint])
  image_handler = Nifty::Backends::Utils::Opennebula::ImageHandler.new(client)
  now = Time.now

  logger.debug('Looking for expired images...')
  image_handler.expired_images.each do |image|
    image_handler.disable_image image

    image_expiration_date = Time.parse(image['TEMPLATE/NIFTY_EXPIRATION'])
    # checks whether image is already expired for specified time
    next if (now - image_expiration_date) < interval

    image_handler.delete_image image
  end
rescue Nifty::Errors::Backends::OpennebulaError => ex
  logger.error("Cannot check and remove expired images: #{ex.message}")
end