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 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
@@ -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
- Vm.new(vm_uid, self) # Isn't this expensive?
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
- def initialize(uid, host)
5
- @uid = uid
6
- @host = host
7
- end
8
-
9
- def record
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 Vm
3
+ class VM < Base
4
4
 
5
- attr_reader :uid
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
- # self.get_state # Too expensive!
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
- name.to_s == "Domain-0"
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
- @host.call("VM.hard_reboot",@uid)
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
- # Record..
83
- def record
84
- @host.get_value("VM.get_record", @uid)
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
- def to_s
88
- @uid.to_s
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.1
7
- date: 2007-08-29 00:00:00 +02:00
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