]> scripts.mit.edu Git - wizard.git/blobdiff - wizard/shell.py
Move a bunch of summary items to full class commands.
[wizard.git] / wizard / shell.py
index 49a79245685697559735beb449533b5a7db3302a..3ed61a323537024a30edbd30f3b554e96bfc6129 100644 (file)
@@ -1,44 +1,26 @@
 import subprocess
+import logging
 import sys
 import os
-import Queue
-import threading
 
-import wizard as _wizard
+import wizard
 from wizard import util
 
-wizard = sys.argv[0]
-
-class CallError(_wizard.Error):
-    def __init__(self, code, args, stdout, stderr):
-        self.code = code
-        self.args = args
-        self.stdout = stdout
-        self.stderr = stderr
-    def __str__(self):
-        return "CallError [%d]" % self.code
-
-class PythonCallError(CallError):
-    def __init__(self, code, args, stdout, stderr):
-        self.name = util.get_exception_name(stderr)
-        CallError.__init__(self, code, args, stdout, stderr)
-    def __str__(self):
-        return "PythonCallError [%s]" % self.name
+"""This is the path to the wizard executable as specified
+by the caller; it lets us recursively invoke wizard"""
+wizard_bin = sys.argv[0]
 
 def is_python(args):
-    return args[0] == "python" or args[0] == wizard
+    return args[0] == "python" or args[0] == wizard_bin
 
 class Shell(object):
     """An advanced shell, with the ability to do dry-run and log commands"""
-    def __init__(self, logger = False, dry = False):
-        """ `logger`    The logger
-            `dry`       Don't run any commands, just print them"""
-        self.logger = logger
+    def __init__(self, dry = False):
+        """ `dry`       Don't run any commands, just print them"""
         self.dry = dry
     def call(self, *args, **kwargs):
         kwargs.setdefault("python", None)
-        if self.dry or self.logger:
-            self.logger.info("Running `" + ' '.join(args) + "`")
+        logging.info("Running `" + ' '.join(args) + "`")
         if self.dry:
             return
         if kwargs["python"] is None and is_python(args):
@@ -64,24 +46,27 @@ class Shell(object):
             raise eclass(proc.returncode, args, stdout, stderr)
         return (stdout, stderr)
     def log(self, stdout, stderr):
-        if self.logger and stdout:
-            self.logger.debug("STDOUT:\n" + stdout)
-        if self.logger and stderr:
-            self.logger.debug("STDERR:\n" + stderr)
+        if stdout:
+            logging.debug("STDOUT:\n" + stdout)
+        if stderr:
+            logging.debug("STDERR:\n" + stderr)
     def callAsUser(self, *args, **kwargs):
         user = kwargs.pop("user", None)
         uid = kwargs.pop("uid", None)
         kwargs.setdefault("python", is_python(args))
         if not user and not uid: return self.call(*args, **kwargs)
-        if uid: return self.call("sudo", "-u", "#" + uid, *args, **kwargs)
+        if util.get_operator_name():
+            # This might be generalized as "preserve some environment"
+            args.insert(0, "SSH_GSSAPI_NAME=" + util.get_operator_name())
+        if uid: return self.call("sudo", "-u", "#" + str(uid), *args, **kwargs)
         if user: return self.call("sudo", "-u", user, *args, **kwargs)
 
 class ParallelShell(Shell):
     """Commands are queued here, and executed in parallel (with
     threading) in accordance with the maximum number of allowed
     subprocesses, and result in callback execution when they finish."""
-    def __init__(self, logger = False, dry = False, max = 10):
-        super(ParallelShell, self).__init__(logger=logger,dry=dry)
+    def __init__(self, dry = False, max = 10):
+        super(ParallelShell, self).__init__(dry=dry)
         self.running = {}
         self.max = max # maximum of commands to run in parallel
     def async(self, proc, args, python, on_success, on_error):
@@ -122,6 +107,22 @@ class ParallelShell(Shell):
 class DummyParallelShell(ParallelShell):
     """Same API as ParallelShell, but doesn't actually parallelize (by
     using only one thread)"""
-    def __init__(self, logger = False, dry = False):
-        super(DummyParallelShell, self).__init__(logger, dry, max=1)
+    def __init__(self, dry = False):
+        super(DummyParallelShell, self).__init__(dry=dry, max=1)
+
+class CallError(wizard.Error):
+    def __init__(self, code, args, stdout, stderr):
+        self.code = code
+        self.args = args
+        self.stdout = stdout
+        self.stderr = stderr
+    def __str__(self):
+        return "CallError [%d]" % self.code
+
+class PythonCallError(CallError):
+    def __init__(self, code, args, stdout, stderr):
+        self.name = util.get_exception_name(stderr)
+        CallError.__init__(self, code, args, stdout, stderr)
+    def __str__(self):
+        return "PythonCallError [%s]" % self.name