More documentation.
[nodemanager.git] / accounts.py
index b22a4ba..e476977 100644 (file)
@@ -7,16 +7,30 @@ import logger
 import tools
 
 
+# shell path -> account class association
+shell_acct_class = {}
+# account type -> account class association
+type_acct_class = {}
+
+def register_class(acct_class):
+    """Call once for each account class.  This method adds the class to the dictionaries used to ook up account classes by shell and type."""
+    shell_acct_class[acct_class.SHELL] = acct_class
+    type_acct_class[acct_class.TYPE] = acct_class
+
+
+# private account name -> worker object association and associated lock
 _name_worker_lock = threading.Lock()
 _name_worker = {}
 
 def all():
+    """Returns a list of all NM accounts on the system.  Format is (type, username)."""
     pw_ents = pwd.getpwall()
     for pw_ent in pw_ents:
-        if pw_ent[6] in acct_class_by_shell:
-            yield acct_class_by_shell[pw_ent[6]].TYPE, pw_ent[0]
+        if pw_ent[6] in shell_acct_class:
+            yield shell_acct_class[pw_ent[6]].TYPE, pw_ent[0]
 
 def get(name):
+    """Return the worker object for a particular username.  If no such object exists, create it first."""
     _name_worker_lock.acquire()
     try:
         if name not in _name_worker: _name_worker[name] = Worker(name)
@@ -35,33 +49,29 @@ def install_ssh_keys(rec):
     tools.fork_as(rec['name'], do_installation)
 
 
-TYPES = []
-acct_class_by_shell = {}
-acct_class_by_type = {}
-
-def register_account_type(acct_class):
-    TYPES.append(acct_class.TYPE)
-    acct_class_by_shell[acct_class.SHELL] = acct_class
-    acct_class_by_type[acct_class.TYPE] = acct_class
-
-
 class Worker:
     # these semaphores are acquired before creating/destroying an account
     _create_sem = threading.Semaphore(1)
     _destroy_sem = threading.Semaphore(1)
 
     def __init__(self, name):
+        # username
         self.name = name
+        # the account object currently associated with this worker
         self._acct = None
+        # task list
+        # outsiders request operations by putting (fn, args...) tuples on _q
+        # the worker thread (created below) will perform these operations in order
         self._q = Queue.Queue()
         tools.as_daemon_thread(self._run)
 
     def ensure_created(self, rec):
+        """Caused the account specified by <rec> to exist if it doesn't already."""
         self._q.put((self._ensure_created, tools.deepcopy(rec)))
 
     def _ensure_created(self, rec):
         curr_class = self._get_class()
-        next_class = acct_class_by_type[rec['account_type']]
+        next_class = type_acct_class[rec['account_type']]
         if next_class != curr_class:
             self._destroy(curr_class)
             self._create_sem.acquire()
@@ -94,7 +104,7 @@ class Worker:
     def _get_class(self):
         try: shell = pwd.getpwnam(self.name)[6]
         except KeyError: return None
-        return acct_class_by_shell[shell]
+        return shell_acct_class[shell]
 
     def _make_acct_obj(self):
         curr_class = self._get_class()