Class: OpenNebula::VirtualMachine

Inherits:
PoolElement show all
Defined in:
lib/opennebula/virtual_machine.rb

Constant Summary collapse

VM_METHODS =

Constants and Class Methods

{
    :info           => "vm.info",
    :allocate       => "vm.allocate",
    :action         => "vm.action",
    :migrate        => "vm.migrate",
    :deploy         => "vm.deploy",
    :chown          => "vm.chown",
    :chmod          => "vm.chmod",
    :monitoring     => "vm.monitoring",
    :attach         => "vm.attach",
    :detach         => "vm.detach",
    :rename         => "vm.rename",
    :update         => "vm.update",
    :resize         => "vm.resize",
    :snapshotcreate => "vm.snapshotcreate",
    :snapshotrevert => "vm.snapshotrevert",
    :snapshotdelete => "vm.snapshotdelete",
    :attachnic      => "vm.attachnic",
    :detachnic      => "vm.detachnic",
    :recover        => "vm.recover",
    :disksaveas     => "vm.disksaveas",
    :disksnapshotcreate => "vm.disksnapshotcreate",
    :disksnapshotrevert => "vm.disksnapshotrevert",
    :disksnapshotdelete => "vm.disksnapshotdelete"
}
VM_STATE =
%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
POWEROFF UNDEPLOYED}
LCM_STATE =
%w{
    LCM_INIT
    PROLOG
    BOOT
    RUNNING
    MIGRATE
    SAVE_STOP
    SAVE_SUSPEND
    SAVE_MIGRATE
    PROLOG_MIGRATE
    PROLOG_RESUME
    EPILOG_STOP
    EPILOG
    SHUTDOWN
    CANCEL
    FAILURE
    CLEANUP_RESUBMIT
    UNKNOWN
    HOTPLUG
    SHUTDOWN_POWEROFF
    BOOT_UNKNOWN
    BOOT_POWEROFF
    BOOT_SUSPENDED
    BOOT_STOPPED
    CLEANUP_DELETE
    HOTPLUG_SNAPSHOT
    HOTPLUG_NIC
    HOTPLUG_SAVEAS
    HOTPLUG_SAVEAS_POWEROFF
    HOTPLUG_SAVEAS_SUSPENDED
    SHUTDOWN_UNDEPLOY
    EPILOG_UNDEPLOY
    PROLOG_UNDEPLOY
    BOOT_UNDEPLOY
    HOTPLUG_PROLOG_POWEROFF
    HOTPLUG_EPILOG_POWEROFF
    BOOT_MIGRATE
    BOOT_FAILURE
    BOOT_MIGRATE_FAILURE
    PROLOG_MIGRATE_FAILURE
    PROLOG_FAILURE
    EPILOG_FAILURE
    EPILOG_STOP_FAILURE
    EPILOG_UNDEPLOY_FAILURE
    PROLOG_MIGRATE_POWEROFF
    PROLOG_MIGRATE_POWEROFF_FAILURE
    PROLOG_MIGRATE_SUSPEND
    PROLOG_MIGRATE_SUSPEND_FAILURE
    BOOT_UNDEPLOY_FAILURE
    BOOT_STOPPED_FAILURE
    PROLOG_RESUME_FAILURE
    PROLOG_UNDEPLOY_FAILURE
    DISK_SNAPSHOT_POWEROFF
    DISK_SNAPSHOT_REVERT_POWEROFF
    DISK_SNAPSHOT_DELETE_POWEROFF
    DISK_SNAPSHOT_SUSPENDED
    DISK_SNAPSHOT_REVERT_SUSPENDED
    DISK_SNAPSHOT_DELETE_SUSPENDED
    DISK_SNAPSHOT
    DISK_SNAPSHOT_REVERT
    DISK_SNAPSHOT_DELETE
}
SHORT_VM_STATES =
{
    "INIT"      => "init",
    "PENDING"   => "pend",
    "HOLD"      => "hold",
    "ACTIVE"    => "actv",
    "STOPPED"   => "stop",
    "SUSPENDED" => "susp",
    "DONE"      => "done",
    "FAILED"    => "fail",
    "POWEROFF"  => "poff",
    "UNDEPLOYED"=> "unde"
}
SHORT_LCM_STATES =
{
    "PROLOG"            => "prol",
    "BOOT"              => "boot",
    "RUNNING"           => "runn",
    "MIGRATE"           => "migr",
    "SAVE_STOP"         => "save",
    "SAVE_SUSPEND"      => "save",
    "SAVE_MIGRATE"      => "save",
    "PROLOG_MIGRATE"    => "migr",
    "PROLOG_RESUME"     => "prol",
    "EPILOG_STOP"       => "epil",
    "EPILOG"            => "epil",
    "SHUTDOWN"          => "shut",
    "CANCEL"            => "shut",
    "FAILURE"           => "fail",
    "CLEANUP_RESUBMIT"  => "clea",
    "UNKNOWN"           => "unkn",
    "HOTPLUG"           => "hotp",
    "SHUTDOWN_POWEROFF" => "shut",
    "BOOT_UNKNOWN"      => "boot",
    "BOOT_POWEROFF"     => "boot",
    "BOOT_SUSPENDED"    => "boot",
    "BOOT_STOPPED"      => "boot",
    "CLEANUP_DELETE"    => "clea",
    "HOTPLUG_SNAPSHOT"  => "snap",
    "HOTPLUG_NIC"       => "hotp",
    "HOTPLUG_SAVEAS"           => "hotp",
    "HOTPLUG_SAVEAS_POWEROFF"  => "hotp",
    "HOTPLUG_SAVEAS_SUSPENDED" => "hotp",
    "SHUTDOWN_UNDEPLOY" => "shut",
    "EPILOG_UNDEPLOY"   => "epil",
    "PROLOG_UNDEPLOY"   => "prol",
    "BOOT_UNDEPLOY"     => "boot",
    "HOTPLUG_PROLOG_POWEROFF"   => "hotp",
    "HOTPLUG_EPILOG_POWEROFF"   => "hotp",
    "BOOT_MIGRATE"              => "boot",
    "BOOT_FAILURE"              => "fail",
    "BOOT_MIGRATE_FAILURE"      => "fail",
    "PROLOG_MIGRATE_FAILURE"    => "fail",
    "PROLOG_FAILURE"            => "fail",
    "EPILOG_FAILURE"            => "fail",
    "EPILOG_STOP_FAILURE"       => "fail",
    "EPILOG_UNDEPLOY_FAILURE"   => "fail",
    "PROLOG_MIGRATE_POWEROFF"   => "migr",
    "PROLOG_MIGRATE_POWEROFF_FAILURE"   => "fail",
    "PROLOG_MIGRATE_SUSPEND"            => "migr",
    "PROLOG_MIGRATE_SUSPEND_FAILURE"    => "fail",
    "BOOT_UNDEPLOY_FAILURE"     => "fail",
    "BOOT_STOPPED_FAILURE"      => "fail",
    "PROLOG_RESUME_FAILURE"     => "fail",
    "PROLOG_UNDEPLOY_FAILURE"   => "fail",
    "DISK_SNAPSHOT_POWEROFF"        => "snap",
    "DISK_SNAPSHOT_REVERT_POWEROFF" => "snap",
    "DISK_SNAPSHOT_DELETE_POWEROFF" => "snap",
    "DISK_SNAPSHOT_SUSPENDED"       => "snap",
    "DISK_SNAPSHOT_REVERT_SUSPENDED"=> "snap",
    "DISK_SNAPSHOT_DELETE_SUSPENDED"=> "snap",
    "DISK_SNAPSHOT"        => "snap",
    "DISK_SNAPSHOT_REVERT" => "snap",
    "DISK_SNAPSHOT_DELETE" => "snap"
}
MIGRATE_REASON =
%w{NONE ERROR USER}
SHORT_MIGRATE_REASON =
{
    "NONE"          => "none",
    "ERROR"         => "erro",
    "USER"          => "user"
}
HISTORY_ACTION =
%w{none migrate live-migrate shutdown shutdown-hard
undeploy undeploy-hard hold release stop suspend resume boot delete
delete-recreate reboot reboot-hard resched unresched poweroff
poweroff-hard disk-attach disk-detach nic-attach nic-detach
snap-create snap-delete}
EXTERNAL_IP_ATTRS =
[
    'GUEST_IP',
    'AWS_IP_ADDRESS',
    'AZ_IPADDRESS',
    'SL_PRIMARYIPADDRESS'
]

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from PoolElement

