knife-vsphere 0.9.5 → 0.9.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.
@@ -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