From 54de2e3c6f06137507bde423681e60f12521f8f3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 15 Apr 2014 17:23:56 -0700 Subject: [PATCH] providers/docker: docker-attach command for following output --- plugins/providers/docker/command/attach.rb | 88 ++++++++++++++++++++ plugins/providers/docker/driver.rb | 2 - plugins/providers/docker/executor/vagrant.rb | 15 +++- plugins/providers/docker/plugin.rb | 6 ++ templates/locales/providers_docker.yml | 8 ++ 5 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 plugins/providers/docker/command/attach.rb diff --git a/plugins/providers/docker/command/attach.rb b/plugins/providers/docker/command/attach.rb new file mode 100644 index 000000000..213c726c3 --- /dev/null +++ b/plugins/providers/docker/command/attach.rb @@ -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 diff --git a/plugins/providers/docker/driver.rb b/plugins/providers/docker/driver.rb index ae28e0dc5..0ec6b4b1f 100644 --- a/plugins/providers/docker/driver.rb +++ b/plugins/providers/docker/driver.rb @@ -99,8 +99,6 @@ module VagrantPlugins end end - private - def execute(*cmd, &block) @executor.execute(*cmd, &block) end diff --git a/plugins/providers/docker/executor/vagrant.rb b/plugins/providers/docker/executor/vagrant.rb index 151c068a5..046686c62 100644 --- a/plugins/providers/docker/executor/vagrant.rb +++ b/plugins/providers/docker/executor/vagrant.rb @@ -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 diff --git a/plugins/providers/docker/plugin.rb b/plugins/providers/docker/plugin.rb index 3fd4bcf07..18973373f 100644 --- a/plugins/providers/docker/plugin.rb +++ b/plugins/providers/docker/plugin.rb @@ -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! diff --git a/templates/locales/providers_docker.yml b/templates/locales/providers_docker.yml index 68b87b6db..58b717d57 100644 --- a/templates/locales/providers_docker.yml +++ b/templates/locales/providers_docker.yml @@ -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: |-