knife-essentials 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -116,6 +116,70 @@ work. Use +--tree+ parameter to show this in a tree structure. Use +--remote+
116
116
  to perform this operation against the data on the server rather than the local
117
117
  Chef repository.
118
118
 
119
+ = CONFIGURATION
120
+
121
+ There are several variables you can set in your +knife.rb+ file to alter the
122
+ behavior of knife-essentials
123
+
124
+ == chef_repo_path
125
+
126
+ chef_repo_path PATH|[PATH1, PATH2, ...]
127
+
128
+ This is the path to the top of your chef repository. Multiple paths are
129
+ supported. If you do not specify this, it defaults to +cookbook_path/..+ (for
130
+ historical reasons, many knife.rb files contain +cookbook_path+.)
131
+
132
+ If you specify this or +cookbook_path+, it is not necessary to specify the other paths (+client_path+,
133
+ +data_bag_path+, etc.). They will be assumed to be under the chef_repo_path(s).
134
+
135
+ == *_path
136
+
137
+ client_path PATH|[PATH1, PATH2, ...]
138
+ cookbook_path PATH|[PATH1, PATH2, ...]
139
+ data_bag_path PATH|[PATH1, PATH2, ...]
140
+ environment_path PATH|[PATH1, PATH2, ...]
141
+ node_path PATH|[PATH1, PATH2, ...]
142
+ role_path PATH|[PATH1, PATH2, ...]
143
+ user_path PATH|[PATH1, PATH2, ...]
144
+
145
+ The local path where client json files, cookbook directories, etc. are stored.
146
+ Each supports multiple paths, in which case all files/subdirectories from each
147
+ path are merged into one virtual path (i.e. when you +knife list cookbooks+ it
148
+ will show you a list including all cookbooks from all cookbook_paths).
149
+
150
+ You generally do NOT need to specify these. If you do not specify an _path
151
+ variable, it is set to chef_repo_path/clients|cookbooks|data_bags|environments|nodes|roles|users.
152
+ Each of these supports multiple paths. If multiple paths are supported, and a
153
+ new object is downloaded (say, a new cookbook), the object is downloaded into
154
+ the *first* path in the list. Updated objects stay where they are.
155
+
156
+ == versioned_cookbooks
157
+
158
+ versioned_cookbooks true
159
+
160
+ This option, when set to +true+, will cause knife-essentials to work with
161
+ multiple versions of cookbooks. In this case, your /cookbooks directory will
162
+ have cookbook directory names of the form: +apache2-1.0.0+, +apache2-1.0.1+,
163
+ +mysql-1.1.2+, etc. A full download of /cookbooks will download all versions,
164
+ And a diff of a specific version will diff exactly that version and no other.
165
+
166
+ This is super handy, especially combined with repo_mode "everything," as it will
167
+ allow you to back up or restore a full copy of your Chef server.
168
+
169
+ == repo_mode
170
+
171
+ repo_mode "everything"
172
+
173
+ By default, knife-essentials only maps "cookbooks," "data_bags," environments," and "roles." If you specify repo_mode "everything", it will map *everything* on the server,
174
+ including users, clients and nodes.
175
+
176
+ The author is not particularly happy about the necessity for this, and will try
177
+ to get rid of it as soon as a way is found to avoid violating the Principle of
178
+ Least Surprise. The reason things are split this way is that most people don't
179
+ store users, clients and nodes in source control. +knife deps+ fares very
180
+ poorly due to the way things are; but +knife diff+ gets surprising if it shows
181
+ nodes, which aren't usually in your repo.
182
+
119
183
  == NOTE ABOUT WILDCARDS
120
184
 
121
185
  knife-essentials supports wildcards internally, and will use them to sift through objects
@@ -1,10 +1,12 @@
1
1
  require 'json'
2
2
  require 'chef_fs/data_handler/data_handler_base'
3
+ require 'chef_fs/file_system/base_fs_object'
3
4
 
4
5
  class Chef
5
6
  class Knife
6
7
  remove_const(:Raw) if const_defined?(:Raw) && Raw.name == 'Chef::Knife::Raw' # override Chef's version
