From 3bef6462fa8117dde2f55a3ff06dbf1b1a8e02a8 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 30 Nov 2008 06:19:04 +0000 Subject: Big thandy installation refactoring. Things should be saner now: we recognize that checking an item is sometimes orthogonal to installing it; we do not carry around big bits of unimplemented machinery; we actually document what stuff does in thandy-spec.txt; we do more OO in the places that make sense and less in the places that do not; and almost as an afterthought, we support the command installer type internally. Now all we need is a frontend to make command installers. git-svn-id: file:///home/or/svnrepo/updater/trunk@17414 55e972cd-5a19-0410-ae62-a4d7a52db4cd --- lib/thandy/packagesys/ExePackages.py | 145 ++++++++++++++++------------------- 1 file changed, 68 insertions(+), 77 deletions(-) (limited to 'lib/thandy/packagesys/ExePackages.py') diff --git a/lib/thandy/packagesys/ExePackages.py b/lib/thandy/packagesys/ExePackages.py index be0517a..59be63e 100644 --- a/lib/thandy/packagesys/ExePackages.py +++ b/lib/thandy/packagesys/ExePackages.py @@ -2,84 +2,75 @@ import subprocess import logging +import re +import os import thandy.util -import thandy.packagesys.PackageSystem as ps -import thandy.packagesys.PackageDB as pdb +import thandy.packagesys.PackageSystem as PS +import thandy.packagesys.PackageDB as PDB + +class RegistryChecker(PS.Checker): + def __init__(self, key, version): + PS.Checker.__init__(self) + self._key = key + self._version = version + + def __repr__(self): + return "RegistryChecker(%r, %r)"%(self._key, self._version) + + def getInstalledVersions(self): + try: + return [ thandy.util.getRegistryValue(self._key) ] + except thandy.util.NoRegistry: + raise thandy.CheckNotSupported("This OS has no registry.") + + def isInstalled(self): + return self._version in self.getInstalledVersions() + +class CommandInstaller(PS.Installer): + def __init__(self, relPath, installCommand, removeCommand=None): + PS.Installer.__init__(self, relPath) + self._installCommand = installCommand + self._removeCommand = removeCommand + + def __repr__(self): + parts = [ "CommandInstaller(%r, %r" %(self._relPath, + self._installCommand) ] + if self.removeCommand: + parts.append(", %r"%self.removeCommand) + parts.append(")") + return "".join(parts) + + def install(self): + self._runCommand(self._installCommand) + + def remove(self): + if self._removeCommand: + raise thandy.RemoveNotSupported() + self._runCommand(self._removeCommand) + + def _runCommand(self, command): + d = { "FILE": self.getFilename() } + def replace(m): + return d[m.group(1)] + try: + c = [ re.sub(r'\$\{([\w_]+)\}', replace, word) for word in command ] + except KeyError: + raise thandy.InstallFailed("Unrecognized option in command %s" + %command) + logging.info("Installing %s. Command is %s", self._relPath, c) + + return_code = self._execute(c) + if return_code != 0: + raise thandy.InstallFailed("Return code %s from calling %s"% + (return_code, c)) + + def _execute(self, cmd): + try: + return subprocess.call(cmd) + except OSError, e: + logging.warn("Error from trying to call %s: %s", cmd, e) + raise thandy.InstallFailed("Could not execute install command %s" + %cmd) -class ExePackageSystem(pdb.DBBackedPackageSystem): - def __init__(self, repo): - pdb.DBBackedPackageSystem.__init__(self) - self._repo = repo - - def getName(self): - return "exe" - - def packageHandlesFromJSON(self, pkg): - if pkg['format'] != 'exe': - raise thandy.FormatException() - - handles = [] - for entry in pkg['files']: - if len(entry) < 3: - continue - rp, h, extra = entry[:3] - version = pkg['version'] - - handles.append( - ExePackageHandle(self.getDB(), - pkg['name'], - version, - [], # filelist not implemented in this. - rp, - self._repo.getFilename(rp), - arguments=extra.get('exe_args', []), - registry_ent=extra.get('registry_ent'))) - return handles - - def canBeAutomatic(self): - return True - - def canHaveUI(self): - return True - -class ExePackageHandle(pdb.DBBackedPackageHandle): - def __init__(self, packageDB, name, version, filelist, relpath, filename, - arguments, registry_ent=None): - pdb.DBBackedPackageHandle.__init__(self, 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: - try: - ver = thandy.util.getRegistryValue(self._registry_ent[0]) - if ver != None: - return ver - except thandy.util.NoRegistry: - pass - - return pdb.DBBackedPackageHandle.getInstalledVersion(self, transaction) - - def isInstalled(self, transaction=None): - if self._registry_ent != None: - try: - ver = thandy.util.getRegistryValue(self._registry_ent[0]) - return ver == self._registry_ent[1] - except thandy.util.NoRegistry: - pass - - return pdb.DBBackedPackageHandle.isInstalled(self, transaction) - - - def _doInstall(self): - commandline = [ self._filename ] + self._arguments - logging.info("Installing %s. Command line: %s", self._filename, - commandline) - subprocess.call(commandline) -- cgit v1.2.3