Merge pull request #3580 from mitchellh/f-tty-docker-run

vagrant docker-run tty
This commit is contained in:
Mitchell Hashimoto 2014-04-29 16:33:11 -07:00
commit 0b8809006b
6 changed files with 49 additions and 15 deletions

View File

@ -165,11 +165,6 @@ module Vagrant
# If we're still here, it means we're supposed to subprocess
# out to ssh rather than exec it.
#
# There is a lot of special-case code for Windows below. Windows
# has a bug with creating a TTY file handle for stdin so SSH doesn't
# work well. We simulate it by copying stdin over. It isn't ideal,
# but it kind of works.
LOGGER.info("Executing SSH in subprocess: #{command_options.inspect}")
process = ChildProcess.build("ssh", *command_options)
process.io.inherit!

View File

@ -26,6 +26,9 @@ module VagrantPlugins
# No ports should be shared to the host
params[:ports] = []
# Allocate a pty if it was requested
params[:pty] = true if env[:run_pty]
# We link to our original container
# TODO
end
@ -55,10 +58,20 @@ module VagrantPlugins
elsif params[:detach]
env[:ui].detail(" \n"+I18n.t("docker_provider.running_detached"))
else
ui_opts = {}
# If we're running with a pty, we want the output to look as
# authentic as possible. We don't prefix things and we don't
# output a newline.
if env[:run_pty]
ui_opts[:prefix] = false
ui_opts[:new_line] = false
end
# For run commands, we run it and stream back the output
env[:ui].detail(" \n"+I18n.t("docker_provider.running")+"\n ")
@driver.create(params) do |type, data|
env[:ui].detail(data.chomp)
@driver.create(params, stdin: env[:run_pty]) do |type, data|
env[:ui].detail(data.chomp, **ui_opts)
end
end
@ -94,6 +107,7 @@ module VagrantPlugins
name: container_name,
ports: forwarded_ports,
privileged: @provider_config.privileged,
pty: false,
volumes: @provider_config.volumes,
}
end

View File

@ -9,6 +9,7 @@ module VagrantPlugins
def execute
options = {}
options[:detach] = false
options[:pty] = false
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant docker-run [command...]"
@ -19,6 +20,10 @@ module VagrantPlugins
o.on("--[no-]detach", "Run in the background") do |d|
options[:detach] = d
end
o.on("-t", "--[no-]tty", "Allocate a pty") do |t|
options[:pty] = t
end
end
# Parse out the extra args to send to SSH, which is everything
@ -36,12 +41,17 @@ module VagrantPlugins
argv = parse_options(opts)
return if !argv
with_target_vms(argv, provider: :docker) do |machine|
target_opts = { provider: :docker }
target_opts[:single_target] = options[:pty]
with_target_vms(argv, target_opts) do |machine|
# Run it!
machine.action(
:run_command,
run_command: command,
run_detach: options[:detach])
run_detach: options[:detach],
run_pty: options[:pty],
)
end
0

View File

@ -25,7 +25,7 @@ module VagrantPlugins
match[1]
end
def create(params, &block)
def create(params, **opts, &block)
image = params.fetch(:image)
links = params.fetch(:links)
ports = Array(params[:ports])
@ -44,10 +44,11 @@ module VagrantPlugins
run_cmd += volumes.map { |v| ['-v', v.to_s] }
run_cmd += %W(--privileged) if params[:privileged]
run_cmd += %W(-h #{params[:hostname]}) if params[:hostname]
run_cmd << "-i" << "-t" if params[:pty]
run_cmd += params[:extra_args] if params[:extra_args]
run_cmd += [image, cmd]
execute(*run_cmd.flatten, &block).chomp
execute(*run_cmd.flatten, **opts, &block).chomp
end
def state(cid)
@ -130,8 +131,8 @@ module VagrantPlugins
end
end
def execute(*cmd, &block)
@executor.execute(*cmd, &block)
def execute(*cmd, **opts, &block)
@executor.execute(*cmd, **opts, &block)
end
end
end

View File

@ -7,7 +7,7 @@ module VagrantPlugins
# The Local executor executes a Docker client that is running
# locally.
class Local
def execute(*cmd, &block)
def execute(*cmd, **opts, &block)
# Append in the options for subprocess
cmd << { :notify => [:stdout, :stderr] }

View File

@ -10,12 +10,15 @@ module VagrantPlugins
@host_machine = host_machine
end
def execute(*cmd, &block)
def execute(*cmd, **opts, &block)
quote = '"'
cmd = cmd.map do |a|
"#{quote}#{::Vagrant::Util::ShellQuote.escape(a, quote)}#{quote}"
end.join(" ")
# If we want stdin, we just run in a full subprocess
return ssh_run(cmd) if opts[:stdin]
# 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.
@ -61,6 +64,17 @@ module VagrantPlugins
stdout.chomp
end
protected
def ssh_run(cmd)
@host_machine.action(
:ssh_run,
ssh_run_command: cmd,
)
""
end
end
end
end