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