#id, #name, new_with_id, #to_str

Methods inherited from XMLElement

#[], #add_element, #attr, #delete_element, #each, #each_xpath, #element_xml, #has_elements?, #initialize_xml, #name, #retrieve_elements, #template_like_str, #template_str, #template_xml, #text, #to_hash, #to_xml

Constructor Details

#initialize(xml, client) ⇒ VirtualMachine

Class constructor



243
244
245
# File 'lib/opennebula/virtual_machine.rb', line 243

def initialize(xml, client)
    super(xml,client)
end

Class Method Details

.build_xml(pe_id = nil) ⇒ Object

Creates a VirtualMachine description with just its identifier this method should be used to create plain VirtualMachine objects. id the id of the vm

Example:

vnet = VirtualMachine.new(VirtualMachine.build_xml(3),rpc_client)


221
222
223
224
225
226
227
228
229
# File 'lib/opennebula/virtual_machine.rb', line 221

def VirtualMachine.build_xml(pe_id=nil)
    if pe_id
        vm_xml = "<VM><ID>#{pe_id}</ID></VM>"
    else
        vm_xml = "<VM></VM>"
    end

    XMLElement.build_xml(vm_xml, 'VM')
end

.get_history_action(action) ⇒ Object



238
239
240
# File 'lib/opennebula/virtual_machine.rb', line 238

