Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use '-o IdentityFile=' instead of '-i' #7862

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/vagrant/util/ssh.rb
Expand Up @@ -129,7 +129,11 @@ def self.exec(ssh_info, opts={})
# If we're not in plain mode and :private_key_path is set attach the private key path(s).
if !plain_mode && options[:private_key_path]
options[:private_key_path].each do |path|
command_options += ["-i", path.to_s]

# Use '-o' instead of '-i' because '-i' does not call
# percent_expand in misc.c, but '-o' does. when passing the path,
# replace '%' in the path with '%%' to escape the '%'
command_options += ["-o", "IdentityFile=%s" % [path.to_s.gsub('%', '%%')]]
end
end

Expand Down
2 changes: 1 addition & 1 deletion plugins/provisioners/ansible/provisioner/host.rb
Expand Up @@ -254,7 +254,7 @@ def prepare_ansible_ssh_args
# Multiple Private Keys
unless !config.inventory_path && @ssh_info[:private_key_path].size == 1
@ssh_info[:private_key_path].each do |key|
ssh_options << "-i '#{key}'"
ssh_options << "-o 'IdentityFile=%s'" % [ key.gsub('%', '%%') ]
end
end

Expand Down
20 changes: 17 additions & 3 deletions test/unit/plugins/provisioners/ansible/provisioner_test.rb
Expand Up @@ -643,8 +643,22 @@ def self.it_should_create_and_use_generated_inventory(with_ssh_user = true)
it "passes additional Identity Files via ANSIBLE_SSH_ARGS" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args|
cmd_opts = args.last
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-i '/an/other/identity'")
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-i '/yet/an/other/key'")
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o 'IdentityFile=/an/other/identity'")
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o 'IdentityFile=/yet/an/other/key'")
}
end
end

describe "with an identity file containing `%`" do
before do
ssh_info[:private_key_path] = ['/foo%bar/key', '/bar%%buz/key']
end

it "replaces `%` with `%%`" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args|
cmd_opts = args.last
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o 'IdentityFile=/foo%%bar/key'")
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o 'IdentityFile=/bar%%%%buz/key'")
}
end
end
Expand Down Expand Up @@ -871,7 +885,7 @@ def self.it_should_create_and_use_generated_inventory(with_ssh_user = true)

it "shows the ansible-playbook command, with additional quotes when required" do
expect(machine.env.ui).to receive(:detail).with { |full_command|
expect(full_command).to eq(%Q(PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_ROLES_PATH='/up/to the stars' ANSIBLE_HOST_KEY_CHECKING=true ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes -i '/my/key1' -i '/my/key2' -o ForwardAgent=yes -o ControlMaster=no -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --connection=ssh --timeout=30 --ask-sudo-pass --ask-vault-pass --limit="machine*:&vagrant:!that_one" --inventory-file=#{generated_inventory_dir} --extra-vars="{\\"var1\\":\\"string with 'apostrophes', \\\\\\\\, \\\\\\" and =\\",\\"var2\\":{\\"x\\":42}}" --sudo --sudo-user=deployer -vvv --vault-password-file=#{File.expand_path(__FILE__)} --tags=db,www --skip-tags=foo,bar --start-at-task="joe's awesome task" --why-not --su-user=foot --ask-su-pass --limit=all --private-key=./myself.key --extra-vars='{\"var3\":\"foo\"}' playbook.yml))
expect(full_command).to eq(%Q(PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_ROLES_PATH='/up/to the stars' ANSIBLE_HOST_KEY_CHECKING=true ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes -o 'IdentityFile=/my/key1' -o 'IdentityFile=/my/key2' -o ForwardAgent=yes -o ControlMaster=no -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --connection=ssh --timeout=30 --ask-sudo-pass --ask-vault-pass --limit="machine*:&vagrant:!that_one" --inventory-file=#{generated_inventory_dir} --extra-vars="{\\"var1\\":\\"string with 'apostrophes', \\\\\\\\, \\\\\\" and =\\",\\"var2\\":{\\"x\\":42}}" --sudo --sudo-user=deployer -vvv --vault-password-file=#{File.expand_path(__FILE__)} --tags=db,www --skip-tags=foo,bar --start-at-task="joe's awesome task" --why-not --su-user=foot --ask-su-pass --limit=all --private-key=./myself.key --extra-vars='{\"var3\":\"foo\"}' playbook.yml))
}
end
end
Expand Down