chef-metal 0.11.beta.6 → 0.11.beta.7

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
  SHA1:
3
- metadata.gz: 57e203c5e2a58d054e8d303906e5b40d2478ed37
4
- data.tar.gz: 0b8b3b991467d7d834f546f5f43deea6d2082698
3
+ metadata.gz: 5295f868cdb91eb708ae603119f352c45d3ef5fe
4
+ data.tar.gz: fdfde295e6a4085a79052dd4546804263f29b23e
5
5
  SHA512:
6
- metadata.gz: 6e53205b1f8a91b810aac8f45f830194d2a9b6012351d64f7cb51d2da219f71d5aa1cb5a534d710bbaf7a7a2a98041d38dd843149eebd3927e97366a61e70440
7
- data.tar.gz: bfc2fbef95fc8c9692d48621fe4aefb353422742350c79e49a5386af627dfc7aba41140d589f250916abf7c6fd6a290b3fc92b9da56fdce620ab5bf8c0301234
6
+ metadata.gz: b866ac1631345db40f2a8847e7a642dd25e71f6812e5e03c69fa2c24a11ded94cd2252593a2132ab512ca1e0366716809b94d02a94a9e819d077aa518761ff66
7
+ data.tar.gz: 5054683877ed189a7617d543e8aee69862ee19b8cb0fa7b3779da00a9281d3dfd92c31393f5d54a2d4ec066fe107b87bde48fdf303682179042d114cdeaf4365
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Chef Metal Changelog
2
2
 
3
+ ## 0.11.beta.7 (5/30/2014)
4
+
5
+ - fix machine_batch error report to be less verbose
6
+ - allow options to be set from with_driver
7
+ - fail when machine is being moved from driver to driver
8
+ - support knife.rb config for non-canonical URLs
9
+ - @marcusn disconnect from SSH when there is a problem
10
+
3
11
  ## 0.11.beta.6 (5/28/2014)
4
12
 
5
13
  - Fix machine_batch defaults to be significantly less stupid
data/README.md CHANGED
@@ -5,6 +5,10 @@ This library solves the problem of repeatably creating machines and infrastructu
5
5
 
6
6
  Currently, chef-metal supports vagrant, Unixes/ssh, and Windows/winrm with real chef-servers or with automagical chef-zero tunneling. Fog and Docker support (to cover EC2 and LXC) are next up. Further out, we'd like to extend support to image factories (using the machine resource to produce images) and PXE support.
7
7
 
