kitchen-hyperv 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f95a36b67d309f5558ce09e652f1b2e1dae920b3e4f7dd87ef42e874d0d70b89
4
- data.tar.gz: d226329f6c724cf74adce0422276f0b4346e57cd7f1964e42f24a7c2a59c88aa
3
+ metadata.gz: 4b55ec98fe0feae9159324c3c4d4aba29d3c765e02ce8119a8018d626c77f033
4
+ data.tar.gz: 0a97571d04c65942c06a8f20d7efb20088be51b793481dd11ece2c929d56faf8
5
5
  SHA512:
6
- metadata.gz: 3a71c5e7ae19eadf9bdacd4fa616365e162f944c36bc14b3091cdabc71ca845062d900790d79455a1b07fd68b159aacc85b5ab861b798e14f82ad8d230129273
7
- data.tar.gz: eac21386957db5983da0411ad14d11c5b7f2bbf38406b57fd78c56ca05c32e137b62be9e7e8ba0638eaeaab633b52a1b323d339d4cad743735a4291172384d4d
6
+ metadata.gz: 4579cd9d4e532a42092d1cf50bf7d6d74c9977f848bcf4ee83871378d82f843d2b13127ad0a0814d5fabd036ac76117a7fc02d478223b80fe92f6aa005ab817f
7
+ data.tar.gz: 53278bdf748446af609e584df729fde28fe60db46afe6a747b9186f10399d4d1a39d8fee3fdde23d234ee2d988a5eb3081315330c93a84bead84d7e64ebf84c3
data/Gemfile ADDED
@@ -0,0 +1,29 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in kitchen-pester.gemspec
4
+ gemspec
5
+
6
+ group :integration do
7
+ gem "berkshelf"
8
+ gem "kitchen-inspec"
9
+ gem "kitchen-dokken"
10
+ gem "kitchen-vagrant"
11
+ end
12
+
13
+ group :changelog do
14
+ gem "github_changelog_generator", "1.15.0"
15
+ end
16
+
17
+ group :debug do
18
+ gem "pry"
19
+ gem "pry-byebug"
20
+ gem "pry-stack_explorer"
21
+ end
22
+
23
+ group :chefstyle do
24
+ gem "chefstyle"
25
+ end
26
+
27
+ group :docs do
28
+ gem "yard"
29
+ end
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015 Steven Murawski
1
+ Copyright (c) 2020 Steven Murawski
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
@@ -0,0 +1,50 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "bundler/gem_tasks"
4
+ require "kitchen/driver/hyperv_version"
5
+
6
+ require "rake/testtask"
7
+ Rake::TestTask.new(:unit) do |t|
8
+ t.libs.push "lib"
9
+ t.test_files = FileList["spec/**/*_spec.rb"]
10
+ t.verbose = true
11
+ end
12
+
13
+ desc "Run all test suites"
14
+ task test: :unit
15
+
16
+ begin
17
+ require "chefstyle"
18
+ require "rubocop/rake_task"
19
+ RuboCop::RakeTask.new(:style) do |task|
20
+ task.options += ["--display-cop-names", "--no-color"]
21
+ end
22
+ rescue LoadError
23
+ puts "chefstyle is not available. (sudo) gem install chefstyle to do style checking."
24
+ end
25
+
26
+ desc "Run all quality tasks"
27
+ task quality: :style
28
+
29
+ begin
30
+ require "yard"
31
+ YARD::Rake::YardocTask.new
32
+ rescue LoadError
33
+ puts "yard is not available. (sudo) gem install yard to generate yard documentation."
34
+ end
35
+
36
+ task default: %i{test quality}
37
+ begin
38
+ require "github_changelog_generator/task"
39
+
40
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
41
+ config.future_release = "v#{Kitchen::Driver::HYPERV_VERSION}"
42
+ config.issues = false
43
+ config.pulls = true
44
+ config.user = "test-kitchen"
45
+ config.project = "kitchen-hyperv"
46
+ end
47
+ rescue LoadError
48
+ puts "github_changelog_generator is not available. " \
49
+ "gem install github_changelog_generator to generate changelogs"
50
+ end
@@ -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 = "https://github.com/test-kitchen/kitchen-hyperv"
15
+ spec.license = "Apache-2.0"
16
+
17
+ spec.files = %w{LICENSE kitchen-hyperv.gemspec Gemfile Rakefile support/hyperv.ps1}
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "minitest", "~> 5.3", "< 5.15"
23
+ spec.add_development_dependency "minitest-stub-const"
24
+ spec.add_development_dependency "mocha", "~> 1.1"
25
+
26
+ spec.add_dependency "test-kitchen", ">= 1.4", "< 3"
27
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-hyperv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Murawski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-20 00:00:00.000000000 Z
11
+ date: 2020-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,89 +39,25 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: pry
42
+ name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
45
+ - - "~>"
53
46
  - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: cane
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: finstyle
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: yard
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
47
+ version: '5.3'
48
+ - - "<"
102
49
  - !ruby/object:Gem::Version
