fog-libvirt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTORS.md +23 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE.md +20 -0
  5. data/README.md +29 -0
  6. data/Rakefile +122 -0
  7. data/fog-libvirt.gemspec +49 -0
  8. data/lib/fog/bin/libvirt.rb +58 -0
  9. data/lib/fog/libvirt/compute.rb +136 -0
  10. data/lib/fog/libvirt/models/compute/README.md +76 -0
  11. data/lib/fog/libvirt/models/compute/interface.rb +25 -0
  12. data/lib/fog/libvirt/models/compute/interfaces.rb +20 -0
  13. data/lib/fog/libvirt/models/compute/network.rb +29 -0
  14. data/lib/fog/libvirt/models/compute/networks.rb +20 -0
  15. data/lib/fog/libvirt/models/compute/nic.rb +50 -0
  16. data/lib/fog/libvirt/models/compute/nics.rb +12 -0
  17. data/lib/fog/libvirt/models/compute/node.rb +29 -0
  18. data/lib/fog/libvirt/models/compute/nodes.rb +20 -0
  19. data/lib/fog/libvirt/models/compute/pool.rb +84 -0
  20. data/lib/fog/libvirt/models/compute/pools.rb +20 -0
  21. data/lib/fog/libvirt/models/compute/server.rb +401 -0
  22. data/lib/fog/libvirt/models/compute/servers.rb +21 -0
  23. data/lib/fog/libvirt/models/compute/templates/network.xml.erb +6 -0
  24. data/lib/fog/libvirt/models/compute/templates/pool.xml.erb +6 -0
  25. data/lib/fog/libvirt/models/compute/templates/server.xml.erb +54 -0
  26. data/lib/fog/libvirt/models/compute/templates/volume.xml.erb +26 -0
  27. data/lib/fog/libvirt/models/compute/util/uri.rb +138 -0
  28. data/lib/fog/libvirt/models/compute/util/util.rb +32 -0
  29. data/lib/fog/libvirt/models/compute/volume.rb +122 -0
  30. data/lib/fog/libvirt/models/compute/volumes.rb +20 -0
  31. data/lib/fog/libvirt/requests/compute/clone_volume.rb +18 -0
  32. data/lib/fog/libvirt/requests/compute/create_domain.rb +17 -0
  33. data/lib/fog/libvirt/requests/compute/create_volume.rb +16 -0
  34. data/lib/fog/libvirt/requests/compute/define_domain.rb +17 -0
  35. data/lib/fog/libvirt/requests/compute/define_pool.rb +16 -0
  36. data/lib/fog/libvirt/requests/compute/destroy_interface.rb +18 -0
  37. data/lib/fog/libvirt/requests/compute/destroy_network.rb +17 -0
  38. data/lib/fog/libvirt/requests/compute/get_node_info.rb +37 -0
  39. data/lib/fog/libvirt/requests/compute/list_domains.rb +105 -0
  40. data/lib/fog/libvirt/requests/compute/list_interfaces.rb +57 -0
  41. data/lib/fog/libvirt/requests/compute/list_networks.rb +55 -0
  42. data/lib/fog/libvirt/requests/compute/list_pool_volumes.rb +19 -0
  43. data/lib/fog/libvirt/requests/compute/list_pools.rb +71 -0
  44. data/lib/fog/libvirt/requests/compute/list_volumes.rb +88 -0
  45. data/lib/fog/libvirt/requests/compute/mock_files/domain.xml +40 -0
  46. data/lib/fog/libvirt/requests/compute/pool_action.rb +19 -0
  47. data/lib/fog/libvirt/requests/compute/update_display.rb +31 -0
  48. data/lib/fog/libvirt/requests/compute/vm_action.rb +19 -0
  49. data/lib/fog/libvirt/requests/compute/volume_action.rb +18 -0
  50. data/lib/fog/libvirt/version.rb +5 -0
  51. data/lib/fog/libvirt.rb +18 -0
  52. data/tests/helper.rb +17 -0
  53. data/tests/helpers/formats_helper.rb +98 -0
  54. data/tests/helpers/formats_helper_tests.rb +110 -0
  55. data/tests/helpers/mock_helper.rb +14 -0
  56. data/tests/helpers/succeeds_helper.rb +9 -0
  57. data/tests/libvirt/compute_tests.rb +17 -0
  58. data/tests/libvirt/models/compute/interface_tests.rb +27 -0
  59. data/tests/libvirt/models/compute/interfaces_tests.rb +14 -0
  60. data/tests/libvirt/models/compute/network_tests.rb +27 -0
  61. data/tests/libvirt/models/compute/networks_tests.rb +13 -0
  62. data/tests/libvirt/models/compute/nic_tests.rb +31 -0
  63. data/tests/libvirt/models/compute/nics_tests.rb +10 -0
  64. data/tests/libvirt/models/compute/pool_tests.rb +27 -0
  65. data/tests/libvirt/models/compute/pools_tests.rb +13 -0
  66. data/tests/libvirt/models/compute/server_tests.rb +58 -0
  67. data/tests/libvirt/models/compute/servers_tests.rb +14 -0
  68. data/tests/libvirt/models/compute/volume_tests.rb +38 -0
  69. data/tests/libvirt/models/compute/volumes_tests.rb +14 -0
  70. data/tests/libvirt/requests/compute/create_domain_tests.rb +21 -0
  71. data/tests/libvirt/requests/compute/define_domain_tests.rb +11 -0
  72. data/tests/libvirt/requests/compute/update_display.rb +13 -0
  73. metadata +355 -0