8
+ A NOTE: the upcoming 0.11 has multiple changes and this document is not yet up to date with respect to them. For guides to writing drivers, embedding drivers and configuring Chef Metal, start here:
9
+
10
+ [Chef Metal, Configuration and Drivers](https://github.com/opscode/chef-metal/blob/master/docs/blogs/2012-05-22-new-driver-interface.html.markdown#chef-metal-configuration-and-drivers)
11
+
8
12
  Try It Out
9
13
  ----------
10
14
 
@@ -17,13 +17,16 @@ class Chef::Provider::Machine < Chef::Provider::LWRPBase
17
17
  end
18
18
 
19
19
  action :allocate do
20
- new_driver.allocate_machine(action_handler, machine_spec, machine_options)
20
+ if current_driver && current_driver.driver_url != new_driver.driver_url
21
+ raise "Cannot move '#{machine_spec.name}' from #{current_driver.driver_url} to #{new_driver.driver_url}: machine moving is not supported. Destroy and recreate."
22
+ end
23
+ new_driver.allocate_machine(action_handler, machine_spec, new_machine_options)
21
24
  machine_spec.save(action_handler)
22
25
  end
23
26
 
24
27
  action :ready do
25
28
  action_allocate
26
- machine = current_driver.ready_machine(action_handler, machine_spec, machine_options)
29
+ machine = current_driver.ready_machine(action_handler, machine_spec, current_machine_options)
27
30
  machine_spec.save(action_handler)
28
31
  machine
29
32
  end
@@ -56,7 +59,7 @@ class Chef::Provider::Machine < Chef::Provider::LWRPBase
56
59
  end
57
60
 
58
61
  action :converge_only do
59
- machine = run_context.chef_metal.connect_to_machine(machine_spec, machine_options)
62
+ machine = run_context.chef_metal.connect_to_machine(machine_spec, current_machine_options)
60
63
  begin
61
64
  machine.converge(action_handler)
62
65
  ensure
@@ -66,33 +69,39 @@ class Chef::Provider::Machine < Chef::Provider::LWRPBase
66
69
 
67
70
  action :stop do
68
71
  if current_driver
69
- current_driver.stop_machine(action_handler, machine_spec, machine_options)
72
+ current_driver.stop_machine(action_handler, machine_spec, current_machine_options)
70
73
  end
71
74
  end
72
75
 
73
76
  action :destroy do
74
77
  if current_driver
75
- current_driver.destroy_machine(action_handler, machine_spec, machine_options)
78
+ current_driver.destroy_machine(action_handler, machine_spec, current_machine_options)
76
79
  end
77
80
  end
78
81
 
82
+ attr_reader :machine_spec
83
+
79
84
  def new_driver
80
85
  run_context.chef_metal.driver_for(new_resource.driver)
81
86
  end
82
87
 
83
- def new_driver_config
84
- run_context.chef_metal.driver_config_for(new_resource.driver)
85
- end
86
-
87
88
  def current_driver
88
89
  if machine_spec.driver_url
89
- run_context.chef_metal.driver_for_url(machine_spec.driver_url)
90
+ run_context.chef_metal.driver_for(machine_spec.driver_url)
90
91
  end
91
92
  end
92
93
 
93
- attr_reader :machine_spec
94
+ def new_machine_options
95
+ machine_options(new_driver)
96
+ end
97
+
98
+ def current_machine_options
99
+ if current_driver
100
+ machine_options(current_driver)
101
+ end
102
+ end
94
103
 
95
- def machine_options
104
+ def machine_options(driver)
96
105
  configs = []
97
106
  configs << {
98
107
  :convergence_options =>
@@ -109,7 +118,7 @@ class Chef::Provider::Machine < Chef::Provider::LWRPBase
109
118
  end
110
119
  }
111
120
  configs << new_resource.machine_options if new_resource.machine_options
112
- configs << new_driver_config[:machine_options] if new_driver_config[:machine_options]
121
+ configs << driver.config[:machine_options] if driver.config[:machine_options]
113
122
  Cheffish::MergedConfig.new(*configs)
114
123
  end
115
124
 
@@ -12,6 +12,33 @@ class Chef::Provider::MachineBatch < Chef::Provider::LWRPBase
12
12
  @action_handler ||= ChefMetal::ChefProviderActionHandler.new(self)
13
13
  end
14
14
 
15
+ # We override this because we want to hide @from_recipe
16
+ def to_text
17
+ ivars = instance_variables.map { |ivar| ivar.to_sym } - HIDDEN_IVARS - [ :@from_recipe, :@machines ]
18
+ text = "# Declared in #{@source_line}\n\n"
19
+ text << self.class.dsl_name + "(\"#{name}\") do\n"
20
+ ivars.each do |ivar|
21
+ if (value = instance_variable_get(ivar)) && !(value.respond_to?(:empty?) && value.empty?)
22
+ value_string = value.respond_to?(:to_text) ? value.to_text : value.inspect
23
+ text << " #{ivar.to_s.sub(/^@/,'')} #{value_string}\n"
24
+ end
25
+ end
26
+ machine_names = @machines.map do |m|
27
+ if m.is_a?(ChefMetal::MachineSpec)
28
+ m.name
29
+ elsif m.is_a?(Chef::Resource::Machine)
30
+ m.name
31
+ else
32
+ m
33
+ end
34
+ end
35
+ text << " machines #{machine_names.inspect}"
36
+ [@not_if, @only_if].flatten.each do |conditional|
37
+ text << " #{conditional.to_text}\n"
38
+ end
39
+ text << "end\n"
40
+ end
41
+
15
42
  use_inline_resources
16
43
 
17
44
  def whyrun_supported?
@@ -101,11 +128,22 @@ class Chef::Provider::MachineBatch < Chef::Provider::LWRPBase
101
128
 
102
129
  def by_new_driver
103
130
  result = {}
131
+ drivers = {}
104
132
  @machines.each do |m|
105
133
  if m[:desired_driver]
106
- driver = run_context.chef_metal.driver_for(m[:desired_driver])
134
+ drivers[m[:desired_driver]] ||= run_context.chef_metal.driver_for(m[:desired_driver])
135
+ driver = drivers[m[:desired_driver]]
136
+ # Check whether the current driver is same or different; we disallow
137
+ # moving a machine from one place to another.
138
+ if m[:spec].driver_url
139
+ drivers[m[:spec].driver_url] ||= run_context.chef_metal.driver_for(m[:spec].driver_url)
140
+ current_driver = drivers[m[:spec].driver_url]
141
+ if driver.driver_url != current_driver.driver_url
142
+ raise "Cannot move '#{m[:spec].name}' from #{current_driver.driver_url} to #{driver.driver_url}: machine moving is not supported. Destroy and recreate."
143
+ end
144
+ end
107
145
  result[driver] ||= {}
108
- result[driver][m[:spec]] = m[:options]
146
+ result[driver][m[:spec]] = m[:machine_options].call(driver)
109
147
  end
110
148
  end
111
149
  result
@@ -113,11 +151,13 @@ class Chef::Provider::MachineBatch < Chef::Provider::LWRPBase
113
151
 
114
152
  def by_current_driver
115
153
  result = {}
154
+ drivers = {}
116
155
  @machines.each do |m|
117
156
  if m[:spec].driver_url
118
- driver = run_context.chef_metal.driver_for_url(m[:spec].driver_url)
157
+ drivers[m[:spec].driver_url] ||= run_context.chef_metal.driver_for(m[:spec].driver_url)
158
+ driver = drivers[m[:spec].driver_url]
119
159
  result[driver] ||= {}
120
- result[driver][m[:spec]] = m[:options]
160
+ result[driver][m[:spec]] = m[:machine_options].call(driver)
121
161
  end
122
162
  end
123
163
  result
@@ -134,7 +174,7 @@ class Chef::Provider::MachineBatch < Chef::Provider::LWRPBase
134
174
  :spec => provider.machine_spec,
135
175
  :desired_driver => machine_resource.driver,
136
176
  :files => machine_resource.files,
137
- :options => provider.machine_options
177
+ :machine_options => proc { |driver| provider.machine_options(driver) }
138
178
  }