def VirtualMachine.get_history_action(action)
    return HISTORY_ACTION[action.to_i]
end

.get_reason(reason) ⇒ Object



231
232
233
234
235
236
# File 'lib/opennebula/virtual_machine.rb', line 231

def VirtualMachine.get_reason(reason)
    reason=MIGRATE_REASON[reason.to_i]
    reason_str=SHORT_MIGRATE_REASON[reason]

    reason_str
end

Instance Method Details

#allocate(description, hold = false) ⇒ nil, OpenNebula::Error

Allocates a new VirtualMachine in OpenNebula

Parameters:

  • description (String)

    A string containing the template of the VirtualMachine.

  • hold (true, false) (defaults to: false)

    false to create the VM in pending state, true to create it on hold

Returns:



267
268
269
# File 'lib/opennebula/virtual_machine.rb', line 267

def allocate(description, hold=false)
    super(VM_METHODS[:allocate], description, hold)
end

#cancelObject

Deprecated.

use #shutdown



352
353
354
# File 'lib/opennebula/virtual_machine.rb', line 352

def cancel
    shutdown(true)
end

#chmod(owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u, other_m, other_a) ⇒ nil, OpenNebula::Error

Changes the permissions. Each [Integer] argument must be 1 to allow, 0 deny, -1 do not change

Returns:



536
537
538
539
540
# File 'lib/opennebula/virtual_machine.rb', line 536

def chmod(owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u,
        other_m, other_a)
    super(VM_METHODS[:chmod], owner_u, owner_m, owner_a, group_u,
        group_m, group_a, other_u, other_m, other_a)
end

#chmod_octet(octet) ⇒ nil, OpenNebula::Error

Changes the permissions.

Parameters:

  • octet (String)

    Permissions octed , e.g. 640

Returns:



527
528
529
# File 'lib/opennebula/virtual_machine.rb', line 527

def chmod_octet(octet)
    super(VM_METHODS[:chmod], octet)
end

#chown(uid, gid) ⇒ Object

Changes the owner/group

uid

Integer the new owner id. Set to -1 to leave the current one

gid

Integer the new group id. Set to -1 to leave the current one

return

nil in case of success or an Error object



518
519
520
# File 'lib/opennebula/virtual_machine.rb', line 518

def chown(uid, gid)
    super(VM_METHODS[:chown], uid, gid)
end

#delete(recreate = false) ⇒ Object

Deletes a VM from the pool



422
423
424
425
426
427
428
# File 'lib/opennebula/virtual_machine.rb', line 422

def delete(recreate=false)
    if recreate
        action('delete-recreate')
    else
        action('delete')
    end
end

#deploy(host_id, enforce = false, ds_id = -1)) ⇒ nil, OpenNebula::Error

Initiates the instance of the VM on the target host.

