knife-xenserver 1.2.3 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0a21012f437a6b7241b41a04ae171ce86c27ed40
4
+ data.tar.gz: 625142e1c88af7d2268efd3dd823cdaa7e83969a
5
+ SHA512:
6
+ metadata.gz: 97caa51eb4b6bbf79f02f25cf3576b5ccd30a416c2d795954e586c5007987dd73c92e06a3f92c902f1a7d482d43e2ac94e5378230f1d1c48d929805a031484f5
7
+ data.tar.gz: b68b1bddf3c70ca6862af78b388ac6acc58f6ca16c9a2093fbd626a1dd5a3ea7f826ce524a76b6245855c8b2a75a4fe41f010beda448b02db6eb910c687ca756
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # 1.3.1 - Thy 06 Jun 2013
2
+
3
+ * Fixing some --extra-vdis parsing issues
4
+ * Fix nasty bug while trying to roll back destroying the created VM
5
+
6
+ # 1.3.0 - Thy 06 Jun 2013
7
+
8
+ * New **sr list** command to list storage repositories.
9
+ * Experimental **sr create** command to create a Storage Repository.
10
+ * The **vm create** command now supports --extra-vdis option to
11
+ create additional VDIs and attach them to the VM.
12
+ * New **host list** command: currently lists UUID only.
13
+
14
+
1
15
  # 1.2.3 - Fri 07 Dec 2012
2
16
 
3
17
  * Drop alchemist gem, fixing some compat issues with some ruby 1.9
@@ -0,0 +1,41 @@
1
+ #
2
+ # Author:: Sergio Rubio (<rubiojr@frameos.org>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'chef/knife/xenserver_base'
19
+
20
+ class Chef
21
+ class Knife
22
+ class XenserverHostList < Knife
23
+
24
+ include Knife::XenserverBase
25
+
26
+ banner "knife xenserver host list (options)"
27
+
28
+ def run
29
+ hosts = connection.hosts
30
+ table = table do |t|
31
+ t.headings = %w{NAME UUID}
32
+ hosts.each do |host|
33
+ t << [host.name, host.uuid]
34
+ end
35
+ end
36
+ puts table if !hosts.empty?
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,99 @@
1
+ #
2
+ # Author:: Sergio Rubio (<rubiojr@frameos.org>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'chef/knife/xenserver_base'
19
+ require 'resolv'
20
+
21
+ class Chef
22
+ class Knife
23
+ class XenserverSrCreate < Knife
24
+
25
+ include Knife::XenserverBase
26
+
27
+ banner "knife xenserver sr create (options)"
28
+
29
+ option :sr_name,
30
+ :long => "--sr-name NAME",
31
+ :description => "The Storage Repository name"
32
+
33
+ option :sr_type,
34
+ :long => "--sr-type TYPE",
35
+ :description => "The Storage Repository type (ext|lvm)"
36
+
37
+ option :sr_device,
38
+ :long => "--sr-device PATH",
39
+ :description => "Block device path in host"
40
+
41
+ option :sr_host,
42
+ :long => "--sr-host UUID",
43
+ :description => "Host where the Storage Repository will be created"
44
+
45
+ def run
46
+ sr_name = config[:sr_name]
47
+ if not sr_name
48
+ ui.error("Invalid Storage Repository name (--sr-name)")
49
+ exit 1
50
+ end
51
+
52
+ sr_type = config[:sr_type]
53
+ if not sr_type
54
+ ui.error("Invalid Storage Repository type (--sr-type)")
55
+ exit 1
56
+ end
57
+
58
+ sr_device = config[:sr_device]
59
+ if not sr_device
60
+ ui.error("Invalid Storage Repository device (--sr-device)")
61
+ exit 1
62
+ end
63
+
64
+ hosts = connection.hosts
65
+ sr_host = config[:sr_host]
66
+ if sr_host.nil? and hosts.size > 1
67
+ if not sr_host
68
+ ui.error("More than one host found in the pool.")
69
+ ui.error("--sr-host parameter is mandatory")
70
+ exit 1
71
+ end
72
+ end
73
+
74
+ if sr_host
75
+ # Find the host in the pool
76
+ host = connection.hosts.find { |h| h.uuid == sr_host }
77
+ else
78
+ # We only have one hosts
79
+ host = hosts.first
80
+ end
81
+
82
+ # The given host was not found in the pool
83
+ if host.nil?
84
+ ui.error "Host #{sr_host} not found in the pool"
85
+ exit 1
86
+ end
87
+
88
+ dconfig = { :device => sr_device }
89
+ puts "Creating SR #{sr_name.yellow} in host #{host.name} (#{sr_type}, #{sr_device})..."
90
+ vm = connection.storage_repositories.create :name => sr_name,
91
+ :host => host,
92
+ :device_config => dconfig,
93
+ :type => sr_type
94
+
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,72 @@
1
+ #
2
+ # Author:: Sergio Rubio (<rubiojr@frameos.org>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'chef/knife/xenserver_base'
19
+
20
+ class Chef
21
+ class Knife
22
+ class XenserverSrList < Knife
23
+
24
+ include Knife::XenserverBase
25
+
26
+ banner "knife xenserver sr list (options)"
27
+
28
+ option :sr_type,
29
+ :long => "--sr-types",
30
+ :description => "List only the types specified (comma separated types)",
31
+ :default => 'ext,lvm'
32
+
33
+ option :numeric_utilisation,
34
+ :long => "--[no-]numeric-utilisation",
35
+ :description => "Print SR utilisation in bytes",
36
+ :default => false,
37
+ :boolean => true
38
+
39
+ def run
40
+ # Finding the current host (the one we used to get the connection)
41
+ #xshost = config[:xenserver_host] || Chef::Config[:knife][:xenserver_host]
42
+ #address = Resolv.getaddress xshost
43
+ #host = connection.hosts.find { |h| h.address == address }
44
+
45
+ # Storage Repositories belong to the pool,
46
+ # There's no way to list host storage repositories AFAIK
47
+ repositories = connection.storage_repositories
48
+ table = table do |t|
49
+ t.headings = %w{NAME TYPE UTILISATION UUID}
50
+ valid_types = config[:sr_type].split(',').map { |t| t.strip }
51
+ repositories.each do |sr|
52
+ # we only list LVM and EXT repositories by default
53
+ next unless valid_types.include? sr.type
54
+ if config[:numeric_utilisation]
55
+ utilisation = sr.physical_utilisation
56
+ else
57
+ if sr.physical_size.to_i > 0
58
+ utilisation = (sr.physical_utilisation.to_i * 100)/sr.physical_size.to_f * 100
59
+ utilisation = "%.2f%" % utilisation
60
+ else
61
+ utilisation = "100%"
62
+ end
63
+ end
64
+ t << [sr.name, sr.type, utilisation, sr.uuid]
65
+ end
66
+ end
67
+ puts table if !repositories.empty?
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -158,6 +158,10 @@ class Chef
158
158
  :long => '--vm-domain DOMAIN',
