xen 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +26 -1
- data/lib/xen.rb +7 -1
- data/lib/xen/base.rb +19 -0
- data/lib/xen/console.rb +16 -0
- data/lib/xen/host.rb +26 -1
- data/lib/xen/network.rb +8 -16
- data/lib/xen/sr.rb +12 -0
- data/lib/xen/vbd.rb +39 -0
- data/lib/xen/vdi.rb +51 -0
- data/lib/xen/vif.rb +19 -0
- data/lib/xen/vm.rb +73 -18
- metadata +9 -3
data/README
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
Xen strives to be the Ruby interface talking to the Xen API. It grew from our own need to talk to Xen Servers with Ruby.
|
4
4
|
|
5
|
+
=== Install:
|
6
|
+
xen is a registered rubygem, so you can just do
|
7
|
+
sudo gem install xen
|
8
|
+
|
9
|
+
And you're good to go.
|
10
|
+
|
5
11
|
=== Usage:
|
6
12
|
|
7
13
|
# Connect to xenhost
|
@@ -13,4 +19,23 @@ Xen strives to be the Ruby interface talking to the Xen API. It grew from our ow
|
|
13
19
|
end
|
14
20
|
|
15
21
|
# Restart a certain VM
|
16
|
-
xenhost.find_vm('example_vm').clean_reboot!
|
22
|
+
xenhost.find_vm('example_vm').clean_reboot!
|
23
|
+
|
24
|
+
|
25
|
+
=== Creating a new VM:
|
26
|
+
|
27
|
+
h = Xen::Host.new('10.1.10.200')
|
28
|
+
|
29
|
+
network =Xen::Network.find_by_name 'xenbr101', h
|
30
|
+
|
31
|
+
vm = h.create_vm 'slice', 128*1024*1024
|
32
|
+
|
33
|
+
vdi_hda1 = h.create_vdi 'vdi1', 'phy:/dev/xendomains/slice-root'
|
34
|
+
vdi_hda2 = h.create_vdi 'vdi2', 'phy:/dev/xendomains/slice-swap'
|
35
|
+
|
36
|
+
vbd1 = h.create_vbd 'hda1', vm, vdi_hda1
|
37
|
+
vbd2 = h.create_vbd 'hda2', vm, vdi_hda2
|
38
|
+
|
39
|
+
vif = h.create_vif vm, network, '00:30:48:88:81:03'
|
40
|
+
|
41
|
+
vm.start!
|
data/lib/xen.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
+
require 'xen/base.rb'
|
1
2
|
require 'xen/connection.rb'
|
2
3
|
require 'xen/host.rb'
|
3
4
|
require 'xen/vm.rb'
|
4
|
-
require 'xen/network.rb'
|
5
|
+
require 'xen/network.rb'
|
6
|
+
require 'xen/sr.rb'
|
7
|
+
require 'xen/vdi.rb'
|
8
|
+
require 'xen/vbd.rb'
|
9
|
+
require 'xen/console.rb'
|
10
|
+
require 'xen/vif.rb'
|
data/lib/xen/base.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Xen
|
2
|
+
class Base
|
3
|
+
def initialize(uid, host)
|
4
|
+
@uid, @host = uid, host
|
5
|
+
end
|
6
|
+
|
7
|
+
def uuid
|
8
|
+
self.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
@uid.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def record
|
16
|
+
@host.get_value("#{self.class.to_s.gsub(/^.*::/, '')}.get_record", @uid)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/xen/console.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Xen
|
2
|
+
class Console < Base
|
3
|
+
|
4
|
+
# The initial config for a new VDI device
|
5
|
+
@initial_config = {
|
6
|
+
:protocol => 'rfb'
|
7
|
+
}
|
8
|
+
|
9
|
+
# Create method, takes a name, a device (p.ex. 'phy:/dev/storage/slice') and a host
|
10
|
+
def self.create(vm, host)
|
11
|
+
config = @initial_config.merge({:VM => vm.uuid})
|
12
|
+
uuid = host.get_value("console.create", config)
|
13
|
+
self.new(uuid, host)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/xen/host.rb
CHANGED
@@ -18,7 +18,7 @@ module Xen
|
|
18
18
|
# Gives an array of active VM's on that Host.
|
19
19
|
def vms
|
20
20
|
get_value("host.get_resident_VMs", uid).collect do |vm_uid|
|
21
|
-
|
21
|
+
VM.new(vm_uid, self) # Isn't this expensive?
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -47,6 +47,31 @@ module Xen
|
|
47
47
|
get_value("host.get_record")
|
48
48
|
end
|
49
49
|
|
50
|
+
# gives the local storage resource
|
51
|
+
def get_local_sr
|
52
|
+
SR.get_local(self)
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_vdi(name, dev)
|
56
|
+
VDI.create(name, dev, self)
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_vbd(device, vm, vdi)
|
60
|
+
VBD.create(device, vm, vdi, self)
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_vif(vm, network, mac)
|
64
|
+
VIF.create(vm, network, mac, self)
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_vm(name, memory)
|
68
|
+
VM.create(name, memory, self)
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_console(vm)
|
72
|
+
Console.create(vm, self)
|
73
|
+
end
|
74
|
+
|
50
75
|
def to_s
|
51
76
|
uid.to_s
|
52
77
|
end
|
data/lib/xen/network.rb
CHANGED
@@ -1,21 +1,13 @@
|
|
1
1
|
module Xen
|
2
|
-
class Network
|
2
|
+
class Network < Base
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@host.call("network.get_record", @uid)['Value']
|
11
|
-
end
|
12
|
-
|
13
|
-
def uuid
|
14
|
-
self.to_s
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_s
|
18
|
-
@uid.to_s
|
4
|
+
# Searches the networks for a certain name
|
5
|
+
def self.find_by_name(name, host)
|
6
|
+
host.get_value("network.get_all").collect do |networkuid|
|
7
|
+
return self.new(networkuid, host) if host.get_value("network.get_name_label", networkuid) == name
|
8
|
+
end
|
9
|
+
nil
|
19
10
|
end
|
11
|
+
|
20
12
|
end
|
21
13
|
end
|
data/lib/xen/sr.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Xen
|
2
|
+
class SR < Base
|
3
|
+
|
4
|
+
# Searches the host for the first storage resource with the type set to 'local'
|
5
|
+
def self.get_local(host)
|
6
|
+
host.get_value("SR.get_all").each do |sruid|
|
7
|
+
return self.new(sruid, host) if host.get_value("SR.get_type", sruid) == 'local'
|
8
|
+
end
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/xen/vbd.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Xen
|
2
|
+
class VBD < Base
|
3
|
+
|
4
|
+
@initial_config = {
|
5
|
+
# :device=>"hda1",
|
6
|
+
:bootable=>"0",
|
7
|
+
:mode=>"RW",
|
8
|
+
:type=>"disk",
|
9
|
+
:driver=>"paravirtualised",
|
10
|
+
# :VM => "73a2c34f-d5f1-2c96-e6f6-ca98de793d2d",
|
11
|
+
# :VDI => "20b1af7c-fe3a-bdf4-eeb8-c8635d0daadc"
|
12
|
+
}
|
13
|
+
|
14
|
+
# Creates a new VBD. Required paramters are the device ('hda1'), the vm object, the vdi object and the host
|
15
|
+
def self.create(dev, vm, vdi, host)
|
16
|
+
o = @initial_config.merge({:device => dev,
|
17
|
+
:VM => vm.uuid,
|
18
|
+
:VDI => vdi.uuid})
|
19
|
+
uuid = host.get_value("VBD.create", o)
|
20
|
+
self.new(uuid, host)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Gets the connected VDI
|
24
|
+
def vdi
|
25
|
+
Xen::VDI.new(@host.get_value('VBD.get_VDI', self.uuid), @host)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Destroys the VBD
|
29
|
+
def destroy!
|
30
|
+
@host.call('VBD.destroy', self.uuid)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Gives a nice description
|
34
|
+
def humanize
|
35
|
+
r = self.record
|
36
|
+
"VBD #{self.uuid} is disk '#{r['device']}' in the VM, connected to VDI #{self.vdi}\n" + self.vdi.humanize('\--')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/xen/vdi.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Xen
|
2
|
+
class VDI < Base
|
3
|
+
|
4
|
+
# The initial config for a new VDI device
|
5
|
+
@initial_config = {
|
6
|
+
:type => 'system',
|
7
|
+
:sharable => false,
|
8
|
+
}
|
9
|
+
|
10
|
+
# Create method, takes a name, a device (p.ex. 'phy:/dev/storage/slice') and a host
|
11
|
+
def self.create(name, dev, host)
|
12
|
+
sr = host.get_local_sr
|
13
|
+
config = @initial_config.merge({:name_label => name,
|
14
|
+
:other_config => {:location => dev},
|
15
|
+
:SR => sr.uuid })
|
16
|
+
uuid = host.get_value("VDI.create", config)
|
17
|
+
self.new(uuid, host)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finds a device when given a devicename
|
21
|
+
def self.find_by_device(dev, host)
|
22
|
+
host.get_value('VDI.get_all').each do |vdi|
|
23
|
+
vdirecord = host.get_value('VDI.get_record', vdi)
|
24
|
+
return self.new(vdi, host) if vdirecord['other_config']['location'] == dev
|
25
|
+
end
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# Destroys the current VDI
|
30
|
+
def destroy!
|
31
|
+
@host.call 'VDI.destroy', self.uuid
|
32
|
+
end
|
33
|
+
|
34
|
+
# Gets all the VDBs connected
|
35
|
+
def vbds
|
36
|
+
@host.get_value('VDI.get_VBDs', self.uuid).collect do |vbd|
|
37
|
+
Xen::VBD.new(vbd, @host)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Gives some human string
|
42
|
+
def humanize(prepend)
|
43
|
+
r = self.record
|
44
|
+
if !r
|
45
|
+
prepend + "Unknown vdi #{self.uuid}"
|
46
|
+
else
|
47
|
+
prepend + "VDI #{self.uuid} is device #{r['other_config']['location']}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/xen/vif.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Xen
|
2
|
+
class VIF < Base
|
3
|
+
|
4
|
+
@initial_config = {
|
5
|
+
:device => "eth0",
|
6
|
+
:MTU => "1500"
|
7
|
+
}
|
8
|
+
|
9
|
+
# Creates a new VIF in a vm. The mac address is spelled out, with colons in between
|
10
|
+
def self.create(vm, network, mac, host)
|
11
|
+
o = @initial_config.merge({:VM => vm.uuid,
|
12
|
+
:network => network.uuid,
|
13
|
+
:MAC => mac
|
14
|
+
})
|
15
|
+
uuid = host.get_value("VIF.create", o)
|
16
|
+
self.new(uuid, host)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/xen/vm.rb
CHANGED
@@ -1,13 +1,58 @@
|
|
1
1
|
module Xen
|
2
2
|
|
3
|
-
class
|
3
|
+
class VM < Base
|
4
4
|
|
5
|
-
|
5
|
+
@initial_config = {
|
6
|
+
# :name_label => '',
|
7
|
+
:name_description => 'Openminds APIs zijn vetgeil',
|
8
|
+
:user_version => 1,
|
9
|
+
:is_a_template => false,
|
10
|
+
# :memory_static_max => 32,
|
11
|
+
# :memory_dynamic_max => 32,
|
12
|
+
# :memory_dynamic_min => 32,
|
13
|
+
# :memory_static_min => 32,
|
14
|
+
:VCPUs_policy => '',
|
15
|
+
:VCPUs_params => '',
|
16
|
+
:VCPUS_features_required => '',
|
17
|
+
:VCPUs_features_can_use => '',
|
18
|
+
:VCPUs_features_force_on => '',
|
19
|
+
:VCPUs_features_force_off => '',
|
20
|
+
:actions_after_shutdown => 'restart',
|
21
|
+
:actions_after_reboot => 'restart',
|
22
|
+
:actions_after_suspend => 'destroy',
|
23
|
+
:actions_after_crash => 'restart',
|
24
|
+
:bios_boot => '',
|
25
|
+
:platform_std_VGA => false,
|
26
|
+
:platform_serial => '',
|
27
|
+
:platform_localtime => false,
|
28
|
+
:platform_clock_offset => false,
|
29
|
+
:platform_enable_audio => false,
|
30
|
+
:builder => 'linux',
|
31
|
+
:boot_method => '',
|
32
|
+
:PV_kernel => '/boot/xenu-linux-2.6.18-domu',
|
33
|
+
:PV_initrd => '',
|
34
|
+
:PV_args => 'root=/dev/hda1 ro 4',
|
35
|
+
:grub_cmdline => '',
|
36
|
+
:PCI_bus => '',
|
37
|
+
:other_config => '' ,
|
38
|
+
}
|
39
|
+
|
40
|
+
# Creates a new VM with a certain name set and a amount of memory (in bytes) on a host
|
41
|
+
def self.create(name, memory, host)
|
42
|
+
o = @initial_config.merge({
|
43
|
+
:name_label => name,
|
44
|
+
:memory_static_max => memory,
|
45
|
+
:memory_dynamic_max => memory,
|
46
|
+
:memory_dynamic_min => memory,
|
47
|
+
:memory_static_min => memory
|
48
|
+
})
|
49
|
+
uid = host.get_value("VM.create", o)
|
50
|
+
self.new(uid, host)
|
6
51
|
|
7
52
|
# Creates a new VM, Given the VM's UID and the host it is running on.
|
8
53
|
def initialize(uid, host)
|
9
54
|
@uid, @host = uid, host
|
10
|
-
|
55
|
+
preload_record!
|
11
56
|
end
|
12
57
|
|
13
58
|
# Gets the state of the VM. The first time it is called it query's the server, other times it is cached. There is an optional parameter 'refresh' which, when true, will re-query the server.
|
@@ -24,19 +69,14 @@ module Xen
|
|
24
69
|
|
25
70
|
# Returns the VM's name
|
26
71
|
def name
|
27
|
-
@host.get_value("VM.get_name_label",@uid)
|
72
|
+
@name ||= @host.get_value("VM.get_name_label",@uid)
|
28
73
|
end
|
29
74
|
|
30
75
|
# Returns true if the current vm happens to be dom0.
|
31
76
|
def is_dom0?
|
32
|
-
|
77
|
+
@control_domain
|
33
78
|
end
|
34
79
|
|
35
|
-
# Returns the VM's uuid
|
36
|
-
def uuid
|
37
|
-
@host.get_value("VM.get_uuid",@uid)
|
38
|
-
end
|
39
|
-
|
40
80
|
# Starts a VM, and returns the current state
|
41
81
|
def start!(paused = false)
|
42
82
|
@host.call("VM.start",@uid, paused)
|
@@ -75,17 +115,32 @@ module Xen
|
|
75
115
|
|
76
116
|
# Hard reboots the VM, and returns the current state
|
77
117
|
def hard_reboot!
|
78
|
-
|
118
|
+
# Update 30/08/2007
|
119
|
+
# This function just returns an ENOTIMPLEMENTED in the Xen API, so we'll have to implement it ourselves
|
120
|
+
# @host.call("VM.hard_reboot",@uid)
|
121
|
+
|
122
|
+
# Should do:
|
123
|
+
# hard_shutdown!
|
124
|
+
# start!
|
79
125
|
state(true)
|
80
126
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
127
|
+
|
128
|
+
def vdbs
|
129
|
+
@host.get_value('VM.get_VBDs', self.uuid).collect do |vbd|
|
130
|
+
Xen::VBD.new(vbd, @host)
|
131
|
+
end
|
85
132
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|
133
|
+
|
134
|
+
private
|
135
|
+
def preload_record
|
136
|
+
data = record
|
137
|
+
@dom_id = data["domid"]
|
138
|
+
@kernel = data["PV_kernel"]
|
139
|
+
@kernel_args = data["PV_args"]
|
140
|
+
@name = data["name_label"]
|
141
|
+
# vifs
|
142
|
+
@control_domain = data["is_control_domain"]
|
89
143
|
end
|
144
|
+
|
90
145
|
end
|
91
146
|
end
|
metadata
CHANGED
@@ -3,13 +3,13 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: xen
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date: 2007-08-
|
6
|
+
version: 0.1.2
|
7
|
+
date: 2007-08-31 00:00:00 +02:00
|
8
8
|
summary: A package that is a link between Ruby and Xen API.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: xen-ruby@openminds.be
|
12
|
-
homepage:
|
12
|
+
homepage: ruby-xen.rubyforge.com
|
13
13
|
rubyforge_project:
|
14
14
|
description:
|
15
15
|
autorequire: xen
|
@@ -31,9 +31,15 @@ authors:
|
|
31
31
|
- Jan De Poorter
|
32
32
|
files:
|
33
33
|
- lib/xen
|
34
|
+
- lib/xen/base.rb
|
34
35
|
- lib/xen/connection.rb
|
36
|
+
- lib/xen/console.rb
|
35
37
|
- lib/xen/host.rb
|
36
38
|
- lib/xen/network.rb
|
39
|
+
- lib/xen/sr.rb
|
40
|
+
- lib/xen/vbd.rb
|
41
|
+
- lib/xen/vdi.rb
|
42
|
+
- lib/xen/vif.rb
|
37
43
|
- lib/xen/vm.rb
|
38
44
|
- lib/xen.rb
|
39
45
|
- README
|