chef-metal 0.14.2 → 0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -1
  3. data/README.md +2 -257
  4. data/Rakefile +0 -4
  5. data/lib/chef_metal.rb +1 -87
  6. data/lib/chef_metal/action_handler.rb +1 -66
  7. data/lib/chef_metal/add_prefix_action_handler.rb +1 -29
  8. data/lib/chef_metal/chef_image_spec.rb +1 -106
  9. data/lib/chef_metal/chef_machine_spec.rb +1 -82
  10. data/lib/chef_metal/chef_provider_action_handler.rb +1 -72
  11. data/lib/chef_metal/chef_run_data.rb +1 -125
  12. data/lib/chef_metal/convergence_strategy.rb +1 -26
  13. data/lib/chef_metal/convergence_strategy/install_cached.rb +1 -157
  14. data/lib/chef_metal/convergence_strategy/install_msi.rb +1 -56
  15. data/lib/chef_metal/convergence_strategy/install_sh.rb +1 -53
  16. data/lib/chef_metal/convergence_strategy/no_converge.rb +1 -37
  17. data/lib/chef_metal/convergence_strategy/precreate_chef_objects.rb +1 -181
  18. data/lib/chef_metal/driver.rb +1 -288
  19. data/lib/chef_metal/image_spec.rb +1 -70
  20. data/lib/chef_metal/machine.rb +1 -110
  21. data/lib/chef_metal/machine/basic_machine.rb +1 -82
  22. data/lib/chef_metal/machine/unix_machine.rb +1 -276
  23. data/lib/chef_metal/machine/windows_machine.rb +1 -102
  24. data/lib/chef_metal/machine_spec.rb +1 -78
  25. data/lib/chef_metal/recipe_dsl.rb +1 -94
  26. data/lib/chef_metal/transport.rb +1 -87
  27. data/lib/chef_metal/transport/ssh.rb +1 -288
  28. data/lib/chef_metal/transport/winrm.rb +1 -134
  29. data/lib/chef_metal/version.rb +1 -3
  30. metadata +19 -145
  31. data/bin/metal +0 -275
  32. data/lib/chef/provider/machine.rb +0 -171
  33. data/lib/chef/provider/machine_batch.rb +0 -186
  34. data/lib/chef/provider/machine_execute.rb +0 -30
  35. data/lib/chef/provider/machine_file.rb +0 -49
  36. data/lib/chef/provider/machine_image.rb +0 -54
  37. data/lib/chef/resource/machine.rb +0 -116
  38. data/lib/chef/resource/machine_batch.rb +0 -72
  39. data/lib/chef/resource/machine_execute.rb +0 -22
  40. data/lib/chef/resource/machine_file.rb +0 -28
  41. data/lib/chef/resource/machine_image.rb +0 -29
