[tor-commits] [arm/master] Config option to shut down tor when quiting

atagar at torproject.org atagar at torproject.org
Sun Jul 10 01:05:31 UTC 2011


commit 2ce33556601d2c4a1d0b177d7cbb075a3e8bec7e
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Jul 9 16:08:39 2011 -0700

    Config option to shut down tor when quiting
    
    If attached to an arm made tor instance and the config option is set then
    offers to shut down tor gracefully when quitting.
---
 armrc.sample          |    4 ++++
 src/cli/controller.py |   25 ++++++++++++++++++++++++-
 src/util/torTools.py  |   24 ++++++++++++++++++++++++
 3 files changed, 52 insertions(+), 1 deletions(-)

diff --git a/armrc.sample b/armrc.sample
index bfe8976..c893bf9 100644
--- a/armrc.sample
+++ b/armrc.sample
@@ -31,6 +31,10 @@ features.colorInterface true
 # none, red, green, yellow, blue, cyan, magenta, black, white
 features.colorOverride none
 
+# If arm is attached to an arm started tor instance when it shuts down then
+# offers to shut down tor too if true, otherwise skips this prompt.
+features.offerTorShutdownOnQuit false
+
 # Includes unicode characters in the interface.
 features.printUnicode true
 
diff --git a/src/cli/controller.py b/src/cli/controller.py
index 633296e..ae1a59b 100644
--- a/src/cli/controller.py
+++ b/src/cli/controller.py
@@ -28,6 +28,7 @@ ARM_CONTROLLER = None
 CONFIG = {"startup.events": "N3",
           "startup.dataDirectory": "~/.arm",
           "startup.blindModeEnabled": False,
+          "features.offerTorShutdownOnQuit": False,
           "features.panels.show.graph": True,
           "features.panels.show.log": True,
           "features.panels.show.connection": True,
@@ -388,10 +389,32 @@ class Controller:
   
   def quit(self):
     """
-    Terminates arm after the input is processed.
+    Terminates arm after the input is processed. Optionally if we're connected
+    to a arm generated tor instance then this may check if that should be shut
+    down too.
     """
     
     self._isDone = True
+    
+    if CONFIG["features.offerTorShutdownOnQuit"]:
+      conn = torTools.getConn()
+      torrcLoc = conn.getInfo("config-file")
+      wizardTorrcLoc = self.getDataDirectory() + "torrc"
+      
+      if torrcLoc == wizardTorrcLoc:
+        while True:
+          msg = "Shut down the Tor instance arm started (y/n)?"
+          confirmationKey = cli.popups.showMsg(msg, attr = curses.A_BOLD)
+          
+          if confirmationKey in (ord('y'), ord('Y')):
+            # attempts a graceful shutdown of tor, showing the issue if
+            # unsuccessful then continuing the shutdown
+            try: conn.shutdown()
+            except IOError, exc: cli.popups.showMsg(str(exc), 3, curses.A_BOLD)
+            
+            break
+          elif confirmationKey in (ord('n'), ord('N')):
+            break
 
 def shutdownDaemons():
   """
diff --git a/src/util/torTools.py b/src/util/torTools.py
index 7e9fa37..0fb71a8 100644
--- a/src/util/torTools.py
+++ b/src/util/torTools.py
@@ -1465,6 +1465,30 @@ class Controller(TorCtl.PostEventListener):
     
     if raisedException: raise raisedException
   
+  def shutdown(self, force = False):
+    """
+    Sends a shutdown signal to the attached tor instance. For relays the
+    actual shutdown is delayed for thirty seconds unless the force flag is
+    given. This raises an IOError if a signal is sent but fails.
+    
+    Arguments:
+      force - triggers an immediate shutdown for relays if True
+    """
+    
+    self.connLock.acquire()
+    
+    raisedException = None
+    if self.isAlive():
+      try:
+        signal = "HALT" if force else "SHUTDOWN"
+        self.conn.send_signal(signal)
+      except Exception, exc:
+        raisedException = IOError(str(exc))
+    
+    self.connLock.release()
+    
+    if raisedException: raise raisedException
+  
   def msg_event(self, event):
     """
     Listens for reload signal (hup), which is either produced by:





More information about the tor-commits mailing list