knife-essentials 1.0.0 → 1.1
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/lib/chef/knife/raw_essentials.rb +3 -0
- data/lib/chef/knife/serve_essentials.rb +397 -0
- data/lib/chef_fs/command_line.rb +2 -17
- data/lib/chef_fs/file_system.rb +25 -25
- data/lib/chef_fs/file_system/acl_entry.rb +2 -0
- data/lib/chef_fs/file_system/cookbook_dir.rb +16 -8
- data/lib/chef_fs/file_system/cookbook_file.rb +2 -0
- data/lib/chef_fs/file_system/cookbooks_dir.rb +3 -1
- data/lib/chef_fs/file_system/data_bag_dir.rb +7 -3
- data/lib/chef_fs/file_system/data_bags_dir.rb +11 -7
- data/lib/chef_fs/file_system/memory_dir.rb +50 -0
- data/lib/chef_fs/file_system/memory_file.rb +15 -0
- data/lib/chef_fs/file_system/memory_root.rb +19 -0
- data/lib/chef_fs/file_system/nodes_dir.rb +2 -0
- data/lib/chef_fs/file_system/rest_list_dir.rb +4 -0
- data/lib/chef_fs/file_system/rest_list_entry.rb +11 -7
- data/lib/chef_fs/knife.rb +10 -2
- data/lib/chef_fs/version.rb +1 -1
- data/spec/support/file_system_support.rb +7 -47
- metadata +6 -2
@@ -45,6 +45,9 @@ class Chef
|
|
45
45
|
chef_rest = Chef::REST.new(Chef::Config[:chef_server_url])
|
46
46
|
begin
|
47
47
|
output ChefFS::RawRequest.api_request(chef_rest, config[:method].to_sym, chef_rest.create_url(name_args[0]), {}, data)
|
48
|
+
rescue Timeout::Error => e
|
49
|
+
ui.error "Server timeout"
|
50
|
+
exit 1
|
48
51
|
rescue Net::HTTPServerException => e
|
49
52
|
ui.error "Server responded with error #{e.response.code} \"#{e.response.message}\""
|
50
53
|
ui.error "Error Body: #{e.response.body}" if e.response.body && e.response.body != ''
|
@@ -0,0 +1,397 @@
|
|
1
|
+
require 'chef_fs/knife'
|
2
|
+
require 'chef_zero/server'
|
3
|
+
require 'chef_zero/data_store/memory_store'
|
4
|
+
|
5
|
+
# For ChefFSStore
|
6
|
+
require 'chef_fs/file_pattern'
|
7
|
+
require 'chef_fs/file_system'
|
8
|
+
require 'chef_fs/file_system/not_found_error'
|
9
|
+
require 'chef_fs/file_system/memory_root'
|
10
|
+
require 'chef_zero/data_store/data_already_exists_error'
|
11
|
+
require 'chef_zero/data_store/data_not_found_error'
|
12
|
+
|
13
|
+
class Chef
|
14
|
+
class Knife
|
15
|
+
remove_const(:Serve) if const_defined?(:Serve) && Serve.name == 'Chef::Knife::Serve' # override Chef's version
|
16
|
+
class Serve < ::ChefFS::Knife
|
17
|
+
ChefFS = ::ChefFS
|
18
|
+
banner "knife show [PATTERN1 ... PATTERNn]"
|
19
|
+
|
20
|
+
common_options
|
21
|
+
|
22
|
+
option :remote,
|
23
|
+
:long => '--remote',
|
24
|
+
:boolean => true,
|
25
|
+
:description => "Proxy the remote server instead of the local filesystem"
|
26
|
+
|
27
|
+
option :host,
|
28
|
+
:short => '-H',
|
29
|
+
:long => '--host=HOST',
|
30
|
+
:description => "Host to bind to (default: 127.0.0.1)"
|
31
|
+
|
32
|
+
option :port,
|
33
|
+
:short => '-p',
|
34
|
+
:long => '--port=PORT',
|
35
|
+
:description => "Port to listen on (default: 4000)"
|
36
|
+
|
37
|
+
option :generate_real_keys,
|
38
|
+
:long => '--[no-]generate-keys',
|
39
|
+
:boolean => true,
|
40
|
+
:description => "Whether to generate actual keys or fake it (faster). Default: false."
|
41
|
+
|
42
|
+
def run
|
43
|
+
server_options = {}
|
44
|
+
server_options[:data_store] = ChefFSDataStore.new(proc { config[:remote] ? create_chef_fs : create_local_fs })
|
45
|
+
server_options[:log_level] = Chef::Log.level
|
46
|
+
server_options[:host] = config[:host] if config[:host]
|
47
|
+
server_options[:port] = config[:port] ? config[:port].to_i : 4000
|
48
|
+
server_options[:generate_real_keys] = config[:generate_real_keys] if config[:generate_real_keys]
|
49
|
+
|
50
|
+
ChefZero::Server.new(server_options).start(:publish => true)
|
51
|
+
end
|
52
|
+
|
53
|
+
class ChefFSDataStore
|
54
|
+
def initialize(chef_fs)
|
55
|
+
@chef_fs = chef_fs
|
56
|
+
@memory_store = ChefZero::DataStore::MemoryStore.new
|
57
|
+
end
|
58
|
+
|
59
|
+
def chef_fs
|
60
|
+
@chef_fs.call
|
61
|
+
end
|
62
|
+
|
63
|
+
MEMORY_PATHS = %w(sandboxes file_store)
|
64
|
+
|
65
|
+
def create_dir(path, name, *options)
|
66
|
+
if use_memory_store?(path)
|
67
|
+
@memory_store.create_dir(path, name, *options)
|
68
|
+
else
|
69
|
+
with_dir(path) do |parent|
|
70
|
+
parent.create_child(chef_fs_filename(path + [name]), nil)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def create(path, name, data, *options)
|
76
|
+
if use_memory_store?(path)
|
77
|
+
@memory_store.create(path, name, data, *options)
|
78
|
+
|
79
|
+
elsif path[0] == 'cookbooks' && path.length == 2
|
80
|
+
# Do nothing. The entry gets created when the cookbook is created.
|
81
|
+
|
82
|
+
else
|
83
|
+
if !data.is_a?(String)
|
84
|
+
raise "set only works with strings"
|
85
|
+
end
|
86
|
+
|
87
|
+
with_dir(path) do |parent|
|
88
|
+
parent.create_child(chef_fs_filename(path + [name]), data)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def get(path, request=nil)
|
94
|
+
if use_memory_store?(path)
|
95
|
+
@memory_store.get(path)
|
96
|
+
|
97
|
+
elsif path[0] == 'file_store' && path[1] == 'repo'
|
98
|
+
entry = ChefFS::FileSystem.resolve_path(chef_fs, path[2..-1].join('/'))
|
99
|
+
begin
|
100
|
+
entry.read
|
101
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
102
|
+
raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e)
|
103
|
+
end
|
104
|
+
|
105
|
+
else
|
106
|
+
with_entry(path) do |entry|
|
107
|
+
if path[0] == 'cookbooks' && path.length == 3
|
108
|
+
# get /cookbooks/NAME/version
|
109
|
+
result = entry.chef_object.to_hash
|
110
|
+
result.each_pair do |key, value|
|
111
|
+
if value.is_a?(Array)
|
112
|
+
value.each do |file|
|
113
|
+
if file.is_a?(Hash) && file.has_key?('checksum')
|
114
|
+
relative = ['file_store', 'repo', 'cookbooks']
|
115
|
+
if Chef::Config.versioned_cookbooks
|
116
|
+
relative << "#{path[1]}-#{path[2]}"
|
117
|
+
else
|
118
|
+
relative << path[1]
|
119
|
+
end
|
120
|
+
relative = relative + file[:path].split('/')
|
121
|
+
file['url'] = ChefZero::RestBase::build_uri(request.base_uri, relative)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
JSON.pretty_generate(result)
|
127
|
+
|
128
|
+
else
|
129
|
+
entry.read
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def set(path, data, *options)
|
136
|
+
if use_memory_store?(path)
|
137
|
+
@memory_store.set(path, data, *options)
|
138
|
+
else
|
139
|
+
if !data.is_a?(String)
|
140
|
+
raise "set only works with strings: #{path} = #{data.inspect}"
|
141
|
+
end
|
142
|
+
|
143
|
+
# Write out the files!
|
144
|
+
if path[0] == 'cookbooks' && path.length == 3
|
145
|
+
write_cookbook(path, data, *options)
|
146
|
+
else
|
147
|
+
with_dir(path[0..-2]) do |parent|
|
148
|
+
parent.create_child(chef_fs_filename(path), data)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def delete(path)
|
155
|
+
if use_memory_store?(path)
|
156
|
+
@memory_store.delete(path)
|
157
|
+
else
|
158
|
+
with_entry(path) do |entry|
|
159
|
+
if path[0] == 'cookbooks' && path.length >= 3
|
160
|
+
entry.delete(true)
|
161
|
+
else
|
162
|
+
entry.delete
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def delete_dir(path, *options)
|
169
|
+
if use_memory_store?(path)
|
170
|
+
@memory_store.delete_dir(path, *options)
|
171
|
+
else
|
172
|
+
with_entry(path) do |entry|
|
173
|
+
entry.delete(options.include?(:recursive))
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def list(path)
|
179
|
+
if use_memory_store?(path)
|
180
|
+
@memory_store.list(path)
|
181
|
+
|
182
|
+
elsif path[0] == 'cookbooks' && path.length == 1
|
183
|
+
with_entry(path) do |entry|
|
184
|
+
begin
|
185
|
+
if Chef::Config.versioned_cookbooks
|
186
|
+
# /cookbooks/name-version -> /cookbooks/name
|
187
|
+
entry.children.map { |child| split_name_version(child.name)[0] }.uniq
|
188
|
+
else
|
189
|
+
entry.children.map { |child| child.name }
|
190
|
+
end
|
191
|
+
rescue ChefFS::FileSystem::NotFoundError
|
192
|
+
# If the cookbooks dir doesn't exist, we have no cookbooks (not 404)
|
193
|
+
[]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
elsif path[0] == 'cookbooks' && path.length == 2
|
198
|
+
if Chef::Config.versioned_cookbooks
|
199
|
+
# list /cookbooks/name = filter /cookbooks/name-version down to name
|
200
|
+
entry.children.map { |child| split_name_version(child.name) }.
|
201
|
+
select { |name, version| name == path[1] }.
|
202
|
+
map { |name, version| version }.to_a
|
203
|
+
else
|
204
|
+
# list /cookbooks/name = <single version>
|
205
|
+
version = get_single_cookbook_version(path)
|
206
|
+
[version]
|
207
|
+
end
|
208
|
+
|
209
|
+
else
|
210
|
+
with_entry(path) do |entry|
|
211
|
+
begin
|
212
|
+
entry.children.map { |c| zero_filename(c) }.sort
|
213
|
+
rescue ChefFS::FileSystem::NotFoundError
|
214
|
+
# /cookbooks, /data, etc. never return 404
|
215
|
+
if path_always_exists?(path)
|
216
|
+
[]
|
217
|
+
else
|
218
|
+
raise
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def exists?(path)
|
226
|
+
if use_memory_store?(path)
|
227
|
+
@memory_store.exists?(path)
|
228
|
+
else
|
229
|
+
path_always_exists?(path) || ChefFS::FileSystem.resolve_path(chef_fs, to_chef_fs_path(path)).exists?
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def exists_dir?(path)
|
234
|
+
if use_memory_store?(path)
|
235
|
+
@memory_store.exists_dir?(path)
|
236
|
+
elsif path[0] == 'cookbooks' && path.length == 2
|
237
|
+
list([ path[0] ]).include?(path[1])
|
238
|
+
else
|
239
|
+
ChefFS::FileSystem.resolve_path(chef_fs, to_chef_fs_path(path)).exists?
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
|
245
|
+
def use_memory_store?(path)
|
246
|
+
return path[0] == 'sandboxes' || path[0] == 'file_store' && path[1] == 'checksums' || path == [ 'environments', '_default' ]
|
247
|
+
end
|
248
|
+
|
249
|
+
def write_cookbook(path, data, *options)
|
250
|
+
# Create a little ChefFS memory filesystem with the data
|
251
|
+
if Chef::Config.versioned_cookbooks
|
252
|
+
cookbook_path = "cookbooks/#{path[1]}-#{path[2]}"
|
253
|
+
else
|
254
|
+
cookbook_path = "cookbooks/#{path[1]}"
|
255
|
+
end
|
256
|
+
puts "Write cookbook #{cookbook_path}"
|
257
|
+
cookbook_fs = ChefFS::FileSystem::MemoryRoot.new('uploading')
|
258
|
+
cookbook = JSON.parse(data, :create_additions => false)
|
259
|
+
cookbook.each_pair do |key, value|
|
260
|
+
if value.is_a?(Array)
|
261
|
+
value.each do |file|
|
262
|
+
if file.is_a?(Hash) && file.has_key?('checksum')
|
263
|
+
file_data = @memory_store.get(['file_store', 'checksums', file['checksum']])
|
264
|
+
cookbook_fs.add_file("#{cookbook_path}/#{file['path']}", file_data)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# Use the copy/diff algorithm to copy it down so we don't destroy
|
271
|
+
# chefignored data. This is terribly un-thread-safe.
|
272
|
+
ChefFS::FileSystem.copy_to(ChefFS::FilePattern.new("/#{cookbook_path}"), cookbook_fs, chef_fs, nil, {:purge => true})
|
273
|
+
end
|
274
|
+
|
275
|
+
def split_name_version(entry_name)
|
276
|
+
name_version = entry_name.split('-')
|
277
|
+
name = name_version[0..-2].join('-')
|
278
|
+
version = name_version[-1]
|
279
|
+
[name,version]
|
280
|
+
end
|
281
|
+
|
282
|
+
def to_chef_fs_path(path)
|
283
|
+
_to_chef_fs_path(path).join('/')
|
284
|
+
end
|
285
|
+
|
286
|
+
def chef_fs_filename(path)
|
287
|
+
_to_chef_fs_path(path)[-1]
|
288
|
+
end
|
289
|
+
|
290
|
+
def _to_chef_fs_path(path)
|
291
|
+
if path[0] == 'data'
|
292
|
+
path = path.dup
|
293
|
+
path[0] = 'data_bags'
|
294
|
+
if path.length >= 3
|
295
|
+
path[2] = "#{path[2]}.json"
|
296
|
+
end
|
297
|
+
elsif path[0] == 'cookbooks'
|
298
|
+
if path.length == 2
|
299
|
+
raise ChefZero::DataStore::DataNotFoundError.new(path)
|
300
|
+
elsif Chef::Config.versioned_cookbooks
|
301
|
+
if path.length >= 3
|
302
|
+
# cookbooks/name/version -> cookbooks/name-version
|
303
|
+
path = [ path[0], "#{path[1]}-#{path[2]}" ] + path[3..-1]
|
304
|
+
end
|
305
|
+
else
|
306
|
+
if path.length >= 3
|
307
|
+
# cookbooks/name/version/... -> /cookbooks/name/... iff metadata says so
|
308
|
+
version = get_single_cookbook_version(path)
|
309
|
+
if path[2] == version
|
310
|
+
path = path[0..1] + path[3..-1]
|
311
|
+
else
|
312
|
+
raise ChefZero::DataStore::DataNotFoundError.new(path)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
elsif path.length == 2
|
317
|
+
path = path.dup
|
318
|
+
path[1] = "#{path[1]}.json"
|
319
|
+
end
|
320
|
+
path
|
321
|
+
end
|
322
|
+
|
323
|
+
def to_zero_path(entry)
|
324
|
+
path = entry.path.split('/')[1..-1]
|
325
|
+
if path[0] == 'data_bags'
|
326
|
+
path = path.dup
|
327
|
+
path[0] = 'data'
|
328
|
+
if path.length >= 3
|
329
|
+
path[2] = path[2][0..-6]
|
330
|
+
end
|
331
|
+
|
332
|
+
elsif path[0] == 'cookbooks'
|
333
|
+
if Chef::Config.versioned_cookbooks
|
334
|
+
# cookbooks/name-version/... -> cookbooks/name/version/...
|
335
|
+
if path.length >= 2
|
336
|
+
name, version = split_name_version(path[1])
|
337
|
+
path = [ path[0], name, version ] + path[2..-1]
|
338
|
+
end
|
339
|
+
else
|
340
|
+
if path.length >= 2
|
341
|
+
# cookbooks/name/... -> cookbooks/name/version/...
|
342
|
+
version = get_single_cookbook_version(path)
|
343
|
+
path = path[0..1] + [version] + path[2..-1]
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
elsif path.length == 2 && path[0] != 'cookbooks'
|
348
|
+
path = path.dup
|
349
|
+
path[1] = path[1][0..-6]
|
350
|
+
end
|
351
|
+
path
|
352
|
+
end
|
353
|
+
|
354
|
+
def zero_filename(entry)
|
355
|
+
to_zero_path(entry)[-1]
|
356
|
+
end
|
357
|
+
|
358
|
+
def path_always_exists?(path)
|
359
|
+
return path.length == 1 && %w(clients cookbooks data environments nodes roles users).include?(path[0])
|
360
|
+
end
|
361
|
+
|
362
|
+
def with_entry(path)
|
363
|
+
begin
|
364
|
+
yield ChefFS::FileSystem.resolve_path(chef_fs, to_chef_fs_path(path))
|
365
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
366
|
+
raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def with_dir(path)
|
371
|
+
begin
|
372
|
+
yield get_dir(_to_chef_fs_path(path), true)
|
373
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
374
|
+
raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
def get_dir(path, create=false)
|
379
|
+
result = ChefFS::FileSystem.resolve_path(chef_fs, path.join('/'))
|
380
|
+
if result.exists?
|
381
|
+
result
|
382
|
+
elsif create
|
383
|
+
get_dir(path[0..-2], create).create_child(result.name, nil)
|
384
|
+
else
|
385
|
+
raise ChefZero::DataStore::DataNotFoundError.new(path)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
def get_single_cookbook_version(path)
|
390
|
+
dir = ChefFS::FileSystem.resolve_path(chef_fs, path[0..1].join('/'))
|
391
|
+
metadata = ChefZero::CookbookData.metadata_from(dir, path[1], nil, [])
|
392
|
+
metadata[:version] || '0.0.0'
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
data/lib/chef_fs/command_line.rb
CHANGED
@@ -90,6 +90,7 @@ module ChefFS
|
|
90
90
|
else
|
91
91
|
yield "Only in #{format_path.call(new_entry.parent)}: #{new_entry.name}\n"
|
92
92
|
end
|
93
|
+
|
93
94
|
when :modified
|
94
95
|
next if diff_filter && diff_filter !~ /M/
|
95
96
|
if output_mode == :name_only
|
@@ -101,6 +102,7 @@ module ChefFS
|
|
101
102
|
result << diff_text(old_path, new_path, old_value, new_value)
|
102
103
|
yield result
|
103
104
|
end
|
105
|
+
|
104
106
|
when :both_nonexistent
|
105
107
|
when :added_cannot_upload
|
106
108
|
when :deleted_cannot_download
|
@@ -232,23 +234,6 @@ module ChefFS
|
|
232
234
|
return [ [ :error, old_entry, new_entry, nil, nil, e ] ]
|
233
235
|
end
|
234
236
|
|
235
|
-
class Differ
|
236
|
-
def initialize(old_entry, new_entry, recurse_depth, get_content)
|
237
|
-
@old_entry = old_entry
|
238
|
-
@new_entry = new_entry
|
239
|
-
@recurse_depth = recurse_depth
|
240
|
-
@get_content = get_content
|
241
|
-
end
|
242
|
-
|
243
|
-
attr_reader :old_entry
|
244
|
-
attr_reader :new_entry
|
245
|
-
attr_reader :recurse_depth
|
246
|
-
attr_reader :get_content
|
247
|
-
|
248
|
-
def each
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
237
|
private
|
253
238
|
|
254
239
|
def self.sort_keys(json_object)
|
data/lib/chef_fs/file_system.rb
CHANGED
@@ -135,7 +135,7 @@ module ChefFS
|
|
135
135
|
# puts message
|
136
136
|
# end
|
137
137
|
#
|
138
|
-
def self.copy_to(pattern, src_root, dest_root, recurse_depth, options, ui, format_path)
|
138
|
+
def self.copy_to(pattern, src_root, dest_root, recurse_depth, options, ui = nil, format_path = nil)
|
139
139
|
found_result = false
|
140
140
|
error = false
|
141
141
|
parallel_do(list_pairs(pattern, src_root, dest_root)) do |src, dest|
|
@@ -145,7 +145,7 @@ module ChefFS
|
|
145
145
|
error ||= child_error
|
146
146
|
end
|
147
147
|
if !found_result && pattern.exact_path
|
148
|
-
ui.error "#{pattern}: No such file or directory on remote or local"
|
148
|
+
ui.error "#{pattern}: No such file or directory on remote or local" if ui
|
149
149
|
error = true
|
150
150
|
end
|
151
151
|
error
|
@@ -275,20 +275,20 @@ module ChefFS
|
|
275
275
|
|
276
276
|
error = false
|
277
277
|
begin
|
278
|
-
dest_path = format_path.call(dest_entry)
|
279
|
-
src_path = format_path.call(src_entry)
|
278
|
+
dest_path = format_path.call(dest_entry) if ui
|
279
|
+
src_path = format_path.call(src_entry) if ui
|
280
280
|
if !src_entry.exists?
|
281
281
|
if options[:purge]
|
282
282
|
# If we would not have uploaded it, we will not purge it.
|
283
283
|
if src_entry.parent.can_have_child?(dest_entry.name, dest_entry.dir?)
|
284
284
|
if options[:dry_run]
|
285
|
-
ui.output "Would delete #{dest_path}"
|
285
|
+
ui.output "Would delete #{dest_path}" if ui
|
286
286
|
else
|
287
287
|
dest_entry.delete(true)
|
288
|
-
ui.output "Deleted extra entry #{dest_path} (purge is on)"
|
288
|
+
ui.output "Deleted extra entry #{dest_path} (purge is on)" if ui
|
289
289
|
end
|
290
290
|
else
|
291
|
-
Chef::Log.info("Not deleting extra entry #{dest_path} (purge is off)")
|
291
|
+
Chef::Log.info("Not deleting extra entry #{dest_path} (purge is off)") if ui
|
292
292
|
end
|
293
293
|
end
|
294
294
|
|
@@ -297,21 +297,21 @@ module ChefFS
|
|
297
297
|
# If the entry can do a copy directly from filesystem, do that.
|
298
298
|
if new_dest_parent.respond_to?(:create_child_from)
|
299
299
|
if options[:dry_run]
|
300
|
-
ui.output "Would create #{dest_path}"
|
300
|
+
ui.output "Would create #{dest_path}" if ui
|
301
301
|
else
|
302
302
|
new_dest_parent.create_child_from(src_entry)
|
303
|
-
ui.output "Created #{dest_path}"
|
303
|
+
ui.output "Created #{dest_path}" if ui
|
304
304
|
end
|
305
305
|
return
|
306
306
|
end
|
307
307
|
|
308
308
|
if src_entry.dir?
|
309
309
|
if options[:dry_run]
|
310
|
-
ui.output "Would create #{dest_path}"
|
310
|
+
ui.output "Would create #{dest_path}" if ui
|
311
311
|
new_dest_dir = new_dest_parent.child(src_entry.name)
|
312
312
|
else
|
313
313
|
new_dest_dir = new_dest_parent.create_child(src_entry.name, nil)
|
314
|
-
ui.output "Created #{dest_path}"
|
314
|
+
ui.output "Created #{dest_path}" if ui
|
315
315
|
end
|
316
316
|
# Directory creation is recursive.
|
317
317
|
if recurse_depth != 0
|
@@ -323,10 +323,10 @@ module ChefFS
|
|
323
323
|
end
|
324
324
|
else
|
325
325
|
if options[:dry_run]
|
326
|
-
ui.output "Would create #{dest_path}"
|
326
|
+
ui.output "Would create #{dest_path}" if ui
|
327
327
|
else
|
328
328
|
new_dest_parent.create_child(src_entry.name, src_entry.read)
|
329
|
-
ui.output "Created #{dest_path}"
|
329
|
+
ui.output "Created #{dest_path}" if ui
|
330
330
|
end
|
331
331
|
end
|
332
332
|
end
|
@@ -338,10 +338,10 @@ module ChefFS
|
|
338
338
|
if dest_entry.respond_to?(:copy_from)
|
339
339
|
if options[:force] || compare(src_entry, dest_entry)[0] == false
|
340
340
|
if options[:dry_run]
|
341
|
-
ui.output "Would update #{dest_path}"
|
341
|
+
ui.output "Would update #{dest_path}" if ui
|
342
342
|
else
|
343
343
|
dest_entry.copy_from(src_entry)
|
344
|
-
ui.output "Updated #{dest_path}"
|
344
|
+
ui.output "Updated #{dest_path}" if ui
|
345
345
|
end
|
346
346
|
end
|
347
347
|
return
|
@@ -359,12 +359,12 @@ module ChefFS
|
|
359
359
|
end
|
360
360
|
else
|
361
361
|
# If they are different types.
|
362
|
-
ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n")
|
362
|
+
ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n") if ui
|
363
363
|
return
|
364
364
|
end
|
365
365
|
else
|
366
366
|
if dest_entry.dir?
|
367
|
-
ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n")
|
367
|
+
ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n") if ui
|
368
368
|
return
|
369
369
|
else
|
370
370
|
|
@@ -380,23 +380,23 @@ module ChefFS
|
|
380
380
|
end
|
381
381
|
if should_copy
|
382
382
|
if options[:dry_run]
|
383
|
-
ui.output "Would update #{dest_path}"
|
383
|
+
ui.output "Would update #{dest_path}" if ui
|
384
384
|
else
|
385
385
|
src_value = src_entry.read if src_value.nil?
|
386
386
|
dest_entry.write(src_value)
|
387
|
-
ui.output "Updated #{dest_path}"
|
387
|
+
ui.output "Updated #{dest_path}" if ui
|
388
388
|
end
|
389
389
|
end
|
390
390
|
end
|
391
391
|
end
|
392
392
|
end
|
393
393
|
rescue DefaultEnvironmentCannotBeModifiedError => e
|
394
|
-
ui.warn "#{format_path.call(e.entry)} #{e.reason}."
|
394
|
+
ui.warn "#{format_path.call(e.entry)} #{e.reason}." if ui
|
395
395
|
rescue OperationFailedError => e
|
396
|
-
ui.error "#{format_path.call(e.entry)} failed to #{e.operation}: #{e.message}"
|
396
|
+
ui.error "#{format_path.call(e.entry)} failed to #{e.operation}: #{e.message}" if ui
|
397
397
|
error = true
|
398
398
|
rescue OperationNotAllowedError => e
|
399
|
-
ui.error "#{format_path.call(e.entry)} #{e.reason}."
|
399
|
+
ui.error "#{format_path.call(e.entry)} #{e.reason}." if ui
|
400
400
|
error = true
|
401
401
|
end
|
402
402
|
error
|
@@ -405,13 +405,13 @@ module ChefFS
|
|
405
405
|
def self.get_or_create_parent(entry, options, ui, format_path)
|
406
406
|
parent = entry.parent
|
407
407
|
if parent && !parent.exists?
|
408
|
-
parent_path = format_path.call(parent)
|
408
|
+
parent_path = format_path.call(parent) if ui
|
409
409
|
parent_parent = get_or_create_parent(entry.parent, options, ui, format_path)
|
410
410
|
if options[:dry_run]
|
411
|
-
ui.output "Would create #{parent_path}"
|
411
|
+
ui.output "Would create #{parent_path}" if ui
|
412
412
|
else
|
413
413
|
parent = parent_parent.create_child(parent.name, nil)
|
414
|
-
ui.output "Created #{parent_path}"
|
414
|
+
ui.output "Created #{parent_path}" if ui
|
415
415
|
end
|
416
416
|
end
|
417
417
|
return parent
|
@@ -40,6 +40,8 @@ module ChefFS
|
|
40
40
|
PERMISSIONS.each do |permission|
|
41
41
|
begin
|
42
42
|
rest.put_rest("#{api_path}/#{permission}", { permission => acls[permission] })
|
43
|
+
rescue Timeout::Error => e
|
44
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Timeout writing: #{e}"
|
43
45
|
rescue Net::HTTPServerException => e
|
44
46
|
if e.response.code == "404"
|
45
47
|
raise ChefFS::FileSystem::NotFoundError.new(self, e)
|
@@ -125,9 +125,13 @@ module ChefFS
|
|
125
125
|
if recurse
|
126
126
|
begin
|
127
127
|
rest.delete_rest(api_path)
|
128
|
+
rescue Timeout::Error => e
|
129
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "Timeout deleting: #{e}"
|
128
130
|
rescue Net::HTTPServerException
|
129
131
|
if $!.response.code == "404"
|
130
132
|
raise ChefFS::FileSystem::NotFoundError.new(self, $!)
|
133
|
+
else
|
134
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "HTTP error deleting: #{e}"
|
131
135
|
end
|
132
136
|
end
|
133
137
|
else
|
@@ -189,22 +193,26 @@ module ChefFS
|
|
189
193
|
ensure
|
190
194
|
Chef::Config[:http_retry_count] = old_retry_count
|
191
195
|
end
|
192
|
-
|
193
|
-
|
194
|
-
|
196
|
+
|
197
|
+
rescue Timeout::Error => e
|
198
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "Timeout reading: #{e}"
|
199
|
+
|
200
|
+
rescue Net::HTTPServerException => e
|
201
|
+
if e.response.code == "404"
|
202
|
+
@could_not_get_chef_object = e
|
195
203
|
raise ChefFS::FileSystem::NotFoundError.new(self, @could_not_get_chef_object)
|
196
204
|
else
|
197
|
-
raise
|
205
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "HTTP error reading: #{e}"
|
198
206
|
end
|
199
207
|
|
200
208
|
# Chef bug http://tickets.opscode.com/browse/CHEF-3066 ... instead of 404 we get 500 right now.
|
201
209
|
# Remove this when that bug is fixed.
|
202
|
-
rescue Net::HTTPFatalError
|
203
|
-
if
|
204
|
-
@could_not_get_chef_object =
|
210
|
+
rescue Net::HTTPFatalError => e
|
211
|
+
if e.response.code == "500"
|
212
|
+
@could_not_get_chef_object = e
|
205
213
|
raise ChefFS::FileSystem::NotFoundError.new(self, @could_not_get_chef_object)
|
206
214
|
else
|
207
|
-
raise
|
215
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "HTTP error reading: #{e}"
|
208
216
|
end
|
209
217
|
end
|
210
218
|
end
|
@@ -38,6 +38,8 @@ module ChefFS
|
|
38
38
|
rest.sign_on_redirect = false
|
39
39
|
begin
|
40
40
|
tmpfile = rest.get_rest(file[:url], true)
|
41
|
+
rescue Timeout::Error => e
|
42
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "Timeout reading #{file[:url]}: #{e}"
|
41
43
|
rescue Net::HTTPServerException => e
|
42
44
|
raise ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "#{e.message} retrieving #{file[:url]}"
|
43
45
|
ensure
|
@@ -64,6 +64,8 @@ module ChefFS
|
|
64
64
|
|
65
65
|
def upload_cookbook_from(other)
|
66
66
|
Chef::Config[:versioned_cookbooks] ? upload_versioned_cookbook(other) : upload_unversioned_cookbook(other)
|
67
|
+
rescue Timeout::Error => e
|
68
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Timeout writing: #{e}"
|
67
69
|
rescue Net::HTTPServerException => e
|
68
70
|
case e.response.code
|
69
71
|
when "409"
|
@@ -71,7 +73,7 @@ module ChefFS
|
|
71
73
|
Chef::Log.debug(e)
|
72
74
|
raise Exceptions::CookbookFrozen
|
73
75
|
else
|
74
|
-
raise
|
76
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "HTTP error writing: #{e}"
|
75
77
|
end
|
76
78
|
end
|
77
79
|
|
@@ -52,9 +52,13 @@ module ChefFS
|
|
52
52
|
end
|
53
53
|
begin
|
54
54
|
rest.delete_rest(api_path)
|
55
|
-
rescue
|
56
|
-
|
57
|
-
|
55
|
+
rescue Timeout::Error => e
|
56
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "Timeout deleting: #{e}"
|
57
|
+
rescue Net::HTTPServerException => e
|
58
|
+
if e.response.code == "404"
|
59
|
+
raise ChefFS::FileSystem::NotFoundError.new(self, e)
|
60
|
+
else
|
61
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "HTTP error deleting: #{e}"
|
58
62
|
end
|
59
63
|
end
|
60
64
|
end
|
@@ -36,11 +36,13 @@ module ChefFS
|
|
36
36
|
@children ||= ChefFS::RawRequest.raw_json(rest, api_path).keys.sort.map do |entry|
|
37
37
|
DataBagDir.new(entry, self, true)
|
38
38
|
end
|
39
|
-
rescue
|
40
|
-
|
41
|
-
|
39
|
+
rescue Timeout::Error => e
|
40
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:children, self, e), "Timeout getting children: #{e}"
|
41
|
+
rescue Net::HTTPServerException => e
|
42
|
+
if e.response.code == "404"
|
43
|
+
raise ChefFS::FileSystem::NotFoundError.new(self, e)
|
42
44
|
else
|
43
|
-
raise
|
45
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:children, self, e), "HTTP error getting children: #{e}"
|
44
46
|
end
|
45
47
|
end
|
46
48
|
end
|
@@ -52,9 +54,11 @@ module ChefFS
|
|
52
54
|
def create_child(name, file_contents)
|
53
55
|
begin
|
54
56
|
rest.post_rest(api_path, { 'name' => name })
|
55
|
-
rescue
|
56
|
-
|
57
|
-
|
57
|
+
rescue Timeout::Error => e
|
58
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "Timeout creating child '#{name}': #{e}"
|
59
|
+
rescue Net::HTTPServerException => e
|
60
|
+
if e.response.code != "409"
|
61
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "HTTP error creating child '#{name}': #{e}"
|
58
62
|
end
|
59
63
|
end
|
60
64
|
DataBagDir.new(name, self, true)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'chef_fs/file_system/base_fs_dir'
|
2
|
+
require 'chef_fs/file_system/nonexistent_fs_object'
|
3
|
+
require 'chef_fs/file_system/memory_file'
|
4
|
+
|
5
|
+
module ChefFS
|
6
|
+
module FileSystem
|
7
|
+
class MemoryDir < ChefFS::FileSystem::BaseFSDir
|
8
|
+
def initialize(name, parent)
|
9
|
+
super(name, parent)
|
10
|
+
@children = []
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :children
|
14
|
+
|
15
|
+
def child(name)
|
16
|
+
@children.select { |child| child.name == name }.first || ChefFS::FileSystem::NonexistentFSObject.new(name, self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_child(child)
|
20
|
+
@children.push(child)
|
21
|
+
end
|
22
|
+
|
23
|
+
def can_have_child?(name, is_dir)
|
24
|
+
root.cannot_be_in_regex ? (name !~ root.cannot_be_in_regex) : true
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_file(path, value)
|
28
|
+
path_parts = path.split('/')
|
29
|
+
dir = add_dir(path_parts[0..-2].join('/'))
|
30
|
+
file = MemoryFile.new(path_parts[-1], dir, value)
|
31
|
+
dir.add_child(file)
|
32
|
+
file
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_dir(path)
|
36
|
+
path_parts = path.split('/')
|
37
|
+
dir = self
|
38
|
+
path_parts.each do |path_part|
|
39
|
+
subdir = dir.child(path_part)
|
40
|
+
if !subdir.exists?
|
41
|
+
subdir = MemoryDir.new(path_part, dir)
|
42
|
+
dir.add_child(subdir)
|
43
|
+
end
|
44
|
+
dir = subdir
|
45
|
+
end
|
46
|
+
dir
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'chef_fs/file_system/base_fs_object'
|
2
|
+
|
3
|
+
module ChefFS
|
4
|
+
module FileSystem
|
5
|
+
class MemoryFile < ChefFS::FileSystem::BaseFSObject
|
6
|
+
def initialize(name, parent, value)
|
7
|
+
super(name, parent)
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
def read
|
11
|
+
return @value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'chef_fs/file_system/memory_dir'
|
2
|
+
|
3
|
+
module ChefFS
|
4
|
+
module FileSystem
|
5
|
+
class MemoryRoot < MemoryDir
|
6
|
+
def initialize(pretty_name, cannot_be_in_regex = nil)
|
7
|
+
super('', nil)
|
8
|
+
@pretty_name = pretty_name
|
9
|
+
@cannot_be_in_regex = cannot_be_in_regex
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :cannot_be_in_regex
|
13
|
+
|
14
|
+
def path_for_printing
|
15
|
+
@pretty_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -34,6 +34,8 @@ module ChefFS
|
|
34
34
|
@children ||= ChefFS::RawRequest.raw_json(rest, env_api_path).keys.sort.map do |key|
|
35
35
|
_make_child_entry("#{key}.json", true)
|
36
36
|
end
|
37
|
+
rescue Timeout::Error => e
|
38
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:children, self, e), "Timeout retrieving children: #{e}"
|
37
39
|
rescue Net::HTTPServerException => e
|
38
40
|
if $!.response.code == "404"
|
39
41
|
raise ChefFS::FileSystem::NotFoundError.new(self, $!)
|
@@ -47,6 +47,8 @@ module ChefFS
|
|
47
47
|
@children ||= ChefFS::RawRequest.raw_json(rest, api_path).keys.sort.map do |key|
|
48
48
|
_make_child_entry("#{key}.json", true)
|
49
49
|
end
|
50
|
+
rescue Timeout::Error => e
|
51
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:children, self, e), "Timeout retrieving children: #{e}"
|
50
52
|
rescue Net::HTTPServerException => e
|
51
53
|
if $!.response.code == "404"
|
52
54
|
raise ChefFS::FileSystem::NotFoundError.new(self, $!)
|
@@ -74,6 +76,8 @@ module ChefFS
|
|
74
76
|
|
75
77
|
begin
|
76
78
|
rest.post_rest(api_path, object)
|
79
|
+
rescue Timeout::Error => e
|
80
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "Timeout creating '#{name}': #{e}"
|
77
81
|
rescue Net::HTTPServerException => e
|
78
82
|
if e.response.code == "404"
|
79
83
|
raise ChefFS::FileSystem::NotFoundError.new(self, e)
|
@@ -68,11 +68,13 @@ module ChefFS
|
|
68
68
|
def delete(recurse)
|
69
69
|
begin
|
70
70
|
rest.delete_rest(api_path)
|
71
|
-
rescue
|
72
|
-
|
73
|
-
|
71
|
+
rescue Timeout::Error => e
|
72
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "Timeout deleting: #{e}"
|
73
|
+
rescue Net::HTTPServerException => e
|
74
|
+
if e.response.code == "404"
|
75
|
+
raise ChefFS::FileSystem::NotFoundError.new(self, e)
|
74
76
|
else
|
75
|
-
raise
|
77
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "Timeout deleting: #{e}"
|
76
78
|
end
|
77
79
|
end
|
78
80
|
end
|
@@ -84,9 +86,11 @@ module ChefFS
|
|
84
86
|
def _read_hash
|
85
87
|
begin
|
86
88
|
json = ChefFS::RawRequest.raw_request(rest, api_path)
|
89
|
+
rescue Timeout::Error => e
|
90
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "Timeout reading: #{e}"
|
87
91
|
rescue Net::HTTPServerException => e
|
88
92
|
if $!.response.code == "404"
|
89
|
-
raise ChefFS::FileSystem::NotFoundError.new(self,
|
93
|
+
raise ChefFS::FileSystem::NotFoundError.new(self, e)
|
90
94
|
else
|
91
95
|
raise ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "HTTP error reading: #{e}"
|
92
96
|
end
|
@@ -125,7 +129,6 @@ module ChefFS
|
|
125
129
|
value = minimize_value(value)
|
126
130
|
value_json = Chef::JSONCompat.to_json_pretty(value)
|
127
131
|
begin
|
128
|
-
#other_value = Chef::JSONCompat.from_json(other_value_json, :create_additions => false)
|
129
132
|
other_value = JSON.parse(other_value_json, :create_additions => false)
|
130
133
|
rescue JSON::ParserError => e
|
131
134
|
Chef::Log.warn("Parse error reading #{other.path_for_printing} as JSON: #{e}")
|
@@ -143,7 +146,6 @@ module ChefFS
|
|
143
146
|
|
144
147
|
def write(file_contents)
|
145
148
|
begin
|
146
|
-
#object = Chef::JSONCompat.from_json(file_contents).to_hash
|
147
149
|
object = JSON.parse(file_contents, :create_additions => false)
|
148
150
|
rescue JSON::ParserError => e
|
149
151
|
raise ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Parse error reading JSON: #{e}"
|
@@ -158,6 +160,8 @@ module ChefFS
|
|
158
160
|
|
159
161
|
begin
|
160
162
|
rest.put_rest(api_path, object)
|
163
|
+
rescue Timeout::Error => e
|
164
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Timeout writing: #{e}"
|
161
165
|
rescue Net::HTTPServerException => e
|
162
166
|
if e.response.code == "404"
|
163
167
|
raise ChefFS::FileSystem::NotFoundError.new(self, e)
|
data/lib/chef_fs/knife.rb
CHANGED
@@ -96,7 +96,11 @@ module ChefFS
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def chef_fs
|
99
|
-
@chef_fs ||=
|
99
|
+
@chef_fs ||= create_chef_fs
|
100
|
+
end
|
101
|
+
|
102
|
+
def create_chef_fs
|
103
|
+
ChefFS::FileSystem::ChefServerRootDir.new("remote", Chef::Config)
|
100
104
|
end
|
101
105
|
|
102
106
|
def object_paths
|
@@ -193,7 +197,11 @@ module ChefFS
|
|
193
197
|
end
|
194
198
|
|
195
199
|
def local_fs
|
196
|
-
@local_fs ||=
|
200
|
+
@local_fs ||= create_local_fs
|
201
|
+
end
|
202
|
+
|
203
|
+
def create_local_fs
|
204
|
+
ChefFS::FileSystem::ChefRepositoryFileSystemRootDir.new(object_paths)
|
197
205
|
end
|
198
206
|
|
199
207
|
def pattern_args
|
data/lib/chef_fs/version.rb
CHANGED
@@ -17,56 +17,16 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef_fs/file_system'
|
20
|
-
require 'chef_fs/file_system/
|
21
|
-
require 'chef_fs/file_system/
|
20
|
+
require 'chef_fs/file_system/memory_root'
|
21
|
+
require 'chef_fs/file_system/memory_dir'
|
22
|
+
require 'chef_fs/file_system/memory_file'
|
22
23
|
|
23
24
|
module FileSystemSupport
|
24
|
-
class MemoryFile < ChefFS::FileSystem::BaseFSObject
|
25
|
-
def initialize(name, parent, value)
|
26
|
-
super(name, parent)
|
27
|
-
@value = value
|
28
|
-
end
|
29
|
-
def read
|
30
|
-
return @value
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class MemoryDir < ChefFS::FileSystem::BaseFSDir
|
35
|
-
def initialize(name, parent)
|
36
|
-
super(name, parent)
|
37
|
-
@children = []
|
38
|
-
end
|
39
|
-
attr_reader :children
|
40
|
-
def child(name)
|
41
|
-
@children.select { |child| child.name == name }.first || ChefFS::FileSystem::NonexistentFSObject.new(name, self)
|
42
|
-
end
|
43
|
-
def add_child(child)
|
44
|
-
@children.push(child)
|
45
|
-
end
|
46
|
-
def can_have_child?(name, is_dir)
|
47
|
-
root.cannot_be_in_regex ? (name !~ root.cannot_be_in_regex) : true
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
class MemoryRoot < MemoryDir
|
52
|
-
def initialize(pretty_name, cannot_be_in_regex = nil)
|
53
|
-
super('', nil)
|
54
|
-
@pretty_name = pretty_name
|
55
|
-
@cannot_be_in_regex = cannot_be_in_regex
|
56
|
-
end
|
57
|
-
|
58
|
-
attr_reader :cannot_be_in_regex
|
59
|
-
|
60
|
-
def path_for_printing
|
61
|
-
@pretty_name
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
25
|
def memory_fs(pretty_name, value, cannot_be_in_regex = nil)
|
66
26
|
if !value.is_a?(Hash)
|
67
27
|
raise "memory_fs() must take a Hash"
|
68
28
|
end
|
69
|
-
dir = MemoryRoot.new(pretty_name, cannot_be_in_regex)
|
29
|
+
dir = ChefFS::FileSystem::MemoryRoot.new(pretty_name, cannot_be_in_regex)
|
70
30
|
value.each do |key, child|
|
71
31
|
dir.add_child(memory_fs_value(child, key.to_s, dir))
|
72
32
|
end
|
@@ -75,13 +35,13 @@ module FileSystemSupport
|
|
75
35
|
|
76
36
|
def memory_fs_value(value, name = '', parent = nil)
|
77
37
|
if value.is_a?(Hash)
|
78
|
-
dir = MemoryDir.new(name, parent)
|
38
|
+
dir = ChefFS::FileSystem::MemoryDir.new(name, parent)
|
79
39
|
value.each do |key, child|
|
80
40
|
dir.add_child(memory_fs_value(child, key.to_s, dir))
|
81
41
|
end
|
82
42
|
dir
|
83
43
|
else
|
84
|
-
MemoryFile.new(name, parent, value || "#{name}\n")
|
44
|
+
ChefFS::FileSystem::MemoryFile.new(name, parent, value || "#{name}\n")
|
85
45
|
end
|
86
46
|
end
|
87
47
|
|
@@ -94,7 +54,7 @@ module FileSystemSupport
|
|
94
54
|
end
|
95
55
|
|
96
56
|
def no_blocking_calls_allowed
|
97
|
-
[ MemoryFile, MemoryDir ].each do |c|
|
57
|
+
[ ChefFS::FileSystem::MemoryFile, ChefFS::FileSystem::MemoryDir ].each do |c|
|
98
58
|
[ :children, :exists?, :read ].each do |m|
|
99
59
|
c.any_instance.stub(m).and_raise("#{m.to_s} should not be called")
|
100
60
|
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: 1.
|
4
|
+
version: '1.1'
|
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-05-
|
12
|
+
date: 2013-05-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: chef
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- lib/chef/knife/edit_essentials.rb
|
126
126
|
- lib/chef/knife/list_essentials.rb
|
127
127
|
- lib/chef/knife/raw_essentials.rb
|
128
|
+
- lib/chef/knife/serve_essentials.rb
|
128
129
|
- lib/chef/knife/show_essentials.rb
|
129
130
|
- lib/chef/knife/upload_essentials.rb
|
130
131
|
- lib/chef/knife/xargs_essentials.rb
|
@@ -163,6 +164,9 @@ files:
|
|
163
164
|
- lib/chef_fs/file_system/file_system_entry.rb
|
164
165
|
- lib/chef_fs/file_system/file_system_error.rb
|
165
166
|
- lib/chef_fs/file_system/file_system_root_dir.rb
|
167
|
+
- lib/chef_fs/file_system/memory_dir.rb
|
168
|
+
- lib/chef_fs/file_system/memory_file.rb
|
169
|
+
- lib/chef_fs/file_system/memory_root.rb
|
166
170
|
- lib/chef_fs/file_system/multiplexed_dir.rb
|
167
171
|
- lib/chef_fs/file_system/must_delete_recursively_error.rb
|
168
172
|
- lib/chef_fs/file_system/nodes_dir.rb
|