Parameters:

  • host_id (Interger)

    The host id (hid) of the target host where the VM will be instantiated.

  • enforce (true|false) (defaults to: false)

    If it is set to true, the host capacity will be checked, and the deployment will fail if the host is overcommited. Defaults to false

  • ds_id (Integer) (defaults to: -1))

    The System Datastore where to deploy the VM. To use the default, set it to -1

Returns:



316
317
318
319
320
321
322
323
324
# File 'lib/opennebula/virtual_machine.rb', line 316

def deploy(host_id, enforce=false, ds_id=-1)
    enforce ||= false
    ds_id ||= -1
    return call(VM_METHODS[:deploy],
                @pe_id,
                host_id.to_i,
                enforce,
                ds_id.to_i)
end

#deploy_idObject

Returns the deploy_id of the VirtualMachine (numeric value)



701
702
703
# File 'lib/opennebula/virtual_machine.rb', line 701

def deploy_id
    self['DEPLOY_ID']
end

#disk_attach(disk_template) ⇒ nil, OpenNebula::Error Also known as: attachdisk

Attaches a disk to a running VM

Parameters:

  • disk_template (String)

    Template containing a DISK element

Returns:



386
387
388
# File 'lib/opennebula/virtual_machine.rb', line 386

def disk_attach(disk_template)
    return call(VM_METHODS[:attach], @pe_id, disk_template)
end

#disk_detach(disk_id) ⇒ nil, OpenNebula::Error Also known as: detachdisk

Detaches a disk from a running VM

Parameters:

  • disk_id (Integer)

    Id of the disk to be detached

Returns:



397
398
399
# File 'lib/opennebula/virtual_machine.rb', line 397

def disk_detach(disk_id)
    return call(VM_METHODS[:detach], @pe_id, disk_id)
end

#disk_saveas(disk_id, image_name, image_type = "", snap_id = -1)) ⇒ Integer, OpenNebula::Error

Set the specified vm’s disk to be saved as a new image

current disk image state

Parameters:

  • disk_id (Integer)

    ID of the disk to be saved

  • image_name (String)

    Name for the new image where the disk will be saved

  • image_type (String) (defaults to: "")

    Type of the new image. Set to empty string to use the default type

  • snap_id (Integer) (defaults to: -1))

    ID of the snapshot to save, -1 to use the

Returns:

  • (Integer, OpenNebula::Error)

    the new Image ID in case of success, error otherwise



487
488
489
490
491
492
493
494
495
496
497
# File 'lib/opennebula/virtual_machine.rb', line 487

def disk_saveas(disk_id, image_name, image_type="", snap_id=-1)
    return Error.new('ID not defined') if !@pe_id

    rc = @client.call(VM_METHODS[:disksaveas],
                      @pe_id,
                      disk_id,
                      image_name,
                      image_type,
                      snap_id)
    return rc
end

#disk_snapshot_create(disk_id, name) ⇒ Integer, OpenNebula::Error

Takes a new snapshot of a disk

Parameters:

  • disk_id (Integer)

    Id of the disk

  • name (String)

    description for the snapshot

Returns:



622
623
624
# File 'lib/opennebula/virtual_machine.rb', line 622

def disk_snapshot_create(disk_id, name)
  return call(VM_METHODS[:disksnapshotcreate], @pe_id, disk_id, name)
end

#disk_snapshot_delete(disk_id, snap_id) ⇒ nil, OpenNebula::Error

Deletes a disk snapshot

Parameters:

  • disk_id (Integer)

    Id of the disk

  • snap_id (Integer)

    Id of the snapshot

Returns:



644
645
646
# File 'lib/opennebula/virtual_machine.rb', line 644

def disk_snapshot_delete(disk_id, snap_id)
  return call(VM_METHODS[:disksnapshotdelete], @pe_id, disk_id, snap_id)
end

#disk_snapshot_revert(disk_id, snap_id) ⇒ nil, OpenNebula::Error

Reverts disk state to a previously taken snapshot

Parameters:

  • disk_id (Integer)

    Id of the disk

  • snap_id (Integer)

    Id of the snapshot

Returns:



633
634
635
# File 'lib/opennebula/virtual_machine.rb', line 633