103
- version: '0'
50
+ version: '5.15'
104
51
  type: :development
105
52
  prerelease: false
106
53
  version_requirements: !ruby/object:Gem::Requirement
107
54
  requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: countloc
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
55
+ - - "~>"
116
56
  - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
57
+ version: '5.3'
58
+ - - "<"
123
59
  - !ruby/object:Gem::Version
124
- version: '0'
60
+ version: '5.15'
125
61
  - !ruby/object:Gem::Dependency
126
62
  name: minitest-stub-const
127
63
  requirement: !ruby/object:Gem::Requirement
@@ -140,16 +76,16 @@ dependencies:
140
76
  name: mocha
141
77
  requirement: !ruby/object:Gem::Requirement
142
78
  requirements:
143
- - - ">="
79
+ - - "~>"
144
80
  - !ruby/object:Gem::Version
145
- version: '0'
81
+ version: '1.1'
146
82
  type: :development
147
83
  prerelease: false
148
84
  version_requirements: !ruby/object:Gem::Requirement
149
85
  requirements:
150
- - - ">="
86
+ - - "~>"
151
87
  - !ruby/object:Gem::Version
152
- version: '0'
88
+ version: '1.1'
153
89
  - !ruby/object:Gem::Dependency
154
90
  name: test-kitchen
155
91
  requirement: !ruby/object:Gem::Requirement
@@ -177,10 +113,10 @@ executables: []
177
113
  extensions: []
178
114
  extra_rdoc_files: []
179
115
  files:
116
+ - Gemfile
180
117
  - LICENSE
181
- - lib/kitchen/driver/hyperv.rb
182
- - lib/kitchen/driver/hyperv_version.rb
183
- - lib/kitchen/driver/powershell.rb
118
+ - Rakefile
119
+ - kitchen-hyperv.gemspec
184
120
  - support/hyperv.ps1
185
121
  homepage: https://github.com/test-kitchen/kitchen-hyperv
186
122
  licenses:
@@ -201,8 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
137
  - !ruby/object:Gem::Version
202
138
  version: '0'
203
139
  requirements: []
204
- rubyforge_project:
205
- rubygems_version: 2.7.6
140
+ rubygems_version: 3.1.2
206
141
  signing_key:
207
142
  specification_version: 4
208
143
  summary: Hyper-V Driver for Test-Kitchen
