knife-essentials 0.8.4 → 0.8.5
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/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)
|