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

Sign up to get free protection for your applications and to get access to all the features.
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