7
8
  class Raw < Chef::Knife
9
+ ChefFS = ::ChefFS
8
10
  banner "knife raw REQUEST_PATH"
9
11
 
10
12
  option :method,
@@ -42,7 +44,7 @@ class Chef
42
44
  end
43
45
  chef_rest = Chef::REST.new(Chef::Config[:chef_server_url])
44
46
  begin
45
- output ChefFS::FileSystem::BaseFSObject.api_request(chef_rest, config[:method].to_sym, chef_rest.create_url(name_args[0]), {}, data)
47
+ output ::ChefFS::FileSystem::BaseFSObject.api_request(chef_rest, config[:method].to_sym, chef_rest.create_url(name_args[0]), {}, data)
46
48
  rescue Net::HTTPServerException => e
47
49
  ui.error "Server responded with error #{e.response.code} \"#{e.response.message}\""
48
50
  ui.error "Error Body: #{e.response.body}" if e.response.body && e.response.body != ''
@@ -51,7 +51,7 @@ module ChefFS
51
51
  if $!.response.code == "404"
52
52
  raise ChefFS::FileSystem::NotFoundError.new(self, $!)
53
53
  else
54
- raise ChefFS::FileSystem::OperationFailedError.new(:children, self, e)
54
+ raise ChefFS::FileSystem::OperationFailedError.new(:children, self, e), "HTTP error retrieving children: #{e}"
55
55
  end
56
56
  end
57
57
  end
@@ -27,79 +27,78 @@ module ChefFS
27
27
  def self.common_options
28
28
  option :repo_mode,
29
29
  :long => '--repo-mode MODE',
30
- :default => "default",
31
- :description => "Specifies the local repository layout. Values: default or full"
30
+ :description => "Specifies the local repository layout. Values: default or everything"
32
31
 
33
32
  option :chef_repo_path,
34
33
  :long => '--chef-repo-path PATH',
35
- :default => nil,
36
- :description => 'Overrides the location of chef repo. Default is specified by chef_repo_paths in the config'
34
+ :description => 'Overrides the location of chef repo. Default is specified by chef_repo_path in the config'
37
35
  end
38
36
 
39
- def chef_fs
40
- @chef_fs ||= ChefFS::FileSystem::ChefServerRootDir.new("remote", Chef::Config, config[:repo_mode])
41
- end
37
+ def configure_chef
38
+ super
39
+ Chef::Config[:repo_mode] = config[:repo_mode] if config[:repo_mode]
42
40
 
43
- def chef_repo_paths
44
- @chef_repo_paths ||= begin
45
- result = config_paths(:chef_repo_path)
46
- if result
47
- result
48
- else
49
- if Chef::Config[:cookbook_path]
50
- Array(Chef::Config[:cookbook_path]).flatten.map { |path| File.expand_path('..', path) }
51
- else
52
- nil
53
- end
54
- end
41
+ # --chef-repo-path overrides all other paths
42
+ path_variables = %w(client_path cookbook_path data_bag_path environment_path node_path role_path user_path)
43
+ if config[:chef_repo_path]
44
+ Chef::Config[:chef_repo_path] = config[:chef_repo_path]
45
+ path_variables.each do |variable_name|
46
+ Chef::Config[variable_name.to_sym] = nil
47
+ end
48
+ end
49
+
50
+ # Infer chef_repo_path from cookbook_path if not speciifed
51
+ if !Chef::Config[:chef_repo_path]
52
+ if Chef::Config[:cookbook_path]
53
+ Chef::Config[:chef_repo_path] = Array(Chef::Config[:cookbook_path]).flatten.map { |path| File.expand_path('..', path) }
54
+ end
55
55
  end
56
- end
57
56
 
