knife 17.2.18 → 17.4.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/knife.gemspec +2 -0
- data/lib/chef/knife/bootstrap.rb +3 -0
- data/lib/chef/knife/bootstrap/train_connector.rb +3 -3
- data/lib/chef/knife/client_create.rb +21 -0
- data/lib/chef/knife/core/bootstrap_context.rb +4 -4
- data/lib/chef/knife/core/windows_bootstrap_context.rb +4 -4
- data/lib/chef/knife/ssh.rb +29 -17
- data/lib/chef/knife/supermarket_unshare.rb +2 -1
- data/lib/chef/knife/version.rb +1 -1
- data/spec/data/knife/temp_dir/tmp.pem +0 -0
- data/spec/integration/client_create_spec.rb +1 -0
- data/spec/integration/commands_spec.rb +55 -0
- data/spec/integration/cookbook_download_spec.rb +1 -1
- data/spec/unit/knife/bootstrap_spec.rb +14 -1
- data/spec/unit/knife/client_create_spec.rb +37 -2
- data/spec/unit/knife/core/bootstrap_context_spec.rb +6 -6
- data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +5 -5
- data/spec/unit/knife/ssh_spec.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70c4e18afa9b4762387d8a0a6c9c75bca9e1e42723a041147bea36c2efaae176
|
4
|
+
data.tar.gz: '00953cd3c86ab1e11eb9ddb9a8fdf8fffbae40705671090169411877fa72a069'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2d2130d599b56a3d43bbbbe5f64407dfc19aaec9df4ea87af2b835b950dda18ef1b9eb6cee28fae9ee05bafef8b6fe180219b36f1f7fbe5333b4efcd3236002
|
7
|
+
data.tar.gz: 0d500fcfd9e9aa0830d04bae3f9d4e3712ab52bf6fcd9b87c4f0e3bbb2149f8568d179c41656189b7614bdbdd91e8dbd5d14800c38771275466c5e3c9e0c78f0
|
data/knife.gemspec
CHANGED
@@ -30,6 +30,8 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_dependency "net-ssh-multi", "~> 1.2", ">= 1.2.1"
|
31
31
|
s.add_dependency "ed25519", "~> 1.2" # ed25519 ssh key support
|
32
32
|
s.add_dependency "bcrypt_pbkdf", "~> 1.1" # ed25519 ssh key support
|
33
|
+
# we can't use this gem until illegal instruction issues are resolved
|
34
|
+
# s.add_dependency "x25519" # ed25519 KEX module
|
33
35
|
s.add_dependency "highline", ">= 1.6.9", "< 3" # Used in UI to present a list, no other usage.
|
34
36
|
|
35
37
|
s.add_dependency "tty-prompt", "~> 0.21" # knife ui.ask prompt
|
data/lib/chef/knife/bootstrap.rb
CHANGED
@@ -20,6 +20,7 @@ require_relative "../knife"
|
|
20
20
|
require_relative "data_bag_secret_options"
|
21
21
|
require "chef-utils/dist" unless defined?(ChefUtils::Dist)
|
22
22
|
require "license_acceptance/cli_flags/mixlib_cli"
|
23
|
+
|
23
24
|
module LicenseAcceptance
|
24
25
|
autoload :Acceptor, "license_acceptance/acceptor"
|
25
26
|
end
|
@@ -705,6 +706,8 @@ class Chef
|
|
705
706
|
ui.warn("#{e.message} - trying with pty request")
|
706
707
|
conn_options[:pty] = true # ensure we can talk to systems with requiretty set true in sshd config
|
707
708
|
retry
|
709
|
+
elsif e.reason == :sudo_missing_terminal
|
710
|
+
ui.error "Sudo password is required for this operation. Please enter password using -P or --ssh-password option"
|
708
711
|
elsif config[:use_sudo_password] && (e.reason == :sudo_password_required || e.reason == :bad_sudo_password) && limit < 3
|
709
712
|
ui.warn("Failed to authenticate #{conn_options[:user]} to #{server_name} - #{e.message} \n sudo: #{limit} incorrect password attempt")
|
710
713
|
sudo_password = ui.ask("Enter sudo password for #{conn_options[:user]}@#{server_name}:", echo: false)
|
@@ -240,7 +240,7 @@ class Chef
|
|
240
240
|
|
241
241
|
# Now that everything is populated, fill in anything missing
|
242
242
|
# that may be found in user ssh config
|
243
|
-
opts.merge!(missing_opts_from_ssh_config(opts
|
243
|
+
opts.merge!(missing_opts_from_ssh_config(opts))
|
244
244
|
|
245
245
|
Train.target_config(opts)
|
246
246
|
end
|
@@ -297,12 +297,12 @@ class Chef
|
|
297
297
|
# in the configuration passed in.
|
298
298
|
# This is necessary because train will default these values
|
299
299
|
# itself - causing SSH config data to be ignored
|
300
|
-
def missing_opts_from_ssh_config(config
|
300
|
+
def missing_opts_from_ssh_config(config)
|
301
301
|
return {} unless config[:backend] == "ssh"
|
302
302
|
|
303
303
|
host_cfg = ssh_config_for_host(config[:host])
|
304
304
|
opts_out = {}
|
305
|
-
|
305
|
+
host_cfg.each do |key, _value|
|
306
306
|
if SSH_CONFIG_OVERRIDE_KEYS.include?(key) && !config.key?(key)
|
307
307
|
opts_out[key] = host_cfg[key]
|
308
308
|
end
|
@@ -81,6 +81,14 @@ class Chef
|
|
81
81
|
client.public_key File.read(File.expand_path(config[:public_key]))
|
82
82
|
end
|
83
83
|
|
84
|
+
# Check the file before creating the client so the api is more transactional.
|
85
|
+
if config[:file]
|
86
|
+
file = config[:file]
|
87
|
+
dir_name = File.dirname(file)
|
88
|
+
check_writable_or_exists(dir_name, "Directory")
|
89
|
+
check_writable_or_exists(file, "File")
|
90
|
+
end
|
91
|
+
|
84
92
|
output = edit_hash(client)
|
85
93
|
final_client = create_client(output)
|
86
94
|
ui.info("Created #{final_client}")
|
@@ -96,6 +104,19 @@ class Chef
|
|
96
104
|
end
|
97
105
|
end
|
98
106
|
end
|
107
|
+
|
108
|
+
# To check if file or directory exists or writable and raise exception accordingly
|
109
|
+
def check_writable_or_exists(file, type)
|
110
|
+
if File.exist?(file)
|
111
|
+
unless File.writable?(file)
|
112
|
+
ui.fatal "#{type} #{file} is not writable. Check permissions."
|
113
|
+
exit 1
|
114
|
+
end
|
115
|
+
else
|
116
|
+
ui.fatal "#{type} #{file} does not exist."
|
117
|
+
exit 1
|
118
|
+
end
|
119
|
+
end
|
99
120
|
end
|
100
121
|
end
|
101
122
|
end
|
@@ -171,12 +171,12 @@ class Chef
|
|
171
171
|
client_rb << "fips true\n"
|
172
172
|
end
|
173
173
|
|
174
|
-
unless chef_config[:
|
175
|
-
client_rb << "file_cache_path \"#{chef_config[:
|
174
|
+
unless chef_config[:unix_bootstrap_file_cache_path].nil?
|
175
|
+
client_rb << "file_cache_path \"#{chef_config[:unix_bootstrap_file_cache_path]}\"\n"
|
176
176
|
end
|
177
177
|
|
178
|
-
unless chef_config[:
|
179
|
-
client_rb << "file_backup_path \"#{chef_config[:
|
178
|
+
unless chef_config[:unix_bootstrap_file_backup_path].nil?
|
179
|
+
client_rb << "file_backup_path \"#{chef_config[:unix_bootstrap_file_backup_path]}\"\n"
|
180
180
|
end
|
181
181
|
|
182
182
|
client_rb
|
@@ -71,8 +71,8 @@ class Chef
|
|
71
71
|
client_rb = <<~CONFIG
|
72
72
|
chef_server_url "#{chef_config[:chef_server_url]}"
|
73
73
|
validation_client_name "#{chef_config[:validation_client_name]}"
|
74
|
-
file_cache_path "#{ChefConfig::PathHelper.escapepath(
|
75
|
-
file_backup_path "#{ChefConfig::PathHelper.escapepath(
|
74
|
+
file_cache_path "#{ChefConfig::PathHelper.escapepath(chef_config[:windows_bootstrap_file_cache_path] || "")}"
|
75
|
+
file_backup_path "#{ChefConfig::PathHelper.escapepath(chef_config[:windows_bootstrap_file_backup_path] || "")}"
|
76
76
|
cache_options ({:path => "#{ChefConfig::PathHelper.escapepath(ChefConfig::Config.etc_chef_dir(windows: true))}\\\\cache\\\\checksums", :skip_expires => true})
|
77
77
|
CONFIG
|
78
78
|
|
@@ -86,8 +86,8 @@ class Chef
|
|
86
86
|
client_rb << "# Using default node name (fqdn)\n"
|
87
87
|
end
|
88
88
|
|
89
|
-
if
|
90
|
-
client_rb << %Q{log_level :#{
|
89
|
+
if chef_config[:config_log_level]
|
90
|
+
client_rb << %Q{log_level :#{chef_config[:config_log_level]}\n}
|
91
91
|
else
|
92
92
|
client_rb << "log_level :auto\n"
|
93
93
|
end
|
data/lib/chef/knife/ssh.rb
CHANGED
@@ -134,6 +134,18 @@ class Chef
|
|
134
134
|
boolean: true,
|
135
135
|
default: false
|
136
136
|
|
137
|
+
option :pty,
|
138
|
+
long: "--[no-]pty",
|
139
|
+
description: "Request a PTY, enabled by default.",
|
140
|
+
boolean: true,
|
141
|
+
default: true
|
142
|
+
|
143
|
+
option :require_pty,
|
144
|
+
long: "--[no-]require-pty",
|
145
|
+
description: "Raise exception if a PTY cannot be acquired, disabled by default.",
|
146
|
+
boolean: true,
|
147
|
+
default: false
|
148
|
+
|
137
149
|
def session
|
138
150
|
ssh_error_handler = Proc.new do |server|
|
139
151
|
if config[:on_error]
|
@@ -353,26 +365,26 @@ class Chef
|
|
353
365
|
ui.msg(str)
|
354
366
|
end
|
355
367
|
|
356
|
-
|
368
|
+
# @param command [String] the command to run
|
369
|
+
# @param session_list [???] list of sessions, one per node
|
370
|
+
#
|
371
|
+
def ssh_command(command, session_list = session)
|
372
|
+
stderr = ""
|
357
373
|
exit_status = 0
|
358
|
-
subsession ||= session
|
359
374
|
command = fixup_sudo(command)
|
360
375
|
command.force_encoding("binary") if command.respond_to?(:force_encoding)
|
361
|
-
|
362
|
-
open_session(subsession, command)
|
363
|
-
rescue => e
|
364
|
-
open_session(subsession, command, true)
|
365
|
-
end
|
366
|
-
end
|
367
|
-
|
368
|
-
def open_session(subsession, command, pty = false)
|
369
|
-
stderr = ""
|
370
|
-
exit_status = 0
|
371
|
-
subsession.open_channel do |chan|
|
376
|
+
session_list.open_channel do |chan|
|
372
377
|
if config[:on_error] && exit_status != 0
|
373
378
|
chan.close
|
374
379
|
else
|
375
|
-
|
380
|
+
if config[:pty]
|
381
|
+
chan.request_pty do |ch, success|
|
382
|
+
unless success
|
383
|
+
ui.warn("Failed to obtain a PTY from #{ch.connection.host}")
|
384
|
+
raise ArgumentError, "Request for PTY failed" if config[:require_pty]
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
376
388
|
chan.exec command do |ch, success|
|
377
389
|
raise ArgumentError, "Cannot execute #{command}" unless success
|
378
390
|
|
@@ -383,13 +395,11 @@ class Chef
|
|
383
395
|
ichannel.send_data("#{get_password}\n")
|
384
396
|
end
|
385
397
|
end
|
386
|
-
|
387
398
|
ch.on_extended_data do |_, _type, data|
|
388
|
-
raise ArgumentError if data.eql?("sudo: no tty present and no askpass program specified\n")
|
399
|
+
raise ArgumentError, "No PTY present. If a PTY is required use --require-pty" if data.eql?("sudo: no tty present and no askpass program specified\n")
|
389
400
|
|
390
401
|
stderr += data
|
391
402
|
end
|
392
|
-
|
393
403
|
ch.on_request "exit-status" do |ichannel, data|
|
394
404
|
exit_status = [exit_status, data.read_long].max
|
395
405
|
end
|
@@ -398,6 +408,8 @@ class Chef
|
|
398
408
|
end
|
399
409
|
session.loop
|
400
410
|
exit_status
|
411
|
+
ensure
|
412
|
+
session_list.close
|
401
413
|
end
|
402
414
|
|
403
415
|
def get_password
|
@@ -50,7 +50,8 @@ class Chef
|
|
50
50
|
rescue Net::HTTPClientException => e
|
51
51
|
raise e unless /Forbidden/.match?(e.message)
|
52
52
|
|
53
|
-
ui.error "Forbidden: You must be the maintainer of #{@cookbook_name} to unshare it."
|
53
|
+
ui.error "Forbidden: You must be the maintainer of #{@cookbook_name} to unshare it & #{config[:supermarket_site]} must allow maintainers to unshare cookbooks."
|
54
|
+
ui.warn "The default supermarket #{default_config[:supermarket_site]} does not allow maintainers to unshare cookbooks."
|
54
55
|
exit 1
|
55
56
|
end
|
56
57
|
|
data/lib/chef/knife/version.rb
CHANGED
File without changes
|
@@ -50,6 +50,7 @@ describe "knife client create", :workstation do
|
|
50
50
|
|
51
51
|
it "saves the private key to a file" do
|
52
52
|
Dir.mktmpdir do |tgt|
|
53
|
+
File.open("#{tgt}/bah.pem", "w") { |pub| pub.write("test key") }
|
53
54
|
knife("client create -f #{tgt}/bah.pem bah").should_succeed stderr: out
|
54
55
|
expect(File).to exist("#{tgt}/bah.pem")
|
55
56
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Marc Pardise (<marc@chef.io>)
|
3
|
+
# Copyright:: Copyright (c) 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
|
+
require "chef/knife"
|
19
|
+
|
20
|
+
Chef::Knife.subcommand_loader.load_commands
|
21
|
+
commands = Chef::Knife::SubcommandLoader.generate_hash["_autogenerated_command_paths"]["plugins_paths"].keys
|
22
|
+
|
23
|
+
# Directly execute each support knife command
|
24
|
+
context "Command Sanity Check: executing ", :workstation do
|
25
|
+
describe "bundle exec knife" do
|
26
|
+
commands.each do |command|
|
27
|
+
command_name = command.gsub("_", " ")
|
28
|
+
modified_command, expected_result = case command_name
|
29
|
+
when /knife/
|
30
|
+
# because rspec is the actual executable running, the option parser error message
|
31
|
+
# is invalid from within the test.
|
32
|
+
next
|
33
|
+
when /config (use|get|list) profile.*/
|
34
|
+
# hyphenated special cases
|
35
|
+
[command_name, /^USAGE: knife config #{$1}-profile.*/]
|
36
|
+
when /(role|node|env) (env )?run list(.*)/
|
37
|
+
# underscored special cases...
|
38
|
+
env_part = $2.nil? ? "" : "env_"
|
39
|
+
["#{$1} #{$2}run_list#{$3}", /^USAGE: knife #{$1} #{env_part}run_list#{$3}.*/]
|
40
|
+
else
|
41
|
+
[ command_name, /^USAGE: knife #{command_name}.*/]
|
42
|
+
end
|
43
|
+
|
44
|
+
# By using bundle exec knife instead of directly loading the command class or using the knife() helper,
|
45
|
+
# we ensure that this is a valid end-to-end test. This operates on the assumption
|
46
|
+
# that we continue to require the command class to be fully loaded so that it can handle the parsing of
|
47
|
+
# its own options.
|
48
|
+
full_command = "#{modified_command} --invalid-option outputs usage for '#{modified_command}' to stdout"
|
49
|
+
it full_command do
|
50
|
+
result = `bundle exec knife #{full_command}`
|
51
|
+
expect(result).to match(expected_result)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -1307,7 +1307,7 @@ describe Chef::Knife::Bootstrap do
|
|
1307
1307
|
context "when no identity file is specified" do
|
1308
1308
|
it "generates the expected configuration (no keys, keys_only false)" do
|
1309
1309
|
expect(knife.ssh_identity_opts).to eq( {
|
1310
|
-
key_files: [
|
1310
|
+
key_files: [],
|
1311
1311
|
keys_only: false,
|
1312
1312
|
})
|
1313
1313
|
end
|
@@ -2050,6 +2050,19 @@ describe Chef::Knife::Bootstrap do
|
|
2050
2050
|
expect { knife.do_connect({}) }.to raise_error(expected_error)
|
2051
2051
|
end
|
2052
2052
|
end
|
2053
|
+
|
2054
|
+
context "when a train sudo error is thrown for missing terminal" do
|
2055
|
+
let(:ui_error_msg) { "Sudo password is required for this operation. Please enter password using -P or --ssh-password option" }
|
2056
|
+
let(:expected_error) { Train::UserError.new(ui_error_msg, :sudo_missing_terminal) }
|
2057
|
+
before do
|
2058
|
+
allow(connection).to receive(:connect!).and_raise(expected_error)
|
2059
|
+
end
|
2060
|
+
it "outputs user friendly error message" do
|
2061
|
+
expect { knife.do_connect({}) }.not_to raise_error
|
2062
|
+
expect(stderr.string).to include(ui_error_msg)
|
2063
|
+
end
|
2064
|
+
end
|
2065
|
+
|
2053
2066
|
end
|
2054
2067
|
|
2055
2068
|
describe "validate_winrm_transport_opts!" do
|
@@ -122,10 +122,12 @@ describe Chef::Knife::ClientCreate do
|
|
122
122
|
end
|
123
123
|
|
124
124
|
it "should write the private key to a file" do
|
125
|
-
|
125
|
+
file = Tempfile.new
|
126
|
+
file_path = file.path
|
127
|
+
knife.config[:file] = file_path
|
126
128
|
filehandle = double("Filehandle")
|
127
129
|
expect(filehandle).to receive(:print).with("woot")
|
128
|
-
expect(File).to receive(:open).with(
|
130
|
+
expect(File).to receive(:open).with(file_path, "w").and_yield(filehandle)
|
129
131
|
knife.run
|
130
132
|
end
|
131
133
|
end
|
@@ -164,6 +166,39 @@ describe Chef::Knife::ClientCreate do
|
|
164
166
|
expect(client.validator).to be_truthy
|
165
167
|
end
|
166
168
|
end
|
169
|
+
|
170
|
+
describe "with -f or --file when dir or file is not writable or does not exists" do
|
171
|
+
let(:dir_path) { File.expand_path(File.join(CHEF_SPEC_DATA, "knife", "temp_dir")) }
|
172
|
+
let(:file_path) { File.expand_path(File.join(dir_path, "tmp.pem")) }
|
173
|
+
|
174
|
+
it "when the directory does not exists" do
|
175
|
+
knife.config[:file] = "example/client1.pem"
|
176
|
+
expect(knife.ui).to receive(:fatal).with("Directory example does not exist.")
|
177
|
+
expect { knife.run }.to raise_error(SystemExit)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "when the directory not writable" do
|
181
|
+
knife.config[:file] = file_path
|
182
|
+
File.chmod(777, dir_path)
|
183
|
+
expect(knife.ui).to receive(:fatal).with("Directory #{dir_path} is not writable. Check permissions.")
|
184
|
+
expect { knife.run }.to raise_error(SystemExit)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "when the file does not exists" do
|
188
|
+
path = "#{dir_path}/client1.pem"
|
189
|
+
knife.config[:file] = path
|
190
|
+
File.chmod(0755, dir_path)
|
191
|
+
expect(knife.ui).to receive(:fatal).with("File #{path} does not exist.")
|
192
|
+
expect { knife.run }.to raise_error(SystemExit)
|
193
|
+
end
|
194
|
+
|
195
|
+
it "when the file is not writable" do
|
196
|
+
knife.config[:file] = file_path
|
197
|
+
File.chmod(777, file_path)
|
198
|
+
expect(knife.ui).to receive(:fatal).with("File #{file_path} is not writable. Check permissions.")
|
199
|
+
expect { knife.run }.to raise_error(SystemExit)
|
200
|
+
end
|
201
|
+
end
|
167
202
|
end
|
168
203
|
end
|
169
204
|
end
|
@@ -80,16 +80,16 @@ describe Chef::Knife::Core::BootstrapContext do
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
describe "when
|
84
|
-
let(:chef_config) { {
|
85
|
-
it "sets
|
83
|
+
describe "when unix_bootstrap_file_cache_path is set" do
|
84
|
+
let(:chef_config) { { unix_bootstrap_file_cache_path: "/home/opscode/cache" } }
|
85
|
+
it "sets unix_bootstrap_file_cache_path in the generated config file" do
|
86
86
|
expect(bootstrap_context.config_content).to include("file_cache_path \"/home/opscode/cache\"")
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
describe "when
|
91
|
-
let(:chef_config) { {
|
92
|
-
it "sets
|
90
|
+
describe "when unix_bootstrap_file_backup_path is set" do
|
91
|
+
let(:chef_config) { { unix_bootstrap_file_backup_path: "/home/opscode/backup" } }
|
92
|
+
it "sets unix_bootstrap_file_backup_path in the generated config file" do
|
93
93
|
expect(bootstrap_context.config_content).to include("file_backup_path \"/home/opscode/backup\"")
|
94
94
|
end
|
95
95
|
end
|
@@ -154,8 +154,8 @@ describe Chef::Knife::Core::WindowsBootstrapContext do
|
|
154
154
|
config_log_location: STDOUT,
|
155
155
|
chef_server_url: "http://chef.example.com:4444",
|
156
156
|
validation_client_name: "chef-validator-testing",
|
157
|
-
|
158
|
-
|
157
|
+
windows_bootstrap_file_cache_path: "c:/chef/cache",
|
158
|
+
windows_bootstrap_file_backup_path: "c:/chef/backup",
|
159
159
|
cache_options: ({ path: "c:/chef/cache/checksums", skip_expires: true })
|
160
160
|
)
|
161
161
|
)
|
@@ -165,11 +165,11 @@ describe Chef::Knife::Core::WindowsBootstrapContext do
|
|
165
165
|
expected = <<~EXPECTED
|
166
166
|
echo.chef_server_url "http://chef.example.com:4444"
|
167
167
|
echo.validation_client_name "chef-validator-testing"
|
168
|
-
echo.file_cache_path "
|
169
|
-
echo.file_backup_path "
|
168
|
+
echo.file_cache_path "c:/chef/cache"
|
169
|
+
echo.file_backup_path "c:/chef/backup"
|
170
170
|
echo.cache_options ^({:path =^> "C:\\\\chef\\\\cache\\\\checksums", :skip_expires =^> true}^)
|
171
171
|
echo.# Using default node name ^(fqdn^)
|
172
|
-
echo.log_level
|
172
|
+
echo.log_level :info
|
173
173
|
echo.log_location STDOUT
|
174
174
|
EXPECTED
|
175
175
|
expect(bootstrap_context.config_content).to eq expected
|
data/spec/unit/knife/ssh_spec.rb
CHANGED
@@ -289,7 +289,7 @@ describe Chef::Knife::Ssh do
|
|
289
289
|
let(:execution_channel2) { double(:execution_channel, on_data: nil, on_extended_data: nil) }
|
290
290
|
let(:session_channel2) { double(:session_channel, request_pty: nil) }
|
291
291
|
|
292
|
-
let(:session) { double(:session, loop: nil) }
|
292
|
+
let(:session) { double(:session, loop: nil, close: nil) }
|
293
293
|
|
294
294
|
let(:command) { "false" }
|
295
295
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 17.
|
4
|
+
version: 17.4.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Jacob
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-config
|
@@ -751,6 +751,7 @@ files:
|
|
751
751
|
- spec/data/kitchen/openldap/recipes/woot.rb
|
752
752
|
- spec/data/knife-home/.chef/plugins/knife/example_home_subcommand.rb
|
753
753
|
- spec/data/knife-site-subcommands/plugins/knife/example_subcommand.rb
|
754
|
+
- spec/data/knife/temp_dir/tmp.pem
|
754
755
|
- spec/data/knife_subcommand/test_explicit_category.rb
|
755
756
|
- spec/data/knife_subcommand/test_name_mapping.rb
|
756
757
|
- spec/data/knife_subcommand/test_yourself.rb
|
@@ -950,6 +951,7 @@ files:
|
|
950
951
|
- spec/integration/client_key_show_spec.rb
|
951
952
|
- spec/integration/client_list_spec.rb
|
952
953
|
- spec/integration/client_show_spec.rb
|
954
|
+
- spec/integration/commands_spec.rb
|
953
955
|
- spec/integration/common_options_spec.rb
|
954
956
|
- spec/integration/config_list_spec.rb
|
955
957
|
- spec/integration/config_show_spec.rb
|
@@ -1148,7 +1150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1148
1150
|
- !ruby/object:Gem::Version
|
1149
1151
|
version: '0'
|
1150
1152
|
requirements: []
|
1151
|
-
rubygems_version: 3.2.
|
1153
|
+
rubygems_version: 3.2.22
|
1152
1154
|
signing_key:
|
1153
1155
|
specification_version: 4
|
1154
1156
|
summary: The knife CLI for Chef Infra.
|