#!/usr/share/ucs-test/runner python ## desc: Checks if App packages are available as i386 ## tags: [appcenter] ## exposure: dangerous ## packages: ## - univention-directory-manager-tools ## - univention-management-console-module-appcenter # Bug [31792] import apt import univention.management.console.modules.appcenter.app_center as app import univention.lib.package_manager as PM import sys from subprocess import call, Popen, PIPE from univention.config_registry import ConfigRegistry from univention.config_registry.frontend import ucr_update ARCHS = set('i386 amd64'.split()) UCR_ARCH = 'repository/online/architectures' class Test(object): def __init__(self): self.ucr = ConfigRegistry() self.ucr.load() self._ucr_arch_settings = self.ucr.get(UCR_ARCH) self._other_arch = self._get_other_arch() self.cache = apt.Cache() self.cache.open() self.pkg_cache = None self.package_manager = PM.PackageManager() self.installed = {} self.failed = {} def _get_other_arch(self): proc = Popen(('dpkg', '--print-architecture'), stdout=PIPE) stdout, _stderr = proc.communicate() other = ARCHS - set([stdout.strip()]) assert len(other) == 1 return ' '.join(other) def get_installed_default_packages(self): print "Gathering packages of installed apps " apps = app.Application.all() for application in apps: packages = [] pkgs = [] if application.is_installed(self.package_manager): for idefault_package in application.get('defaultpackages'): pkgs.append(idefault_package) if application.get('defaultpackagesmaster'): for idefault_package_master in application.get('defaultpackagesmaster'): pkgs.append(idefault_package_master) while pkgs: current_pkg = pkgs.pop() if current_pkg in packages: continue else: packages.append(current_pkg) pkg = self.cache[current_pkg] def _getDependencies(packages, ignore_if_not_installed=False): for entry in packages: appcenter_dependency = self.get_appcenter_packages_from_cache(entry, ignore_if_not_installed) if appcenter_dependency: pkgs.append(appcenter_dependency) _getDependencies(pkg.installed.dependencies) _getDependencies(pkg.installed.recommends, True) if packages: _list = self.installed.setdefault(application.id, []) for package in packages: _list.append(package) def get_appcenter_packages_from_cache(self, pkg, ignore_if_not_installed=False): new_pkg_name = pkg[0].name try: new_pkg = self.cache[new_pkg_name] except KeyError: try: new_pkg = self.cache.get_providing_packages(new_pkg_name)[0] except: print "Warning: cannot obtain package data for %s ... ignoring (could be a missing recommended package)" % new_pkg_name return None if ignore_if_not_installed and not new_pkg.is_installed: return None if new_pkg and new_pkg.installed and new_pkg.installed.uri: if '://appcenter.'in new_pkg.installed.uri: return(new_pkg_name) def check_packages_available(self): print "Checking if packages are available" for app, app_packages in self.installed.iteritems(): for app_package in app_packages: i386 = None amd64 = None all = None group = apt.apt_pkg.Group(self.pkg_cache, app_package) try: i386 = group.find_package('i386').version_list[0].ver_str except (AttributeError, IndexError): try: all = group.find_package('all').version_list[0].ver_str except (AttributeError, IndexError): pass else: amd64 = group.find_package('amd64').version_list[0].ver_str if not i386 and all: self.failed[app] = { app_package: 'version expected: %s, version found: %s' % (amd64, 'none found'), } if i386 and i386 != amd64: self.failed[app] = { app_package: 'version expected: %s, version found: %s' % (amd64, i386), } def set_multi_architecture(self): if self._other_arch: print "Adding %s architecture" % self._other_arch ucr_update(self.ucr, {UCR_ARCH: ' '.join(ARCHS)}) call(('dpkg', '--add-architecture', self._other_arch)) call(('apt-get', '-qq', 'update')) self.pkg_cache = apt.apt_pkg.Cache() if not self.pkg_cache.is_multi_arch: print "Error adding %s architecture" % self._other_arch sys.exit(1) else: self.pkg_cache = apt.apt_pkg.Cache() def unset_multi_architecture(self): if self._other_arch: print "Restoring architecture settings" ucr_update(self.ucr, {UCR_ARCH: self._ucr_arch_settings}) call(('dpkg', '--remove-architecture', self._other_arch)) if __name__ == "__main__": test = Test() test.get_installed_default_packages() try: test.set_multi_architecture() test.check_packages_available() finally: test.unset_multi_architecture() if test.failed: print "####" print "Missing packages detected:" print test.failed sys.exit(1) else: print "No missing packages detected"