From 5e70ad0ec20d83fdb874350add97056447c5ff5c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 10 Aug 2012 00:57:23 -0700 Subject: [PATCH] `vagrant ssh -c` now uses a middleware sequence --- lib/vagrant/action.rb | 1 + lib/vagrant/action/builtin/ssh_run.rb | 43 ++++++++++++++++++++++++++ plugins/commands/ssh/command.rb | 32 ++----------------- plugins/providers/virtualbox/action.rb | 11 +++++++ 4 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 lib/vagrant/action/builtin/ssh_run.rb diff --git a/lib/vagrant/action.rb b/lib/vagrant/action.rb index 91a2091cf..ee28a6b93 100644 --- a/lib/vagrant/action.rb +++ b/lib/vagrant/action.rb @@ -18,6 +18,7 @@ module Vagrant autoload :Call, "vagrant/action/builtin/call" autoload :Confirm, "vagrant/action/builtin/confirm" autoload :SSHExec, "vagrant/action/builtin/ssh_exec" + autoload :SSHRun, "vagrant/action/builtin/ssh_run" end module Env diff --git a/lib/vagrant/action/builtin/ssh_run.rb b/lib/vagrant/action/builtin/ssh_run.rb new file mode 100644 index 000000000..1969600eb --- /dev/null +++ b/lib/vagrant/action/builtin/ssh_run.rb @@ -0,0 +1,43 @@ +require "log4r" + +module Vagrant + module Action + module Builtin + # This class will run a single command on the remote machine and will + # mirror the output to the UI. The resulting exit status of the command + # will exist in the `:ssh_run_exit_status` key in the environment. + class SSHRun + def initialize(app, env) + @app = app + @logger = Log4r::Logger.new("vagrant::action::builtin::ssh_run") + end + + def call(env) + command = env[:ssh_run_command] + + @logger.debug("Executing command: #{command}") + exit_status = 0 + exit_status = env[:machine].communicate.execute(command, :error_check => false) do |type, data| + # Determine the proper channel to send the output onto depending + # on the type of data we are receiving. + channel = type == :stdout ? :out : :error + + # Print the output as it comes in, but don't prefix it and don't + # force a new line so that the output is properly preserved however + # it may be formatted. + env[:ui].info(data.to_s, + :prefix => false, + :new_line => false, + :channel => channel) + end + + # Set the exit status on a known environmental variable + env[:ssh_run_exit_status] = exit_status + + # Call the next middleware + @app.call(env) + end + end + end + end +end diff --git a/plugins/commands/ssh/command.rb b/plugins/commands/ssh/command.rb index e84d77a9d..d8e7ae4f5 100644 --- a/plugins/commands/ssh/command.rb +++ b/plugins/commands/ssh/command.rb @@ -37,13 +37,10 @@ module VagrantPlugins # Execute the actual SSH with_target_vms(argv, :single_target => true) do |vm| - # Basic checks that are required for proper SSH - # raise Vagrant::Errors::VMNotCreatedError if !vm.created? - # raise Vagrant::Errors::VMInaccessible if !vm.state == :inaccessible - # raise Vagrant::Errors::VMNotRunningError if vm.state != :running - if options[:command] - ssh_execute(vm, options[:command]) + # XXX: Exit with proper exit status + @logger.debug("Executing single command on remote machine: #{options[:command]}") + vm.action(:ssh_run, :ssh_run_command => options[:command]) else opts = { :plain_mode => options[:plain_mode], @@ -57,29 +54,6 @@ module VagrantPlugins # Success, exit status 0 0 - end - - protected - - def ssh_execute(vm, command=nil) - exit_status = 0 - - @logger.debug("Executing command: #{command}") - exit_status = vm.channel.execute(command, :error_check => false) do |type, data| - # Determine the proper channel to send the output onto depending - # on the type of data we are receiving. - channel = type == :stdout ? :out : :error - - # Print the SSH output as it comes in, but don't prefix it and don't - # force a new line so that the output is properly preserved - vm.ui.info(data.to_s, - :prefix => false, - :new_line => false, - :channel => channel) - end - - # Exit with the exit status we got from executing the command - exit exit_status end end end diff --git a/plugins/providers/virtualbox/action.rb b/plugins/providers/virtualbox/action.rb index 44961e2a3..804be8911 100644 --- a/plugins/providers/virtualbox/action.rb +++ b/plugins/providers/virtualbox/action.rb @@ -68,6 +68,17 @@ module VagrantPlugins b.use SSHExec end end + + # This is the action that will run a single SSH command. + def self.action_ssh_run + Vagrant::Action::Builder.new.tap do |b| + b.use CheckVirtualbox + b.use CheckCreated + b.use CheckAccessible + b.use CheckRunning + b.use SSHRun + end + end end end end