Remove the "easy" plugins until a future version
This commit is contained in:
parent
387692f9c8
commit
8f24d2d98c
|
@ -69,7 +69,6 @@ module Vagrant
|
|||
autoload :Config, 'vagrant/config'
|
||||
autoload :Downloaders, 'vagrant/downloaders'
|
||||
autoload :Driver, 'vagrant/driver'
|
||||
autoload :Easy, 'vagrant/easy'
|
||||
autoload :Environment, 'vagrant/environment'
|
||||
autoload :Errors, 'vagrant/errors'
|
||||
autoload :Guest, 'vagrant/guest'
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
module Vagrant
|
||||
module Easy
|
||||
autoload :CommandBase, "vagrant/easy/command_base"
|
||||
autoload :CommandAPI, "vagrant/easy/command_api"
|
||||
autoload :Operations, "vagrant/easy/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.
|
||||
def self.create_command(name, &block)
|
||||
# Create a new command class for this command, and return it
|
||||
command = Class.new(CommandBase)
|
||||
command.configure(name, &block)
|
||||
command
|
||||
end
|
||||
|
||||
# This creates a new easy hook. This should not be called by the
|
||||
# general public. Instead, use the plugin interface.
|
||||
#
|
||||
# @return [Proc]
|
||||
def self.create_hook(&block)
|
||||
# Create a lambda which simply calls the plugin with the operations
|
||||
lambda do |env|
|
||||
ops = Operations.new(env[:vm])
|
||||
block.call(ops)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,95 +0,0 @@
|
|||
require "delegate"
|
||||
require "optparse"
|
||||
|
||||
require "log4r"
|
||||
|
||||
require "vagrant/easy/operations"
|
||||
|
||||
module Vagrant
|
||||
module Easy
|
||||
# This is the API that easy commands have access to. It is a subclass
|
||||
# of Operations so it has access to all those methods as well.
|
||||
class CommandAPI < DelegateClass(Operations)
|
||||
attr_reader :argv
|
||||
|
||||
def initialize(vm, argv)
|
||||
super(Operations.new(vm))
|
||||
|
||||
@logger = Log4r::Logger.new("vagrant::easy::command_api")
|
||||
@argv = argv
|
||||
@vm = vm
|
||||
end
|
||||
|
||||
# Gets the value of an argument from the command line. Many arguments
|
||||
# can be given as a parameter and the first matching one will be returned.
|
||||
#
|
||||
# @return [String]
|
||||
def arg(*names)
|
||||
@logger.info("reading args: #{names.inspect}")
|
||||
|
||||
# Mangle the names a bit to add "=VALUE" to every flag.
|
||||
names = names.map do |name|
|
||||
"#{name}=VALUE"
|
||||
end
|
||||
|
||||
# Create a basic option parser
|
||||
parser = OptionParser.new
|
||||
|
||||
# Add on a matcher for this thing
|
||||
result = nil
|
||||
parser.on(*names) do |value|
|
||||
result = value
|
||||
end
|
||||
|
||||
begin
|
||||
# The `dup` is required in @argv because the OptionParser
|
||||
# modifies it in place as it finds matching arguments.
|
||||
parser.parse!(@argv.dup)
|
||||
rescue OptionParser::MissingArgument
|
||||
# Missing argument means the argument existed but had no data,
|
||||
# so we mark it as an empty string
|
||||
result = ""
|
||||
rescue OptionParser::InvalidOption
|
||||
# Ignore!
|
||||
end
|
||||
|
||||
# Return the results
|
||||
result
|
||||
end
|
||||
|
||||
# Returns any extra arguments that are past a "--" on the command line.
|
||||
#
|
||||
# @return [String]
|
||||
def arg_extra
|
||||
# Split the arguments and remove the "--"
|
||||
remaining = @argv.drop_while { |v| v != "--" }
|
||||
remaining.shift
|
||||
|
||||
# Return the remaining arguments
|
||||
remaining.join(" ")
|
||||
end
|
||||
|
||||
# Outputs an error message to the UI.
|
||||
#
|
||||
# @param [String] message Message to send.
|
||||
def error(message)
|
||||
@vm.ui.error(message)
|
||||
end
|
||||
|
||||
# Outputs a normal message to the UI. Use this for any standard-level
|
||||
# messages.
|
||||
#
|
||||
# @param [String] message Message to send.
|
||||
def info(message)
|
||||
@vm.ui.info(message)
|
||||
end
|
||||
|
||||
# Outputs a success message to the UI.
|
||||
#
|
||||
# @param [String] message Message to send.
|
||||
def success(message)
|
||||
@vm.ui.success(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,79 +0,0 @@
|
|||
require "log4r"
|
||||
|
||||
module Vagrant
|
||||
module Easy
|
||||
# Base class for all easy commands. This contains the basic code
|
||||
# that knows how to run the easy commands.
|
||||
class CommandBase < Vagrant.plugin("1", :command)
|
||||
# This is the command that this easy command responds to
|
||||
attr_reader :command
|
||||
|
||||
# This is called by the {EasyCommand.create} method when creating
|
||||
# an easy command to set the invocation command.
|
||||
def self.configure(name, &block)
|
||||
# We use class-level instance variables so that each class has
|
||||
# its own single command/runner. If we use class variables then this
|
||||
# whole base sharse a single one.
|
||||
@command = name
|
||||
@runner = block
|
||||
end
|
||||
|
||||
def initialize(*args, &block)
|
||||
if self.class == CommandBase
|
||||
raise "CommandBase must not be instantiated directly. Please subclass."
|
||||
end
|
||||
|
||||
# Let the regular command state setup
|
||||
super
|
||||
|
||||
# Get the command we're listening to and the block we're invoking
|
||||
# when we get that command, do some basic validation.
|
||||
@command = self.class.instance_variable_get(:@command)
|
||||
@runner = self.class.instance_variable_get(:@runner)
|
||||
if !@command || !@runner
|
||||
raise ArgumentError, "CommandBase requires both a command and a runner"
|
||||
end
|
||||
|
||||
@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 = nil
|
||||
begin
|
||||
argv = parse_options(opts)
|
||||
rescue Errors::CLIInvalidOptions
|
||||
# This means that an invalid flag such as "--foo" was passed.
|
||||
# We usually show the help at this point (in built-in commands),
|
||||
# but since we don't know what our implementation does, we just
|
||||
# pass the flags through now.
|
||||
argv = @argv.dup
|
||||
end
|
||||
|
||||
# If argv is nil then `parse_options` halted execution and we
|
||||
# halt our own execution here.
|
||||
return 0 if !argv
|
||||
|
||||
# The Multi-VM argument is the first argument as long as the
|
||||
# first argument is not a flag.
|
||||
names = nil
|
||||
names = argv[0] if argv[0] !~ /^-/
|
||||
|
||||
# Run the action for each VM.
|
||||
@logger.info("Running easy command: #{@command}")
|
||||
with_target_vms(names) do |vm|
|
||||
@logger.debug("Running easy command for VM: #{vm.name}")
|
||||
@runner.call(CommandAPI.new(vm, argv))
|
||||
end
|
||||
|
||||
# Exit status 0 every time for now
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,158 +0,0 @@
|
|||
require "ostruct"
|
||||
require "tempfile"
|
||||
|
||||
require "log4r"
|
||||
|
||||
require "vagrant/util/subprocess"
|
||||
|
||||
module Vagrant
|
||||
module Easy
|
||||
# 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::operations")
|
||||
@vm = vm
|
||||
end
|
||||
|
||||
# Download a file from the remote virtual machine. If `to` is nil, then
|
||||
# the contents are returned as a string.
|
||||
#
|
||||
# @param [String] from Path on the remote VM to download.
|
||||
# @param [String] to Path to a local file to save to.
|
||||
# @return [String] File contents if `to` is nil.
|
||||
def download(from, to=nil)
|
||||
raise Errors::VMNotRunningError if @vm.state != :running
|
||||
|
||||
@logger.info("download: #{from} => #{to}")
|
||||
@vm.channel.download(from, to)
|
||||
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
|
||||
# @param [Hash] options Additional options
|
||||
def local(command, options=nil)
|
||||
@logger.info("local: #{command}")
|
||||
|
||||
block = nil
|
||||
options = { :echo => true }.merge(options || {})
|
||||
|
||||
if options[:echo]
|
||||
# If we're echoing data, then setup the block that sends the
|
||||
# data to the UI.
|
||||
block = Proc.new do |type, data|
|
||||
if type == :stdout || type == :stderr
|
||||
@vm.ui.info(data.to_s,
|
||||
:prefix => false,
|
||||
:new_line => false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Vagrant::Util::Subprocess.execute(command, :notify => [:stdout, :stderr], &block)
|
||||
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
|
||||
# @param [Hash] options Additional options
|
||||
def run(command, options=nil)
|
||||
@logger.info("run: #{command}")
|
||||
options = { :echo => true }.merge(options || {})
|
||||
remote_command(:execute, command, options)
|
||||
end
|
||||
|
||||
# Same as {run} except runs the command with superuser privileges
|
||||
# via `sudo`.
|
||||
#
|
||||
# @param [String] command Command
|
||||
# @param [Hash] options Additional options
|
||||
def sudo(command, options=nil)
|
||||
@logger.info("sudo: #{command}")
|
||||
options = { :echo => true }.merge(options || {})
|
||||
remote_command(:sudo, command, options)
|
||||
end
|
||||
|
||||
# Uploads a file to the virtual machine.
|
||||
#
|
||||
# Note that the `to` path must have proper permissions setup so that the
|
||||
# SSH user can upload to it. If it does not, then you should upload
|
||||
# to a location you do have permission to, then use {#sudo} to move
|
||||
# it.
|
||||
#
|
||||
# @param [String] from Path to a local file or an IO object.
|
||||
# @param [String] to Path where to upload to.
|
||||
def upload(from, to)
|
||||
raise Errors::VMNotRunningError if @vm.state != :running
|
||||
|
||||
# If we're dealing with an IO object, then save it to a temporary
|
||||
# file and upload that. We define `temp = nil` here so that it
|
||||
# doesn't go out of scope and get GC'd until after the method
|
||||
# closes.
|
||||
temp = nil
|
||||
if from.is_a?(IO)
|
||||
temp = Tempfile.new("vagrant")
|
||||
temp.write(from)
|
||||
temp.close
|
||||
|
||||
from = temp.path
|
||||
end
|
||||
|
||||
# Perform the upload
|
||||
@logger.info("upload: #{from} => #{to}")
|
||||
@vm.channel.upload(from, to)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Runs a command on the remote host.
|
||||
def remote_command(type, command, options)
|
||||
# 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
|
||||
|
||||
# If we're echoing data, then echo it!
|
||||
if options[:echo]
|
||||
@vm.ui.info(data.to_s,
|
||||
:prefix => false,
|
||||
:new_line => false)
|
||||
end
|
||||
end
|
||||
|
||||
# Return the result
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,9 +10,6 @@ module Vagrant
|
|||
|
||||
# This is thrown when a command name given is invalid.
|
||||
class InvalidCommandName < Error; end
|
||||
|
||||
# This is thrown when a hook "position" is invalid.
|
||||
class InvalidEasyHookPosition < Error; end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -143,38 +143,6 @@ module Vagrant
|
|||
data[:config]
|
||||
end
|
||||
|
||||
# Defines an "easy hook," which gives an easier interface to hook
|
||||
# into action sequences.
|
||||
def self.easy_hook(position, name, &block)
|
||||
if ![:before, :after].include?(position)
|
||||
raise InvalidEasyHookPosition, "must be :before, :after"
|
||||
end
|
||||
|
||||
# This is the command sent to sequences to insert
|
||||
insert_method = "insert_#{position}".to_sym
|
||||
|
||||
# Create the hook
|
||||
hook = Easy.create_hook(&block)
|
||||
|
||||
# Define an action hook that listens to all actions and inserts
|
||||
# the hook properly if the sequence contains what we're looking for
|
||||
action_hook(ALL_ACTIONS) do |seq|
|
||||
index = seq.index(name)
|
||||
seq.send(insert_method, index, hook) if index
|
||||
end
|
||||
end
|
||||
|
||||
# Defines an "easy command," which is a command with limited
|
||||
# functionality but far less boilerplate required over traditional
|
||||
# commands. Easy commands let you make basic commands quickly and
|
||||
# easily.
|
||||
#
|
||||
# @param [String] name Name of the command, how it will be invoked
|
||||
# on the command line.
|
||||
def self.easy_command(name, &block)
|
||||
command(name) { Easy.create_command(name, &block) }
|
||||
end
|
||||
|
||||
# Defines an additionally available guest implementation with
|
||||
# the given key.
|
||||
#
|
||||
|
|
|
@ -10,9 +10,6 @@ module Vagrant
|
|||
|
||||
# This is thrown when a command name given is invalid.
|
||||
class InvalidCommandName < Error; end
|
||||
|
||||
# This is thrown when a hook "position" is invalid.
|
||||
class InvalidEasyHookPosition < Error; end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -134,38 +134,6 @@ module Vagrant
|
|||
nil
|
||||
end
|
||||
|
||||
# Defines an "easy hook," which gives an easier interface to hook
|
||||
# into action sequences.
|
||||
def self.easy_hook(position, name, &block)
|
||||
if ![:before, :after].include?(position)
|
||||
raise InvalidEasyHookPosition, "must be :before, :after"
|
||||
end
|
||||
|
||||
# This is the command sent to sequences to insert
|
||||
insert_method = "insert_#{position}".to_sym
|
||||
|
||||
# Create the hook
|
||||
hook = Easy.create_hook(&block)
|
||||
|
||||
# Define an action hook that listens to all actions and inserts
|
||||
# the hook properly if the sequence contains what we're looking for
|
||||
action_hook(ALL_ACTIONS) do |seq|
|
||||
index = seq.index(name)
|
||||
seq.send(insert_method, index, hook) if index
|
||||
end
|
||||
end
|
||||
|
||||
# Defines an "easy command," which is a command with limited
|
||||
# functionality but far less boilerplate required over traditional
|
||||
# commands. Easy commands let you make basic commands quickly and
|
||||
# easily.
|
||||
#
|
||||
# @param [String] name Name of the command, how it will be invoked
|
||||
# on the command line.
|
||||
def self.easy_command(name, &block)
|
||||
command(name) { Easy.create_command(name, &block) }
|
||||
end
|
||||
|
||||
# Defines an additionally available guest implementation with
|
||||
# the given key.
|
||||
#
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
require File.expand_path("../../../base", __FILE__)
|
||||
|
||||
describe Vagrant::Easy::CommandBase do
|
||||
let(:klass) { Class.new(described_class) }
|
||||
|
||||
it "should raise an error if instantiated directly" do
|
||||
expect { described_class.new(nil, nil) }.to raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "should raise an error if command/runner are not set" do
|
||||
expect { klass.new(nil, nil) }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "should inherit the configured name" do
|
||||
klass.configure("name") {}
|
||||
|
||||
instance = klass.new(nil, nil)
|
||||
instance.command.should == "name"
|
||||
end
|
||||
end
|
|
@ -128,17 +128,6 @@ describe Vagrant::Plugin::V1::Plugin do
|
|||
end
|
||||
end
|
||||
|
||||
describe "easy commands" do
|
||||
it "should register with the commands" do
|
||||
plugin = Class.new(described_class) do
|
||||
easy_command("foo") {}
|
||||
end
|
||||
|
||||
# Check that the command class subclasses the easy command base
|
||||
plugin.command[:foo].should < Vagrant::Easy::CommandBase
|
||||
end
|
||||
end
|
||||
|
||||
describe "guests" do
|
||||
it "should register guest classes" do
|
||||
plugin = Class.new(described_class) do
|
||||
|
|
|
@ -136,17 +136,6 @@ describe Vagrant::Plugin::V2::Plugin do
|
|||
end
|
||||
end
|
||||
|
||||
describe "easy commands" do
|
||||
it "should register with the commands" do
|
||||
plugin = Class.new(described_class) do
|
||||
easy_command("foo") {}
|
||||
end
|
||||
|
||||
# Check that the command class subclasses the easy command base
|
||||
plugin.command[:foo].should < Vagrant::Easy::CommandBase
|
||||
end
|
||||
end
|
||||
|
||||
describe "guests" do
|
||||
it "should register guest classes" do
|
||||
plugin = Class.new(described_class) do
|
||||
|
|
Loading…
Reference in New Issue