module Vixen::Bridge

Public Class Methods

connect(hostType, hostname, port, username, password, &block) click to toggle source
# File lib/vixen/bridge.rb, line 70
def self.connect(hostType, hostname, port, username, password, &block)
  progress_proc = safe_proc_from_block &block
  hostname = "https://%s%s/sdk" % [hostname, port == 0 ? '' : ":#{port}"] if hostname
  Vixen.logger.info "connecting to %s with username %s" % [hostname.inspect, username.inspect]
  job = Vixen::Model::Job.new(VixHost_Connect(VixApiVersion[:api_version],
                               hostType,
                               hostname,
                               port,
                               username,
                               password,
                               0,
                               VixHandle[:invalid],
                               progress_proc,
                               nil))
  spin_until_job_complete("connect to host", job)
  pointer_to_handle do |host_handle_pointer|
    Vixen.logger.debug "getting handle from connection job"
    VixJob_Wait job.handle, VixPropertyId[:job_result_handle],
                :pointer, host_handle_pointer,
                :int, VixPropertyId[:none]
  end
end
create_snapshot(vm_handle, name, description, &block) click to toggle source
# File lib/vixen/bridge.rb, line 220
def self.create_snapshot(vm_handle, name, description, &block)
  progress_proc = safe_proc_from_block &block
  snapshot_handle = pointer_to_handle do |snapshot_handle_pointer|
    wait_for_async_handle_creation_job "create snapshot", snapshot_handle_pointer, 0.2, 0.2 do
      Vixen.logger.info "creating %s snapshot" % name
      VixVM_CreateSnapshot vm_handle, name, description,
                           VixCreateSnapshotOptions[:include_memory],
                           VixHandle[:invalid], progress_proc, nil
    end
  end
end
current_power_state(vm_handle) click to toggle source
# File lib/vixen/bridge.rb, line 365
def self.current_power_state(vm_handle)
  get_int_property vm_handle, VixPropertyId[:vm_power_state]
end
current_snapshot(vm_handle) click to toggle source
# File lib/vixen/bridge.rb, line 247
def self.current_snapshot(vm_handle)
  pointer_to_handle do |snapshot_handle_pointer|
    Vixen.logger.debug "retrieving current snapshot"
    VixVM_GetCurrentSnapshot vm_handle, snapshot_handle_pointer
  end
end
destroy(handle) click to toggle source
# File lib/vixen/bridge.rb, line 203
def self.destroy(handle)
  Vixen.logger.debug "destroying %s handle (%s)" %
    [Vixen::Constants::VixHandleType[Vix_GetHandleType(handle)], handle]
  Vix_ReleaseHandle handle
end
disconnect(handle) click to toggle source
# File lib/vixen/bridge.rb, line 197
def self.disconnect(handle)
  Vixen.logger.debug "disconnecting from %s handle (%s)" %
    [Vixen::Constants::VixHandleType[Vix_GetHandleType(handle)], handle]
  VixHost_Disconnect handle
end
get_children(snapshot_handle) click to toggle source
# File lib/vixen/bridge.rb, line 273
def self.get_children(snapshot_handle)
  count = pointer_to_int { |int_pointer| VixSnapshot_GetNumChildren(snapshot_handle, int_pointer) }
  children = []
  count.times do |n|
    handle = pointer_to_handle do |handle_pointer|
      VixSnapshot_GetChild(snapshot_handle, n, handle_pointer)
    end
    child = Vixen::Model::Snapshot.new( handle )
    children << child
  end
  children
end
get_int_property(handle, property_id) click to toggle source
# File lib/vixen/bridge.rb, line 298
def self.get_int_property(handle, property_id)
  pointer_to_int do |int_pointer|
    Vixen.logger.debug "getting %s property" % Vixen::Constants::VixPropertyId[property_id]
    Vix_GetProperties(handle, property_id,
                      :pointer, int_pointer,
                      :int, VixPropertyId[:none])
  end