def disk_snapshot_revert(disk_id, snap_id)
  return call(VM_METHODS[:disksnapshotrevert], @pe_id, disk_id, snap_id)
end

#finalize(recreate = false) ⇒ Object

Deprecated.

use #delete instead



431
432
433
# File 'lib/opennebula/virtual_machine.rb', line 431

def finalize(recreate=false)
    delete(recreate)
end

#gidObject

Returns the group identifier

return

Integer the element’s group ID



696
697
698
# File 'lib/opennebula/virtual_machine.rb', line 696

def gid
    self['GID'].to_i
end

#holdObject

Sets a VM to hold state, scheduler will not deploy it



357
358
359
# File 'lib/opennebula/virtual_machine.rb', line 357

def hold
    action('hold')
end

#infoObject Also known as: info!

Retrieves the information of the given VirtualMachine.



252
253
254
# File 'lib/opennebula/virtual_machine.rb', line 252

def info()
    super(VM_METHODS[:info], 'VM')
end

#keep_disks?Boolean

Returns the deploy_id of the VirtualMachine (numeric value)

Returns:

  • (Boolean)


706
707
708
709
# File 'lib/opennebula/virtual_machine.rb', line 706

def keep_disks?
    !self['USER_TEMPLATE/KEEP_DISKS_ON_DONE'].nil? &&
        self['USER_TEMPLATE/KEEP_DISKS_ON_DONE'].downcase=="yes"
end

#lcm_stateObject

Returns the LCM state of the VirtualMachine (numeric value)



674
675
676
# File 'lib/opennebula/virtual_machine.rb', line 674

def lcm_state
    self['LCM_STATE'].to_i
end

#lcm_state_strObject

Returns the LCM state of the VirtualMachine (string value)



679
680
681
# File 'lib/opennebula/virtual_machine.rb', line 679

def lcm_state_str
    LCM_STATE[lcm_state]
end

#live_migrate(host_id, enforce = false) ⇒ Object

Deprecated.

use #migrate instead



471
472
473
# File 'lib/opennebula/virtual_machine.rb', line 471

def live_migrate(host_id, enforce=false)
    migrate(host_id, true, enforce)
end

#migrate(host_id, live = false, enforce = false, ds_id = -1)) ⇒ nil, OpenNebula::Error

Moves a running VM to the specified host. With live=true the migration is done withdout downtime.

Parameters:

  • host_id (Interger)

    The host id (hid) of the target host where the VM will be migrated.

  • live (true|false) (defaults to: false)

    If true the migration is done without downtime. Defaults to false

  • enforce (true|false) (defaults to: false)

    If it is set to true, the host capacity will be checked, and the deployment will fail if the host is overcommited. Defaults to false

  • ds_id (Integer) (defaults to: -1))

    The System Datastore where to migrate the VM. To use the current one, set it to -1

Returns:



465
466
467
468
# File 'lib/opennebula/virtual_machine.rb', line 465

def migrate(host_id, live=false, enforce=false, ds_id=-1)
    call(VM_METHODS[:migrate], @pe_id, host_id.to_i, live==true,
        enforce, ds_id.to_i)
end

#monitoring(xpath_expressions) ⇒ Hash<String, Array<Array<int>>>, OpenNebula::Error

Retrieves this VM’s monitoring data from OpenNebula

Examples:

vm.monitoring( ['MONITORING/CPU', 'MONITORING/NETTX'] )

{
 "MONITORING/CPU"=>[["1435085098", "47"], ["1435085253", "5"],
   ["1435085410", "48"], ["1435085566", "3"], ["1435088136", "2"]],
 "MONITORING/NETTX"=>[["1435085098", "0"], ["1435085253", "50"],
   ["1435085410", "50"], ["1435085566", "50"], ["1435085723", "50"]]
}

Parameters:

  • xpath_expressions (Array<String>)

    Elements to retrieve.

Returns:

  • (Hash<String, Array<Array<int>>>, OpenNebula::Error)

    Hash with the requested xpath expressions, and an Array of ‘timestamp, value’.



559
560
561
562
# File 'lib/opennebula/virtual_machine.rb', line 559

def monitoring(xpath_expressions)
    return super(VM_METHODS[:monitoring], 'VM',
        'LAST_POLL', xpath_expressions)
end

#monitoring_xmlString