@@ -0,0 +1,12 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/libvirt/models/compute/nic'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Libvirt
7
+ class Nics < Fog::Collection
8
+ model Fog::Compute::Libvirt::Nic
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ require 'fog/core/model'
2
+
3
+ module Fog
4
+ module Compute
5
+ class Libvirt
6
+ class Node < Fog::Model
7
+ identity :uuid
8
+
9
+ attribute :model
10
+ attribute :memory
11
+ attribute :cpus
12
+ attribute :mhz
13
+ attribute :nodes
14
+ attribute :sockets
15
+ attribute :cores
16
+ attribute :threads
17
+ attribute :type
18
+ attribute :version
19
+ attribute :uri
20
+ attribute :node_free_memory
21
+ attribute :max_vcpus
22
+ attribute :manufacturer
23
+ attribute :product
24
+ attribute :serial
25
+ attribute :hostname
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/libvirt/models/compute/node'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Libvirt
7
+ class Nodes < Fog::Collection
8
+ model Fog::Compute::Libvirt::Node
9
+
10
+ def all(filter={ })
11
+ load(service.get_node_info)
12
+ end
13
+
14
+ def get
15
+ all.first
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,84 @@
1
+ require 'fog/core/model'
2
+
3
+ module Fog
4
+ module Compute
5
+ class Libvirt
6
+ class Pool < Fog::Model
7
+ attr_reader :xml
8
+
9
+ identity :uuid
10
+
11
+ attribute :persistent
12
+ attribute :autostart
13
+ attribute :active
14
+ attribute :name
15
+ attribute :allocation
16
+ attribute :capacity
17
+ attribute :num_of_volumes
18
+ attribute :state
19
+
20
+ def initialize(attributes={} )
21
+ # Can be created by passing in XML
22
+ @xml = attributes.delete(:xml)
23
+ super(attributes)
24
+ end
25
+
26
+ def save
27
+ raise Fog::Errors::Error.new('Creating a new pool requires proper xml') unless xml
28
+ self.uuid = (persistent ? service.define_pool(xml) : service.create_pool(xml)).uuid
29
+ reload
30
+ end
31
+
32
+ # Start the pool = make it active
33
+ # Performs a libvirt create (= start)
34
+ def start
35
+ service.pool_action uuid, :create
36
+ end
37
+
38
+ # Stop the pool = make it non-active
39
+ # Performs a libvirt destroy (= stop)
40
+ def stop
41
+ service.pool_action uuid, :destroy
42
+ end
43
+
44
+ # Shuts down the pool
45
+ def shutdown
46
+ stop
47
+ end
48
+
49
+ # Build this storage pool
50
+ def build
51
+ service.pool_action uuid, :build
52
+ end
53
+
54
+ # Destroys the storage pool
55
+ def destroy
56
+ # Shutdown pool if active
57
+ service.pool_action uuid, :destroy if active?
58
+ # If this is a persistent domain we need to undefine it
59
+ service.pool_action uuid, :undefine if persistent?
60
+ end
61
+
62
+ # Is the pool active or not?
63
+ def active?
64
+ active
65
+ end
66
+
67
+ # Will the pool autostart or not?
68
+ def auto_start?
69
+ autostart
70
+ end
71
+
72
+ # Is the pool persistent or not?
73
+ def persistent?
74
+ persistent
75
+ end
76
+
77
+ # Retrieves the volumes of this pool
78
+ def volumes
79
+ service.list_pool_volumes uuid
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,20 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/libvirt/models/compute/pool'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Libvirt
7
+ class Pools < Fog::Collection
8
+ model Fog::Compute::Libvirt::Pool
9
+
10
+ def all(filter = {})
11
+ load(service.list_pools(filter))
12
+ end
13
+
14
+ def get(uuid)
15
+ self.all(:uuid => uuid).first
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,401 @@
1
+ require 'fog/compute/models/server'
2
+ require 'fog/libvirt/models/compute/util/util'
3
+ require 'net/ssh/proxy/command'
4
+
5
+ module Fog
6
+ module Compute
7
+ class Libvirt
8
+ class Server < Fog::Compute::Server
9
+ include Fog::Compute::LibvirtUtil
10
+ attr_reader :xml
11
+
12
+ identity :id, :aliases => 'uuid'
13
+
14
+ attribute :cpus
15
+ attribute :cputime
16
+ attribute :os_type
17
+ attribute :memory_size
18
+ attribute :max_memory_size
19
+ attribute :name
20
+ attribute :arch
21
+ attribute :persistent
22
+ attribute :domain_type
23
+ attribute :uuid
24
+ attribute :autostart
25
+ attribute :nics
26
+ attribute :volumes
27
+ attribute :active
28
+ attribute :boot_order
29
+ attribute :display
30
+
31
+ attribute :state
32
+
33
+ # The following attributes are only needed when creating a new vm
34
+ #TODO: Add depreciation warning
35
+ attr_accessor :iso_dir, :iso_file
36
+ attr_accessor :network_interface_type ,:network_nat_network, :network_bridge_name
37
+ attr_accessor :volume_format_type, :volume_allocation,:volume_capacity, :volume_name, :volume_pool_name, :volume_template_name, :volume_path
38
+ attr_accessor :password
39
+
40
+ # Can be created by passing in :xml => "<xml to create domain/server>"
41
+ # or by providing :template_options => {
42
+ # :name => "", :cpus => 1, :memory_size => 256 , :volume_template
43
+ # }
44
+
45
+ def initialize(attributes={} )
46
+ @xml = attributes.delete(:xml)
47
+ verify_boot_order(attributes[:boot_order])
48
+ super defaults.merge(attributes)
49
+ initialize_nics
50
+ initialize_volumes
51
+ end
52
+
53
+ def new?
54
+ uuid.nil?
55
+ end
56
+
57
+ def save
58
+ raise Fog::Errors::Error.new('Saving an existing server may create a duplicate') unless new?
59
+ create_or_clone_volume unless xml or @volumes
60
+ @xml ||= to_xml
61
+ self.id = (persistent ? service.define_domain(xml) : service.create_domain(xml)).uuid
62
+ reload
63
+ rescue => e
64
+ raise Fog::Errors::Error.new("Error saving the server: #{e}")
65
+ end
66
+
67
+ def start
68
+ return true if active?
69
+ action_status = service.vm_action(uuid, :create)
70
+ reload
71
+ action_status
72
+ end
73
+
74
+ def mac
75
+ nics.first.mac if nics && nics.first
76
+ end
77
+
78
+ def disk_path
79
+ volumes.first.path if volumes and volumes.first
80
+ end
81
+
82
+ def destroy(options={ :destroy_volumes => false})
83
+ poweroff unless stopped?
84
+ service.vm_action(uuid, :undefine)
85
+ volumes.each { |vol| vol.destroy } if options[:destroy_volumes]
86
+ true
87
+ end
88
+
89
+ def reboot
90
+ action_status = service.vm_action(uuid, :reboot)
91
+ reload
92
+ action_status
93
+ end
94
+
95
+ def poweroff
96
+ action_status = service.vm_action(uuid, :destroy)
97
+ reload
98
+ action_status
99
+ end
100
+
101
+ def shutdown
102
+ action_status = service.vm_action(uuid, :shutdown)
103
+ reload
104
+ action_status
105
+ end
106
+
107
+ def resume
108
+ action_status = service.vm_action(uuid, :resume)
109
+ reload
110
+ action_status
111
+ end
112
+
113
+ def suspend
114
+ action_status = service.vm_action(uuid, :suspend)
115
+ reload
116
+ action_status
117
+ end
118
+
119
+ def stopped?
120
+ state == "shutoff"
121
+ end
122
+
123
+ def ready?
124
+ state == "running"
125
+ end
126
+
127
+ #alias methods
128
+ alias_method :halt, :poweroff
129
+ alias_method :stop, :shutdown
130
+ alias_method :active?, :active
131
+
132
+ def volumes
133
+ # lazy loading of volumes
134
+ @volumes ||= (@volumes_path || []).map{|path| service.volumes.all(:path => path).first }
135
+ end
136
+
137
+ def private_ip_address
138
+ ip_address(:private)
139
+ end
140
+
141
+ def public_ip_address
142
+ ip_address(:public)
143
+ end
144
+
145
+ def ssh(commands)
146
+ requires :ssh_ip_address, :username
147
+
148
+ ssh_options={}
149
+ ssh_options[:password] = password unless password.nil?
150
+ ssh_options[:proxy]= ssh_proxy unless ssh_proxy.nil?
151
+
152
+ super(commands, ssh_options)
153
+ end
154
+
155
+ def ssh_proxy
156
+ # if this is a direct connection, we don't need a proxy to be set.
157
+ return nil unless connection.uri.ssh_enabled?
158
+ user_string= service.uri.user ? "-l #{service.uri.user}" : ""
159
+ Net::SSH::Proxy::Command.new("ssh #{user_string} #{service.uri.host} nc %h %p")
160
+ end
161
+
162
+ # Transfers a file
163
+ def scp(local_path, remote_path, upload_options = {})
164
+ requires :ssh_ip_address, :username
165
+
166
+ scp_options = {}
167
+ scp_options[:password] = password unless self.password.nil?
168
+ scp_options[:key_data] = [private_key] if self.private_key
169
+ scp_options[:proxy]= ssh_proxy unless self.ssh_proxy.nil?
170
+
171
+ Fog::SCP.new(ssh_ip_address, username, scp_options).upload(local_path, remote_path, upload_options)
172
+ end
173
+
174
+ # Sets up a new key
175
+ def setup(credentials = {})
176
+ requires :public_key, :ssh_ip_address, :username
177
+
178
+ credentials[:proxy]= ssh_proxy unless ssh_proxy.nil?
179
+ credentials[:password] = password unless self.password.nil?
180
+ credentails[:key_data] = [private_key] if self.private_key
181
+
182
+ commands = [
183
+ %{mkdir .ssh},
184
+ # %{passwd -l #{username}}, #Not sure if we need this here
185
+ # %{echo "#{Fog::JSON.encode(attributes)}" >> ~/attributes.json}
186
+ ]
187
+ if public_key
188
+ commands << %{echo "#{public_key}" >> ~/.ssh/authorized_keys}
189
+ end
190
+
191
+ # wait for domain to be ready
192
+ Timeout::timeout(360) do
193
+ begin
194
+ Timeout::timeout(8) do
195
+ Fog::SSH.new(ssh_ip_address, username, credentials.merge(:timeout => 4)).run('pwd')
196
+ end
197
+ rescue Errno::ECONNREFUSED
198
+ sleep(2)
199
+ retry
200
+ rescue Net::SSH::AuthenticationFailed, Timeout::Error
201
+ retry
202
+ end
203
+ end
204
+ Fog::SSH.new(ssh_ip_address, username, credentials).run(commands)
205
+ end
206
+
207
+ def update_display attrs = {}
208
+ service.update_display attrs.merge(:uuid => uuid)
209
+ reload
210
+ end
211
+
212
+ # can't use deprecate method, as the value is part of the display hash
213
+ def vnc_port
214
+ Fog::Logger.deprecation("#{self.class} => #vnc_port is deprecated, use #display[:port] instead [light_black](#{caller.first})[/]")
215
+ display[:port]
216
+ end
217
+
218
+ private
219
+ attr_accessor :volumes_path
220
+
221
+ # This retrieves the ip address of the mac address
222
+ # It returns an array of public and private ip addresses
223
+ # Currently only one ip address is returned, but in the future this could be multiple
224
+ # if the server has multiple network interface
225
+ def addresses(service_arg=service, options={})
226
+ mac=self.mac
227
+
228
+ # Aug 24 17:34:41 juno arpwatch: new station 10.247.4.137 52:54:00:88:5a:0a eth0.4
229
+ # Aug 24 17:37:19 juno arpwatch: changed ethernet address 10.247.4.137 52:54:00:27:33:00 (52:54:00:88:5a:0a) eth0.4
230
+ # Check if another ip_command string was provided
231
+ ip_command_global=service_arg.ip_command.nil? ? 'grep $mac /var/log/arpwatch.log|sed -e "s/new station//"|sed -e "s/changed ethernet address//g" |sed -e "s/reused old ethernet //" |tail -1 |cut -d ":" -f 4-| cut -d " " -f 3' : service_arg.ip_command
232
+ ip_command_local=options[:ip_command].nil? ? ip_command_global : options[:ip_command]
233
+
234
+ ip_command="mac=#{mac}; server_name=#{name}; "+ip_command_local
235
+
236
+ ip_address=nil
237
+
238
+ if service_arg.uri.ssh_enabled?
239
+
240
+ # Retrieve the parts we need from the service to setup our ssh options
241
+ user=service_arg.uri.user #could be nil
242
+ host=service_arg.uri.host
243
+ keyfile=service_arg.uri.keyfile
244
+ port=service_arg.uri.port
245
+
246
+ # Setup the options
247
+ ssh_options={}
248
+ ssh_options[:keys]=[ keyfile ] unless keyfile.nil?
249
+ ssh_options[:port]=port unless keyfile.nil?
250
+ ssh_options[:paranoid]=true if service_arg.uri.no_verify?
251
+
252
+ begin
253
+ result=Fog::SSH.new(host, user, ssh_options).run(ip_command)
254
+ rescue Errno::ECONNREFUSED
255
+ raise Fog::Errors::Error.new("Connection was refused to host #{host} to retrieve the ip_address for #{mac}")
256
+ rescue Net::SSH::AuthenticationFailed
257
+ raise Fog::Errors::Error.new("Error authenticating over ssh to host #{host} and user #{user}")
258
+ end
259
+
260
+ # Check for a clean exit code
261
+ if result.first.status == 0
262
+ ip_address=result.first.stdout.strip
263
+ else
264
+ # We got a failure executing the command
265
+ raise Fog::Errors::Error.new("The command #{ip_command} failed to execute with a clean exit code")
266
+ end
267
+
268
+ else
269
+ # It's not ssh enabled, so we assume it is
270
+ if service_arg.uri.transport=="tls"
271
+ raise Fog::Errors::Error.new("TlS remote transport is not currently supported, only ssh")
272
+ end
273
+
274
+ # Execute the ip_command locally
275
+ # Initialize empty ip_address string
276
+ ip_address=""
277
+
278
+ IO.popen("#{ip_command}") do |p|
279
+ p.each_line do |l|
280
+ ip_address+=l
281
+ end
282
+ status=Process.waitpid2(p.pid)[1].exitstatus
283
+ if status!=0
284
+ raise Fog::Errors::Error.new("The command #{ip_command} failed to execute with a clean exit code")
285
+ end
286
+ end
287
+
288
+ #Strip any new lines from the string
289
+ ip_address=ip_address.chomp
290
+ end
291
+
292
+ # The Ip-address command has been run either local or remote now
293
+
294
+ if ip_address==""
295
+ #The grep didn't find an ip address result"
296
+ ip_address=nil
297
+ else
298
+ # To be sure that the command didn't return another random string
299
+ # We check if the result is an actual ip-address
300
+ # otherwise we return nil
301
+ unless ip_address=~/^(\d{1,3}\.){3}\d{1,3}$/
302
+ raise Fog::Errors::Error.new(
303
+ "The result of #{ip_command} does not have valid ip-address format\n"+
304
+ "Result was: #{ip_address}\n"
305
+ )
306
+ end
307
+ end
308
+
309
+ return { :public => [ip_address], :private => [ip_address]}
310
+ end
311
+
312
+ def ip_address(key)
313
+ addresses[key].nil? ? nil : addresses[key].first
314
+ end
315
+
316
+ def initialize_nics
317
+ if nics
318
+ nics.map! { |nic| nic.is_a?(Hash) ? service.nics.new(nic) : nic }
319
+ else
320
+ self.nics = [service.nics.new({:type => network_interface_type, :bridge => network_bridge_name, :network => network_nat_network})]
321
+ end
322
+ end
323
+
324
+ def initialize_volumes
325
+ if attributes[:volumes] && !attributes[:volumes].empty?
326
+ @volumes = attributes[:volumes].map { |vol| vol.is_a?(Hash) ? service.volumes.new(vol) : vol }
327
+ end
328
+ end
329
+
330
+ def create_or_clone_volume
331
+ options = {:name => volume_name || default_volume_name}
332
+ # Check if a disk template was specified
333
+ if volume_template_name
334
+ template_volume = service.volumes.all(:name => volume_template_name).first
335
+ raise Fog::Errors::Error.new("Template #{volume_template_name} not found") unless template_volume
336
+ begin
337
+ volume = template_volume.clone("#{options[:name]}")
338
+ rescue => e
339
+ raise Fog::Errors::Error.new("Error creating the volume : #{e}")
340
+ end
341
+ else
342
+ # If no template volume was given, let's create our own volume
343
+ options[:pool_name] = volume_pool_name if volume_pool_name
344
+ options[:format_type] = volume_format_type if volume_format_type
345
+ options[:capacity] = volume_capacity if volume_capacity
346
+ options[:allocation] = volume_allocation if volume_allocation
347
+
348
+ begin
349
+ volume = service.volumes.create(options)
350
+ rescue => e
351
+ raise Fog::Errors::Error.new("Error creating the volume : #{e}")
352
+ end
353
+ end
354
+ @volumes.nil? ? @volumes = [volume] : @volumes << volume
355
+ end
356
+
357
+ def default_iso_dir
358
+ "/var/lib/libvirt/images"
359
+ end
360
+
361
+ def default_volume_name
362
+ "#{name}.#{volume_format_type || 'img'}"
363
+ end
364
+
365
+ def defaults
366
+ {
367
+ :persistent => true,
368
+ :cpus => 1,
369
+ :memory_size => 256 *1024,
370
+ :name => randomized_name,
371
+ :os_type => "hvm",
372
+ :arch => "x86_64",
373
+ :domain_type => "kvm",
374
+ :iso_dir => default_iso_dir,
375
+ :network_interface_type => "network",
376
+ :network_nat_network => "default",
377
+ :network_bridge_name => "br0",
378
+ :boot_order => default_boot_order,
379
+ :display => default_display
380
+ }
381
+ end
382
+
383
+ def default_boot_order
384
+ %w[hd cdrom network]
385
+ end
386
+
387
+ def verify_boot_order order = []
388
+ if order
389
+ order.each do |b|
390
+ raise "invalid boot order, possible values are: hd, network and/or cdrom" unless default_boot_order.include?(b)
391
+ end
392
+ end
393
+ end
394
+
395
+ def default_display
396
+ {:port => '-1', :listen => '127.0.0.1', :type => 'vnc', :password => '' }
397
+ end
398
+ end
399
+ end
400
+ end
401
+ end
@@ -0,0 +1,21 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/libvirt/models/compute/server'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Libvirt
7
+ class Servers < Fog::Collection
8
+ model Fog::Compute::Libvirt::Server
9
+
10
+ def all(filter={})
11
+ load(service.list_domains(filter))
12
+ end
13
+
14
+ def get(uuid)
15
+ data = service.list_domains(:uuid => uuid)
16
+ new data.first if data
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+ <network>
2
+ <name><%= name %></name>
3
+ <forward mode='<%= network_mode %>'/>
4
+ <bridge name='<%= bridge_name %>' stp='on' delay='0' />
5
+ </ip>
6
+ </network>
@@ -0,0 +1,6 @@
1
+ <pool type="dir">
2
+ <name><%= name %></name>
3
+ <target>
4
+ <path><%= path %></path>
5
+ </target>
6
+ </pool>
@@ -0,0 +1,54 @@
1
+ <domain type='<%= domain_type %>'>
2
+ <name><%= name %></name>
3
+ <memory><%= memory_size %></memory>
4
+ <vcpu><%= cpus %></vcpu>
5
+ <os>
6
+ <type arch='<%= arch %>'><%= os_type %></type>
7
+ <% boot_order.each do |dev| -%>
8
+ <boot dev='<%= dev %>'/>
9
+ <% end -%>
10
+ </os>
11
+ <features>
12
+ <acpi/>
13
+ <apic/>
14
+ <pae/>
15
+ </features>
16
+ <clock offset='utc'/>
17
+ <devices>
18
+ <% volumes.each do |vol| -%>
19
+ <disk type='file' device='disk'>
20
+ <driver name='qemu' type='<%= vol.format_type %>'/>
21
+ <source file='<%= vol.path %>'/>
22
+ <%# we need to ensure a unique target dev -%>
23
+ <target dev='vd<%= ('a'..'z').to_a[volumes.index(vol)] %>' bus='virtio'/>
24
+ </disk>
25
+ <% end -%>
26
+ <% if iso_file -%>
27
+ <disk type='file' device='cdrom'>
28
+ <driver name='qemu' type='raw'/>
29
+ <source file='<%= "#{iso_dir}/#{iso_file}" %>'/>
30
+ <target dev='hdc' bus='ide'/>
31
+ <readonly/>
32
+ <address type='drive' controller='0' bus='1' unit='0'/>
33
+ </disk>
34
+ <% end -%>
35
+ <% nics.each do |nic| -%>
36
+ <interface type='<%= nic.type %>'>
37
+ <source <%= nic.type == 'bridge' ? "bridge='#{nic.bridge}'" : "network='#{nic.network}'" %> />
38
+ <model type='<%= nic.model %>'/>
39
+ </interface>
40
+ <% end -%>
41
+ <serial type='pty'>
42
+ <target port='0'/>
43
+ </serial>
44
+ <console type='pty'>
45
+ <target port='0'/>
46
+ </console>
47
+ <input type='tablet' bus='usb'/>
48
+ <input type='mouse' bus='ps2'/>
49
+ <graphics type='<%= display[:type] %>' port='<%= display[:port] %>' autoport='yes' <% if display[:listen] and !(display[:listen].empty?) %> listen='<%= display[:listen] %>'<% end %> <% if display[:password] and !(display[:password].empty?) %>passwd='<%=display[:password] %>'<% end %> />
50
+ <video>
51
+ <model type='cirrus' vram='9216' heads='1'/>
52
+ </video>
53
+ </devices>
54
+ </domain>
@@ -0,0 +1,26 @@
1
+ <volume>
2
+ <name><%= name %></name>
3
+ <allocation unit="<%= split_size_unit(allocation)[1] %>"><%= split_size_unit(allocation)[0] %></allocation>
4
+ <capacity unit="<%= split_size_unit(capacity)[1] %>"><%= split_size_unit(capacity)[0] %></capacity>
5
+ <target>
6
+ <format type="<%= format_type %>"/>
7
+ <permissions>
8
+ <owner>0</owner>
9
+ <group>0</group>
10
+ <mode>0744</mode>
11
+ <label>virt_image_t</label>
12
+ </permissions>
13
+ </target>
14
+ <% if backing_volume -%>
15
+ <backingStore>
16
+ <path><%= backing_volume.path %></path>
17
+ <format type="<%= backing_volume.format_type %>"/>
18
+ <permissions>
19
+ <owner>0</owner>
20
+ <group>0</group>
21
+ <mode>0744</mode>
22
+ <label>virt_image_t</label>
23
+ </permissions>
24
+ </backingStore>
25
+ <% end -%>
26
+ </volume>