diff --git a/pisi/api.py b/pisi/api.py index cfcc7724..ec65809f 100644 --- a/pisi/api.py +++ b/pisi/api.py @@ -44,6 +44,7 @@ import pisi.operations.upgrade import pisi.operations.install import pisi.operations.history import pisi.operations.helper +import pisi.operations.check import pisi.operations.emerge import pisi.operations.build import pisi.comariface @@ -274,6 +275,15 @@ def get_conflicts(packages): """ return pisi.conflict.calculate_conflicts(packages, pisi.db.packagedb.PackageDB()) +def check(package, config=False): + """ + Returns a dictionary that contains a list of both corrupted and missing files + @param package: name of the package to be checked + @param config: _only_ check the config files of the package, default behaviour is to check all the files + of the package but the config files + """ + return pisi.operations.check.check_package(package, config) + def search_package(terms, lang=None, repo=None): """ Return a list of packages that contains all the given terms either in its name, summary or @@ -578,30 +588,6 @@ def info_name(package_name, useinstalldb=False): files = None return metadata, files, repo -def check(package): - md, files = info(package, True) - corrupt = [] - for f in files.list: - ctx.ui.info(_("Checking /%s ") % f.path, noln=True, verbose=True) - if os.path.lexists("/%s" % f.path): - if f.hash and f.type != "config": - try: - if os.path.islink("/%s" % f.path): - if f.hash != pisi.util.sha1_data(os.readlink("/%s" % f.path)): - corrupt.append(f) - ctx.ui.error(_("\nCorrupt file: %s") % ("/%s" %f.path)) - elif f.hash != pisi.util.sha1_file("/%s" % f.path): - corrupt.append(f) - ctx.ui.error(_("\nCorrupt file: %s") % ("/%s" %f.path)) - else: - ctx.ui.info(_("OK"), verbose=True) - except pisi.util.FileError,e: - ctx.ui.error("\n%s" % e) - else: - corrupt.append(f) - ctx.ui.error(_("\nMissing file: %s") % ("/%s" % f.path)) - return corrupt - def index(dirs=None, output='pisi-index.xml', skip_sources=False, skip_signing=False): """Accumulate PiSi XML files in a directory, and write an index.""" index = pisi.index.Index() diff --git a/pisi/cli/check.py b/pisi/cli/check.py index 3ff72942..66dd2a5c 100644 --- a/pisi/cli/check.py +++ b/pisi/cli/check.py @@ -47,6 +47,8 @@ If no packages are given, checks all installed packages. group = optparse.OptionGroup(self.parser, _("check options")) group.add_option("-c", "--component", action="store", default=None, help=_("Check installed packages under given component")) + group.add_option("--config", action="store_true", + default=False, help=_("Checks only changed config files of the packages")) self.parser.add_option_group(group) def run(self): @@ -65,12 +67,17 @@ If no packages are given, checks all installed packages. ctx.ui.info(_('Checking all installed packages')) pkgs = pisi.api.list_installed() + check_config = ctx.get_option('config') for pkg in pkgs: ctx.ui.info(_('* Checking %s... ') % pkg, noln=True) if self.installdb.has_package(pkg): - corrupt = pisi.api.check(pkg) - if corrupt: - ctx.ui.info(_('\nPackage %s is corrupt.') % pkg) + check_results = pisi.api.check(pkg, check_config) + corrupted = check_results['missing'] or check_results['corrupted'] + if corrupted: + if check_config: + ctx.ui.info(_('\nPackage %s has changed config files.') % pkg) + else: + ctx.ui.info(_('\nPackage %s is corrupt.') % pkg) else: ctx.ui.info(_("OK"), verbose=False) else: diff --git a/pisi/db/installdb.py b/pisi/db/installdb.py index 5f399bfd..722a1a80 100644 --- a/pisi/db/installdb.py +++ b/pisi/db/installdb.py @@ -125,6 +125,10 @@ class InstallDB(lazydb.LazyDB): files.read(files_xml) return files + def get_config_files(self, package): + files = self.get_files(package) + return filter(lambda x: x.type == 'config', files.list) + def search_package(self, terms, lang=None): resum = '.*?%s.*?' redesc = '.*?%s.*?' diff --git a/pisi/operations/check.py b/pisi/operations/check.py new file mode 100644 index 00000000..30748e9b --- /dev/null +++ b/pisi/operations/check.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2008, TUBITAK/UEKAE +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# Please read the COPYING file. + +import os +import pisi +import pisi.context as ctx + +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + +def file_corrupted(pfile): + if os.path.islink("/%s" % pfile.path): + if pisi.util.sha1_data(os.readlink("/%s" % pfile.path)) != pfile.hash: + return True + else: + if pisi.util.sha1_file("/%s" % pfile.path) != pfile.hash: + return True + return False + +def check_files(files, check_config=False): + results = {'missing':[],'corrupted':[]} + for f in files: + if not check_config and f.type == "config": + continue + if not f.hash: + continue + ctx.ui.info(_("Checking /%s ") % f.path, noln=True, verbose=True) + if os.path.lexists("/%s" % f.path): + if file_corrupted(f): + if f.type == "config": + msg = _("\nChanged config file: %s") + else: + msg = _("\nCorrupt file: %s") + ctx.ui.error(msg % ("/%s" %f.path)) + results['corrupted'].append(f.path) + else: + ctx.ui.info(_("OK"), verbose=True) + else: + results['missing'].append(f.path) + return results + +def check_config_files(package): + config_files = pisi.db.installdb.InstallDB().get_config_files(package) + return check_files(config_files, True) + +def check_package_files(package): + files = pisi.db.installdb.InstallDB().get_files(package).list + return check_files(files) + +def check_package(package, config=False): + if config: + return check_config_files(package) + else: + return check_package_files(package)