knife-xapi 0.2.2 → 0.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.
@@ -42,24 +42,25 @@ class Chef::Knife
42
42
  require 'readline'
43
43
  end
44
44
 
45
- option :host,
45
+ option :xapi_host,
46
46
  :short => "-h SERVER_URL",
47
47
  :long => "--host SERVER_URL",
48
48
  :description => "The url to the xenserver, http://somehost.local.lan/",
49
- :proc => Proc.new { |host| Chef::Config[:knife][:xenserver_host] = host }
49
+ :proc => Proc.new { |host| Chef::Config[:knife][:xapi_host] = host }
50
50
 
51
- option :xenserver_password,
51
+ option :xapi_password,
52
52
  :short => "-K PASSWORD",
53
- :long => "--xenserver-password PASSWORD",
53
+ :long => "--xapi-password PASSWORD",
54
54
  :description => "Your xenserver password",
55
- :proc => Proc.new { |key| Chef::Config[:knife][:xenserver_password] = key }
55
+ :proc => Proc.new { |key| Chef::Config[:knife][:xapi_password] = key }
56
56
 
57
- option :xenserver_username,
57
+ option :xapi_username,
58
58
  :short => "-A USERNAME",
59
- :long => "--xenserver-username USERNAME",
59
+ :long => "--xapi-username USERNAME",
60
60
  :description => "Your xenserver username",
61
- :proc => Proc.new { |username| Chef::Config[:knife][:xenserver_username] = username }
61
+ :proc => Proc.new { |username| Chef::Config[:knife][:xapi_username] = username }
62
62
  end
63
+
63
64
  end
64
65
 
65
66
  # highline setup
@@ -71,11 +72,12 @@ class Chef::Knife
71
72
  def xapi
72
73
  @xapi ||= begin
73
74
 
74
- session = XenApi::Client.new( Chef::Config[:knife][:xenserver_host] )
75
+ ui.fatal "Must provide a xapi host with --host "unless locate_config_value(:xapi_host)
76
+ session = XenApi::Client.new( locate_config_value(:xapi_host) )
75
77
 
76
78
  # get the password from the user
77
- password = Chef::Config[:knife][:xenserver_password] || nil
78
- username = Chef::Config[:knife][:xenserver_username] || "root"
79
+ password = locate_config_value(:xapi_password) || nil
80
+ username = locate_config_value(:xapi_username) || "root"
79
81
  if password.nil? or password.empty?
80
82
  password = h.ask("Enter password for user #{username}: " ) { |input| input.echo = "*" }
81
83
  end
@@ -132,7 +134,7 @@ class Chef::Knife
132
134
 
133
135
  # ensure return values
134
136
  if found
135
- puts "Using Template: #{h.color(found["name_label"], :cyan)}"
137
+ ui.msg "Using Template: #{h.color(found["name_label"], :cyan)}"
136
138
  return get_template(found["name_label"]) # get the ref to this one
137
139
  end
138
140
  return nil
@@ -162,7 +164,7 @@ class Chef::Knife
162
164
 
163
165
  # add a new vif
164
166
  def add_vif_by_name(vm_ref, dev_num, net_name)
165
- puts "Looking up vif for: #{h.color(net_name, :cyan)}"
167
+ Chef::Log.debug "Looking up vif for: #{h.color(net_name, :cyan)}"
166
168
  network_ref = xapi.network.get_by_name_label(net_name).first
167
169
  if network_ref.nil?
168
170
  ui.warn "#{h.color(net_name,:red)} not found, moving on"
@@ -170,7 +172,7 @@ class Chef::Knife
170
172
  end
171
173
 
172
174
  mac = generate_mac
173
- puts "Provisioning: #{h.color(net_name, :cyan)}, #{h.color(mac,:green)}, #{h.color(network_ref, :yellow)}"
175
+ Chef::Log.debug "Provisioning: #{h.color(net_name, :cyan)}, #{h.color(mac,:green)}, #{h.color(network_ref, :yellow)}"
174
176
 
