diff options
-rw-r--r-- | lib/chef/knife/bootstrap/train_connector.rb | 35 | ||||
-rw-r--r-- | spec/unit/knife/bootstrap/train_connector_spec.rb | 21 |
2 files changed, 32 insertions, 24 deletions
diff --git a/lib/chef/knife/bootstrap/train_connector.rb b/lib/chef/knife/bootstrap/train_connector.rb index 8487116f08..a3611470d1 100644 --- a/lib/chef/knife/bootstrap/train_connector.rb +++ b/lib/chef/knife/bootstrap/train_connector.rb @@ -18,6 +18,7 @@ require "train" require "tempfile" unless defined?(Tempfile) require "uri" unless defined?(URI) +require "securerandom" unless defined?(SecureRandom) class Chef class Knife @@ -32,7 +33,7 @@ class Chef $tmp.FullName EOM - MKTEMP_NIX_COMMAND ||= "bash -c 'd=$(mktemp -d ${TMPDIR:-/tmp}/chef_XXXXXX); echo $d'".freeze + DEFAULT_REMOTE_TEMP ||= "/tmp".freeze def initialize(host_url, default_protocol, opts) @host_url = host_url @@ -114,22 +115,24 @@ class Chef # # @return [String] the temporary path created on the remote host. def temp_dir - cmd = windows? ? MKTEMP_WIN_COMMAND : MKTEMP_NIX_COMMAND @tmpdir ||= begin - res = run_command!(cmd) - # Since pty is enabled in the connection, stderr to be merged into stdout. - # So, there are cases where unnecessary multi-line output - # is included before the result of mktemp. - dir = res.stdout.split.last - unless windows? - # Ensure that dir has the correct owner. We are possibly - # running with sudo right now - so this directory would be owned by root. - # File upload is performed over SCP as the current logged-in user, - # so we'll set ownership to ensure that works. - run_command!("chown #{config[:user]} '#{dir}'") - end - dir - end + if windows? + run_command!(MKTEMP_WIN_COMMAND).stdout.split.last + else + # Get a 6 chars string using secure random + # eg. /tmp/chef_XXXXXX. + # Use mkdir to create TEMP dir to get rid of mktemp + dir = "#{DEFAULT_REMOTE_TEMP}/chef_#{SecureRandom.alphanumeric(6)}" + cmd = "mkdir -p %s" % dir + # Ensure that dir has the correct owner. We are possibly + # running with sudo right now - so this directory would be owned by root. + # File upload is performed over SCP as the current logged-in user, + # so we'll set ownership to ensure that works. + cmd += " && sudo chown #{config[:user]} '#{dir}'" + run_command!(cmd) + dir + end + end end # diff --git a/spec/unit/knife/bootstrap/train_connector_spec.rb b/spec/unit/knife/bootstrap/train_connector_spec.rb index 52345f3cde..a2b7a571b0 100644 --- a/spec/unit/knife/bootstrap/train_connector_spec.rb +++ b/spec/unit/knife/bootstrap/train_connector_spec.rb @@ -155,21 +155,26 @@ describe Chef::Knife::Bootstrap::TrainConnector do context "under linux and unix-like" do let(:family) { "debian" } let(:name) { "ubuntu" } + let(:random) { "wScHX6" } + let(:dir) { "/tmp/chef_#{random}" } + + before do + allow(SecureRandom).to receive(:alphanumeric).with(6).and_return(random) + end + it "uses the *nix command to create the temp dir and sets ownership to logged-in user" do - expected_command = Chef::Knife::Bootstrap::TrainConnector::MKTEMP_NIX_COMMAND + expected_command = "mkdir -p #{dir} && sudo chown user1 '#{dir}'" expect(subject).to receive(:run_command!).with(expected_command) - .and_return double("result", stdout: "/a/path") - expect(subject).to receive(:run_command!).with("chown user1 '/a/path'") - expect(subject.temp_dir).to eq "/a/path" + .and_return double("result", stdout: "\r\n") + expect(subject.temp_dir).to eq(dir) end context "with noise in stderr" do it "uses the *nix command to create the temp dir and sets ownership to logged-in user" do - expected_command = Chef::Knife::Bootstrap::TrainConnector::MKTEMP_NIX_COMMAND + expected_command = "mkdir -p #{dir} && sudo chown user1 '#{dir}'" expect(subject).to receive(:run_command!).with(expected_command) - .and_return double("result", stdout: "sudo: unable to resolve host hostname.localhost\r\n" + "/a/path\r\n") - expect(subject).to receive(:run_command!).with("chown user1 '/a/path'") - expect(subject.temp_dir).to eq "/a/path" + .and_return double("result", stdout: "sudo: unable to resolve host hostname.localhost\r\n" + "#{dir}\r\n") + expect(subject.temp_dir).to eq(dir) end end end |