summaryrefslogtreecommitdiffstats
path: root/src/lib/Client/Tools/APT.py
diff options
context:
space:
mode:
authorSol Jerome <sol.jerome@gmail.com>2012-03-24 11:20:07 -0500
committerSol Jerome <sol.jerome@gmail.com>2012-03-24 11:20:07 -0500
commitdab1d03d81c538966d03fb9318a4588a9e803b44 (patch)
treef51e27fa55887e9fb961766805fe43f0da56c5b9 /src/lib/Client/Tools/APT.py
parent5cd6238df496a3cea178e4596ecd87967cce1ce6 (diff)
downloadbcfg2-dab1d03d81c538966d03fb9318a4588a9e803b44.tar.gz
bcfg2-dab1d03d81c538966d03fb9318a4588a9e803b44.tar.bz2
bcfg2-dab1d03d81c538966d03fb9318a4588a9e803b44.zip
Allow to run directly from a git checkout (#1037)
Signed-off-by: Sol Jerome <sol.jerome@gmail.com>
Diffstat (limited to 'src/lib/Client/Tools/APT.py')
-rw-r--r--src/lib/Client/Tools/APT.py271
1 files changed, 0 insertions, 271 deletions
diff --git a/src/lib/Client/Tools/APT.py b/src/lib/Client/Tools/APT.py
deleted file mode 100644
index 6b839ffbc..000000000
--- a/src/lib/Client/Tools/APT.py
+++ /dev/null
@@ -1,271 +0,0 @@
-"""This is the Bcfg2 support for apt-get."""
-
-# suppress apt API warnings
-import warnings
-warnings.filterwarnings("ignore", "apt API not stable yet",
- FutureWarning)
-import apt.cache
-import os
-
-import Bcfg2.Client.Tools
-import Bcfg2.Options
-
-# Options for tool locations
-opts = {'install_path': Bcfg2.Options.CLIENT_APT_TOOLS_INSTALL_PATH,
- 'var_path': Bcfg2.Options.CLIENT_APT_TOOLS_VAR_PATH,
- 'etc_path': Bcfg2.Options.CLIENT_SYSTEM_ETC_PATH}
-setup = Bcfg2.Options.OptionParser(opts)
-setup.parse([])
-install_path = setup['install_path']
-var_path = setup['var_path']
-etc_path = setup['etc_path']
-DEBSUMS = '%s/bin/debsums' % install_path
-APTGET = '%s/bin/apt-get' % install_path
-DPKG = '%s/bin/dpkg' % install_path
-
-class APT(Bcfg2.Client.Tools.Tool):
- """The Debian toolset implements package and service operations and inherits
- the rest from Toolset.Toolset.
-
- """
- name = 'APT'
- __execs__ = [DEBSUMS, APTGET, DPKG]
- __handles__ = [('Package', 'deb'), ('Path', 'ignore')]
- __req__ = {'Package': ['name', 'version'], 'Path': ['type']}
-
- def __init__(self, logger, setup, config):
- Bcfg2.Client.Tools.Tool.__init__(self, logger, setup, config)
- path_entries = os.environ['PATH'].split(':')
- for reqdir in ['/sbin', '/usr/sbin']:
- if reqdir not in path_entries:
- os.environ['PATH'] = os.environ['PATH'] + ':' + reqdir
- self.pkgcmd = '%s ' % APTGET + \
- '-o DPkg::Options::=--force-overwrite ' + \
- '-o DPkg::Options::=--force-confold ' + \
- '-o DPkg::Options::=--force-confmiss ' + \
- '--reinstall ' + \
- '--force-yes '
- if not self.setup['debug']:
- self.pkgcmd += '-q=2 '
- self.pkgcmd += '-y install %s'
- self.ignores = [entry.get('name') for struct in config \
- for entry in struct \
- if entry.tag == 'Path' and \
- entry.get('type') == 'ignore']
- self.__important__ = self.__important__ + \
- ["%s/cache/debconf/config.dat" % var_path,
- "%s/cache/debconf/templates.dat" % var_path,
- '/etc/passwd', '/etc/group',
- '%s/apt/apt.conf' % etc_path,
- '%s/dpkg/dpkg.cfg' % etc_path] + \
- [entry.get('name') for struct in config for entry in struct \
- if entry.tag == 'Path' and \
- entry.get('name').startswith('%s/apt/sources.list' % etc_path)]
- self.nonexistent = [entry.get('name') for struct in config for entry in struct \
- if entry.tag == 'Path' and entry.get('type') == 'nonexistent']
- os.environ["DEBIAN_FRONTEND"] = 'noninteractive'
- self.actions = {}
- if self.setup['kevlar'] and not self.setup['dryrun']:
- self.cmd.run("%s --force-confold --configure --pending" % DPKG)
- self.cmd.run("%s clean" % APTGET)
- try:
- self.pkg_cache = apt.cache.Cache()
- except SystemError:
- e = sys.exc_info()[1]
- self.logger.info("Failed to initialize APT cache: %s" % e)
- raise Bcfg2.Client.Tools.toolInstantiationError
- self.pkg_cache.update()
- self.pkg_cache = apt.cache.Cache()
- if 'req_reinstall_pkgs' in dir(self.pkg_cache):
- self._newapi = True
- else:
- self._newapi = False
-
- def FindExtra(self):
- """Find extra packages."""
- packages = [entry.get('name') for entry in self.getSupportedEntries()]
- if self._newapi:
- extras = [(p.name, p.installed.version) for p in self.pkg_cache
- if p.is_installed and p.name not in packages]
- else:
- extras = [(p.name, p.installedVersion) for p in self.pkg_cache
- if p.isInstalled and p.name not in packages]
- return [Bcfg2.Client.XML.Element('Package', name=name, \
- type='deb', version=version) \
- for (name, version) in extras]
-
- def VerifyDebsums(self, entry, modlist):
- output = self.cmd.run("%s -as %s" % (DEBSUMS, entry.get('name')))[1]
- if len(output) == 1 and "no md5sums for" in output[0]:
- self.logger.info("Package %s has no md5sums. Cannot verify" % \
- entry.get('name'))
- entry.set('qtext', "Reinstall Package %s-%s to setup md5sums? (y/N) " \
- % (entry.get('name'), entry.get('version')))
- return False
- files = []
- for item in output:
- if "checksum mismatch" in item:
- files.append(item.split()[-1])
- elif "changed file" in item:
- files.append(item.split()[3])
- elif "can't open" in item:
- if item.split()[5] not in self.nonexistent:
- files.append(item.split()[5])
- elif "missing file" in item and \
- item.split()[3] in self.nonexistent:
- # these files should not exist
- continue
- elif "is not installed" in item or "missing file" in item:
- self.logger.error("Package %s is not fully installed" \
- % entry.get('name'))
- else:
- self.logger.error("Got Unsupported pattern %s from debsums" \
- % item)
- files.append(item)
- files = list(set(files) - set(self.ignores))
- # We check if there is file in the checksum to do
- if files:
- # if files are found there we try to be sure our modlist is sane
- # with erroneous symlinks
- modlist = [os.path.realpath(filename) for filename in modlist]
- bad = [filename for filename in files if filename not in modlist]
- if bad:
- self.logger.debug("It is suggested that you either manage these "
- "files, revert the changes, or ignore false "
- "failures:")
- self.logger.info("Package %s failed validation. Bad files are:" % \
- entry.get('name'))
- self.logger.info(bad)
- entry.set('qtext',
- "Reinstall Package %s-%s to fix failing files? (y/N) " % \
- (entry.get('name'), entry.get('version')))
- return False
- return True
-
- def VerifyPackage(self, entry, modlist, checksums=True):
- """Verify package for entry."""
- if not 'version' in entry.attrib:
- self.logger.info("Cannot verify unversioned package %s" %
- (entry.attrib['name']))
- return False
- pkgname = entry.get('name')
- if self.pkg_cache.has_key(pkgname):
- if self._newapi:
- is_installed = self.pkg_cache[pkgname].is_installed
- else:
- is_installed = self.pkg_cache[pkgname].isInstalled
- if not self.pkg_cache.has_key(pkgname) or not is_installed:
- self.logger.info("Package %s not installed" % (entry.get('name')))
- entry.set('current_exists', 'false')
- return False
-
- pkg = self.pkg_cache[pkgname]
- if self._newapi:
- installed_version = pkg.installed.version
- candidate_version = pkg.candidate.version
- else:
- installed_version = pkg.installedVersion
- candidate_version = pkg.candidateVersion
- if entry.get('version') == 'auto':
- if self._newapi:
- is_upgradable = self.pkg_cache._depcache.is_upgradable(pkg._pkg)
- else:
- is_upgradable = self.pkg_cache._depcache.IsUpgradable(pkg._pkg)
- if is_upgradable:
- desiredVersion = candidate_version
- else:
- desiredVersion = installed_version
- elif entry.get('version') == 'any':
- desiredVersion = installed_version
- else:
- desiredVersion = entry.get('version')
- if desiredVersion != installed_version:
- entry.set('current_version', installed_version)
- entry.set('qtext', "Modify Package %s (%s -> %s)? (y/N) " % \
- (entry.get('name'), entry.get('current_version'),
- desiredVersion))
- return False
- else:
- # version matches
- if not self.setup['quick'] and entry.get('verify', 'true') == 'true' \
- and checksums:
- pkgsums = self.VerifyDebsums(entry, modlist)
- return pkgsums
- return True
-
- def Remove(self, packages):
- """Deal with extra configuration detected."""
- pkgnames = " ".join([pkg.get('name') for pkg in packages])
- self.pkg_cache = apt.cache.Cache()
- if len(packages) > 0:
- self.logger.info('Removing packages:')
- self.logger.info(pkgnames)
- for pkg in pkgnames.split(" "):
- try:
- if self._newapi:
- self.pkg_cache[pkg].mark_delete(purge=True)
- else:
- self.pkg_cache[pkg].markDelete(purge=True)
- except:
- if self._newapi:
- self.pkg_cache[pkg].mark_delete()
- else:
- self.pkg_cache[pkg].markDelete()
- try:
- self.pkg_cache.commit()
- except SystemExit:
- # thank you python-apt 0.6
- pass
- self.pkg_cache = apt.cache.Cache()
- self.modified += packages
- self.extra = self.FindExtra()
-
- def Install(self, packages, states):
- # it looks like you can't install arbitrary versions of software
- # out of the pkg cache, we will still need to call apt-get
- ipkgs = []
- bad_pkgs = []
- for pkg in packages:
- if not self.pkg_cache.has_key(pkg.get('name')):
- self.logger.error("APT has no information about package %s" % (pkg.get('name')))
- continue
- if pkg.get('version') in ['auto', 'any']:
- if self._newapi:
- ipkgs.append("%s=%s" % (pkg.get('name'),
- self.pkg_cache[pkg.get('name')].candidate.version))
- else:
- ipkgs.append("%s=%s" % (pkg.get('name'),
- self.pkg_cache[pkg.get('name')].candidateVersion))
- continue
- if self._newapi:
- avail_vers = [x.ver_str for x in \
- self.pkg_cache[pkg.get('name')]._pkg.version_list]
- else:
- avail_vers = [x.VerStr for x in \
- self.pkg_cache[pkg.get('name')]._pkg.VersionList]
- if pkg.get('version') in avail_vers:
- ipkgs.append("%s=%s" % (pkg.get('name'), pkg.get('version')))
- continue
- else:
- self.logger.error("Package %s: desired version %s not in %s" \
- % (pkg.get('name'), pkg.get('version'),
- avail_vers))
- bad_pkgs.append(pkg.get('name'))
- if bad_pkgs:
- self.logger.error("Cannot find correct versions of packages:")
- self.logger.error(bad_pkgs)
- if not ipkgs:
- return
- rc = self.cmd.run(self.pkgcmd % (" ".join(ipkgs)))[0]
- if rc:
- self.logger.error("APT command failed")
- self.pkg_cache = apt.cache.Cache()
- self.extra = self.FindExtra()
- for package in packages:
- states[package] = self.VerifyPackage(package, [], checksums=False)
- if states[package]:
- self.modified.append(package)
-
- def VerifyPath(self, entry, _):
- """Do nothing here since we only verify Path type=ignore."""
- return True