58
- # Smooth out some inappropriate (for now) variable defaults in Chef.
59
- def config_paths(name)
60
- result = case name
61
- when :data_bag_path
62
- Chef::Config[name] == Chef::Config.platform_specific_path('/var/chef/data_bags') ? nil : Chef::Config[name]
63
- when :node_path
64
- Chef::Config[name] == '/var/chef/node' ? nil : Chef::Config[name]
65
- when :role_path
66
- Chef::Config[name] == Chef::Config.platform_specific_path('/var/chef/roles') ? nil : Chef::Config[name]
67
- else
68
- Chef::Config[name]
57
+ # Smooth out some (for now) inappropriate defaults set by Chef
58
+ if Chef::Config[:data_bag_path] == Chef::Config.platform_specific_path('/var/chef/data_bags')
59
+ Chef::Config[:data_bag_path] = nil
60
+ end
61
+ if Chef::Config[:node_path] == '/var/chef/node'
62
+ Chef::Config[:node_path] = nil
69
63
  end
70
- if result
71
- Array(result).flatten
72
- else
73
- nil
64
+ if Chef::Config[:role_path] == Chef::Config.platform_specific_path('/var/chef/roles')
65
+ Chef::Config[:role_path] = nil
74
66
  end
67
+
68
+ # Infer any *_path variables that are not specified
69
+ if Chef::Config[:chef_repo_path]
70
+ path_variables.each do |variable_name|
71
+ chef_repo_paths = Array(Chef::Config[:chef_repo_path]).flatten
72
+ variable = variable_name.to_sym
73
+ if !Chef::Config[variable]
74
+ # cookbook_path -> cookbooks
75
+ Chef::Config[variable] = chef_repo_paths.map { |path| File.join(path, "#{variable_name[0..-6]}s") }
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ def chef_fs
82
+ @chef_fs ||= ChefFS::FileSystem::ChefServerRootDir.new("remote", Chef::Config, Chef::Config[:repo_mode])
75
83
  end
76
84
 
77
85
  def object_paths
78
86
  @object_paths ||= begin
87
+ if !Chef::Config[:chef_repo_path]
88
+ Chef::Log.error("Must specify either chef_repo_path or cookbook_path in Chef config file")
89
+ exit(1)
90
+ end
91
+
79
92
  result = {}
80
- if config[:repo_mode] == 'everything'
93
+ if Chef::Config[:repo_mode] == 'everything'
81
94
  object_names = %w(clients cookbooks data_bags environments nodes roles users)
82
95
  else
83
96
  object_names = %w(cookbooks data_bags environments roles)
84
97
  end
85
98
  object_names.each do |object_name|
86
- # If --chef-repo-path is passed in the command line, then override *everything*
87
- # and assume all the subdirectory is contained in that directory.
88
- if config[:chef_repo_path]
89
- paths = [ "#{config[:chef_repo_path]}/#{object_name}" ]
90
- else
91
- variable_name = "#{object_name[0..-2]}_path" # cookbooks -> cookbook_path
92
- paths = config_paths(variable_name.to_sym)
93
- if !paths
94
- if !chef_repo_paths
95
- Chef::Log.error("Must specify either chef_repo_path or #{variable_name} in Chef config file")
96
- exit(1)
97
- end
98
- paths = chef_repo_paths.map { |path| File.join(path, object_name) }
99
- end
100
- end
101
- paths = paths.flatten.map { |path| File.expand_path(path) }
102
- result[object_name] = paths
99
+ variable_name = "#{object_name[0..-2]}_path" # cookbooks -> cookbook_path
100
+ paths = Array(Chef::Config[variable_name]).flatten
101
+ result[object_name] = paths.map { |path| File.expand_path(path) }
103
102
  end
104
103
  result
105
104
  end
@@ -143,7 +142,7 @@ module ChefFS
143
142
  end
144
143
 
145
144
  # Check chef_repo_path
146
- chef_repo_paths.each do |chef_repo_path|
145
+ Array(Chef::Config[:chef_repo_path]).flatten.each do |chef_repo_path|
147
146
  realest_chef_repo_path = ChefFS::PathUtils.realest_path(chef_repo_path)
148
147
  if absolute_path == realest_chef_repo_path
149
148
  return '/'
@@ -1,3 +1,3 @@
1
1
  module ChefFS
2
- VERSION = "0.9.3"
2
+ VERSION = "0.9.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-essentials
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-11 00:00:00.000000000 Z
12
+ date: 2013-03-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef-zero