chef 0.9.8.beta.1 → 0.9.8.beta.2
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.
- data/bin/shef +5 -18
- data/distro/common/man/man8/knife.8 +632 -243
- data/distro/common/markdown/knife.mkd +251 -44
- data/lib/chef/application/knife.rb +4 -0
- data/lib/chef/data_bag.rb +4 -4
- data/lib/chef/data_bag_item.rb +9 -1
- data/lib/chef/knife.rb +15 -6
- data/lib/chef/knife/bootstrap.rb +1 -7
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +32 -0
- data/lib/chef/knife/cookbook_create.rb +83 -33
- data/lib/chef/knife/ec2_server_create.rb +25 -3
- data/lib/chef/mixin/language.rb +9 -1
- data/lib/chef/provider/file.rb +1 -0
- data/lib/chef/provider/package/zypper.rb +2 -2
- data/lib/chef/resource/remote_file.rb +1 -1
- data/lib/chef/shef.rb +146 -47
- data/lib/chef/shef/ext.rb +436 -181
- data/lib/chef/shef/model_wrapper.rb +120 -0
- data/lib/chef/shef/shef_rest.rb +28 -0
- data/lib/chef/shef/shef_session.rb +91 -4
- data/lib/chef/version.rb +1 -1
- metadata +6 -3
data/lib/chef/shef/ext.rb
CHANGED
@@ -5,29 +5,33 @@
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
#
|
17
|
+
|
18
|
+
require 'tempfile'
|
17
19
|
require 'chef/recipe'
|
18
20
|
require 'fileutils'
|
19
21
|
require 'chef/version'
|
20
22
|
require 'chef/shef/shef_session'
|
23
|
+
require 'chef/shef/model_wrapper'
|
24
|
+
require 'chef/shef/shef_rest'
|
21
25
|
|
22
26
|
module Shef
|
23
27
|
module Extensions
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
#
|
28
|
-
#
|
29
|
-
module
|
30
|
-
|
28
|
+
|
29
|
+
Help = Struct.new(:cmd, :desc, :explanation)
|
30
|
+
|
31
|
+
# Extensions to be included in every 'main' object in shef. These objects
|
32
|
+
# are extended with this module.
|
33
|
+
module ObjectCoreExtensions
|
34
|
+
|
31
35
|
def ensure_session_select_defined
|
32
36
|
# irb breaks if you prematurely define IRB::JobMangager
|
33
37
|
# so these methods need to be defined at the latest possible time.
|
@@ -57,72 +61,86 @@ module Shef
|
|
57
61
|
irb(context_obj)
|
58
62
|
end
|
59
63
|
end
|
60
|
-
|
61
|
-
def help_banner
|
64
|
+
|
65
|
+
def help_banner
|
62
66
|
banner = []
|
63
67
|
banner << ""
|
64
|
-
banner <<
|
68
|
+
banner << "Shef Help"
|
65
69
|
banner << "".ljust(80, "=")
|
66
70
|
banner << "| " + "Command".ljust(25) + "| " + "Description"
|
67
71
|
banner << "".ljust(80, "=")
|
68
72
|
|
69
|
-
self.
|
70
|
-
banner << "| " + cmd.ljust(25) + "| " +
|
73
|
+
self.all_help_descriptions.each do |help_text|
|
74
|
+
banner << "| " + help_text.cmd.ljust(25) + "| " + help_text.desc
|
71
75
|
end
|
72
76
|
banner << "".ljust(80, "=")
|
73
77
|
banner << "\n"
|
78
|
+
banner << "Use help(:command) to get detailed help with individual commands"
|
79
|
+
banner << "\n"
|
74
80
|
banner.join("\n")
|
75
81
|
end
|
76
|
-
|
82
|
+
|
83
|
+
def explain_command(method_name)
|
84
|
+
help = self.all_help_descriptions.find { |h| h.cmd.to_s == method_name.to_s }
|
85
|
+
if help
|
86
|
+
puts ""
|
87
|
+
puts "Command: #{method_name}"
|
88
|
+
puts "".ljust(80, "=")
|
89
|
+
puts help.explanation || help.desc
|
90
|
+
puts "".ljust(80, "=")
|
91
|
+
puts ""
|
92
|
+
else
|
93
|
+
puts ""
|
94
|
+
puts "command #{method_name} not found or no help available"
|
95
|
+
puts ""
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
77
99
|
# helpfully returns +:on+ so we can have sugary syntax like `tracing on'
|
78
100
|
def on
|
79
101
|
:on
|
80
102
|
end
|
81
|
-
|
103
|
+
|
82
104
|
# returns +:off+ so you can just do `tracing off'
|
83
105
|
def off
|
84
106
|
:off
|
85
107
|
end
|
86
|
-
|
87
|
-
module ClassMethods
|
88
108
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
def all_help_descriptions
|
94
|
-
if (sc = superclass) && superclass.respond_to?(:help_descriptions)
|
95
|
-
help_descriptions + sc.help_descriptions
|
96
|
-
else
|
97
|
-
help_descriptions
|
98
|
-
end
|
99
|
-
end
|
109
|
+
def help_descriptions
|
110
|
+
@help_descriptions ||= []
|
111
|
+
end
|
100
112
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
def subcommands(subcommand_help={})
|
106
|
-
@subcommand_help = subcommand_help
|
107
|
-
end
|
113
|
+
def all_help_descriptions
|
114
|
+
help_descriptions
|
115
|
+
end
|
108
116
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
117
|
+
def desc(help_text)
|
118
|
+
@desc = help_text
|
119
|
+
end
|
120
|
+
|
121
|
+
def explain(explain_text)
|
122
|
+
@explain = explain_text
|
123
|
+
end
|
124
|
+
|
125
|
+
def subcommands(subcommand_help={})
|
126
|
+
@subcommand_help = subcommand_help
|
127
|
+
end
|
128
|
+
|
129
|
+
def singleton_method_added(mname)
|
130
|
+
if @desc
|
131
|
+
help_descriptions << Help.new(mname.to_s, @desc.to_s, @explain)
|
132
|
+
@desc, @explain = nil, nil
|
133
|
+
end
|
134
|
+
if @subcommand_help
|
135
|
+
@subcommand_help.each do |subcommand, text|
|
136
|
+
help_descriptions << Help.new("#{mname}.#{subcommand}", text.to_s, nil)
|
118
137
|
end
|
119
|
-
@subcommand_help = {}
|
120
138
|
end
|
121
|
-
|
139
|
+
@subcommand_help = {}
|
122
140
|
end
|
123
|
-
|
141
|
+
|
124
142
|
end
|
125
|
-
|
143
|
+
|
126
144
|
module String
|
127
145
|
def on_off_to_bool
|
128
146
|
case self
|
@@ -135,33 +153,396 @@ module Shef
|
|
135
153
|
end
|
136
154
|
end
|
137
155
|
end
|
138
|
-
|
156
|
+
|
139
157
|
module Symbol
|
140
158
|
def on_off_to_bool
|
141
159
|
self.to_s.on_off_to_bool
|
142
160
|
end
|
143
161
|
end
|
144
|
-
|
162
|
+
|
145
163
|
module TrueClass
|
146
164
|
def to_on_off_str
|
147
165
|
"on"
|
148
166
|
end
|
149
|
-
|
167
|
+
|
150
168
|
def on_off_to_bool
|
151
169
|
self
|
152
170
|
end
|
153
171
|
end
|
154
|
-
|
172
|
+
|
155
173
|
module FalseClass
|
156
174
|
def to_on_off_str
|
157
175
|
"off"
|
158
176
|
end
|
159
|
-
|
177
|
+
|
160
178
|
def on_off_to_bool
|
161
179
|
self
|
162
180
|
end
|
163
181
|
end
|
164
|
-
|
182
|
+
|
183
|
+
# Methods that have associated help text need to be dynamically added
|
184
|
+
# to the main irb objects, so we define them in a proc and later
|
185
|
+
# instance_eval the proc in the object.
|
186
|
+
ObjectUIExtensions = Proc.new do
|
187
|
+
extend Shef::Extensions::ObjectCoreExtensions
|
188
|
+
|
189
|
+
desc "prints this help message"
|
190
|
+
explain(<<-E)
|
191
|
+
## SUMMARY ##
|
192
|
+
When called with no argument, +help+ prints a table of all shef commands. When
|
193
|
+
called with an argument COMMAND, +help+ prints a detailed explanation of the
|
194
|
+
command if available, or the description if no explanation is available.
|
195
|
+
E
|
196
|
+
def help(commmand=nil)
|
197
|
+
if commmand
|
198
|
+
explain_command(commmand)
|
199
|
+
else
|
200
|
+
puts help_banner
|
201
|
+
end
|
202
|
+
:ucanhaz_halp
|
203
|
+
end
|
204
|
+
alias :halp :help
|
205
|
+
|
206
|
+
desc "prints information about chef"
|
207
|
+
def version
|
208
|
+
puts "This is shef, the Chef shell.\n" +
|
209
|
+
" Chef Version: #{::Chef::VERSION}\n" +
|
210
|
+
" http://www.opscode.com/chef\n" +
|
211
|
+
" http://wiki.opscode.com/display/chef/Home"
|
212
|
+
:ucanhaz_automation
|
213
|
+
end
|
214
|
+
alias :shef :version
|
215
|
+
|
216
|
+
desc "switch to recipe mode"
|
217
|
+
def recipe
|
218
|
+
find_or_create_session_for Shef.session.recipe
|
219
|
+
:recipe
|
220
|
+
end
|
221
|
+
|
222
|
+
desc "switch to attributes mode"
|
223
|
+
def attributes
|
224
|
+
find_or_create_session_for Shef.session.node
|
225
|
+
:attributes
|
226
|
+
end
|
227
|
+
|
228
|
+
desc "returns the current node (i.e., this host)"
|
229
|
+
def node
|
230
|
+
Shef.session.node
|
231
|
+
end
|
232
|
+
|
233
|
+
desc "pretty print the node's attributes"
|
234
|
+
def ohai(key=nil)
|
235
|
+
pp(key ? node.attribute[key] : node.attribute)
|
236
|
+
end
|
237
|
+
|
238
|
+
desc "run chef using the current recipe"
|
239
|
+
def run_chef
|
240
|
+
Chef::Log.level = :debug
|
241
|
+
session = Shef.session
|
242
|
+
runrun = Chef::Runner.new(session.run_context).converge
|
243
|
+
Chef::Log.level = :info
|
244
|
+
runrun
|
245
|
+
end
|
246
|
+
|
247
|
+
desc "returns an object to control a paused chef run"
|
248
|
+
subcommands :resume => "resume the chef run",
|
249
|
+
:step => "run only the next resource",
|
250
|
+
:skip_back => "move back in the run list",
|
251
|
+
:skip_forward => "move forward in the run list"
|
252
|
+
def chef_run
|
253
|
+
Shef.session.resource_collection.iterator
|
254
|
+
end
|
255
|
+
|
256
|
+
desc "resets the current recipe"
|
257
|
+
def reset
|
258
|
+
Shef.session.reset!
|
259
|
+
end
|
260
|
+
|
261
|
+
desc "assume the identity of another node."
|
262
|
+
def become_node(node_name)
|
263
|
+
Shef::DoppelGangerSession.instance.assume_identity(node_name)
|
264
|
+
:doppelganger
|
265
|
+
end
|
266
|
+
alias :doppelganger :become_node
|
267
|
+
|
268
|
+
desc "turns printout of return values on or off"
|
269
|
+
def echo(on_or_off)
|
270
|
+
conf.echo = on_or_off.on_off_to_bool
|
271
|
+
end
|
272
|
+
|
273
|
+
desc "says if echo is on or off"
|
274
|
+
def echo?
|
275
|
+
puts "echo is #{conf.echo.to_on_off_str}"
|
276
|
+
end
|
277
|
+
|
278
|
+
desc "turns on or off tracing of execution. *verbose*"
|
279
|
+
def tracing(on_or_off)
|
280
|
+
conf.use_tracer = on_or_off.on_off_to_bool
|
281
|
+
tracing?
|
282
|
+
end
|
283
|
+
alias :trace :tracing
|
284
|
+
|
285
|
+
desc "says if tracing is on or off"
|
286
|
+
def tracing?
|
287
|
+
puts "tracing is #{conf.use_tracer.to_on_off_str}"
|
288
|
+
end
|
289
|
+
alias :trace? :tracing?
|
290
|
+
|
291
|
+
desc "simple ls style command"
|
292
|
+
def ls(directory)
|
293
|
+
Dir.entries(directory)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
RESTApiExtensions = Proc.new do
|
298
|
+
desc "edit an object in your EDITOR"
|
299
|
+
explain(<<-E)
|
300
|
+
## SUMMARY ##
|
301
|
+
+edit(object)+ allows you to edit any object that can be converted to JSON.
|
302
|
+
When finished editing, this method will return the edited object:
|
303
|
+
|
304
|
+
new_node = edit(existing_node)
|
305
|
+
|
306
|
+
## EDITOR SELECTION ##
|
307
|
+
Shef looks for an editor using the following logic
|
308
|
+
1. Looks for an EDITOR set by Shef.editor = "EDITOR"
|
309
|
+
2. Looks for an EDITOR configured in your shef config file
|
310
|
+
3. Uses the value of the EDITOR environment variable
|
311
|
+
E
|
312
|
+
def edit(object)
|
313
|
+
unless Shef.editor
|
314
|
+
puts "Please set your editor with Shef.editor = \"vim|emacs|mate|ed\""
|
315
|
+
return :failburger
|
316
|
+
end
|
317
|
+
|
318
|
+
filename = "shef-edit-#{object.class.name}-"
|
319
|
+
if object.respond_to?(:name)
|
320
|
+
filename += object.name
|
321
|
+
elsif object.respond_to?(:id)
|
322
|
+
filename += object.id
|
323
|
+
end
|
324
|
+
|
325
|
+
edited_data = Tempfile.open([filename, ".js"]) do |tempfile|
|
326
|
+
tempfile.sync = true
|
327
|
+
tempfile.puts object.to_json
|
328
|
+
system("#{Shef.editor.to_s} #{tempfile.path}")
|
329
|
+
tempfile.rewind
|
330
|
+
tempfile.read
|
331
|
+
end
|
332
|
+
|
333
|
+
JSON.parse(edited_data)
|
334
|
+
end
|
335
|
+
|
336
|
+
desc "Find and edit API clients"
|
337
|
+
explain(<<-E)
|
338
|
+
## SUMMARY ##
|
339
|
+
+clients+ allows you to query you chef server for information about your api
|
340
|
+
clients.
|
341
|
+
|
342
|
+
## LIST ALL CLIENTS ##
|
343
|
+
To see all clients on the system, use
|
344
|
+
|
345
|
+
clients.all #=> [<Chef::ApiClient...>, ...]
|
346
|
+
|
347
|
+
If the output from all is too verbose, or you're only interested in a specific
|
348
|
+
value from each of the objects, you can give a code block to +all+:
|
349
|
+
|
350
|
+
clients.all { |client| client.name } #=> [CLIENT1_NAME, CLIENT2_NAME, ...]
|
351
|
+
|
352
|
+
## SHOW ONE CLIENT ##
|
353
|
+
To see a specific client, use
|
354
|
+
|
355
|
+
clients.show(CLIENT_NAME)
|
356
|
+
|
357
|
+
## SEARCH FOR CLIENTS ##
|
358
|
+
You can also search for clients using +find+ or +search+. You can use the
|
359
|
+
familiar string search syntax:
|
360
|
+
|
361
|
+
clients.search("KEY:VALUE")
|
362
|
+
|
363
|
+
Just as the +all+ subcommand, the +search+ subcommand can use a code block to
|
364
|
+
filter or transform the information returned from the search:
|
365
|
+
|
366
|
+
clients.search("KEY:VALUE") { |c| c.name }
|
367
|
+
|
368
|
+
You can also use a Hash based syntax, multiple search conditions will be
|
369
|
+
joined with AND.
|
370
|
+
|
371
|
+
clients.find :KEY => :VALUE, :KEY2 => :VALUE2, ...
|
372
|
+
|
373
|
+
## BULK-EDIT CLIENTS ##
|
374
|
+
**BE CAREFUL, THIS IS DESTRUCTIVE**
|
375
|
+
You can bulk edit API Clients using the +transform+ subcommand, which requires
|
376
|
+
a code block. Each client will be saved after the code block is run. If the
|
377
|
+
code block returns +nil+ or +false+, that client will be skipped:
|
378
|
+
|
379
|
+
clients.transform("*:*") do |client|
|
380
|
+
if client.name =~ /borat/i
|
381
|
+
client.admin(false)
|
382
|
+
true
|
383
|
+
else
|
384
|
+
nil
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
This will strip the admin privileges from any client named after borat.
|
389
|
+
E
|
390
|
+
subcommands :all => "list all api clients",
|
391
|
+
:show => "load an api client by name",
|
392
|
+
:search => "search for API clients",
|
393
|
+
:transform => "edit all api clients via a code block and save them"
|
394
|
+
def clients
|
395
|
+
@clients ||= Shef::ModelWrapper.new(Chef::ApiClient, :client)
|
396
|
+
end
|
397
|
+
|
398
|
+
desc "Find and edit cookbooks"
|
399
|
+
subcommands :all => "list all cookbooks",
|
400
|
+
:show => "load a cookbook by name",
|
401
|
+
:transform => "edit all cookbooks via a code block and save them"
|
402
|
+
def cookbooks
|
403
|
+
@cookbooks ||= Shef::ModelWrapper.new(Chef::CookbookVersion)
|
404
|
+
end
|
405
|
+
|
406
|
+
desc "Find and edit nodes via the API"
|
407
|
+
explain(<<-E)
|
408
|
+
## SUMMARY ##
|
409
|
+
+nodes+ Allows you to query your chef server for information about your nodes.
|
410
|
+
|
411
|
+
## LIST ALL NODES ##
|
412
|
+
You can list all nodes using +all+ or +list+
|
413
|
+
|
414
|
+
nodes.all #=> [<Chef::Node...>, <Chef::Node...>, ...]
|
415
|
+
|
416
|
+
To limit the information returned for each node, pass a code block to the +all+
|
417
|
+
subcommand:
|
418
|
+
|
419
|
+
nodes.all { |node| node.name } #=> [NODE1_NAME, NODE2_NAME, ...]
|
420
|
+
|
421
|
+
## SHOW ONE NODE ##
|
422
|
+
You can show the data for a single node using the +show+ subcommand:
|
423
|
+
|
424
|
+
nodes.show("NODE_NAME") => <Chef::Node @name="NODE_NAME" ...>
|
425
|
+
|
426
|
+
## SEARCH FOR NODES ##
|
427
|
+
You can search for nodes using the +search+ or +find+ subcommands:
|
428
|
+
|
429
|
+
nodes.find(:name => "app*") #=> [<Chef::Node @name="app1.example.com" ...>, ...]
|
430
|
+
|
431
|
+
Similarly to +all+, you can pass a code block to limit or transform the
|
432
|
+
information returned:
|
433
|
+
|
434
|
+
nodes.find(:name => "app#") { |node| node.ec2 }
|
435
|
+
|
436
|
+
## BULK EDIT NODES ##
|
437
|
+
**BE CAREFUL, THIS OPERATION IS DESTRUCTIVE**
|
438
|
+
|
439
|
+
Bulk edit nodes by passing a code block to the +transform+ or +bulk_edit+
|
440
|
+
subcommand. The block will be applied to each matching node, and then the node
|
441
|
+
will be saved. If the block returns +nil+ or +false+, that node will be
|
442
|
+
skipped.
|
443
|
+
|
444
|
+
nodes.transform do |node|
|
445
|
+
if node.fqdn =~ /.*\\.preprod\\.example\\.com/
|
446
|
+
node.set[:environment] = "preprod"
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
This will assign the attribute to every node with a FQDN matching the regex.
|
451
|
+
E
|
452
|
+
subcommands :all => "list all nodes",
|
453
|
+
:show => "load a node by name",
|
454
|
+
:search => "search for nodes",
|
455
|
+
:transform => "edit all nodes via a code block and save them"
|
456
|
+
def nodes
|
457
|
+
@nodes ||= Shef::ModelWrapper.new(Chef::Node)
|
458
|
+
end
|
459
|
+
|
460
|
+
desc "Find and edit roles via the API"
|
461
|
+
explain(<<-E)
|
462
|
+
## SUMMARY ##
|
463
|
+
+roles+ allows you to query and edit roles on your Chef server.
|
464
|
+
|
465
|
+
## SUBCOMMANDS ##
|
466
|
+
* all (list)
|
467
|
+
* show (load)
|
468
|
+
* search (find)
|
469
|
+
* transform (bulk_edit)
|
470
|
+
|
471
|
+
## SEE ALSO ##
|
472
|
+
See the help for +nodes+ for more information about the subcommands.
|
473
|
+
E
|
474
|
+
subcommands :all => "list all roles",
|
475
|
+
:show => "load a role by name",
|
476
|
+
:search => "search for roles",
|
477
|
+
:transform => "edit all roles via a code block and save them"
|
478
|
+
def roles
|
479
|
+
@roles ||= Shef::ModelWrapper.new(Chef::Role)
|
480
|
+
end
|
481
|
+
|
482
|
+
desc "Find and edit +databag_name+ via the api"
|
483
|
+
explain(<<-E)
|
484
|
+
## SUMMARY ##
|
485
|
+
+databags(DATABAG_NAME)+ allows you to query and edit data bag items on your
|
486
|
+
Chef server. Unlike other commands for working with data on the server,
|
487
|
+
+databags+ requires the databag name as an argument, for example:
|
488
|
+
databags(:users).all
|
489
|
+
|
490
|
+
## SUBCOMMANDS ##
|
491
|
+
* all (list)
|
492
|
+
* show (load)
|
493
|
+
* search (find)
|
494
|
+
* transform (bulk_edit)
|
495
|
+
|
496
|
+
## SEE ALSO ##
|
497
|
+
See the help for +nodes+ for more information about the subcommands.
|
498
|
+
|
499
|
+
E
|
500
|
+
subcommands :all => "list all items in the data bag",
|
501
|
+
:show => "load a data bag item by id",
|
502
|
+
:search => "search for items in the data bag",
|
503
|
+
:transform => "edit all items via a code block and save them"
|
504
|
+
def databags(databag_name)
|
505
|
+
@named_databags_wrappers ||= {}
|
506
|
+
@named_databags_wrappers[databag_name] ||= Shef::NamedDataBagWrapper.new(databag_name)
|
507
|
+
end
|
508
|
+
|
509
|
+
desc "A REST Client configured to authenticate with the API"
|
510
|
+
def api
|
511
|
+
@rest = Shef::ShefREST.new(Chef::Config[:chef_server_url])
|
512
|
+
end
|
513
|
+
|
514
|
+
end
|
515
|
+
|
516
|
+
RecipeUIExtensions = Proc.new do
|
517
|
+
alias :original_resources :resources
|
518
|
+
|
519
|
+
desc "list all the resources on the current recipe"
|
520
|
+
def resources(*args)
|
521
|
+
if args.empty?
|
522
|
+
pp run_context.resource_collection.instance_variable_get(:@resources_by_name).keys
|
523
|
+
else
|
524
|
+
pp resources = original_resources(*args)
|
525
|
+
resources
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
def self.extend_context_object(obj)
|
531
|
+
obj.instance_eval(&ObjectUIExtensions)
|
532
|
+
obj.instance_eval(&RESTApiExtensions)
|
533
|
+
obj.extend(FileUtils)
|
534
|
+
obj.extend(Chef::Mixin::Language)
|
535
|
+
end
|
536
|
+
|
537
|
+
def self.extend_context_node(node_obj)
|
538
|
+
node_obj.instance_eval(&ObjectUIExtensions)
|
539
|
+
end
|
540
|
+
|
541
|
+
def self.extend_context_recipe(recipe_obj)
|
542
|
+
recipe_obj.instance_eval(&ObjectUIExtensions)
|
543
|
+
recipe_obj.instance_eval(&RecipeUIExtensions)
|
544
|
+
end
|
545
|
+
|
165
546
|
end
|
166
547
|
end
|
167
548
|
|
@@ -181,129 +562,3 @@ class FalseClass
|
|
181
562
|
include Shef::Extensions::FalseClass
|
182
563
|
end
|
183
564
|
|
184
|
-
class Object
|
185
|
-
extend Shef::Extensions::Object::ClassMethods
|
186
|
-
include Shef::Extensions::Object
|
187
|
-
include FileUtils
|
188
|
-
|
189
|
-
desc "prints this help message"
|
190
|
-
def shef_help(title="Help: Shef")
|
191
|
-
#puts Shef::Extensions::Object.help_banner("Shef Help")
|
192
|
-
puts help_banner(title)
|
193
|
-
:ucanhaz_halp
|
194
|
-
end
|
195
|
-
alias :halp :shef_help
|
196
|
-
|
197
|
-
desc "prints information about chef"
|
198
|
-
def version
|
199
|
-
puts "This is shef, the Chef shell.\n" +
|
200
|
-
" Chef Version: #{::Chef::VERSION}\n" +
|
201
|
-
" http://www.opscode.com/chef\n" +
|
202
|
-
" http://wiki.opscode.com/display/chef/Home"
|
203
|
-
:ucanhaz_automation
|
204
|
-
end
|
205
|
-
alias :shef :version
|
206
|
-
|
207
|
-
desc "switch to recipe mode"
|
208
|
-
def recipe
|
209
|
-
find_or_create_session_for Shef.session.recipe
|
210
|
-
:recipe
|
211
|
-
end
|
212
|
-
|
213
|
-
desc "switch to attributes mode"
|
214
|
-
def attributes
|
215
|
-
find_or_create_session_for Shef.session.node
|
216
|
-
:attributes
|
217
|
-
end
|
218
|
-
|
219
|
-
desc "returns the current node (i.e., this host)"
|
220
|
-
def node
|
221
|
-
Shef.session.node
|
222
|
-
end
|
223
|
-
|
224
|
-
desc "pretty print the node's attributes"
|
225
|
-
def ohai(key=nil)
|
226
|
-
pp(key ? node.attribute[key] : node.attribute)
|
227
|
-
end
|
228
|
-
|
229
|
-
desc "run chef using the current recipe"
|
230
|
-
def run_chef
|
231
|
-
Chef::Log.level = :debug
|
232
|
-
session = Shef.session
|
233
|
-
runrun = Chef::Runner.new(session.run_context).converge
|
234
|
-
Chef::Log.level = :info
|
235
|
-
runrun
|
236
|
-
end
|
237
|
-
|
238
|
-
desc "returns an object to control a paused chef run"
|
239
|
-
subcommands :resume => "resume the chef run",
|
240
|
-
:step => "run only the next resource",
|
241
|
-
:skip_back => "move back in the run list",
|
242
|
-
:skip_forward => "move forward in the run list"
|
243
|
-
def chef_run
|
244
|
-
Shef.session.resource_collection.iterator
|
245
|
-
end
|
246
|
-
|
247
|
-
desc "resets the current recipe"
|
248
|
-
def reset
|
249
|
-
Shef.session.reset!
|
250
|
-
end
|
251
|
-
|
252
|
-
desc "turns printout of return values on or off"
|
253
|
-
def echo(on_or_off)
|
254
|
-
conf.echo = on_or_off.on_off_to_bool
|
255
|
-
end
|
256
|
-
|
257
|
-
desc "says if echo is on or off"
|
258
|
-
def echo?
|
259
|
-
puts "echo is #{conf.echo.to_on_off_str}"
|
260
|
-
end
|
261
|
-
|
262
|
-
desc "turns on or off tracing of execution. *verbose*"
|
263
|
-
def tracing(on_or_off)
|
264
|
-
conf.use_tracer = on_or_off.on_off_to_bool
|
265
|
-
tracing?
|
266
|
-
end
|
267
|
-
alias :trace :tracing
|
268
|
-
|
269
|
-
desc "says if tracing is on or off"
|
270
|
-
def tracing?
|
271
|
-
puts "tracing is #{conf.use_tracer.to_on_off_str}"
|
272
|
-
end
|
273
|
-
alias :trace? :tracing?
|
274
|
-
|
275
|
-
desc "simple ls style command"
|
276
|
-
def ls(directory)
|
277
|
-
Dir.entries(directory)
|
278
|
-
end
|
279
|
-
|
280
|
-
end
|
281
|
-
|
282
|
-
class String
|
283
|
-
undef_method :version
|
284
|
-
end
|
285
|
-
|
286
|
-
class NilClass
|
287
|
-
undef_method :version
|
288
|
-
end
|
289
|
-
|
290
|
-
class Chef
|
291
|
-
class Recipe
|
292
|
-
|
293
|
-
def shef_help
|
294
|
-
super("Help: Shef/Recipe")
|
295
|
-
end
|
296
|
-
|
297
|
-
alias :original_resources :resources
|
298
|
-
|
299
|
-
desc "list all the resources on the current recipe"
|
300
|
-
def resources(*args)
|
301
|
-
if args.empty?
|
302
|
-
pp run_context.resource_collection.instance_variable_get(:@resources_by_name).keys
|
303
|
-
else
|
304
|
-
pp resources = original_resources(*args)
|
305
|
-
resources
|
306
|
-
end
|
307
|
-
end
|
308
|
-
end
|
309
|
-
end
|