175
177
  vif = {
176
178
  'device' => dev_num.to_s,
@@ -38,21 +38,23 @@ class Chef
38
38
  :short => "-T Template Name Label",
39
39
  :long => "--xapi-vm-template",
40
40
  :description => "xapi template name to create from. accepts an string or regex",
41
- :proc => Proc.new { |template| Chef::Config[:knife][:xapi_vm_template] = template }
41
+ :proc => Proc.new { |template| Chef::Config[:knife][:vm_template] = template }
42
42
 
43
43
  option :domain,
44
44
  :short => "-f Name",
45
45
  :long => "--domain Name",
46
46
  :description => "the domain name for the guest",
47
- :proc => Proc.new { |domain| Chef::Config[:knife][:xapi_domainname] = domain }
47
+ :proc => Proc.new { |domain| Chef::Config[:knife][:domain] = domain },
48
+ :default => ""
48
49
 
49
50
  option :install_repo,
50
51
  :short => "-R If you're using a builtin template you will need to specify a repo url",
51
52
  :long => "--xapi-install-repo",
52
53
  :description => "Install repo for this template (if needed)",
53
- :proc => Proc.new { |repo| Chef::Config[:knife][:xapi_install_repo] = repo }
54
+ :proc => Proc.new { |repo| Chef::Config[:knife][:install_repo] = repo },
55
+ :default => "http://isoredirect.centos.org/centos/6/os/x86_64/"
54
56
 
55
- option :storage_repo,
57
+ option :xapi_sr,
56
58
  :short => "-S Storage repo to provision VM from",
57
59
  :long => "--xapi-sr",
58
60
  :description => "The Xen SR to use, If blank will use pool/hypervisor default",
@@ -62,25 +64,29 @@ class Chef
62
64
  :short => "-B Set of kernel boot params to pass to the vm",
63
65
  :long => "--xapi-kernel-params",
64
66
  :description => "You can add more boot options to the vm e.g.: \"ks='http://foo.local/ks'\"",
65
- :proc => Proc.new {|kernel| Chef::Config[:knife][:xapi_kernel_params] = kernel }
67
+ :proc => Proc.new {|kernel| Chef::Config[:knife][:xapi_kernel_params] = kernel },
68
+ :default => "graphical utf8"
66
69
 
67
- option :disk_size,
70
+ option :xapi_disk_size,
68
71
  :short => "-D Size of disk. 1g 512m etc",
69
72
  :long => "--xapi-disk-size",
70
73
  :description => "The size of the root disk, use 'm' 'g' 't' if no unit specified assumes g",
71
- :proc => Proc.new {|disk| Chef::Config[:knife][:xapi_disk_size] = disk }
74
+ :proc => Proc.new {|disk| Chef::Config[:knife][:xapi_disk_size] = disk },
75
+ :default => "8g"
72
76
 
73
- option :cpus,
77
+ option :xapi_cpus,
74
78
  :short => "-C Number of VCPUs to provision",
75
79
  :long => "--xapi-cpus",
76
80
  :description => "Number of VCPUS this vm should have 1 4 8 etc",
81
+ :default => 2,
77
82
  :proc => Proc.new {|cpu| Chef::Config[:knife][:xapi_cpus] = cpu }
78
83
 
79
- option :mem,
84
+ option :xapi_mem,
80
85
  :short => "-M Ammount of memory to provision",
81
86
  :long => "--xapi-mem",
82
87
  :description => "Ammount of memory the VM should have specify with m g etc 512m, 2g if no unit spcified it assumes gigabytes",
83
- :proc => Proc.new {|mem| Chef::Config[:knife][:xapi_mem] = mem }
88
+ :proc => Proc.new {|mem| Chef::Config[:knife][:xapi_mem] = mem },
89
+ :default => "1g"
84
90
 
85
91
  option :chef_node_name,
86
92
  :short => "-N NAME",
@@ -91,7 +97,8 @@ class Chef
91
97
  :short => "-S KEY",
92
98
  :long => "--ssh-key KEY",
93
99
  :description => "The SSH key id",
94
- :proc => Proc.new { |key| Chef::Config[:knife][:xapi_ssh_key_id] = key }
100
+ :proc => Proc.new { |key| Chef::Config[:knife][:ssh_key_name] = key }
101
+
95
102
 
96
103
  option :ssh_user,
97
104
  :short => "-x USERNAME",
@@ -108,19 +115,19 @@ class Chef
108
115
  :short => "-p PORT",
109
116
  :long => "--ssh-port PORT",
110
117
  :description => "The ssh port",
111
- :default => "22",
112
- :proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
118
+ :proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key },
119
+ :default => "22"
113
120
 
114
121
  option :bootstrap_version,
115
122
  :long => "--bootstrap-version VERSION",
116
123
  :description => "The version of Chef to install",
117
124
  :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
118
125
 
119
- option :distro,
120
- :short => "-d DISTRO",
121
- :long => "--distro DISTRO",
122
- :description => "Bootstrap a distro using a template",
123
- :proc => Proc.new { |d| Chef::Config[:knife][:distro] = d },
126
+ option :bootstrap_template,
127
+ :short => "-d Template Name",
128
+ :long => "--bootstrap-template Template Name",
129
+ :description => "Bootstrap using a specific template",
130
+ :proc => Proc.new { |d| Chef::Config[:knife][:bootstrap_template] = d },
124
131
  :default => "ubuntu10.04-gems"