end
get_parent(snapshot_handle) click to toggle source
# File lib/vixen/bridge.rb, line 266
def self.get_parent(snapshot_handle)
  pointer_to_handle do |snapshot_handle_pointer|
    Vixen.logger.debug "retrieving snapshot parent"
    VixSnapshot_GetParent snapshot_handle, snapshot_handle_pointer
  end
end
get_root_snapshots(vm_handle) click to toggle source
# File lib/vixen/bridge.rb, line 254
def self.get_root_snapshots(vm_handle)
  count = pointer_to_int { |int_pointer| VixVM_GetNumRootSnapshots(vm_handle, int_pointer) }
  snapshots = []
  count.times do |n|
    handle = pointer_to_handle do |handle_pointer|
      VixVM_GetRootSnapshot(vm_handle, n, handle_pointer)
    end
    snapshots << Vixen::Model::Snapshot.new( handle )
  end
  snapshots
end
get_string_property(handle, property_id) click to toggle source
# File lib/vixen/bridge.rb, line 286
def self.get_string_property(handle, property_id)
  string = pointer_to_string do |string_pointer|
    Vixen.logger.debug "getting %s property" % Vixen::Constants::VixPropertyId[property_id]
    Vix_GetProperties(handle, property_id,
                      :pointer, string_pointer,
                      :int, VixPropertyId[:none])
  end
  value = string.read_string.dup
  Vix_FreeBuffer(string)
  return value
