kitchen-hyperv 0.1.20 → 0.2.0

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,194 +1,193 @@
1
- #
2
- # Author:: Steven Murawski <smurawski@chef.io>
3
- # Copyright:: Copyright (c) 2015 Chef Software, Inc.
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
- require 'mixlib/shellout'
19
- require 'fileutils'
20
- require 'JSON'
21
-
22
- module Kitchen
23
- module Driver
24
- module PowerShellScripts
25
- def encode_command(script)
26
- encoded_script = script.encode('UTF-16LE', 'UTF-8')
27
- Base64.strict_encode64(encoded_script)
28
- end
29
-
30
- def is_64bit?
31
- os_arch = ENV['PROCESSOR_ARCHITEW6432'] || ENV['PROCESSOR_ARCHITECTURE']
32
- os_arch == 'AMD64'
33
- end
34
-
35
- def powershell_64_bit
36
- if is_64bit?
37
- 'c:\windows\system32\windowspowershell\v1.0\powershell.exe'
38
- else
39
- 'c:\windows\sysnative\windowspowershell\v1.0\powershell.exe'
40
- end
41
- end
42
-
43
- def wrap_command(script)
44
- base_script_path = File.join(File.dirname(__FILE__), '/../../../support/hyperv.ps1')
45
- debug("Loading functions from #{base_script_path}")
46
- new_script = ". #{base_script_path}; " << script
47
- debug("Wrapped script: #{new_script}")
48
- "#{powershell_64_bit} -noprofile -encodedcommand #{encode_command new_script} -outputformat Text"
49
- end
50
-
51
- # Convenience method to run a powershell command locally.
52
- #
53
- # @param cmd [String] command to run locally
54
- # @param options [Hash] options hash
55
- # @see Kitchen::ShellOut.run_command
56
- # @api private
57
- def run_ps(cmd, options = {})
58
- cmd = "echo #{cmd}" if config[:dry_run]
59
- debug('Preparing to run: ')
60
- debug(" #{cmd}")
61
- wrapped_command = wrap_command cmd
62
- execute_command wrapped_command, options
63
- end
64
-
65
- # rubocop:disable Metrics/AbcSize
66
- def execute_command(cmd, options = {})
67
- debug("#Local Command BEGIN (#{cmd})")
68
- sh = Mixlib::ShellOut.new(cmd, options)
69
- sh.run_command
70
- debug("Local Command END #{Util.duration(sh.execution_time)}")
71
- fail "Failed: #{sh.stderr}" if sh.error?
72
- JSON.parse(sh.stdout) if sh.stdout.length > 2
73
- end
74
- # rubocop:enable Metrics/AbcSize
75
-
76
- def new_differencing_disk_ps
77
- <<-DIFF
78
-
79
- New-DifferencingDisk -Path "#{differencing_disk_path}" -ParentPath "#{parent_vhd_path}"
80
- DIFF
81
- end
82
-
83
- def ensure_vm_running_ps
84
- <<-RUNNING
85
-
86
- Assert-VmRunning -ID "#{@state[:id]}" | ConvertTo-Json
87
- RUNNING
88
- end
89
-
90
- # rubocop:disable Metrics/MethodLength
91
- def new_vm_ps
92
- <<-NEWVM
93
-
94
- $NewVMParams = @{
95
- Generation = #{config[:vm_generation]}
96
- MemoryStartupBytes = #{config[:memory_startup_bytes]}
97
- Name = "#{instance.name}"
98
- Path = "#{kitchen_vm_path}"
99
- VHDPath = "#{differencing_disk_path}"
100
- SwitchName = "#{config[:vm_switch]}"
101
- ProcessorCount = #{config[:processor_count]}
102
- UseDynamicMemory = "#{config[:dynamic_memory]}"
103
- DynamicMemoryMinBytes = #{config[:dynamic_memory_min_bytes]}
104
- DynamicMemoryMaxBytes = #{config[:dynamic_memory_max_bytes]}
105
- }
106
- New-KitchenVM @NewVMParams | ConvertTo-Json
107
- NEWVM
108
- end
109
- # rubocop:enable Metrics/MethodLength
110
-
111
- def vm_details_ps
112
- <<-DETAILS
113
-
114
- Get-VmDetail -id "#{@state[:id]}" | ConvertTo-Json
115
- DETAILS
116
- end
117
-
118
- def delete_vm_ps
119
- <<-REMOVE
120
-
121
- $null = Get-VM -ID "#{@state[:id]}" |
122
- Stop-VM -Force -TurnOff -PassThru |
123
- Remove-VM -Force
124
- REMOVE
125
- end
126
-
127
- def set_vm_ipaddress_ps
128
- <<-VMIP
129
-
130
- (Get-VM -id "#{@state[:id]}").NetworkAdapters |
131
- Set-VMNetworkConfiguration -ipaddress "#{config[:ip_address]}" `
132
- -subnet "#{config[:subnet]}" `
133
- -gateway "#{config[:gateway]}" `
134
- -dnsservers #{ruby_array_to_ps_array(config[:dns_servers])} |
135
- ConvertTo-Json
136
- VMIP
137
- end
138
-
139
- def vm_default_switch_ps
140
- <<-VMSWITCH
141
- Get-DefaultVMSwitch | ConvertTo-Json
142
- VMSWITCH
143
- end
144
-
145
- def mount_vm_iso
146
- <<-MOUNTISO
147
- mount-vmiso -id "#{@state[:id]}" -Path #{config[:iso_path]}
148
- MOUNTISO
149
- end
150
-
151
- def copy_vm_file_ps(source, dest)
152
- <<-FILECOPY
153
- Function CopyFile ($VM, [string]$SourcePath, [string]$DestPath) {
154
- #Write-Host "Copying file to VM - Source: $SourcePath Destination $DestPath"
155
- $VM | Copy-VMFile -SourcePath $SourcePath -DestinationPath $DestPath -CreateFullPath -FileSource Host -Force
156
- }
157
-
158
- $sourceLocation = '#{source}'
159
- $destinationLocation = '#{dest}'
160
- $vmId = '#{@state[:id]}'
161
- If (Test-Path $sourceLocation) {
162
- $vm = Get-VM -ID $vmId
163
- $service = 'Guest Service Interface'
164
-
165
- If ((Get-VMIntegrationService -Name $service -VM $vm).Enabled -ne $true) {
166
- Enable-VMIntegrationService -Name $service -VM $vm
167
- Start-Sleep -Seconds 3
168
- }
169
-
170
- If ((Get-Item $sourceLocation) -is [System.IO.DirectoryInfo]) {
171
- ForEach ($item in (Get-ChildItem -Path $sourceLocation -File)) {
172
- $destFullPath = (Join-Path $destinationLocation $item.Name)
173
- CopyFile $vm $item.FullName $destFullPath
174
- }
175
- }
176
- Else {
177
- CopyFile $vm $sourceLocation $destinationLocation
178
- }
179
- }
180
- else {
181
- Write-Error "Source file path does not exist: $sourceLocation"
182
- }
183
- FILECOPY
184
- end
185
-
186
- private
187
-
188
- def ruby_array_to_ps_array(list)
189
- return "@()" if list.nil? || list.empty?
190
- list.to_s.tr('[]','()').prepend('@')
191
- end
192
- end
193
- end
194
- end
1
+ #
2
+ # Author:: Steven Murawski <smurawski@chef.io>
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
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
+ require 'mixlib/shellout'
19
+ require 'fileutils'
20
+ require 'JSON'
21
+
22
+ module Kitchen
23
+ module Driver
24
+ module PowerShellScripts
25
+ def encode_command(script)
26
+ encoded_script = script.encode('UTF-16LE', 'UTF-8')
27
+ Base64.strict_encode64(encoded_script)
28
+ end
29
+
30
+ def is_64bit?
31
+ os_arch = ENV['PROCESSOR_ARCHITEW6432'] || ENV['PROCESSOR_ARCHITECTURE']
32
+ os_arch == 'AMD64'
33
+ end
34
+
35
+ def powershell_64_bit
36
+ if is_64bit?
37
+ 'c:\windows\system32\windowspowershell\v1.0\powershell.exe'
38
+ else
39
+ 'c:\windows\sysnative\windowspowershell\v1.0\powershell.exe'
40
+ end
41
+ end
42
+
43
+ def wrap_command(script)
44
+ base_script_path = File.join(File.dirname(__FILE__), '/../../../support/hyperv.ps1')
45
+ debug("Loading functions from #{base_script_path}")
46
+ new_script = ". #{base_script_path}; " << script
47
+ debug("Wrapped script: #{new_script}")
48
+ "#{powershell_64_bit} -noprofile -executionpolicy bypass" \
49
+ " -encodedcommand #{encode_command new_script} -outputformat Text"
50
+ end
51
+
52
+ # Convenience method to run a powershell command locally.
53
+ #
54
+ # @param cmd [String] command to run locally
55
+ # @param options [Hash] options hash
56
+ # @see Kitchen::ShellOut.run_command
57
+ # @api private
58
+ def run_ps(cmd, options = {})
59
+ cmd = "echo #{cmd}" if config[:dry_run]
60
+ debug('Preparing to run: ')
61
+ debug(" #{cmd}")
62
+ wrapped_command = wrap_command cmd
63
+ execute_command wrapped_command, options
64
+ end
65
+
66
+ def execute_command(cmd, options = {})
67
+ debug("#Local Command BEGIN (#{cmd})")
68
+ sh = Mixlib::ShellOut.new(cmd, options)
69
+ sh.run_command
70
+ debug("Local Command END #{Util.duration(sh.execution_time)}")
71
+ raise "Failed: #{sh.stderr}" if sh.error?
72
+ JSON.parse(sh.stdout) if sh.stdout.length > 2
73
+ end
74
+
75
+ def new_differencing_disk_ps
76
+ <<-DIFF
77
+
78
+ New-DifferencingDisk -Path "#{differencing_disk_path}" -ParentPath "#{parent_vhd_path}"
79
+ DIFF
80
+ end
81
+
82
+ def ensure_vm_running_ps
83
+ <<-RUNNING
84
+
85
+ Assert-VmRunning -ID "#{@state[:id]}" | ConvertTo-Json
86
+ RUNNING
87
+ end
88
+
89
+ def new_vm_ps
90
+ <<-NEWVM
91
+
92
+ $NewVMParams = @{
93
+ Generation = #{config[:vm_generation]}
94
+ MemoryStartupBytes = #{config[:memory_startup_bytes]}
95
+ Name = "#{instance.name}"
96
+ Path = "#{kitchen_vm_path}"
97
+ VHDPath = "#{differencing_disk_path}"
98
+ SwitchName = "#{config[:vm_switch]}"
99
+ ProcessorCount = #{config[:processor_count]}
100
+ UseDynamicMemory = "#{config[:dynamic_memory]}"
101
+ DynamicMemoryMinBytes = #{config[:dynamic_memory_min_bytes]}
102
+ DynamicMemoryMaxBytes = #{config[:dynamic_memory_max_bytes]}
103
+ boot_iso_path = "#{boot_iso_path}"
104
+ }
105
+ New-KitchenVM @NewVMParams | ConvertTo-Json
106
+ NEWVM
107
+ end
108
+
109
+ def vm_details_ps
110
+ <<-DETAILS
111
+
112
+ Get-VmDetail -id "#{@state[:id]}" | ConvertTo-Json
113
+ DETAILS
114
+ end
115
+
116
+ def delete_vm_ps
117
+ <<-REMOVE
118
+
119
+ $null = Get-VM -ID "#{@state[:id]}" |
120
+ Stop-VM -Force -TurnOff -PassThru |
121
+ Remove-VM -Force
122
+ REMOVE
123
+ end
124
+
125
+ def set_vm_ipaddress_ps
126
+ <<-VMIP
127
+
128
+ (Get-VM -id "#{@state[:id]}").NetworkAdapters |
129
+ Set-VMNetworkConfiguration -ipaddress "#{config[:ip_address]}" `
130
+ -subnet "#{config[:subnet]}" `
131
+ -gateway "#{config[:gateway]}" `
132
+ -dnsservers #{ruby_array_to_ps_array(config[:dns_servers])} |
133
+ ConvertTo-Json
134
+ VMIP
135
+ end
136
+
137
+ def vm_default_switch_ps
138
+ <<-VMSWITCH
139
+ Get-DefaultVMSwitch #{config[:vm_switch]} | ConvertTo-Json
140
+ VMSWITCH
141
+ end
142
+
143
+ def mount_vm_iso
144
+ <<-MOUNTISO
145
+ mount-vmiso -id "#{@state[:id]}" -Path #{config[:iso_path]}
146
+ MOUNTISO
147
+ end
148
+
149
+ def copy_vm_file_ps(source, dest)
150
+ <<-FILECOPY
151
+ Function CopyFile ($VM, [string]$SourcePath, [string]$DestPath) {
152
+ $p = @{ CreateFullPath = $true ; FileSource = 'Host'; Force = $true }
153
+ $VM |
154
+ Copy-VMFile -SourcePath $SourcePath -DestinationPath $DestPath @p
155
+ }
156
+
157
+ $sourceLocation = '#{source}'
158
+ $destinationLocation = '#{dest}'
159
+ $vmId = '#{@state[:id]}'
160
+ If (Test-Path $sourceLocation) {
161
+ $vm = Get-VM -ID $vmId
162
+ $service = 'Guest Service Interface'
163
+
164
+ If ((Get-VMIntegrationService -Name $service -VM $vm).Enabled -ne $true) {
165
+ Enable-VMIntegrationService -Name $service -VM $vm
166
+ Start-Sleep -Seconds 3
167
+ }
168
+
169
+ If ((Get-Item $sourceLocation) -is [System.IO.DirectoryInfo]) {
170
+ ForEach ($item in (Get-ChildItem -Path $sourceLocation -File)) {
171
+ $destFullPath = (Join-Path $destinationLocation $item.Name)
172
+ CopyFile $vm $item.FullName $destFullPath
173
+ }
174
+ }
175
+ Else {
176
+ CopyFile $vm $sourceLocation $destinationLocation
177
+ }
178
+ }
179
+ else {
180
+ Write-Error "Source file path does not exist: $sourceLocation"
181
+ }
182
+ FILECOPY
183
+ end
184
+
185
+ private
186
+
187
+ def ruby_array_to_ps_array(list)
188
+ return "@()" if list.nil? || list.empty?
189
+ list.to_s.tr('[]','()').prepend('@')
190
+ end
191
+ end
192
+ end
193
+ end
@@ -1,70 +1,70 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2015, Fletcher Nichol
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
-
19
- require_relative "../../spec_helper"
20
-
21
- require "logger"
22
- require "stringio"
23
- require "kitchen"
24
- require 'kitchen/driver/hyperv_version'
25
- require "kitchen/driver/hyperv"
26
- require "kitchen/provisioner/dummy"
27
- require "kitchen/transport/dummy"
28
- require "kitchen/verifier/dummy"
29
-
30
- describe Kitchen::Driver::Hyperv do
31
-
32
- let(:logged_output) { StringIO.new }
33
- let(:logger) { Logger.new(logged_output) }
34
- let(:config) { { :kitchen_root => "c:/test_root" } }
35
- let(:platform) { Kitchen::Platform.new(:name => "fooos-99") }
36
- let(:suite) { Kitchen::Suite.new(:name => "suitey") }
37
- let(:verifier) { Kitchen::Verifier::Dummy.new }
38
- let(:provisioner) { Kitchen::Provisioner::Dummy.new }
39
- let(:transport) { Kitchen::Transport::Dummy.new }
40
- let(:state_file) { stub("state_file") }
41
- let(:state) { Hash.new }
42
- let(:env) { Hash.new }
43
-
44
- let(:driver_object) { Kitchen::Driver::Hyperv.new(config) }
45
-
46
- let(:driver) do
47
- d = driver_object
48
- instance
49
- d
50
- end
51
-
52
- let(:instance) do
53
- Kitchen::Instance.new(
54
- :verifier => verifier,
55
- :driver => driver_object,
56
- :logger => logger,
57
- :suite => suite,
58
- :platform => platform,
59
- :provisioner => provisioner,
60
- :transport => transport,
61
- :state_file => state_file
62
- )
63
- end
64
-
65
- #before { stub_const("ENV", env) }
66
-
67
- it 'driver api_version is 2' do
68
- driver.diagnose_plugin[:api_version].must_equal(2)
69
- end
70
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2015, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative "../../spec_helper"
20
+
21
+ require "logger"
22
+ require "stringio"
23
+ require "kitchen"
24
+ require 'kitchen/driver/hyperv_version'
25
+ require "kitchen/driver/hyperv"
26
+ require "kitchen/provisioner/dummy"
27
+ require "kitchen/transport/dummy"
28
+ require "kitchen/verifier/dummy"
29
+
30
+ describe Kitchen::Driver::Hyperv do
31
+
32
+ let(:logged_output) { StringIO.new }
33
+ let(:logger) { Logger.new(logged_output) }
34
+ let(:config) { { :kitchen_root => "c:/test_root" } }
35
+ let(:platform) { Kitchen::Platform.new(:name => "fooos-99") }
36
+ let(:suite) { Kitchen::Suite.new(:name => "suitey") }
37
+ let(:verifier) { Kitchen::Verifier::Dummy.new }
38
+ let(:provisioner) { Kitchen::Provisioner::Dummy.new }
39
+ let(:transport) { Kitchen::Transport::Dummy.new }
40
+ let(:state_file) { stub("state_file") }
41
+ let(:state) { Hash.new }
42
+ let(:env) { Hash.new }
43
+
44
+ let(:driver_object) { Kitchen::Driver::Hyperv.new(config) }
45
+
46
+ let(:driver) do
47
+ d = driver_object
48
+ instance
49
+ d
50
+ end
51
+
52
+ let(:instance) do
53
+ Kitchen::Instance.new(
54
+ :verifier => verifier,
55
+ :driver => driver_object,
56
+ :logger => logger,
57
+ :suite => suite,
58
+ :platform => platform,
59
+ :provisioner => provisioner,
60
+ :transport => transport,
61
+ :state_file => state_file
62
+ )
63
+ end
64
+
65
+ #before { stub_const("ENV", env) }
66
+
67
+ it 'driver api_version is 2' do
68
+ driver.diagnose_plugin[:api_version].must_equal(2)
69
+ end
70
+ end