providers/docker: docker-attach command for following output

This commit is contained in:
Mitchell Hashimoto 2014-04-15 17:23:56 -07:00
parent 6e07ab0d97
commit 54de2e3c6f
5 changed files with 114 additions and 5 deletions

View File

@ -0,0 +1,88 @@
module VagrantPlugins
module DockerProvider
module Command
class Attach < Vagrant.plugin("2", :command)
def self.synopsis
"attaches to the output stream of a container"
end
def execute
options = {}
options[:follow] = false
options[:prefix] = true
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant docker-attach [options]"
o.separator ""
o.separator "Options:"
o.separator ""
o.on("--[no-]follow", "Continue streaming in log output") do |f|
options[:follow] = f
end
o.on("--[no-]prefix", "Don't prefix output with machine names") do |p|
options[:prefix] = p
end
end
# Parse the options
argv = parse_options(opts)
return if !argv
output_options = {}
output_options[:prefix] = false if !options[:prefix]
# TODO: exit with exit status != 0 if all machines are unknown
# or not created.
# Go through each machine and execute the client on it
with_target_vms(argv) do |machine|
if machine.provider_name != :docker
machine.ui.output(I18n.t("docker_provider.not_docker_provder"))
next
end
state = machine.state
if state == :host_state_unknown
machine.ui.output(I18n.t("docker_provider.attach_host_state_unknown"))
next
elsif state == :not_created
machine.ui.output(I18n.t("docker_provider.not_created_skip"))
next
end
command = ["docker", "logs"]
command << "--follow" if options[:follow]
command << machine.id
data_acc = ""
machine.provider.driver.execute(*command) do |type, data|
# Accumulate the data so we only output lines at a time
data_acc << data
# If we have a newline, then output all the lines we have so far
if data_acc.include?("\n")
lines = data_acc.split("\n")
if !data_acc.end_with?("\n")
data_acc = lines.pop.chomp
else
data_acc = ""
end
lines.each do |line|
line = " " if line == ""
machine.ui.output(line, **output_options)
end
end
end
# Output any remaining data
machine.ui.output(data_acc, **output_options) if !data_acc.empty?
end
end
end
end
end
end

View File

@ -99,8 +99,6 @@ module VagrantPlugins
end
end
private
def execute(*cmd, &block)
@executor.execute(*cmd, &block)
end

View File

@ -34,13 +34,22 @@ module VagrantPlugins
if !fenced
index = stdout.index(start_fence)
if index
fenced = true
index += start_fence.length
stdout = stdout[index..-1]
stdout.chomp!
end
end
block.call(type, data) if block && fenced
# We're now fenced, send all the data through
if block
block.call(:stdout, stdout)
block.call(:stderr, stderr)
end
end
else
# If we're already fenced, just send the data through.
block.call(type, data) if block && fenced
end
end
if code != 0

View File

@ -22,6 +22,12 @@ module VagrantPlugins
Provider
end
command("docker-attach", primary: false) do
require_relative "command/attach"
init!
Command::Attach
end
config(:docker, :provider) do
require_relative 'config'
init!

View File

@ -1,5 +1,9 @@
en:
docker_provider:
attach_host_state_unknown: |-
This container requires a host VM, and the state of that VM
is unknown. Run `vagrant up` to verify that the container and
its host VM is running, then try again.
creating: |-
Creating the container...
created: |-
@ -11,6 +15,10 @@ en:
host_machine_starting: |-
Vagrant will now create or start a local VM to act as the Docker
host. You'll see the output of the `vagrant up` for this VM below.
not_created_skip: |-
Container not created. Skipping.
not_docker_provider: |-
Not backed by Docker provider. Skipping.
messages:
destroying: |-