diff options
| author | Nick Mathewson <nickm@torproject.org> | 2008-11-17 20:55:28 +0000 | 
|---|---|---|
| committer | Nick Mathewson <nickm@torproject.org> | 2008-11-17 20:55:28 +0000 | 
| commit | 2fe77ca953e916966a28e4cf3895565a464cc8fd (patch) | |
| tree | 18a50e432b4fe343bc0d223ccd02d3011859e1c0 | |
| parent | e5ec1b2ce20f7578fea683229aadc95431fdb451 (diff) | |
Add win32 registry support to thandy. untested.
git-svn-id: file:///home/or/svnrepo/updater/trunk@17319 55e972cd-5a19-0410-ae62-a4d7a52db4cd
| -rw-r--r-- | lib/thandy/formats.py | 27 | ||||
| -rw-r--r-- | lib/thandy/packagesys/ExePackages.py | 23 | ||||
| -rw-r--r-- | lib/thandy/packagesys/PackageDB.py | 2 | ||||
| -rw-r--r-- | lib/thandy/util.py | 20 | ||||
| -rw-r--r-- | samples/example-package.cfg | 13 | 
5 files changed, 77 insertions, 8 deletions
| diff --git a/lib/thandy/formats.py b/lib/thandy/formats.py index ff65173..e047d87 100644 --- a/lib/thandy/formats.py +++ b/lib/thandy/formats.py @@ -456,6 +456,18 @@ PACKAGE_SCHEMA = S.Obj(              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 @@ def makePackageObj(config_fname, package_fname):                          '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 @@ def makePackageObj(config_fname, package_fname):      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) diff --git a/lib/thandy/packagesys/ExePackages.py b/lib/thandy/packagesys/ExePackages.py index 4989f3a..d82d86e 100644 --- a/lib/thandy/packagesys/ExePackages.py +++ b/lib/thandy/packagesys/ExePackages.py @@ -31,7 +31,8 @@ class ExePackageSystem(pdb.DBBackedPackageSystem):                                   [],  # 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 ExePackageSystem(pdb.DBBackedPackageSystem):  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, diff --git a/lib/thandy/packagesys/PackageDB.py b/lib/thandy/packagesys/PackageDB.py index c829ac3..d4070bf 100644 --- a/lib/thandy/packagesys/PackageDB.py +++ b/lib/thandy/packagesys/PackageDB.py @@ -56,7 +56,7 @@ class DBBackedPackageHandle(thandy.packagesys.PackageSystem.PackageHandle):          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) diff --git a/lib/thandy/util.py b/lib/thandy/util.py index f2bac17..0c0aa9d 100644 --- a/lib/thandy/util.py +++ b/lib/thandy/util.py @@ -109,3 +109,23 @@ def randChooseWeighted(lst):      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() diff --git a/samples/example-package.cfg b/samples/example-package.cfg index 8e0b578..6df6ac0 100644 --- a/samples/example-package.cfg +++ b/samples/example-package.cfg @@ -37,8 +37,17 @@ format = "none"  #  # 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' ] | 
