2014-04-11 01:26:19 +00:00
|
|
|
require "vagrant/util/shell_quote"
|
|
|
|
|
|
|
|
module VagrantPlugins
|
|
|
|
module DockerProvider
|
|
|
|
module Executor
|
|
|
|
# The Vagrant executor runs Docker over SSH against the given
|
|
|
|
# Vagrant-managed machine.
|
|
|
|
class Vagrant
|
|
|
|
def initialize(host_machine)
|
|
|
|
@host_machine = host_machine
|
|
|
|
end
|
|
|
|
|
2014-04-29 23:27:22 +00:00
|
|
|
def execute(*cmd, **opts, &block)
|
2014-04-11 01:26:19 +00:00
|
|
|
quote = '"'
|
|
|
|
cmd = cmd.map do |a|
|
|
|
|
"#{quote}#{::Vagrant::Util::ShellQuote.escape(a, quote)}#{quote}"
|
|
|
|
end.join(" ")
|
|
|
|
|
2014-04-29 23:27:22 +00:00
|
|
|
# If we want stdin, we just run in a full subprocess
|
|
|
|
return ssh_run(cmd) if opts[:stdin]
|
|
|
|
|
2014-04-11 01:26:19 +00:00
|
|
|
# Add a start fence so we know when to start reading output.
|
|
|
|
# We have to do this because boot2docker outputs a login shell
|
|
|
|
# boot2docker version that we get otherwise and messes up output.
|
|
|
|
start_fence = "========== VAGRANT DOCKER BEGIN =========="
|
2014-04-28 01:26:12 +00:00
|
|
|
ssh_cmd = "echo -n \"#{start_fence}\"; #{cmd}"
|
2014-04-11 01:26:19 +00:00
|
|
|
|
|
|
|
stderr = ""
|
|
|
|
stdout = ""
|
|
|
|
fenced = false
|
|
|
|
comm = @host_machine.communicate
|
|
|
|
code = comm.execute(ssh_cmd, error_check: false) do |type, data|
|
|
|
|
next if ![:stdout, :stderr].include?(type)
|
|
|
|
stderr << data if type == :stderr
|
|
|
|
stdout << data if type == :stdout
|
|
|
|
|
|
|
|
if !fenced
|
|
|
|
index = stdout.index(start_fence)
|
|
|
|
if index
|
2014-04-16 00:23:56 +00:00
|
|
|
fenced = true
|
|
|
|
|
2014-04-11 01:26:19 +00:00
|
|
|
index += start_fence.length
|
|
|
|
stdout = stdout[index..-1]
|
|
|
|
stdout.chomp!
|
2014-04-16 00:23:56 +00:00
|
|
|
|
|
|
|
# We're now fenced, send all the data through
|
|
|
|
if block
|
2014-04-28 01:26:12 +00:00
|
|
|
block.call(:stdout, stdout) if stdout != ""
|
|
|
|
block.call(:stderr, stderr) if stderr != ""
|
2014-04-16 00:23:56 +00:00
|
|
|
end
|
2014-04-11 01:26:19 +00:00
|
|
|
end
|
2014-04-16 00:23:56 +00:00
|
|
|
else
|
|
|
|
# If we're already fenced, just send the data through.
|
|
|
|
block.call(type, data) if block && fenced
|
2014-04-11 01:26:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if code != 0
|
|
|
|
raise Errors::ExecuteError,
|
|
|
|
command: cmd,
|
|
|
|
stderr: stderr.chomp,
|
|
|
|
stdout: stdout.chomp
|
|
|
|
end
|
|
|
|
|
|
|
|
stdout.chomp
|
|
|
|
end
|
2014-04-29 23:27:22 +00:00
|
|
|
|
|
|
|
protected
|
|
|
|
|
|
|
|
def ssh_run(cmd)
|
|
|
|
@host_machine.action(
|
|
|
|
:ssh_run,
|
|
|
|
ssh_run_command: cmd,
|
|
|
|
)
|
|
|
|
|
|
|
|
""
|
|
|
|
end
|
2014-04-11 01:26:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|