Retrieves this VM’s monitoring data from OpenNebula, in XML

Returns:

  • (String)

    VM monitoring data, in XML



567
568
569
570
571
# File 'lib/opennebula/virtual_machine.rb', line 567

def monitoring_xml()
    return Error.new('ID not defined') if !@pe_id

    return @client.call(VM_METHODS[:monitoring], @pe_id)
end

#nic_attach(nic_template) ⇒ nil, OpenNebula::Error

Attaches a NIC to a running VM

Parameters:

  • nic_template (String)

    Template containing a NIC element

Returns:



408
409
410
# File 'lib/opennebula/virtual_machine.rb', line 408

def nic_attach(nic_template)
    return call(VM_METHODS[:attachnic], @pe_id, nic_template)
end

#nic_detach(nic_id) ⇒ nil, OpenNebula::Error

Detaches a NIC from a running VM

Parameters:

  • nic_id (Integer)

    Id of the NIC to be detached

Returns:



417
418
419
# File 'lib/opennebula/virtual_machine.rb', line 417

def nic_detach(nic_id)
    return call(VM_METHODS[:detachnic], @pe_id, nic_id)
end

#poweroff(hard = false) ⇒ Object

Powers off a running VM



337
338
339
# File 'lib/opennebula/virtual_machine.rb', line 337

def poweroff(hard=false)
    action(hard ? 'poweroff-hard' : 'poweroff')
end

#reboot(hard = false) ⇒ Object

Reboots an already deployed VM



342
343
344
# File 'lib/opennebula/virtual_machine.rb', line 342

def reboot(hard=false)
    action(hard ? 'reboot-hard' : 'reboot')
end

#recover(result) ⇒ nil, OpenNebula::Error

Recovers an ACTIVE VM

retry (2)

Parameters:

  • result (Integer)

    Recover with failure (0), success (1) or

  • result (info)

    Additional information needed to recover the VM

Returns:



655
656
657
# File 'lib/opennebula/virtual_machine.rb', line 655

def recover(result)
    return call(VM_METHODS[:recover], @pe_id, result)
end

#releaseObject

Releases a VM from hold state



362
363
364
# File 'lib/opennebula/virtual_machine.rb', line 362

def release
    action('release')
end

#rename(name) ⇒ nil, OpenNebula::Error

Renames this VM

Parameters:

  • name (String)

    New name for the VM.

Returns:



579
580
581
# File 'lib/opennebula/virtual_machine.rb', line 579

def rename(name)
    return call(VM_METHODS[:rename], @pe_id, name)
end

#reschedObject

Sets the re-scheduling flag for the VM



441
442
443
# File 'lib/opennebula/virtual_machine.rb', line 441

def resched
    action('resched')
end

#resetObject

Deprecated.

use #reboot



347
348
349
# File 'lib/opennebula/virtual_machine.rb', line 347

def reset
    reboot(true)
end

#resize(capacity_template, enforce) ⇒ nil, OpenNebula::Error

Resize the VM

Parameters:

  • capacity_template (String)

    Template containing the new capacity elements CPU, VCPU, MEMORY. If one of them is not present, or its value is 0, it will not be resized

  • enforce (true|false)

    If it is set to true, the host capacity will be checked. This will only affect oneadmin requests, regular users resize requests will always be enforced

Returns:



510
511
512
# File 'lib/opennebula/virtual_machine.rb', line 510

def resize(capacity_template, enforce)
    return call(VM_METHODS[:resize], @pe_id, capacity_template, enforce)
end

#resubmitObject

Deprecated.

use #delete instead



436
437
438
# File 'lib/opennebula/virtual_machine.rb', line 436

def resubmit
    action('delete-recreate')
end

#resumeObject

Resumes the execution of a saved VM



377
378
379
# File 'lib/opennebula/virtual_machine.rb', line 377

def resume
    action('resume')
end

#save_as_template(name) ⇒ Integer, OpenNebula::Error

Clones the VM’s source Template, replacing the disks with live snapshots of the current disks. The VM capacity and NICs are also preserved

Parameters:

  • name (String)

    Name for the new Template

Returns:

  • (Integer, OpenNebula::Error)

    the new Template ID in case of success, error otherwise



718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
# File 'lib/opennebula/virtual_machine.rb', line 718