125
132
 
126
133
  option :template_file,
@@ -212,41 +219,40 @@ class Chef
212
219
  $stdout.sync = true
213
220
 
214
221
  # get the template vm we are going to build from
215
- template_ref = find_template( Chef::Config[:knife][:xapi_vm_template] )
222
+ template_ref = find_template( locate_config_value(:vm_template) )
216
223
 
217
- ui.msg "Cloning Guest from Template: #{h.color(template_ref, :bold, :cyan )}"
224
+ Chef::Log.debug "Cloning Guest from Template: #{h.color(template_ref, :bold, :cyan )}"
218
225
  vm_ref = xapi.VM.clone(template_ref, server_name)
219
226
 
227
+ # TODO: lift alot of this
220
228
  begin
221
- xapi.VM.set_name_description(vm_ref, "VM built by knife-xapi as #{server_name}")
229
+ xapi.VM.set_name_description(vm_ref, "VM from knife-xapi as #{server_name}")
222
230
 
223
231
  # configure the install repo
224
- repo = Chef::Config[:knife][:xapi_install_repo] || "http://isoredirect.centos.org/centos/5/os/x86_64/"
225
- ui.msg "Setting Install Repo: #{h.color(repo,:bold, :cyan)}"
232
+ repo = locate_config_value(:install_repo)
226
233
  xapi.VM.set_other_config(vm_ref, { "install-repository" => repo } )
227
-
228
- cpus = Chef::Config[:knife][:xapi_cpus].to_s || "2"
234
+
235
+
236
+ cpus = locate_config_value( :xapi_cpus ).to_s
237
+
229
238
  xapi.VM.set_VCPUs_max( vm_ref, cpus )
230
239
  xapi.VM.set_VCPUs_at_startup( vm_ref, cpus )
231
240
 
232
- memory_size = input_to_bytes( Chef::Config[:knife][:xapi_mem] || "1g" ).to_s
233
- ui.msg "Mem size: #{ h.color( memory_size, :cyan)}"
234
-
241
+ memory_size = input_to_bytes( locate_config_value(:xapi_mem) ).to_s
235
242
  # static-min <= dynamic-min = dynamic-max = static-max
236
243
  xapi.VM.set_memory_limits(vm_ref, memory_size, memory_size, memory_size, memory_size)
237
244
 
238
245
  #
239
246
  # setup the Boot args
240
247
  #
241
- boot_args = Chef::Config[:knife][:xapi_kernel_params] || "graphical utf8"
242
- domainname = Chef::Config[:knife][:xapi_domainname] || ""
248
+ boot_args = locate_config_value(:kernel_params)
249
+ domainname = locate_config_value(:domain)
243
250
 
244
251
  # if no hostname param set hostname to given vm name
245
252
  boot_args << " hostname=#{server_name}" unless boot_args.match(/hostname=.+\s?/)
246
253
  # if domainname is supplied we put that in there as well
247
254
  boot_args << " domainname=#{domainname}" unless boot_args.match(/domainname=.+\s?/)
248
255
 
249
- ui.msg "Setting Boot Args: #{h.color boot_args, :cyan}"
250
256
  xapi.VM.set_PV_args( vm_ref, boot_args )
251
257
 
252
258
  # TODO: validate that the vm gets a network here
@@ -259,23 +265,23 @@ class Chef
259
265
  end
260
266
  end
261
267
 
262
- sr_ref = find_default_sr
263
- if Chef::Config[:knife][:xapi_sr]
264
- sr_ref = get_sr_by_name( Chef::Config[:knife][:xapi_sr] )
268
+ if locate_config_value(:xapi_sr)
269
+ sr_ref = get_sr_by_name( locate_config_value(:xapi_sr) )
270
+ else
271
+ sr_ref = find_default_sr
265
272
  end
266
273
 
267
274
  if sr_ref.nil?
268
275
  ui.error "SR specified not found or can't be used Aborting"
269
276
  cleanup(vm_ref)
270
277
  end
271
- ui.msg "SR: #{h.color sr_ref, :cyan} created"
278
+ Chef::Log.debug "SR: #{h.color sr_ref, :cyan}"
272
279
 
273
280
  # Create the VDI
274
- disk_size = Chef::Config[:knife][:xapi_disk_size] || "8g"
275
- vdi_ref = create_vdi("#{server_name}-root", sr_ref, disk_size )
281
+ vdi_ref = create_vdi("#{server_name}-root", sr_ref, locate_config_value(:xapi_disk_size) )
276
282
  # if vdi_ref is nill we need to bail/cleanup
277
283
  cleanup(vm_ref) unless vdi_ref
278
- ui.msg( "#{ h.color "OK", :green}" )
284
+ ui.msg( "#{ h.color "OK", :green} ")
279
285
 
280
286
  # Attach the VDI to the VM
281
287
  vbd_ref = create_vbd(vm_ref, vdi_ref, 0)
@@ -283,13 +289,17 @@ class Chef
283
289
  ui.msg( "#{ h.color "OK", :green}" )
284
290
 
285
291
  ui.msg "Provisioning new Guest: #{h.color(vm_ref, :bold, :cyan )}"
292
+ ui.msg "Boot Args: #{h.color boot_args,:bold, :cyan}"
293
+ ui.msg "Install Repo: #{ h.color(repo,:bold, :cyan)}"
294
+ ui.msg "Memory: #{ h.color( locate_config_value(:xapi_mem).to_s, :bold, :cyan)}"
295
+ ui.msg "CPUs: #{ h.color( locate_config_value(:xapi_cpus).to_s, :bold, :cyan)}"
296
+ ui.msg "Disk: #{ h.color( locate_config_value(:xapi_disk_size).to_s, :bold, :cyan)}"
286
297
  provisioned = xapi.VM.provision(vm_ref)
287
298
 
288
299
  ui.msg "Starting new Guest #{h.color( provisioned, :cyan)} "
289
-
290
300
  task = xapi.Async.VM.start(vm_ref, false, true)
291
301
  wait_on_task(task)
292
- ui.msg( "#{ h.color "Done!", :green}" )
302
+ ui.msg( "#{ h.color "OK!", :green}" )
293
303
 
294
304
  exit 0 unless locate_config_value(:run_list)
295
305
  rescue Exception => e
@@ -312,7 +322,7 @@ class Chef
312
322
  timeout(480) do
313
323
  print(".") until tcp_test_ssh(guest_addr) {
314
324
  sleep @initial_sleep_delay ||= 10
315
- puts("done")
325
+ ui.msg( "#{ h.color "OK!", :green}" )
316
326
  }
317
327
  end
318
328
  rescue Timeout::Error
@@ -321,8 +331,12 @@ class Chef
321
331
  end
322
332
 
323
333
 
324
- begin
325
- server_name << ".#{domainname}" unless domainname.empty?
334
+ # begin
335
+ if domainname.empty?
336
+ server = server_name
337
+ else
338
+ server = "#{server_name}.#{domainname}"
339
+ end
326
340
  bootstrap = Chef::Knife::Bootstrap.new
327
341
  bootstrap.name_args = [ guest_addr ]
328
342
  bootstrap.config[:run_list] = config[:run_list]
@@ -330,9 +344,9 @@ class Chef
330
344
  bootstrap.config[:ssh_port] = config[:ssh_port]
331
345
  bootstrap.config[:ssh_password] = config[:ssh_password]
332
346
  bootstrap.config[:identity_file] = config[:identity_file]
333
- bootstrap.config[:chef_node_name] = config[:chef_node_name] || server_name
347
+ bootstrap.config[:chef_node_name] = config[:chef_node_name] || server
334
348
  bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
335
- bootstrap.config[:distro] = locate_config_value(:distro)
349
+ bootstrap.config[:distro] = locate_config_value(:bootstrap_template)
336
350
  bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
337
351
  bootstrap.config[:template_file] = locate_config_value(:template_file)
338
352
  bootstrap.config[:environment] = config[:environment]
@@ -340,12 +354,12 @@ class Chef
340
354
  bootstrap.config[:run_list] = config[:run_list]
341
355
 
342
356
  bootstrap.run
343
- rescue Exception => e
344
- ui.msg "#{h.color 'ERROR:'} #{h.color( e.message, :red )}"
345
- puts "Nested backtrace:"
346
- ui.msg "#{h.color( e.backtrace.join("\n"), :yellow)}"
347
- cleanup(vm_ref)
348
- end
357
+ # rescue Exception => e
358
+ # ui.msg "#{h.color 'ERROR:'} #{h.color( e.message, :red )}"
359
+ # puts "Nested backtrace:"
360
+ # ui.msg "#{h.color( e.backtrace.join("\n"), :yellow)}"
361
+ # cleanup(vm_ref)
362
+ # end
349
363
 
350
364
  end
351
365
 
