[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r17319: {updater} Add win32 registry support to thandy. untested. (in updater/trunk: lib/thandy lib/thandy/packagesys samples)



Author: nickm
Date: 2008-11-17 15:55:28 -0500 (Mon, 17 Nov 2008)
New Revision: 17319

Modified:
   updater/trunk/lib/thandy/formats.py
   updater/trunk/lib/thandy/packagesys/ExePackages.py
   updater/trunk/lib/thandy/packagesys/PackageDB.py
   updater/trunk/lib/thandy/util.py
   updater/trunk/samples/example-package.cfg
Log:
Add win32 registry support to thandy. untested.

Modified: updater/trunk/lib/thandy/formats.py
===================================================================
--- updater/trunk/lib/thandy/formats.py	2008-11-17 20:00:04 UTC (rev 17318)
+++ updater/trunk/lib/thandy/formats.py	2008-11-17 20:55:28 UTC (rev 17319)
@@ -456,6 +456,18 @@
             shortdesc=S.DictOf(S.AnyStr(), S.AnyStr()),
             longdesc=S.DictOf(S.AnyStr(), S.AnyStr()))
 
+def checkWinRegistryKeyname(keyname):
+    """Check keyname for superficial well-formedness as a win32 registry entry
+       name."""
+    hkey, rest = keyname.split("\\", 1)
+    key, value = rest.rsplit("\\", 1)
+    if hkey not in [ "HKEY_CURRENT_CONFIG",
+                     "HKEY_CURRENT_USER",
+                     "HKEY_LOCAL_MACHINE" ]:
+        raise thandy.FormatException("Bad hkey on registry entry.")
+    elif not key or not value:
+        raise thandy.FormatException("Bad registry entry.")
+
 ALL_ROLES = ('timestamp', 'mirrors', 'bundle', 'package', 'master')
 
 class Key:
@@ -613,7 +625,8 @@
                         'format',
                         'location',
                         'relpath',
-                        ], ['rpm_version', 'exe_args'], preload)
+                        ], ['rpm_version', 'exe_args',
+                            'exe_registry_ent' ], preload)
 
     f = open(package_fname, 'rb')
     digest = getFileDigest(f)
@@ -633,12 +646,20 @@
 
     if format == 'rpm':
         if not r.get('rpm_version'):
-            raise Thandy.FormatException("missing rpm_version value")
+            raise thandy.FormatException("missing rpm_version value")
         extra['rpm_version'] = r['rpm_version']
     elif format == 'exe':
         if not r.get('exe_args'):
-            raise Thandy.FormatException("missing exe_args value")
+            raise thandy.FormatException("missing exe_args value")
         extra['exe_args'] = r['exe_args']
+        if r.get('exe_registry_ent'):
+            if len(exe_registry_ent) != 2:
+                raise thandy.FormatException("Bad length on exe_registry_ent")
+            regkey, regval = r['exe_registry_ent']
+            checkWinRegistryKeyname(regkey)
+            if not isinstance(regval, basestring):
+                raise thandy.FormatException("Bad version on exe_registry_ent")
+            extra['registry_ent'] = [ regkey, regval ]
 
     PACKAGE_SCHEMA.checkMatch(result)
 

Modified: updater/trunk/lib/thandy/packagesys/ExePackages.py
===================================================================
--- updater/trunk/lib/thandy/packagesys/ExePackages.py	2008-11-17 20:00:04 UTC (rev 17318)
+++ updater/trunk/lib/thandy/packagesys/ExePackages.py	2008-11-17 20:55:28 UTC (rev 17319)
@@ -31,7 +31,8 @@
                                  [],  # filelist not implemented in this.
                                  rp,
                                  self._repo.getFilename(rp),
-                                 extra['exe_args']))
+                                 arguments=extra['exe_args'],
+                                 registry_ent=extra.get('registry_ent')))
         return handles
 
     def canBeAutomatic(self):
