chef-metal 0.14.2 → 0.15

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.
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