chef 11.12.0.alpha.1-x86-mingw32 → 11.12.0.rc.1-x86-mingw32
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.
- checksums.yaml +4 -4
- data/lib/chef/api_client/registration.rb +46 -9
- data/lib/chef/application.rb +1 -0
- data/lib/chef/application/client.rb +25 -24
- data/lib/chef/client.rb +34 -0
- data/lib/chef/config.rb +11 -0
- data/lib/chef/cookbook/chefignore.rb +10 -2
- data/lib/chef/cookbook/metadata.rb +31 -3
- data/lib/chef/cookbook/synchronizer.rb +2 -2
- data/lib/chef/cookbook/syntax_check.rb +4 -4
- data/lib/chef/encrypted_data_bag_item.rb +37 -1
- data/lib/chef/exceptions.rb +1 -0
- data/lib/chef/guard_interpreter/default_guard_interpreter.rb +42 -0
- data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +122 -0
- data/lib/chef/http.rb +0 -1
- data/lib/chef/http/decompressor.rb +7 -4
- data/lib/chef/http/simple.rb +5 -0
- data/lib/chef/http/validate_content_length.rb +28 -12
- data/lib/chef/knife.rb +1 -0
- data/lib/chef/knife/client_bulk_delete.rb +48 -9
- data/lib/chef/knife/client_delete.rb +4 -4
- data/lib/chef/knife/cookbook_bulk_delete.rb +1 -1
- data/lib/chef/knife/cookbook_upload.rb +17 -7
- data/lib/chef/knife/core/bootstrap_context.rb +1 -1
- data/lib/chef/knife/core/ui.rb +42 -5
- data/lib/chef/knife/node_run_list_add.rb +31 -2
- data/lib/chef/knife/ssh.rb +44 -31
- data/lib/chef/knife/ssl_check.rb +213 -0
- data/lib/chef/knife/ssl_fetch.rb +145 -0
- data/lib/chef/mixin/deep_merge.rb +13 -5
- data/lib/chef/mixin/shell_out.rb +9 -3
- data/lib/chef/node.rb +23 -4
- data/lib/chef/node/immutable_collections.rb +32 -0
- data/lib/chef/platform/provider_mapping.rb +21 -18
- data/lib/chef/platform/query_helpers.rb +10 -2
- data/lib/chef/policy_builder/expand_node_object.rb +3 -6
- data/lib/chef/provider/cron.rb +25 -3
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/package/dpkg.rb +2 -1
- data/lib/chef/provider/package/windows.rb +80 -0
- data/lib/chef/provider/package/windows/msi.rb +69 -0
- data/lib/chef/provider/powershell_script.rb +19 -6
- data/lib/chef/provider/service/solaris.rb +11 -7
- data/lib/chef/resource.rb +18 -5
- data/lib/chef/resource/conditional.rb +20 -7
- data/lib/chef/resource/cron.rb +18 -2
- data/lib/chef/resource/execute.rb +0 -2
- data/lib/chef/resource/powershell_script.rb +23 -1
- data/lib/chef/resource/script.rb +25 -0
- data/lib/chef/resource/subversion.rb +4 -0
- data/lib/chef/resource/windows_package.rb +79 -0
- data/lib/chef/resource/windows_script.rb +0 -5
- data/lib/chef/resources.rb +1 -0
- data/lib/chef/rest.rb +6 -1
- data/lib/chef/run_context.rb +22 -2
- data/lib/chef/run_context/cookbook_compiler.rb +12 -0
- data/lib/chef/util/editor.rb +92 -0
- data/lib/chef/util/file_edit.rb +22 -54
- data/lib/chef/version.rb +2 -2
- data/lib/chef/win32/api/installer.rb +166 -0
- data/lib/chef/win32/version.rb +8 -0
- data/spec/data/standalone_cookbook/Gemfile +1 -0
- data/spec/data/standalone_cookbook/chefignore +9 -0
- data/spec/data/standalone_cookbook/recipes/default.rb +3 -0
- data/spec/data/standalone_cookbook/vendor/bundle/ruby/2.0.0/gems/multi_json-1.9.0/lib/multi_json.rb +1 -0
- data/spec/functional/resource/powershell_spec.rb +262 -1
- data/spec/functional/win32/versions_spec.rb +3 -3
- data/spec/integration/knife/chefignore_spec.rb +1 -2
- data/spec/integration/knife/raw_spec.rb +8 -13
- data/spec/integration/knife/redirection_spec.rb +6 -14
- data/spec/integration/solo/solo_spec.rb +19 -0
- data/spec/support/shared/functional/windows_script.rb +1 -1
- data/spec/support/shared/integration/app_server_support.rb +42 -0
- data/spec/support/shared/integration/integration_helper.rb +1 -0
- data/spec/support/shared/unit/script_resource.rb +38 -0
- data/spec/unit/api_client/registration_spec.rb +109 -38
- data/spec/unit/application/client_spec.rb +48 -1
- data/spec/unit/cookbook/chefignore_spec.rb +10 -0
- data/spec/unit/cookbook/metadata_spec.rb +45 -1
- data/spec/unit/cookbook/syntax_check_spec.rb +28 -0
- data/spec/unit/cookbook_spec.rb +0 -10
- data/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +56 -0
- data/spec/unit/http/simple_spec.rb +32 -0
- data/spec/unit/http/validate_content_length_spec.rb +187 -0
- data/spec/unit/knife/bootstrap_spec.rb +13 -4
- data/spec/unit/knife/client_bulk_delete_spec.rb +123 -38
- data/spec/unit/knife/client_delete_spec.rb +4 -4
- data/spec/unit/knife/cookbook_upload_spec.rb +181 -88
- data/spec/unit/knife/core/bootstrap_context_spec.rb +11 -1
- data/spec/unit/knife/core/ui_spec.rb +109 -38
- data/spec/unit/knife/node_run_list_add_spec.rb +24 -1
- data/spec/unit/knife/ssh_spec.rb +17 -6
- data/spec/unit/knife/ssl_check_spec.rb +187 -0
- data/spec/unit/knife/ssl_fetch_spec.rb +151 -0
- data/spec/unit/mixin/deep_merge_spec.rb +17 -0
- data/spec/unit/node/immutable_collections_spec.rb +55 -0
- data/spec/unit/node_spec.rb +9 -0
- data/spec/unit/platform/query_helpers_spec.rb +32 -0
- data/spec/unit/platform_spec.rb +193 -175
- data/spec/unit/policy_builder/expand_node_object_spec.rb +1 -1
- data/spec/unit/provider/cron_spec.rb +175 -1
- data/spec/unit/provider/mount/mount_spec.rb +33 -3
- data/spec/unit/provider/package/dpkg_spec.rb +4 -0
- data/spec/unit/provider/package/windows/msi_spec.rb +60 -0
- data/spec/unit/provider/package/windows_spec.rb +80 -0
- data/spec/unit/provider/service/macosx_spec.rb +3 -3
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +35 -10
- data/spec/unit/pure_application_spec.rb +32 -0
- data/spec/unit/recipe_spec.rb +4 -0
- data/spec/unit/resource/conditional_spec.rb +13 -12
- data/spec/unit/resource/cron_spec.rb +7 -2
- data/spec/unit/resource/powershell_spec.rb +85 -2
- data/spec/unit/resource/subversion_spec.rb +5 -0
- data/spec/unit/resource/windows_package_spec.rb +74 -0
- data/spec/unit/resource_spec.rb +23 -1
- data/spec/unit/rest_spec.rb +15 -0
- data/spec/unit/run_context/cookbook_compiler_spec.rb +12 -0
- data/spec/unit/run_context_spec.rb +7 -0
- data/spec/unit/util/editor_spec.rb +152 -0
- data/spec/unit/util/file_edit_spec.rb +37 -1
- metadata +41 -30
data/lib/chef/exceptions.rb
CHANGED
@@ -76,6 +76,7 @@ class Chef
|
|
76
76
|
class CookbookNotFoundInRepo < ArgumentError; end
|
77
77
|
class RecipeNotFound < ArgumentError; end
|
78
78
|
class AttributeNotFound < RuntimeError; end
|
79
|
+
class MissingCookbookDependency < StandardError; end # CHEF-5120
|
79
80
|
class InvalidCommandOption < RuntimeError; end
|
80
81
|
class CommandTimeout < RuntimeError; end
|
81
82
|
class RequestedUIDUnavailable < RuntimeError; end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Edwards (<adamed@getchef.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
class Chef
|
20
|
+
class GuardInterpreter
|
21
|
+
class DefaultGuardInterpreter
|
22
|
+
include Chef::Mixin::ShellOut
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def initialize(command, opts)
|
27
|
+
@command = command
|
28
|
+
@command_opts = opts
|
29
|
+
end
|
30
|
+
|
31
|
+
public
|
32
|
+
|
33
|
+
def evaluate
|
34
|
+
shell_out(@command, @command_opts).status.success?
|
35
|
+
rescue Chef::Exceptions::CommandTimeout
|
36
|
+
Chef::Log.warn "Command '#{@command}' timed out"
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,122 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Edwards (<adamed@getchef.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/guard_interpreter/default_guard_interpreter'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class GuardInterpreter
|
23
|
+
class ResourceGuardInterpreter < DefaultGuardInterpreter
|
24
|
+
|
25
|
+
def initialize(parent_resource, command, opts, &block)
|
26
|
+
super(command, opts)
|
27
|
+
@parent_resource = parent_resource
|
28
|
+
@resource = get_interpreter_resource(parent_resource)
|
29
|
+
end
|
30
|
+
|
31
|
+
def evaluate
|
32
|
+
# Add attributes inherited from the parent class
|
33
|
+
# to the resource
|
34
|
+
merge_inherited_attributes
|
35
|
+
|
36
|
+
# Script resources have a code attribute, which is
|
37
|
+
# what is used to execute the command, so include
|
38
|
+
# that with attributes specified by caller in opts
|
39
|
+
block_attributes = @command_opts.merge({:code => @command})
|
40
|
+
|
41
|
+
# Handles cases like powershell_script where default
|
42
|
+
# attributes are different when used in a guard vs. not. For
|
43
|
+
# powershell_script in particular, this will go away when
|
44
|
+
# the one attribue that causes this changes its default to be
|
45
|
+
# the same after some period to prepare for deprecation
|
46
|
+
if @resource.class.respond_to?(:get_default_attributes)
|
47
|
+
block_attributes = @resource.class.send(:get_default_attributes, @command_opts).merge(block_attributes)
|
48
|
+
end
|
49
|
+
|
50
|
+
resource_block = block_from_attributes(block_attributes)
|
51
|
+
evaluate_action(nil, &resource_block)
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
|
56
|
+
def evaluate_action(action=nil, &block)
|
57
|
+
@resource.instance_eval(&block)
|
58
|
+
|
59
|
+
run_action = action || @resource.action
|
60
|
+
|
61
|
+
begin
|
62
|
+
@resource.run_action(run_action)
|
63
|
+
resource_updated = @resource.updated
|
64
|
+
rescue Mixlib::ShellOut::ShellCommandFailed
|
65
|
+
resource_updated = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
resource_updated
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_interpreter_resource(parent_resource)
|
72
|
+
if parent_resource.nil? || parent_resource.node.nil?
|
73
|
+
raise ArgumentError, "Node for guard resource parent must not be nil"
|
74
|
+
end
|
75
|
+
|
76
|
+
resource_class = Chef::Resource.resource_for_node(parent_resource.guard_interpreter, parent_resource.node)
|
77
|
+
|
78
|
+
if resource_class.nil?
|
79
|
+
raise ArgumentError, "Specified guard_interpreter resource #{parent_resource.guard_interpreter.to_s} unknown for this platform"
|
80
|
+
end
|
81
|
+
|
82
|
+
if ! resource_class.ancestors.include?(Chef::Resource::Script)
|
83
|
+
raise ArgumentError, "Specified guard interpreter class #{resource_class} must be a kind of Chef::Resource::Script resource"
|
84
|
+
end
|
85
|
+
|
86
|
+
empty_events = Chef::EventDispatch::Dispatcher.new
|
87
|
+
anonymous_run_context = Chef::RunContext.new(parent_resource.node, {}, empty_events)
|
88
|
+
interpreter_resource = resource_class.new('Guard resource', anonymous_run_context)
|
89
|
+
|
90
|
+
interpreter_resource
|
91
|
+
end
|
92
|
+
|
93
|
+
def block_from_attributes(attributes)
|
94
|
+
Proc.new do
|
95
|
+
attributes.keys.each do |attribute_name|
|
96
|
+
send(attribute_name, attributes[attribute_name]) if respond_to?(attribute_name)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def merge_inherited_attributes
|
102
|
+
inherited_attributes = []
|
103
|
+
|
104
|
+
if @parent_resource.class.respond_to?(:guard_inherited_attributes)
|
105
|
+
inherited_attributes = @parent_resource.class.send(:guard_inherited_attributes)
|
106
|
+
end
|
107
|
+
|
108
|
+
if inherited_attributes && !inherited_attributes.empty?
|
109
|
+
inherited_attributes.each do |attribute|
|
110
|
+
if @parent_resource.respond_to?(attribute) && @resource.respond_to?(attribute)
|
111
|
+
parent_value = @parent_resource.send(attribute)
|
112
|
+
child_value = @resource.send(attribute)
|
113
|
+
if parent_value || child_value
|
114
|
+
@resource.send(attribute, parent_value)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
data/lib/chef/http.rb
CHANGED
@@ -94,16 +94,21 @@ class Chef
|
|
94
94
|
# object you can use to unzip/inflate a streaming response.
|
95
95
|
def stream_response_handler(response)
|
96
96
|
if gzip_disabled?
|
97
|
+
Chef::Log.debug "disable_gzip is set. \
|
98
|
+
Not using #{response[CONTENT_ENCODING]} \
|
99
|
+
and initializing noop stream deflator."
|
97
100
|
NoopInflater.new
|
98
101
|
else
|
99
102
|
case response[CONTENT_ENCODING]
|
100
103
|
when GZIP
|
101
|
-
Chef::Log.debug "
|
104
|
+
Chef::Log.debug "Initializing gzip stream deflator"
|
102
105
|
GzipInflater.new
|
103
106
|
when DEFLATE
|
104
|
-
Chef::Log.debug "
|
107
|
+
Chef::Log.debug "Initializing deflate stream deflator"
|
105
108
|
DeflateInflater.new
|
106
109
|
else
|
110
|
+
Chef::Log.debug "content_encoding = '#{response[CONTENT_ENCODING]}' \
|
111
|
+
initializing noop stream deflator."
|
107
112
|
NoopInflater.new
|
108
113
|
end
|
109
114
|
end
|
@@ -137,5 +142,3 @@ class Chef
|
|
137
142
|
end
|
138
143
|
end
|
139
144
|
end
|
140
|
-
|
141
|
-
|
data/lib/chef/http/simple.rb
CHANGED
@@ -49,22 +49,20 @@ class Chef
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def handle_response(http_response, rest_request, return_value)
|
52
|
-
|
53
|
-
Chef::Log.debug("HTTP server did not include a Content-Length header in response, cannot identify truncated downloads.")
|
54
|
-
return [http_response, rest_request, return_value]
|
55
|
-
end
|
56
|
-
validate(response_content_length(http_response), http_response.body.bytesize)
|
52
|
+
validate(http_response, http_response.body.bytesize) if http_response && http_response.body
|
57
53
|
return [http_response, rest_request, return_value]
|
58
54
|
end
|
59
55
|
|
60
56
|
def handle_stream_complete(http_response, rest_request, return_value)
|
61
|
-
if
|
62
|
-
Chef::Log.debug("HTTP server did not include a Content-Length header in response, cannot idenfity streamed download.")
|
63
|
-
elsif @content_length_counter.nil?
|
57
|
+
if @content_length_counter.nil?
|
64
58
|
Chef::Log.debug("No content-length information collected for the streamed download, cannot identify streamed download.")
|
65
59
|
else
|
66
|
-
validate(
|
60
|
+
validate(http_response, @content_length_counter.content_length)
|
67
61
|
end
|
62
|
+
|
63
|
+
# Make sure the counter is reset since this object might get used
|
64
|
+
# again. See CHEF-5100
|
65
|
+
@content_length_counter = nil
|
68
66
|
return [http_response, rest_request, return_value]
|
69
67
|
end
|
70
68
|
|
@@ -73,7 +71,9 @@ class Chef
|
|
73
71
|
end
|
74
72
|
|
75
73
|
private
|
74
|
+
|
76
75
|
def response_content_length(response)
|
76
|
+
return nil if response['content-length'].nil?
|
77
77
|
if response['content-length'].is_a?(Array)
|
78
78
|
response['content-length'].first.to_i
|
79
79
|
else
|
@@ -81,12 +81,28 @@ class Chef
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
def validate(
|
85
|
-
|
86
|
-
|
84
|
+
def validate(http_response, response_length)
|
85
|
+
content_length = response_content_length(http_response)
|
86
|
+
transfer_encoding = http_response['transfer-encoding']
|
87
|
+
content_encoding = http_response['content-encoding']
|
88
|
+
|
89
|
+
if content_length.nil?
|
90
|
+
Chef::Log.debug "HTTP server did not include a Content-Length header in response, cannot identify truncated downloads."
|
91
|
+
return true
|
92
|
+
end
|
93
|
+
|
94
|
+
# if Transfer-Encoding is set the RFC states that we must ignore the Content-Length field
|
95
|
+
# CHEF-5041: some proxies uncompress gzip content, leave the incorrect content-length, but set the transfer-encoding field
|
96
|
+
unless transfer_encoding.nil?
|
97
|
+
Chef::Log.debug "Transfer-Encoding header is set, skipping Content-Length check."
|
98
|
+
return true
|
99
|
+
end
|
100
|
+
|
87
101
|
if response_length != content_length
|
88
102
|
raise Chef::Exceptions::ContentLengthMismatch.new(response_length, content_length)
|
89
103
|
end
|
104
|
+
|
105
|
+
Chef::Log.debug "Content-Length validated correctly."
|
90
106
|
true
|
91
107
|
end
|
92
108
|
end
|
data/lib/chef/knife.rb
CHANGED
@@ -421,6 +421,7 @@ class Chef
|
|
421
421
|
|
422
422
|
# Don't try to load a knife.rb if it wasn't specified.
|
423
423
|
if config[:config_file]
|
424
|
+
Chef::Config.config_file = config[:config_file]
|
424
425
|
fetcher = Chef::ConfigFetcher.new(config[:config_file], Chef::Config.config_file_jail)
|
425
426
|
if fetcher.config_missing?
|
426
427
|
ui.error("Specified config file #{config[:config_file]} does not exist#{Chef::Config.config_file_jail ? " or is not under config file jail #{Chef::Config.config_file_jail}" : ""}!")
|
@@ -27,6 +27,11 @@ class Chef
|
|
27
27
|
require 'chef/json_compat'
|
28
28
|
end
|
29
29
|
|
30
|
+
option :delete_validators,
|
31
|
+
:short => "-D",
|
32
|
+
:long => "--delete-validators",
|
33
|
+
:description => "Force deletion of clients if they're validators"
|
34
|
+
|
30
35
|
banner "knife client bulk delete REGEX (options)"
|
31
36
|
|
32
37
|
def run
|
@@ -38,28 +43,62 @@ class Chef
|
|
38
43
|
|
39
44
|
matcher = /#{name_args[0]}/
|
40
45
|
clients_to_delete = {}
|
46
|
+
validators_to_delete = {}
|
41
47
|
all_clients.each do |name, client|
|
42
48
|
next unless name =~ matcher
|
43
|
-
|
49
|
+
if client.validator
|
50
|
+
validators_to_delete[client.name] = client
|
51
|
+
else
|
52
|
+
clients_to_delete[client.name] = client
|
53
|
+
end
|
44
54
|
end
|
45
55
|
|
46
|
-
if clients_to_delete.empty?
|
56
|
+
if clients_to_delete.empty? && validators_to_delete.empty?
|
47
57
|
ui.info "No clients match the expression /#{name_args[0]}/"
|
48
58
|
exit 0
|
49
59
|
end
|
50
60
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
ui.msg("")
|
55
|
-
ui.confirm("Are you sure you want to delete these clients")
|
61
|
+
check_and_delete_validators(validators_to_delete)
|
62
|
+
check_and_delete_clients(clients_to_delete)
|
63
|
+
end
|
56
64
|
|
57
|
-
|
65
|
+
def check_and_delete_validators(validators)
|
66
|
+
unless validators.empty?
|
67
|
+
unless config[:delete_validators]
|
68
|
+
ui.msg("Following clients are validators and will not be deleted.")
|
69
|
+
print_clients(validators)
|
70
|
+
ui.msg("You must specify --delete-validators to delete the validator clients")
|
71
|
+
else
|
72
|
+
ui.msg("The following validators will be deleted:")
|
73
|
+
print_clients(validators)
|
74
|
+
if ui.confirm_without_exit("Are you sure you want to delete these validators")
|
75
|
+
destroy_clients(validators)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def check_and_delete_clients(clients)
|
82
|
+
unless clients.empty?
|
83
|
+
ui.msg("The following clients will be deleted:")
|
84
|
+
print_clients(clients)
|
85
|
+
ui.confirm("Are you sure you want to delete these clients")
|
86
|
+
destroy_clients(clients)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def destroy_clients(clients)
|
91
|
+
clients.sort.each do |name, client|
|
58
92
|
client.destroy
|
59
93
|
ui.msg("Deleted client #{name}")
|
60
94
|
end
|
61
95
|
end
|
96
|
+
|
97
|
+
def print_clients(clients)
|
98
|
+
ui.msg("")
|
99
|
+
ui.msg(ui.list(clients.keys.sort, :columns_down))
|
100
|
+
ui.msg("")
|
101
|
+
end
|
62
102
|
end
|
63
103
|
end
|
64
104
|
end
|
65
|
-
|
@@ -27,9 +27,9 @@ class Chef
|
|
27
27
|
require 'chef/json_compat'
|
28
28
|
end
|
29
29
|
|
30
|
-
option :
|
31
|
-
:short => "-
|
32
|
-
:long => "--
|
30
|
+
option :delete_validators,
|
31
|
+
:short => "-D",
|
32
|
+
:long => "--delete-validators",
|
33
33
|
:description => "Force deletion of client if it's a validator"
|
34
34
|
|
35
35
|
banner "knife client delete CLIENT (options)"
|
@@ -46,7 +46,7 @@ class Chef
|
|
46
46
|
delete_object(Chef::ApiClient, @client_name, 'client') {
|
47
47
|
object = Chef::ApiClient.load(@client_name)
|
48
48
|
if object.validator
|
49
|
-
unless config[:
|
49
|
+
unless config[:delete_validators]
|
50
50
|
ui.fatal("You must specify --force to delete the validator client #{@client_name}")
|
51
51
|
exit 2
|
52
52
|
end
|
@@ -49,7 +49,7 @@ class Chef
|
|
49
49
|
ui.msg ""
|
50
50
|
|
51
51
|
unless config[:yes]
|
52
|
-
ui.confirm("Do you really want to delete these cookbooks
|
52
|
+
ui.confirm("Do you really want to delete these cookbooks")
|
53
53
|
|
54
54
|
if config[:purge]
|
55
55
|
ui.msg("Files that are common to multiple cookbooks are shared, so purging the files may break other cookbooks.")
|
@@ -93,6 +93,7 @@ class Chef
|
|
93
93
|
end
|
94
94
|
|
95
95
|
assert_environment_valid!
|
96
|
+
warn_about_cookbook_shadowing
|
96
97
|
version_constraints_to_update = {}
|
97
98
|
upload_failures = 0
|
98
99
|
upload_ok = 0
|
@@ -139,6 +140,7 @@ class Chef
|
|
139
140
|
end
|
140
141
|
end
|
141
142
|
|
143
|
+
|
142
144
|
upload_failures += @name_args.length - @cookbooks_to_upload.length
|
143
145
|
|
144
146
|
if upload_failures == 0
|
@@ -199,6 +201,10 @@ class Chef
|
|
199
201
|
end
|
200
202
|
|
201
203
|
def warn_about_cookbook_shadowing
|
204
|
+
# because cookbooks are lazy-loaded, we have to force the loader
|
205
|
+
# to load the cookbooks the user intends to upload here:
|
206
|
+
cookbooks_to_upload
|
207
|
+
|
202
208
|
unless cookbook_repo.merged_cookbooks.empty?
|
203
209
|
ui.warn "* " * 40
|
204
210
|
ui.warn(<<-WARNING)
|
@@ -257,14 +263,18 @@ WARNING
|
|
257
263
|
end
|
258
264
|
|
259
265
|
def check_for_dependencies!(cookbook)
|
260
|
-
# for
|
266
|
+
# for all dependencies, check if the version is on the server, or
|
261
267
|
# the version is in the cookbooks being uploaded. If not, exit and warn the user.
|
262
|
-
cookbook.metadata.dependencies.
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
+
missing_dependencies = cookbook.metadata.dependencies.reject do |cookbook_name, version|
|
269
|
+
check_server_side_cookbooks(cookbook_name, version) || check_uploading_cookbooks(cookbook_name, version)
|
270
|
+
end
|
271
|
+
|
272
|
+
unless missing_dependencies.empty?
|
273
|
+
missing_cookbook_names = missing_dependencies.map { |cookbook_name, version| "'#{cookbook_name}' version '#{version}'"}
|
274
|
+
ui.error "Cookbook #{cookbook.name} depends on cookbooks which are not currently"
|
275
|
+
ui.error "being uploaded and cannot be found on the server."
|
276
|
+
ui.error "The missing cookbook(s) are: #{missing_cookbook_names.join(', ')}"
|
277
|
+
exit 1
|
268
278
|
end
|
269
279
|
end
|
270
280
|
|