chef-metal-vsphere 0.2.0 → 0.3.0.beta.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 +4 -4
- data/.gitignore +27 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +3 -0
- data/{LICENSE → LICENSE.txt} +4 -2
- data/README.md +29 -42
- data/Rakefile +31 -22
- data/TODO.md +41 -0
- data/chef-metal-vpshere.gemspec +34 -0
- data/lib/chef_metal/driver_init/vsphere.rb +3 -0
- data/lib/chef_metal_vsphere.rb +1 -11
- data/lib/chef_metal_vsphere/version.rb +1 -1
- data/lib/chef_metal_vsphere/vsphere_driver.rb +325 -0
- data/spec/driver_spec.rb +21 -0
- data/spec/spec_helper.rb +2 -0
- data/test/.chef/knife.rb +4 -0
- data/test/cookbooks/test/libraries/vmonkey_helper.rb +34 -0
- data/test/cookbooks/test/recipes/destroy_all.rb +8 -0
- data/test/cookbooks/test/recipes/simple.rb +11 -0
- data/test/cookbooks/test/recipes/vagrant.rb +11 -0
- data/test/cookbooks/test/recipes/vsphere.rb +18 -0
- metadata +111 -34
- data/lib/chef_metal/provisioner_init/vsphere_init.rb +0 -3
- data/lib/chef_metal_vsphere/vsphere_helpers.rb +0 -168
- data/lib/chef_metal_vsphere/vsphere_provisioner.rb +0 -310
data/spec/driver_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe ChefMetalVsphere::VsphereDriver do
|
4
|
+
describe '::canonicalize_url' do
|
5
|
+
let(:vmonkey_config) do
|
6
|
+
{
|
7
|
+
host: 'spec_host',
|
8
|
+
datacenter: 'spec_datacenter',
|
9
|
+
cluster: 'spec_cluster'
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
allow(VMonkey).to receive(:default_opts) { vmonkey_config }
|
15
|
+
end
|
16
|
+
|
17
|
+
subject { described_class::canonicalize_url('vsphere', {}) }
|
18
|
+
|
19
|
+
it { should include('vsphere:spec_host:spec_datacenter:spec_cluster') }
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/test/.chef/knife.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module VmonkeyHelper
|
2
|
+
@instructions = "
|
3
|
+
For the test coobook to run with the vsphere driver, you need:
|
4
|
+
- On the machine running the specs:
|
5
|
+
+ #{ENV['VMONKEY_YML']} (see below)
|
6
|
+
|
7
|
+
- On your vSphere system
|
8
|
+
+ A VM or Template from which VMs will be cloned (:bootstrap_options => :template)
|
9
|
+
+ A working Folder into which VMs will be cloned (:bootstrap_options => :working_folder)
|
10
|
+
+ Clones of the Template must provide SSH port 22 with root password authentication (:ssh_options => :password)
|
11
|
+
|
12
|
+
Place the following in #{ENV['VMONKEY_YML']}
|
13
|
+
host: vcenter_host_name
|
14
|
+
user: vcenter_user_name
|
15
|
+
password: your_mothers_maiden_name
|
16
|
+
insecure: true
|
17
|
+
ssl: true
|
18
|
+
datacenter: datacenter_name
|
19
|
+
cluster: cluster_name
|
20
|
+
test:
|
21
|
+
:bootstrap_options:
|
22
|
+
template: /path/to/a/vm/template
|
23
|
+
folder: /path/to/a/folder/to/place/new/vms
|
24
|
+
:ssh_options:
|
25
|
+
password: your_first_pet
|
26
|
+
"
|
27
|
+
|
28
|
+
def self.config
|
29
|
+
yml_path = File.expand_path( ENV['VMONKEY_YML'] )
|
30
|
+
YAML::load_file(yml_path).inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
|
31
|
+
rescue
|
32
|
+
raise @instructions
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'chef_metal_vagrant'
|
2
|
+
test_dir = File.expand_path('../../../../..', File.dirname(__FILE__))
|
3
|
+
with_driver "vagrant:#{test_dir}/.vagrant"
|
4
|
+
|
5
|
+
vagrant_box 'precise64' do
|
6
|
+
url 'http://files.vagrantup.com/precise64.box'
|
7
|
+
end
|
8
|
+
|
9
|
+
with_machine_options :vagrant_options => {
|
10
|
+
'vm.box' => 'precise64'
|
11
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'chef_metal_vsphere'
|
2
|
+
config = VmonkeyHelper.config
|
3
|
+
|
4
|
+
with_driver 'vsphere'
|
5
|
+
|
6
|
+
with_machine_options({
|
7
|
+
bootstrap_options: {
|
8
|
+
template: config[:test][:bootstrap_options][:template],
|
9
|
+
folder: config[:test][:bootstrap_options][:folder]
|
10
|
+
},
|
11
|
+
ssh_options: {
|
12
|
+
user: 'root',
|
13
|
+
password: config[:test][:ssh_options][:password],
|
14
|
+
port: 22,
|
15
|
+
user_known_hosts_file: '/dev/null',
|
16
|
+
paranoid: false
|
17
|
+
}
|
18
|
+
})
|
metadata
CHANGED
@@ -1,88 +1,157 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-metal-vsphere
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Brian Dupras
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05
|
11
|
+
date: 2014-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '11.12'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '11.12'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: chef-metal
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '0.11'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '0.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: vmonkey
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.6'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rspec
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
|
-
- -
|
73
|
+
- - ~>
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
75
|
+
version: '3.0'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
|
-
- -
|
80
|
+
- - ~>
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
82
|
+
version: '3.0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rake
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
|
-
- -
|
87
|
+
- - ~>
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
89
|
+
version: '10.3'
|
62
90
|
type: :development
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
|
-
- -
|
94
|
+
- - ~>
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
69
|
-
|
70
|
-
|
96
|
+
version: '10.3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: mixlib-shellout
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.4.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.4.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: chef-metal-vagrant
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.4'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.4'
|
125
|
+
description: chef-metal vSphere driver
|
126
|
+
email:
|
127
|
+
- brian@duprasville.com
|
71
128
|
executables: []
|
72
129
|
extensions: []
|
73
130
|
extra_rdoc_files:
|
74
131
|
- README.md
|
75
|
-
- LICENSE
|
132
|
+
- LICENSE.txt
|
76
133
|
files:
|
77
|
-
-
|
134
|
+
- .gitignore
|
135
|
+
- CHANGELOG.md
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
78
138
|
- README.md
|
79
139
|
- Rakefile
|
80
|
-
-
|
140
|
+
- TODO.md
|
141
|
+
- chef-metal-vpshere.gemspec
|
142
|
+
- lib/chef_metal/driver_init/vsphere.rb
|
81
143
|
- lib/chef_metal_vsphere.rb
|
82
144
|
- lib/chef_metal_vsphere/version.rb
|
83
|
-
- lib/chef_metal_vsphere/
|
84
|
-
-
|
85
|
-
|
145
|
+
- lib/chef_metal_vsphere/vsphere_driver.rb
|
146
|
+
- spec/driver_spec.rb
|
147
|
+
- spec/spec_helper.rb
|
148
|
+
- test/.chef/knife.rb
|
149
|
+
- test/cookbooks/test/libraries/vmonkey_helper.rb
|
150
|
+
- test/cookbooks/test/recipes/destroy_all.rb
|
151
|
+
- test/cookbooks/test/recipes/simple.rb
|
152
|
+
- test/cookbooks/test/recipes/vagrant.rb
|
153
|
+
- test/cookbooks/test/recipes/vsphere.rb
|
154
|
+
homepage: https://github.com/vmtricks/chef-metal-vsphere
|
86
155
|
licenses:
|
87
156
|
- MIT
|
88
157
|
metadata: {}
|
@@ -92,18 +161,26 @@ require_paths:
|
|
92
161
|
- lib
|
93
162
|
required_ruby_version: !ruby/object:Gem::Requirement
|
94
163
|
requirements:
|
95
|
-
- -
|
164
|
+
- - '>='
|
96
165
|
- !ruby/object:Gem::Version
|
97
166
|
version: '0'
|
98
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
168
|
requirements:
|
100
|
-
- -
|
169
|
+
- - '>'
|
101
170
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
171
|
+
version: 1.3.1
|
103
172
|
requirements: []
|
104
173
|
rubyforge_project:
|
105
|
-
rubygems_version: 2.
|
174
|
+
rubygems_version: 2.1.11
|
106
175
|
signing_key:
|
107
176
|
specification_version: 4
|
108
|
-
summary:
|
109
|
-
test_files:
|
177
|
+
summary: chef-metal vSphere driver
|
178
|
+
test_files:
|
179
|
+
- spec/driver_spec.rb
|
180
|
+
- spec/spec_helper.rb
|
181
|
+
- test/.chef/knife.rb
|
182
|
+
- test/cookbooks/test/libraries/vmonkey_helper.rb
|
183
|
+
- test/cookbooks/test/recipes/destroy_all.rb
|
184
|
+
- test/cookbooks/test/recipes/simple.rb
|
185
|
+
- test/cookbooks/test/recipes/vagrant.rb
|
186
|
+
- test/cookbooks/test/recipes/vsphere.rb
|
@@ -1,168 +0,0 @@
|
|
1
|
-
module ChefMetalVsphere
|
2
|
-
module Helpers
|
3
|
-
|
4
|
-
def vim
|
5
|
-
# reconnect on every call - connections may silently timeout during long operations (e.g. cloning)
|
6
|
-
conn_opts = {
|
7
|
-
:host => connect_options['vsphere_host'],
|
8
|
-
:port => connect_options['vsphere_port'],
|
9
|
-
:path => connect_options['vshere_path'],
|
10
|
-
:use_ssl => connect_options['vsphere_ssl'],
|
11
|
-
:insecure => connect_options['vsphere_insecure'],
|
12
|
-
:proxyHost => connect_options['proxy_host'],
|
13
|
-
:proxyPort => connect_options['proxy_port'],
|
14
|
-
:user => connect_options['vsphere_user'],
|
15
|
-
:password => connect_options['vsphere_password']
|
16
|
-
}
|
17
|
-
|
18
|
-
vim = RbVmomi::VIM.connect conn_opts
|
19
|
-
return vim
|
20
|
-
end
|
21
|
-
|
22
|
-
def find_vm(dc_name, vm_folder, vm_name)
|
23
|
-
folder = find_folder(dc_name, vm_folder) or raise("vSphere Folder not found [#{vm_folder}] for vm #{vm_name}")
|
24
|
-
vm = folder.find(vm_name, RbVmomi::VIM::VirtualMachine)
|
25
|
-
end
|
26
|
-
|
27
|
-
def vm_started?(vm, wait_on_port = 22)
|
28
|
-
return false if vm.nil?
|
29
|
-
state = vm.runtime.powerState
|
30
|
-
return false unless state == 'poweredOn'
|
31
|
-
return false unless port_ready?(vm, wait_on_port)
|
32
|
-
return true
|
33
|
-
end
|
34
|
-
|
35
|
-
def vm_stopped?(vm)
|
36
|
-
return true if vm.nil?
|
37
|
-
state = vm.runtime.powerState
|
38
|
-
return false unless state == 'poweredOff'
|
39
|
-
return false
|
40
|
-
end
|
41
|
-
|
42
|
-
def start_vm(vm, wait_on_port = 22)
|
43
|
-
state = vm.runtime.powerState
|
44
|
-
unless state == 'poweredOn'
|
45
|
-
vm.PowerOnVM_Task.wait_for_completion
|
46
|
-
end
|
47
|
-
|
48
|
-
sleep 1 until port_ready?(vm, wait_on_port)
|
49
|
-
end
|
50
|
-
|
51
|
-
def stop_vm(vm)
|
52
|
-
begin
|
53
|
-
vm.ShutdownGuest
|
54
|
-
sleep 2 until vm.runtime.powerState == 'poweredOff'
|
55
|
-
rescue
|
56
|
-
vm.PowerOffVM_Task.wait_for_completion
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def port_ready?(vm, port)
|
61
|
-
vm_ip = vm.guest.ipAddress
|
62
|
-
return false if vm_ip.nil?
|
63
|
-
|
64
|
-
begin
|
65
|
-
tcp_socket = TCPSocket.new(vm_ip, port)
|
66
|
-
readable = IO.select([tcp_socket], nil, nil, 5)
|
67
|
-
if readable
|
68
|
-
true
|
69
|
-
else
|
70
|
-
false
|
71
|
-
end
|
72
|
-
rescue Errno::ETIMEDOUT
|
73
|
-
false
|
74
|
-
rescue Errno::EPERM
|
75
|
-
false
|
76
|
-
rescue Errno::ECONNREFUSED
|
77
|
-
false
|
78
|
-
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
|
79
|
-
false
|
80
|
-
ensure
|
81
|
-
tcp_socket && tcp_socket.close
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
#folder could be like: /Level1/Level2/folder_name
|
86
|
-
def find_folder(dc_name, folder_name)
|
87
|
-
#dc(dc_name).vmFolder.childEntity.grep(RbVmomi::VIM::Folder).find { |x| x.name == folder_name }
|
88
|
-
baseEntity = dc(dc_name).vmFolder
|
89
|
-
entityArray = folder_name.split('/')
|
90
|
-
entityArray.each do |entityArrItem|
|
91
|
-
if entityArrItem != ''
|
92
|
-
baseEntity = baseEntity.childEntity.grep(RbVmomi::VIM::Folder).find { |f| f.name == entityArrItem }
|
93
|
-
end
|
94
|
-
end
|
95
|
-
baseEntity
|
96
|
-
end
|
97
|
-
|
98
|
-
def dc(dc_name)
|
99
|
-
vim.serviceInstance.find_datacenter(dc_name) or raise("vSphere Datacenter not found [#{datacenter}]")
|
100
|
-
end
|
101
|
-
|
102
|
-
def do_vm_clone(dc_name, vm_template, vm_name, options)
|
103
|
-
pool = options['resource_pool'] ? find_pool(dc(dc_name), options['resource_pool']) : vm_template.resourcePool
|
104
|
-
raise ':resource_pool must be specified when cloning from a VM Template' if pool.nil?
|
105
|
-
|
106
|
-
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
|
107
|
-
location: RbVmomi::VIM.VirtualMachineRelocateSpec(pool: pool),
|
108
|
-
powerOn: false,
|
109
|
-
template: false
|
110
|
-
)
|
111
|
-
|
112
|
-
clone_spec.config = RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => Array.new)
|
113
|
-
|
114
|
-
unless options['customization_spec'].to_s.empty?
|
115
|
-
clone_spec.customization = find_customization_spec(options['customization_spec'])
|
116
|
-
end
|
117
|
-
|
118
|
-
unless options['annotation'].to_s.nil?
|
119
|
-
clone_spec.config.annotation = options['annotation']
|
120
|
-
end
|
121
|
-
|
122
|
-
unless options['num_cpus'].to_s.nil?
|
123
|
-
clone_spec.config.numCPUs = options['num_cpus']
|
124
|
-
end
|
125
|
-
|
126
|
-
unless options['memory_mb'].to_s.nil?
|
127
|
-
clone_spec.config.memoryMB = options['memory_mb']
|
128
|
-
end
|
129
|
-
|
130
|
-
vm_template.CloneVM_Task(
|
131
|
-
name: vm_name,
|
132
|
-
folder: find_folder(dc_name, options['vm_folder']),
|
133
|
-
spec: clone_spec
|
134
|
-
).wait_for_completion
|
135
|
-
end
|
136
|
-
|
137
|
-
def find_pool(dc, pool_name)
|
138
|
-
baseEntity = dc.hostFolder
|
139
|
-
entityArray = pool_name.split('/')
|
140
|
-
entityArray.each do |entityArrItem|
|
141
|
-
if entityArrItem != ''
|
142
|
-
if baseEntity.is_a? RbVmomi::VIM::Folder
|
143
|
-
baseEntity = baseEntity.childEntity.find { |f| f.name == entityArrItem } or nil
|
144
|
-
elsif baseEntity.is_a? RbVmomi::VIM::ClusterComputeResource or baseEntity.is_a? RbVmomi::VIM::ComputeResource
|
145
|
-
baseEntity = baseEntity.resourcePool.resourcePool.find { |f| f.name == entityArrItem } or nil
|
146
|
-
elsif baseEntity.is_a? RbVmomi::VIM::ResourcePool
|
147
|
-
baseEntity = baseEntity.resourcePool.find { |f| f.name == entityArrItem } or nil
|
148
|
-
else
|
149
|
-
baseEntity = nil
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
raise "vSphere ResourcePool not found [#{pool_name}]" if baseEntity.nil?
|
155
|
-
|
156
|
-
baseEntity = baseEntity.resourcePool if not baseEntity.is_a?(RbVmomi::VIM::ResourcePool) and baseEntity.respond_to?(:resourcePool)
|
157
|
-
baseEntity
|
158
|
-
end
|
159
|
-
|
160
|
-
def find_customization_spec(customization_spec)
|
161
|
-
csm = vim.serviceContent.customizationSpecManager
|
162
|
-
csi = csm.GetCustomizationSpec(:name => customization_spec)
|
163
|
-
spec = csi.spec
|
164
|
-
raise "Customization Spec not found [#{customization_spec}]" if spec.nil?
|
165
|
-
spec
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|