@@ -1,3 +1,3 @@
1
1
  module KnifeXenserver
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-xapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-29 00:00:00.000000000 Z
12
+ date: 2012-06-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef
@@ -81,10 +81,8 @@ executables: []
81
81
  extensions: []
82
82
  extra_rdoc_files:
83
83
  - LICENSE
84
- - README.rdoc
85
84
  files:
86
85
  - LICENSE
87
- - README.rdoc
88
86
  - lib/chef/knife/xapi_base.rb
89
87
  - lib/chef/knife/xapi_guest_create.rb
90
88
  - lib/chef/knife/xapi_guest_delete.rb
@@ -1,58 +0,0 @@
1
- =Knife Xapi
2
- This plugin gives knife the ability to create guests on a XAPI compatable hyper visor
3
-
4
- ==Installation
5
- This plugin is distributed as a Ruby Gem. To install it, run:
6
- gem install knife-xapi
7
-
8
- ==Configuration
9
- Config options are extenable in the knife.rb the folowing k/v pairs are implemented
10
-
11
- Chef::Config[:knife][:xenserver_host] :: The API Host to connect to
12
- Chef::Config[:knife][:xenserver_username] :: The User name to connect to the api with
13
- Chef::Config[:knife][:xenserver_password] :: The Password (if not set will prompt on commandline)
14
- Chef::Config[:knife][:xapi_vm_template] :: Set a default template to be used when creating Guests
15
- Chef::Config[:knife][:xapi_install_repo] :: The install repo config option to set when using Xen builtin templates
16
- Chef::Config[:knife][:xapi_sr] :: The Storage Repository to provision from, uses pool/hypervisor default when not set
17
- Chef::Config[:knife][:xapi_disk_size] :: Default VM disk size (8g if not specified)
18
- Chef::Config[:knife][:xapi_cpus] :: The Default CPUs to provision for guests (2 if not specified)
19
- Chef::Config[:knife][:xapi_mem] = mem :: The Defaul ammount of Memory for guests (1g if not specified)
20
- Chef::Config[:knife][:xapi_kernel_params] :: Optional Boot paramaters to pass to the guest
21
- Chef::Config[:knife][:xapi_bootstrap] :: Not implemented yet, but will be the bootstrap script to execute after guest create
22
-
23
- ==Usage
24
- =Create
25
- Basic usage to create a VM from existing VM template:
26
- knife xapi guest create "NewBox" "public" --xapi-vm-template "MyBaseBox" --host http://sandbox/
27
-
28
-
29
- More verbose example using a kickstart file and booting the Centos 5 default template:
30
- knife xapi guest create "MySpiffyBox" "pub_network" --host http://sandbox/ \
31
- -B "dns=8.8.8.8 ks=http://192.168.6.4/repo/ks/default.ks ip=192.168.6.7 netmask=255.255.255.0 gateway=192.168.6.1" \
32
- -R http://192.168.6.5/repo/centos/5/os/x86_64 -C 4 -M 4g -D 5g
33
- *-B Boot args where i am assigning all the centos/rhel boot args for Ip setup and kickstart file
34
- *-R Repo URL used by xenserver to start the net install
35
- *-C Number of cpus for this guest
36
- *-M Memory size
37
- *-D Disk size
38
-
39
- Use Knife builtin help schematic for more info
40
- knife xapi guest create --help
41
-
42
- =Delete
43
- Delete is pretty simple. When there are multiple vms with a name label you should be prompted to select one
44
- knife xapi guest delete testing
45
-
46
- If you know the UUID of the VM you can specify --uuid
47
- knife xapi guest delete b461c0d2-d24d-bc02-3231-711101f57b8e --uuid
48
-
49
- =List
50
- List shows the vm's on the pool/host Ignoring Controll domains and templates. VM OpaqueRef and UUID are displayed which can be
51
- knife xapi guest list
52
- Name Label Ref UUID
53
- test-server OpaqueRef:82065b80-55ff-63ce-ef89-6b33fb5fd272 9b0a0afa-5573-7875-b787-47fbfa2548a4
54
- tester OpaqueRef:2d239fbd-bff6-4e60-f675-e1d2530199d2 de760651-2db8-6f81-0783-7b8364f591fd
55
- test-client OpaqueRef:e4bbd801-c9be-e355-2a22-2ca468a90a81 35156957-45f4-02f8-6de9-6adbcd5e0c6d
56
- test-client OpaqueRef:f5b562f8-a493-f535-335e-ae70b3177869 f46e4d6b-bd9e-e47b-5f0d-b849ff75c5ef
57
-
58
-