Vagrant: Util::Powershell.execute_inline doesn't properly flatten command to be executed

Created on 7 Aug 2018  ยท  2Comments  ยท  Source: hashicorp/vagrant

Vagrant version

Vagrant 2.1.2

Host operating system

Windows 7 x64

Guest operating system

Ubuntu 16.04 LTS

Vagrantfile

(Yes, I'm using Homestead, but the Vagrant developers on the Gitter chat channel don't believe it to be a factor here, and green-lighted posting this as-is.)

# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'json'
require 'yaml'

VAGRANTFILE_API_VERSION ||= "2"
confDir = $confDir ||= File.expand_path(File.dirname(__FILE__))

homesteadYamlPath = confDir + "/Homestead.yaml"
homesteadJsonPath = confDir + "/Homestead.json"
afterScriptPath = confDir + "/after.sh"
aliasesPath = confDir + "/aliases"

require File.expand_path(File.dirname(__FILE__) + '/scripts/homestead.rb')

Vagrant.require_version '>= 2.1.0'

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.trigger.after :halt, :destroy do |trigger|
        trigger.run = {inline: 'taskkill /f /fi "IMAGENAME eq winnfsd.exe"'}
    end

    if File.exist? aliasesPath then
        config.vm.provision "file", source: aliasesPath, destination: "/tmp/bash_aliases"
        config.vm.provision "shell" do |s|
            s.inline = "awk '{ sub(\"\r$\", \"\"); print }' /tmp/bash_aliases > /home/vagrant/.bash_aliases"
        end
    end

    if File.exist? homesteadYamlPath then
        settings = YAML::load(File.read(homesteadYamlPath))
    elsif File.exist? homesteadJsonPath then
        settings = JSON::parse(File.read(homesteadJsonPath))
    else
        abort "Homestead settings file not found in #{confDir}"
    end

    Homestead.configure(config, settings)

    if File.exist? afterScriptPath then
        config.vm.provision "shell", path: afterScriptPath, privileged: false, keep_color: true
    end

    if Vagrant.has_plugin?('vagrant-hostsupdater')
        config.hostsupdater.aliases = settings['sites'].map { |site| site['map'] }
    elsif Vagrant.has_plugin?('vagrant-hostmanager')
        config.hostmanager.enabled = true
        config.hostmanager.manage_host = true
        config.hostmanager.aliases = settings['sites'].map { |site| site['map'] }
    end
end

Debug output

https://gist.github.com/cbj4074/b9f4d7c149db733dc49de55dd856ab93

Expected behavior

The trigger should have fired as expected and executed the specified command.

Actual behavior

> vagrant halt
==> homestead-7: Running triggers after halt ...
==> homestead-7: Running trigger...
    homestead-7: Running local: Inline script
    homestead-7: taskkill /f /fi "IMAGENAME eq winnfsd.exe"
    homestead-7: At line:1 char:30
    homestead-7: + [taskkill, /f, /fi, IMAGENAME eq winnfsd.exe]
    homestead-7: +                              ~
    homestead-7: Missing ] at end of attribute or type literal.
    homestead-7: At line:1 char:31
    homestead-7: + [taskkill, /f, /fi, IMAGENAME eq winnfsd.exe]
    homestead-7: +                               ~~
    homestead-7: Unexpected token 'eq' in expression or statement.
    homestead-7:     + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    homestead-7:     + FullyQualifiedErrorId : EndSquareBracketExpectedAtEndOfAttribute

For what it's worth, if I change the quoting style, and remove the nested quotes and / characters, in an effort to simplify the script content, the error changes:

> vagrant halt
==> homestead-7: Running triggers after halt ...
==> homestead-7: Running trigger...
    homestead-7: Running local: Inline script
    homestead-7: taskkill
    homestead-7: Unable to find type [taskkill]. Make sure that the assembly that contains this type is loaded.
    homestead-7: At line:1 char:1
    homestead-7: + [taskkill]
    homestead-7: + ~~~~~~~~~~
    homestead-7:     + CategoryInfo          : InvalidOperation: (taskkill:TypeName) [], RuntimeException
    homestead-7:     + FullyQualifiedErrorId : TypeNotFound

If I execute the same command, taskkill, directly in a Powershell terminal, it works as expected.

Steps to reproduce

  1. Define a trigger that uses an inline script in the Vagrantfile and execute an action that causes the trigger to fire.
bug core has-pr hoswindows triggers

Most helpful comment

Problem is here: https://github.com/hashicorp/vagrant/blob/master/lib/vagrant/util/powershell.rb#L142

The #execute_inline command needs to properly flatten out the passed in command, otherwise it gets interpolated as the command array rather than a splat of commands and arguments to be executed.

There might also be a problem with the #execute_cmd function, as it does the same thing with the passed in command.

All 2 comments

Problem is here: https://github.com/hashicorp/vagrant/blob/master/lib/vagrant/util/powershell.rb#L142

The #execute_inline command needs to properly flatten out the passed in command, otherwise it gets interpolated as the command array rather than a splat of commands and arguments to be executed.

There might also be a problem with the #execute_cmd function, as it does the same thing with the passed in command.

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rrzaripov picture rrzaripov  ยท  3Comments

luispabon picture luispabon  ยท  3Comments

mpontillo picture mpontillo  ยท  3Comments

RobertSwirsky picture RobertSwirsky  ยท  3Comments

tomhking picture tomhking  ยท  3Comments