@@ -1,279 +0,0 @@
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 :dynamic_memory_min_bytes, 536_870_912
41
- default_config :dynamic_memory_max_bytes, 2_147_483_648
42
- default_config :dynamic_memory, false
43
- default_config :processor_count, 2
44
- default_config :ip_address
45
- default_config :gateway
46
- default_config :dns_servers
47
- default_config :subnet, '255.255.255.0'
48
- default_config :vm_switch
49
- default_config :vm_vlan_id
50
- default_config :iso_path
51
- default_config :boot_iso_path
52
- default_config :enable_guest_services
53
- default_config :vm_note
54
- default_config :resize_vhd
55
- default_config :additional_disks
56
- default_config :vm_generation, 1
57
- default_config :disable_secureboot, false
58
- default_config :static_mac_address
59
- default_config :disk_type do |driver|
60
- File.extname(driver[:parent_vhd_name])
61
- end
62
-
63
- include Kitchen::Driver::PowerShellScripts
64
-
65
- def create(state)
66
- @state = state
67
- validate_vm_settings
68
- create_new_differencing_disk
69
- create_additional_disks
70
- create_virtual_machine
71
- set_virtual_machine_note
72
- update_state
73
- mount_virtual_machine_iso
74
- instance.transport.connection(@state).wait_until_ready
75
- copy_vm_files
76
- info("Hyper-V instance #{instance.to_str} created.")
77
- end
78
-
79
- def destroy(state)
80
- @state = state
81
- if differencing_disk_exists && !vm_exists_silent
82
- remove_differencing_disk
83
- end
84
- return unless vm_exists
85
- instance.transport.connection(state).close
86
- remove_virtual_machine
87
- remove_differencing_disk
88
- remove_additional_disks
89
- info("The Hyper-V instance #{instance.to_str} has been removed.")
90
- state.delete(:id)
91
- end
92
-
93
- private
94
-
95
- def validate_vm_settings
96
- raise "Missing parent_vhd_folder" unless vhd_folder?
97
- raise "Missing parent_vhd_name" unless vhd?
98
- if config[:dynamic_memory]
99
- startup_bytes = config[:memory_startup_bytes]
100
- min = config[:dynamic_memory_min_bytes]
101
- max = config[:dynamic_memory_max_bytes]
102
- memory_valid = startup_bytes.between?(min, max)
103
- warning = "memory_startup_bytes (#{startup_bytes}) must" \
104
- " fall within dynamic memory range (#{min}-#{max})"
105
- raise warning unless memory_valid
106
- end
107
- config[:vm_switch] = vm_switch
108
- if config[:vm_vlan_id]
109
- vm_vlan_id = config[:vm_vlan_id]
110
- vm_vlan_id_min = 1
111
- vm_vlan_id_max = 4094
112
- vm_vlan_id_valid = vm_vlan_id.between?(vm_vlan_id_min, vm_vlan_id_max)
113
- vm_vlan_id_warning = "vm_vlan_id (#{vm_vlan_id}) must be a valid 802.1Q" \
114
- " VLAN ID between (#{vm_vlan_id_min}-#{vm_vlan_id_max})"
115
- raise vm_vlan_id_warning unless vm_vlan_id_valid
116
- end
117
- end
118
-
119
- def create_new_differencing_disk
120
- info("Creating differencing disk for #{instance.name}.")
121
- run_ps new_differencing_disk_ps
122
- info("Created differencing disk for #{instance.name}.")
123
- set_new_vhd_size
124
- end
125
-
126
- def create_additional_disks
127
- return if config[:additional_disks].nil?
128
- @additional_disk_objects = []
129
- config[:additional_disks].each do |additional_disk|
130
- raise "Missing name for additional disk" unless additional_disk[:name]
131
- disk_type = additional_disk[:type] || config[:disk_type]
132
- disk_path = additional_disk_path(additional_disk[:name], disk_type)
133
- raise "Additional disk file already exists: #{disk_path}" unless !File.exist?(disk_path)
134
- disk_size = additional_disk[:size_gb] || 5
135
- info("Creating additional disk #{additional_disk[:name]} for #{instance.name}.")
136
- run_ps new_additional_disk_ps(disk_path, disk_size)
137
- info("Created additional disk #{additional_disk[:name]} for #{instance.name}.")
138
- @additional_disk_objects.push(disk_path)
139
- end
140
- end
141
-
142
- def vm_switch
143
- default_switch_object = run_ps vm_default_switch_ps
144
- if default_switch_object.nil? ||
145
- !default_switch_object.key?('Name') ||
146
- default_switch_object['Name'].empty?
147
- raise "Failed to find a default VM Switch."
148
- end
149
- default_switch_object['Name']
150
- end
151
-
152
- def create_virtual_machine
153
- return if vm_exists
154
- info("Creating virtual machine for #{instance.name}.")
155
- new_vm_object = run_ps new_vm_ps
156
- @state[:id] = new_vm_object['Id']
157
- info("Created virtual machine for #{instance.name}.")
158
- end
159
-
160
- def update_state
161
- vm_details
162
- @state[:id] = @vm['Id']
163
- @state[:hostname] = @vm['IpAddress']
164
- @state[:vm_name] = @vm['Name']
165
- end
166
-
167
- def vm_details
168
- run_ps set_vm_ipaddress_ps if config[:ip_address]
169
- @vm = run_ps vm_details_ps
170
- end
171
-
172
- def mount_virtual_machine_iso
173
- return unless config[:iso_path]
174
- info("Mounting #{config[:iso_path]}")
175
- run_ps mount_vm_iso
176
- info("Done mounting #{config[:iso_path]}")
177
- end
178
-
179
- def set_new_vhd_size
180
- return unless config[:resize_vhd]
181
- info("Resizing differencing disk for #{instance.name}.")
182
- run_ps resize_vhd
183
- info("Resized differencing disk for #{instance.name}.")
184
- end
185
-
186
- def set_virtual_machine_note
187
- return unless config[:vm_note]
188
- info("Adding note to VM: '#{config[:vm_note]}'")
189
- run_ps set_vm_note
190
- end
191
-
192
- def copy_vm_files
193
- return if config[:copy_vm_files].nil?
194
- info("Copying files to virtual machine")
195
- config[:copy_vm_files].each do |file_info|
196
- run_ps copy_vm_file_ps(file_info[:source], file_info[:dest])
197
- end
198
- info("Copied files to virtual machine")
199
- end
200
-
201
- def vm_exists
202
- info('Checking for existing virtual machine.')
203
- return false unless @state.key?(:id) && !@state[:id].nil?
204
- existing_vm = run_ps ensure_vm_running_ps
205
- return false if existing_vm.nil? || existing_vm['Id'].nil?
206
- info("Found an exising VM with an ID: #{existing_vm['Id']}")
207
- true
208
- end
209
-
210
- # Used in testing if a stale diff disk exists. Silent so the output doesn't
211
- # appear twice on the kitchen destroy command for the second check for vm_exists
212
- def vm_exists_silent
213
- return false unless @state.key?(:id) && !@state[:id].nil?
214
- existing_vm = run_ps ensure_vm_running_ps
215
- return false if existing_vm.nil? || existing_vm['Id'].nil?
216
- true
217
- end
218
-
219
- def differencing_disk_exists
220
- return unless File.exist? differencing_disk_path
221
- true
222
- end
223
-
224
- def remove_virtual_machine
225
- info("Deleting virtual machine for #{instance.name}")
226
- run_ps delete_vm_ps
227
- info("Deleted virtual machine for #{instance.name}")
228
- end
229
-
230
- def remove_differencing_disk
231
- info("Removing the differencing disk for #{instance.name}.")
232
- FileUtils.rm(differencing_disk_path)
233
- info("Removed the differencing disk for #{instance.name}.")
234
- end
235
-
236
- def remove_additional_disks
237
- return if config[:additional_disks].nil?
238
- config[:additional_disks].each do |additional_disk|
239
- raise "Missing name for additional disk" unless additional_disk[:name]
240
- disk_type = additional_disk[:type] || config[:disk_type]
241
- disk_path = additional_disk_path(additional_disk[:name], disk_type)
242
- if File.exist?(disk_path)
243
- info("Removing additional disk #{additional_disk[:name]} for #{instance.name}.")
244
- FileUtils.rm(disk_path)
245
- info("Removed additional disk #{additional_disk[:name]} for #{instance.name}.")
246
- end
247
- end
248
- end
249
-
250
- def kitchen_vm_path
251
- @kitchen_vm_path ||= File.join(config[:kitchen_root], ".kitchen/#{instance.name}")
252
- end
253
-
254
- def boot_iso_path
255
- @boot_iso_path ||= config[:boot_iso_path]
256
- end
257
-
258
- def differencing_disk_path
259
- @differencing_disk_path ||= File.join(kitchen_vm_path, "diff" + "#{config[:disk_type]}")
260
- end
261
-
262
- def additional_disk_path(disk_name, disk_type)
263
- File.join(kitchen_vm_path, disk_name + disk_type)
264
- end
265
-
266
- def parent_vhd_path
267
- @parent_vhd_path ||= File.join(config[:parent_vhd_folder], config[:parent_vhd_name])
268
- end
269
-
270
- def vhd_folder?
271
- config[:parent_vhd_folder] && Dir.exist?(config[:parent_vhd_folder])
272
- end
273
-
274
- def vhd?
275
- config[:parent_vhd_name] && File.exist?(parent_vhd_path)
276
- end
277
- end
278
- end
279
- end
@@ -1,22 +0,0 @@
1
- #
2
- # Author:: Steven Murawski <smurawski@chef.io>
3
- # Copyright:: Copyright (c) 2015-2018 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.5.3'.freeze
21
- end
22
- end
@@ -1,240 +0,0 @@
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
- ruby_arch = ['foo'].pack('p').size == 4 ? 32 : 64
33
- os_arch == 'AMD64' && ruby_arch == 64
34
- end
35
-
36
- def is_32bit?
37
- os_arch = ENV['PROCESSOR_ARCHITEW6432'] || ENV['PROCESSOR_ARCHITECTURE']
38
- ruby_arch = ['foo'].pack('p').size == 4 ? 32 : 64
39
- os_arch != 'AMD64' && ruby_arch == 32
40
- end
41
-
42
- def powershell_64_bit
43
- if is_64bit? || is_32bit?
44
- 'c:\windows\system32\windowspowershell\v1.0\powershell.exe'
45
- else
46
- 'c:\windows\sysnative\windowspowershell\v1.0\powershell.exe'
47
- end
48
- end
49
-
50
- def wrap_command(script)
51
- base_script_path = File.join(File.dirname(__FILE__), '/../../../support/hyperv.ps1')
52
- debug("Loading functions from #{base_script_path}")
53
- new_script = [ ". #{base_script_path}", "#{script}" ].join(";\n")
54
- debug("Wrapped script: #{new_script}")
55
- "#{powershell_64_bit} -noprofile -executionpolicy bypass" \
56
- " -encodedcommand #{encode_command new_script} -outputformat Text"
57
- end
58
-
59
- # Convenience method to run a powershell command locally.
60
- #
61
- # @param cmd [String] command to run locally
62
- # @param options [Hash] options hash
63
- # @see Kitchen::ShellOut.run_command
64
- # @api private
65
- def run_ps(cmd, options = {})
66
- cmd = "echo #{cmd}" if config[:dry_run]
67
- debug('Preparing to run: ')
68
- debug(" #{cmd}")
69
- wrapped_command = wrap_command cmd
70
- execute_command wrapped_command, options
71
- end
72
-
73
- def execute_command(cmd, options = {})
74
- debug("#Local Command BEGIN (#{cmd})")
75
- sh = Mixlib::ShellOut.new(cmd, options)
76
- sh.run_command
77
- debug("Local Command END #{Util.duration(sh.execution_time)}")
78
- raise "Failed: #{sh.stderr}" if sh.error?
79
- stdout = sanitize_stdout(sh.stdout)
80
- JSON.parse(stdout) if stdout.length > 2
81
- end
82
-
83
- def sanitize_stdout(stdout)
84
- stdout.split("\n").select { |s| !s.start_with?("PS") }.join("\n")
85
- end
86
-
87
- def new_differencing_disk_ps
88
- <<-DIFF
89
-
90
- New-DifferencingDisk -Path "#{differencing_disk_path}" -ParentPath "#{parent_vhd_path}"
91
- DIFF
92
- end
93
-
94
- def new_additional_disk_ps(disk_path, disk_size)
95
- <<-ADDDISK
96
-
97
- New-VHD -Path "#{disk_path}" -SizeBytes #{disk_size}GB | Out-Null
98
- ADDDISK
99
- end
100
-
101
- def ensure_vm_running_ps
102
- <<-RUNNING
103
-
104
- Assert-VmRunning -ID "#{@state[:id]}" | ConvertTo-Json
105
- RUNNING
106
- end
107
-
108
- def new_vm_ps
109
- <<-NEWVM
110
-
111
- $NewVMParams = @{
112
- Generation = #{config[:vm_generation]}
113
- DisableSecureBoot = "#{config[:disable_secureboot]}"
114
- MemoryStartupBytes = #{config[:memory_startup_bytes]}
115
- StaticMacAddress = "#{config[:static_mac_address]}"
116
- Name = "#{instance.name}"
117
- Path = "#{kitchen_vm_path}"
118
- VHDPath = "#{differencing_disk_path}"
119
- SwitchName = "#{config[:vm_switch]}"
120
- VlanId = #{config[:vm_vlan_id] || '$null'}
121
- ProcessorCount = #{config[:processor_count]}
122
- UseDynamicMemory = "#{config[:dynamic_memory]}"
123
- DynamicMemoryMinBytes = #{config[:dynamic_memory_min_bytes]}
124
- DynamicMemoryMaxBytes = #{config[:dynamic_memory_max_bytes]}
125
- boot_iso_path = "#{boot_iso_path}"
126
- EnableGuestServices = "#{config[:enable_guest_services]}"
127
- #{additional_disks}
128
- }
129
- New-KitchenVM @NewVMParams | ConvertTo-Json
130
- NEWVM
131
- end
132
-
133
- def additional_disks
134
- return if config[:additional_disks].nil?
135
- <<-EOH
136
- AdditionalDisks = @("#{@additional_disk_objects.join('","')}")
137
- EOH
138
- end
139
-
140
- def vm_details_ps
141
- <<-DETAILS
142
-
143
- Get-VmDetail -id "#{@state[:id]}" | ConvertTo-Json
144
- DETAILS
145
- end
146
-
147
- def delete_vm_ps
148
- <<-REMOVE
149
-
150
- $null = Get-VM -ID "#{@state[:id]}" |
151
- Stop-VM -Force -TurnOff -PassThru |
152
- Remove-VM -Force
153
- REMOVE
154
- end
155
-
156
- def set_vm_ipaddress_ps
157
- <<-VMIP
158
-
159
- while ((Get-VM -id "#{@state[:id]}").NetworkAdapters[0].Status -ne 'Ok'){
160
- start-sleep 10
161
- }
162
-
163
- (Get-VM -id "#{@state[:id]}").NetworkAdapters |
164
- Set-VMNetworkConfiguration -ipaddress "#{config[:ip_address]}" `
165
- -subnet "#{config[:subnet]}" `
166
- -gateway "#{config[:gateway]}" `
167
- -dnsservers #{ruby_array_to_ps_array(config[:dns_servers])} |
168
- ConvertTo-Json
169
- VMIP
170
- end
171
-
172
- def vm_default_switch_ps
173
- <<-VMSWITCH
174
- Get-DefaultVMSwitch #{config[:vm_switch]} | ConvertTo-Json
175
- VMSWITCH
176
- end
177
-
178
- def mount_vm_iso
179
- <<-MOUNTISO
180
- mount-vmiso -id "#{@state[:id]}" -Path #{config[:iso_path]}
181
- MOUNTISO
182
- end
183
-
184
- def resize_vhd
185
- <<-VMNOTE
186
- Resize-VHD -Path "#{parent_vhd_path}" -SizeBytes #{config[:resize_vhd]}
187
- VMNOTE
188
- end
189
-
190
- def set_vm_note
191
- <<-VMNOTE
192
- Set-VM -Name (Get-VM | Where-Object{ $_.ID -eq "#{@state[:id]}"}).Name -Note "#{config[:vm_note]}"
193
- VMNOTE
194
- end
195
-
196
- def copy_vm_file_ps(source, dest)
197
- <<-FILECOPY
198
- Function CopyFile ($VM, [string]$SourcePath, [string]$DestPath) {
199
- $p = @{ CreateFullPath = $true ; FileSource = 'Host'; Force = $true }
200
- $VM |
201
- Copy-VMFile -SourcePath $SourcePath -DestinationPath $DestPath @p
202
- }
203
-
204
- $sourceLocation = '#{source}'
205
- $destinationLocation = '#{dest}'
206
- $vmId = '#{@state[:id]}'
207
- If (Test-Path $sourceLocation) {
208
- $vm = Get-VM -ID $vmId
209
- $service = 'Guest Service Interface'
210
-
211
- If ((Get-VMIntegrationService -Name $service -VM $vm).Enabled -ne $true) {
212
- Enable-VMIntegrationService -Name $service -VM $vm
213
- Start-Sleep -Seconds 3
214
- }
215
-
216
- If ((Get-Item $sourceLocation) -is [System.IO.DirectoryInfo]) {
217
- ForEach ($item in (Get-ChildItem -Path $sourceLocation -File)) {
218
- $destFullPath = (Join-Path $destinationLocation $item.Name)
219
- CopyFile $vm $item.FullName $destFullPath
220
- }
221
- }
222
- Else {
223
- CopyFile $vm $sourceLocation $destinationLocation
224
- }
225
- }
226
- else {
227
- Write-Error "Source file path does not exist: $sourceLocation"
228
- }
229
- FILECOPY
230
- end
231
-
232
- private
233
-
234
- def ruby_array_to_ps_array(list)
235
- return "@()" if list.nil? || list.empty?
236
- list.to_s.tr('[]','()').prepend('@')
237
- end
238
- end
239
- end
240
- end