159
159
  :description => 'DOMAIN of host to set in xenstore'
160
160
 
161
+ option :extra_vdis,
162
+ :long => '--extra-vdis "SR name":size1[,"SR NAME":size2,..]',
163
+ :description => 'Create and attach additional VDIs (size in MB)'
164
+
161
165
  def tcp_test_ssh(hostname)
162
166
  tcp_socket = TCPSocket.new(hostname, 22)
163
167
  readable = IO.select([tcp_socket], nil, nil, 5)
@@ -181,14 +185,12 @@ class Chef
181
185
  $stdout.sync = true
182
186
 
183
187
  unless config[:vm_template]
184
- ui.error("You have not provided a valid template name. (--vm-template)")
185
- exit 1
188
+ raise "You have not provided a valid template name. (--vm-template)"
186
189
  end
187
190
 
188
191
  vm_name = config[:vm_name]
189
192
  if not vm_name
190
- ui.error("Invalid Virtual Machine name (--vm-name)")
191
- exit 1
193
+ raise "Invalid Virtual Machine name (--vm-name)"
192
194
  end
193
195
 
194
196
  unless config[:vm_gateway]
@@ -207,8 +209,7 @@ class Chef
207
209
  end
208
210
 
209
211
  if template.nil?
210
- ui.error "Template #{config[:vm_template]} not found."
211
- exit 1
212
+ raise "Template #{config[:vm_template]} not found."
212
213
  end
213
214
 
214
215
  puts "Creating VM #{config[:vm_name].yellow}..."
@@ -217,6 +218,9 @@ class Chef
217
218
  vm = connection.servers.new :name => config[:vm_name],
218
219
  :template_name => config[:vm_template]
219
220
  vm.save :auto_start => false
221
+ # Useful for the global exception handler
222
+ @created_vm = vm
223
+
220
224
  if not config[:keep_template_networks]
221
225
  vm.vifs.each do |vif|
222
226
  vif.destroy
@@ -246,7 +250,10 @@ class Chef
246
250
  if config[:vm_tags]
247
251
  vm.set_attribute 'tags', config[:vm_tags].split(',')
248
252
  end
253
+
249
254
  vm.provision
255
+ # Create additional VDIs (virtual disks)
256
+ create_extra_vdis(vm)
250
257
  vm.start
251
258
  vm.reload
252
259
 
@@ -287,8 +294,7 @@ class Chef
287
294
  timeout -= 1
288
295
  if timeout == 0
289
296
  puts
290
- ui.error "Timeout trying to reach the VM. Couldn't find the IP address."
291
- exit 1
297
+ raise "Timeout trying to reach the VM. Couldn't find the IP address."
292
298
  end
293
299
  end
294
300
  print "\n#{ui.color("Waiting for sshd... ", :magenta)}"
@@ -332,6 +338,66 @@ class Chef
332
338
  bootstrap.config[:ssh_password] = config[:ssh_password]
333
339
  bootstrap
334
340
  end
341
+
342
+ def create_extra_vdis(vm)
343
+ # Return if no extra VDIs were specified
344
+ return unless config[:extra_vdis]
345
+ count = 0
346
+
347
+ vdis = config[:extra_vdis].strip.chomp.split(',')
348
+ vdis.each do |vdi|
349
+ count += 1
350
+ # if options is "Storage Repository":size
351
+ if vdi =~ /.*:.*/
352
+ sr, size = vdi.split(':')
353
+ else #only size was specified
354
+ sr = nil
355
+ size = vdi
356
+ end
357
+ unless size =~ /^\d+$/
358
+ raise "Invalid VDI size. Not numeric."
359
+ end
360
+ # size in bytes
361
+ bsize = size.to_i * 1024 * 1024
362
+
363
+ # If the storage repository has been omitted,
364
+ # use the default SR from the first pool, othewise
365
+ # find the SR required
366
+ if sr.nil?
367
+ sr = connection.pools.first.default_sr
368
+ ui.warn "No storage repository defined for extra VDI #{count}."
369
+ ui.warn "Using default SR from Pool: #{sr.name}"
370
+ else
371
+ found = connection.storage_repositories.find { |s| s.name == sr }
372
+ unless found
373
+ raise "Storage Repository #{sr} not available"
374
+ end
375
+ sr = found
376
+ end
377
+
378
+ # Name of the VDI
379
+ name = "#{config[:vm_name]}-extra-vdi-#{count}"
380
+
381
+ puts "Creating extra VDI (#{size} MB, #{name}, #{sr.name || 'Default SR'})"
382
+ vdi = connection.vdis.create :name => name,
383
+ :storage_repository => sr,
384
+ :description => name,
385
+ :virtual_size => bsize.to_s
386
+
387
+ begin
388
+ # Attach the VBD
389
+ connection.vbds.create :server => vm,
390
+ :vdi => vdi,
391
+ :userdevice => count.to_s,
392
+ :bootable => false
393
+ rescue => e
394
+ ui.error "Could not attach the VBD to the server"
395
+ # Try to destroy the VDI
396
+ vdi.destroy rescue nil
397
+ raise e
398
+ end
399
+ end
400
+ end
335
401
 
336
402
  def create_nics(networks, macs, vm)
337
403
  net_arr = networks.split(/,/).map { |x| { :network => x } }
@@ -349,8 +415,7 @@ class Chef
349
415
  nics.each do |n|
350
416
  net = networks.find { |net| net.name == n[:network] }
351
417
  if net.nil?
352
- ui.error "Network #{n[:network]} not found"
353
- exit 1
418
+ raise "Network #{n[:network]} not found"
354
419
  end
355
420
  nic_count += 1
