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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/README.md +2 -257
- data/Rakefile +0 -4
- data/lib/chef_metal.rb +1 -87
- data/lib/chef_metal/action_handler.rb +1 -66
- data/lib/chef_metal/add_prefix_action_handler.rb +1 -29
- data/lib/chef_metal/chef_image_spec.rb +1 -106
- data/lib/chef_metal/chef_machine_spec.rb +1 -82
- data/lib/chef_metal/chef_provider_action_handler.rb +1 -72
- data/lib/chef_metal/chef_run_data.rb +1 -125
- data/lib/chef_metal/convergence_strategy.rb +1 -26
- data/lib/chef_metal/convergence_strategy/install_cached.rb +1 -157
- data/lib/chef_metal/convergence_strategy/install_msi.rb +1 -56
- data/lib/chef_metal/convergence_strategy/install_sh.rb +1 -53
- data/lib/chef_metal/convergence_strategy/no_converge.rb +1 -37
- data/lib/chef_metal/convergence_strategy/precreate_chef_objects.rb +1 -181
- data/lib/chef_metal/driver.rb +1 -288
- data/lib/chef_metal/image_spec.rb +1 -70
- data/lib/chef_metal/machine.rb +1 -110
- data/lib/chef_metal/machine/basic_machine.rb +1 -82
- data/lib/chef_metal/machine/unix_machine.rb +1 -276
- data/lib/chef_metal/machine/windows_machine.rb +1 -102
- data/lib/chef_metal/machine_spec.rb +1 -78
- data/lib/chef_metal/recipe_dsl.rb +1 -94
- data/lib/chef_metal/transport.rb +1 -87
- data/lib/chef_metal/transport/ssh.rb +1 -288
- data/lib/chef_metal/transport/winrm.rb +1 -134
- data/lib/chef_metal/version.rb +1 -3
- metadata +19 -145
- data/bin/metal +0 -275
- data/lib/chef/provider/machine.rb +0 -171
- data/lib/chef/provider/machine_batch.rb +0 -186
- data/lib/chef/provider/machine_execute.rb +0 -30
- data/lib/chef/provider/machine_file.rb +0 -49
- data/lib/chef/provider/machine_image.rb +0 -54
- data/lib/chef/resource/machine.rb +0 -116
- data/lib/chef/resource/machine_batch.rb +0 -72
- data/lib/chef/resource/machine_execute.rb +0 -22
- data/lib/chef/resource/machine_file.rb +0 -28
- data/lib/chef/resource/machine_image.rb +0 -29
@@ -1,134 +1 @@
|
|
1
|
-
require
|
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"
|
data/lib/chef_metal/version.rb
CHANGED
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.
|
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-
|
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@
|
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
|
-
-
|
33
|
+
- CHANGELOG.md
|
150
34
|
- LICENSE
|
151
35
|
- README.md
|
152
|
-
-
|
153
|
-
- lib/
|
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
|
-
|
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.
|
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
|