@@ -42,15 +43,33 @@
 
 class ExePackageHandle(pdb.DBBackedPackageHandle):
     def __init__(self, packageDB, name, version, filelist, relpath, filename,
-                 arguments):
+                 arguments, registry_ent=None):
         pdb.DBBackedPackageHandle.__init__(packageDB, name, version, filelist)
         self._relPath = relpath
         self._filename = filename
         self._arguments = arguments
+        self._registry_ent = registry_ent
 
     def getRelativePath(self):
         return self._relPath
 
+    def getInstalledVersion(self, transaction=None):
+        if self._registry_ent != None:
+            ver = thandy.util.getRegistryValue(self._registry_ent[0])
+            if ver != None:
+                return ver
+        else:
+            return pdb.DBBackedPackageHandle.getInstalledVersion(self, transaction)
+
+    def isInstalled(self, transaction=None):
+        if self._registry_ent != None:
+            ver = thandy.util.getRegistryValue(self._registry_ent[0])
+            if ver == self._registry_ent[1]
+                return True
+        else:
+            return pdb.DBBackedPackageHandle.isInstalled(self, transaction)
+
+
     def _doInstall(self):
         commandline = [ self._filename ] + self._arguments
         logging.info("Installing %s.  Command line: %s", self._filename,

Modified: updater/trunk/lib/thandy/packagesys/PackageDB.py
===================================================================
--- updater/trunk/lib/thandy/packagesys/PackageDB.py	2008-11-17 20:00:04 UTC (rev 17318)
+++ updater/trunk/lib/thandy/packagesys/PackageDB.py	2008-11-17 20:55:28 UTC (rev 17319)
@@ -56,7 +56,7 @@
         raise NotImplemented()
 
     def anyVersionInstalled(self, transaction=None):
-        return self._packageDB.getCurVersion(self._name) != None
+        return self.getInstalledVersion(transaction) != None
 
     def getInstalledVersion(self, transaction=None):
         return self._packageDB.getCurVersion(self._name)

Modified: updater/trunk/lib/thandy/util.py
===================================================================
--- updater/trunk/lib/thandy/util.py	2008-11-17 20:00:04 UTC (rev 17318)
+++ updater/trunk/lib/thandy/util.py	2008-11-17 20:55:28 UTC (rev 17319)
@@ -109,3 +109,23 @@
 
     return lst[-1][1]
 
+def getRegistryValue(keyname):
+    """Read the contents of a Windows registry key from a given base."""
+
+    hkey, rest = keyname.split("\\", 1)
+    key, value = rest.rsplit("\\", 1)
+    if not hkey.startswith("HKEY_"):
+        return None
+
+    base = getattr(_winreg, hkey)
+    settings = None
+
+    try:
+        try:
+            settings = _winreg.OpenKey(base, key)
+            return _winreg.QueryValueEx(settings, value)[0]
+        except (WindowsError, ValueError, TypeError):
+            return None
+    finally:
+        if settings is not None:
+            settings.close()

Modified: updater/trunk/samples/example-package.cfg
===================================================================
--- updater/trunk/samples/example-package.cfg	2008-11-17 20:00:04 UTC (rev 17318)
+++ updater/trunk/samples/example-package.cfg	2008-11-17 20:55:28 UTC (rev 17319)
@@ -37,8 +37,17 @@
 #  # that does not have its own built-in installation mechanism.)
 #
 # format = "exe"
+#
 # # What arguments do you pass to this package to install it?
 # # This needs to be a list of strings.
 # exe_args = [ "--silent", "--automatic", "--omit-bugs", ]
-
-
+#
+# # Optional: a registry key, value pair for a version number that this
+# # package will set when it installs itself.  The exe is responsible for
+# # setting this value; thandy only reads the value to see whether the
+# # exe is installed.
+# #    (Remember to prefix your registry string with r, so that the internal
+# # backslashes are automatically escaped.)
+#
+# exe_registry_ent = [ r'HKEY_LOCAL_MACHINE\Software\Blahblahblach\Version',
+#                      '0.1.2' ]