kitchen-hyperv 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7588944a18673c39d89916777a86bfd20fefada1
4
+ data.tar.gz: f11736929cca5a1c06ce00e8b27e9f8821991992
5
+ SHA512:
6
+ metadata.gz: 51c6e027033709b450e949468550bf3bad75a2ab43e6c32a972d21d40f9cd75329e0624b62b6bdd9137fa6827e4b0838c5df1fcc9762b6e00cf0dc9eb9800ab3
7
+ data.tar.gz: 113b8020c4d1f4e25941d7699cb494851f45eac56e09aa38ac0179a419d85f7f9569865ab3648aabbcafca62aa8ac22d2bb43e247f1cfcaf1a847dede9e9d70d
data/.cane ADDED
@@ -0,0 +1,2 @@
1
+ --no-doc
2
+ --style-measure 100
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ Metrics/LineLength:
2
+ Max: 100
3
+
4
+ Style/Documentation:
5
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kitchen-hyperv.gemspec
4
+ gemspec
5
+
6
+ gem 'win32-process'
7
+ gem 'win32-api'
8
+ gem 'windows-pr'
9
+ gem 'windows-api'
10
+ gem 'ffi'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Steven Murawski
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Kitchen::Hyperv
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'kitchen-hyperv'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install kitchen-hyperv
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/kitchen-hyperv/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "bundler/gem_tasks"
4
+
5
+ require "rake/testtask"
6
+ Rake::TestTask.new(:unit) do |t|
7
+ t.libs.push "lib"
8
+ t.test_files = FileList["spec/**/*_spec.rb"]
9
+ t.verbose = true
10
+ end
11
+
12
+ desc "Run all test suites"
13
+ task :test => [:unit]
14
+
15
+ desc "Display LOC stats"
16
+ task :stats do
17
+ puts "\n## Production Code Stats"
18
+ sh "countloc -r lib"
19
+ puts "\n## Test Code Stats"
20
+ sh "countloc -r spec"
21
+ end
22
+
23
+ require "finstyle"
24
+ require "rubocop/rake_task"
25
+ RuboCop::RakeTask.new(:style) do |task|
26
+ task.options << "--display-cop-names"
27
+ task.options << "--lint"
28
+ task.options << '--config' << '.rubocop.yml'
29
+ task.patterns = ['lib/**/*.rb']
30
+ end
31
+
32
+ require "cane/rake_task"
33
+ desc "Run cane to check quality metrics"
34
+ Cane::RakeTask.new do |cane|
35
+ cane.canefile = "./.cane"
36
+ end
37
+
38
+ desc "Run all quality tasks"
39
+ task :quality => [:cane, :style, :stats]
40
+
41
+ require "yard"
42
+ YARD::Rake::YardocTask.new
43
+
44
+ desc "Generate gem dependency graph"
45
+ task :viz do
46
+ Bundler.with_clean_env do
47
+ sh "bundle viz --without test development guard " \
48
+ "--requirements --version"
49
+ end
50
+ end
51
+
52
+ task :default => [:test, :quality]
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'kitchen/driver/hyperv_version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "kitchen-hyperv"
9
+ spec.version = Kitchen::Driver::HYPERV_VERSION
10
+ spec.authors = ["Steven Murawski"]
11
+ spec.email = ["steven.murawski@gmail.com"]
12
+ spec.summary = 'Hyper-V Driver for Test-Kitchen'
13
+ spec.description = 'Hyper-V Driver for Test-Kitchen'
14
+ spec.homepage = ""
15
+ spec.license = "Apache 2"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "pry", "~> 0.10"
25
+
26
+ spec.add_dependency "test-kitchen", "~> 1.4"
27
+ end
@@ -0,0 +1,139 @@
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
+
19
+ require 'kitchen'
20
+ require 'kitchen/driver'
21
+ require 'kitchen/driver/hyperv_version'
22
+ require 'kitchen/driver/powershell'
23
+ require 'mixlib/shellout'
24
+ require 'fileutils'
25
+ require 'JSON'
26
+
27
+ module Kitchen
28
+
29
+ module Driver
30
+
31
+ # Driver for Hyper-V
32
+ class Hyperv < Kitchen::Driver::Base
33
+
34
+ kitchen_driver_api_version 2
35
+ plugin_version Kitchen::Driver::HYPERV_VERSION
36
+
37
+ default_config :parent_vhd_folder
38
+ default_config :parent_vhd_name
39
+ default_config :memory_startup_bytes, 536_870_912
40
+ default_config :processor_count, 2
41
+ default_config :password
42
+ # because test-kitchen defaults to the wrong value
43
+ default_config :username, 'Administrator'
44
+ default_config :ip_address
45
+ default_config :vm_switch
46
+
47
+ include Kitchen::Driver::PowerShellScripts
48
+
49
+ def create(state)
50
+ @state = state
51
+ validate_vm_settings
52
+ create_new_differencing_disk
53
+ create_virtual_machine
54
+ update_state
55
+ instance.transport.connection(@state).wait_until_ready
56
+ info("Hyper-V instance #{instance.to_str} created.")
57
+ end
58
+
59
+ def destroy(state)
60
+ @state = state
61
+ return unless vm_exists
62
+ instance.transport.connection(state).close
63
+ remove_virtual_machine
64
+ remove_differencing_disk
65
+ info("The Hyper-V instance #{instance.to_str} has been removed.")
66
+ state.delete(:id)
67
+ end
68
+
69
+ private
70
+
71
+ def validate_vm_settings
72
+ return if config[:vm_switch]
73
+ config[:vm_switch] = (run_ps vm_default_switch_ps)['Name']
74
+ end
75
+
76
+ def kitchen_vm_path
77
+ @kitchen_vm_path ||= File.join(config[:kitchen_root], ".kitchen/#{instance.name}")
78
+ end
79
+
80
+ def differencing_disk_path
81
+ @differencing_disk_path ||= File.join(kitchen_vm_path, 'diff.vhd')
82
+ end
83
+
84
+ def parent_vhd_path
85
+ @parent_vhd_path ||= File.join(config[:parent_vhd_folder], config[:parent_vhd_name])
86
+ end
87
+
88
+ def vm_exists
89
+ info('Checking for existing virtual machine.')
90
+ return false unless @state.key?(:id) || @state[:id].nil?
91
+ existing_vm = run_ps ensure_vm_running_ps
92
+ info("Found an exising VM with an ID: #{existing_vm['Id']}")
93
+ return true unless existing_vm.nil? || existing_vm['Id'].nil?
94
+ #fail('Failed to start existing VM.')
95
+ end
96
+
97
+ def remove_differencing_disk
98
+ info("Removing the differencing disk for #{instance.name}.")
99
+ FileUtils.rm(differencing_disk_path)
100
+ info("Removed the differencing disk for #{instance.name}.")
101
+ end
102
+
103
+ def create_new_differencing_disk
104
+ return if File.exist? differencing_disk_path
105
+ info("Creating differencing disk for #{instance.name}.")
106
+ run_ps new_differencing_disk_ps
107
+ info("Created differencing disk for #{instance.name}.")
108
+ end
109
+
110
+ def remove_virtual_machine
111
+ info("Deleting virtual machine for #{instance.name}")
112
+ run_ps delete_vm_ps
113
+ info("Deleted virtual machine for #{instance.name}")
114
+ end
115
+
116
+ def create_virtual_machine
117
+ return if vm_exists
118
+ info("Creating virtual machine for #{instance.name}.")
119
+ new_vm_object = run_ps new_vm_ps
120
+ @state[:id] = new_vm_object['Id']
121
+ info("Created virtual machine for #{instance.name}.")
122
+ end
123
+
124
+ def update_state
125
+ vm_details
126
+ @state[:id] = @vm['Id']
127
+ @state[:hostname] = @vm['IpAddress']
128
+ @state[:vm_name] = @vm['Name']
129
+ @state[:password] = config[:password]
130
+ @state[:username] = config[:username]
131
+ end
132
+
133
+ def vm_details
134
+ run_ps set_vm_ipaddress_ps if config[:ip_address]
135
+ @vm = run_ps vm_details_ps
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,22 @@
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
+ module Kitchen
19
+ module Driver
20
+ HYPERV_VERSION = '0.1.0'
21
+ end
22
+ end
@@ -0,0 +1,131 @@
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 powershell_64_bit
31
+ 'c:\windows\sysnative\windowspowershell\v1.0\powershell.exe'
32
+ end
33
+
34
+ def wrap_command(script)
35
+ base_script_path = File.join(File.dirname(__FILE__), '/../../../support/hyperv.ps1')
36
+ debug("Loading functions from #{base_script_path}")
37
+ new_script = ". #{base_script_path}; " << script
38
+ debug("Wrapped script: #{new_script}")
39
+ "#{powershell_64_bit} -encodedcommand #{encode_command new_script} -outputformat Text"
40
+ end
41
+
42
+ # Convenience method to run a powershell command locally.
43
+ #
44
+ # @param cmd [String] command to run locally
45
+ # @param options [Hash] options hash
46
+ # @see Kitchen::ShellOut.run_command
47
+ # @api private
48
+ def run_ps(cmd, options = {})
49
+ cmd = "echo #{cmd}" if config[:dry_run]
50
+ debug('Preparing to run: ')
51
+ debug(" #{cmd}")
52
+ wrapped_command = wrap_command cmd
53
+ execute_command wrapped_command, options
54
+ end
55
+
56
+ # rubocop:disable Metrics/AbcSize
57
+ def execute_command(cmd, options = {})
58
+ debug("#Local Command BEGIN (#{cmd})")
59
+ sh = Mixlib::ShellOut.new(cmd, options)
60
+ sh.run_command
61
+ debug("Local Command END #{Util.duration(sh.execution_time)}")
62
+ fail "Failed: #{sh.stderr}" if sh.error?
63
+ JSON.parse(sh.stdout) if sh.stdout.length > 2
64
+ end
65
+ # rubocop:enable Metrics/AbcSize
66
+
67
+ def new_differencing_disk_ps
68
+ <<-DIFF
69
+
70
+ New-DifferencingDisk -Path "#{differencing_disk_path}" -ParentPath "#{parent_vhd_path}"
71
+ DIFF
72
+ end
73
+
74
+ def ensure_vm_running_ps
75
+ <<-RUNNING
76
+
77
+ Assert-VmRunning -ID "#{@state[:id]}" | ConvertTo-Json
78
+ RUNNING
79
+ end
80
+
81
+ # rubocop:disable Metrics/MethodLength
82
+ def new_vm_ps
83
+ <<-NEWVM
84
+
85
+ $NewVMParams = @{
86
+ Generation = 1
87
+ MemoryStartupBytes = #{config[:memory_startup_bytes]}
88
+ Name = "#{instance.name}"
89
+ Path = "#{kitchen_vm_path}"
90
+ VHDPath = "#{differencing_disk_path}"
91
+ SwitchName = "#{config[:vm_switch]}"
92
+ ProcessorCount = #{config[:processor_count]}
93
+ }
94
+ New-KitchenVM @NewVMParams | ConvertTo-Json
95
+ NEWVM
96
+ end
97
+ # rubocop:enable Metrics/MethodLength
98
+
99
+ def vm_details_ps
100
+ <<-DETAILS
101
+
102
+ Get-VmDetail -id "#{@state[:id]}" | ConvertTo-Json
103
+ DETAILS
104
+ end
105
+
106
+ def delete_vm_ps
107
+ <<-REMOVE
108
+
109
+ $null = Get-VM -ID "#{@state[:id]}" |
110
+ Stop-VM -Force -TurnOff -PassThru |
111
+ Remove-VM -Force
112
+ REMOVE
113
+ end
114
+
115
+ def set_vm_ipaddress_ps
116
+ <<-VMIP
117
+
118
+ (Get-VM -id "#{@state[:id]}").NetworkAdapters |
119
+ Set-VMNetworkConfiguration -ipaddress "#{config[:ip_address]}" -subnet 255.255.255.0 |
120
+ ConvertTo-Json
121
+ VMIP
122
+ end
123
+
124
+ def vm_default_switch_ps
125
+ <<-VMSWITCH
126
+ Get-DefaultVMSwitch | ConvertTo-Json
127
+ VMSWITCH
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +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
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, 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
+ gem "minitest"
20
+ gem "minitest-stub-const"
21
+
22
+ if ENV["CODECLIMATE_REPO_TOKEN"]
23
+ require "codeclimate-test-reporter"
24
+ CodeClimate::TestReporter.start
25
+ elsif ENV["COVERAGE"]
26
+ require "simplecov"
27
+ SimpleCov.profiles.define "gem" do
28
+ command_name "Specs"
29
+
30
+ add_filter ".gem/"
31
+ add_filter "/spec/"
32
+ add_filter "/lib/vendor/"
33
+
34
+ add_group "Libraries", "/lib/"
35
+ end
36
+ SimpleCov.start "gem"
37
+ end
38
+
39
+ require 'minitest'
40
+ require 'minitest/stub_const'
41
+ require "minitest/autorun"
42
+ require "mocha/setup"
43
+ require "tempfile"
@@ -0,0 +1,2 @@
1
+ . $PSScriptRoot\..\..\support\hyperv.ps1
2
+
@@ -0,0 +1,149 @@
1
+
2
+ $ProgressPreference = "SilentlyContinue"
3
+
4
+ <<<<<<< HEAD:lib/kitchen/support/hyperv.ps1
5
+ function new-differencingdisk
6
+ =======
7
+ function New-DifferencingDisk
8
+ >>>>>>> rubocop'd and some tests:support/hyperv.ps1
9
+ {
10
+ [cmdletbinding()]
11
+ param ([string[]]$Path, [string]$ParentPath)
12
+ if (-not (test-path $Path))
13
+ {
14
+ $null = new-vhd @psboundparameters -Differencing
15
+ }
16
+ }
17
+
18
+ function Assert-VmRunning
19
+ {
20
+ [cmdletbinding()]
21
+ param([string]$Id)
22
+
23
+ if ([string]::IsNullOrEmpty($ID))
24
+ {
25
+ $Output = [pscustomobject]@{Name = '';State =''}
26
+ }
27
+ else
28
+ {
29
+ $Output = Get-VM -Id $ID |
30
+ foreach {
31
+ if ($_.State -notlike 'Running')
32
+ {
33
+ $_ | start-vm -passthru
34
+ }
35
+ else
36
+ {
37
+ $_
38
+ }
39
+ } |
40
+ select Name, Id, State
41
+ }
42
+ $output
43
+ }
44
+
45
+ function New-KitchenVM
46
+ {
47
+ [cmdletbinding()]
48
+ param (
49
+ $Generation = 1,
50
+ $MemoryStartupBytes,
51
+ $Name,
52
+ $Path,
53
+ $VHDPath,
54
+ $SwitchName,
55
+ $ProcessorCount
56
+ )
57
+ $null = $psboundparameters.remove('ProcessorCount')
58
+ new-vm @psboundparameters |
59
+ Set-Vm -ProcessorCount $ProcessorCount -passthru |
60
+ Start-Vm -passthru |
61
+ foreach {
62
+ $vm = $_
63
+ do {
64
+ start-sleep -seconds 2
65
+ } while ($vm.state -notlike 'Running')
66
+ $vm
67
+ } |
68
+ select Name, Id, State
69
+ }
70
+
71
+ function Get-VmIP($vm)
72
+ {
73
+ $vm.networkadapters.ipaddresses |
74
+ where {$_ -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'} |
75
+ select -first 1
76
+ }
77
+
78
+ Function Set-VMNetworkConfiguration
79
+ {
80
+ [CmdletBinding()]
81
+ Param (
82
+ [parameter(valuefrompipeline)]
83
+ [object]$NetworkAdapter,
84
+ [String[]]$IPAddress=@(),
85
+ [String[]]$Subnet=@()
86
+ )
87
+
88
+ $VM = Get-WmiObject -Namespace 'root\virtualization\v2' -Class 'Msvm_ComputerSystem' | Where-Object { $_.ElementName -eq $NetworkAdapter.VMName }
89
+ $VMSettings = $vm.GetRelated('Msvm_VirtualSystemSettingData') | Where-Object { $_.VirtualSystemType -eq 'Microsoft:Hyper-V:System:Realized' }
90
+ $VMNetAdapters = $VMSettings.GetRelated('Msvm_SyntheticEthernetPortSettingData')
91
+
92
+ $NetworkSettings = @()
93
+ foreach ($NetAdapter in $VMNetAdapters) {
94
+ if ($NetAdapter.Address -eq $NetworkAdapter.MacAddress) {
95
+ $NetworkSettings = $NetworkSettings + $NetAdapter.GetRelated("Msvm_GuestNetworkAdapterConfiguration")
96
+ }
97
+ }
98
+
99
+ $NetworkSettings[0].IPAddresses = $IPAddress
100
+ $NetworkSettings[0].Subnets = $Subnet
101
+ $NetworkSettings[0].ProtocolIFType = 4096
102
+ $NetworkSettings[0].DHCPEnabled = $false
103
+
104
+
105
+ $Service = Get-WmiObject -Class "Msvm_VirtualSystemManagementService" -Namespace "root\virtualization\v2"
106
+ $setIP = $Service.SetGuestNetworkAdapterConfiguration($VM, $NetworkSettings[0].GetText(1))
107
+
108
+ if ($setip.ReturnValue -eq 4096) {
109
+ $job=[WMI]$setip.job
110
+
111
+ while ($job.JobState -eq 3 -or $job.JobState -eq 4) {
112
+ start-sleep 1
113
+ $job=[WMI]$setip.job
114
+ }
115
+
116
+ if ($job.JobState -ne 7) {
117
+ $job.GetError()
118
+ }
119
+ }
120
+ (Get-VM -id $NetworkAdapter.VmId).NetworkAdapter | select Name, IpAddress
121
+ }
122
+
123
+ function Get-VmDetail
124
+ {
125
+ [cmdletbinding()]
126
+ param($Id)
127
+
128
+ get-vm -id $Id |
129
+ foreach {
130
+ $vm = $_
131
+ do {
132
+ start-sleep -seconds 1
133
+ } while (-not (Get-VmIP $vm))
134
+
135
+ [pscustomobject]@{
136
+ Name = $vm.name
137
+ Id = $vm.ID
138
+ IpAddress = (Get-VmIP $vm)
139
+ }
140
+ }
141
+ <<<<<<< HEAD:lib/kitchen/support/hyperv.ps1
142
+ =======
143
+ }
144
+
145
+ function Get-DefaultVMSwitch
146
+ {
147
+ Get-VMSwitch | Select -First 1
148
+ >>>>>>> rubocop'd and some tests:support/hyperv.ps1
149
+ }
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kitchen-hyperv
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Steven Murawski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-kitchen
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.4'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.4'
69
+ description: Hyper-V Driver for Test-Kitchen
70
+ email:
71
+ - steven.murawski@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".cane"
77
+ - ".gitignore"
78
+ - ".rubocop.yml"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - kitchen-hyperv.gemspec
84
+ - lib/kitchen/driver/hyperv.rb
85
+ - lib/kitchen/driver/hyperv_version.rb
86
+ - lib/kitchen/driver/powershell.rb
87
+ - spec/kitchen/driver/hyperv_spec.rb
88
+ - spec/spec_helper.rb
89
+ - spec/support/hyperv.Tests.ps1
90
+ - support/hyperv.ps1
91
+ homepage: ''
92
+ licenses:
93
+ - Apache 2
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.4.4
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Hyper-V Driver for Test-Kitchen
115
+ test_files:
116
+ - spec/kitchen/driver/hyperv_spec.rb
117
+ - spec/spec_helper.rb
118
+ - spec/support/hyperv.Tests.ps1
119
+ has_rdoc: