Build up some operations that can be run.
These are heavily inspired by Fabric! Thanks!
This commit is contained in:
parent
00aba5ac03
commit
1d7e02cd63
|
@ -1,7 +1,8 @@
|
|||
require "log4r"
|
||||
|
||||
module Vagrant
|
||||
class EasyCommand
|
||||
module EasyCommand
|
||||
autoload :Base, "vagrant/easy_command/base"
|
||||
autoload :Operations, "vagrant/easy_command/operations"
|
||||
|
||||
# This creates a new easy command. This typically is not called
|
||||
# directly. Instead, the plugin interface's `easy_command` is
|
||||
# used to create one of these.
|
||||
|
@ -11,47 +12,5 @@ module Vagrant
|
|||
command.configure(name, &block)
|
||||
command
|
||||
end
|
||||
|
||||
# Base class for all easy commands. This contains the basic code
|
||||
# that knows how to run the easy commands.
|
||||
class Base < Vagrant::Command::Base
|
||||
@@command = nil
|
||||
@@runner = nil
|
||||
|
||||
# This is called by the {EasyCommand.create} method when creating
|
||||
# an easy command to set the invocation command.
|
||||
def self.configure(name, &block)
|
||||
@@command = name
|
||||
@@runner = block
|
||||
end
|
||||
|
||||
def initialize(*args, &block)
|
||||
super
|
||||
|
||||
@logger = Log4r::Logger.new("vagrant::easy_command::#{@@command}")
|
||||
end
|
||||
|
||||
def execute
|
||||
# Build up a basic little option parser
|
||||
opts = OptionParser.new do |opts|
|
||||
opts.banner = "Usage: vagrant #{@@command}"
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
|
||||
# Run the action for each VM.
|
||||
@logger.info("Running easy command: #{@@command}")
|
||||
with_target_vms(argv) do |vm|
|
||||
@logger.debug("Running easy command for VM: #{vm.name}")
|
||||
|
||||
@@runner.call(nil)
|
||||
end
|
||||
|
||||
# Exit status 0 every time for now
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
require "log4r"
|
||||
|
||||
module Vagrant
|
||||
module EasyCommand
|
||||
# Base class for all easy commands. This contains the basic code
|
||||
# that knows how to run the easy commands.
|
||||
class Base < Vagrant::Command::Base
|
||||
@@command = nil
|
||||
@@runner = nil
|
||||
|
||||
# This is called by the {EasyCommand.create} method when creating
|
||||
# an easy command to set the invocation command.
|
||||
def self.configure(name, &block)
|
||||
@@command = name
|
||||
@@runner = block
|
||||
end
|
||||
|
||||
def initialize(*args, &block)
|
||||
super
|
||||
|
||||
@logger = Log4r::Logger.new("vagrant::easy_command::#{@@command}")
|
||||
end
|
||||
|
||||
def execute
|
||||
# Build up a basic little option parser
|
||||
opts = OptionParser.new do |opts|
|
||||
opts.banner = "Usage: vagrant #{@@command}"
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
|
||||
# Run the action for each VM.
|
||||
@logger.info("Running easy command: #{@@command}")
|
||||
with_target_vms(argv) do |vm|
|
||||
@logger.debug("Running easy command for VM: #{vm.name}")
|
||||
@@runner.call(Operations.new(vm))
|
||||
end
|
||||
|
||||
# Exit status 0 every time for now
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,86 @@
|
|||
require "ostruct"
|
||||
|
||||
require "log4r"
|
||||
|
||||
require "vagrant/util/subprocess"
|
||||
|
||||
module Vagrant
|
||||
module EasyCommand
|
||||
# This class contains all the "operations" that easy commands are able
|
||||
# to run. An instance of this is class is what is sent into the callback
|
||||
# for all easy commands.
|
||||
class Operations
|
||||
def initialize(vm)
|
||||
@logger = Log4r::Logger.new("vagrant::easy_command::operations")
|
||||
@vm = vm
|
||||
end
|
||||
|
||||
# Runs a command on the local machine. This will return an object where
|
||||
# you can access the `exit_code`, `stdout`, and `stderr` easiy:
|
||||
#
|
||||
# output = local("echo foo")
|
||||
# puts "Output was #{output.stdout}"
|
||||
#
|
||||
# (Likewise, `exit_code` and `stderr` are attributes on the return value)
|
||||
#
|
||||
# It is recommended you use this `local` method rather than trying to
|
||||
# manually use Ruby's underlying subprocess tools because this will use
|
||||
# the Vagrant `Subprocess` class which has been refined over the years
|
||||
# to work equally well on Windows, Mac OS X, Linux as well as on many
|
||||
# runtimes such as CRuby and JRuby.
|
||||
#
|
||||
# @param [String] command Command to run
|
||||
def local(command)
|
||||
@logger.info("local: #{command}")
|
||||
Vagrant::Util::Subprocess.execute(command)
|
||||
end
|
||||
|
||||
# Run a shell command within the VM. The command will run within a
|
||||
# shell environment, and the output and exit code will be returned
|
||||
# as an object with attributes: `exit_code, `stdout`, and `stderr`.
|
||||
# Example:
|
||||
#
|
||||
# output = run("echo foo")
|
||||
# puts "Output was #{output.stdout}"
|
||||
#
|
||||
# @param [String] command Command to run
|
||||
def run(command)
|
||||
@logger.info("run: #{command}")
|
||||
remote_command(:execute, command)
|
||||
end
|
||||
|
||||
# Same as {run} except runs the command with superuser privileges
|
||||
# via `sudo`.
|
||||
#
|
||||
# @param [String] command Command
|
||||
def sudo(command)
|
||||
@logger.info("sudo: #{command}")
|
||||
remote_command(:sudo, command)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Runs a command on the remote host.
|
||||
def remote_command(type, command)
|
||||
# If the VM is not running, then we can't run SSH commands...
|
||||
raise Errors::VMNotRunningError if @vm.state != :running
|
||||
|
||||
# Initialize the result object, execute, and store the data
|
||||
result = OpenStruct.new
|
||||
result.stderr = ""
|
||||
result.stdout = ""
|
||||
result.exit_code = @vm.channel.send(type, command,
|
||||
:error_check => false) do |type, data|
|
||||
if type == :stdout
|
||||
result.stdout += data
|
||||
elsif type == :stderr
|
||||
result.stderr += data
|
||||
end
|
||||
end
|
||||
|
||||
# Return the result
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue