knife-xenserver 1.0.1 → 1.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.
- data/CHANGELOG.md +9 -0
- data/README.md +9 -0
- data/lib/chef/knife/xenserver_vm_create.rb +84 -32
- data/lib/chef/knife/xenserver_vm_poweroff.rb +59 -0
- data/lib/chef/knife/xenserver_vm_poweron.rb +47 -0
- data/lib/knife-xenserver/version.rb +1 -1
- data/vendor/fog/lib/fog/xenserver/requests/compute/add_attribute.rb +25 -0
- metadata +5 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# 1.1 - 2012/10/21
|
2
|
+
|
3
|
+
* Fixed --no-host-key-verify vm create flag
|
4
|
+
* added power on/off commands
|
5
|
+
* Allow setting of network information on create for Ubuntu systems
|
6
|
+
(@krobertson, @adamlau)
|
7
|
+
|
8
|
+
See https://github.com/bvox/knife-xenserver/pull/1
|
9
|
+
|
1
10
|
# 0.1.0 - 2012/04/04
|
2
11
|
|
3
12
|
* Initial release
|
data/README.md
CHANGED
@@ -61,6 +61,15 @@ Create a VM from template and add two custom VIFs in networks 'Integration-VLAN'
|
|
61
61
|
--vm-networks 'Integration-VLAN,Another-VLAN' \
|
62
62
|
--mac-addresses 11:22:33:44:55:66
|
63
63
|
|
64
|
+
Create a VM from template and supply ip/host/domain configuration. Requires installation of xe-automater scripts (https://github.com/adamlau/xenserver-automater)
|
65
|
+
|
66
|
+
knife xenserver vm create --vm-template my-template -x root --keep-template-networks \
|
67
|
+
--vm-name my-hostname \
|
68
|
+
--vm-ip 172.20.1.25 --vm-netmask 255.255.0.0 --vm-gateway 172.20.0.1 --vm-dns 172.20.0.3 \
|
69
|
+
--vm-domain my-domain.local
|
70
|
+
|
71
|
+
The domU/guest will also need xe-guest-utilities installed. You can then list xenstore attributes running 'xenstore-ls vm-data' inside domU.
|
72
|
+
|
64
73
|
List hypervisor networks
|
65
74
|
|
66
75
|
knife xenserver network list
|
@@ -103,12 +103,11 @@ class Chef
|
|
103
103
|
:long => "--identity-file IDENTITY_FILE",
|
104
104
|
:description => "The SSH identity file used for authentication"
|
105
105
|
|
106
|
-
option :
|
107
|
-
:long => "--no-host-key-verify",
|
106
|
+
option :host_key_verify,
|
107
|
+
:long => "--[no-]host-key-verify",
|
108
108
|
:description => "Disable host key verification",
|
109
109
|
:boolean => true,
|
110
|
-
:default =>
|
111
|
-
:proc => Proc.new { true }
|
110
|
+
:default => true
|
112
111
|
|
113
112
|
option :skip_bootstrap,
|
114
113
|
:long => "--skip-bootstrap",
|
@@ -140,6 +139,26 @@ class Chef
|
|
140
139
|
:description => "Mac address list",
|
141
140
|
:default => nil
|
142
141
|
|
142
|
+
option :vm_ip,
|
143
|
+
:long => '--vm-ip IP',
|
144
|
+
:description => 'IP address to set in xenstore'
|
145
|
+
|
146
|
+
option :vm_gateway,
|
147
|
+
:long => '--vm-gateway GATEWAY',
|
148
|
+
:description => 'Gateway address to set in xenstore'
|
149
|
+
|
150
|
+
option :vm_netmask,
|
151
|
+
:long => '--vm-netmask NETMASK',
|
152
|
+
:description => 'Netmask to set in xenstore'
|
153
|
+
|
154
|
+
option :vm_dns,
|
155
|
+
:long => '--vm-dns NAMESERVER',
|
156
|
+
:description => 'DNS servers to set in xenstore'
|
157
|
+
|
158
|
+
option :vm_domain,
|
159
|
+
:long => '--vm-domain DOMAIN',
|
160
|
+
:description => 'DOMAIN of host to set in xenstore'
|
161
|
+
|
143
162
|
def tcp_test_ssh(hostname)
|
144
163
|
tcp_socket = TCPSocket.new(hostname, 22)
|
145
164
|
readable = IO.select([tcp_socket], nil, nil, 5)
|
@@ -173,6 +192,17 @@ class Chef
|
|
173
192
|
exit 1
|
174
193
|
end
|
175
194
|
|
195
|
+
unless config[:vm_gateway]
|
196
|
+
if config[:vm_ip]
|
197
|
+
last_octet = Chef::Config[:knife][:xenserver_default_vm_gateway_last_octet] || 1
|
198
|
+
config[:vm_gateway] = config[:vm_ip].gsub(/\.\d+$/, ".#{last_octet}")
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
config[:vm_netmask] ||= Chef::Config[:knife][:xenserver_default_vm_netmask]
|
203
|
+
config[:vm_dns] ||= Chef::Config[:knife][:xenserver_default_vm_dns]
|
204
|
+
config[:vm_domain] ||= Chef::Config[:knife][:xenserver_default_vm_domain]
|
205
|
+
|
176
206
|
template = connection.servers.templates.find do |s|
|
177
207
|
(s.name == config[:vm_template]) or (s.uuid == config[:vm_template])
|
178
208
|
end
|
@@ -201,6 +231,19 @@ class Chef
|
|
201
231
|
vm.set_attribute 'memory_limits', mem, mem, mem, mem
|
202
232
|
vm.set_attribute 'VCPUs_max', config[:vm_cpus]
|
203
233
|
vm.set_attribute 'VCPUs_at_startup', config[:vm_cpus]
|
234
|
+
|
235
|
+
# network configuration through xenstore
|
236
|
+
attrs = {}
|
237
|
+
(attrs['vm-data/ip'] = config[:vm_ip]) if config[:vm_ip]
|
238
|
+
(attrs['vm-data/gw'] = config[:vm_gateway]) if config[:vm_gateway]
|
239
|
+
(attrs['vm-data/netmask'] = config[:vm_netmask]) if config[:vm_netmask]
|
240
|
+
(attrs['vm-data/dns'] = config[:vm_dns]) if config[:vm_dns]
|
241
|
+
(attrs['vm-data/dm'] = config[:vm_domain]) if config[:vm_domain]
|
242
|
+
if !attrs.empty?
|
243
|
+
puts "Adding attributes to xenstore..."
|
244
|
+
vm.set_attribute 'xenstore_data', attrs
|
245
|
+
end
|
246
|
+
|
204
247
|
if config[:vm_tags]
|
205
248
|
vm.set_attribute 'tags', config[:vm_tags].split(',')
|
206
249
|
end
|
@@ -217,38 +260,47 @@ class Chef
|
|
217
260
|
timeout = 180
|
218
261
|
found = connection.servers.all.find { |v| v.name == vm.name }
|
219
262
|
servers = connection.servers
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
263
|
+
if config[:vm_ip]
|
264
|
+
vm.refresh
|
265
|
+
print "\nTrying to #{'SSH'.yellow} to #{config[:vm_ip].yellow}... "
|
266
|
+
print(".") until tcp_test_ssh(config[:vm_ip]) do
|
267
|
+
sleep @initial_sleep_delay ||= 10; puts(" done")
|
268
|
+
@ssh_ip = config[:vm_ip]
|
269
|
+
end
|
270
|
+
else
|
271
|
+
loop do
|
272
|
+
begin
|
273
|
+
vm.refresh
|
274
|
+
if not vm.guest_metrics.nil? and not vm.guest_metrics.networks.empty?
|
275
|
+
networks = []
|
276
|
+
vm.guest_metrics.networks.each do |k,v|
|
277
|
+
networks << v
|
278
|
+
end
|
279
|
+
networks = networks.join(",")
|
280
|
+
puts
|
281
|
+
puts "\n#{ui.color("Server IPs:", :cyan)} #{networks}"
|
282
|
+
break
|
227
283
|
end
|
228
|
-
|
284
|
+
rescue Fog::Errors::Error
|
285
|
+
print "\r#{ui.color('Waiting a valid IP', :magenta)}..." + "." * (100 - timeout)
|
286
|
+
end
|
287
|
+
sleep 1
|
288
|
+
timeout -= 1
|
289
|
+
if timeout == 0
|
229
290
|
puts
|
230
|
-
|
231
|
-
|
291
|
+
ui.error "Timeout trying to reach the VM. Couldn't find the IP address."
|
292
|
+
exit 1
|
232
293
|
end
|
233
|
-
rescue Fog::Errors::Error
|
234
|
-
print "\r#{ui.color('Waiting a valid IP', :magenta)}..." + "." * (100 - timeout)
|
235
|
-
end
|
236
|
-
sleep 1
|
237
|
-
timeout -= 1
|
238
|
-
if timeout == 0
|
239
|
-
puts
|
240
|
-
ui.error "Timeout trying to reach the VM. Couldn't find the IP address."
|
241
|
-
exit 1
|
242
294
|
end
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
295
|
+
print "\n#{ui.color("Waiting for sshd... ", :magenta)}"
|
296
|
+
vm.guest_metrics.networks.each do |k,v|
|
297
|
+
print "\nTrying to #{'SSH'.yellow} to #{v.yellow}... "
|
298
|
+
print(".") until tcp_test_ssh(v) do
|
299
|
+
sleep @initial_sleep_delay ||= 10; puts(" done")
|
300
|
+
@ssh_ip = v
|
301
|
+
end
|
302
|
+
break if @ssh_ip
|
250
303
|
end
|
251
|
-
break if @ssh_ip
|
252
304
|
end
|
253
305
|
|
254
306
|
bootstrap_for_node(vm).run
|
@@ -277,7 +329,7 @@ class Chef
|
|
277
329
|
bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
|
278
330
|
bootstrap.config[:template_file] = locate_config_value(:template_file)
|
279
331
|
bootstrap.config[:environment] = config[:environment]
|
280
|
-
bootstrap.config[:
|
332
|
+
bootstrap.config[:host_key_verify] = config[:host_key_verify]
|
281
333
|
bootstrap.config[:ssh_password] = config[:ssh_password]
|
282
334
|
bootstrap
|
283
335
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Sergio Rubio (<rubiojr@bvox.net>)
|
3
|
+
# Copyright:: Copyright (c) 2012 Sergio Rubio
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife/xenserver_base'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class XenserverVmPoweroff < Knife
|
24
|
+
|
25
|
+
include Knife::XenserverBase
|
26
|
+
|
27
|
+
banner "knife xenserver vm poweroff VM_NAME [VM_NAME] (options)"
|
28
|
+
|
29
|
+
option :hard,
|
30
|
+
:long => "--hard",
|
31
|
+
:description => "Force VM shutdown",
|
32
|
+
:boolean => true,
|
33
|
+
:default => false,
|
34
|
+
:proc => Proc.new { true }
|
35
|
+
|
36
|
+
def run
|
37
|
+
powered_off = []
|
38
|
+
connection.servers.each do |vm|
|
39
|
+
@name_args.each do |vm_name|
|
40
|
+
if (vm_name == vm.name) or (vm_name == vm.uuid)
|
41
|
+
confirm("Do you really want to #{'poweroff'.bold.red} this virtual machine #{vm.name.bold.red}")
|
42
|
+
if config[:hard]
|
43
|
+
vm.stop 'hard'
|
44
|
+
else
|
45
|
+
vm.stop 'clean'
|
46
|
+
end
|
47
|
+
powered_off << vm_name
|
48
|
+
ui.info("#{'Powered off'.yellow} virtual machine #{vm.name.yellow} [uuid: #{vm.uuid}]")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@name_args.each do |vm_name|
|
53
|
+
ui.warn "Virtual Machine #{vm_name} not found" if not powered_off.include?(vm_name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Sergio Rubio (<rubiojr@bvox.net>)
|
3
|
+
# Copyright:: Copyright (c) 2012 Sergio Rubio
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife/xenserver_base'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class XenserverVmPoweron < Knife
|
24
|
+
|
25
|
+
include Knife::XenserverBase
|
26
|
+
|
27
|
+
banner "knife xenserver vm poweron VM_NAME [VM_NAME] (options)"
|
28
|
+
|
29
|
+
def run
|
30
|
+
powered_on = []
|
31
|
+
connection.servers.each do |vm|
|
32
|
+
@name_args.each do |vm_name|
|
33
|
+
if (vm_name == vm.name) or (vm_name == vm.uuid)
|
34
|
+
vm.start
|
35
|
+
powered_on << vm_name
|
36
|
+
ui.info("#{'Powered on'.yellow} virtual machine #{vm.name.yellow} [uuid: #{vm.uuid}]")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@name_args.each do |vm_name|
|
41
|
+
ui.warn "Virtual Machine #{vm_name} not found" if not powered_on.include?(vm_name)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class XenServer
|
4
|
+
|
5
|
+
class Real
|
6
|
+
|
7
|
+
require 'fog/xenserver/parser'
|
8
|
+
|
9
|
+
def add_attribute( klass, ref, attr_name, *value )
|
10
|
+
@connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => "#{klass}.add_#{attr_name.gsub('-','_')}"}, ref, *value)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class Mock
|
16
|
+
|
17
|
+
def add_attribute( klass, ref, attr_name, value )
|
18
|
+
Fog::Mock.not_implemented
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-xenserver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: '1.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-
|
12
|
+
date: 2012-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: terminal-table
|
@@ -129,7 +129,10 @@ files:
|
|
129
129
|
- lib/chef/knife/xenserver_vm_create.rb
|
130
130
|
- lib/chef/knife/xenserver_vm_delete.rb
|
131
131
|
- lib/chef/knife/xenserver_vm_list.rb
|
132
|
+
- lib/chef/knife/xenserver_vm_poweroff.rb
|
133
|
+
- lib/chef/knife/xenserver_vm_poweron.rb
|
132
134
|
- lib/knife-xenserver/version.rb
|
135
|
+
- vendor/fog/lib/fog/xenserver/requests/compute/add_attribute.rb
|
133
136
|
homepage: http://github.com/rubiojr/knife-xenserver
|
134
137
|
licenses: []
|
135
138
|
post_install_message:
|