356
421
  c = {
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module XenServer
3
- VERSION = "1.2.3"
3
+ VERSION = "1.3.1"
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,96 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-xenserver
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 1.2.3
4
+ version: 1.3.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Sergio Rubio
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-01-06 00:00:00.000000000 Z
11
+ date: 2013-06-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- type: :runtime
14
+ name: terminal-table
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
20
+ type: :runtime
22
21
  prerelease: false
23
22
  version_requirements: !ruby/object:Gem::Requirement
24
- none: false
25
23
  requirements:
26
- - - ! '>='
24
+ - - '>='
27
25
  - !ruby/object:Gem::Version
28
26
  version: '0'
29
- name: terminal-table
30
27
  - !ruby/object:Gem::Dependency
31
- type: :runtime
28
+ name: chef
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0.10'
34
+ type: :runtime
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
- none: false
41
37
  requirements:
42
- - - ! '>='
38
+ - - '>='
43
39
  - !ruby/object:Gem::Version
44
40
  version: '0.10'
45
- name: chef
46
41
  - !ruby/object:Gem::Dependency
47
- type: :runtime
42
+ name: fog
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '1.4'
48
+ type: :runtime
54
49
  prerelease: false
55
50
  version_requirements: !ruby/object:Gem::Requirement
56
- none: false
57
51
  requirements:
58
- - - ! '>='
52
+ - - '>='
59
53
  - !ruby/object:Gem::Version
60
54
  version: '1.4'
61
- name: fog
62
55
  - !ruby/object:Gem::Dependency
63
- type: :runtime
56
+ name: colored
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
62
+ type: :runtime
70
63
  prerelease: false
71
64
  version_requirements: !ruby/object:Gem::Requirement
72
- none: false
73
65
  requirements:
74
- - - ! '>='
66
+ - - '>='
75
67
  - !ruby/object:Gem::Version
76
68
  version: '0'
77
- name: colored
78
69
  - !ruby/object:Gem::Dependency
79
- type: :runtime
70
+ name: uuidtools
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - '>='
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
76
+ type: :runtime
86
77
  prerelease: false
87
78
  version_requirements: !ruby/object:Gem::Requirement
88
- none: false
89
79
  requirements:
90
- - - ! '>='
80
+ - - '>='
91
81
  - !ruby/object:Gem::Version
92
82
  version: '0'
93
- name: uuidtools
94
83
  description: XenServer Support for Chef's Knife Command
95
84
  email:
96
85
  - rubiojr@frameos.org
@@ -107,7 +96,10 @@ files:
107
96
  - README.md
108
97
  - knife-xenserver.gemspec
109
98
  - lib/chef/knife/xenserver_base.rb
99
+ - lib/chef/knife/xenserver_host_list.rb
110
100
  - lib/chef/knife/xenserver_network_list.rb
101
+ - lib/chef/knife/xenserver_sr_create.rb
102
+ - lib/chef/knife/xenserver_sr_list.rb
111
103
  - lib/chef/knife/xenserver_template_create.rb
112
104
  - lib/chef/knife/xenserver_template_list.rb
113
105
  - lib/chef/knife/xenserver_vm_create.rb
@@ -119,27 +111,25 @@ files:
119
111
  - vendor/fog/lib/fog/xenserver/requests/compute/add_attribute.rb
120
112
  homepage: http://github.com/rubiojr/knife-xenserver
121
113
  licenses: []
114
+ metadata: {}
122
115
  post_install_message:
123
116
  rdoc_options: []
124
117
  require_paths:
125
118
  - lib
126
119
  required_ruby_version: !ruby/object:Gem::Requirement
127
- none: false
128
120
  requirements:
129
- - - ! '>='
121
+ - - '>='
130
122
  - !ruby/object:Gem::Version
131
123
  version: '0'
132
124
  required_rubygems_version: !ruby/object:Gem::Requirement
133
- none: false
134
125
  requirements:
135
- - - ! '>='
126
+ - - '>='
136
127
  - !ruby/object:Gem::Version
137
128
  version: '0'
138
129
  requirements: []
139
130
  rubyforge_project:
140
- rubygems_version: 1.8.24
131
+ rubygems_version: 2.0.2
141
132
  signing_key:
142
- specification_version: 3
133
+ specification_version: 4
143
134
  summary: XenServer Support for Chef's Knife Command
144
135
  test_files: []
145
- has_rdoc: true