Class: Sudo::Wrapper

Inherits:
Object show all
Defined in:
lib/sudo/wrapper.rb

Defined Under Namespace

Classes: Finalizer, NoValidSocket, NoValidSudoPid, NotRunning, RuntimeError, SocketNotFound, SudoFailed, SudoProcessAlreadyExists, SudoProcessExists, SudoProcessNotFound

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ruby_opts = '') ⇒ Wrapper

ruby_opts are the command line options to the sudo ruby interpreter; usually you don’t need to specify stuff like “-rmygem/mylib”, libraries will be sorta “inherited”.



60
61
62
63
64
65
66
67
# File 'lib/sudo/wrapper.rb', line 60

def initialize(ruby_opts='') 
  @proxy            = nil
  @socket           = "/tmp/rubysu-#{Process.pid}-#{object_id}" 
  @sudo_pid         = nil
  @ruby_opts        = ruby_opts
  @loaded_features  = []
  # @load_path        = [] # currentl unused
end

Class Method Details

.run(ruby_opts) {|sudo| ... } ⇒ Object

Yields a new running Sudo::Wrapper, and do all the necessary cleanup when the block exits.

ruby_opts

is passed to Sudo::Wrapper::new .

Yields:

  • (sudo)


33
34
35
36
37
# File 'lib/sudo/wrapper.rb', line 33

def run(ruby_opts) # :yields: sudo
  sudo = new(ruby_opts).start!
  yield sudo
  sudo.stop!
end

Instance Method Details

#[](object) ⇒ Object

Gives a copy of object with root privileges.



133
134
135
136
137
138
139
140
# File 'lib/sudo/wrapper.rb', line 133

def [](object)
  if running?
    load_features
    MethodProxy.new object, @proxy
  else
    raise NotRunning
  end
end

#load_featuresObject

Load needed libraries in the DRb server. Usually you don’t need to call this directly.



105
106
107
108
109
110
111
112
113
114
# File 'lib/sudo/wrapper.rb', line 105

def load_features
  unless $LOADED_FEATURES == @loaded_features
    new_features = $LOADED_FEATURES - @loaded_features
    new_features.each do |feature|
      @proxy.proxy Kernel, :require, feature
      @loaded_features << feature
    end
    #@loaded_features += new_features
  end
end

#running?Boolean

Returns:

  • (Boolean)


116
117
118
119
120
121
122
# File 'lib/sudo/wrapper.rb', line 116

def running?
  true if (
    @sudo_pid and Process.exists? @sudo_pid and
    @socket   and File.exists?    @socket   and
    @proxy
  )
end

#server_uriObject



69
# File 'lib/sudo/wrapper.rb', line 69

def server_uri; "drbunix:#{@socket}"; end

#start!Object

Start the sudo-ed Ruby process.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/sudo/wrapper.rb', line 72

def start! 
  Sudo::System.check
  
  @sudo_pid = spawn( 
"sudo ruby -I#{LIBDIR} #{@ruby_opts} #{SERVER_SCRIPT} #{@socket} #{Process.uid}"
  ) 
  Process.detach(@sudo_pid) if @sudo_pid # avoid zombies
  ObjectSpace.define_finalizer self, Finalizer.new(
      :pid => @sudo_pid, :socket => @socket
  )

  if wait_for(:timeout => 1){File.exists? @socket}
    @proxy = DRbObject.new_with_uri(server_uri)
  else
    raise RuntimeError, "Couldn't create DRb socket #{@socket}"  
  end

  #set_load_path # apparently, we don't need this
  
  load_features

  self
end

#stop!Object

Free the resources opened by this Wrapper: e.g. the sudo-ed ruby process and the Unix-domain socket used to communicate to it via ::DRb.



127
128
129
130
# File 'lib/sudo/wrapper.rb', line 127

def stop!
  self.class.cleanup!(:pid => @sudo_pid, :socket => @socket)
  @proxy = nil
end