chef 0.10.0.beta.8 → 0.10.0.beta.9

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 (70) hide show
  1. data/distro/common/html/knife-bootstrap.1.html +69 -10
  2. data/distro/common/html/knife-client.1.html +25 -22
  3. data/distro/common/html/knife-configure.1.html +1 -1
  4. data/distro/common/html/knife-cookbook-site.1.html +91 -19
  5. data/distro/common/html/knife-cookbook.1.html +216 -76
  6. data/distro/common/html/knife-data-bag.1.html +1 -1
  7. data/distro/common/html/knife-environment.1.html +177 -3
  8. data/distro/common/html/knife-exec.1.html +44 -3
  9. data/distro/common/html/knife-index.1.html +1 -1
  10. data/distro/common/html/knife-node.1.html +5 -3
  11. data/distro/common/html/knife-recipe.1.html +1 -1
  12. data/distro/common/html/knife-role.1.html +83 -19
  13. data/distro/common/html/knife-search.1.html +43 -2
  14. data/distro/common/html/knife-ssh.1.html +57 -2
  15. data/distro/common/html/knife-status.1.html +33 -2
  16. data/distro/common/html/knife-tag.1.html +45 -1
  17. data/distro/common/html/knife.1.html +94 -161
  18. data/distro/common/html/shef.1.html +283 -0
  19. data/distro/common/man/man1/knife-bootstrap.1 +56 -4
  20. data/distro/common/man/man1/knife-client.1 +12 -11
  21. data/distro/common/man/man1/knife-configure.1 +1 -1
  22. data/distro/common/man/man1/knife-cookbook-site.1 +64 -22
  23. data/distro/common/man/man1/knife-cookbook.1 +200 -122
  24. data/distro/common/man/man1/knife-data-bag.1 +1 -1
  25. data/distro/common/man/man1/knife-environment.1 +167 -2
  26. data/distro/common/man/man1/knife-exec.1 +36 -3
  27. data/distro/common/man/man1/knife-index.1 +1 -1
  28. data/distro/common/man/man1/knife-node.1 +2 -1
  29. data/distro/common/man/man1/knife-role.1 +48 -24
  30. data/distro/common/man/man1/knife-search.1 +27 -3
  31. data/distro/common/man/man1/knife-ssh.1 +43 -2
  32. data/distro/common/man/man1/knife-status.1 +14 -2
  33. data/distro/common/man/man1/knife-tag.1 +32 -2
  34. data/distro/common/man/man1/knife.1 +91 -186
  35. data/distro/common/man/man1/shef.1 +237 -26
  36. data/distro/common/markdown/man1/knife-bootstrap.mkd +57 -7
  37. data/distro/common/markdown/man1/knife-client.mkd +19 -17
  38. data/distro/common/markdown/man1/knife-cookbook-site.mkd +63 -15
  39. data/distro/common/markdown/man1/knife-cookbook.mkd +220 -103
  40. data/distro/common/markdown/man1/knife-environment.mkd +144 -1
  41. data/distro/common/markdown/man1/knife-exec.mkd +29 -1
  42. data/distro/common/markdown/man1/knife-node.mkd +1 -1
  43. data/distro/common/markdown/man1/knife-role.mkd +36 -30
  44. data/distro/common/markdown/man1/knife-search.mkd +0 -1
  45. data/distro/common/markdown/man1/knife-ssh.mkd +0 -2
  46. data/distro/common/markdown/man1/knife-status.mkd +0 -2
  47. data/distro/common/markdown/man1/knife-tag.mkd +31 -0
  48. data/distro/common/markdown/man1/knife.mkd +93 -165
  49. data/distro/common/markdown/man1/shef.mkd +189 -0
  50. data/lib/chef/api_client.rb +36 -35
  51. data/lib/chef/application/knife.rb +1 -1
  52. data/lib/chef/client.rb +1 -0
  53. data/lib/chef/cookbook/cookbook_version_loader.rb +29 -7
  54. data/lib/chef/cookbook_uploader.rb +55 -36
  55. data/lib/chef/cookbook_version.rb +3 -1
  56. data/lib/chef/couchdb.rb +0 -1
  57. data/lib/chef/knife/cookbook_list.rb +1 -1
  58. data/lib/chef/knife/cookbook_show.rb +1 -0
  59. data/lib/chef/knife/core/generic_presenter.rb +3 -3
  60. data/lib/chef/knife/help.rb +6 -2
  61. data/lib/chef/knife/tag_create.rb +26 -5
  62. data/lib/chef/knife/tag_delete.rb +34 -5
  63. data/lib/chef/knife/tag_list.rb +24 -6
  64. data/lib/chef/node.rb +1 -0
  65. data/lib/chef/role.rb +1 -0
  66. data/lib/chef/shef.rb +1 -0
  67. data/lib/chef/version.rb +1 -1
  68. metadata +4 -4
  69. data/distro/common/man/man1/knife-recipe.1 +0 -13
  70. data/distro/common/markdown/man1/knife-recipe.mkd +0 -24