139
179
  elsif machine.is_a?(ChefMetal::MachineSpec)
140
180
  machine_spec = machine
@@ -142,7 +182,7 @@ class Chef::Provider::MachineBatch < Chef::Provider::LWRPBase
142
182
  :spec => machine_spec,
143
183
  :desired_driver => new_resource.driver,
144
184
  :files => new_resource.files,
145
- :options => new_machine_options
185
+ :machine_options => proc { |driver| machine_options(driver) }
146
186
  }
147
187
  else
148
188
  name = machine
@@ -152,23 +192,17 @@ class Chef::Provider::MachineBatch < Chef::Provider::LWRPBase
152
192
  :spec => machine_spec,
153
193
  :desired_driver => new_resource.driver,
154
194
  :files => new_resource.files,
155
- :options => new_machine_options
195
+ :machine_options => proc { |driver| machine_options(driver) }
156
196
  }
157
197
  end
158
- end.select { |m| !m.nil? }.to_a
198
+ end.to_a
159
199
  end
160
200
 
161
- def new_machine_options
162
- @new_machine_options ||= begin
163
- result = { :convergence_options => { :chef_server => new_resource.chef_server } }
164
- result = Chef::Mixin::DeepMerge.hash_only_merge(result, new_config[:machine_options]) if new_config[:machine_options]
165
- result = Chef::Mixin::DeepMerge.hash_only_merge(result, new_resource.machine_options)
166
- result
167
- end
168
- end
169
-
170
- def new_config
171
- @new_config ||= run_context.chef_metal.driver_config_for(new_resource.driver)
201
+ def machine_options(driver)
202
+ result = { :convergence_options => { :chef_server => new_resource.chef_server } }
203
+ result = Chef::Mixin::DeepMerge.hash_only_merge(result, run_context.chef_metal.config[:machine_options]) if run_context.chef_metal.config[:machine_options]
204
+ result = Chef::Mixin::DeepMerge.hash_only_merge(result, driver.config[:machine_options]) if driver.config && driver.config[:machine_options]
205
+ result = Chef::Mixin::DeepMerge.hash_only_merge(result, new_resource.machine_options)
206
+ result
172
207
  end
173
-
174
208
  end
data/lib/chef_metal.rb CHANGED
@@ -30,23 +30,44 @@ module ChefMetal
30
30
  @@registered_driver_classes[name] = driver
31
31
  end
32
32
 
33
- def self.config_for_url(driver_url, config = Cheffish.profiled_config)
34
- if config && config[:drivers] && config[:drivers][driver_url]
35
- config = Cheffish::MergedConfig.new(config[:drivers][driver_url], config)
36
- end
37
- config || {}
38
- end
39
-
40
33
  def self.default_driver(config = Cheffish.profiled_config)
