class VagrantPlugins::OVirtProvider::Action::CreateVM

Public Class Methods

new(app, env) click to toggle source
# File lib/vagrant-ovirt4/action/create_vm.rb, line 10
def initialize(app, env)
  @logger = Log4r::Logger.new("vagrant_ovirt4::action::create_vm")
  @app = app
end

Public Instance Methods

call(env) click to toggle source
# File lib/vagrant-ovirt4/action/create_vm.rb, line 15
def call(env)
  # Get config.
  config = env[:machine].provider_config

  hostname = env[:machine].config.vm.hostname
  hostname = 'vagrant' if hostname.nil?

  # Output the settings we're going to use to the user
  env[:ui].info(I18n.t("vagrant_ovirt4.creating_vm"))
  env[:ui].info(" -- Name:          #{hostname}")
  env[:ui].info(" -- Cluster:       #{config.cluster}")
  env[:ui].info(" -- Template:      #{config.template}")
  env[:ui].info(" -- Console Type:  #{config.console}")
  env[:ui].info(" -- BIOS Serial:   #{config.bios_serial}")
  env[:ui].info(" -- Optimized For: #{config.optimized_for}")
  env[:ui].info(" -- Description:   #{config.description}")
  env[:ui].info(" -- Comment:       #{config.comment}")
  env[:ui].info(" -- Disk:          #{Filesize.from("#{config.disk_size} B").to_f('GB').to_i} GB") unless config.disk_size.nil?
  env[:ui].info(" -- Memory:        ")
  env[:ui].info(" ---- Memory:      #{Filesize.from("#{config.memory_size} B").to_f('MB').to_i} MB")
  env[:ui].info(" ---- Maximum:     #{Filesize.from("#{config.memory_maximum} B").to_f('MB').to_i} MB")
  env[:ui].info(" ---- Guaranteed:  #{Filesize.from("#{config.memory_guaranteed} B").to_f('MB').to_i} MB")
  env[:ui].info(" -- Cpu:           ")
  env[:ui].info(" ---- Cores:       #{config.cpu_cores}")
  env[:ui].info(" ---- Sockets:     #{config.cpu_sockets}")
  env[:ui].info(" ---- Threads:     #{config.cpu_threads}")
  env[:ui].info(" -- Cloud-Init:    #{!config.cloud_init.nil? }")

  # Create oVirt VM.
  attr = {
      :name     => hostname,
      :description => config.description,
      :comment => config.comment,
      :cpu      => {
        :architecture => 'x86_64',
        :topology => {
          :cores   => config.cpu_cores,
          :sockets => config.cpu_sockets,
          :threads => config.cpu_threads,
        },
      },
      :memory_policy => OvirtSDK4::MemoryPolicy.new(
        ballooning: true,
        guaranteed: config.memory_guaranteed,
        max: config.memory_maximum,
      ),
      :memory   => config.memory_size,
      :cluster  => {
        :name => config.cluster,
      },
      :template => {
        :name => config.template,
      },
      :display  => {
        :type => config.console,
      },
      :type => config.optimized_for,
  }

  begin
    server = env[:vms_service].add(attr) 
  rescue OvirtSDK4::Error => e
    fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
    retry if e.message =~ /Related operation is currently in progress/

    if config.debug
      raise e
    else
      raise Errors::CreateVMError,
        :error_message => fault_message
    end
  end

  # Immediately save the ID since it is created at this point.
  env[:machine].id = server.id

  # Wait till all volumes are ready.
  env[:ui].info(I18n.t("vagrant_ovirt4.wait_for_ready_vm"))
  for i in 0..300
    disk_ready = true
    vm_service = env[:vms_service].vm_service(env[:machine].id)
    disk_attachments_service = vm_service.disk_attachments_service
    disk_attachments = disk_attachments_service.list
    disk_attachments.each do |disk_attachment|
      disk = env[:connection].follow_link(disk_attachment.disk)
      if disk.status != 'ok'
        disk_ready = false
        break
      end
    end
    ready = (disk_ready and env[:vms_service].vm_service(server.id).get.status.to_sym == :down)
    break if ready
    sleep 2
  end

  if not ready
    raise Errors::WaitForReadyVmTimeout
  end

  begin
    if config.bios_serial
      vm_service = env[:vms_service].vm_service(env[:machine].id)
      vm_service.update(
        serial_number: {
          policy: OvirtSDK4::SerialNumberPolicy::CUSTOM,
          value: config.bios_serial,
        }
      )
    end
  rescue OvirtSDK4::Error => e
    fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
    retry if e.message =~ /Related operation is currently in progress/

    if config.debug
      raise e
    else
      raise Errors::UpdateBiosError,
        :error_message => fault_message
    end
  end


  @app.call(env)
end
recover(env) click to toggle source
# File lib/vagrant-ovirt4/action/create_vm.rb, line 140
def recover(env)
  return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)

  # Undo the import
  env[:ui].info(I18n.t("vagrant_ovirt4.error_recovering"))
  destroy_env = env.dup
  destroy_env.delete(:interrupted)
  destroy_env[:config_validate] = false
  destroy_env[:force_confirm_destroy] = true
  env[:action_runner].run(Action.action_destroy, destroy_env)
  env[:connection].close()
end