lib/rye/box.rb in rye-0.8.18 vs lib/rye/box.rb in rye-0.8.19
- old
+ new
@@ -31,11 +31,16 @@
def host; @rye_host; end
def opts; @rye_opts; end
def safe; @rye_safe; end
def user; @rye_user; end
+ def root?; user.to_s == "root" end
+ def enable_sudo; @rye_sudo = true; end
+ def disable_sudo; @rye_sudo = false; end
+ def sudo?; @rye_sudo == true end
+
# Returns the current value of the stash +@rye_stash+
def stash; @rye_stash; end
def quiet; @rye_quiet; end
def nickname; @rye_nickname || host; end
@@ -82,10 +87,11 @@
# * :info => an IO object to print Rye::Box command info to. Default: nil
# * :debug => an IO object to print Rye::Box debugging info to. Default: nil
# * :error => an IO object to print Rye::Box errors to. Default: STDERR
# * :getenv => pre-fetch +host+ environment variables? (default: true)
# * :password => the user's password (ignored if there's a valid private key)
+ # * :sudo => Run all commands via sudo (default: false)
#
# NOTE: +opts+ can also contain any parameter supported by
# Net::SSH.start that is not already mentioned above.
#
def initialize(host='localhost', opts={})
@@ -119,11 +125,11 @@
# that are not meant for it.
@rye_safe, @rye_debug = @rye_opts.delete(:safe), @rye_opts.delete(:debug)
@rye_info, @rye_error = @rye_opts.delete(:info), @rye_opts.delete(:error)
@rye_getenv = {} if @rye_opts.delete(:getenv) # Enable getenv with a hash
@rye_ostype, @rye_impltype = @rye_opts.delete(:ostype), @rye_opts.delete(:impltype)
- @rye_quiet = @rye_opts.delete(:quiet)
+ @rye_quiet, @rye_sudo = @rye_opts.delete(:quiet), @rye_opts.delete(:sudo)
# Just in case someone sends a true value rather than IO object
@rye_debug = STDERR if @rye_debug == true
@rye_error = STDERR if @rye_error == true
@rye_info = STDOUT if @rye_info == true
@@ -428,14 +434,20 @@
uniqlines = authorized_keys.readlines.uniq.join
authorized_keys = StringIO.new(uniqlines)
# We need to rewind so that all of the StringIO object is uploaded
authorized_keys.rewind
- self.mkdir(:p, :m, '700', File.dirname(akey_path))
- self.file_upload(authorized_keys, "#{homedir}/#{akey_path}")
- self.chmod('0600', akey_path)
- self.chown(:R, this_user.to_s, File.dirname(akey_path))
+ full_path = "#{homedir}/#{akey_path}"
+ temp_path = "/tmp/rye-#{user}-#{File.basename(akey_path)}"
+
+ sudo do
+ mkdir :p, :m, '700', File.dirname(akey_path)
+ file_upload authorized_keys, temp_path
+ mv temp_path, full_path
+ chmod '0600', akey_path
+ chown :R, this_user.to_s, File.dirname(akey_path)
+ end
end
# And let's return to the directory we came from.
self.cd prevdir
@@ -585,10 +597,28 @@
ret = self.instance_exec *args, &block
@rye_quiet = previous_state
ret
end
+ # Like batch, except it enables sudo mode before executing the block.
+ # If the user is already root, this has no effect. Otherwise all
+ # commands executed in the block will run via sudo.
+ #
+ # If no block is specified then sudo is called just like a regular
+ # command.
+ def sudo(*args, &block)
+ if block.nil?
+ __allow('sudo', args);
+ else
+ previous_state = @rye_sudo
+ enable_sudo
+ ret = self.instance_exec *args, &block
+ @rye_sudo = previous_state
+ ret
+ end
+ end
+
# instance_exec for Ruby 1.8 written by Mauricio Fernandez
# http://eigenclass.org/hiki/instance_exec
if RUBY_VERSION =~ /1.8/
module InstanceExecHelper; end
include InstanceExecHelper
@@ -814,10 +844,10 @@
# Single character symbols with be converted to command line
# switches. Example: +:l+ becomes +-l+
def prep_args(*args)
args = args.flatten.compact
args = args.first.to_s.split(/\s+/) if args.size == 1
- cmd = args.shift
+ cmd = sudo? ? :sudo : args.shift
# Symbols to switches. :l -> -l, :help -> --help
args.collect! do |a|
if a.is_a?(Symbol)
a = (a.to_s.size == 1) ? "-#{a}" : a.to_s