41
34
  driver_for_url(config[:driver], config)
42
35
  end
43
36
 
44
- def self.driver_for_url(driver_url, config = Cheffish.profiled_config)
45
- cluster_type = driver_url.split(':', 2)[0]
46
- require "chef_metal/driver_init/#{cluster_type}"
47
- driver_class = @@registered_driver_classes[cluster_type]
48
- config = config_for_url(driver_url, config)
49
- driver_class.from_url(driver_url, config || {})
37
+ def self.driver_for_url(driver_url, config = Cheffish.profiled_config, allow_different_config = false)
38
+ #
39
+ # Create and cache the driver
40
+ #
41
+ #
42
+ # Figure out the driver class
43
+ #
44
+ scheme = driver_url.split(':', 2)[0]
45
+ require "chef_metal/driver_init/#{scheme}"
46
+ driver_class = @@registered_driver_classes[scheme]
47
+
48
+ #
49
+ # Merge in any driver-specific config
50
+ #
51
+ if config[:drivers] && config[:drivers][driver_url]
52
+ config = Cheffish::MergedConfig.new(config[:drivers][driver_url], config)
53
+ end
54
+
55
+ #
56
+ # Canonicalize the URL
57
+ #
58
+ canonicalized_url, canonicalized_config = driver_class.canonicalize_url(driver_url, config)
59
+ config = canonicalized_config if canonicalized_config
60
+
61
+ #
62
+ # Merge in config from the canonicalized URL if it is different
63
+ #
64
+ if canonicalized_url != driver_url
65
+ if config[:drivers] && config[:drivers][canonicalized_url]
66
+ config = Cheffish::MergedConfig.new(config[:drivers][canonicalized_url], config)
67
+ end
68
+ end
69
+
70
+ driver_class.from_url(canonicalized_url, config)
50
71
  end
51
72
 
52
73
  def self.connect_to_machine(machine_spec, config = Cheffish.profiled_config)
@@ -13,10 +13,18 @@ module ChefMetal
13
13
 
14
14
  attr_reader :config
15
15
  attr_reader :drivers
16
+ attr_reader :current_driver
16
17
 
17
- with :driver
18
18
  with :machine_options
19
19
 
20
+ def with_driver(driver, options = nil, &block)
21
+ if drivers[driver] && options
22
+ raise "Driver #{driver} has already been created, options #{options} would be ignored!"
23
+ end
24
+ @current_driver = driver
25
+ @current_driver_options = options
26
+ end
27
+
20
28
  def auto_batch_machines
21
29
  if !@auto_batch_machines.nil?
22
30
  @auto_batch_machines
@@ -37,7 +45,7 @@ module ChefMetal
37
45
  if @current_machine_options
38
46
  @current_machine_options
39
47
  else
40
- driver_config_for(current_driver)[:machine_options] || {}
48
+ driver_for(current_driver).config[:machine_options] || {}
41
49
  end
42
50
  end
43
51
 
@@ -49,15 +57,22 @@ module ChefMetal
49
57
  driver.is_a?(String) ? driver_for_url(driver) : driver
50
58
  end
51
59
 
52
- def driver_config_for(driver)
53
- ChefMetal.config_for_url(driver_for(driver).driver_url, config)
54
- end
60
+ private
55
61
 
56
62
  def driver_for_url(driver_url)
57
63
  drivers[driver_url] ||= begin
58
- driver = ChefMetal.driver_for_url(driver_url, config)
64
+ if driver_url == @current_driver && @current_driver_options
65
+ # Use the driver options if available
66
+ merged_config = Cheffish::MergedConfig.new({ :driver_options => @current_driver_options }, config)
67
+ driver = ChefMetal.driver_for_url(driver_url, merged_config)
68
+ else
69
+ driver = ChefMetal.driver_for_url(driver_url, config)
70
+ end
59
71
  # Check the canonicalized driver_url from the driver
60
72
  if driver.driver_url != driver_url
73
+ if drivers[driver.driver_url] && @current_driver_options
74
+ raise "Canonical driver #{driver.driver_url} for #{driver_url} has already been created! Current options #{@current_driver_options} would be ignored."
75
+ end
61
76
  drivers[driver.driver_url] ||= driver
62
77
  else
63
78
  driver
@@ -13,8 +13,8 @@ require 'chef/provider/machine_execute'
13
13
  class Chef
14
14
  module DSL
15
15
  module Recipe
