knife-essentials 0.8.4 → 0.8.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/chef/knife/delete_essentials.rb +37 -8
- data/lib/chef/knife/deps_essentials.rb +5 -5
- data/lib/chef/knife/diff_essentials.rb +9 -1
- data/lib/chef/knife/download_essentials.rb +1 -1
- data/lib/chef/knife/list_essentials.rb +5 -5
- data/lib/chef/knife/raw_essentials.rb +7 -2
- data/lib/chef/knife/show_essentials.rb +14 -4
- data/lib/chef/knife/upload_essentials.rb +1 -1
- data/lib/chef_fs/command_line.rb +18 -10
- data/lib/chef_fs/file_system.rb +4 -4
- data/lib/chef_fs/file_system/base_fs_object.rb +10 -10
- data/lib/chef_fs/file_system/chef_repository_file_system_root_dir.rb +1 -1
- data/lib/chef_fs/file_system/chef_server_root_dir.rb +0 -2
- data/lib/chef_fs/file_system/cookbook_dir.rb +17 -12
- data/lib/chef_fs/file_system/cookbooks_dir.rb +1 -1
- data/lib/chef_fs/file_system/data_bag_dir.rb +4 -3
- data/lib/chef_fs/file_system/data_bag_item.rb +1 -1
- data/lib/chef_fs/file_system/data_bags_dir.rb +2 -2
- data/lib/chef_fs/file_system/{operation_skipped_error.rb → default_environment_cannot_be_modified_error.rb} +8 -3
- data/lib/chef_fs/file_system/environments_dir.rb +5 -7
- data/lib/chef_fs/file_system/file_system_entry.rb +6 -6
- data/lib/chef_fs/file_system/must_delete_recursively_error.rb +4 -1
- data/lib/chef_fs/file_system/nodes_dir.rb +2 -2
- data/lib/chef_fs/file_system/nonexistent_fs_object.rb +0 -12
- data/lib/chef_fs/file_system/not_found_error.rb +4 -1
- data/lib/chef_fs/file_system/operation_not_allowed_error.rb +19 -1
- data/lib/chef_fs/file_system/rest_list_dir.rb +2 -2
- data/lib/chef_fs/file_system/rest_list_entry.rb +3 -3
- data/lib/chef_fs/knife.rb +5 -4
- data/lib/chef_fs/path_utils.rb +6 -4
- data/lib/chef_fs/version.rb +1 -1
- data/spec/integration/delete_spec.rb +684 -0
- data/spec/integration/diff_spec.rb +75 -1
- data/spec/integration/download_spec.rb +101 -4
- data/spec/integration/raw_spec.rb +171 -0
- data/spec/integration/show_spec.rb +124 -0
- data/spec/integration/upload_spec.rb +122 -13
- metadata +6 -3
@@ -11,18 +11,17 @@ class Chef
|
|
11
11
|
common_options
|
12
12
|
|
13
13
|
option :recurse,
|
14
|
+
:short => '-r',
|
14
15
|
:long => '--[no-]recurse',
|
15
16
|
:boolean => true,
|
16
17
|
:default => false,
|
17
18
|
:description => "Delete directories recursively."
|
18
19
|
option :remote_only,
|
19
|
-
:short => '-R',
|
20
20
|
:long => '--remote-only',
|
21
21
|
:boolean => true,
|
22
22
|
:default => false,
|
23
23
|
:description => "Only delete the remote copy (leave the local copy)."
|
24
24
|
option :local_only,
|
25
|
-
:short => '-L',
|
26
25
|
:long => '--local-only',
|
27
26
|
:boolean => true,
|
28
27
|
:default => false,
|
@@ -36,41 +35,71 @@ class Chef
|
|
36
35
|
end
|
37
36
|
|
38
37
|
# Get the matches (recursively)
|
38
|
+
error = false
|
39
39
|
if config[:remote_only]
|
40
40
|
pattern_args.each do |pattern|
|
41
41
|
ChefFS::FileSystem.list(chef_fs, pattern) do |result|
|
42
|
-
delete_result(result)
|
42
|
+
if delete_result(result)
|
43
|
+
error = true
|
44
|
+
end
|
43
45
|
end
|
44
46
|
end
|
45
47
|
elsif config[:local_only]
|
46
48
|
pattern_args.each do |pattern|
|
47
49
|
ChefFS::FileSystem.list(local_fs, pattern) do |result|
|
48
|
-
delete_result(result)
|
50
|
+
if delete_result(result)
|
51
|
+
error = true
|
52
|
+
end
|
49
53
|
end
|
50
54
|
end
|
51
55
|
else
|
52
56
|
pattern_args.each do |pattern|
|
53
57
|
ChefFS::FileSystem.list_pairs(pattern, chef_fs, local_fs) do |chef_result, local_result|
|
54
|
-
delete_result(chef_result, local_result)
|
58
|
+
if delete_result(chef_result, local_result)
|
59
|
+
error = true
|
60
|
+
end
|
55
61
|
end
|
56
62
|
end
|
57
63
|
end
|
64
|
+
|
65
|
+
if error
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def format_path_with_root(entry)
|
71
|
+
root = entry.root == chef_fs ? " (remote)" : " (local)"
|
72
|
+
"#{format_path(entry)}#{root}"
|
58
73
|
end
|
59
74
|
|
60
75
|
def delete_result(*results)
|
61
76
|
deleted_any = false
|
77
|
+
found_any = false
|
78
|
+
error = false
|
62
79
|
results.each do |result|
|
63
80
|
begin
|
64
81
|
result.delete(config[:recurse])
|
65
82
|
deleted_any = true
|
83
|
+
found_any = true
|
66
84
|
rescue ChefFS::FileSystem::NotFoundError
|
85
|
+
# This is not an error unless *all* of them were not found
|
86
|
+
rescue ChefFS::FileSystem::MustDeleteRecursivelyError => e
|
87
|
+
ui.error "#{format_path_with_root(e.entry)} must be deleted recursively! Pass -r to knife delete."
|
88
|
+
found_any = true
|
89
|
+
error = true
|
90
|
+
rescue ChefFS::FileSystem::OperationNotAllowedError => e
|
91
|
+
ui.error "#{format_path_with_root(e.entry)} #{e.reason}."
|
92
|
+
found_any = true
|
93
|
+
error = true
|
67
94
|
end
|
68
95
|
end
|
69
96
|
if deleted_any
|
70
|
-
output("Deleted #{format_path(results[0]
|
71
|
-
|
72
|
-
ui.error "#{format_path(results[0]
|
97
|
+
output("Deleted #{format_path(results[0])}")
|
98
|
+
elsif !found_any
|
99
|
+
ui.error "#{format_path(results[0])}: No such file or directory"
|
100
|
+
error = true
|
73
101
|
end
|
102
|
+
error
|
74
103
|
end
|
75
104
|
end
|
76
105
|
end
|
@@ -54,13 +54,13 @@ class Chef
|
|
54
54
|
child_entry = ChefFS::FileSystem.resolve_path(@root, child)
|
55
55
|
print_flattened_dependencies(child_entry, dependencies)
|
56
56
|
end
|
57
|
-
output format_path(entry
|
57
|
+
output format_path(entry)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
def print_dependencies_tree(entry, dependencies, printed = {}, depth = 0)
|
62
62
|
dependencies[entry.path] = get_dependencies(entry) if !dependencies[entry.path]
|
63
|
-
output "#{' '*depth}#{format_path(entry
|
63
|
+
output "#{' '*depth}#{format_path(entry)}"
|
64
64
|
if !printed[entry.path] && (config[:recurse] || depth == 0)
|
65
65
|
printed[entry.path] = true
|
66
66
|
dependencies[entry.path].each do |child|
|
@@ -104,13 +104,13 @@ class Chef
|
|
104
104
|
result
|
105
105
|
|
106
106
|
elsif !entry.exists?
|
107
|
-
raise ChefFS::FileSystem::NotFoundError
|
107
|
+
raise ChefFS::FileSystem::NotFoundError.new(entry)
|
108
108
|
|
109
109
|
else
|
110
110
|
[]
|
111
111
|
end
|
112
|
-
rescue ChefFS::FileSystem::NotFoundError
|
113
|
-
ui.error "#{format_path(entry
|
112
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
113
|
+
ui.error "#{format_path(e.entry)}: No such file or directory"
|
114
114
|
self.exit_code = 2
|
115
115
|
[]
|
116
116
|
end
|
@@ -36,10 +36,18 @@ class Chef
|
|
36
36
|
patterns = pattern_args_from(name_args.length > 0 ? name_args : [ "" ])
|
37
37
|
|
38
38
|
# Get the matches (recursively)
|
39
|
+
error = false
|
39
40
|
patterns.each do |pattern|
|
40
|
-
ChefFS::CommandLine.diff_print(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, output_mode, proc { |entry| format_path(entry
|
41
|
+
found_match = ChefFS::CommandLine.diff_print(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, output_mode, proc { |entry| format_path(entry) } ) do |diff|
|
41
42
|
stdout.print diff
|
42
43
|
end
|
44
|
+
if !found_match
|
45
|
+
ui.error "#{pattern}: No such file or directory on remote or local"
|
46
|
+
error = true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
if error
|
50
|
+
exit 1
|
43
51
|
end
|
44
52
|
end
|
45
53
|
end
|
@@ -44,7 +44,7 @@ class Chef
|
|
44
44
|
|
45
45
|
error = false
|
46
46
|
pattern_args.each do |pattern|
|
47
|
-
error ||= ChefFS::FileSystem.copy_to(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, config, ui, proc { |entry| format_path(entry
|
47
|
+
error ||= ChefFS::FileSystem.copy_to(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, config, ui, proc { |entry| format_path(entry) })
|
48
48
|
end
|
49
49
|
if error
|
50
50
|
exit 1
|
@@ -51,7 +51,7 @@ class Chef
|
|
51
51
|
elsif result.exists?
|
52
52
|
results << result
|
53
53
|
elsif pattern.exact_path
|
54
|
-
ui.error "#{format_path(result
|
54
|
+
ui.error "#{format_path(result)}: No such file or directory"
|
55
55
|
self.exit_code = 1
|
56
56
|
end
|
57
57
|
end
|
@@ -80,7 +80,7 @@ class Chef
|
|
80
80
|
else
|
81
81
|
printed_something = true
|
82
82
|
end
|
83
|
-
output "#{format_path(result
|
83
|
+
output "#{format_path(result)}:"
|
84
84
|
print_results(children.map { |result| maybe_add_slash(result.name, result.dir?) }.sort, "")
|
85
85
|
end
|
86
86
|
|
@@ -90,8 +90,8 @@ class Chef
|
|
90
90
|
def add_dir_result(result)
|
91
91
|
begin
|
92
92
|
children = result.children.sort_by { |child| child.name }
|
93
|
-
rescue ChefFS::FileSystem::NotFoundError
|
94
|
-
ui.error "#{format_path(
|
93
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
94
|
+
ui.error "#{format_path(e.entry)}: No such file or directory"
|
95
95
|
return []
|
96
96
|
end
|
97
97
|
|
@@ -107,7 +107,7 @@ class Chef
|
|
107
107
|
end
|
108
108
|
|
109
109
|
def print_result_paths(results, indent = "")
|
110
|
-
print_results(results.map { |result| maybe_add_slash(format_path(result
|
110
|
+
print_results(results.map { |result| maybe_add_slash(format_path(result), result.dir?) }, indent)
|
111
111
|
end
|
112
112
|
|
113
113
|
def print_results(results, indent)
|
@@ -40,7 +40,13 @@ class Chef
|
|
40
40
|
data = IO.read(config[:input])
|
41
41
|
end
|
42
42
|
chef_rest = Chef::REST.new(Chef::Config[:chef_server_url])
|
43
|
-
|
43
|
+
begin
|
44
|
+
output api_request(chef_rest, config[:method].to_sym, chef_rest.create_url(name_args[0]), {}, data)
|
45
|
+
rescue Net::HTTPServerException => e
|
46
|
+
ui.error "Server responded with error #{e.response.code} \"#{e.response.message}\""
|
47
|
+
ui.error "Error Body: #{e.response.body}" if e.response.body && e.response.body != ''
|
48
|
+
exit 1
|
49
|
+
end
|
44
50
|
end
|
45
51
|
|
46
52
|
ACCEPT_ENCODING = "Accept-Encoding".freeze
|
@@ -86,7 +92,6 @@ class Chef
|
|
86
92
|
msg << (exception["error"].respond_to?(:join) ? exception["error"].join(", ") : exception["error"].to_s)
|
87
93
|
Chef::Log.info(msg)
|
88
94
|
end
|
89
|
-
output response.body
|
90
95
|
response.error!
|
91
96
|
end
|
92
97
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'chef_fs/knife'
|
2
2
|
require 'chef_fs/file_system'
|
3
|
+
require 'chef_fs/file_system/not_found_error'
|
3
4
|
|
4
5
|
class Chef
|
5
6
|
class Knife
|
@@ -17,21 +18,30 @@ class Chef
|
|
17
18
|
|
18
19
|
def run
|
19
20
|
# Get the matches (recursively)
|
21
|
+
error = false
|
20
22
|
pattern_args.each do |pattern|
|
21
23
|
ChefFS::FileSystem.list(config[:local] ? local_fs : chef_fs, pattern) do |result|
|
22
24
|
if result.dir?
|
23
|
-
ui.error "#{result
|
25
|
+
ui.error "#{format_path(result)}: is a directory" if pattern.exact_path
|
26
|
+
error = true
|
24
27
|
else
|
25
28
|
begin
|
26
29
|
value = result.read
|
27
|
-
output "#{result
|
30
|
+
output "#{format_path(result)}:"
|
28
31
|
output(format_for_display(value))
|
29
|
-
rescue ChefFS::FileSystem::
|
30
|
-
ui.error "#{
|
32
|
+
rescue ChefFS::FileSystem::OperationNotAllowedError => e
|
33
|
+
ui.error "#{format_path(e.entry)}: #{e.reason}."
|
34
|
+
error = true
|
35
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
36
|
+
ui.error "#{format_path(e.entry)}: No such file or directory"
|
37
|
+
error = true
|
31
38
|
end
|
32
39
|
end
|
33
40
|
end
|
34
41
|
end
|
42
|
+
if error
|
43
|
+
exit 1
|
44
|
+
end
|
35
45
|
end
|
36
46
|
end
|
37
47
|
end
|
@@ -44,7 +44,7 @@ class Chef
|
|
44
44
|
|
45
45
|
error = false
|
46
46
|
pattern_args.each do |pattern|
|
47
|
-
error ||= ChefFS::FileSystem.copy_to(pattern, local_fs, chef_fs, config[:recurse] ? nil : 1, config, ui, proc { |entry| format_path(entry
|
47
|
+
error ||= ChefFS::FileSystem.copy_to(pattern, local_fs, chef_fs, config[:recurse] ? nil : 1, config, ui, proc { |entry| format_path(entry) })
|
48
48
|
end
|
49
49
|
if error
|
50
50
|
exit 1
|
data/lib/chef_fs/command_line.rb
CHANGED
@@ -27,7 +27,9 @@ module ChefFS
|
|
27
27
|
end
|
28
28
|
|
29
29
|
get_content = (output_mode != :name_only && output_mode != :name_status)
|
30
|
+
found_match = false
|
30
31
|
diff(pattern, a_root, b_root, recurse_depth, get_content) do |type, old_entry, new_entry, old_value, new_value|
|
32
|
+
found_match = true unless type == :both_nonexistent
|
31
33
|
old_path = format_path.call(old_entry)
|
32
34
|
new_path = format_path.call(new_entry)
|
33
35
|
|
@@ -90,21 +92,22 @@ module ChefFS
|
|
90
92
|
elsif output_mode == :name_status
|
91
93
|
yield "M\t#{new_path}\n"
|
92
94
|
end
|
95
|
+
when :both_nonexistent
|
96
|
+
when :added_cannot_upload
|
97
|
+
when :deleted_cannot_download
|
98
|
+
when :same
|
99
|
+
# Skip these silently
|
93
100
|
end
|
94
101
|
end
|
95
102
|
end
|
103
|
+
found_match
|
96
104
|
end
|
97
105
|
|
98
106
|
def self.diff(pattern, a_root, b_root, recurse_depth, get_content)
|
99
|
-
found_result = false
|
100
107
|
ChefFS::FileSystem.list_pairs(pattern, a_root, b_root) do |a, b|
|
101
|
-
|
108
|
+
diff_entries(a, b, recurse_depth, get_content) do |diff|
|
102
109
|
yield diff
|
103
110
|
end
|
104
|
-
found_result = true if existed
|
105
|
-
end
|
106
|
-
if !found_result && pattern.exact_path
|
107
|
-
yield "#{pattern}: No such file or directory on remote or local"
|
108
111
|
end
|
109
112
|
end
|
110
113
|
|
@@ -147,7 +150,11 @@ module ChefFS
|
|
147
150
|
else
|
148
151
|
are_same, old_value, new_value = ChefFS::FileSystem.compare(old_entry, new_entry)
|
149
152
|
if are_same
|
150
|
-
|
153
|
+
if old_value == :none
|
154
|
+
yield [ :both_nonexistent, old_entry, new_entry ]
|
155
|
+
else
|
156
|
+
yield [ :same, old_entry, new_entry ]
|
157
|
+
end
|
151
158
|
else
|
152
159
|
if old_value == :none
|
153
160
|
old_exists = false
|
@@ -168,10 +175,12 @@ module ChefFS
|
|
168
175
|
# If one of the files doesn't exist, we only want to print the diff if the
|
169
176
|
# other file *could be uploaded/downloaded*.
|
170
177
|
if !old_exists && !old_entry.parent.can_have_child?(new_entry.name, new_entry.dir?)
|
171
|
-
|
178
|
+
yield [ :old_cannot_upload, old_entry, new_entry ]
|
179
|
+
return
|
172
180
|
end
|
173
181
|
if !new_exists && !new_entry.parent.can_have_child?(old_entry.name, old_entry.dir?)
|
174
|
-
|
182
|
+
yield [ :new_cannot_upload, old_entry, new_entry ]
|
183
|
+
return
|
175
184
|
end
|
176
185
|
|
177
186
|
if get_content
|
@@ -197,7 +206,6 @@ module ChefFS
|
|
197
206
|
end
|
198
207
|
end
|
199
208
|
end
|
200
|
-
return true
|
201
209
|
end
|
202
210
|
|
203
211
|
private
|
data/lib/chef_fs/file_system.rb
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef_fs/path_utils'
|
20
|
-
require 'chef_fs/file_system/
|
20
|
+
require 'chef_fs/file_system/default_environment_cannot_be_modified_error'
|
21
21
|
require 'chef_fs/file_system/operation_not_allowed_error'
|
22
22
|
|
23
23
|
module ChefFS
|
@@ -348,10 +348,10 @@ module ChefFS
|
|
348
348
|
end
|
349
349
|
end
|
350
350
|
end
|
351
|
-
rescue
|
352
|
-
#
|
351
|
+
rescue DefaultEnvironmentCannotBeModifiedError => e
|
352
|
+
ui.warn "#{format_path.call(e.entry)} #{e.reason}."
|
353
353
|
rescue OperationNotAllowedError => e
|
354
|
-
ui.error e.
|
354
|
+
ui.error "#{format_path.call(e.entry)} #{e.reason}."
|
355
355
|
error = true
|
356
356
|
end
|
357
357
|
error
|
@@ -99,13 +99,13 @@ module ChefFS
|
|
99
99
|
|
100
100
|
# Override children to report your *actual* list of children as an array.
|
101
101
|
def children
|
102
|
-
raise NotFoundError
|
102
|
+
raise NotFoundError.new(self) if !exists?
|
103
103
|
[]
|
104
104
|
end
|
105
105
|
|
106
106
|
# Expand this entry into a chef object (Chef::Role, ::Node, etc.)
|
107
107
|
def chef_object
|
108
|
-
raise NotFoundError
|
108
|
+
raise NotFoundError.new(self) if !exists?
|
109
109
|
nil
|
110
110
|
end
|
111
111
|
|
@@ -116,15 +116,15 @@ module ChefFS
|
|
116
116
|
# your entry class, and will be called without actually reading the
|
117
117
|
# file_contents. This is used for knife upload /cookbooks/cookbookname.
|
118
118
|
def create_child(name, file_contents)
|
119
|
-
raise NotFoundError
|
120
|
-
raise OperationNotAllowedError.new(:create_child
|
119
|
+
raise NotFoundError.new(self) if !exists?
|
120
|
+
raise OperationNotAllowedError.new(:create_child, self)
|
121
121
|
end
|
122
122
|
|
123
123
|
# Delete this item, possibly recursively. Entries MUST NOT delete a
|
124
124
|
# directory unless recurse is true.
|
125
125
|
def delete(recurse)
|
126
|
-
raise NotFoundError
|
127
|
-
raise OperationNotAllowedError.new(:delete
|
126
|
+
raise NotFoundError.new(self) if !exists?
|
127
|
+
raise OperationNotAllowedError.new(:delete, self)
|
128
128
|
end
|
129
129
|
|
130
130
|
# Ask whether this entry is a directory. If not, it is a file.
|
@@ -158,14 +158,14 @@ module ChefFS
|
|
158
158
|
|
159
159
|
# Read the contents of this file entry.
|
160
160
|
def read
|
161
|
-
raise NotFoundError
|
162
|
-
raise OperationNotAllowedError.new(:read
|
161
|
+
raise NotFoundError.new(self) if !exists?
|
162
|
+
raise OperationNotAllowedError.new(:read, self)
|
163
163
|
end
|
164
164
|
|
165
165
|
# Write the contents of this file entry.
|
166
166
|
def write(file_contents)
|
167
|
-
raise NotFoundError
|
168
|
-
raise OperationNotAllowedError.new(:write
|
167
|
+
raise NotFoundError.new(self) if !exists?
|
168
|
+
raise OperationNotAllowedError.new(:write, self)
|
169
169
|
end
|
170
170
|
|
171
171
|
# Important directory attributes: name, parent, path, root
|
@@ -37,7 +37,7 @@ module ChefFS
|
|
37
37
|
attr_reader :child_paths
|
38
38
|
|
39
39
|
def children
|
40
|
-
@children ||= child_paths.keys.map { |name| make_child_entry(name) }.select { |child| !child.nil? }
|
40
|
+
@children ||= child_paths.keys.sort.map { |name| make_child_entry(name) }.select { |child| !child.nil? }
|
41
41
|
end
|
42
42
|
|
43
43
|
def can_have_child?(name, is_dir)
|