@@ -0,0 +1,189 @@
1
+ shef(1) -- Interactive Chef Console
2
+ ========================================
3
+
4
+ ## SYNOPSIS
5
+
6
+ __shef__ [_named configuration_] _(options)_
7
+
8
+ * `-S`, `--server CHEF_SERVER_URL`:
9
+ The chef server URL
10
+ * `-z`, `--client`:
11
+ chef-client mode
12
+ * `-c`, `--config CONFIG`:
13
+ The configuration file to use
14
+ * `-j`, `--json-attributes JSON_ATTRIBS`:
15
+ Load attributes from a JSON file or URL
16
+ * `-l`, `--log-level LOG_LEVEL`:
17
+ Set the logging level
18
+ * `-s`, `--solo`:
19
+ chef-solo shef session
20
+ * `-a`, `--standalone`:
21
+ standalone shef session
22
+ * `-v`, `--version`:
23
+ Show chef version
24
+ * `-h`, `--help`:
25
+ Show command options
26
+
27
+ When no --config option is specified, shef attempts to load a default configuration file:
28
+
29
+ * If a _named configuration_ is given, shef will load ~/.chef/_named
30
+ configuration_/shef.rb
31
+ * If no _named configuration_ is given shef will load ~/.chef/shef.rb if it exists
32
+ * Shef falls back to loading /etc/chef/client.rb or /etc/chef/solo.rb if -z or
33
+ -s options are given and no shef.rb can be found.
34
+ * The --config option takes precedence over implicit configuration
35
+ paths.
36
+
37
+ ## DESCRIPTION
38
+
39
+ `shef` is an irb(1) (interactive ruby) session customized for Chef.
40
+ `shef` serves two primary functions: it provides a means to
41
+ interact with a Chef Server interactively using a convenient DSL; it
42
+ allows you to define and run Chef recipes interactively.
43
+
44
+ ## SYNTAX
45
+ Shef uses irb's subsession feature to provide multiple modes of
46
+ interaction. In addition to the primary mode which is entered on start,
47
+ `recipe` and `attributes` modes are available.
48
+
49
+ ## PRIMARY MODE
50
+ The following commands are available in the primary
51
+ session:
52
+
53
+ * `help`:
54
+ Prints a list of available commands
55
+ * `version`:
56
+ Prints the Chef version
57
+ * `recipe`:
58
+ Switches to `recipe` mode
59
+ * `attributes`:
60
+ Switches to `attributes` mode
61
+ * `run_chef`:
62
+ Initiates a chef run
63
+ * `reset`:
64
+ reinitializes shef
65
+ * `echo :on|:off`:
66
+ Turns irb's echo function on or off. Echo is _on_ by default.
67
+ * `tracing :on|:off`:
68
+ Turns irb's function tracing feature on or off. Tracing is extremely
69
+ verbose and expected to be of interest primarily to developers.
70
+ * `node`:
71
+ Returns the _node_ object for the current host. See knife-node(1)
72
+ for more information about nodes.
73
+ * `ohai`:
74
+ Prints the attributes of _node_
75
+
76
+ In addition to these commands, shef provides a DSL for accessing data on
77
+ the Chef Server. When working with remote data in shef, you chain method
78
+ calls in the form _object type_._operation_, where _object type_ is in
79
+ plural form. The following object types are available:
80
+
81
+ * `nodes`
82
+ * `roles`
83
+ * `data_bags`
84
+ * `clients`
85
+ * `cookbooks`
86
+
87
+ For each _object type_ the following operations are available:
88
+
89
+ * _object type_.all(_&block_):
90
+ Loads all items from the server. If the optional code _block_ is
91
+ given, each item will be passed to the block and the results
92
+ returned, similar to ruby's `Enumerable#map` method.
93
+ * _object type_.show(_object name_):
94
+ Aliased as _object type_.load
95
+
96
+ Loads the singular item identified by _object name_.
97
+ * _object type_.search(_query_, _&block_):
98
+ Aliased as _object type_.find
99
+
100
+ Runs a search against the server and returns the matching items. If
101
+ the optional code _block_ is given each item will be passed to the
102
+ block and the results returned.
103
+
104
+ The _query_ may be a Solr/Lucene format query given as a String, or
105
+ a Hash of conditions. If a Hash is given, the options will be ANDed
106
+ together. To join conditions with OR, use negative queries, or any
107
+ advanced search syntax, you must provide give the query in String
108
+ form.
109
+ * _object type_.transform(:all|_query_, _&block_):
110
+ Aliased as _object type_.bulk_edit
111
+
112
+ Bulk edit objects by processing them with the (required) code _block_.
113
+ You can edit all objects of the given type by passing the Symbol
114
+ `:all` as the argument, or only a subset by passing a _query_ as the
115
+ argument. The _query_ is evaluated in the same way as with
116
+ __search__.
117
+
118
+ The return value of the code _block_ is used to alter the behavior
119
+ of `transform`. If the value returned from the block is `nil` or
120
+ `false`, the object will not be saved. Otherwise, the object is
121
+ saved after being passed to the block. This behavior can be
122
+ exploited to create a dry run to test a data transformation.
123
+
124
+ ## RECIPE MODE
125
+ Recipe mode implements Chef's recipe DSL. Exhaustively documenting this
126
+ DSL is outside the scope of this document. See the following pages in
127
+ the Chef documentation for more information:
128
+
129
+ * <http://wiki.opscode.com/display/chef/Resources>
130
+ * <http://wiki.opscode.com/display/chef/Recipes>
131
+
132
+ Once you have defined resources in the recipe, you can trigger a
133
+ convergence run via `run_chef`
134
+
135
+ ## EXAMPLES
136
+
137
+ * A "Hello World" interactive recipe
138
+
139
+ chef > recipe
140
+ chef:recipe > echo :off
141
+ chef:recipe > file "/tmp/hello\_world"
142
+ chef:recipe > run\_chef
143
+ [Sat, 09 Apr 2011 08:56:56 -0700] INFO: Processing file[/tmp/hello\_world] action create ((irb#1) line 2)
144
+ [Sat, 09 Apr 2011 08:56:56 -0700] INFO: file[/tmp/hello\_world] created file /tmp/hello\_world
145
+ chef:recipe > pp ls '/tmp'
146
+ [".",
147
+ "..",
148
+ "hello\_world"]
149
+
150
+ * Search for _nodes_ by role, and print their IP addresses
151
+
152
+ chef > nodes.find(:roles => 'monitoring-server') {|n| n[:ipaddress] }
153
+ => ["10.254.199.5"]
154
+
155
+ * Remove the role _obsolete_ from every node in the system
156
+
157
+ chef > nodes.transform(:all) {|n| n.run\_list.delete('role[obsolete]') }
158
+ => [node[chef098b2.opschef.com], node[ree-woot], node[graphite-dev], node[fluke.localdomain], node[ghost.local], node[kallistec]]
159
+
160
+
161
+ ## BUGS
162
+ The name `shef` is clever in print but is confusing when spoken aloud.
163
+ Pronouncing `shef` as `chef console` is an imperfect workaround.
164
+
165
+ `shef` often does not perfectly replicate the context in which
166
+ chef-client(8) configures a host, which may lead to discrepancies in
167
+ observed behavior.
168
+
169
+ `shef` has to duplicate much code from chef-client's internal libraries
170
+ and may become out of sync with the behavior of those libraries.
171
+
172
+ ## SEE ALSO
173
+ chef-client(8) knife(1)
174
+ <http://wiki.opscode.com/display/chef/Shef>
175
+
176
+ ## AUTHOR
177
+ Chef was written by Adam Jacob <adam@opscode.com> with many
178
+ contributions from the community. Shef was written by Daniel DeLeo.
179
+
180
+ ## DOCUMENTATION
181
+ This manual page was written by Daniel DeLeo <dan@opscode.com>.
182
+ Permission is granted to copy, distribute and / or modify this
183
+ document under the terms of the Apache 2.0 License.
184
+
185
+ ## CHEF
186
+ Shef is distributed with Chef. <http://wiki.opscode.com/display/chef/Home>
187
+
188
+
189
+
@@ -7,9 +7,9 @@
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
9
9
  # You may obtain a copy of the License at
10
- #
10
+ #
11
11
  # http://www.apache.org/licenses/LICENSE-2.0
12
- #
12
+ #
13
13
  # Unless required by applicable law or agreed to in writing, software
14
14
  # distributed under the License is distributed on an "AS IS" BASIS,
15
15
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,22 +25,23 @@ require 'chef/certificate'
25
25
  require 'chef/index_queue'
26
26
  require 'chef/mash'
27
27
  require 'chef/json_compat'
28
+ require 'chef/search/query'
28
29
 
29
30
  class Chef
30
- class ApiClient
31
-
31
+ class ApiClient
32
+
32
33
  include Chef::Mixin::FromFile
33
34
  include Chef::Mixin::ParamsValidate
34
35
  include Chef::IndexQueue::Indexable
35
-
36
-
36
+
37
+
37
38
  DESIGN_DOCUMENT = {
38
39
  "version" => 1,
39
40
  "language" => "javascript",
40
41
  "views" => {
41
42
  "all" => {
42
43
  "map" => <<-EOJS
43
- function(doc) {
44
+ function(doc) {
44
45
  if (doc.chef_type == "client") {
45
46
  emit(doc.name, doc);
46
47
  }
@@ -49,7 +50,7 @@ class Chef
49
50
  },
50
51
  "all_id" => {
51
52
  "map" => <<-EOJS
52
- function(doc) {
53
+ function(doc) {
53
54
  if (doc.chef_type == "client") {
54
55
  emit(doc.name, doc.name);
55
56
  }
@@ -60,10 +61,10 @@ class Chef
60
61
  }
61
62
 
62
63
  attr_accessor :couchdb_rev, :couchdb_id, :couchdb
63
-
64
+
64
65
  # Create a new Chef::ApiClient object.
65
66
  def initialize(couchdb=nil)
66
- @name = ''
67
+ @name = ''
67
68
  @public_key = nil
68
69
  @private_key = nil
69
70
  @couchdb_rev = nil
@@ -76,7 +77,7 @@ class Chef
76
77
  #
77
78
  # @params [Optional String] The name must be alpha-numeric plus - and _.
78
79
  # @return [String] The current value of the name.
79
- def name(arg=nil)
80
+ def name(arg=nil)
80
81
  set_or_return(
81
82
  :name,
82
83
  arg,
@@ -84,7 +85,7 @@ class Chef
84
85
  )
85
86
  end
86
87
 
87
- # Gets or sets whether this client is an admin.
88
+ # Gets or sets whether this client is an admin.
88
89
  #
89
90
  # @params [Optional True/False] Should be true or false - default is false.
90
91
  # @return [True/False] The current value
@@ -97,10 +98,10 @@ class Chef
97
98
  end
98
99
 
99
100
  # Gets or sets the public key.
100
- #
101
- # @params [Optional String] The string representation of the public key.
101
+ #
102
+ # @params [Optional String] The string representation of the public key.
102
103
  # @return [String] The current value.
103
- def public_key(arg=nil)
104
+ def public_key(arg=nil)
104
105
  set_or_return(
105
106
  :public_key,
106
107
  arg,
@@ -109,10 +110,10 @@ class Chef
109
110
  end
110
111
 
111
112
  # Gets or sets the private key.
112
- #
113
+ #
113
114
  # @params [Optional String] The string representation of the private key.
114
115
  # @return [String] The current value.
115
- def private_key(arg=nil)
116
+ def private_key(arg=nil)
116
117
  set_or_return(
117
118
  :private_key,
118
119
  arg,
@@ -122,7 +123,7 @@ class Chef
122
123
 
123
124
  # Creates a new public/private key pair, and populates the public_key and
124
125
  # private_key attributes.
125
- #
126
+ #
126
127
  # @return [True]
127
128
  def create_keys
128
129
  results = Chef::Certificate.gen_keypair(self.name)
@@ -133,7 +134,7 @@ class Chef
133
134
 
134
135
  # The hash representation of the object. Includes the name and public_key,
135
136
  # but never the private key.
136
- #
137
+ #
137
138
  # @return [Hash]
138
139
  def to_hash
139
140
  result = {
@@ -148,12 +149,12 @@ class Chef
148
149
  end
149
150
 
150
151
  # The JSON representation of the object.
151
- #
152
+ #
152
153
  # @return [String] the JSON string.
153
154
  def to_json(*a)
154
155
  to_hash.to_json(*a)
155
156
  end
156
-
157
+
157
158
  def self.json_create(o)
158
159
  client = Chef::ApiClient.new
159
160
  client.name(o["name"] || o["clientname"])
@@ -164,7 +165,7 @@ class Chef
164
165
  client.index_id = client.couchdb_id
165
166
  client
166
167
  end
167
-
168
+
168
169
  # List all the Chef::ApiClient objects in the CouchDB. If inflate is set
169
170
  # to true, you will get the full list of all ApiClients, fully inflated.
170
171
  def self.cdb_list(inflate=false, couchdb=nil)
@@ -172,7 +173,7 @@ class Chef
172
173
  lookup = (inflate ? "value" : "key")
173
174
  rs["rows"].collect { |r| r[lookup] }
174
175
  end
175
-
176
+
176
177
  def self.list(inflate=false)
177
178
  if inflate
178
179
  response = Hash.new
@@ -185,15 +186,15 @@ class Chef
185
186
  Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("clients")
186
187
  end
187
188
  end
188
-
189
+
189
190
  # Load a client by name from CouchDB
190
- #
191
+ #
191
192
  # @params [String] The name of the client to load
192
193
  # @return [Chef::ApiClient] The resulting Chef::ApiClient object
193
194
  def self.cdb_load(name, couchdb=nil)
194
195
  (couchdb || Chef::CouchDB.new).load("client", name)
195
196
  end
196
-
197
+
197
198
  # Load a client by name via the API
198
199
  def self.load(name)
199
200
  response = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("clients/#{name}")
@@ -205,7 +206,7 @@ class Chef
205
206
  client
206
207
  end
207
208
  end
208
-
209
+
209
210
  # Remove this client from the CouchDB
210
211
  #
211
212
  # @params [String] The name of the client to delete
@@ -213,17 +214,17 @@ class Chef
213
214
  def cdb_destroy
214
215
  @couchdb.delete("client", @name, @couchdb_rev)
215
216
  end
216
-
217
+
217
218
  # Remove this client via the REST API
218
219
  def destroy
219
220
  Chef::REST.new(Chef::Config[:chef_server_url]).delete_rest("clients/#{@name}")
220
221
  end
221
-
222
+
222
223
  # Save this client to the CouchDB
223
224
  def cdb_save
224
225
  @couchdb_rev = @couchdb.store("client", @name, self)["rev"]
225
226
  end
226
-
227
+
227
228
  # Save this client via the REST API, returns a hash including the private key
228
229
  def save(new_key=false, validation=false)
229
230
  if validation
@@ -237,23 +238,23 @@ class Chef
237
238
  rescue Net::HTTPServerException => e
238
239
  # If that fails, go ahead and try and update it
239
240
  if e.response.code == "409"
240
- r.put_rest("clients/#{name}", { :name => self.name, :admin => self.admin, :private_key => new_key })
241
+ r.put_rest("clients/#{name}", { :name => self.name, :admin => self.admin, :private_key => new_key })
241
242
  else
242
243
  raise e
243
244
  end
244
245
  end
245
- end
246
-
246
+ end
247
+
247
248
  # Create the client via the REST API
248
249
  def create
249
250
  Chef::REST.new(Chef::Config[:chef_server_url]).post_rest("clients", self)
250
251
  end
251
-
252
+
252
253
  # Set up our CouchDB design document
253
254
  def self.create_design_document(couchdb=nil)
254
255
  (couchdb ||= Chef::CouchDB.new).create_design_document("clients", DESIGN_DOCUMENT)
255
256
  end
256
-
257
+
257
258
  # As a string
258
259
  def to_s
259
260
  "client[#{@name}]"
@@ -24,7 +24,7 @@ class Chef::Application::Knife < Chef::Application
24
24
 
25
25
  NO_COMMAND_GIVEN = "You need to pass a sub-command (e.g., knife SUB-COMMAND)\n"
26
26
 
27
- banner "Usage: #{$0} sub-command (options)"
27
+ banner "Usage: knife sub-command (options)"
28
28
 
29
29
  option :config_file,
30
30
  :short => "-c CONFIG",
data/lib/chef/client.rb CHANGED
@@ -22,6 +22,7 @@ require 'chef/config'
22
22
  require 'chef/mixin/params_validate'
23
23
  require 'chef/log'
24
24
  require 'chef/rest'
25
+ require 'chef/api_client'
25
26
  require 'chef/platform'
26
27
  require 'chef/node'
27
28
  require 'chef/role'
@@ -56,7 +56,9 @@ class Chef
56
56
 
57
57
  remove_ignored_files
58
58
 
59
- if File.exists?(File.join(@cookbook_path, "metadata.json"))
59
+ if File.exists?(File.join(@cookbook_path, "metadata.rb"))
60
+ @metadata_filenames << File.join(@cookbook_path, "metadata.rb")
61
+ elsif File.exists?(File.join(@cookbook_path, "metadata.json"))
60
62
  @metadata_filenames << File.join(@cookbook_path, "metadata.json")
61
63
  end
62
64
 
@@ -88,12 +90,14 @@ class Chef
88
90
  # Generates the Cookbook::Metadata object
89
91
  def metadata(cookbook_version)
90
92
  @metadata = Chef::Cookbook::Metadata.new(cookbook_version)
91
- @metadata_filenames.each do |meta_json|
92
- begin
93
- @metadata.from_json(IO.read(meta_json))
94
- rescue JSON::ParserError
95
- Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + meta_json)
96
- raise
93
+ @metadata_filenames.each do |metadata_file|
94
+ case metadata_file
95
+ when /\.rb$/
96
+ apply_ruby_metadata(metadata_file)
97
+ when /\.json$/
98
+ apply_json_metadata(metadata_file)
99
+ else
100
+ raise RuntimeError, "Invalid metadata file: #{metadata_file} for cookbook: #{cookbook_version}"
97
101
  end
98
102
  end
99
103
  @metadata
@@ -146,6 +150,24 @@ class Chef
146
150
  end
147
151
  end
148
152
 
153
+ def apply_ruby_metadata(file)
154
+ begin
155
+ @metadata.from_file(file)
156
+ rescue JSON::ParserError
157
+ Chef::Log.error("Error evaluating metadata.rb for #@cookbook_name in " + file)
158
+ raise
159
+ end
160
+ end
161
+
162
+ def apply_json_metadata(file)
163
+ begin
164
+ @metadata.from_json(IO.read(file))
165
+ rescue JSON::ParserError
166
+ Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
167
+ raise
168
+ end
169
+ end
170
+
149
171
  end
150
172
  end
151
173
  end