kitchen-hyperv 0.1.20 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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