kitchen-vmm 0.1.1
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 +15 -0
- data/.cane +2 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +14 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +228 -0
- data/Rakefile +52 -0
- data/kitchen-vmm.gemspec +31 -0
- data/lib/kitchen/driver/vmm.rb +102 -0
- data/lib/kitchen/driver/vmm_utils.rb +84 -0
- data/lib/kitchen/driver/vmm_version.rb +7 -0
- data/support/delete_vm.ps1 +35 -0
- data/support/import_vm.ps1 +165 -0
- data/support/utils/manage_credentials.ps1 +26 -0
- data/support/utils/manage_trusted_hosts.ps1 +28 -0
- data/support/utils/vmm_executor.ps1 +43 -0
- data/support/utils/write_messages.ps1 +20 -0
- metadata +175 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
YjJiM2EyYmI2YjE1MTgzYmRkM2JkNWY2NjVkMDlmNTM5OTc2OTQzNw==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
OTgxMzBkZmYyMWQ2MDM1ZTc1N2I3NTAzOWE1MTQ5NTIyMzViYjUxYg==
|
|
7
|
+
SHA512:
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
YTNkMzUyOTFjODM4MmVlMjYzZDY4MjlmNmE1YjFjMWYyYTVmMDhjOTk3NjUx
|
|
10
|
+
YWU2NjcwOTJiMDBmYjhlMmZhYjgzMjQzN2ZkMTVhOGRhODFmOTAxNGE2ZjQz
|
|
11
|
+
OTlkZTVhY2E3ODdjMGFlNWFjYzE5MWVmYmM2MmVmZTllNmYxM2E=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
MWI1M2NmNmE0ODQ4OWM5NzM4NmQwM2QyY2UyNzQ0YjZkNjNiM2MzNGRkMzlm
|
|
14
|
+
NWI0MzA1ZGFjNzM4ZDQ4NjdjYjM1Nzc3NDA4NzU1MTM2YTg1MjQ3YTk3MWYw
|
|
15
|
+
MzBkZDViNDk4NTUwMDkxYTY5YjgwMjM0NjliNTQ5ZDRiZWE0NmY=
|
data/.cane
ADDED
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
language: ruby
|
|
2
|
+
rvm:
|
|
3
|
+
- 2.0.0
|
|
4
|
+
bundler_args: --without doc guard --jobs 7
|
|
5
|
+
script: bundle exec rake build
|
|
6
|
+
deploy:
|
|
7
|
+
provider: rubygems
|
|
8
|
+
api_key:
|
|
9
|
+
secure: j4qKRcVgSpULZXlSyGSt5WmHTCazXmH1uNNcfpUioIMOZkceh7CWspMps3FWSPIbINqLoSfzK4hJbUcnoqSZ79ho8NBbcNvqTIJXxFoYbhTgTlUwdNovgto4WmqwEYDSWp+ShryLqLkRY6WGFFUu2ve4eRum1akQcaxkQC1vjcKsQXUDFCY8qW6unsFQivV3YMX+baTHcOpB/YyEqwkHq5N6173U7eM0Rmu5F39PIKovb/wBLYomuV7vDH7kGvxernVguUNC0azgLe9j1lTQT1bkmn78pCwb9PYeW8xkkTWW0DSZf5n9TSG1jhECGUkmeNJbMBpFioApvYfEoyKq58vPPJ5eyjz5rvOshfwIefzOgdS6RoHMfWzA1StzPj3iQwnhow70vhU4vZJ3HI8pTyCv2szhItdBL6Z4Hc90KrXKX6HaBuRHw2wv48+tvoKU3hnguswrYer7nSOSfTKMxMHTNoevlieRNX/3Suh7/8laV1eobYRv7yUSkGpFdeT+8FqlSBJVG/A6fyct/DqOhMLV48y8Rc2pqDTdVJ638LAwdcUhvvqYe04i5Zxr7Qa0Wi89bHLRhR0R3o5pvgVAJt3wjVKKHz0kuN1cbP60B4d/Xmp8lQRL0MADAVfaiSJvI/vDMCt48/qBzRe4IQBMwI4iMCwDZ56DTyXKaGO08x8=
|
|
10
|
+
gem: kitchen-vmm
|
|
11
|
+
on:
|
|
12
|
+
tags: true
|
|
13
|
+
repo: jarig/kitchen-vmm
|
|
14
|
+
all_branches: true
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016 Jaroslav
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Kitchen::VMM
|
|
2
|
+
|
|
3
|
+
|Travis CI|Gem|
|
|
4
|
+
|-----|-----|
|
|
5
|
+
| [](https://travis-ci.org/jarig/kitchen-vmm)|[](http://badge.fury.io/rb/kitchen-vmm)|
|
|
6
|
+
|
|
7
|
+
Supports: Windows, Linux
|
|
8
|
+
|
|
9
|
+
Virtual Machine Management plugin for Kitchen.
|
|
10
|
+
|
|
11
|
+
This provider will allow you to create VMs in the remote Virtual Machine Manager via Test Kitchen.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Install kitchen-vmm gem
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
chef gem 'kitchen-vmm'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
1. You should have template in your VMM which has following things setup:
|
|
24
|
+
- WinRM and firewall configured, using:
|
|
25
|
+
```
|
|
26
|
+
winrm quickconfig
|
|
27
|
+
```
|
|
28
|
+
- Either domain or local user with admin rights.
|
|
29
|
+
You can specify its creds using
|
|
30
|
+
(either in cookbook .kitchen.yml or in $HOME/.kitchen/config.yml):
|
|
31
|
+
```yaml
|
|
32
|
+
transport:
|
|
33
|
+
name: winrm
|
|
34
|
+
username: <username>
|
|
35
|
+
password: <password>
|
|
36
|
+
```
|
|
37
|
+
- Once VM created in VMM it should automatically get IP assigned, as well as it should be directly accessible from your machine.
|
|
38
|
+
2. Run kitchen commands under **Administrator** (in admin shell).
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
In the .kitchen.yml
|
|
43
|
+
|
|
44
|
+
### Configure Driver
|
|
45
|
+
|
|
46
|
+
Globally
|
|
47
|
+
```yaml
|
|
48
|
+
driver:
|
|
49
|
+
name: vmm
|
|
50
|
+
vm_template_name: default-template
|
|
51
|
+
vm_host_group_name: default-group
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or per platform
|
|
55
|
+
```yaml
|
|
56
|
+
platforms:
|
|
57
|
+
- name: platform1
|
|
58
|
+
driver:
|
|
59
|
+
name: vmm
|
|
60
|
+
vm_template_name: 'overidden-template'
|
|
61
|
+
vm_host_group_name: overidden-group
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Configure Transport
|
|
65
|
+
|
|
66
|
+
In case you need to create both Linux and Windows machines, then different transport types have to be used(ssh for linux and winrm for windows).
|
|
67
|
+
For easier maintenance and cleaner configuration you can create global kitchen configuration under $HOME/<username>/.kitchen/config.yml with following contents:
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
<% WINRM_USERNAME = 'winrm_user' %>
|
|
71
|
+
<% WINRM_PASSWORD = 'winrm_dassword' %>
|
|
72
|
+
|
|
73
|
+
# default transport settings
|
|
74
|
+
transport:
|
|
75
|
+
name: ssh
|
|
76
|
+
username: ssh_user
|
|
77
|
+
ssh_key: <path_to_key>
|
|
78
|
+
# winrm related settings that do not clash with ssh ones can also go here
|
|
79
|
+
# example: winrm_transport
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Then in your kitchen.yml specify transport either for platform or suite
|
|
83
|
+
```yaml
|
|
84
|
+
suites:
|
|
85
|
+
- name: windows-basic
|
|
86
|
+
run_list:
|
|
87
|
+
- recipe[windows-basic::default]
|
|
88
|
+
transport:
|
|
89
|
+
name: winrm
|
|
90
|
+
username: <%= WINRM_USERNAME %>
|
|
91
|
+
password: <%= WINRM_PASSWORD %>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Required parameters:
|
|
95
|
+
|
|
96
|
+
* #### vm_template_name
|
|
97
|
+
|
|
98
|
+
VMM template name that will be used for VM creation.
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
driver_config:
|
|
102
|
+
...
|
|
103
|
+
vm_template_name: vagrant-template-w8.1-64
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
* #### vm_host_group_name
|
|
107
|
+
|
|
108
|
+
VMM host group where VM will be placed.
|
|
109
|
+
NOTE: Your template or *vm_hardware_profile* should match it as well.
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
driver_config:
|
|
113
|
+
...
|
|
114
|
+
vm_host_group_name: 'Host-Group-Name'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
* #### vmm_server_address
|
|
118
|
+
|
|
119
|
+
IP/Hostname of the VMM server where VMs are going to be created.
|
|
120
|
+
```yaml
|
|
121
|
+
driver_config:
|
|
122
|
+
...
|
|
123
|
+
vmm_server_address: '192.124.125.10'
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Optional parameters:
|
|
127
|
+
|
|
128
|
+
* #### vm_name
|
|
129
|
+
|
|
130
|
+
Specify name of a VM that is going to be created. Default is Kitchen instance name.
|
|
131
|
+
If VM with such name already exists driver might get random number appended to it.
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
driver_config:
|
|
135
|
+
...
|
|
136
|
+
vm_name: 'my-vm-in-vmm'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
* #### vm_hardware_profile
|
|
140
|
+
|
|
141
|
+
Specify alternate HW profile that should be used instead of the one provided in your original template.
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
driver_config:
|
|
145
|
+
...
|
|
146
|
+
vm_hardware_profile: 'TestHW-8core-8gb'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
* #### proxy_server_address
|
|
150
|
+
|
|
151
|
+
If your local machine do not have direct access to the machine that hosts VMM, but you have proxy server(jump box) you can specify its IP in *proxy_server_address* property.
|
|
152
|
+
|
|
153
|
+
```yaml
|
|
154
|
+
driver_config:
|
|
155
|
+
...
|
|
156
|
+
proxy_server_address: 'my-proxy-to-vmm'
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
* #### ad_server
|
|
160
|
+
|
|
161
|
+
You can tell the provider to move your VM under some particular OU once it's created.
|
|
162
|
+
|
|
163
|
+
URL of AD server. Can be derived by running ```echo %LOGONSERVER%``` command in CMD of the VM environment.
|
|
164
|
+
|
|
165
|
+
Example:
|
|
166
|
+
```yaml
|
|
167
|
+
driver_config:
|
|
168
|
+
...
|
|
169
|
+
ad_server: 'my-ad-server.some.domain.local'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
* #### ad_source_path
|
|
173
|
+
|
|
174
|
+
Base DN container where VM appears(and it will be moved from) once it's created.
|
|
175
|
+
Example:
|
|
176
|
+
```yaml
|
|
177
|
+
driver_config:
|
|
178
|
+
...
|
|
179
|
+
ad_source_path: 'CN=Computers,DC=some,DC=domain,DC=local'
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
* #### ad_target_path
|
|
183
|
+
|
|
184
|
+
New AD path where VM should be moved to.
|
|
185
|
+
Example:
|
|
186
|
+
```yaml
|
|
187
|
+
driver_config:
|
|
188
|
+
...
|
|
189
|
+
ad_target_path: 'OU=Vagrant,OU=Chef-Nodes,DC=some,DC=domain,DC=local'
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
## Troubleshooting
|
|
194
|
+
|
|
195
|
+
### Authorization failure
|
|
196
|
+
|
|
197
|
+
Check that winrm is configured properly in the VM, if username/password is local then ensure you've set winrm transport to plaintext for kitchen.
|
|
198
|
+
```yaml
|
|
199
|
+
transport:
|
|
200
|
+
name: winrm
|
|
201
|
+
...
|
|
202
|
+
winrm_transport: plaintext
|
|
203
|
+
```
|
|
204
|
+
and enable basic auth and unencrypted connection in a VM.
|
|
205
|
+
```
|
|
206
|
+
winrm set winrm/config/service/auth @{Basic="true"}
|
|
207
|
+
winrm set winrm/config/service @{AllowUnencrypted="true"}
|
|
208
|
+
```
|
|
209
|
+
and on your local machine
|
|
210
|
+
```
|
|
211
|
+
winrm set winrm/config/client/auth @{Basic="true"}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Unencrypted traffic is currently disabled in the client configuration
|
|
215
|
+
|
|
216
|
+
Run following command on your machine as well:
|
|
217
|
+
```
|
|
218
|
+
winrm set winrm/config/service @{AllowUnencrypted="true"}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
## Contributing
|
|
223
|
+
|
|
224
|
+
1. Fork it ( https://github.com/[my-github-username]/kitchen-vmm/fork )
|
|
225
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
226
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
227
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
228
|
+
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]
|
data/kitchen-vmm.gemspec
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
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/vmm_version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = "kitchen-vmm"
|
|
9
|
+
spec.version = Kitchen::Driver::VMM_VERSION
|
|
10
|
+
spec.authors = ["Jaroslav Gorjatsev"]
|
|
11
|
+
spec.email = ["gjarik@gmail.com"]
|
|
12
|
+
spec.summary = 'Virtual Machine Manager Driver for Test-Kitchen'
|
|
13
|
+
spec.description = 'Virtual Machine Manager Driver for Test-Kitchen'
|
|
14
|
+
spec.homepage = "https://github.com/jarig/kitchen-vmm"
|
|
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
|
+
spec.add_development_dependency "cane"
|
|
26
|
+
spec.add_development_dependency "finstyle"
|
|
27
|
+
spec.add_development_dependency "rubocop"
|
|
28
|
+
spec.add_development_dependency "yard"
|
|
29
|
+
|
|
30
|
+
spec.add_dependency "test-kitchen", "~> 1.4"
|
|
31
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'kitchen'
|
|
2
|
+
require 'kitchen/driver'
|
|
3
|
+
require 'kitchen/driver/vmm_version'
|
|
4
|
+
require 'kitchen/driver/vmm_utils'
|
|
5
|
+
require 'mixlib/shellout'
|
|
6
|
+
require 'fileutils'
|
|
7
|
+
require 'JSON'
|
|
8
|
+
|
|
9
|
+
module Kitchen
|
|
10
|
+
|
|
11
|
+
module Driver
|
|
12
|
+
|
|
13
|
+
# Driver for VMM
|
|
14
|
+
class Vmm < Kitchen::Driver::Base
|
|
15
|
+
|
|
16
|
+
kitchen_driver_api_version 2
|
|
17
|
+
plugin_version Kitchen::Driver::VMM_VERSION
|
|
18
|
+
|
|
19
|
+
default_config :vm_template_name
|
|
20
|
+
default_config :vm_host_group_name
|
|
21
|
+
default_config :vmm_server_address
|
|
22
|
+
default_config :vm_name, nil
|
|
23
|
+
default_config :vm_hardware_profile, ''
|
|
24
|
+
default_config :proxy_server_address, ''
|
|
25
|
+
default_config :ad_server, ''
|
|
26
|
+
default_config :ad_source_path, ''
|
|
27
|
+
default_config :ad_target_path, ''
|
|
28
|
+
|
|
29
|
+
def create(state)
|
|
30
|
+
@state = state
|
|
31
|
+
validate_vm_settings
|
|
32
|
+
create_virtual_machine
|
|
33
|
+
info("VM instance #{instance.to_str} created.")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def destroy(state)
|
|
37
|
+
@state = state
|
|
38
|
+
instance.transport.connection(state).close
|
|
39
|
+
remove_virtual_machine
|
|
40
|
+
info("The VM instance #{instance.to_str} has been removed.")
|
|
41
|
+
state.delete(:id)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
include Kitchen::Driver::VMMUtils
|
|
47
|
+
|
|
48
|
+
def validate_vm_settings
|
|
49
|
+
raise "Missing vmm_server_address" unless config[:vmm_server_address]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def kitchen_vm_path
|
|
53
|
+
@kitchen_vm_path ||= File.join(config[:kitchen_root], ".kitchen/#{instance.name}")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def remove_virtual_machine
|
|
57
|
+
info("Deleting virtual machine for #{instance.name}")
|
|
58
|
+
options = {
|
|
59
|
+
vmm_server_address: config[:vmm_server_address],
|
|
60
|
+
proxy_server_address: config[:proxy_server_address],
|
|
61
|
+
vm_id: @state[:id]
|
|
62
|
+
}
|
|
63
|
+
execute('delete_vm.ps1', options)
|
|
64
|
+
info("Deleted virtual machine for #{instance.name}")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def vm_exists
|
|
68
|
+
false
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def create_virtual_machine
|
|
72
|
+
return if vm_exists
|
|
73
|
+
info("Creating virtual machine for #{instance.name}.")
|
|
74
|
+
options = {
|
|
75
|
+
vmm_server_address: config[:vmm_server_address],
|
|
76
|
+
proxy_server_address: config[:proxy_server_address],
|
|
77
|
+
vm_hardware_profile: config[:vm_hardware_profile],
|
|
78
|
+
vm_name: config[:vm_name] || instance.name,
|
|
79
|
+
vm_template_name: config[:vm_template_name],
|
|
80
|
+
vm_host_group_name: config[:vm_host_group_name],
|
|
81
|
+
ad_server: config[:ad_server],
|
|
82
|
+
ad_source_path: config[:ad_source_path],
|
|
83
|
+
ad_target_path: config[:ad_target_path]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
info("Creating and registering VM in the VMM (#{options[:vmm_server_address]})...")
|
|
88
|
+
if options[:ad_server] && options[:ad_source_path] && options[:ad_target_path]
|
|
89
|
+
info(" ..and moving it under #{options[:ad_target_path]} after it's created.")
|
|
90
|
+
end
|
|
91
|
+
vm = execute('import_vm.ps1', options)
|
|
92
|
+
info("Successfully created the VM with name: #{vm['name']}")
|
|
93
|
+
@state[:id] = vm['id']
|
|
94
|
+
@state[:hostname] = vm['hostname']
|
|
95
|
+
@state[:vm_name] = vm['name']
|
|
96
|
+
|
|
97
|
+
info("Created virtual machine for #{instance.name}.")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end # class VMM
|
|
101
|
+
end # module Driver
|
|
102
|
+
end # module Kitchen
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Kitchen
|
|
2
|
+
module Driver
|
|
3
|
+
module VMMUtils
|
|
4
|
+
|
|
5
|
+
ERROR_REGEXP = /===Begin-Error===(.+?)===End-Error===/m
|
|
6
|
+
OUTPUT_REGEXP = /===Begin-Output===(.+?)===End-Output===/m
|
|
7
|
+
|
|
8
|
+
def execute(path, options)
|
|
9
|
+
r = execute_powershell(path, options)
|
|
10
|
+
if r.error?
|
|
11
|
+
raise ("Powershell failed, #{path}:#{r.stderr}")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# We only want unix-style line endings within Vagrant
|
|
15
|
+
r.stdout.gsub!("\r\n", "\n")
|
|
16
|
+
r.stderr.gsub!("\r\n", "\n")
|
|
17
|
+
|
|
18
|
+
error_match = ERROR_REGEXP.match(r.stdout)
|
|
19
|
+
output_match = OUTPUT_REGEXP.match(r.stdout)
|
|
20
|
+
|
|
21
|
+
if error_match
|
|
22
|
+
data = JSON.parse(error_match[1])
|
|
23
|
+
|
|
24
|
+
# We have some error data.
|
|
25
|
+
raise "#{path}:#{data["error"]}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Nothing
|
|
29
|
+
return nil if !output_match
|
|
30
|
+
return JSON.parse(output_match[1])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def execute_powershell(path, options = {})
|
|
34
|
+
lib_path = Pathname.new(File.expand_path("../../../../support", __FILE__))
|
|
35
|
+
script_path = lib_path.join(path).to_s.gsub("/", "\\")
|
|
36
|
+
ps_options = ''
|
|
37
|
+
options.each do |key, value|
|
|
38
|
+
unless value.nil?
|
|
39
|
+
ps_options += " -#{key} \"#{value}\""
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
#
|
|
43
|
+
stdout_stream_reader = StreamReader.new do |line|
|
|
44
|
+
info(line)
|
|
45
|
+
end
|
|
46
|
+
ps_run = Mixlib::ShellOut.new("powershell.exe -File #{script_path} #{ps_options} -ErrorAction Stop")
|
|
47
|
+
debug("Command: #{ps_run.command}")
|
|
48
|
+
ps_run.live_stdout = stdout_stream_reader
|
|
49
|
+
ps_run.run_command
|
|
50
|
+
return ps_run
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# for powershell stdout read
|
|
54
|
+
class StreamReader
|
|
55
|
+
require 'stringio'
|
|
56
|
+
|
|
57
|
+
def initialize(&block)
|
|
58
|
+
@block = block
|
|
59
|
+
@buffer = StringIO.new
|
|
60
|
+
@buffer.sync = true if @buffer.respond_to?(:sync)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def <<(chunk)
|
|
64
|
+
overflow = ''
|
|
65
|
+
|
|
66
|
+
@buffer.write(chunk)
|
|
67
|
+
@buffer.rewind
|
|
68
|
+
|
|
69
|
+
@buffer.each_line do |line|
|
|
70
|
+
if line.match(/\r?\n/)
|
|
71
|
+
@block.call(line.strip)
|
|
72
|
+
else
|
|
73
|
+
overflow = line
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
@buffer.truncate(@buffer.rewind)
|
|
78
|
+
@buffer.write(overflow)
|
|
79
|
+
end
|
|
80
|
+
end # StreamReader
|
|
81
|
+
|
|
82
|
+
end # module VMMUtils
|
|
83
|
+
end # module Driver
|
|
84
|
+
end # module Kitchen
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Param(
|
|
2
|
+
[Parameter(Mandatory=$true)]
|
|
3
|
+
[string]$vm_id,
|
|
4
|
+
[Parameter(Mandatory=$true)]
|
|
5
|
+
[string]$vmm_server_address,
|
|
6
|
+
[string]$proxy_server_address=$null
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Include the following modules
|
|
11
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
12
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
13
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
$script_block = {
|
|
17
|
+
# external vars
|
|
18
|
+
$vm_id = $using:vm_id
|
|
19
|
+
|
|
20
|
+
# Get VM
|
|
21
|
+
$vm = Get-SCVirtualMachine -ID $vm_id -ErrorAction Ignore
|
|
22
|
+
if ( $vm )
|
|
23
|
+
{
|
|
24
|
+
if ( $vm.status -eq 'Running' )
|
|
25
|
+
{
|
|
26
|
+
$res = Stop-VM $vm
|
|
27
|
+
}
|
|
28
|
+
$res = Remove-VM $vm
|
|
29
|
+
} else
|
|
30
|
+
{
|
|
31
|
+
Write-Host "VM do not exists or not found: $vm_id"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
execute $script_block $vmm_server_address $proxy_server_address
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Param(
|
|
2
|
+
[Parameter(Mandatory=$true)]
|
|
3
|
+
[string]$vm_name,
|
|
4
|
+
[Parameter(Mandatory=$true)]
|
|
5
|
+
[string]$vmm_server_address,
|
|
6
|
+
[Parameter(Mandatory=$true)]
|
|
7
|
+
[string]$vm_template_name,
|
|
8
|
+
[Parameter(Mandatory=$true)]
|
|
9
|
+
[string]$vm_host_group_name,
|
|
10
|
+
[string]$vm_hardware_profile=$null,
|
|
11
|
+
[string]$proxy_server_address=$null,
|
|
12
|
+
[string]$ad_server=$null,
|
|
13
|
+
[string]$ad_source_path=$null,
|
|
14
|
+
[string]$ad_target_path=$null
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# Include the following modules
|
|
18
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
19
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
20
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
$script_block = {
|
|
24
|
+
# external vars
|
|
25
|
+
$vm_name = $using:vm_name
|
|
26
|
+
$vm_host_group_name = $using:vm_host_group_name
|
|
27
|
+
$server_address = $using:vmm_server_address
|
|
28
|
+
$vm_template_name = $using:vm_template_name
|
|
29
|
+
$vm_hardware_profile_name = $using:vm_hardware_profile
|
|
30
|
+
$ad_server = $using:ad_server
|
|
31
|
+
$ad_source_path = $using:ad_source_path
|
|
32
|
+
$ad_target_path = $using:ad_target_path
|
|
33
|
+
|
|
34
|
+
$description = "VM created by chef test-kitchen for testing purposes"
|
|
35
|
+
$MinFreeSpaceGB = 300 #
|
|
36
|
+
|
|
37
|
+
$domain_name = $null
|
|
38
|
+
if ( $ad_source_path )
|
|
39
|
+
{
|
|
40
|
+
$domain_name = $($ad_source_path.split(",")|Where {$_.Contains("DC")}| ForEach-Object { $_.replace("DC=", "") }) -join "."
|
|
41
|
+
}
|
|
42
|
+
# Truncate vm name to 15 chars due to windows limitation
|
|
43
|
+
$vm_name = $vm_name.substring(0, [math]::Min(15, $vm_name.length))
|
|
44
|
+
|
|
45
|
+
# get VM Template object
|
|
46
|
+
$VMTemplate = Get-SCVMTemplate -Name $vm_template_name
|
|
47
|
+
# get host group
|
|
48
|
+
$VMHostGroup = Get-VMHostGroup -Name $vm_host_group_name
|
|
49
|
+
#
|
|
50
|
+
Write-Host "Creating VM from template $vm_template_name"
|
|
51
|
+
|
|
52
|
+
$tries = 10
|
|
53
|
+
while ( $tries -gt 0 ) {
|
|
54
|
+
$vm = Get-SCVirtualMachine -Name $vm_name
|
|
55
|
+
if ( $vm -eq $null ) {
|
|
56
|
+
break
|
|
57
|
+
} else {
|
|
58
|
+
$vm_name = $vm_name.substring(0, [math]::Min(14, $vm_name.length)) + $(Get-Random -Minimum 0 -Maximum 10)
|
|
59
|
+
}
|
|
60
|
+
$tries -= 1
|
|
61
|
+
}
|
|
62
|
+
if ( $vm -eq $null )
|
|
63
|
+
{
|
|
64
|
+
# Get and sort the host ratings for all the hosts in the host group.
|
|
65
|
+
# select host which has rating > 0
|
|
66
|
+
$hRatingHashParams = @{VMTemplate=$VMTemplate;
|
|
67
|
+
DiskSpaceGB=$MinFreeSpaceGB;
|
|
68
|
+
VMName=$vm_name;
|
|
69
|
+
VMHostGroup=$VMHostGroup;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if ( $vm_hardware_profile_name )
|
|
73
|
+
{
|
|
74
|
+
$vm_hardware_profile = Get-SCHardwareProfile | where {$_.Name -eq $vm_hardware_profile_name}
|
|
75
|
+
Write-host "Applying hardware profile: $vm_hardware_profile_name"
|
|
76
|
+
$VMTemplate = New-SCVMTemplate -Name "Temporary Template$([guid]::NewGuid())" -VMTemplate $VMTemplate -HardwareProfile $vm_hardware_profile
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
$VMHost = $null
|
|
80
|
+
$HostRatings = @(Get-SCVMHostRating @hRatingHashParams | Sort-Object -property Rating -descending)
|
|
81
|
+
If($HostRatings.Count -eq 0) { throw "No hosts meet the requirements." }
|
|
82
|
+
$VMHost = $HostRatings[0].VMHost
|
|
83
|
+
|
|
84
|
+
# If there is at least one host that will support the virtual machine, create the virtual machine on the highest-rated host.
|
|
85
|
+
If ($VMHost -ne $null )
|
|
86
|
+
{
|
|
87
|
+
# get placement path
|
|
88
|
+
$path = $($VMHost.DiskVolumes | where { $_.IsAvailableForPlacement -eq $True } | Sort-Object -Property FreeSpace -Descending)[0]
|
|
89
|
+
Write-Host "----- Creating VM ----"
|
|
90
|
+
Write-Host "Host: $VMHost, $($VMHost.CPUManufacturer) $($VMHost.Rank)"
|
|
91
|
+
Write-host "Placement path: $($path.Name), Free space - $($path.FreeSpace/1024/1024/1024) GB"
|
|
92
|
+
Write-Host "Name: $vm_name"
|
|
93
|
+
Write-Host "----- ----------- ----"
|
|
94
|
+
# Create the virtual machine.
|
|
95
|
+
$vmCreateParams = @{Name=$vm_name;
|
|
96
|
+
Path=$path.Name;
|
|
97
|
+
VMHost = $VMHost;
|
|
98
|
+
VMTemplate=$VMTemplate;
|
|
99
|
+
Description=$description;
|
|
100
|
+
ComputerName=$vm_name;
|
|
101
|
+
BlockDynamicOptimization=$false;
|
|
102
|
+
ReturnImmediately = $false; AnswerFile = $null;
|
|
103
|
+
StartAction = "NeverAutoTurnOnVM";
|
|
104
|
+
StopAction = "TurnOffVM";
|
|
105
|
+
StartVM=$true;
|
|
106
|
+
ErrorAction="stop";
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
$vm = New-SCVirtualMachine @vmCreateParams
|
|
110
|
+
} else {
|
|
111
|
+
Write-Error "Cannot find suitable host for the VM."
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
Write-Warning "Machine $vm_name already exists on host $($vm.VMHost.Name)"
|
|
115
|
+
}
|
|
116
|
+
Write-Host "Machine created."
|
|
117
|
+
# try to move it in AD
|
|
118
|
+
try
|
|
119
|
+
{
|
|
120
|
+
# move it to under AD path if required
|
|
121
|
+
if ($ad_target_path -ne $null -and $ad_source_path -ne $null -and $ad_server -ne $null)
|
|
122
|
+
{
|
|
123
|
+
Write-host "Moving it AD under $ad_target_path"
|
|
124
|
+
$cred_param = @{}
|
|
125
|
+
if ($proxy_credential)
|
|
126
|
+
{
|
|
127
|
+
# if proxy used to overcome credssp auth
|
|
128
|
+
$cred_param["Credential"] = $proxy_credential
|
|
129
|
+
}
|
|
130
|
+
$ad_res = Get-ADComputer -Identity:"CN=$vm_name,$ad_source_path" -Server:$ad_server -ErrorAction Ignore @cred_param
|
|
131
|
+
if ( $ad_res -ne $null )
|
|
132
|
+
{
|
|
133
|
+
Move-ADObject -Identity:"CN=$vm_name,$ad_source_path" -TargetPath:$ad_target_path -Server:$ad_server @cred_param
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
} catch
|
|
137
|
+
{
|
|
138
|
+
Write-Warning "Couldn't move under specified OU: $_"
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
$fqdn = $vm.ComputerNameString
|
|
142
|
+
if ( ! $fqdn.contains($domain_name) )
|
|
143
|
+
{
|
|
144
|
+
# Linux machines do not always set domain name propery for example
|
|
145
|
+
$fqdn = "$fqdn.$domain_name"
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# return vm object
|
|
149
|
+
@{
|
|
150
|
+
vm = $vm
|
|
151
|
+
fqdn = $fqdn
|
|
152
|
+
ip = $ip
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
$result = execute $script_block $vmm_server_address $proxy_server_address
|
|
157
|
+
|
|
158
|
+
$resultHash = @{
|
|
159
|
+
hostname = $result.fqdn
|
|
160
|
+
name = $result.vm.Name
|
|
161
|
+
id = $result.vm.id.guid
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
$result = ConvertTo-Json $resultHash
|
|
165
|
+
Write-Output-Message $result
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
# get either cached or entered in the prompt credentials
|
|
3
|
+
function Get-Creds($server_address, $prompt_message, $username = $null, $password = $null )
|
|
4
|
+
{
|
|
5
|
+
$temp_folder = $env:temp
|
|
6
|
+
# get creds
|
|
7
|
+
$cred_file = $temp_folder + "\creds_$server_address.clixml"
|
|
8
|
+
if ( Test-Path $cred_file )
|
|
9
|
+
{
|
|
10
|
+
$credential = Import-CliXml $cred_file
|
|
11
|
+
} else
|
|
12
|
+
{
|
|
13
|
+
if ( $username -ne $null -and $password -ne $null )
|
|
14
|
+
{
|
|
15
|
+
# creds passed, use them
|
|
16
|
+
$password = ConvertTo-SecureString -string $password -asPlainText -force
|
|
17
|
+
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
|
|
18
|
+
} else
|
|
19
|
+
{
|
|
20
|
+
$credential = Get-Credential -Message $prompt_message
|
|
21
|
+
}
|
|
22
|
+
$credential | Export-CliXml $cred_file
|
|
23
|
+
Write-host "Credentials for $server_address is cached in $cred_file"
|
|
24
|
+
}
|
|
25
|
+
return $credential
|
|
26
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
# add $address to trusted host list
|
|
3
|
+
function Add-To-Trusted($address)
|
|
4
|
+
{
|
|
5
|
+
$trusted_hosts = get-item wsman:\localhost\Client\TrustedHosts
|
|
6
|
+
if ( $address -as [ipaddress] -and !$trusted_hosts.Value.Contains($address) )
|
|
7
|
+
{
|
|
8
|
+
if ($trusted_hosts.Value)
|
|
9
|
+
{
|
|
10
|
+
$new_th_values = "$($trusted_hosts.Value),$address"
|
|
11
|
+
} else {
|
|
12
|
+
$new_th_values = $address
|
|
13
|
+
}
|
|
14
|
+
set-item wsman:\localhost\Client\TrustedHosts $new_th_values -Force
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# remove $address from trusted host list
|
|
19
|
+
function Remove-From-Trusted($address)
|
|
20
|
+
{
|
|
21
|
+
# remove $address from trusted hosts
|
|
22
|
+
$trusted_hosts = get-item wsman:\localhost\Client\TrustedHosts
|
|
23
|
+
if ( $trusted_hosts.Value.Contains($address) )
|
|
24
|
+
{
|
|
25
|
+
$new_th_values = $trusted_hosts.Value -replace ",?$address", ""
|
|
26
|
+
set-item wsman:\localhost\Client\TrustedHosts $new_th_values -Force
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#
|
|
2
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
3
|
+
. ([System.IO.Path]::Combine($Dir, "manage_credentials.ps1"))
|
|
4
|
+
. ([System.IO.Path]::Combine($Dir, "manage_trusted_hosts.ps1"))
|
|
5
|
+
|
|
6
|
+
# execute script block for VMM
|
|
7
|
+
function execute($block, $vmm_server_address, $proxy_server_address)
|
|
8
|
+
{
|
|
9
|
+
$proxy_credential = $null
|
|
10
|
+
if ($proxy_server_address -ne $null )
|
|
11
|
+
{
|
|
12
|
+
$proxy_credential = Get-Creds $proxy_server_address "Credentials for proxy server: $proxy_server_address"
|
|
13
|
+
}
|
|
14
|
+
$vmm_credential = Get-Creds $vmm_server_address "Credentials for VMM server: $vmm_server_address"
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
$init_vmm_block = {
|
|
18
|
+
try {
|
|
19
|
+
ipmo 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\psModules\virtualmachinemanager'
|
|
20
|
+
} catch
|
|
21
|
+
{
|
|
22
|
+
write-error 'You need to install Virtual Machine Manager R2 client first.'
|
|
23
|
+
throw $_.Exception
|
|
24
|
+
}
|
|
25
|
+
#
|
|
26
|
+
$proxy_credential = $using:proxy_credential # make those available within $block as well
|
|
27
|
+
$vmm_server = Get-VMMServer -ComputerName $using:vmm_server_address -Credential $using:vmm_credential
|
|
28
|
+
}
|
|
29
|
+
# prepend init block to execution block
|
|
30
|
+
$block_to_run = [ScriptBlock]::Create($init_vmm_block.ToString() + $block.ToString())
|
|
31
|
+
#
|
|
32
|
+
if ( $proxy_server_address -eq $null )
|
|
33
|
+
{
|
|
34
|
+
$res = $(Start-Job $block_to_run | Wait-Job | Receive-Job)
|
|
35
|
+
} else
|
|
36
|
+
{
|
|
37
|
+
Add-To-Trusted $proxy_server_address
|
|
38
|
+
$so = New-PSSessionOption -IdleTimeout 240000
|
|
39
|
+
$res = invoke-command -ComputerName $proxy_server_address -Credential $proxy_credential -ScriptBlock $block_to_run -SessionOption $so
|
|
40
|
+
Remove-From-Trusted $proxy_server_address
|
|
41
|
+
}
|
|
42
|
+
return $res
|
|
43
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#-------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
|
3
|
+
# All Rights Reserved. Licensed under the MIT License.
|
|
4
|
+
#--------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
function Write-Error-Message($message) {
|
|
7
|
+
$error_message = @{
|
|
8
|
+
error = "$message"
|
|
9
|
+
}
|
|
10
|
+
Write-Host "===Begin-Error==="
|
|
11
|
+
$result = ConvertTo-json $error_message
|
|
12
|
+
Write-Host $result
|
|
13
|
+
Write-Host "===End-Error==="
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function Write-Output-Message($message) {
|
|
17
|
+
Write-Host "===Begin-Output==="
|
|
18
|
+
Write-Host $message
|
|
19
|
+
Write-Host "===End-Output==="
|
|
20
|
+
}
|
metadata
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: kitchen-vmm
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jaroslav Gorjatsev
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-06-13 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: 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
|
+
- - ! '>='
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ! '>='
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: test-kitchen
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ~>
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '1.4'
|
|
118
|
+
type: :runtime
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ~>
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '1.4'
|
|
125
|
+
description: Virtual Machine Manager Driver for Test-Kitchen
|
|
126
|
+
email:
|
|
127
|
+
- gjarik@gmail.com
|
|
128
|
+
executables: []
|
|
129
|
+
extensions: []
|
|
130
|
+
extra_rdoc_files: []
|
|
131
|
+
files:
|
|
132
|
+
- .cane
|
|
133
|
+
- .gitignore
|
|
134
|
+
- .rubocop.yml
|
|
135
|
+
- .travis.yml
|
|
136
|
+
- CHANGELOG.md
|
|
137
|
+
- Gemfile
|
|
138
|
+
- LICENSE
|
|
139
|
+
- README.md
|
|
140
|
+
- Rakefile
|
|
141
|
+
- kitchen-vmm.gemspec
|
|
142
|
+
- lib/kitchen/driver/vmm.rb
|
|
143
|
+
- lib/kitchen/driver/vmm_utils.rb
|
|
144
|
+
- lib/kitchen/driver/vmm_version.rb
|
|
145
|
+
- support/delete_vm.ps1
|
|
146
|
+
- support/import_vm.ps1
|
|
147
|
+
- support/utils/manage_credentials.ps1
|
|
148
|
+
- support/utils/manage_trusted_hosts.ps1
|
|
149
|
+
- support/utils/vmm_executor.ps1
|
|
150
|
+
- support/utils/write_messages.ps1
|
|
151
|
+
homepage: https://github.com/jarig/kitchen-vmm
|
|
152
|
+
licenses:
|
|
153
|
+
- Apache 2
|
|
154
|
+
metadata: {}
|
|
155
|
+
post_install_message:
|
|
156
|
+
rdoc_options: []
|
|
157
|
+
require_paths:
|
|
158
|
+
- lib
|
|
159
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
|
+
requirements:
|
|
161
|
+
- - ! '>='
|
|
162
|
+
- !ruby/object:Gem::Version
|
|
163
|
+
version: '0'
|
|
164
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
|
+
requirements:
|
|
166
|
+
- - ! '>='
|
|
167
|
+
- !ruby/object:Gem::Version
|
|
168
|
+
version: '0'
|
|
169
|
+
requirements: []
|
|
170
|
+
rubyforge_project:
|
|
171
|
+
rubygems_version: 2.4.5
|
|
172
|
+
signing_key:
|
|
173
|
+
specification_version: 4
|
|
174
|
+
summary: Virtual Machine Manager Driver for Test-Kitchen
|
|
175
|
+
test_files: []
|