def save_as_template(name)
    img_ids = []
    new_tid = nil

    begin
        rc = info()
        raise if OpenNebula.is_error?(rc)

        tid = self['TEMPLATE/TEMPLATE_ID']
        if tid.nil? || tid.empty?
            rc = Error.new('VM has no template to be saved')
            raise
        end

        if state_str() != "POWEROFF"
            rc = Error.new("VM state must be POWEROFF, "<<
                "current state is #{state_str()}, #{lcm_state_str()}")
            raise
        end

        # Clone the source template
        rc = OpenNebula::Template.new_with_id(tid, @client).clone(name)
        raise if OpenNebula.is_error?(rc)

        new_tid = rc

        # Replace the original template's capacity with the actual VM values
        replace = ""

        cpu = self['TEMPLATE/CPU']
        if !cpu.nil? && !cpu.empty?
            replace << "CPU = #{cpu}\n"
        end

        vcpu = self['TEMPLATE/VCPU']
        if !vcpu.nil? && !vcpu.empty?
            replace << "VCPU = #{vcpu}\n"
        end

        mem = self['TEMPLATE/MEMORY']
        if !mem.nil? && !mem.empty?
            replace << "MEMORY = #{mem}\n"
        end

        self.each('TEMPLATE/DISK') do |disk|
            # While the previous snapshot is still in progress, we wait
            # indefinitely
            rc = info()
            raise if OpenNebula.is_error?(rc)

            steps = 0
            while lcm_state_str() == "HOTPLUG_SAVEAS_POWEROFF"
                if steps < 30
                    sleep 1
                else
                    sleep 15
                end

                rc = info()
                raise if OpenNebula.is_error?(rc)

                steps += 1
            end

            # If the VM is not busy with a previous disk snapshot, we wait
            # but this time with a timeout
            rc = wait_state("POWEROFF")
            raise if OpenNebula.is_error?(rc)

            disk_id = disk["DISK_ID"]
            if disk_id.nil? || disk_id.empty?
                rc = Error.new('The DISK_ID is missing from the VM template')
                raise
            end

            image_id = disk["IMAGE_ID"]

            if !image_id.nil? && !image_id.empty?
                rc = disk_saveas(disk_id.to_i,"#{name}-disk-#{disk_id}","",-1)

                raise if OpenNebula.is_error?(rc)

                img_ids << rc.to_i

                replace << "DISK = [ IMAGE_ID = #{rc} ]\n"
            else
                # Volatile disks cannot be saved, so the definition is copied
                replace << self.template_like_str(
                    "TEMPLATE", true, "DISK[DISK_ID=#{disk_id}]") << "\n"
            end
        end

        self.each('TEMPLATE/NIC') do |nic|
            nic_id = nic["NIC_ID"]
            if nic_id.nil? || nic_id.empty?
                rc = Error.new('The NIC_ID is missing from the VM template')
                raise
            end

            net_id = nic["NETWORK_ID"]

            if !net_id.nil? && !net_id.empty?
                replace << "NIC = [ NETWORK_ID = #{net_id} ]\n"
            else
                # This NIC does not use a Virtual Network
                replace << self.template_like_str(
                    "TEMPLATE", true, "NIC[NIC_ID=#{nic_id}]") << "\n"
            end
        end

        # Required by the Sunstone Cloud View
        replace << "SAVED_TEMPLATE_ID = #{tid}\n"

        new_tmpl = OpenNebula::Template.new_with_id(new_tid, @client)

        rc = new_tmpl.update(replace, true)
        raise if OpenNebula.is_error?(rc)

        return new_tid

    rescue
        # Rollback. Delete the template and the images created
        if !new_tid.nil?
            new_tmpl = OpenNebula::Template.new_with_id(new_tid, @client)
            new_tmpl.delete()
        end

        img_ids.each do |id|
            img = OpenNebula::Image.new_with_id(id, @client)
            img.delete()
        end

        return rc
    end
end

#shutdown(hard = false) ⇒ Object

Shutdowns an already deployed VM



327
328
329
# File 'lib/opennebula/virtual_machine.rb', line 327

def shutdown(hard=false)
    action(hard ? 'shutdown-hard' : 'shutdown')
end

