knife-xapi 0.3.5 → 0.3.6
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.
data/lib/chef/knife/xapi_base.rb
CHANGED
@@ -26,6 +26,23 @@ unless defined?(XAPI_TEMP_REGEX)
|
|
26
26
|
XAPI_TEMP_REGEX = /^CentOS 5.*\(64-bit\)/
|
27
27
|
end
|
28
28
|
|
29
|
+
unless defined?(XAPI_DEFAULTS)
|
30
|
+
XAPI_DEFAULTS = {
|
31
|
+
:domain => "",
|
32
|
+
:ssh_user => "root",
|
33
|
+
:ssh_port => "22",
|
34
|
+
:install_repo => "http://isoredirect.centos.org/centos/6/os/x86_64/",
|
35
|
+
:xapi_disk_size => "graphical utf8",
|
36
|
+
:xapi_disk_size => "8g",
|
37
|
+
:xapi_cpus => "1g",
|
38
|
+
:xapi_mem => "1g",
|
39
|
+
:bootstrap_template => "ubuntu10.04-gems",
|
40
|
+
:template_file => false,
|
41
|
+
:run_list => [],
|
42
|
+
:json_attributes => {}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
29
46
|
require 'chef/knife'
|
30
47
|
require 'units/standard'
|
31
48
|
require 'xenapi'
|
@@ -33,6 +50,7 @@ require 'xenapi'
|
|
33
50
|
class Chef::Knife
|
34
51
|
module XapiBase
|
35
52
|
|
53
|
+
|
36
54
|
def self.included(includer)
|
37
55
|
includer.class_eval do
|
38
56
|
deps do
|
@@ -45,17 +63,27 @@ class Chef::Knife
|
|
45
63
|
option :xapi_host,
|
46
64
|
:short => "-h SERVER_URL",
|
47
65
|
:long => "--host SERVER_URL",
|
66
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:xapi_host] = key },
|
48
67
|
:description => "The url to the xenserver, http://somehost.local.lan/"
|
49
68
|
|
50
69
|
option :xapi_password,
|
51
70
|
:short => "-K PASSWORD",
|
52
71
|
:long => "--xapi-password PASSWORD",
|
72
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:xapi_password] = key },
|
53
73
|
:description => "Your xenserver password"
|
54
74
|
|
55
75
|
option :xapi_username,
|
56
76
|
:short => "-A USERNAME",
|
57
77
|
:long => "--xapi-username USERNAME",
|
78
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:xapi_username] = key },
|
58
79
|
:description => "Your xenserver username"
|
80
|
+
|
81
|
+
option :domain,
|
82
|
+
:short => "-f Name",
|
83
|
+
:long => "--domain Name",
|
84
|
+
:description => "the domain name for the guest",
|
85
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:domain] = key }
|
86
|
+
|
59
87
|
end
|
60
88
|
|
61
89
|
end
|
@@ -86,7 +114,7 @@ class Chef::Knife
|
|
86
114
|
|
87
115
|
def locate_config_value(key)
|
88
116
|
key = key.to_sym
|
89
|
-
config[key] || Chef::Config[:knife][key]
|
117
|
+
config[key] || Chef::Config[:knife][key] || XAPI_DEFAULTS[key]
|
90
118
|
end
|
91
119
|
|
92
120
|
# get template by name_label
|
@@ -25,6 +25,7 @@ class Chef
|
|
25
25
|
class Knife
|
26
26
|
class XapiGuestCreate < Knife
|
27
27
|
include Chef::Knife::XapiBase
|
28
|
+
|
28
29
|
require 'timeout'
|
29
30
|
|
30
31
|
deps do
|
@@ -32,53 +33,51 @@ class Chef
|
|
32
33
|
Chef::Knife::Bootstrap.load_deps
|
33
34
|
end
|
34
35
|
|
36
|
+
|
37
|
+
|
35
38
|
banner "knife xapi guest create NAME [NETWORKS] (options)"
|
36
39
|
|
37
|
-
option :
|
40
|
+
option :xapi_vm_template,
|
38
41
|
:short => "-T Template Name Label",
|
39
42
|
:long => "--xapi-vm-template",
|
43
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:xapi_vm_template] = key },
|
40
44
|
:description => "xapi template name to create from. accepts an string or regex"
|
41
45
|
|
42
|
-
option :domain,
|
43
|
-
:short => "-f Name",
|
44
|
-
:long => "--domain Name",
|
45
|
-
:description => "the domain name for the guest",
|
46
|
-
:default => ""
|
47
|
-
|
48
46
|
option :install_repo,
|
49
47
|
:short => "-R If you're using a builtin template you will need to specify a repo url",
|
50
|
-
:long => "--
|
48
|
+
:long => "--install-repo",
|
51
49
|
:description => "Install repo for this template (if needed)",
|
52
|
-
:
|
50
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:install_repo] = key }
|
53
51
|
|
54
52
|
option :xapi_sr,
|
55
53
|
:short => "-S Storage repo to provision VM from",
|
56
54
|
:long => "--xapi-sr",
|
55
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:xapi_sr] = key },
|
57
56
|
:description => "The Xen SR to use, If blank will use pool/hypervisor default"
|
58
57
|
|
59
58
|
option :kernel_params,
|
60
59
|
:short => "-B Set of kernel boot params to pass to the vm",
|
61
|
-
:long => "--
|
60
|
+
:long => "--kernel-params",
|
62
61
|
:description => "You can add more boot options to the vm e.g.: \"ks='http://foo.local/ks'\"",
|
63
|
-
:
|
62
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:kernel_params] = key }
|
64
63
|
|
65
64
|
option :xapi_disk_size,
|
66
65
|
:short => "-D Size of disk. 1g 512m etc",
|
67
66
|
:long => "--xapi-disk-size",
|
68
67
|
:description => "The size of the root disk, use 'm' 'g' 't' if no unit specified assumes g",
|
69
|
-
:
|
68
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:xapi_disk_size] = key.to_s }
|
70
69
|
|
71
70
|
option :xapi_cpus,
|
72
71
|
:short => "-C Number of VCPUs to provision",
|
73
72
|
:long => "--xapi-cpus",
|
74
73
|
:description => "Number of VCPUS this vm should have 1 4 8 etc",
|
75
|
-
:
|
74
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:xapi_cpus] = key.to_s }
|
76
75
|
|
77
76
|
option :xapi_mem,
|
78
77
|
:short => "-M Ammount of memory to provision",
|
79
78
|
:long => "--xapi-mem",
|
80
79
|
:description => "Ammount of memory the VM should have specify with m g etc 512m, 2g if no unit spcified it assumes gigabytes",
|
81
|
-
:
|
80
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:xapi_mem] = key.to_s }
|
82
81
|
|
83
82
|
option :chef_node_name,
|
84
83
|
:short => "-N NAME",
|
@@ -88,24 +87,25 @@ class Chef
|
|
88
87
|
option :ssh_key_name,
|
89
88
|
:short => "-S KEY",
|
90
89
|
:long => "--ssh-key KEY",
|
90
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_key_name] = key },
|
91
91
|
:description => "The SSH key id"
|
92
92
|
|
93
93
|
option :ssh_user,
|
94
94
|
:short => "-x USERNAME",
|
95
95
|
:long => "--ssh-user USERNAME",
|
96
96
|
:description => "The ssh username",
|
97
|
-
:
|
97
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_user] = key }
|
98
98
|
|
99
99
|
option :ssh_password,
|
100
100
|
:short => "-P PASSWORD",
|
101
101
|
:long => "--ssh-password PASSWORD",
|
102
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_password] = key },
|
102
103
|
:description => "The ssh password"
|
103
104
|
|
104
105
|
option :ssh_port,
|
105
106
|
:short => "-p PORT",
|
106
107
|
:long => "--ssh-port PORT",
|
107
|
-
:description => "The ssh port"
|
108
|
-
:default => "22"
|
108
|
+
:description => "The ssh port"
|
109
109
|
|
110
110
|
option :bootstrap_version,
|
111
111
|
:long => "--bootstrap-version VERSION",
|
@@ -114,31 +114,27 @@ class Chef
|
|
114
114
|
option :bootstrap_template,
|
115
115
|
:short => "-d Template Name",
|
116
116
|
:long => "--bootstrap-template Template Name",
|
117
|
-
:description => "Bootstrap using a specific template"
|
118
|
-
:default => "ubuntu10.04-gems"
|
117
|
+
:description => "Bootstrap using a specific template"
|
119
118
|
|
120
119
|
option :template_file,
|
121
120
|
:short => "-F FILEPATH",
|
122
121
|
:long => "--template-file TEMPLATE",
|
123
|
-
:description => "Full path to location of template to use"
|
124
|
-
|
125
|
-
|
122
|
+
:description => "Full path to location of template to use"
|
123
|
+
|
126
124
|
option :json_attributes,
|
127
125
|
:short => "-j JSON_ATTRIBS",
|
128
126
|
:long => "--json-attributes",
|
129
127
|
:description => "A JSON string to be added to the first run of chef-client",
|
130
|
-
:proc => lambda { |o| JSON.parse(o) }
|
131
|
-
:default => {}
|
128
|
+
:proc => lambda { |o| JSON.parse(o) }
|
132
129
|
|
133
130
|
option :run_list,
|
134
131
|
:short => "-r RUN_LIST",
|
135
132
|
:long => "--run-list RUN_LIST",
|
136
133
|
:description => "Comma separated list of roles/recipes to apply",
|
137
|
-
:proc => lambda { |o| o.split(/[\s,]+/) }
|
138
|
-
:default => []
|
134
|
+
:proc => lambda { |o| o.split(/[\s,]+/) }
|
139
135
|
|
140
136
|
def tcp_test_ssh(hostname)
|
141
|
-
tcp_socket = TCPSocket.new(hostname,
|
137
|
+
tcp_socket = TCPSocket.new(hostname, locate_config_value(:ssh_port) )
|
142
138
|
readable = IO.select([tcp_socket], nil, nil, 5)
|
143
139
|
if readable
|
144
140
|
Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
|
@@ -209,13 +205,18 @@ class Chef
|
|
209
205
|
|
210
206
|
def run
|
211
207
|
server_name = @name_args[0]
|
212
|
-
|
208
|
+
domainname = locate_config_value(:domain)
|
209
|
+
if domainname.empty?
|
210
|
+
fqdn = server_name
|
211
|
+
else
|
212
|
+
fqdn = "#{server_name}.#{domainname}"
|
213
|
+
end
|
213
214
|
|
214
215
|
# get the template vm we are going to build from
|
215
|
-
template_ref = find_template( locate_config_value(:
|
216
|
+
template_ref = find_template( locate_config_value(:xapi_vm_template) )
|
216
217
|
|
217
218
|
Chef::Log.debug "Cloning Guest from Template: #{h.color(template_ref, :bold, :cyan )}"
|
218
|
-
vm_ref = xapi.VM.clone(template_ref,
|
219
|
+
vm_ref = xapi.VM.clone(template_ref, fqdn)
|
219
220
|
|
220
221
|
# TODO: lift alot of this
|
221
222
|
begin
|
@@ -239,7 +240,6 @@ class Chef
|
|
239
240
|
# setup the Boot args
|
240
241
|
#
|
241
242
|
boot_args = locate_config_value(:kernel_params)
|
242
|
-
domainname = locate_config_value(:domain)
|
243
243
|
|
244
244
|
# if no hostname param set hostname to given vm name
|
245
245
|
boot_args << " hostname=#{server_name}" unless boot_args.match(/hostname=.+\s?/)
|
@@ -281,7 +281,7 @@ class Chef
|
|
281
281
|
cleanup(vm_ref) unless vbd_ref
|
282
282
|
ui.msg( "#{ h.color "OK", :green}" )
|
283
283
|
|
284
|
-
ui.msg "Provisioning new Guest: #{h.color(
|
284
|
+
ui.msg "Provisioning new Guest: #{h.color(fqdn, :bold, :cyan )}"
|
285
285
|
ui.msg "Boot Args: #{h.color boot_args,:bold, :cyan}"
|
286
286
|
ui.msg "Install Repo: #{ h.color(repo,:bold, :cyan)}"
|
287
287
|
ui.msg "Memory: #{ h.color( locate_config_value(:xapi_mem).to_s, :bold, :cyan)}"
|
@@ -327,29 +327,24 @@ class Chef
|
|
327
327
|
cleanup(vm_ref)
|
328
328
|
end
|
329
329
|
|
330
|
-
|
330
|
+
|
331
331
|
begin
|
332
|
-
if domainname.empty?
|
333
|
-
server = server_name
|
334
|
-
else
|
335
|
-
server = "#{server_name}.#{domainname}"
|
336
|
-
end
|
337
332
|
bootstrap = Chef::Knife::Bootstrap.new
|
338
333
|
bootstrap.name_args = [ guest_addr ]
|
339
|
-
bootstrap.config[:run_list] =
|
340
|
-
bootstrap.config[:ssh_user] =
|
341
|
-
bootstrap.config[:ssh_port] =
|
342
|
-
bootstrap.config[:ssh_password] =
|
343
|
-
bootstrap.config[:identity_file] =
|
344
|
-
bootstrap.config[:chef_node_name] = config[:chef_node_name] ||
|
334
|
+
bootstrap.config[:run_list] = locate_config_value(:run_list)
|
335
|
+
bootstrap.config[:ssh_user] = locate_config_value(:ssh_user)
|
336
|
+
bootstrap.config[:ssh_port] = locate_config_value(:ssh_port)
|
337
|
+
bootstrap.config[:ssh_password] = locate_config_value(:ssh_password)
|
338
|
+
bootstrap.config[:identity_file] = locate_config_value(:identity_file)
|
339
|
+
bootstrap.config[:chef_node_name] = config[:chef_node_name] || fqdn
|
345
340
|
bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
|
346
341
|
bootstrap.config[:first_boot_attributes] = locate_config_value(:json_attributes)
|
347
342
|
bootstrap.config[:distro] = locate_config_value(:bootstrap_template)
|
348
|
-
bootstrap.config[:use_sudo] = true unless
|
343
|
+
bootstrap.config[:use_sudo] = true unless locate_config_value(:ssh_user) == 'root'
|
349
344
|
bootstrap.config[:template_file] = locate_config_value(:template_file)
|
350
345
|
bootstrap.config[:environment] = config[:environment]
|
351
346
|
bootstrap.config[:host_key_verify] = false
|
352
|
-
bootstrap.config[:run_list] =
|
347
|
+
bootstrap.config[:run_list] = locate_config_value(:run_list)
|
353
348
|
|
354
349
|
bootstrap.run
|
355
350
|
rescue Exception => e
|
data/lib/knife-xapi/version.rb
CHANGED