chef-metal 0.7 → 0.8
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 +6 -0
- data/bin/metal +142 -0
- data/lib/chef/provider/machine_execute.rb +27 -0
- data/lib/chef/resource/machine_execute.rb +23 -0
- data/lib/chef_metal.rb +2 -0
- data/lib/chef_metal/convergence_strategy/install_cached.rb +1 -1
- data/lib/chef_metal/convergence_strategy/install_sh.rb +1 -1
- data/lib/chef_metal/driver.rb +86 -0
- data/lib/chef_metal/instance.rb +54 -0
- data/lib/chef_metal/machine.rb +5 -1
- data/lib/chef_metal/machine/basic_machine.rb +4 -4
- data/lib/chef_metal/transport.rb +25 -1
- data/lib/chef_metal/transport/ssh.rb +17 -8
- data/lib/chef_metal/transport/winrm.rb +18 -7
- data/lib/chef_metal/version.rb +1 -1
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9811bbe55b66c09c1a01be9e87b80b918f2c5428
|
4
|
+
data.tar.gz: 1e5f30552fb823c7e11c9df9e1e08d5682604556
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e94c8a56ae93cdb19752de8ce82c33c5954def45c751b472d941c1c68242c03086fc50daa3f94bc4a9d87763049eea99e4b70b10312f738fa6e78fc768ec53f5
|
7
|
+
data.tar.gz: 91d84206a6fdcb0120f090255e4137e64b98a954c1af11e25bd8db127073744a9bdaad9ebde088d9ec3f96925ef07f87b6f7522ce7652b54f137b04c2b5ba779
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Chef Metal Changelog
|
2
2
|
|
3
|
+
## 0.8 (4/8/2014)
|
4
|
+
|
5
|
+
- New machine_execute resource! (irving@getchef.com)
|
6
|
+
- Experimental "metal" command line: metal execute NODENAME COMMAND ARGS
|
7
|
+
- Transport: Add ability to stream execute() for better nested chef-client debugging
|
8
|
+
|
3
9
|
## 0.7 (4/5/2014)
|
4
10
|
|
5
11
|
- Change transport interface: add ability to rewrite URL instead of forwarding ports
|
data/bin/metal
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
5
|
+
require 'chef'
|
6
|
+
require 'chef_metal'
|
7
|
+
require 'chef/rest'
|
8
|
+
require 'chef/application'
|
9
|
+
require 'chef/knife'
|
10
|
+
require 'chef/server_api'
|
11
|
+
|
12
|
+
class ChefMetal::Application < Chef::Application
|
13
|
+
|
14
|
+
# Mimic self_pipe sleep from Unicorn to capture signals safely
|
15
|
+
SELF_PIPE = []
|
16
|
+
|
17
|
+
option :config_file,
|
18
|
+
:short => "-c CONFIG",
|
19
|
+
:long => "--config CONFIG",
|
20
|
+
:description => "The configuration file to use"
|
21
|
+
|
22
|
+
option :log_level,
|
23
|
+
:short => "-l LEVEL",
|
24
|
+
:long => "--log_level LEVEL",
|
25
|
+
:description => "Set the log level (debug, info, warn, error, fatal)",
|
26
|
+
:proc => lambda { |l| l.to_sym }
|
27
|
+
|
28
|
+
option :log_location,
|
29
|
+
:short => "-L LOGLOCATION",
|
30
|
+
:long => "--logfile LOGLOCATION",
|
31
|
+
:description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
|
32
|
+
:proc => nil
|
33
|
+
|
34
|
+
option :node_name,
|
35
|
+
:short => "-N NODE_NAME",
|
36
|
+
:long => "--node-name NODE_NAME",
|
37
|
+
:description => "The node name for this client",
|
38
|
+
:proc => nil
|
39
|
+
|
40
|
+
option :chef_server_url,
|
41
|
+
:short => "-S CHEFSERVERURL",
|
42
|
+
:long => "--server CHEFSERVERURL",
|
43
|
+
:description => "The chef server URL",
|
44
|
+
:proc => nil
|
45
|
+
|
46
|
+
option :client_key,
|
47
|
+
:short => "-k KEY_FILE",
|
48
|
+
:long => "--client_key KEY_FILE",
|
49
|
+
:description => "Set the client key file location",
|
50
|
+
:proc => nil
|
51
|
+
|
52
|
+
option :local_mode,
|
53
|
+
:short => "-z",
|
54
|
+
:long => "--local-mode",
|
55
|
+
:description => "Point chef-client at local repository",
|
56
|
+
:boolean => true
|
57
|
+
|
58
|
+
option :chef_zero_port,
|
59
|
+
:long => "--chef-zero-port PORT",
|
60
|
+
:description => "Port to start chef-zero on"
|
61
|
+
|
62
|
+
def reconfigure
|
63
|
+
super
|
64
|
+
|
65
|
+
Chef::Config[:chef_server_url] = config[:chef_server_url] if config.has_key? :chef_server_url
|
66
|
+
|
67
|
+
Chef::Config.local_mode = config[:local_mode] if config.has_key?(:local_mode)
|
68
|
+
if Chef::Config.local_mode && !Chef::Config.has_key?(:cookbook_path) && !Chef::Config.has_key?(:chef_repo_path)
|
69
|
+
Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Dir.pwd)
|
70
|
+
end
|
71
|
+
Chef::Config.chef_zero.port = config[:chef_zero_port] if config[:chef_zero_port]
|
72
|
+
|
73
|
+
if Chef::Config[:daemonize]
|
74
|
+
Chef::Config[:interval] ||= 1800
|
75
|
+
end
|
76
|
+
|
77
|
+
if Chef::Config[:once]
|
78
|
+
Chef::Config[:interval] = nil
|
79
|
+
Chef::Config[:splay] = nil
|
80
|
+
end
|
81
|
+
|
82
|
+
if Chef::Config[:json_attribs]
|
83
|
+
config_fetcher = Chef::ConfigFetcher.new(Chef::Config[:json_attribs])
|
84
|
+
@chef_client_json = config_fetcher.fetch_json
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def setup_application
|
89
|
+
end
|
90
|
+
|
91
|
+
def load_config_file
|
92
|
+
if !config.has_key?(:config_file)
|
93
|
+
require 'chef/knife'
|
94
|
+
config[:config_file] = Chef::Knife.locate_config_file
|
95
|
+
end
|
96
|
+
super
|
97
|
+
end
|
98
|
+
|
99
|
+
def run_application
|
100
|
+
Chef::Application.setup_server_connectivity
|
101
|
+
|
102
|
+
command = cli_arguments.shift
|
103
|
+
case command
|
104
|
+
when 'execute'
|
105
|
+
exit_code = 0
|
106
|
+
each_machine(cli_arguments.shift) do |machine|
|
107
|
+
puts "#{machine.node['name']}: running '#{cli_arguments.join(' ')}'"
|
108
|
+
result = machine.execute_always(cli_arguments.join(' '))
|
109
|
+
puts result.stdout if result.stdout != ''
|
110
|
+
STDERR.puts result.stderr if result.stderr != ''
|
111
|
+
exit_code = result.exitstatus if result.exitstatus != 0
|
112
|
+
end
|
113
|
+
exit(exit_code) if exit_code != 0
|
114
|
+
else
|
115
|
+
Chef::Log.error("Command '#{command}' unrecognized")
|
116
|
+
end
|
117
|
+
|
118
|
+
Chef::Application.destroy_server_connectivity
|
119
|
+
end
|
120
|
+
|
121
|
+
def rest
|
122
|
+
@rest ||= Chef::ServerAPI.new()
|
123
|
+
end
|
124
|
+
|
125
|
+
def each_machine(spec)
|
126
|
+
spec.split(',').each do |name|
|
127
|
+
node = rest.get("/nodes/#{name}")
|
128
|
+
provisioner_output = node['normal']['provisioner_output']
|
129
|
+
if !provisioner_output
|
130
|
+
Chef::Log.error("Node #{name} was not provisioned with Metal.")
|
131
|
+
next
|
132
|
+
end
|
133
|
+
|
134
|
+
provisioner = ChefMetal.provisioner_for_node(node)
|
135
|
+
machine = provisioner.connect_to_machine(node)
|
136
|
+
|
137
|
+
yield machine
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
ChefMetal::Application.new.run
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'chef/provider/lwrp_base'
|
2
|
+
require 'cheffish/cheffish_server_api'
|
3
|
+
|
4
|
+
class Chef::Provider::MachineExecute < Chef::Provider::LWRPBase
|
5
|
+
|
6
|
+
use_inline_resources
|
7
|
+
|
8
|
+
def whyrun_supported?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def machine
|
13
|
+
@machine ||= begin
|
14
|
+
if new_resource.machine.kind_of?(ChefMetal::Machine)
|
15
|
+
new_resource.machine
|
16
|
+
else
|
17
|
+
# TODO this is inefficient, can we cache or something?
|
18
|
+
node = Cheffish::CheffishServerAPI.new(new_resource.chef_server).get("/nodes/#{new_resource.machine}")
|
19
|
+
new_resource.provisioner.connect_to_machine(node)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
action :run do
|
25
|
+
machine.execute(self, new_resource.command)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'chef/resource/lwrp_base'
|
2
|
+
require 'chef_metal'
|
3
|
+
require 'chef_metal/machine'
|
4
|
+
require 'chef_metal/provisioner'
|
5
|
+
|
6
|
+
class Chef::Resource::MachineExecute < Chef::Resource::LWRPBase
|
7
|
+
self.resource_name = 'machine_execute'
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
super
|
11
|
+
@chef_server = Cheffish.enclosing_chef_server
|
12
|
+
@provisioner = ChefMetal.enclosing_provisioner
|
13
|
+
end
|
14
|
+
|
15
|
+
actions :run
|
16
|
+
default_action :run
|
17
|
+
|
18
|
+
attribute :command, :kind_of => String, :name_attribute => true
|
19
|
+
attribute :machine, :kind_of => [String, ChefMetal::Machine]
|
20
|
+
|
21
|
+
attribute :chef_server, :kind_of => Hash
|
22
|
+
attribute :provisioner, :kind_of => ChefMetal::Provisioner
|
23
|
+
end
|
data/lib/chef_metal.rb
CHANGED
@@ -4,6 +4,8 @@ require 'chef/resource/machine'
|
|
4
4
|
require 'chef/provider/machine'
|
5
5
|
require 'chef/resource/machine_file'
|
6
6
|
require 'chef/provider/machine_file'
|
7
|
+
require 'chef/resource/machine_execute'
|
8
|
+
require 'chef/provider/machine_execute'
|
7
9
|
|
8
10
|
require 'chef_metal/inline_resource'
|
9
11
|
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module ChefMetal
|
2
|
+
class Provisioner
|
3
|
+
# Inflate a provisioner from node information; we don't want to force the
|
4
|
+
# driver to figure out what the provisioner really needs, since it varies
|
5
|
+
# from provisioner to provisioner.
|
6
|
+
#
|
7
|
+
# ## Parameters
|
8
|
+
# node - node to inflate the provisioner for
|
9
|
+
#
|
10
|
+
# returns a should return a Privisoner from the information provided
|
11
|
+
def self.inflate(node)
|
12
|
+
raise "#{self.class} does not override self.inflate"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Acquire a machine, generally by provisioning it. Returns a Machine
|
16
|
+
# object pointing at the machine, allowing useful actions like setup,
|
17
|
+
# converge, execute, file and directory. The Machine object will have a
|
18
|
+
# "node" property which must be saved to the server (if it is any
|
19
|
+
# different from the original node object).
|
20
|
+
#
|
21
|
+
# ## Parameters
|
22
|
+
# action_handler - the action_handler object that is calling this method; this
|
23
|
+
# is generally a provider, but could be anything that can support the
|
24
|
+
# interface (i.e., in the case of the test kitchen metal driver for
|
25
|
+
# acquiring and destroying VMs).
|
26
|
+
# node - node object (deserialized json) representing this machine. If
|
27
|
+
# the node has a provisioner_options hash in it, these will be used
|
28
|
+
# instead of options provided by the provisioner. TODO compare and
|
29
|
+
# fail if different?
|
30
|
+
# node will have node['normal']['provisioner_options'] in it with any
|
31
|
+
# options. It is a hash with at least these options:
|
32
|
+
#
|
33
|
+
# -- provisioner_url: <provisioner url>
|
34
|
+
#
|
35
|
+
# node['normal']['provisioner_output'] will be populated with
|
36
|
+
# information about the created machine. For vagrant, it is a hash
|
37
|
+
# with at least these options:
|
38
|
+
#
|
39
|
+
# -- provisioner_url: <provisioner url>
|
40
|
+
#
|
41
|
+
def acquire_machine(action_handler, node)
|
42
|
+
raise "#{self.class} does not override acquire_machine"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Connect to a machine without acquiring it. This method will NOT make any
|
46
|
+
# changes to anything.
|
47
|
+
#
|
48
|
+
# ## Parameters
|
49
|
+
# node - node object (deserialized json) representing this machine. The
|
50
|
+
# node may have normal attributes "provisioner_options" and
|
51
|
+
# "provisioner_output" in it, representing the input and output of
|
52
|
+
# any prior "acquire_machine" process (if any).
|
53
|
+
#
|
54
|
+
def connect_to_machine(node)
|
55
|
+
raise "#{self.class} does not override connect_to_machine"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Delete the given machine (idempotent). Should destroy the machine,
|
59
|
+
# returning things to the state before acquire_machine was called.
|
60
|
+
def delete_machine(action_handler, node)
|
61
|
+
raise "#{self.class} does not override delete_machine"
|
62
|
+
end
|
63
|
+
|
64
|
+
# Stop the given machine.
|
65
|
+
def stop_machine(action_handler, node)
|
66
|
+
raise "#{self.class} does not override stop_machine"
|
67
|
+
end
|
68
|
+
|
69
|
+
# Provider notification that happens at the point a resource is declared
|
70
|
+
# (after all properties have been set on it)
|
71
|
+
def resource_created(machine)
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
def save_node(provider, node, chef_server)
|
77
|
+
# Save the node and create the client. TODO strip automatic attributes first so we don't race with "current state"
|
78
|
+
ChefMetal.inline_resource(provider) do
|
79
|
+
chef_node node['name'] do
|
80
|
+
chef_server chef_server
|
81
|
+
raw_json node
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module ChefMetal
|
2
|
+
class Provisioner
|
3
|
+
def create_machine(instance)
|
4
|
+
end
|
5
|
+
def delete_machine(instance)
|
6
|
+
end
|
7
|
+
def stop_machine(instance)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module ChefMetal
|
13
|
+
class Instance
|
14
|
+
def create
|
15
|
+
end
|
16
|
+
def delete
|
17
|
+
end
|
18
|
+
def stop
|
19
|
+
end
|
20
|
+
def converge
|
21
|
+
end
|
22
|
+
def
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
- MachineList (physical)
|
29
|
+
- Driver (lists, creates, deletes associated machines)
|
30
|
+
EC2
|
31
|
+
LXC
|
32
|
+
Docker
|
33
|
+
BareMetal
|
34
|
+
- Machine (physical)
|
35
|
+
- Transport
|
36
|
+
SSH (+Rsync)
|
37
|
+
WinRM
|
38
|
+
LXC IPC
|
39
|
+
Docker API
|
40
|
+
- Provisioner
|
41
|
+
Chef Client
|
42
|
+
Puppet
|
43
|
+
|
44
|
+
- Cluster (logical)
|
45
|
+
Chef server
|
46
|
+
Puppet master
|
47
|
+
- Instance (logical)
|
48
|
+
create
|
49
|
+
delete
|
50
|
+
exists?
|
51
|
+
provision
|
52
|
+
verify
|
53
|
+
execute
|
54
|
+
upload/download
|
data/lib/chef_metal/machine.rb
CHANGED
@@ -17,10 +17,14 @@ module ChefMetal
|
|
17
17
|
raise "converge not overridden on #{self.class}"
|
18
18
|
end
|
19
19
|
|
20
|
-
def execute(action_handler, command)
|
20
|
+
def execute(action_handler, command, options = {})
|
21
21
|
raise "execute not overridden on #{self.class}"
|
22
22
|
end
|
23
23
|
|
24
|
+
def execute_always(command, options = {})
|
25
|
+
raise "execute_always not overridden on #{self.class}"
|
26
|
+
end
|
27
|
+
|
24
28
|
def read_file(path)
|
25
29
|
raise "read_file not overridden on #{self.class}"
|
26
30
|
end
|
@@ -23,14 +23,14 @@ module ChefMetal
|
|
23
23
|
convergence_strategy.converge(action_handler, self)
|
24
24
|
end
|
25
25
|
|
26
|
-
def execute(action_handler, command)
|
26
|
+
def execute(action_handler, command, options = {})
|
27
27
|
action_handler.converge_by "run '#{command}' on #{node['name']}" do
|
28
|
-
transport.execute(command).error!
|
28
|
+
transport.execute(command, options).error!
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def execute_always(command)
|
33
|
-
transport.execute(command)
|
32
|
+
def execute_always(command, options = {})
|
33
|
+
transport.execute(command, options)
|
34
34
|
end
|
35
35
|
|
36
36
|
def read_file(path)
|
data/lib/chef_metal/transport.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module ChefMetal
|
2
2
|
class Transport
|
3
|
-
def execute(command)
|
3
|
+
def execute(command, options = {})
|
4
4
|
raise "execute not overridden on #{self.class}"
|
5
5
|
end
|
6
6
|
|
@@ -31,5 +31,29 @@ module ChefMetal
|
|
31
31
|
def available?
|
32
32
|
raise "available? not overridden on #{self.class}"
|
33
33
|
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
# Helper to implement stdout/stderr streaming in execute
|
38
|
+
def stream_chunk(options, stdout_chunk, stderr_chunk)
|
39
|
+
if options[:stream].is_a?(Proc)
|
40
|
+
options[:stream].call(stdout_chunk, stderr_chunk)
|
41
|
+
else
|
42
|
+
if stdout_chunk
|
43
|
+
if options[:stream_stdout]
|
44
|
+
options[:stream_stdout].print stdout_chunk
|
45
|
+
elsif options[:stream]
|
46
|
+
STDOUT.print stdout_chunk
|
47
|
+
end
|
48
|
+
end
|
49
|
+
if stderr_chunk
|
50
|
+
if options[:stream_stderr]
|
51
|
+
options[:stream_stderr].print stderr_chunk
|
52
|
+
elsif options[:stream]
|
53
|
+
STDERR.print stderr_chunk
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
34
58
|
end
|
35
59
|
end
|
@@ -4,7 +4,7 @@ require 'socket'
|
|
4
4
|
|
5
5
|
module ChefMetal
|
6
6
|
class Transport
|
7
|
-
class SSH < Transport
|
7
|
+
class SSH < ChefMetal::Transport
|
8
8
|
def initialize(host, username, ssh_options, options)
|
9
9
|
require 'net/ssh'
|
10
10
|
require 'net/scp'
|
@@ -19,8 +19,8 @@ module ChefMetal
|
|
19
19
|
attr_reader :ssh_options
|
20
20
|
attr_reader :options
|
21
21
|
|
22
|
-
def execute(command)
|
23
|
-
Chef::Log.info("Executing #{command} on #{username}@#{host}")
|
22
|
+
def execute(command, execute_options = {})
|
23
|
+
Chef::Log.info("Executing #{options[:prefix]}#{command} on #{username}@#{host}")
|
24
24
|
stdout = ''
|
25
25
|
stderr = ''
|
26
26
|
exitstatus = nil
|
@@ -38,10 +38,12 @@ module ChefMetal
|
|
38
38
|
|
39
39
|
channel.on_data do |ch2, data|
|
40
40
|
stdout << data
|
41
|
+
stream_chunk(execute_options, data, nil)
|
41
42
|
end
|
42
43
|
|
43
44
|
channel.on_extended_data do |ch2, type, data|
|
44
45
|
stderr << data
|
46
|
+
stream_chunk(execute_options, nil, data)
|
45
47
|
end
|
46
48
|
|
47
49
|
channel.on_request "exit-status" do |ch, data|
|
@@ -53,9 +55,9 @@ module ChefMetal
|
|
53
55
|
channel.wait
|
54
56
|
|
55
57
|
Chef::Log.info("Completed #{command} on #{username}@#{host}: exit status #{exitstatus}")
|
56
|
-
Chef::Log.debug("Stdout was:\n#{stdout}") if stdout != ''
|
57
|
-
Chef::Log.info("Stderr was:\n#{stderr}") if stderr != ''
|
58
|
-
SSHResult.new(stdout, stderr, exitstatus)
|
58
|
+
Chef::Log.debug("Stdout was:\n#{stdout}") if stdout != '' && !options[:stream] && !options[:stream_stdout]
|
59
|
+
Chef::Log.info("Stderr was:\n#{stderr}") if stderr != '' && !options[:stream] && !options[:stream_stderr]
|
60
|
+
SSHResult.new(command, execute_options, stdout, stderr, exitstatus)
|
59
61
|
end
|
60
62
|
|
61
63
|
def read_file(path)
|
@@ -153,18 +155,25 @@ module ChefMetal
|
|
153
155
|
end
|
154
156
|
|
155
157
|
class SSHResult
|
156
|
-
def initialize(stdout, stderr, exitstatus)
|
158
|
+
def initialize(command, options, stdout, stderr, exitstatus)
|
159
|
+
@command = command
|
160
|
+
@options = options
|
157
161
|
@stdout = stdout
|
158
162
|
@stderr = stderr
|
159
163
|
@exitstatus = exitstatus
|
160
164
|
end
|
161
165
|
|
166
|
+
attr_reader :command
|
167
|
+
attr_reader :options
|
162
168
|
attr_reader :stdout
|
163
169
|
attr_reader :stderr
|
164
170
|
attr_reader :exitstatus
|
165
171
|
|
166
172
|
def error!
|
167
|
-
|
173
|
+
if exitstatus != 0
|
174
|
+
# TODO stdout/stderr is already printed at info/debug level. Let's not print it twice, it's a lot.
|
175
|
+
msg = "Error: command '#{command}' exited with code #{exitstatus}.\n"
|
176
|
+
end
|
168
177
|
end
|
169
178
|
end
|
170
179
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
+
require 'chef_metal/transport'
|
1
2
|
require 'base64'
|
2
3
|
|
3
4
|
module ChefMetal
|
4
5
|
class Transport
|
5
|
-
class WinRM
|
6
|
+
class WinRM < ChefMetal::Transport
|
6
7
|
def initialize(endpoint, type, options = {})
|
7
8
|
@endpoint = endpoint
|
8
9
|
@type = type
|
@@ -13,9 +14,11 @@ module ChefMetal
|
|
13
14
|
attr_reader :type
|
14
15
|
attr_reader :options
|
15
16
|
|
16
|
-
def execute(command)
|
17
|
-
output = session.run_powershell_script(command)
|
18
|
-
|
17
|
+
def execute(command, execute_options = {})
|
18
|
+
output = session.run_powershell_script(command) do |stdout, stderr|
|
19
|
+
stream_chunk(execute_options, stdout, stderr)
|
20
|
+
end
|
21
|
+
WinRMResult.new(command, execute_options, output)
|
19
22
|
end
|
20
23
|
|
21
24
|
def read_file(path)
|
@@ -50,7 +53,7 @@ $file.Close
|
|
50
53
|
end
|
51
54
|
|
52
55
|
def disconnect
|
53
|
-
#
|
56
|
+
#
|
54
57
|
end
|
55
58
|
|
56
59
|
def escape(string)
|
@@ -68,7 +71,9 @@ $file.Close
|
|
68
71
|
end
|
69
72
|
|
70
73
|
class WinRMResult
|
71
|
-
def initialize(output)
|
74
|
+
def initialize(command, options, output)
|
75
|
+
@command = command
|
76
|
+
@options = options
|
72
77
|
@exitstatus = output[:exitcode]
|
73
78
|
@stdout = ''
|
74
79
|
@stderr = ''
|
@@ -81,9 +86,15 @@ $file.Close
|
|
81
86
|
attr_reader :stdout
|
82
87
|
attr_reader :stderr
|
83
88
|
attr_reader :exitstatus
|
89
|
+
attr_reader :command
|
90
|
+
attr_reader :options
|
84
91
|
|
85
92
|
def error!
|
86
|
-
|
93
|
+
if exitstatus != 0
|
94
|
+
msg = "Error: command '#{command}' exited with code #{exitstatus}.\n"
|
95
|
+
msg << "STDOUT: #{stdout}" if !options[:stream] && !options[:stream_stdout]
|
96
|
+
msg << "STDERR: #{stderr}" if !options[:stream] && !options[:stream_stderr]
|
97
|
+
end
|
87
98
|
end
|
88
99
|
end
|
89
100
|
end
|
data/lib/chef_metal/version.rb
CHANGED
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.
|
4
|
+
version: '0.8'
|
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-04-
|
11
|
+
date: 2014-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -138,7 +138,8 @@ dependencies:
|
|
138
138
|
version: '0'
|
139
139
|
description: A library for creating machines and infrastructures idempotently in Chef.
|
140
140
|
email: jkeiser@opscode.com
|
141
|
-
executables:
|
141
|
+
executables:
|
142
|
+
- metal
|
142
143
|
extensions: []
|
143
144
|
extra_rdoc_files:
|
144
145
|
- README.md
|
@@ -150,8 +151,10 @@ files:
|
|
150
151
|
- README.md
|
151
152
|
- CHANGELOG.md
|
152
153
|
- lib/chef/provider/machine.rb
|
154
|
+
- lib/chef/provider/machine_execute.rb
|
153
155
|
- lib/chef/provider/machine_file.rb
|
154
156
|
- lib/chef/resource/machine.rb
|
157
|
+
- lib/chef/resource/machine_execute.rb
|
155
158
|
- lib/chef/resource/machine_file.rb
|
156
159
|
- lib/chef_metal/action_handler.rb
|
157
160
|
- lib/chef_metal/aws_credentials.rb
|
@@ -161,7 +164,9 @@ files:
|
|
161
164
|
- lib/chef_metal/convergence_strategy/no_converge.rb
|
162
165
|
- lib/chef_metal/convergence_strategy/precreate_chef_objects.rb
|
163
166
|
- lib/chef_metal/convergence_strategy.rb
|
167
|
+
- lib/chef_metal/driver.rb
|
164
168
|
- lib/chef_metal/inline_resource.rb
|
169
|
+
- lib/chef_metal/instance.rb
|
165
170
|
- lib/chef_metal/machine/basic_machine.rb
|
166
171
|
- lib/chef_metal/machine/unix_machine.rb
|
167
172
|
- lib/chef_metal/machine/windows_machine.rb
|
@@ -175,6 +180,7 @@ files:
|
|
175
180
|
- lib/chef_metal/transport.rb
|
176
181
|
- lib/chef_metal/version.rb
|
177
182
|
- lib/chef_metal.rb
|
183
|
+
- bin/metal
|
178
184
|
homepage: http://wiki.opscode.com/display/chef
|
179
185
|
licenses: []
|
180
186
|
metadata: {}
|