end
library_location() click to toggle source
# File lib/vixen/bridge.rb, line 11
def self.library_location
  kernel = Facter.value(:kernel) || ''
  arch = Facter.value(:architecture)
  case kernel.downcase
  when 'darwin'
    ext = 'dylib'
  when 'linux'
    ext = 'so'
  when 'windows'
    ext = 'dll'
  end
  File.join(File.dirname(__FILE__), %W[.. .. ext #{kernel} #{arch} libvixAllProducts.#{ext}])
end
open_vm(host_handle, vm_path, &block) click to toggle source
# File lib/vixen/bridge.rb, line 209
def self.open_vm(host_handle, vm_path, &block)
  progress_proc = safe_proc_from_block &block
  vm_handle = pointer_to_handle do |vm_handle_pointer|
    wait_for_async_handle_creation_job "open vm", vm_handle_pointer do
      Vixen.logger.info "opening %s" % vm_path
      VixHost_OpenVM host_handle, vm_path, VixVMOpenOptions[:normal],
                     VixHandle[:invalid], progress_proc, nil
    end
  end
end
pointer_to(type) { |pointer| ... } click to toggle source
# File lib/vixen/bridge.rb, line 93
def self.pointer_to(type, &block)
  pointer = FFI::MemoryPointer.new type, 1
  err = yield pointer
  unless err == VixError[:ok]
    raise "problem executing pointer_to_#{type} block. (error: %s, %s)" %
      [err, Vix_GetErrorText(err, nil)]
  end
  pointer.send "read_#{type}".to_sym
end
pointer_to_bool(&block) click to toggle source
# File lib/vixen/bridge.rb, line 115
def self.pointer_to_bool(&block)
  (pointer_to :int, &block) != 0
end
pointer_to_handle(&block) click to toggle source
# File lib/vixen/bridge.rb, line 103
def self.pointer_to_handle(&block)
  pointer_to :int, &block
end
pointer_to_int(&block) click to toggle source
# File lib/vixen/bridge.rb, line 111
def self.pointer_to_int(&block)
  pointer_to :int, &block
end
pointer_to_string(&block) click to toggle source
# File lib/vixen/bridge.rb, line 107
def self.pointer_to_string(&block)
  pointer_to :pointer, &block
end
power_off(vm_handle, &block) click to toggle source
# File lib/vixen/bridge.rb, line 328
def self.power_off(vm_handle, &block)
  progress_proc = safe_proc_from_block &block
  wait_for_async_job "power off VM" do
    Vixen.logger.debug "powering off vm (%s)" % vm_handle
    VixVM_PowerOff vm_handle, VixVMPowerOptions[:normal], progress_proc, nil
  end
end
power_off_using_guest(vm_handle, &block) click to toggle source
# File lib/vixen/bridge.rb, line 315
def self.power_off_using_guest(vm_handle, &block)
  begin
    progress_proc = safe_proc_from_block &block
    wait_for_async_job "power off VM using tools" do
      Vixen.logger.debug "powering off vm (%s)" % vm_handle
      VixVM_PowerOff vm_handle, VixVMPowerOptions[:from_guest], progress_proc, nil
    end
    true
  rescue
    false
  end
end
power_on(vm_handle, &block) click to toggle source
# File lib/vixen/bridge.rb, line 307
def self.power_on(vm_handle, &block)
  progress_proc = safe_proc_from_block &block
  wait_for_async_job "power on VM" do
    Vixen.logger.debug "powering on vm (%s)" % vm_handle
    VixVM_PowerOn vm_handle, VixVMPowerOptions[:normal], VixHandle[:invalid], progress_proc, nil
  end
end
remove_snapshot(vm, snapshot, &block) click to toggle source
# File lib/vixen/bridge.rb, line 240
def self.remove_snapshot(vm, snapshot, &block)
  progress_proc = safe_proc_from_block &block
  wait_for_async_job(("remove %s snapshot" % snapshot.display_name), 0.2, 0.2) do
    VixVM_RemoveSnapshot vm.handle, snapshot.handle, 0, progress_proc, nil
  end
end
reset(vm_handle, &block) click to toggle source
# File lib/vixen/bridge.rb, line 349
def self.reset(vm_handle, &block)
  progress_proc = safe_proc_from_block &block
  wait_for_async_job "reset VM" do
    Vixen.logger.debug "resetting vm (%s)" % vm_handle
    VixVM_Reset vm_handle, VixVMPowerOptions[:normal], progress_proc, nil
  end
end
reset_using_guest(vm_handle, &block) click to toggle source
# File lib/vixen/bridge.rb, line 336
def self.reset_using_guest(vm_handle, &block)
  begin
    progress_proc = safe_proc_from_block &block
    wait_for_async_job "reset VM using tools" do
      Vixen.logger.debug "resetting vm (%s)" % vm_handle
      VixVM_Reset vm_handle, VixVMPowerOptions[:from_guest], progress_proc, nil
    end
    true
  rescue
    false
  end
end
revert_to_snapshot(vm, snapshot, &block) click to toggle source
# File lib/vixen/bridge.rb, line 232
def self.revert_to_snapshot(vm, snapshot, &block)
  progress_proc = safe_proc_from_block &block
  wait_for_async_job(("revert to %s snapshot" % snapshot.display_name), 0.2, 0.2) do
    VixVM_RevertToSnapshot vm.handle, snapshot.handle, VixVMPowerOptions[:normal],
                           VixHandle[:invalid], progress_proc, nil
  end
end
running_vms(host_handle, &block) click to toggle source
# File lib/vixen/bridge.rb, line 168
def self.running_vms(host_handle, &block)
  available_vms = []

  collect_proc = safe_proc_from_block do |job_handle, event_type, more_event_info, client_data|
    if event_type == VixEventType[:find_item]
      path = get_string_property more_event_info, VixPropertyId[:found_item_location]
      if path
        Vixen.logger.debug "adding running vms %s" % path
        available_vms << path
      end
    end
    if block_given?
      Vixen.logger.debug "preparing to call user-supplied block for running vms progress"
      block.call job_handle, event_type, more_event_info, client_data
    end
  end

  Vixen.logger.debug "finding running vms"
  job = Vixen::Model::Job.new(VixHost_FindItems(host_handle,
                                 VixFindItemType[:running_vms],
                                 VixHandle[:invalid],
                                 -1,
                                 collect_proc,
                                 nil))
  spin_until_job_complete "running vms", job

  available_vms
end
safe_proc_from_block(&block) click to toggle source
# File lib/vixen/bridge.rb, line 59
def self.safe_proc_from_block(&block)
  return nil unless block_given?
  Proc.new do |*args|
    begin
      block.call args
    rescue
      puts STDERR, $!
    end
  end
end
spin_until_job_complete(operation, job, initial_sleep_time = 0.1, sleep_increment = 0.02) click to toggle source
# File lib/vixen/bridge.rb, line 150
def self.spin_until_job_complete(operation, job, initial_sleep_time = 0.1, sleep_increment = 0.02)
  sleep_time = initial_sleep_time
  while ( not pointer_to_bool do |bool_pointer|
    Vixen.logger.debug "sleeping waiting for %s job (%s) to complete" %
      [operation, job.handle]
    sleep sleep_time
    sleep_time += sleep_increment
    Vixen.logger.debug "checking completion of %s job (%s)" %
      [operation, job.handle]
    thr = Thread.start { sleep 0.01; VixJob_CheckCompletion(job.handle, bool_pointer) }
    Vixen.logger.debug "waiting for thread to complete"
    x = thr.value
    Vixen.logger.debug "thread completed with #{x}"
    x
  end) do
  end
end
suspend(vm_handle, &block) click to toggle source
# File lib/vixen/bridge.rb, line 357
def self.suspend(vm_handle, &block)
  progress_proc = safe_proc_from_block &block
  wait_for_async_job "suspend VM" do
    Vixen.logger.debug "suspending vm (%s)" % vm_handle
    VixVM_Suspend vm_handle, VixVMPowerOptions[:normal], progress_proc, nil
  end
end
wait_for_async_handle_creation_job(operation, pointer_to_handle, initial_sleep_time = 0.1, sleep_increment = 0.02) { || ... } click to toggle source
# File lib/vixen/bridge.rb, line 133
def self.wait_for_async_handle_creation_job(operation, pointer_to_handle, initial_sleep_time = 0.1, sleep_increment = 0.02, &block)
  job = Vixen::Model::Job.new(yield)
  Vixen.logger.debug "Waiting for async %s job (%s) to create a new handle" %
    [operation, job.handle]
  spin_until_job_complete(operation, job, initial_sleep_time, sleep_increment)
  err = VixJob_Wait job.handle, VixPropertyId[:job_result_handle],
              :pointer, pointer_to_handle,
              :int, VixPropertyId[:none]
  unless err == VixError[:ok]
    Vixen.logger.error "While executing %s VIX API returned error: %s: %s" %
      [operation, err, Vix_GetErrorText(err, nil)]
    raise "couldn't %s. (error: %s, %s)" %
      [operation, err, Vix_GetErrorText(err, nil)]
  end
  err
end
wait_for_async_job(operation, initial_sleep_time = 0.1, sleep_increment = 0.02) { || ... } click to toggle source
# File lib/vixen/bridge.rb, line 119
def self.wait_for_async_job(operation, initial_sleep_time = 0.1, sleep_increment = 0.02, &block)
  job = Vixen::Model::Job.new(yield)
  Vixen.logger.debug "Waiting for async %s job (%s)" %
    [operation, job.handle]
  spin_until_job_complete(operation, job, initial_sleep_time, sleep_increment)
  err = VixJob_Wait job.handle, VixPropertyId[:none]
  unless err == VixError[:ok]
    Vixen.logger.error "While executing %s VIX API returned error: %s: %s" %
      [operation, err, Vix_GetErrorText(err, nil)]
    raise "couldn't %s. (error: %s, %s)" %
      [operation, err, Vix_GetErrorText(err, nil)]
  end
end