#snapshot_create(name = "") ⇒ Integer, OpenNebula::Error

Creates a new VM snapshot

Parameters:

  • name (String) (defaults to: "")

    Name for the snapshot.

Returns:

  • (Integer, OpenNebula::Error)

    The new snaphost ID in case of success, Error otherwise



589
590
591
592
593
594
# File 'lib/opennebula/virtual_machine.rb', line 589

def snapshot_create(name="")
    return Error.new('ID not defined') if !@pe_id

    name ||= ""
    return @client.call(VM_METHODS[:snapshotcreate], @pe_id, name)
end

#snapshot_delete(snap_id) ⇒ nil, OpenNebula::Error

Deletes a VM snapshot

Parameters:

  • snap_id (Integer)

    Id of the snapshot

Returns:



612
613
614
# File 'lib/opennebula/virtual_machine.rb', line 612

def snapshot_delete(snap_id)
    return call(VM_METHODS[:snapshotdelete], @pe_id, snap_id)
end

#snapshot_revert(snap_id) ⇒ nil, OpenNebula::Error

Reverts to a snapshot

Parameters:

  • snap_id (Integer)

    Id of the snapshot

Returns:



602
603
604
# File 'lib/opennebula/virtual_machine.rb', line 602

def snapshot_revert(snap_id)
    return call(VM_METHODS[:snapshotrevert], @pe_id, snap_id)
end

#stateObject

Returns the VM state of the VirtualMachine (numeric value)



664
665
666
# File 'lib/opennebula/virtual_machine.rb', line 664

def state
    self['STATE'].to_i
end

#state_strObject

Returns the VM state of the VirtualMachine (string value)



669
670
671
# File 'lib/opennebula/virtual_machine.rb', line 669

def state_str
    VM_STATE[state]
end

#statusObject

Returns the short status string for the VirtualMachine



684
685
686
687
688
689
690
691
692
# File 'lib/opennebula/virtual_machine.rb', line 684

def status
    short_state_str=SHORT_VM_STATES[state_str]

    if short_state_str=="actv"
        short_state_str=SHORT_LCM_STATES[lcm_state_str]
    end

    short_state_str
end

#stopObject

Stops a running VM



367
368
369
# File 'lib/opennebula/virtual_machine.rb', line 367

def stop
    action('stop')
end

#suspendObject

Saves a running VM



372
373
374
# File 'lib/opennebula/virtual_machine.rb', line 372

def suspend
    action('suspend')
end

#undeploy(hard = false) ⇒ Object

Shuts down an already deployed VM, saving its state in the system DS



332
333
334
# File 'lib/opennebula/virtual_machine.rb', line 332

def undeploy(hard=false)
    action(hard ? 'undeploy-hard' : 'undeploy')
end

#unreschedObject

Unsets the re-scheduling flag for the VM



446
447
448
# File 'lib/opennebula/virtual_machine.rb', line 446

def unresched
    action('unresched')
end

#update(new_template = nil, append = false) ⇒ nil, OpenNebula::Error

Replaces the template contents

Parameters:

  • new_template (String) (defaults to: nil)

    New template contents

  • append (true, false) (defaults to: false)

    True to append new attributes instead of replace the whole template

Returns:



279
280
281
# File 'lib/opennebula/virtual_machine.rb', line 279

def update(new_template=nil, append=false)
    super(VM_METHODS[:update], new_template, append ? 1 : 0)
end

#user_template_str(indent = true) ⇒ String

Returns the <USER_TEMPLATE> element in text form

Parameters:

  • indent (true, false) (defaults to: true)

    indents the resulting string, defaults to true

Returns:

  • (String)

    The USER_TEMPLATE



288
289
290
# File 'lib/opennebula/virtual_machine.rb', line 288

def user_template_str(indent=true)
    template_like_str('USER_TEMPLATE', indent)
end

#user_template_xmlString

Returns the <USER_TEMPLATE> element in XML form

Returns:

  • (String)

    The USER_TEMPLATE



295
296
297
298
299
300
301
# File 'lib/opennebula/virtual_machine.rb', line 295

def user_template_xml
    if NOKOGIRI
        @xml.xpath('USER_TEMPLATE').to_s
    else
        @xml.elements['USER_TEMPLATE'].to_s
    end
end