From f7894d9c8c83fd01a27e745a880c50023b1ab462 Mon Sep 17 00:00:00 2001 From: Gilles Cornu Date: Mon, 1 Jun 2015 08:36:09 +0200 Subject: [PATCH] provisioners/ansible: fix broken colorized output After #5532 (e745436df3c64537570953d4d815eaec840da46d), it was no longer possible to enable ansible colorized output. Even though `ANSIBLE_NOCOLOR` has no effect *at the moment* in vagrant+ansible integration, I agree to keep it for clarity and consistence. The new `--no-color` behaviour (bug fix #5531) is now covered by a unit test. //cc @marsam, @sethvargo --- plugins/provisioners/ansible/provisioner.rb | 6 +++++ .../provisioners/ansible/provisioner_test.rb | 27 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/plugins/provisioners/ansible/provisioner.rb b/plugins/provisioners/ansible/provisioner.rb index 6b6ea2d87..b328e13d8 100644 --- a/plugins/provisioners/ansible/provisioner.rb +++ b/plugins/provisioners/ansible/provisioner.rb @@ -70,6 +70,12 @@ module VagrantPlugins # as there is no equivalent command line arguments "ANSIBLE_HOST_KEY_CHECKING" => "#{config.host_key_checking}", } + + # When Ansible output is piped in Vagrant integration, its default colorization is + # automatically disabled and the only way to re-enable colors is to use ANSIBLE_FORCE_COLOR. + env["ANSIBLE_FORCE_COLOR"] = "true" if @machine.env.ui.is_a?(Vagrant::UI::Colored) + # Setting ANSIBLE_NOCOLOR is "unnecessary" at the moment, but this could change in the future + # (e.g. local provisioner [GH-2103], possible change in vagrant/ansible integration, etc.) env["ANSIBLE_NOCOLOR"] = "true" unless @machine.env.ui.is_a?(Vagrant::UI::Colored) # ANSIBLE_SSH_ARGS is required for Multiple SSH keys, SSH forwarding and custom SSH settings diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index 5ed6f80e5..1345033f7 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -56,6 +56,10 @@ VF machine.stub(ssh_info: ssh_info) machine.env.stub(active_machines: [[iso_env.machine_names[0], :dummy], [iso_env.machine_names[1], :dummy]]) + stubbed_ui = Vagrant::UI::Colored.new + stubbed_ui.stub(detail: "") + machine.env.stub(ui: stubbed_ui) + config.playbook = 'playbook.yml' end @@ -110,7 +114,8 @@ VF expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o UserKnownHostsFile=/dev/null") end expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o IdentitiesOnly=yes") - expect(cmd_opts[:env]['ANSIBLE_NOCOLOR']).to eql("true") + expect(cmd_opts[:env]['ANSIBLE_FORCE_COLOR']).to eql("true") + expect(cmd_opts[:env]).to_not include("ANSIBLE_NOCOLOR") expect(cmd_opts[:env]['ANSIBLE_HOST_KEY_CHECKING']).to eql(expected_host_key_checking.to_s) expect(cmd_opts[:env]['PYTHONUNBUFFERED']).to eql(1) } @@ -468,7 +473,7 @@ VF it "shows the ansible-playbook command" do expect(machine.env.ui).to receive(:detail).with { |full_command| - expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_NOCOLOR=true ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --timeout=30 --limit='machine1' --inventory-file=#{generated_inventory_dir} playbook.yml") + expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_FORCE_COLOR=true ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --timeout=30 --limit='machine1' --inventory-file=#{generated_inventory_dir} playbook.yml") } end end @@ -483,7 +488,21 @@ VF it "shows the ansible-playbook command" do expect(machine.env.ui).to receive(:detail).with { |full_command| - expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_NOCOLOR=true ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --timeout=30 --limit='machine1' --inventory-file=#{generated_inventory_dir} -v playbook.yml") + expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_FORCE_COLOR=true ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --timeout=30 --limit='machine1' --inventory-file=#{generated_inventory_dir} -v playbook.yml") + } + end + end + + describe "without colorized output" do + before do + machine.env.stub(ui: Vagrant::UI::Basic.new) + end + + it "disables ansible-playbook colored output" do + expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| + cmd_opts = args.last + expect(cmd_opts[:env]).to_not include("ANSIBLE_FORCE_COLOR") + expect(cmd_opts[:env]['ANSIBLE_NOCOLOR']).to eql("true") } end end @@ -541,7 +560,7 @@ VF 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("PYTHONUNBUFFERED=1 ANSIBLE_HOST_KEY_CHECKING=true ANSIBLE_NOCOLOR=true ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes -o IdentityFile=/my/key2 -o ForwardAgent=yes -o ControlMaster=no -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/my/key1 --user=testuser --connection=ssh --timeout=30 --limit='machine*:&vagrant:!that_one' --inventory-file=#{generated_inventory_dir} --extra-vars=@#{File.expand_path(__FILE__)} --sudo --sudo-user=deployer -vvv --ask-sudo-pass --ask-vault-pass --vault-password-file=#{File.expand_path(__FILE__)} --tags=db,www --skip-tags=foo,bar --start-at-task='an awesome task' --why-not --su-user=foot --ask-su-pass --limit='all' playbook.yml") + expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_HOST_KEY_CHECKING=true ANSIBLE_FORCE_COLOR=true ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes -o IdentityFile=/my/key2 -o ForwardAgent=yes -o ControlMaster=no -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/my/key1 --user=testuser --connection=ssh --timeout=30 --limit='machine*:&vagrant:!that_one' --inventory-file=#{generated_inventory_dir} --extra-vars=@#{File.expand_path(__FILE__)} --sudo --sudo-user=deployer -vvv --ask-sudo-pass --ask-vault-pass --vault-password-file=#{File.expand_path(__FILE__)} --tags=db,www --skip-tags=foo,bar --start-at-task='an awesome task' --why-not --su-user=foot --ask-su-pass --limit='all' playbook.yml") } end end