knife-vsphere 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,241 +1,241 @@
1
- #
2
- # Author:: Brian Flad (<bflad417@gmail.com>)
3
- # License:: Apache License, Version 2.0
4
- #
5
- require 'chef/knife'
6
- require 'chef/knife/base_vsphere_command'
7
-
8
- # Lists all known virtual machines in the configured datacenter
9
- class Chef::Knife::VsphereVmVmdkAdd < Chef::Knife::BaseVsphereCommand
10
-
11
- banner "knife vsphere vm vmdk add"
12
-
13
- get_common_options
14
-
15
- option :vmdk_type,
16
- :long => "--vmdk-type TYPE",
17
- :description => "Type of VMDK"
18
- # this is a bad idea as it will let you overcommit SAN by 400% or more. thick is a more "sane" default
19
- $default[:vmdk_type] = "thin"
20
-
21
- option :target_lun,
22
- :long => "--target-lun NAME",
23
- :description => "name of target LUN"
24
-
25
- def run
26
- $stdout.sync = true
27
-
28
- vmname = @name_args[0]
29
- if vmname.nil?
30
- show_usage
31
- ui.fatal("You must specify a virtual machine name")
32
- exit 1
33
- end
34
-
35
- size = @name_args[1]
36
- if size.nil?
37
- ui.fatal "You need a VMDK size!"
38
- show_usage
39
- exit 1
40
- end
41
-
42
- vim = get_vim_connection
43
- vdm = vim.serviceContent.virtualDiskManager
44
- vm = get_vm(vmname)
45
- if vm.nil?
46
- puts "Could not find #{vmname}"
47
- return
48
- end
49
-
50
- target_lun = get_config(:target_lun) unless get_config(:target_lun).nil?
51
- vmdk_size_kb = size.to_i * 1024 * 1024
52
-
53
- if target_lun.nil?
54
- vmdk_datastore = choose_datastore(vm.datastore, size)
55
- exit -1 if vmdk_datastore.nil?
56
- else
57
- vmdk_datastores = find_datastores_regex(target_lun)
58
- vmdk_datastore = choose_datastore(vmdk_datastores, size)
59
- exit -1 if vmdk_datastore.nil?
60
- vmdk_dir = "[#{vmdk_datastore.name}] #{vmname}"
61
- # create the vm folder on the LUN or subsequent operations will fail.
62
- if not vmdk_datastore.exists? vmname
63
- dc = get_datacenter
64
- dc._connection.serviceContent.fileManager.MakeDirectory :name => vmdk_dir, :datacenter => dc, :createParentDirectories => false
65
- end
66
- end
67
-
68
- puts "Choosing: #{vmdk_datastore.name}"
69
-
70
- # now we need to inspect the files in this datastore to get our next file name
71
- next_vmdk = 1
72
- pc = vmdk_datastore._connection.serviceContent.propertyCollector
73
- vms = vmdk_datastore.vm
74
- vmFiles = pc.collectMultiple vms, 'layoutEx.file'
75
- vmFiles.keys.each do |vm|
76
- vmFiles[vm]["layoutEx.file"].each do |layout|
77
- if layout.name.match(/^\[#{vmdk_datastore.name}\] #{vmname}\/#{vmname}_([0-9]+).vmdk/)
78
- num = $1
79
- if next_vmdk <= num.to_i
80
- next_vmdk = num.to_i + 1
81
- end
82
- end
83
- end
84
- end
85
- vmdk_fileName = "#{vmname}/#{vmname}_#{next_vmdk}.vmdk"
86
- vmdk_name = "[#{vmdk_datastore.name}] #{vmdk_fileName}"
87
- vmdk_type = get_config(:vmdk_type)
88
- vmdk_type = "preallocated" if vmdk_type == "thick"
89
- puts "Next vmdk name is => #{vmdk_name}"
90
-
91
- # create the disk
92
- if not vmdk_datastore.exists? vmdk_fileName
93
- vmdk_spec = RbVmomi::VIM::FileBackedVirtualDiskSpec(
94
- :adapterType => "lsiLogic",
95
- :capacityKb => vmdk_size_kb,
96
- :diskType => vmdk_type
97
- )
98
- ui.info "Creating VMDK"
99
- ui.info "#{ui.color "Capacity:", :cyan} #{size} GB"
100
- ui.info "#{ui.color "Disk:", :cyan} #{vmdk_name}"
101
-
102
- if get_config(:noop)
103
- ui.info "#{ui.color "Skipping disk creation process because --noop specified.", :red}"
104
- else
105
- vdm.CreateVirtualDisk_Task(
106
- :datacenter => get_datacenter,
107
- :name => vmdk_name,
108
- :spec => vmdk_spec
109
- ).wait_for_completion
110
- end
111
- end
112
- ui.info "Attaching VMDK to #{vmname}"
113
-
114
- # now we run through the SCSI controllers to see if there's an available one
115
- available_controllers = Array.new()
116
- use_controller = nil
117
- scsi_tree = Hash.new()
118
- vm.config.hardware.device.each do |device|
119
- if device.class == RbVmomi::VIM::VirtualLsiLogicController
120
- if scsi_tree[device.controllerKey].nil?
121
- scsi_tree[device.key]=Hash.new()
122
- scsi_tree[device.key]['children'] = Array.new();
123
- scsi_tree[device.key]['device'] = device;
124
- end
125
- end
126
- if device.class == RbVmomi::VIM::VirtualDisk
127
- if scsi_tree[device.controllerKey].nil?
128
- scsi_tree[device.controllerKey]=Hash.new()
129
- scsi_tree[device.controllerKey]['children'] = Array.new();
130
- end
131
- scsi_tree[device.controllerKey]['children'].push(device)
132
- end
133
- end
134
- scsi_tree.keys.sort.each do |controller|
135
- if scsi_tree[controller]['children'].length < 15
136
- available_controllers.push(scsi_tree[controller]['device'].deviceInfo.label)
137
- end
138
- end
139
-
140
- if available_controllers.length > 0
141
- use_controller = available_controllers[0]
142
- puts "using #{use_controller}"
143
- else
144
-
145
- if scsi_tree.keys.length < 4
146
-
147
- # Add a controller if none are available
148
- puts "no controllers available. Will attempt to create"
149
- new_scsi_key = scsi_tree.keys.sort[scsi_tree.length - 1] + 1
150
- new_scsi_busNumber = scsi_tree[scsi_tree.keys.sort[scsi_tree.length - 1]]['device'].busNumber + 1
151
-
152
- controller_device = RbVmomi::VIM::VirtualLsiLogicController(
153
- :key => new_scsi_key,
154
- :busNumber => new_scsi_busNumber,
155
- :sharedBus => :noSharing
156
- )
157
-
158
- device_config_spec = RbVmomi::VIM::VirtualDeviceConfigSpec(
159
- :device => controller_device,
160
- :operation => RbVmomi::VIM::VirtualDeviceConfigSpecOperation("add")
161
- )
162
-
163
- vm_config_spec = RbVmomi::VIM::VirtualMachineConfigSpec(
164
- :deviceChange => [device_config_spec]
165
- )
166
-
167
- if get_config(:noop)
168
- ui.info "#{ui.color "Skipping controller creation process because --noop specified.", :red}"
169
- else
170
- vm.ReconfigVM_Task(:spec => vm_config_spec).wait_for_completion
171
- end
172
- else
173
- ui.info "Controllers maxed out at 4."
174
- exit -1
175
- end
176
- end
177
-
178
- # now go back and get the new device's name
179
- vm.config.hardware.device.each do |device|
180
- if device.class == RbVmomi::VIM::VirtualLsiLogicController
181
- if device.key == new_scsi_key
182
- use_controller = device.deviceInfo.label
183
- end
184
- end
185
- end
186
-
187
- # add the disk
188
- controller = find_device(vm, use_controller)
189
-
190
- used_unitNumbers = Array.new()
191
- scsi_tree.keys.sort.each do |c|
192
- if controller.key == scsi_tree[c]['device'].key
193
- used_unitNumbers.push(scsi_tree[c]['device'].scsiCtlrUnitNumber)
194
- scsi_tree[c]['children'].each do |disk|
195
- used_unitNumbers.push(disk.unitNumber)
196
- end
197
- end
198
- end
199
-
200
- available_unitNumbers = Array.new
201
- (0 .. 15).each do |scsi_id|
202
- if used_unitNumbers.grep(scsi_id).length > 0
203
- else
204
- available_unitNumbers.push(scsi_id)
205
- end
206
- end
207
-
208
- # ensure we don't try to add the controllers SCSI ID
209
- new_unitNumber = available_unitNumbers.sort[0]
210
- puts "using SCSI ID #{new_unitNumber}"
211
-
212
- vmdk_backing = RbVmomi::VIM::VirtualDiskFlatVer2BackingInfo(
213
- :datastore => vmdk_datastore,
214
- :diskMode => "persistent",
215
- :fileName => vmdk_name
216
- )
217
-
218
- device = RbVmomi::VIM::VirtualDisk(
219
- :backing => vmdk_backing,
220
- :capacityInKB => vmdk_size_kb,
221
- :controllerKey => controller.key,
222
- :key => -1,
223
- :unitNumber => new_unitNumber
224
- )
225
-
226
- device_config_spec = RbVmomi::VIM::VirtualDeviceConfigSpec(
227
- :device => device,
228
- :operation => RbVmomi::VIM::VirtualDeviceConfigSpecOperation("add")
229
- )
230
-
231
- vm_config_spec = RbVmomi::VIM::VirtualMachineConfigSpec(
232
- :deviceChange => [device_config_spec]
233
- )
234
-
235
- if get_config(:noop)
236
- ui.info "#{ui.color "Skipping disk attaching process because --noop specified.", :red}"
237
- else
238
- vm.ReconfigVM_Task(:spec => vm_config_spec).wait_for_completion
239
- end
240
- end
241
- end
1
+ #
2
+ # Author:: Brian Flad (<bflad417@gmail.com>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ require 'chef/knife'
6
+ require 'chef/knife/base_vsphere_command'
7
+
8
+ # Lists all known virtual machines in the configured datacenter
9
+ class Chef::Knife::VsphereVmVmdkAdd < Chef::Knife::BaseVsphereCommand
10
+
11
+ banner "knife vsphere vm vmdk add"
12
+
13
+ get_common_options
14
+
15
+ option :vmdk_type,
16
+ :long => "--vmdk-type TYPE",
17
+ :description => "Type of VMDK"
18
+ # this is a bad idea as it will let you overcommit SAN by 400% or more. thick is a more "sane" default
19
+ $default[:vmdk_type] = "thin"
20
+
21
+ option :target_lun,
22
+ :long => "--target-lun NAME",
23
+ :description => "name of target LUN"
24
+
25
+ def run
26
+ $stdout.sync = true
27
+
28
+ vmname = @name_args[0]
29
+ if vmname.nil?
30
+ show_usage
31
+ ui.fatal("You must specify a virtual machine name")
32
+ exit 1
33
+ end
34
+
35
+ size = @name_args[1]
36
+ if size.nil?
37
+ ui.fatal "You need a VMDK size!"
38
+ show_usage
39
+ exit 1
40
+ end
41
+
42
+ vim = get_vim_connection
43
+ vdm = vim.serviceContent.virtualDiskManager
44
+ vm = get_vm(vmname)
45
+ if vm.nil?
46
+ puts "Could not find #{vmname}"
47
+ return
48
+ end
49
+
50
+ target_lun = get_config(:target_lun) unless get_config(:target_lun).nil?
51
+ vmdk_size_kb = size.to_i * 1024 * 1024
52
+
53
+ if target_lun.nil?
54
+ vmdk_datastore = choose_datastore(vm.datastore, size)
55
+ exit -1 if vmdk_datastore.nil?
56
+ else
57
+ vmdk_datastores = find_datastores_regex(target_lun)
58
+ vmdk_datastore = choose_datastore(vmdk_datastores, size)
59
+ exit -1 if vmdk_datastore.nil?
60
+ vmdk_dir = "[#{vmdk_datastore.name}] #{vmname}"
61
+ # create the vm folder on the LUN or subsequent operations will fail.
62
+ if not vmdk_datastore.exists? vmname
63
+ dc = get_datacenter
64
+ dc._connection.serviceContent.fileManager.MakeDirectory :name => vmdk_dir, :datacenter => dc, :createParentDirectories => false
65
+ end
66
+ end
67
+
68
+ puts "Choosing: #{vmdk_datastore.name}"
69
+
70
+ # now we need to inspect the files in this datastore to get our next file name
71
+ next_vmdk = 1
72
+ pc = vmdk_datastore._connection.serviceContent.propertyCollector
73
+ vms = vmdk_datastore.vm
74
+ vmFiles = pc.collectMultiple vms, 'layoutEx.file'
75
+ vmFiles.keys.each do |vm|
76
+ vmFiles[vm]["layoutEx.file"].each do |layout|
77
+ if layout.name.match(/^\[#{vmdk_datastore.name}\] #{vmname}\/#{vmname}_([0-9]+).vmdk/)
78
+ num = $1
79
+ if next_vmdk <= num.to_i
80
+ next_vmdk = num.to_i + 1
81
+ end
82
+ end
83
+ end
84
+ end
85
+ vmdk_fileName = "#{vmname}/#{vmname}_#{next_vmdk}.vmdk"
86
+ vmdk_name = "[#{vmdk_datastore.name}] #{vmdk_fileName}"
87
+ vmdk_type = get_config(:vmdk_type)
88
+ vmdk_type = "preallocated" if vmdk_type == "thick"
89
+ puts "Next vmdk name is => #{vmdk_name}"
90
+
91
+ # create the disk
92
+ if not vmdk_datastore.exists? vmdk_fileName
93
+ vmdk_spec = RbVmomi::VIM::FileBackedVirtualDiskSpec(
94
+ :adapterType => "lsiLogic",
95
+ :capacityKb => vmdk_size_kb,
96
+ :diskType => vmdk_type
97
+ )
98
+ ui.info "Creating VMDK"
99
+ ui.info "#{ui.color "Capacity:", :cyan} #{size} GB"
100
+ ui.info "#{ui.color "Disk:", :cyan} #{vmdk_name}"
101
+
102
+ if get_config(:noop)
103
+ ui.info "#{ui.color "Skipping disk creation process because --noop specified.", :red}"
104
+ else
105
+ vdm.CreateVirtualDisk_Task(
106
+ :datacenter => get_datacenter,
107
+ :name => vmdk_name,
108
+ :spec => vmdk_spec
109
+ ).wait_for_completion
110
+ end
111
+ end
112
+ ui.info "Attaching VMDK to #{vmname}"
113
+
114
+ # now we run through the SCSI controllers to see if there's an available one
115
+ available_controllers = Array.new()
116
+ use_controller = nil
117
+ scsi_tree = Hash.new()
118
+ vm.config.hardware.device.each do |device|
119
+ if device.class == RbVmomi::VIM::VirtualLsiLogicController
120
+ if scsi_tree[device.controllerKey].nil?
121
+ scsi_tree[device.key]=Hash.new()
122
+ scsi_tree[device.key]['children'] = Array.new();
123
+ scsi_tree[device.key]['device'] = device;
124
+ end
125
+ end
126
+ if device.class == RbVmomi::VIM::VirtualDisk
127
+ if scsi_tree[device.controllerKey].nil?
128
+ scsi_tree[device.controllerKey]=Hash.new()
129
+ scsi_tree[device.controllerKey]['children'] = Array.new();
130
+ end
131
+ scsi_tree[device.controllerKey]['children'].push(device)
132
+ end
133
+ end
134
+ scsi_tree.keys.sort.each do |controller|
135
+ if scsi_tree[controller]['children'].length < 15
136
+ available_controllers.push(scsi_tree[controller]['device'].deviceInfo.label)
137
+ end
138
+ end
139
+
140
+ if available_controllers.length > 0
141
+ use_controller = available_controllers[0]
142
+ puts "using #{use_controller}"
143
+ else
144
+
145
+ if scsi_tree.keys.length < 4
146
+
147
+ # Add a controller if none are available
148
+ puts "no controllers available. Will attempt to create"
149
+ new_scsi_key = scsi_tree.keys.sort[scsi_tree.length - 1] + 1
150
+ new_scsi_busNumber = scsi_tree[scsi_tree.keys.sort[scsi_tree.length - 1]]['device'].busNumber + 1
151
+
152
+ controller_device = RbVmomi::VIM::VirtualLsiLogicController(
153
+ :key => new_scsi_key,
154
+ :busNumber => new_scsi_busNumber,
155
+ :sharedBus => :noSharing
156
+ )
157
+
158
+ device_config_spec = RbVmomi::VIM::VirtualDeviceConfigSpec(
159
+ :device => controller_device,
160
+ :operation => RbVmomi::VIM::VirtualDeviceConfigSpecOperation("add")
161
+ )
162
+
163
+ vm_config_spec = RbVmomi::VIM::VirtualMachineConfigSpec(
164
+ :deviceChange => [device_config_spec]
165
+ )
166
+
167
+ if get_config(:noop)
168
+ ui.info "#{ui.color "Skipping controller creation process because --noop specified.", :red}"
169
+ else
170
+ vm.ReconfigVM_Task(:spec => vm_config_spec).wait_for_completion
171
+ end
172
+ else
173
+ ui.info "Controllers maxed out at 4."
174
+ exit -1
175
+ end
176
+ end
177
+
178
+ # now go back and get the new device's name
179
+ vm.config.hardware.device.each do |device|
180
+ if device.class == RbVmomi::VIM::VirtualLsiLogicController
181
+ if device.key == new_scsi_key
182
+ use_controller = device.deviceInfo.label
183
+ end
184
+ end
185
+ end
186
+
187
+ # add the disk
188
+ controller = find_device(vm, use_controller)
189
+
190
+ used_unitNumbers = Array.new()
191
+ scsi_tree.keys.sort.each do |c|
192
+ if controller.key == scsi_tree[c]['device'].key
193
+ used_unitNumbers.push(scsi_tree[c]['device'].scsiCtlrUnitNumber)
194
+ scsi_tree[c]['children'].each do |disk|
195
+ used_unitNumbers.push(disk.unitNumber)
196
+ end
197
+ end
198
+ end
199
+
200
+ available_unitNumbers = Array.new
201
+ (0 .. 15).each do |scsi_id|
202
+ if used_unitNumbers.grep(scsi_id).length > 0
203
+ else
204
+ available_unitNumbers.push(scsi_id)
205
+ end
206
+ end
207
+
208
+ # ensure we don't try to add the controllers SCSI ID
209
+ new_unitNumber = available_unitNumbers.sort[0]
210
+ puts "using SCSI ID #{new_unitNumber}"
211
+
212
+ vmdk_backing = RbVmomi::VIM::VirtualDiskFlatVer2BackingInfo(
213
+ :datastore => vmdk_datastore,
214
+ :diskMode => "persistent",
215
+ :fileName => vmdk_name
216
+ )
217
+
218
+ device = RbVmomi::VIM::VirtualDisk(
219
+ :backing => vmdk_backing,
220
+ :capacityInKB => vmdk_size_kb,
221
+ :controllerKey => controller.key,
222
+ :key => -1,
223
+ :unitNumber => new_unitNumber
224
+ )
225
+
226
+ device_config_spec = RbVmomi::VIM::VirtualDeviceConfigSpec(
227
+ :device => device,
228
+ :operation => RbVmomi::VIM::VirtualDeviceConfigSpecOperation("add")
229
+ )
230
+
231
+ vm_config_spec = RbVmomi::VIM::VirtualMachineConfigSpec(
232
+ :deviceChange => [device_config_spec]
233
+ )
234
+
235
+ if get_config(:noop)
236
+ ui.info "#{ui.color "Skipping disk attaching process because --noop specified.", :red}"
237
+ else
238
+ vm.ReconfigVM_Task(:spec => vm_config_spec).wait_for_completion
239
+ end
240
+ end
241
+ end