@@ -1,134 +1 @@
1
- require 'chef_metal/transport'
2
- require 'base64'
3
- require 'timeout'
4
-
5
- module ChefMetal
6
- class Transport
7
- class WinRM < ChefMetal::Transport
8
- def initialize(endpoint, type, options, global_config)
9
- @endpoint = endpoint
10
- @type = type
11
- @options = options
12
- @config = global_config
13
- end
14
-
15
- attr_reader :endpoint
16
- attr_reader :type
17
- attr_reader :options
18
- attr_reader :config
19
-
20
- def execute(command, execute_options = {})
21
- output = with_execute_timeout(execute_options) do
22
- session.set_timeout(execute_timeout(execute_options))
23
- session.run_powershell_script(command) do |stdout, stderr|
24
- stream_chunk(execute_options, stdout, stderr)
25
- end
26
- end
27
- WinRMResult.new(command, execute_options, config, output)
28
- end
29
-
30
- def read_file(path)
31
- result = execute("[Convert]::ToBase64String((Get-Content #{escape(path)} -Encoding byte -ReadCount 0))")
32
- if result.exitstatus == 0
33
- Base64.decode64(result.stdout)
34
- else
35
- nil
36
- end
37
- end
38
-
39
- def write_file(path, content)
40
- chunk_size = options[:chunk_size] || 1024
41
- # TODO if we could marshal this data directly, we wouldn't have to base64 or do this godawful slow stuff :(
42
- index = 0
43
- execute("
44
- $ByteArray = [System.Convert]::FromBase64String(#{escape(Base64.encode64(content[index..index+chunk_size-1]))})
45
- $file = [System.IO.File]::Open(#{escape(path)}, 'Create', 'Write')
46
- $file.Write($ByteArray, 0, $ByteArray.Length)
47
- $file.Close
48
- ").error!
49
- index += chunk_size
50
- while index < content.length
51
- execute("
52
- $ByteArray = [System.Convert]::FromBase64String(#{escape(Base64.encode64(content[index..index+chunk_size-1]))})
53
- $file = [System.IO.File]::Open(#{escape(path)}, 'Append', 'Write')
54
- $file.Write($ByteArray, 0, $ByteArray.Length)
55
- $file.Close
56
- ").error!
57
- index += chunk_size
58
- end
59
- end
60
-
61
- def disconnect
62
- #
63
- end
64
-
65
- def escape(string)
66
- "\"#{string.gsub("\"", "`\"")}\""
67
- end
68
-
69
- def available?
70
- # If you can't pwd within 10 seconds, you can't pwd
71
- execute('pwd', :timeout => 10)
72
- true
73
- rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET, ::WinRM::WinRMHTTPTransportError, ::WinRM::WinRMWebServiceError, ::WinRM::WinRMWSManFault
74
- Chef::Log.debug("unavailable: network connection failed or broke: #{$!.inspect}")
75
- disconnect
76
- false
77
- rescue ::WinRM::WinRMAuthorizationError
78
- Chef::Log.debug("unavailable: winrm authentication error: #{$!.inspect} ")
79
- disconnect
80
- false
81
- end
82
-
83
- def make_url_available_to_remote(local_url)
84
- uri = URI(local_url)
85
- host = Socket.getaddrinfo(uri.host, uri.scheme, nil, :STREAM)[0][3]
86
- if host == '127.0.0.1' || host == '::1'
87
- raise 'Unable to converge locally via winrm. Local converge is currently only supported with SSH. You may only converge with winrm against a chef-server.'
88
- end
89
- local_url
90
- end
91
-
92
- protected
93
-
94
- def session
95
- @session ||= begin
96
- require 'kconv' # Really, people? *sigh*
97
- require 'winrm'
98
- ::WinRM::WinRMWebService.new(endpoint, type, options)
99
- end
100
- end
101
-
102
- class WinRMResult
103
- def initialize(command, options, config, output)
104
- @command = command
105
- @options = options
106
- @config = config
107
- @exitstatus = output[:exitcode]
108
- @stdout = ''
109
- @stderr = ''
110
- output[:data].each do |data|
111
- @stdout << data[:stdout] if data[:stdout]
112
- @stderr << data[:stderr] if data[:stderr]
113
- end
114
- end
115
-
116
- attr_reader :stdout
117
- attr_reader :stderr
118
- attr_reader :exitstatus
119
- attr_reader :command
120
- attr_reader :options
121
- attr_reader :config
122
-
123
- def error!
124
- if exitstatus != 0
125
- msg = "Error: command '#{command}' exited with code #{exitstatus}.\n"
126
- msg << "STDOUT: #{stdout}" if !options[:stream] && !options[:stream_stdout] && config[:log_level] != :debug
127
- msg << "STDERR: #{stderr}" if !options[:stream] && !options[:stream_stderr] && config[:log_level] != :debug
128
- raise msg
129
- end
130
- end
131
- end
132
- end
133
- end
134
- end
1
+ require "chef/provisioning/transport/winrm"
@@ -1,3 +1 @@
1
- module ChefMetal
2
- VERSION = '0.14.2'
3
- end
1
+ require "chef/provisioning/version"
metadata CHANGED
@@ -1,192 +1,65 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-metal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.2
4
+ version: '0.15'
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-09-04 00:00:00.000000000 Z
11
+ date: 2014-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: chef
14
+ name: chef-provisioning
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: net-ssh
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ~>
32
- - !ruby/object:Gem::Version
33
- version: '2.0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ~>
39
- - !ruby/object:Gem::Version
40
- version: '2.0'
41
- - !ruby/object:Gem::Dependency
42
- name: net-scp
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ~>
46
- - !ruby/object:Gem::Version
47
- version: '1.0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ~>
53
- - !ruby/object:Gem::Version
54
- version: '1.0'
55
- - !ruby/object:Gem::Dependency
56
- name: net-ssh-gateway
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: 1.2.0
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ~>
67
- - !ruby/object:Gem::Version
68
- version: 1.2.0
69
- - !ruby/object:Gem::Dependency
70
- name: inifile
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ~>
74
- - !ruby/object:Gem::Version
75
- version: '2.0'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ~>
81
- - !ruby/object:Gem::Version
82
- version: '2.0'
83
- - !ruby/object:Gem::Dependency
84
- name: cheffish
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ~>
88
- - !ruby/object:Gem::Version
89
- version: '0.5'
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ~>
95
- - !ruby/object:Gem::Version
96
- version: '0.5'
97
- - !ruby/object:Gem::Dependency
98
- name: winrm
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ~>
102
- - !ruby/object:Gem::Version
103
- version: 1.1.3
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ~>
109
- - !ruby/object:Gem::Version
110
- version: 1.1.3
111
- - !ruby/object:Gem::Dependency
112
- name: rspec
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - '>='
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - '>='
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: rake
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - '>='
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - '>='
24
+ - - ">="
137
25
  - !ruby/object:Gem::Version
138
26
  version: '0'
139
27
  description: A library for creating machines and infrastructures idempotently in Chef.
140
- email: jkeiser@opscode.com
141
- executables:
142
- - metal
28
+ email: jkeiser@getchef.com
29
+ executables: []
143
30
  extensions: []
144
- extra_rdoc_files:
145
- - README.md
146
- - CHANGELOG.md
147
- - LICENSE
31
+ extra_rdoc_files: []
148
32
  files:
149
- - Rakefile
33
+ - CHANGELOG.md
150
34
  - LICENSE
151
35
  - README.md
152
- - CHANGELOG.md
153
- - lib/chef/provider/machine.rb
154
- - lib/chef/provider/machine_batch.rb
155
- - lib/chef/provider/machine_execute.rb
156
- - lib/chef/provider/machine_file.rb
157
- - lib/chef/provider/machine_image.rb
158
- - lib/chef/resource/machine.rb
159
- - lib/chef/resource/machine_batch.rb
160
- - lib/chef/resource/machine_execute.rb
161
- - lib/chef/resource/machine_file.rb
162
- - lib/chef/resource/machine_image.rb
36
+ - Rakefile
37
+ - lib/chef_metal.rb
163
38
  - lib/chef_metal/action_handler.rb
164
39
  - lib/chef_metal/add_prefix_action_handler.rb
165
40
  - lib/chef_metal/chef_image_spec.rb
166
41
  - lib/chef_metal/chef_machine_spec.rb
167
42
  - lib/chef_metal/chef_provider_action_handler.rb
168
43
  - lib/chef_metal/chef_run_data.rb
44
+ - lib/chef_metal/convergence_strategy.rb
169
45
  - lib/chef_metal/convergence_strategy/install_cached.rb
170
46
  - lib/chef_metal/convergence_strategy/install_msi.rb
171
47
  - lib/chef_metal/convergence_strategy/install_sh.rb
172
48
  - lib/chef_metal/convergence_strategy/no_converge.rb
173
49
  - lib/chef_metal/convergence_strategy/precreate_chef_objects.rb
174
- - lib/chef_metal/convergence_strategy.rb
175
50
  - lib/chef_metal/driver.rb
176
51
  - lib/chef_metal/image_spec.rb
52
+ - lib/chef_metal/machine.rb
177
53
  - lib/chef_metal/machine/basic_machine.rb
178
54
  - lib/chef_metal/machine/unix_machine.rb
179
55
  - lib/chef_metal/machine/windows_machine.rb
180
- - lib/chef_metal/machine.rb
181
56
  - lib/chef_metal/machine_spec.rb
182
57
  - lib/chef_metal/recipe_dsl.rb
58
+ - lib/chef_metal/transport.rb
183
59
  - lib/chef_metal/transport/ssh.rb
184
60
  - lib/chef_metal/transport/winrm.rb
185
- - lib/chef_metal/transport.rb
186
61
  - lib/chef_metal/version.rb
187
- - lib/chef_metal.rb
188
- - bin/metal
189
- homepage: http://wiki.opscode.com/display/chef
62
+ homepage: http://github.com/opscode/chef-metal
190
63
  licenses: []
191
64
  metadata: {}
192
65
  post_install_message:
@@ -195,18 +68,19 @@ require_paths:
195
68
  - lib
196
69
  required_ruby_version: !ruby/object:Gem::Requirement
197
70
  requirements:
198
- - - '>='
71
+ - - ">="
199
72
  - !ruby/object:Gem::Version
200
73
  version: '0'
201
74
  required_rubygems_version: !ruby/object:Gem::Requirement
202
75
  requirements:
203
- - - '>='
76
+ - - ">="
204
77
  - !ruby/object:Gem::Version
205
78
  version: '0'
206
79
  requirements: []
207
80
  rubyforge_project:
208
- rubygems_version: 2.0.14
81
+ rubygems_version: 2.2.2
209
82
  signing_key:
210
83
  specification_version: 4
211
84
  summary: A library for creating machines and infrastructures idempotently in Chef.
212
85
  test_files: []
86
+ has_rdoc:
data/bin/metal DELETED
@@ -1,275 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
5
- require 'chef_metal'
6
- require 'chef/rest'
7
- require 'chef/application'
8
- require 'chef/knife'
9
- require 'chef/run_context'
10
- require 'chef/server_api'
11
- require 'chef_metal/action_handler'
12
- require 'chef_metal/version'
13
- require 'chef_metal/chef_machine_spec'
14
-
15
- class ChefMetal::Application < Chef::Application
16
-
17
- # Mimic self_pipe sleep from Unicorn to capture signals safely
18
- SELF_PIPE = []
19
-
20
- option :config_file,
21
- :short => "-c CONFIG",
22
- :long => "--config CONFIG",
23
- :description => "The configuration file to use"
24
-
25
- option :log_level,
26
- :short => "-l LEVEL",
27
- :long => "--log_level LEVEL",
28
- :description => "Set the log level (debug, info, warn, error, fatal)",
29
- :proc => lambda { |l| l.to_sym }
30
-
31
- option :log_location,
32
- :short => "-L LOGLOCATION",
33
- :long => "--logfile LOGLOCATION",
34
- :description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
35
- :proc => nil
36
-
37
- option :node_name,
38
- :short => "-N NODE_NAME",
39
- :long => "--node-name NODE_NAME",
40
- :description => "The node name for this client",
41
- :proc => nil
42
-
43
- option :chef_server_url,
44
- :short => "-S CHEFSERVERURL",
45
- :long => "--server CHEFSERVERURL",
46
- :description => "The chef server URL",
47
- :proc => nil
48
-
49
- option :client_key,
50
- :short => "-k KEY_FILE",
51
- :long => "--client_key KEY_FILE",
52
- :description => "Set the client key file location",
53
- :proc => nil
54
-
55
- option :local_mode,
56
- :short => "-z",
57
- :long => "--local-mode",
58
- :description => "Point chef-client at local repository",
59
- :boolean => true
60
-
61
- option :chef_repo_path,
62
- :long => '--chef-repo-path=PATH',
63
- :description => "Path to Chef repository"
64
-
65
- option :chef_zero_port,
66
- :long => "--chef-zero-port PORT",
67
- :description => "Port to start chef-zero on"
68
-
69
- option :read_only,
70
- :long => "--[no-]read-only",
71
- :description => "Promise that execution will not modify the machine (helps with Docker in particular)"
72
-
73
- option :stream,
74
- :long => "--[no-]stream",
75
- :default => true,
76
- :boolean => true,
77
- :description => "Whether to stream output from the machine (default: true)"
78
-
79
- option :timeout,
80
- :long => "--timeout=TIMEOUT",
81
- :default => 15*60,
82
- :description => "Time to wait for program to execute, or 0 for no timeout (default: 15 minutes)"
83
-
84
- def reconfigure
85
- super
86
-
87
- Chef::Config.chef_server_url = config[:chef_server_url] if config.has_key? :chef_server_url
88
-
89
- Chef::Config.chef_repo_path = config[:chef_repo_path] if config.has_key? :chef_repo_path
90
-
91
- Chef::Config.local_mode = config[:local_mode] if config.has_key?(:local_mode)
92
- if Chef::Config.local_mode && !Chef::Config.has_key?(:cookbook_path) && !Chef::Config.has_key?(:chef_repo_path)
93
- Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Dir.pwd)
94
- end
95
- Chef::Config.chef_zero.port = config[:chef_zero_port] if config[:chef_zero_port]
96
- end
97
-
98
- def setup_application
99
- end
100
-
101
- def load_config_file
102
- if !config.has_key?(:config_file)
103
- require 'chef/knife'
104
- config[:config_file] = Chef::Knife.locate_config_file
105
- end
106
- super
107
- end
108
-
109
- def run_application
110
- exit_code = 0
111
-
112
- Cheffish.honor_local_mode do
113
- command = cli_arguments.shift
114
- case command
115
- when 'execute'
116
- connect_to_machines(cli_arguments.shift) do |machine|
117
- result = machine.execute(action_handler, cli_arguments.join(' '), :read_only => config[:read_only], :stream => config[:stream], :timeout => config[:timeout].to_f)
118
- puts result.stdout if result.stdout != '' && !config[:stream] && Chef::Config.log_level != :debug
119
- STDERR.puts result.stderr if result.stderr != '' && !config[:stream] && Chef::Config.log_level != :debug
120
- exit_code = result.exitstatus if result.exitstatus != 0
121
- end
122
- when 'destroy'
123
- each_current_machine(cli_arguments.shift) do |driver, specs_and_options|
124
- driver.destroy_machines(action_handler, specs_and_options, parallelizer)
125
- end
126
- when 'allocate'
127
- each_new_machine(cli_arguments.shift) do |driver, specs_and_options|
128
- driver.allocate_machines(action_handler, specs_and_options, parallelizer)
129
- end
130
- when 'ready'
131
- each_new_machine(cli_arguments.shift) do |driver, specs_and_options|
132
- driver.allocate_machines(action_handler, specs_and_options, parallelizer)
133
- driver.ready_machines(action_handler, specs_and_options, parallelizer)
134
- end
135
- when 'setup'
136
- each_new_machine(cli_arguments.shift) do |driver, specs_and_options|
137
- driver.allocate_machines(action_handler, specs_and_options, parallelizer)
138
- driver.ready_machines(action_handler, specs_and_options, parallelizer) do |machine|
139
- machine.setup_convergence(action_handler)
140
- end
141
- end
142
- when 'converge'
143
- each_new_machine(cli_arguments.shift) do |driver, specs_and_options|
144
- driver.allocate_machines(action_handler, specs_and_options, parallelizer)
145
- driver.ready_machines(action_handler, specs_and_options, parallelizer) do |machine|
146
- # TODO upload files? Maybe they should be in machine_options?
147
- machine.setup_convergence(action_handler)
148
- machine.converge(action_handler)
149
- end
150
- end
151
- when 'reconverge'
152
- connect_to_machines(cli_arguments.shift) do |machine|
153
- machine.converge(action_handler)
154
- end
155
- when 'stop'
156
- each_current_machine(cli_arguments.shift) do |driver, specs_and_options|
157
- driver.stop_machines(action_handler, specs_and_options, parallelizer)
158
- end
159
- when 'cat'
160
- connect_to_machines(cli_arguments.shift) do |machine|
161
- cli_arguments.each do |remote_path|
162
- puts machine.read_file(remote_path)
163
- end
164
- end
165
- when 'cp'
166
- machines = {}
167
- to = cli_arguments.pop
168
- if to =~ /^([^\/:]+):(.+)$/
169
- to_server = $1
170
- machines[to_server] ||= ChefMetal.connect_to_machine(to_server)
171
- to_path = $2
172
- to_is_directory = machines[to_server].is_directory?(to_path)
173
- else
174
- to_server = nil
175
- to_path = File.absolute_path(to)
176
- end
177
-
178
- cli_arguments.each do |from|
179
- if from =~ /^([^\/:]+):(.+)$/
180
- from_server = $1
181
- from_path = $2
182
- if to_server
183
- raise "Cannot copy from one server to another, or intraserver (from=#{from}, to=#{to})"
184
- end
185
-
186
- machines[from_server] ||= connect_to_machine(from_server)
187
- if File.directory?(to_path)
188
- machines[from_server].download_file(action_handler, from_path, "#{to_path}/#{File.basename(from_path)}")
189
- else
190
- machines[from_server].download_file(action_handler, from_path, to_path)
191
- end
192
- else
193
- from_server = nil
194
- from_path = File.absolute_path(from)
195
- if !to_server
196
- raise "Cannot copy two local files. One of the arguments must be MACHINE:PATH. (from=#{from}, to=#{to})"
197
- end
198
-
199
- if to_is_directory
200
- machines[to_server].upload_file(action_handler, from_path, "#{to_path}/#{File.basename(from_path)}")
201
- else
202
- machines[to_server].upload_file(action_handler, from_path, to_path)
203
- end
204
- end
205
- end
206
- else
207
- Chef::Log.error("Command '#{command}' unrecognized")
208
- end
209
- end
210
-
211
- exit(exit_code) if exit_code != 0
212
- end
213
-
214
- private
215
-
216
- def rest
217
- @rest ||= Chef::ServerAPI.new()
218
- end
219
-
220
- def machine_specs(*specs)
221
- names = specs.collect_concat { |spec| spec.split(',') }.uniq
222
- parallelizer.parallelize(names) { |name| ChefMetal::ChefMachineSpec.get(name) }.to_a
223
- end
224
-
225
- def each_new_machine(spec)
226
- driver = ChefMetal.default_driver
227
- specs_and_options = {}
228
- machine_specs(spec).each do |machine_spec|
229
- specs_and_options[machine_spec] = driver.config[:machine_options]
230
- end
231
- [ [ driver, specs_and_options ] ]
232
- end
233
-
234
- def each_current_machine(spec)
235
- grouped = machine_specs(spec).group_by { |machine_spec| machine_spec.driver_url }
236
- parallelizer.parallelize(grouped) do |driver_url, machine_specs|
237
- if driver_url
238
- driver = ChefMetal.driver_for_url(driver_url)
239
- specs_and_options = {}
240
- machine_specs(spec).each do |machine_spec|
241
- specs_and_options[machine_spec] = driver.config[:machine_options]
242
- end
243
- yield driver, specs_and_options
244
- end
245
- end.to_a
246
- end
247
-
248
- def connect_to_machines(spec)
249
- machine_specs(spec).each do |machine_spec|
250
- yield ChefMetal.connect_to_machine(machine_spec)
251
- end
252
- end
253
-
254
- def parallelizer
255
- Chef::ChefFS::Parallelizer
256
- end
257
-
258
- def action_handler
259
- @action_handler ||= ActionHandler.new
260
- end
261
-
262
- class ActionHandler < ChefMetal::ActionHandler
263
- def recipe_context
264
- # TODO: somehow remove this code; should context really always be needed?
265
- node = Chef::Node.new
266
- node.name 'nothing'
267
- node.automatic[:platform] = 'metal'
268
- node.automatic[:platform_version] = ChefMetal::VERSION
269
- Chef::RunContext.new(node, {},
270
- Chef::EventDispatch::Dispatcher.new(Chef::Formatters::Doc.new(STDOUT,STDERR)))
271
- end
272
- end
273
- end
274
-
275
- ChefMetal::Application.new.run