chef 0.9.0.rc01 → 0.9.0.rc02
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of chef might be problematic. Click here for more details.
- data/distro/common/man/man8/knife.8 +8 -0
- data/distro/common/markdown/knife.mkd +6 -0
- data/lib/chef.rb +1 -0
- data/lib/chef/client.rb +24 -25
- data/lib/chef/couchdb.rb +4 -2
- data/lib/chef/handler.rb +91 -32
- data/lib/chef/handler/json_file.rb +14 -3
- data/lib/chef/knife/cookbook_bulk_delete.rb +5 -8
- data/lib/chef/knife/cookbook_delete.rb +12 -2
- data/lib/chef/run_status.rb +94 -0
- data/lib/chef/version.rb +1 -1
- metadata +4 -3
@@ -252,6 +252,10 @@ Cookbooks are the fundamental unit of distribution in Chef. They encapsulate all
|
|
252
252
|
.P
|
253
253
|
\fBcookbook bulk delete REGEX\fR \fI(options)\fR
|
254
254
|
.
|
255
|
+
.TP
|
256
|
+
\fB\-p\fR, \fB\-\-purge\fR
|
257
|
+
Purge files from backing store. This will disable any cookbook that contains any of the same files as the cookbook being purged.
|
258
|
+
.
|
255
259
|
.P
|
256
260
|
Delete cookbooks on the Chef Server based on a regular expression. The regular expression (\fIREGEX\fR) should be in quotes, not in //'s.
|
257
261
|
.
|
@@ -262,6 +266,10 @@ Delete cookbooks on the Chef Server based on a regular expression. The regular e
|
|
262
266
|
\fB\-a\fR, \fB\-\-all\fR
|
263
267
|
Delete all versions
|
264
268
|
.
|
269
|
+
.TP
|
270
|
+
\fB\-p\fR, \fB\-\-purge\fR
|
271
|
+
Purge files from backing store. This will disable any cookbook that contains any of the same files as the cookbook being purged.
|
272
|
+
.
|
265
273
|
.P
|
266
274
|
Delete the specified \fIVERSION\fR of the named \fICOOKBOOK\fR. If no version is specified, and only one version exists on the server, that version will be deleted. If multiple versions are available on the server, you will be prompted for a version to delete.
|
267
275
|
.
|
@@ -161,6 +161,9 @@ Cookbooks are the fundamental unit of distribution in Chef. They encapsulate all
|
|
161
161
|
|
162
162
|
__cookbook bulk delete REGEX__ _(options)_
|
163
163
|
|
164
|
+
* `-p`, `--purge`:
|
165
|
+
Purge files from backing store. This will disable any cookbook that contains any of the same files as the cookbook being purged.
|
166
|
+
|
164
167
|
Delete cookbooks on the Chef Server based on a regular expression. The regular expression (_REGEX_) should be in quotes, not in //'s.
|
165
168
|
|
166
169
|
__cookbook delete COOKBOOK [VERSION]__ _(options)_
|
@@ -168,6 +171,9 @@ __cookbook delete COOKBOOK [VERSION]__ _(options)_
|
|
168
171
|
* `-a`, `--all`:
|
169
172
|
Delete all versions
|
170
173
|
|
174
|
+
* `-p`, `--purge`:
|
175
|
+
Purge files from backing store. This will disable any cookbook that contains any of the same files as the cookbook being purged.
|
176
|
+
|
171
177
|
Delete the specified _VERSION_ of the named _COOKBOOK_. If no version is specified, and only one version exists on the server, that version will be deleted. If multiple versions are available on the server, you will be prompted for a version to delete.
|
172
178
|
|
173
179
|
__cookbook download COOKBOOK [VERSION]__ _(options)_
|
data/lib/chef.rb
CHANGED
data/lib/chef/client.rb
CHANGED
@@ -74,12 +74,14 @@ class Chef
|
|
74
74
|
build_node
|
75
75
|
|
76
76
|
begin
|
77
|
-
|
77
|
+
run_status = Chef::RunStatus.new(node)
|
78
|
+
run_status.start_clock
|
78
79
|
Chef::Log.info("Starting Chef Run")
|
79
80
|
|
80
81
|
if Chef::Config[:solo]
|
81
82
|
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest) }
|
82
83
|
run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new(Chef::CookbookLoader.new))
|
84
|
+
run_status.run_context = run_context
|
83
85
|
assert_cookbook_path_not_empty(run_context)
|
84
86
|
converge(run_context)
|
85
87
|
else
|
@@ -98,7 +100,8 @@ class Chef
|
|
98
100
|
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, rest, valid_cache_entries) }
|
99
101
|
cookbook_hash = sync_cookbooks(valid_cache_entries)
|
100
102
|
run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new(cookbook_hash))
|
101
|
-
|
103
|
+
run_status.run_context = run_context
|
104
|
+
|
102
105
|
assert_cookbook_path_not_empty(run_context)
|
103
106
|
save_node
|
104
107
|
|
@@ -108,39 +111,35 @@ class Chef
|
|
108
111
|
cleanup_file_cache(valid_cache_entries)
|
109
112
|
end
|
110
113
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
run_report_handlers(start_time, end_time, elapsed_time)
|
114
|
+
run_status.stop_clock
|
115
|
+
Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds")
|
116
|
+
run_report_handlers(run_status)
|
115
117
|
true
|
116
118
|
rescue Exception => e
|
117
|
-
|
119
|
+
run_status.stop_clock
|
120
|
+
run_status.exception = e
|
121
|
+
run_exception_handlers(run_status)
|
118
122
|
Chef::Log.error("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
|
119
123
|
raise
|
124
|
+
ensure
|
125
|
+
run_status = nil
|
120
126
|
end
|
121
127
|
end
|
122
128
|
|
123
|
-
def run_report_handlers(
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
handler.report(node, runner, start_time, end_time, elapsed_time)
|
128
|
-
end
|
129
|
-
Chef::Log.info("Report handlers complete")
|
129
|
+
def run_report_handlers(run_status)
|
130
|
+
Chef::Log.info("Running report handlers")
|
131
|
+
Array(Chef::Config[:report_handlers]).each do |handler|
|
132
|
+
handler.run_report_safely(handler)
|
130
133
|
end
|
134
|
+
Chef::Log.info("Report handlers complete")
|
131
135
|
end
|
132
136
|
|
133
|
-
def run_exception_handlers(
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
Chef::Log.error("Received exception: #{exception.message}")
|
138
|
-
Chef::Log.error("Running exception handlers")
|
139
|
-
Chef::Config[:exception_handlers].each do |handler|
|
140
|
-
handler.report(node, runner, start_time, end_time, elapsed_time, exception)
|
141
|
-
end
|
142
|
-
Chef::Log.error("Exception handlers complete")
|
137
|
+
def run_exception_handlers(run_status)
|
138
|
+
Chef::Log.error("Running exception handlers")
|
139
|
+
Array(Chef::Config[:exception_handlers]).each do |handler|
|
140
|
+
handler.run_report_safely(run_status)
|
143
141
|
end
|
142
|
+
Chef::Log.error("Exception handlers complete")
|
144
143
|
end
|
145
144
|
|
146
145
|
def run_ohai
|
@@ -331,7 +330,7 @@ class Chef
|
|
331
330
|
# true:: Always returns true
|
332
331
|
def converge(run_context)
|
333
332
|
Chef::Log.debug("Converging node #{node_name}")
|
334
|
-
|
333
|
+
@runner = Chef::Runner.new(run_context)
|
335
334
|
runner.converge
|
336
335
|
true
|
337
336
|
end
|
data/lib/chef/couchdb.rb
CHANGED
@@ -160,9 +160,11 @@ class Chef
|
|
160
160
|
end
|
161
161
|
response = @rest.delete_rest("#{couchdb_database}/#{uuid}?rev=#{rev}")
|
162
162
|
response.couchdb = self if response.respond_to?(:couchdb=)
|
163
|
-
Chef::Log.info("Sending #{obj_type}(#{uuid}) to the index queue for deletion..")
|
164
163
|
|
165
|
-
object.
|
164
|
+
if object.respond_to?(:delete_from_index)
|
165
|
+
Chef::Log.info("Sending #{obj_type}(#{uuid}) to the index queue for deletion..")
|
166
|
+
object.delete_from_index(:database => couchdb_database, :id => uuid, :type => obj_type)
|
167
|
+
end
|
166
168
|
|
167
169
|
response
|
168
170
|
end
|
data/lib/chef/handler.rb
CHANGED
@@ -15,47 +15,106 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
+
require 'forwardable'
|
18
19
|
|
19
20
|
class Chef
|
20
21
|
class Handler
|
21
22
|
|
22
|
-
|
23
|
+
extend Forwardable
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
attr_reader :run_status
|
26
|
+
|
27
|
+
##
|
28
|
+
# :method: start_time
|
29
|
+
#
|
30
|
+
# The time the chef run started
|
31
|
+
def_delegator :@run_status, :start_time
|
32
|
+
|
33
|
+
##
|
34
|
+
# :method: end_time
|
35
|
+
#
|
36
|
+
# The time the chef run ended
|
37
|
+
def_delegator :@run_status, :end_time
|
38
|
+
|
39
|
+
##
|
40
|
+
# :method: run_context
|
41
|
+
#
|
42
|
+
# The Chef::RunContext object used by the chef run
|
43
|
+
def_delegator :@run_status, :run_context
|
44
|
+
|
45
|
+
##
|
46
|
+
# :method: exception
|
47
|
+
#
|
48
|
+
# The uncaught Exception that terminated the chef run, or nil if the run
|
49
|
+
# completed successfully
|
50
|
+
def_delegator :@run_status, :exception
|
51
|
+
|
52
|
+
##
|
53
|
+
# :method: backtrace
|
54
|
+
#
|
55
|
+
# The backtrace captured by the uncaught exception that terminated the chef
|
56
|
+
# run, or nil if the run completed successfully
|
57
|
+
def_delegator :@run_status, :backtrace
|
58
|
+
|
59
|
+
##
|
60
|
+
# :method: node
|
61
|
+
#
|
62
|
+
# The Chef::Node for this client run
|
63
|
+
def_delegator :@run_status, :node
|
64
|
+
|
65
|
+
##
|
66
|
+
# :method: all_resources
|
67
|
+
#
|
68
|
+
# An Array containing all resources in the chef run's resource_collection
|
69
|
+
def_delegator :@run_status, :all_resources
|
70
|
+
|
71
|
+
##
|
72
|
+
# :method: updated_resources
|
73
|
+
#
|
74
|
+
# An Array containing all resources that were updated during the chef run
|
75
|
+
def_delegator :@run_status, :updated_resources
|
76
|
+
|
77
|
+
##
|
78
|
+
# :method: success?
|
79
|
+
#
|
80
|
+
# Was the chef run successful? True if the chef run did not raise an
|
81
|
+
# uncaught exception
|
82
|
+
def_delegator :@run_status, :success?
|
83
|
+
|
84
|
+
##
|
85
|
+
# :method: failed?
|
86
|
+
#
|
87
|
+
# Did the chef run fail? True if the chef run raised an uncaught exception
|
88
|
+
def_delegator :@run_status, :failed?
|
89
|
+
|
90
|
+
# The main entry point for report handling. Subclasses should override this
|
91
|
+
# method with their own report handling logic.
|
92
|
+
def report
|
93
|
+
end
|
94
|
+
|
95
|
+
# Runs the report handler, rescuing and logging any errors it may cause.
|
96
|
+
# This ensures that all handlers get a chance to run even if one fails.
|
97
|
+
# This method should not be overridden by subclasses unless you know what
|
98
|
+
# you're doing.
|
99
|
+
def run_report_safely(run_status)
|
100
|
+
run_report_unsafe(run_status)
|
101
|
+
rescue Exception => e
|
102
|
+
Chef::Log.error("Report handler #{self.class.name} raised #{e.inspect}")
|
103
|
+
Array(e.backtrace).each { |line| Chef::Log.error(line) }
|
104
|
+
ensure
|
105
|
+
@run_status = nil
|
28
106
|
end
|
29
107
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
:all => runner.run_context.resource_collection.all_resources,
|
36
|
-
:updated => runner.run_context.resource_collection.inject([]) { |m, r| m << r if r.updated; m }
|
37
|
-
}
|
38
|
-
end
|
39
|
-
if exception
|
40
|
-
data[:success] = false
|
41
|
-
data[:exception] = {
|
42
|
-
:message => exception.message,
|
43
|
-
:backtrace => exception.backtrace
|
44
|
-
}
|
45
|
-
else
|
46
|
-
data[:success] = true
|
47
|
-
end
|
48
|
-
data[:elapsed_time] = elapsed_time
|
49
|
-
data[:start_time] = start_time
|
50
|
-
data[:end_time] = end_time
|
51
|
-
data
|
108
|
+
# Runs the report handler without any error handling. This method should
|
109
|
+
# not be used directly except in testing.
|
110
|
+
def run_report_unsafe(run_status)
|
111
|
+
@run_status = run_status
|
112
|
+
report
|
52
113
|
end
|
53
114
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
File.chmod(octal_mode("0700"), config[:path])
|
58
|
-
end
|
115
|
+
# Return the Hash representation of the run_status
|
116
|
+
def data
|
117
|
+
@run_status.to_hash
|
59
118
|
end
|
60
119
|
|
61
120
|
end
|
@@ -23,18 +23,21 @@ class Chef
|
|
23
23
|
class Handler
|
24
24
|
class JsonFile < ::Chef::Handler
|
25
25
|
|
26
|
+
attr_reader :config
|
27
|
+
|
26
28
|
def initialize(config={})
|
27
|
-
|
29
|
+
@config = config
|
30
|
+
@config[:path] ||= "/var/chef/reports"
|
31
|
+
@config
|
28
32
|
end
|
29
33
|
|
30
|
-
def report
|
34
|
+
def report
|
31
35
|
if exception
|
32
36
|
Chef::Log.error("Creating JSON exception report")
|
33
37
|
else
|
34
38
|
Chef::Log.info("Creating JSON run report")
|
35
39
|
end
|
36
40
|
|
37
|
-
data = build_report_data(node, runner, start_time, end_time, elapsed_time, exception)
|
38
41
|
build_report_dir
|
39
42
|
savetime = Time.now.strftime("%Y%m%d%H%M%S")
|
40
43
|
File.open(File.join(config[:path], "chef-run-report-#{savetime}.json"), "w") do |file|
|
@@ -42,6 +45,14 @@ class Chef
|
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
48
|
+
def build_report_dir
|
49
|
+
unless File.exists?(config[:path])
|
50
|
+
FileUtils.mkdir_p(config[:path])
|
51
|
+
File.chmod(00700, config[:path])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
45
56
|
end
|
46
57
|
end
|
47
58
|
end
|
@@ -24,6 +24,8 @@ class Chef
|
|
24
24
|
class Knife
|
25
25
|
class CookbookBulkDelete < Knife
|
26
26
|
|
27
|
+
option :purge, :short => '-p', :long => '--purge', :boolean => true, :description => 'Permanently remove files from backing data store'
|
28
|
+
|
27
29
|
banner "Sub-Command: cookbook bulk delete REGEX (options)"
|
28
30
|
|
29
31
|
def run
|
@@ -41,10 +43,12 @@ class Chef
|
|
41
43
|
|
42
44
|
confirm("Do you really want to delete these cookbooks? All versions will be deleted. (Y/N) ", false)
|
43
45
|
|
46
|
+
confirm("Files that are common to multiple cookbooks are shared, so purging the files may disable other cookbooks. Are you sure you want to purge files instead of just deleting the cookbooks") if config[:purge]
|
47
|
+
|
44
48
|
cookbooks_names.each do |cookbook_name|
|
45
49
|
versions = rest.get_rest("cookbooks/#{cookbook_name}").values.flatten
|
46
50
|
versions.each do |version|
|
47
|
-
object = rest.delete_rest("cookbooks/#{cookbook_name}/#{version}")
|
51
|
+
object = rest.delete_rest("cookbooks/#{cookbook_name}/#{version}#{config[:purge] ? "?purge=true" : ""}")
|
48
52
|
Chef::Log.info("Deleted cookbook #{cookbook_name.ljust(25)} [#{version}]")
|
49
53
|
end
|
50
54
|
end
|
@@ -52,10 +56,3 @@ class Chef
|
|
52
56
|
end
|
53
57
|
end
|
54
58
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
@@ -24,9 +24,12 @@ class Chef
|
|
24
24
|
|
25
25
|
option :all, :short => '-a', :long => '--all', :boolean => true, :description => 'delete all versions'
|
26
26
|
|
27
|
+
option :purge, :short => '-p', :long => '--purge', :boolean => true, :description => 'Permanently remove files from backing data store'
|
28
|
+
|
27
29
|
banner "Sub-Command: cookbook delete COOKBOOK VERSION (options)"
|
28
30
|
|
29
31
|
def run
|
32
|
+
confirm("Files that are common to multiple cookbooks are shared, so purging the files may disable other cookbooks. Are you sure you want to purge files instead of just deleting the cookbook") if config[:purge]
|
30
33
|
@cookbook_name, @version = name_args
|
31
34
|
if @cookbook_name && @version
|
32
35
|
delete_explicit_version
|
@@ -43,7 +46,7 @@ class Chef
|
|
43
46
|
|
44
47
|
def delete_explicit_version
|
45
48
|
delete_object(Chef::CookbookVersion, "#{@cookbook_name} version #{@version}", "cookbook") do
|
46
|
-
|
49
|
+
delete_request("cookbooks/#{@cookbook_name}/#{@version}", config[:purge])
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
@@ -112,7 +115,7 @@ class Chef
|
|
112
115
|
end
|
113
116
|
|
114
117
|
def delete_version_without_confirmation(version)
|
115
|
-
object =
|
118
|
+
object = delete_request("cookbooks/#{@cookbook_name}/#{version}", config[:purge])
|
116
119
|
output(format_for_display(object)) if config[:print_after]
|
117
120
|
Chef::Log.info("Deleted cookbook[#{@cookbook_name}][#{version}]")
|
118
121
|
end
|
@@ -127,6 +130,13 @@ class Chef
|
|
127
130
|
end
|
128
131
|
end
|
129
132
|
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def delete_request(path, purge)
|
137
|
+
url = "cookbooks/#{@cookbook_name}/#{@version}#{purge ? "?purge=true" : ""}"
|
138
|
+
rest.delete_rest(url)
|
139
|
+
end
|
130
140
|
|
131
141
|
end
|
132
142
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Daniel DeLeo (<dan@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
class Chef::RunStatus
|
20
|
+
|
21
|
+
attr_reader :run_context
|
22
|
+
|
23
|
+
attr_writer :run_context
|
24
|
+
|
25
|
+
attr_reader :start_time
|
26
|
+
|
27
|
+
attr_reader :end_time
|
28
|
+
|
29
|
+
attr_reader :exception
|
30
|
+
|
31
|
+
attr_writer :exception
|
32
|
+
|
33
|
+
def initialize(node)
|
34
|
+
@node = node
|
35
|
+
end
|
36
|
+
|
37
|
+
def node
|
38
|
+
@node
|
39
|
+
end
|
40
|
+
|
41
|
+
def start_clock
|
42
|
+
@start_time = Time.now
|
43
|
+
end
|
44
|
+
|
45
|
+
def stop_clock
|
46
|
+
@end_time = Time.now
|
47
|
+
end
|
48
|
+
|
49
|
+
def elapsed_time
|
50
|
+
if @start_time && @end_time
|
51
|
+
@end_time - @start_time
|
52
|
+
else
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def all_resources
|
58
|
+
@run_context && @run_context.resource_collection.all_resources
|
59
|
+
end
|
60
|
+
|
61
|
+
def updated_resources
|
62
|
+
@run_context && @run_context.resource_collection.select { |r| r.updated }
|
63
|
+
end
|
64
|
+
|
65
|
+
def backtrace
|
66
|
+
@exception && @exception.backtrace
|
67
|
+
end
|
68
|
+
|
69
|
+
def failed?
|
70
|
+
!success?
|
71
|
+
end
|
72
|
+
|
73
|
+
def success?
|
74
|
+
@exception.nil?
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_hash
|
78
|
+
# use a flat hash here so we can't errors from intermediate values being nil
|
79
|
+
{ :node => node,
|
80
|
+
:success => success?,
|
81
|
+
:start_time => start_time,
|
82
|
+
:end_time => end_time,
|
83
|
+
:elapsed_time => elapsed_time,
|
84
|
+
:all_resources => all_resources,
|
85
|
+
:updated_resources => updated_resources,
|
86
|
+
:exception => formatted_exception,
|
87
|
+
:backtrace => backtrace}
|
88
|
+
end
|
89
|
+
|
90
|
+
def formatted_exception
|
91
|
+
@exception && "#{@exception.class.name}: #{@exception.message}"
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
data/lib/chef/version.rb
CHANGED
metadata
CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 0
|
7
7
|
- 9
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.9.0.
|
9
|
+
- rc02
|
10
|
+
version: 0.9.0.rc02
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Jacob
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-06-
|
18
|
+
date: 2010-06-16 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -509,6 +509,7 @@ files:
|
|
509
509
|
- lib/chef/run_list/run_list_expansion.rb
|
510
510
|
- lib/chef/run_list/run_list_item.rb
|
511
511
|
- lib/chef/run_list.rb
|
512
|
+
- lib/chef/run_status.rb
|
512
513
|
- lib/chef/runner.rb
|
513
514
|
- lib/chef/sandbox.rb
|
514
515
|
- lib/chef/search/query.rb
|