Class: Sudo::Wrapper

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

Defined Under Namespace

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ruby_opts = '') ⇒ Wrapper

Returns a new instance of Wrapper.



54
55
56
57
58
59
# File 'lib/sudo/wrapper.rb', line 54

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

Class Method Details

.cleanup!(h) ⇒ Object

Not an instance method, so it may act as a finalizer (as in ObjectSpace.define_finalizer)



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/sudo/wrapper.rb', line 38

def cleanup!(h)
  if h[:pid] and Process.exists? h[:pid]
    system "sudo kill     #{h[:pid]}"               or
    system "sudo kill -9  #{h[:pid]}"               or
    raise SudoProcessStillExists, 
      "Couldn't kill sudo process (PID=#{h[:pid]})" 
  end
  if h[:socket] and File.exists? h[:socket]
    system "sudo rm -f #{h[:socket]}"               or
    raise SocketStillExists,
        "Couldn't delete socket #{h[:socket]}"
  end
end

.run(*args) {|sudo.start!| ... } ⇒ Object

with blocks

Yields:

  • (sudo.start!)


30
31
32
33
34
# File 'lib/sudo/wrapper.rb', line 30

def run(*args)
  sudo = new(*args)
  yield sudo.start!
  sudo.stop!
end

Instance Method Details

#[](object) ⇒ Object



99
100
101
102
103
104
105
# File 'lib/sudo/wrapper.rb', line 99

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

#running?Boolean

Returns:

  • (Boolean)


85
86
87
88
89
90
91
# File 'lib/sudo/wrapper.rb', line 85

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

#server_uriObject



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

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

#start!Object

Raises:



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/sudo/wrapper.rb', line 63

def start! 
  # just to check if we can sudo; and we'll receive a sudo token
  raise SudoFailed unless system "sudo ruby -e ''"

  raise SudoProcessAlreadyExists if @sudo_pid and Process.exists? @sudo_pid
  
  @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
  self
end

#stop!Object



93
94
95
96
97
# File 'lib/sudo/wrapper.rb', line 93

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

end