providers/docker: docker-attach command for following output
This commit is contained in:
parent
6e07ab0d97
commit
54de2e3c6f
|
@ -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
|
|
@ -99,8 +99,6 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def execute(*cmd, &block)
|
def execute(*cmd, &block)
|
||||||
@executor.execute(*cmd, &block)
|
@executor.execute(*cmd, &block)
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,14 +34,23 @@ module VagrantPlugins
|
||||||
if !fenced
|
if !fenced
|
||||||
index = stdout.index(start_fence)
|
index = stdout.index(start_fence)
|
||||||
if index
|
if index
|
||||||
|
fenced = true
|
||||||
|
|
||||||
index += start_fence.length
|
index += start_fence.length
|
||||||
stdout = stdout[index..-1]
|
stdout = stdout[index..-1]
|
||||||
stdout.chomp!
|
stdout.chomp!
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
# 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
|
block.call(type, data) if block && fenced
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if code != 0
|
if code != 0
|
||||||
raise Errors::ExecuteError,
|
raise Errors::ExecuteError,
|
||||||
|
|
|
@ -22,6 +22,12 @@ module VagrantPlugins
|
||||||
Provider
|
Provider
|
||||||
end
|
end
|
||||||
|
|
||||||
|
command("docker-attach", primary: false) do
|
||||||
|
require_relative "command/attach"
|
||||||
|
init!
|
||||||
|
Command::Attach
|
||||||
|
end
|
||||||
|
|
||||||
config(:docker, :provider) do
|
config(:docker, :provider) do
|
||||||
require_relative 'config'
|
require_relative 'config'
|
||||||
init!
|
init!
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
en:
|
en:
|
||||||
docker_provider:
|
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: |-
|
||||||
Creating the container...
|
Creating the container...
|
||||||
created: |-
|
created: |-
|
||||||
|
@ -11,6 +15,10 @@ en:
|
||||||
host_machine_starting: |-
|
host_machine_starting: |-
|
||||||
Vagrant will now create or start a local VM to act as the Docker
|
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.
|
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:
|
messages:
|
||||||
destroying: |-
|
destroying: |-
|
||||||
|
|
Loading…
Reference in New Issue