lib/kitchen/driver/powershell.rb in kitchen-hyperv-0.2.3 vs lib/kitchen/driver/powershell.rb in kitchen-hyperv-0.3.0
- old
+ new
@@ -1,205 +1,212 @@
-#
-# Author:: Steven Murawski <smurawski@chef.io>
-# Copyright:: Copyright (c) 2015 Chef Software, Inc.
-# License:: Apache License, Version 2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-require 'mixlib/shellout'
-require 'fileutils'
-require 'JSON'
-
-module Kitchen
- module Driver
- module PowerShellScripts
- def encode_command(script)
- encoded_script = script.encode('UTF-16LE', 'UTF-8')
- Base64.strict_encode64(encoded_script)
- end
-
- def is_64bit?
- os_arch = ENV['PROCESSOR_ARCHITEW6432'] || ENV['PROCESSOR_ARCHITECTURE']
- ruby_arch = ['foo'].pack('p').size == 4 ? 32 : 64
- os_arch == 'AMD64' && ruby_arch == 64
- end
-
- def is_32bit?
- os_arch = ENV['PROCESSOR_ARCHITEW6432'] || ENV['PROCESSOR_ARCHITECTURE']
- ruby_arch = ['foo'].pack('p').size == 4 ? 32 : 64
- os_arch != 'AMD64' && ruby_arch == 32
- end
-
- def powershell_64_bit
- if is_64bit? || is_32bit?
- 'c:\windows\system32\windowspowershell\v1.0\powershell.exe'
- else
- 'c:\windows\sysnative\windowspowershell\v1.0\powershell.exe'
- end
- end
-
- def wrap_command(script)
- base_script_path = File.join(File.dirname(__FILE__), '/../../../support/hyperv.ps1')
- debug("Loading functions from #{base_script_path}")
- new_script = [ ". #{base_script_path}", "#{script}" ].join(";\n")
- debug("Wrapped script: #{new_script}")
- "#{powershell_64_bit} -noprofile -executionpolicy bypass" \
- " -encodedcommand #{encode_command new_script} -outputformat Text"
- end
-
- # Convenience method to run a powershell command locally.
- #
- # @param cmd [String] command to run locally
- # @param options [Hash] options hash
- # @see Kitchen::ShellOut.run_command
- # @api private
- def run_ps(cmd, options = {})
- cmd = "echo #{cmd}" if config[:dry_run]
- debug('Preparing to run: ')
- debug(" #{cmd}")
- wrapped_command = wrap_command cmd
- execute_command wrapped_command, options
- end
-
- def execute_command(cmd, options = {})
- debug("#Local Command BEGIN (#{cmd})")
- sh = Mixlib::ShellOut.new(cmd, options)
- sh.run_command
- debug("Local Command END #{Util.duration(sh.execution_time)}")
- raise "Failed: #{sh.stderr}" if sh.error?
- stdout = sanitize_stdout(sh.stdout)
- JSON.parse(stdout) if stdout.length > 2
- end
-
- def sanitize_stdout(stdout)
- stdout.split("\n").select { |s| !s.start_with?("PS") }.join("\n")
- end
-
- def new_differencing_disk_ps
- <<-DIFF
-
- New-DifferencingDisk -Path "#{differencing_disk_path}" -ParentPath "#{parent_vhd_path}"
- DIFF
- end
-
- def ensure_vm_running_ps
- <<-RUNNING
-
- Assert-VmRunning -ID "#{@state[:id]}" | ConvertTo-Json
- RUNNING
- end
-
- def new_vm_ps
- <<-NEWVM
-
- $NewVMParams = @{
- Generation = #{config[:vm_generation]}
- MemoryStartupBytes = #{config[:memory_startup_bytes]}
- Name = "#{instance.name}"
- Path = "#{kitchen_vm_path}"
- VHDPath = "#{differencing_disk_path}"
- SwitchName = "#{config[:vm_switch]}"
- ProcessorCount = #{config[:processor_count]}
- UseDynamicMemory = "#{config[:dynamic_memory]}"
- DynamicMemoryMinBytes = #{config[:dynamic_memory_min_bytes]}
- DynamicMemoryMaxBytes = #{config[:dynamic_memory_max_bytes]}
- boot_iso_path = "#{boot_iso_path}"
- }
- New-KitchenVM @NewVMParams | ConvertTo-Json
- NEWVM
- end
-
- def vm_details_ps
- <<-DETAILS
-
- Get-VmDetail -id "#{@state[:id]}" | ConvertTo-Json
- DETAILS
- end
-
- def delete_vm_ps
- <<-REMOVE
-
- $null = Get-VM -ID "#{@state[:id]}" |
- Stop-VM -Force -TurnOff -PassThru |
- Remove-VM -Force
- REMOVE
- end
-
- def set_vm_ipaddress_ps
- <<-VMIP
-
- (Get-VM -id "#{@state[:id]}").NetworkAdapters |
- Set-VMNetworkConfiguration -ipaddress "#{config[:ip_address]}" `
- -subnet "#{config[:subnet]}" `
- -gateway "#{config[:gateway]}" `
- -dnsservers #{ruby_array_to_ps_array(config[:dns_servers])} |
- ConvertTo-Json
- VMIP
- end
-
- def vm_default_switch_ps
- <<-VMSWITCH
- Get-DefaultVMSwitch #{config[:vm_switch]} | ConvertTo-Json
- VMSWITCH
- end
-
- def mount_vm_iso
- <<-MOUNTISO
- mount-vmiso -id "#{@state[:id]}" -Path #{config[:iso_path]}
- MOUNTISO
- end
-
- def copy_vm_file_ps(source, dest)
- <<-FILECOPY
- Function CopyFile ($VM, [string]$SourcePath, [string]$DestPath) {
- $p = @{ CreateFullPath = $true ; FileSource = 'Host'; Force = $true }
- $VM |
- Copy-VMFile -SourcePath $SourcePath -DestinationPath $DestPath @p
- }
-
- $sourceLocation = '#{source}'
- $destinationLocation = '#{dest}'
- $vmId = '#{@state[:id]}'
- If (Test-Path $sourceLocation) {
- $vm = Get-VM -ID $vmId
- $service = 'Guest Service Interface'
-
- If ((Get-VMIntegrationService -Name $service -VM $vm).Enabled -ne $true) {
- Enable-VMIntegrationService -Name $service -VM $vm
- Start-Sleep -Seconds 3
- }
-
- If ((Get-Item $sourceLocation) -is [System.IO.DirectoryInfo]) {
- ForEach ($item in (Get-ChildItem -Path $sourceLocation -File)) {
- $destFullPath = (Join-Path $destinationLocation $item.Name)
- CopyFile $vm $item.FullName $destFullPath
- }
- }
- Else {
- CopyFile $vm $sourceLocation $destinationLocation
- }
- }
- else {
- Write-Error "Source file path does not exist: $sourceLocation"
- }
- FILECOPY
- end
-
- private
-
- def ruby_array_to_ps_array(list)
- return "@()" if list.nil? || list.empty?
- list.to_s.tr('[]','()').prepend('@')
- end
- end
- end
-end
+#
+# Author:: Steven Murawski <smurawski@chef.io>
+# Copyright:: Copyright (c) 2015 Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'mixlib/shellout'
+require 'fileutils'
+require 'JSON'
+
+module Kitchen
+ module Driver
+ module PowerShellScripts
+ def encode_command(script)
+ encoded_script = script.encode('UTF-16LE', 'UTF-8')
+ Base64.strict_encode64(encoded_script)
+ end
+
+ def is_64bit?
+ os_arch = ENV['PROCESSOR_ARCHITEW6432'] || ENV['PROCESSOR_ARCHITECTURE']
+ ruby_arch = ['foo'].pack('p').size == 4 ? 32 : 64
+ os_arch == 'AMD64' && ruby_arch == 64
+ end
+
+ def is_32bit?
+ os_arch = ENV['PROCESSOR_ARCHITEW6432'] || ENV['PROCESSOR_ARCHITECTURE']
+ ruby_arch = ['foo'].pack('p').size == 4 ? 32 : 64
+ os_arch != 'AMD64' && ruby_arch == 32
+ end
+
+ def powershell_64_bit
+ if is_64bit? || is_32bit?
+ 'c:\windows\system32\windowspowershell\v1.0\powershell.exe'
+ else
+ 'c:\windows\sysnative\windowspowershell\v1.0\powershell.exe'
+ end
+ end
+
+ def wrap_command(script)
+ base_script_path = File.join(File.dirname(__FILE__), '/../../../support/hyperv.ps1')
+ debug("Loading functions from #{base_script_path}")
+ new_script = [ ". #{base_script_path}", "#{script}" ].join(";\n")
+ debug("Wrapped script: #{new_script}")
+ "#{powershell_64_bit} -noprofile -executionpolicy bypass" \
+ " -encodedcommand #{encode_command new_script} -outputformat Text"
+ end
+
+ # Convenience method to run a powershell command locally.
+ #
+ # @param cmd [String] command to run locally
+ # @param options [Hash] options hash
+ # @see Kitchen::ShellOut.run_command
+ # @api private
+ def run_ps(cmd, options = {})
+ cmd = "echo #{cmd}" if config[:dry_run]
+ debug('Preparing to run: ')
+ debug(" #{cmd}")
+ wrapped_command = wrap_command cmd
+ execute_command wrapped_command, options
+ end
+
+ def execute_command(cmd, options = {})
+ debug("#Local Command BEGIN (#{cmd})")
+ sh = Mixlib::ShellOut.new(cmd, options)
+ sh.run_command
+ debug("Local Command END #{Util.duration(sh.execution_time)}")
+ raise "Failed: #{sh.stderr}" if sh.error?
+ stdout = sanitize_stdout(sh.stdout)
+ JSON.parse(stdout) if stdout.length > 2
+ end
+
+ def sanitize_stdout(stdout)
+ stdout.split("\n").select { |s| !s.start_with?("PS") }.join("\n")
+ end
+
+ def new_differencing_disk_ps
+ <<-DIFF
+
+ New-DifferencingDisk -Path "#{differencing_disk_path}" -ParentPath "#{parent_vhd_path}"
+ DIFF
+ end
+
+ def ensure_vm_running_ps
+ <<-RUNNING
+
+ Assert-VmRunning -ID "#{@state[:id]}" | ConvertTo-Json
+ RUNNING
+ end
+
+ def new_vm_ps
+ <<-NEWVM
+
+ $NewVMParams = @{
+ Generation = #{config[:vm_generation]}
+ MemoryStartupBytes = #{config[:memory_startup_bytes]}
+ Name = "#{instance.name}"
+ Path = "#{kitchen_vm_path}"
+ VHDPath = "#{differencing_disk_path}"
+ SwitchName = "#{config[:vm_switch]}"
+ ProcessorCount = #{config[:processor_count]}
+ UseDynamicMemory = "#{config[:dynamic_memory]}"
+ DynamicMemoryMinBytes = #{config[:dynamic_memory_min_bytes]}
+ DynamicMemoryMaxBytes = #{config[:dynamic_memory_max_bytes]}
+ boot_iso_path = "#{boot_iso_path}"
+ EnableGuestServices = "#{config[:enable_guest_services]}"
+ }
+ New-KitchenVM @NewVMParams | ConvertTo-Json
+ NEWVM
+ end
+
+ def vm_details_ps
+ <<-DETAILS
+
+ Get-VmDetail -id "#{@state[:id]}" | ConvertTo-Json
+ DETAILS
+ end
+
+ def delete_vm_ps
+ <<-REMOVE
+
+ $null = Get-VM -ID "#{@state[:id]}" |
+ Stop-VM -Force -TurnOff -PassThru |
+ Remove-VM -Force
+ REMOVE
+ end
+
+ def set_vm_ipaddress_ps
+ <<-VMIP
+
+ (Get-VM -id "#{@state[:id]}").NetworkAdapters |
+ Set-VMNetworkConfiguration -ipaddress "#{config[:ip_address]}" `
+ -subnet "#{config[:subnet]}" `
+ -gateway "#{config[:gateway]}" `
+ -dnsservers #{ruby_array_to_ps_array(config[:dns_servers])} |
+ ConvertTo-Json
+ VMIP
+ end
+
+ def vm_default_switch_ps
+ <<-VMSWITCH
+ Get-DefaultVMSwitch #{config[:vm_switch]} | ConvertTo-Json
+ VMSWITCH
+ end
+
+ def mount_vm_iso
+ <<-MOUNTISO
+ mount-vmiso -id "#{@state[:id]}" -Path #{config[:iso_path]}
+ MOUNTISO
+ end
+
+ def set_vm_note
+ <<-VMNOTE
+ Set-VM -Name (Get-VM | Where-Object{ $_.ID -eq "#{@state[:id]}"}).Name -Note "#{config[:vm_note]}"
+ VMNOTE
+ end
+
+ def copy_vm_file_ps(source, dest)
+ <<-FILECOPY
+ Function CopyFile ($VM, [string]$SourcePath, [string]$DestPath) {
+ $p = @{ CreateFullPath = $true ; FileSource = 'Host'; Force = $true }
+ $VM |
+ Copy-VMFile -SourcePath $SourcePath -DestinationPath $DestPath @p
+ }
+
+ $sourceLocation = '#{source}'
+ $destinationLocation = '#{dest}'
+ $vmId = '#{@state[:id]}'
+ If (Test-Path $sourceLocation) {
+ $vm = Get-VM -ID $vmId
+ $service = 'Guest Service Interface'
+
+ If ((Get-VMIntegrationService -Name $service -VM $vm).Enabled -ne $true) {
+ Enable-VMIntegrationService -Name $service -VM $vm
+ Start-Sleep -Seconds 3
+ }
+
+ If ((Get-Item $sourceLocation) -is [System.IO.DirectoryInfo]) {
+ ForEach ($item in (Get-ChildItem -Path $sourceLocation -File)) {
+ $destFullPath = (Join-Path $destinationLocation $item.Name)
+ CopyFile $vm $item.FullName $destFullPath
+ }
+ }
+ Else {
+ CopyFile $vm $sourceLocation $destinationLocation
+ }
+ }
+ else {
+ Write-Error "Source file path does not exist: $sourceLocation"
+ }
+ FILECOPY
+ end
+
+ private
+
+ def ruby_array_to_ps_array(list)
+ return "@()" if list.nil? || list.empty?
+ list.to_s.tr('[]','()').prepend('@')
+ end
+ end
+ end
+end