16
- def with_driver(driver, &block)
17
- run_context.chef_metal.with_driver(driver, &block)
16
+ def with_driver(driver, options = nil, &block)
17
+ run_context.chef_metal.with_driver(driver, options, &block)
18
18
  end
19
19
 
20
20
  def with_machine_options(machine_options, &block)
@@ -125,8 +125,9 @@ module ChefMetal
125
125
  Chef::Log.debug("Closing SSH session on #{username}@#{host}")
126
126
  @session.close
127
127
  rescue
128
+ ensure
129
+ @session = nil
128
130
  end
129
- @session = nil
130
131
  end
131
132
  end
132
133
 
@@ -136,37 +137,16 @@ module ChefMetal
136
137
  true
137
138
  rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET, Net::SSH::Disconnect
138
139
  Chef::Log.debug("#{username}@#{host} unavailable: network connection failed or broke: #{$!.inspect}")
140
+ disconnect
139
141
  false
140
142
  rescue Net::SSH::AuthenticationFailed, Net::SSH::HostKeyMismatch
141
143
  Chef::Log.debug("#{username}@#{host} unavailable: SSH authentication error: #{$!.inspect} ")
144
+ disconnect
142
145
  false
143
146
  end
144
147
 
145
148
  protected
146
149
 
147
- def gateway?
148
- options.key?(:ssh_gateway) and ! options[:ssh_gateway].nil?
149
- end
150
-
151
- def gateway
152
- @gateway ||= begin
153
- gw_host, gw_user = options[:ssh_gateway].split('@').reverse
154
- gw_host, gw_port = gw_host.split(':')
155
- gw_user = ssh_options[:ssh_username] unless gw_user
156
-
157
- ssh_start_opts = { timeout:10 }.merge(ssh_options)
158
- ssh_start_opts[:port] = gw_port || 22
159
-
160
- Chef::Log.debug("Opening SSH gateway to #{gw_user}@#{gw_host} with options #{ssh_start_opts.inspect}")
161
- begin
162
- Net::SSH::Gateway.new(gw_host, gw_user, ssh_start_opts)
163
- rescue Errno::ETIMEDOUT
164
- Chef::Log.debug("Timed out connecting to gateway: #{$!}")
165
- raise InitialConnectTimeout.new($!)
166
- end
167
- end
168
- end
169
-
170
150
  def session
171
151
  @session ||= begin
172
152
  ssh_start_opts = { timeout:10 }.merge(ssh_options)
@@ -230,6 +210,29 @@ module ChefMetal
230
210
 
231
211
  attr_reader :original_error
232
212
  end
213
+
214
+ private
215
+
216
+ def gateway?
217
+ options.key?(:ssh_gateway) and ! options[:ssh_gateway].nil?
218
+ end
219
+
220
+ def gateway
221
+ gw_host, gw_user = options[:ssh_gateway].split('@').reverse
222
+ gw_host, gw_port = gw_host.split(':')
223
+ gw_user = ssh_options[:ssh_username] unless gw_user
224
+
225
+ ssh_start_opts = { timeout:10 }.merge(ssh_options)
226
+ ssh_start_opts[:port] = gw_port || 22
227
+
228
+ Chef::Log.debug("Opening SSH gateway to #{gw_user}@#{gw_host} with options #{ssh_start_opts.inspect}")
229
+ begin
230
+ Net::SSH::Gateway.new(gw_host, gw_user, ssh_start_opts)
231
+ rescue Errno::ETIMEDOUT
232
+ Chef::Log.debug("Timed out connecting to gateway: #{$!}")
233
+ raise InitialConnectTimeout.new($!)
234
+ end
235
+ end
233
236
  end
234
237
  end
235
238
  end
@@ -1,3 +1,3 @@
1
1
  module ChefMetal
2
- VERSION = '0.11.beta.6'
2
+ VERSION = '0.11.beta.7'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-metal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.beta.6
4
+ version: 0.11.beta.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Keiser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-29 00:00:00.000000000 Z
11
+ date: 2014-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef
@@ -86,42 +86,42 @@ dependencies:
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.5.beta.3
89
+ version: 0.5.beta.4
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.5.beta.3
96
+ version: 0.5.beta.4
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: chef-metal-fog
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 0.5.beta.2
103
+ version: 0.5.beta.3
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 0.5.beta.2
110
+ version: 0.5.beta.3
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: chef-metal-vagrant
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 0.4.beta
117
+ version: 0.4.beta.2
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 0.4.beta
124
+ version: 0.4.beta.2
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rspec
127
127
  requirement: !ruby/object:Gem::Requirement