]> scripts.mit.edu Git - wizard.git/commitdiff
Generalize some util functions.
authorEdward Z. Yang <ezyang@mit.edu>
Thu, 13 Aug 2009 03:11:23 +0000 (23:11 -0400)
committerEdward Z. Yang <ezyang@mit.edu>
Thu, 13 Aug 2009 03:13:17 +0000 (23:13 -0400)
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
doc/module/wizard.util.rst
wizard/shell.py
wizard/util.py

index 3104566169e67800983ca60b3b51b983952826cd..9971a2bc99d63c215803d359f7cafb1ac11b09d6 100644 (file)
@@ -17,7 +17,7 @@ Functions
 .. autofunction:: get_dir_owner
 .. autofunction:: get_revision
 .. autofunction:: get_operator_info
-.. autofunction:: get_operator_name
+.. autofunction:: get_operator_name_from_gssapi
 .. autofunction:: get_operator_git
 .. autofunction:: set_operator_env
 .. autofunction:: set_author_env
index c7c7c3e516606a3e8aed73beabd714185df09dcd..963f3804b4817ec2cecedceda3317bae7b201299 100644 (file)
@@ -122,9 +122,9 @@ class Shell(object):
         uid = kwargs.pop("uid", None)
         kwargs.setdefault("python", is_python(args))
         if not user and not uid: return self.call(*args, **kwargs)
-        if util.get_operator_name():
+        if os.getenv("SSH_GSSAPI_NAME"):
             # This might be generalized as "preserve some environment"
-            args.insert(0, "SSH_GSSAPI_NAME=" + util.get_operator_name())
+            args.insert(0, "SSH_GSSAPI_NAME=" + os.getenv("SSH_GSSAPI_NAME"))
         if uid: return self.call("sudo", "-u", "#" + str(uid), *args, **kwargs)
         if user: return self.call("sudo", "-u", user, *args, **kwargs)
     def safeCall(self, *args, **kwargs):
index 2b244de5cbbd4c3194ecf68a463110accea46673..690bc930c4e58c6736aa2d23901d2503709767fb 100644 (file)
@@ -11,6 +11,7 @@ import os
 import subprocess
 import pwd
 import sys
+import socket
 
 import wizard
 
@@ -86,9 +87,12 @@ def get_dir_owner(dir = "."):
     .. note::
 
         This function uses the passwd database and thus
-        only works on scripts servers.
+        only works on scripts servers when querying directories
+        that live on AFS.
     """
-    return pwd.getpwuid(get_dir_uid(dir)).pw_name
+    pwentry = pwd.getpwuid(get_dir_uid(dir))
+    # XXX: Error handling!
+    return pwentry.pw_name
 
 def get_revision():
     """Returns the commit ID of the current Wizard install."""
@@ -97,15 +101,34 @@ def get_revision():
 
 def get_operator_info():
     """
-    Returns tuple of ``(realname, email)`` from Hesiod about the
-    this operator of this script from :func:`get_operator_name`.
-    Useful when generating commit messages.
-    """
-    username = get_operator_name()
-    hesinfo = subprocess.Popen(["hesinfo", username, "passwd"],stdout=subprocess.PIPE).communicate()[0]
-    fields = hesinfo.partition(",")[0]
-    realname = fields.rpartition(":")[2]
-    return realname, username + "@mit.edu"
+    Returns tuple of ``(realname, email)`` about the person running
+    the script.  If run from a scripts server, get info from Hesiod.
+    Otherwise, use the passwd database (email generated probably won't
+    actually accept mail).  Useful when generating commit messages.
+    """
+    username = get_operator_name_from_gssapi()
+    if username:
+        # scripts approach
+        hesinfo = subprocess.Popen(["hesinfo", username, "passwd"],stdout=subprocess.PIPE).communicate()[0]
+        fields = hesinfo.partition(",")[0]
+        realname = fields.rpartition(":")[2]
+        return realname, username + "@mit.edu"
+    else:
+        # more traditional approach, but the email probably doesn't work
+        uid = os.getuid()
+        if not uid:
+            # since root isn't actually a useful designation, but maybe
+            # SUDO_USER contains something helpful
+            sudo_user = os.getenv("SUDO_USER")
+            if not sudo_user:
+                raise NoOperatorInfo
+            pwdentry = pwd.getpwnam(sudo_user)
+        else:
+            pwdentry = pwd.getpwuid(uid)
+        # XXX: error checking might be nice
+        # We follow the Ubuntu convention of gecos being a comma split field
+        # with the person's realname being the first entry.
+        return pwdentry.pw_gecos.split(",")[0], pwdentry.pw_name + "@" + socket.gethostname()
 
 def get_operator_git():
     """
@@ -114,11 +137,10 @@ def get_operator_git():
     """
     return "%s <%s>" % get_operator_info()
 
-def get_operator_name():
+def get_operator_name_from_gssapi():
     """
     Returns username of the person operating this script based
-    off of the :envvar:`SSH_GSSAPI_NAME` environment variable.  Throws
-    :exc:`NoOperatorInfo` if environment variable is not available.
+    off of the :envvar:`SSH_GSSAPI_NAME` environment variable.
 
     .. note::
 
@@ -127,7 +149,8 @@ def get_operator_name():
         environment variable.
     """
     principal = os.getenv("SSH_GSSAPI_NAME")
-    if not principal: raise NoOperatorInfo
+    if not principal:
+        return None
     instance, _, _ = principal.partition("@")
     if instance.endswith("/root"):
         username, _, _ = principal.partition("/")
@@ -154,6 +177,8 @@ def set_author_env():
     variables if applicable. Does nothing if :func:`get_dir_owner` fails.
     """
     try:
+        # XXX: should check if the directory is in AFS, and if not, use
+        # a more traditional metric
         lockername = get_dir_owner()
         os.putenv("GIT_AUTHOR_NAME", "%s locker" % lockername)
         os.putenv("GIT_AUTHOR_EMAIL", "%s@scripts.mit.edu" % lockername)