From bccd41cb69586b8f7211703d0a4bc0e81d7a7b5a Mon Sep 17 00:00:00 2001 From: Alexander Lakhin Date: Thu, 6 Feb 2014 11:44:02 +0400 Subject: [PATCH] Initial commit --- README | 12 + analyze-repo-redundancy.py | 130 ++++++ analyze-repodb.py | 389 +++++++++++++++++ fill-repodb.py | 538 +++++++++++++++++++++++ i586kde.lst | 870 +++++++++++++++++++++++++++++++++++++ prepare-repodb.py | 380 ++++++++++++++++ repo-analyze-config.xml | 83 ++++ versutils.py | 150 +++++++ x86_64.lst | 868 ++++++++++++++++++++++++++++++++++++ 9 files changed, 3420 insertions(+) create mode 100644 README create mode 100755 analyze-repo-redundancy.py create mode 100755 analyze-repodb.py create mode 100755 fill-repodb.py create mode 100644 i586kde.lst create mode 100755 prepare-repodb.py create mode 100644 repo-analyze-config.xml create mode 100644 versutils.py create mode 100644 x86_64.lst diff --git a/README b/README new file mode 100644 index 0000000..ada8c79 --- /dev/null +++ b/README @@ -0,0 +1,12 @@ +Порядок использования скриптов: + +1. Настроить структуру репозиториев и пути в repo-analyze-config.xml +2. Заполнить базу данных информацией из репозиториев: +fill-repodb.py repo-analyze-config.xml +* Скрипт создаёт в текущем каталоге базу данных repo.db размером около 1 Гб +3. Подготовить базу данных к анализу: +prepare-repodb.py +4. Выполнить анализ/проверки: +analyze-repodb.py +analyze-repo-redundancy.py i586kde.lst --repo rosa-dx-chrome-1.0/i586/main/release >i586-redundant.txt + diff --git a/analyze-repo-redundancy.py b/analyze-repo-redundancy.py new file mode 100755 index 0000000..7ede60f --- /dev/null +++ b/analyze-repo-redundancy.py @@ -0,0 +1,130 @@ +import os +import sys +import argparse +import sqlite3 +import string +import rpm +import re +import gettext +from versutils import * + +gettext.install('urpm-tools') + +DB = 'repo.db' + +def parseargs(args): + parser = argparse.ArgumentParser(description=_('Check repository\'s redundancy for a given list of packages.')) + parser.add_argument('packages_lst', metavar='packages.lst', + help=('path to packages.lst')) + parser.add_argument('--repo', action='append', nargs='+', required=True, + metavar='REPO', help=_('URL or name of a repository')) + opts = parser.parse_args() + return opts + +def main(args): + options = parseargs(args) + with open(options.packages_lst, 'r') as f: + ks_cfg = f.read() + section = None + in_packages = False + sel_packages = [] + for line in ks_cfg.split('\n'): + ls = line.strip() + if ls and not ls.startswith('#'): + sel_packages.append(ls) + + conn = sqlite3.connect(DB) + c = conn.cursor() + repodirs = [] + for repo in options.repo[0]: + print repo + rid = c.execute(""" +SELECT id FROM repodirs WHERE name = ? OR name = ? +""", [repo, repo]).fetchall() + if rid is None: + print 'Repository "%" not found.' % repo + exit(1) + repodirs.append(rid[0][0]) + if not repodirs: + print 'No repositories specified.' + exit(1) + if not sel_packages: + print 'No packages specified.' + exit(1) + in_repodirs = ','.join(str(id) for id in repodirs) + package_ids = [] + for spackage in sel_packages: + packages_found = c.execute(""" +SELECT id, nvra, version, release FROM packages WHERE repodir_id IN (%s) AND name = ? +""" % in_repodirs, [spackage]).fetchall() + if not packages_found: + print 'Package "%s" not found!' % spackage + continue + pid = None + if len(packages_found) > 1: + chosen_nvra = None + chosen_version = None + for vpid in packages_found: + better_found = pid is None + verrel = (vpid[2] if vpid[2] is not None else '') + '-' + \ + (vpid[3] if vpid[3] is not None else '') + if not better_found: + better_found = version_ok(chosen_version, + RPMSENSE_GREATER, + verrel) + if better_found: + pid = vpid[0] + chosen_nvra = vpid[1] + chosen_version = verrel + print ('Multiple versions of "%s" found (%s). Choosing latest: %s.' % + (spackage, ', '.join(cp[1] for cp in packages_found), chosen_nvra)) + else: + pid = packages_found[0][0] + package_ids.append(pid) + + package_cnt = 0 + while package_cnt < len(package_ids): + package_cnt = len(package_ids) + in_packages = ','.join(str(id) for id in package_ids) + for required_package in c.execute(""" +SELECT packages.id, packages.name, nvra + FROM packages, requires + WHERE packages.id = requires.dep_package_id AND + packages.repodir_id IN (%s) AND + requires.package_id IN (%s) AND + packages.id NOT IN (%s) + ORDER BY packages.name +""" % (in_repodirs, in_packages, in_packages)): + package_ids.append(required_package[0]) + + in_packages = ','.join(str(id) for id in package_ids) + pre_repodir_id = -1 + repo_packages_cnt = 0 + for reduntant_package in c.execute(""" +SELECT repodir_id, repodirs.name, packages.id, packages.nvra + FROM packages, repodirs + WHERE packages.repodir_id = repodirs.id AND + repodirs.id IN (%s) AND packages.id NOT IN (%s) + ORDER BY repodir_id, nvra +""" % (in_repodirs, in_packages)): + (repodir_id, repodir_name, package_nvra) = \ + (reduntant_package[0], reduntant_package[1], reduntant_package[3]) + if pre_repodir_id != repodir_id: + if pre_repodir_id == -1: + print 'Redundant packages:' + else: + print 'Total: %d' % repo_packages_cnt + print '' + print '%d) %s' % (repodir_id, repodir_name) + pre_repodir_id = repodir_id + repo_packages_cnt = 0 + print '\t%s' % package_nvra + repo_packages_cnt += 1 + if pre_repodir_id != -1: + print 'Total: %d' % repo_packages_cnt + print '' + + conn.rollback() + +if __name__ == "__main__": + main(sys.argv) diff --git a/analyze-repodb.py b/analyze-repodb.py new file mode 100755 index 0000000..6f2a06d --- /dev/null +++ b/analyze-repodb.py @@ -0,0 +1,389 @@ +import os +import sys +import gettext +import argparse +import sqlite3 +import string +import rpm +import re + +DB = 'repo.db' + +def detect_broken_dependencies(dbc): + def print_broken_packages(): + for rpb_name in sorted(repo_packages_broken.keys()): + rpb_id = repo_packages_broken[rpb_name] + dep_chain = [] + dep_id = all_broken[rpb_id]['depid'] + while dep_id != 0: + dep_chain.append('%s (%d)' % (all_broken[dep_id]['nvra'], all_broken[dep_id]['repo'])) + dep_id = all_broken[dep_id]['depid'] + print '\t' + rpb_name + ' => '+ (' => '.join(dep_chain)) + print 'Total: %d' % len(repo_packages_broken) + print '' + + # Detect broken dependencies with recursion + repodirs_analyzed = [] + broken = {} + broken_level0 = dbc.execute(""" +SELECT packages.id, nvra, repodir_id, repodirs.name, requires.name AS req_name, requires.build_arch AS req_arch + FROM packages, repodirs, requires + WHERE packages.repodir_id = repodirs.id AND packages.id=requires.package_id AND + dep_package_id IS NULL + ORDER BY repodir_id, nvra""").fetchall() + + all_broken = {} + if len(broken_level0) > 0: + print 'Broken dependencies (bottom level):' + bp_reqs = [] + pre_repodir_id = -1 + pre_bp_id = -1 + pre_bp_nvra = -1 + pre_cnt = 0 + for bp in broken_level0: + (bp_id, bp_nvra, bp_repodir_id, bp_repodir_name, bp_reqname, bp_reqarch) = \ + (bp[0], bp[1], bp[2], bp[3], bp[4], bp[5]) + broken[bp_id] = bp_nvra + if pre_bp_id != bp_id and pre_bp_id != -1: + print '\t%s (%s)' % (pre_bp_nvra, ', '.join(bp_reqs)) + pre_cnt += 1 + bp_reqs = [] + if bp_reqarch is not None: + bp_reqname += ':' + bp_reqarch + if bp_reqname not in bp_reqs: + bp_reqs.append(bp_reqname) + if pre_repodir_id != bp_repodir_id: + if pre_repodir_id != -1: + print 'Total: %d' % pre_cnt + print '%d) %s' % (bp_repodir_id, bp_repodir_name) + pre_repodir_id = bp_repodir_id + pre_cnt = 0 + if bp_id not in all_broken: + all_broken[bp_id] = {'repo': bp_repodir_id, 'nvra': bp_nvra, 'reqname': bp_reqname, 'depid': 0} + pre_bp_id = bp_id + pre_bp_nvra = bp_nvra + + if pre_bp_id != -1: + print '\t%s (%s)' % (pre_bp_nvra, ','.join(bp_reqs)) + print 'Total: %d' % pre_cnt + + all_broken_cnt = -1 + broken_recursive = [] + while all_broken_cnt < len(all_broken): + all_broken_cnt = len(all_broken) + pids = ','.join(str(id) for id in all_broken.keys()) + #print pids + packages_broken_recurs = dbc.execute(""" +SELECT packages.id, nvra, repodir_id, repodirs.name, requires.name AS req_name, build_arch, dep_package_id + FROM packages, repodirs, requires + WHERE packages.repodir_id = repodirs.id AND packages.id=requires.package_id AND + dep_package_id IN (%(pids)s) AND packages.id NOT IN (%(pids)s) + ORDER BY repodir_id, nvra""" % {'pids': pids}).fetchall() +# print len(packages_broken_recurs) + for packb in packages_broken_recurs: + all_broken[packb[0]] = {'repo': packb[2], 'nvra': packb[1], 'reqname': packb[4], 'build_arch': packb[5], 'depid': packb[6]} + broken_recursive.append(packb[0]) + #print len(all_broken.keys()) + + if broken_recursive: + print 'Recursive broken dependencies:' + all_repodirs = dbc.execute(""" +SELECT id, name, sources FROM repodirs ORDER BY id""").fetchall() + for rd in all_repodirs: + (rd_id, rd_name, rd_sources) = (rd[0], rd[1], rd[2]) + if rd_sources == '.': + archs = dbc.execute(""" +SELECT DISTINCT build_arch FROM requires WHERE package_id IN (SELECT id FROM packages WHERE repodir_id = ?) +""", [rd_id]).fetchall() + for arch_rec in archs: + repo_packages_broken = {all_broken[id]['nvra']: id for id in broken_recursive \ + if all_broken[id]['repo'] == rd_id and all_broken[id]['build_arch'] == arch_rec[0]} + if repo_packages_broken: + print '%d) %s (%s)' % (rd_id, rd_name, arch_rec[0]) + print_broken_packages() + else: + repo_packages_broken = {all_broken[id]['nvra']: id for id in broken_recursive if all_broken[id]['repo'] == rd_id} + if repo_packages_broken: + print '%d) %s' % (rd_id, rd_name) + print_broken_packages() + + #all_repodirs = dbc.execute(""" +#SELECT id, name FROM repodirs ORDER BY id""").fetchall() + #for rd in all_repodirs: + #(rd_id, rd_name) = (rd[0], rd[1]) + #repo_broken_recurs = dbc.execute(""" +#SELECT packages.id, nvra, requires.name AS req_name + #FROM packages, requires + #WHERE packages.repodir_id = ? AND packages.id=requires.package_id AND + #dep_package_id IS NULL AND packages.id NOT IN() + #""").fetchall() + #print rd_name + + +def detect_lost_sources(dbc): + print '===' + print 'Lost sources:' + repodirs = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs WHERE sources <> '.' ORDER BY id +""").fetchall() + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + lost_sources = dbc.execute(""" +SELECT name, nvra, sourcerpm FROM packages + WHERE repodir_id = ? AND + sourcerpm IS NOT NULL AND sourcerpm_package IS NULL + ORDER BY name +""", [rd_id]).fetchall() + if lost_sources: + print '%d) %s' % (rd_id, rd_name) + for ls in lost_sources: + print '\t%s (%s)' % (ls[1], ls[2]) + print 'Total: %d' % len(lost_sources) + + +def analyze_partitioning(dbc): + print '===' + print 'Possible partitioning:' + repodirs = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs WHERE sources <> '.' ORDER BY id +""").fetchall() + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + partitions = [] + partitioned_packages = [] + singles = [] + while True: + ppackages = ','.join(str(id) for id in partitioned_packages) + if not ppackages: + ppackages = '0' + pkg1_rec = dbc.execute(""" +SELECT id, name, nvra + FROM packages WHERE repodir_id = ? AND id NOT IN (%s) + ORDER BY name + LIMIT 1""" % ppackages, [rd_id]).fetchall() + if not pkg1_rec: + break + if not partitioned_packages: + print '%d) %s' % (rd_id, rd_name) + (pkg_id, pkg_name) = (pkg1_rec[0][0], pkg1_rec[0][2]) + partition_names = [] + partition_names.append(pkg_name) + partition_ids = [] + partition_ids.append(pkg_id) + partitioned_packages.append(pkg_id) + current_level_packages = [pkg_id] + while True: + cl_packages = ','.join(str(id) for id in current_level_packages) + part_packages = ','.join(str(id) for id in partition_ids) + upper_packages = dbc.execute(""" +SELECT packages.id, packages.name, nvra + FROM packages, requires + WHERE packages.id = requires.package_id AND + packages.repodir_id = ? AND + requires.dep_package_id IN (%s) AND + packages.id NOT IN (%s) + ORDER BY packages.name +""" % (cl_packages, part_packages), [rd_id]).fetchall() + + lower_packages = dbc.execute(""" +SELECT packages.id, packages.name, nvra + FROM packages, requires + WHERE packages.id = requires.dep_package_id AND + packages.repodir_id = ? AND + requires.package_id IN (%s) AND + packages.id NOT IN (%s) + ORDER BY packages.name +""" % (cl_packages, part_packages), [rd_id]).fetchall() + + if not upper_packages and not lower_packages: + break + current_level_packages = [] + for rec in upper_packages: + if rec[0] not in current_level_packages: + current_level_packages.append(rec[0]) + partitioned_packages.append(rec[0]) + partition_ids.append(rec[0]) + partition_names.append(rec[2]) + for rec in lower_packages: + if rec[0] not in current_level_packages: + current_level_packages.append(rec[0]) + partitioned_packages.append(rec[0]) + partition_ids.append(rec[0]) + partition_names.append(rec[2]) + + if len(partition_names) == 1: + #print partition_names + singles.append(partition_names[0]) + #raise Exception('aaa') + else: + for p in sorted(partition_names): + print '\t%s', p + print 'Total: %d' % len(partition_names) + print '---' + print '' + + if len(singles) > 0: + print 'Singles:' + for s in sorted(singles): + print '\t%s' % s + print 'Total: %d' % len(singles) + +def detect_lost_object_files(dbc): + print '===' + print 'Lost object (executable) files (provided but not found):' + repodirs = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs ORDER BY id +""").fetchall() + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + lost_object_files = dbc.execute(""" +SELECT nvra, package_files.path, mark + FROM packages, package_files + WHERE repodir_id = ? AND packages.id = package_files.package_id AND mark = 'not-found' + ORDER BY packages.name, package_files.path +""", [rd_id]).fetchall() + if lost_object_files: + print '%d) %s' % (rd_id, rd_name) + for lof in lost_object_files: + print '\t%s: %s' % (lof[0], lof[1]) + print 'Total: %d' % len(lost_object_files) + +def detect_broken_object_links(dbc): + print '===' + print 'Invalid object (executable) file links:' + repodirs = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs ORDER BY id +""").fetchall() + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + broken_object_links = dbc.execute(""" +SELECT nvra, package_files.path, link_to_path, mark + FROM packages, package_files + WHERE repodir_id = ? AND packages.id = package_files.package_id AND + mark = 'link' AND link_to_path IS NOT NULL AND link_to_file_id IS NULL + ORDER BY packages.name, package_files.path +""", [rd_id]).fetchall() + if broken_object_links: + print '%d) %s' % (rd_id, rd_name) + for bol in broken_object_links: + print '\t%s: %s -/-> %s' % \ + (bol[0], bol[1], bol[2]) + print 'Total: %d' % len(broken_object_links) + +def get_repodir_depends(dbc, repodir_id): + dep_repos = dbc.execute(""" +SELECT depend_repodir_name FROM repodir_depends WHERE repodir_id = ? +""", [repodir_id]).fetchall() + return ', '.join([dep_repo[0] for dep_repo in dep_repos]) + +def detect_so_needed_not_found(dbc): + repodirs = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs ORDER BY id +""").fetchall() + print '===' + print 'Objects needed and resolved by rpm requires-provides:' + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + objects_needed_resolved1 = dbc.execute(""" +SELECT COUNT(1) FROM packages CROSS JOIN package_files CROSS JOIN so_needed CROSS JOIN so_needed_res + WHERE repodir_id = ? AND package_files.package_id = packages.id AND + so_needed.obj_file_id = package_files.id AND so_needed_id = so_needed.id AND res_type = 1 +""", [rd_id]).fetchone() + print '%d) %s: %d' % (rd_id, rd_name, objects_needed_resolved1[0]) + + print '===' + print 'Objects needed and resolved by flat search:' + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + objects_needed_resolved2 = dbc.execute(""" +SELECT COUNT(1) FROM packages CROSS JOIN package_files CROSS JOIN so_needed CROSS JOIN so_needed_res + WHERE repodir_id = ? AND package_files.package_id = packages.id AND + so_needed.obj_file_id = package_files.id AND so_needed_id = so_needed.id AND res_type = 2 +""", [rd_id]).fetchone() + print '%d) %s: %d' % (rd_id, rd_name, objects_needed_resolved2[0]) + + print '===' + print 'Objects needed but not resolved:' + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + objects_needed_not_resolved = dbc.execute(""" +SELECT packages.nvra, package_files.path, so_needed.name + FROM packages CROSS JOIN package_files CROSS JOIN so_needed + LEFT OUTER JOIN so_needed_res ON so_needed_id = so_needed.id + WHERE repodir_id = ? AND package_files.package_id = packages.id AND + so_needed.obj_file_id = package_files.id AND so_needed_id IS NULL +""", [rd_id]).fetchall() + if objects_needed_not_resolved: + repodir_depends = get_repodir_depends(dbc, rd_id) + print ('%d) %s' % (rd_id, rd_name)) + \ + ('' if repodir_depends == '' else + (' (depends on: %s)' % repodir_depends)) + for obj_nr in objects_needed_not_resolved: + print '\t%s: %s -?-> %s' % (obj_nr[0], obj_nr[1], obj_nr[2]) + print 'Total: %d' % len(objects_needed_not_resolved) + +def detect_symbols_not_found(dbc): + repodirs = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs ORDER BY id +""").fetchall() + + print '===' + print 'Symbols resolved by .so NEEDED search:' + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + symbols_resolved1_2 = dbc.execute(""" +SELECT COUNT(1) FROM packages CROSS JOIN package_files CROSS JOIN obj_symbols CROSS JOIN obj_symbols_res + WHERE packages.repodir_id = ? AND packages.id = package_files.package_id AND + package_files.id = obj_symbols.obj_file_id AND sym_type = 0 AND + obj_symbols_res.obj_sym_id = obj_symbols.id AND res_type IN (1, 2) +""", [rd_id]).fetchone() + print '%d) %s: %d' % (rd_id, rd_name, symbols_resolved1_2[0]) + + + print '===' + print 'Symbols resolved by flat search:' + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + symbols_resolved3 = dbc.execute(""" +SELECT COUNT(1) FROM packages CROSS JOIN package_files CROSS JOIN obj_symbols CROSS JOIN obj_symbols_res + WHERE packages.repodir_id = ? AND packages.id = package_files.package_id AND + package_files.id = obj_symbols.obj_file_id AND sym_type = 0 AND + obj_symbols_res.obj_sym_id = obj_symbols.id AND res_type = 3 +""", [rd_id]).fetchone() + print '%d) %s: %d' % (rd_id, rd_name, symbols_resolved3[0]) + + print '===' + print 'Symbols not resolved:' + for repodir in repodirs: + (rd_id, rd_name) = (repodir[0], repodir[1]) + symbols_not_resolved = dbc.execute(""" +SELECT packages.nvra, package_files.path, obj_symbols.name + FROM packages CROSS JOIN package_files CROSS JOIN obj_symbols + WHERE packages.repodir_id = ? AND packages.id = package_files.package_id AND + package_files.id = obj_symbols.obj_file_id AND sym_type = 0 AND + NOT EXISTS (SELECT 1 FROM obj_symbols_res WHERE obj_sym_id = obj_symbols.id) +""", [rd_id]).fetchall() + if symbols_not_resolved: + repodir_depends = get_repodir_depends(dbc, rd_id) + print ('%d) %s' % (rd_id, rd_name)) + \ + ('' if repodir_depends == '' else + (' (depends on: %s)' % repodir_depends)) + for sym_nr in symbols_not_resolved: + print '\t%s: %s -?-> %s' % (sym_nr[0], sym_nr[1], sym_nr[2]) + print 'Total: %d' % len(symbols_not_resolved) + +def main(args): + + conn = sqlite3.connect(DB) + dbc = conn.cursor() + detect_broken_dependencies(dbc) + detect_lost_sources(dbc) + analyze_partitioning(dbc) + detect_lost_object_files(dbc) + detect_broken_object_links(dbc) + detect_so_needed_not_found(dbc) + detect_symbols_not_found(dbc) + conn.close() + +if __name__ == "__main__": + main(sys.argv) diff --git a/fill-repodb.py b/fill-repodb.py new file mode 100755 index 0000000..b10b355 --- /dev/null +++ b/fill-repodb.py @@ -0,0 +1,538 @@ +# -*- coding: utf-8 -*- + +import os +import sys +import gettext +import argparse +import sqlite3 +import string +import rpm +import re +import tempfile +import xml.etree.ElementTree as ET +import subprocess +import shutil +import time +import multiprocessing as mp +import gc + +gettext.install('urpm-tools') + +DB = 'repo.db' + +NUM_PROCESSES = 4 # number of CPU's (evaluated automatically) + +RPMFILEMODE_DIRECTORY = 0x4000 +RPMFILEMODE_EXECUTE = 0111 + +def getFileList(path, ext, filelist): + extlen = len(ext) + dir_list = os.listdir(path) + + for d in dir_list: + if os.path.isdir(path + '/' + d): + filelist = getFileList(path + '/' + d, ext, filelist) + else: + if string.lower(d[-extlen:]) == '%s' % (ext): + newpath = os.path.normpath(path + '/' + d) + filelist.append(newpath) + return filelist + +def parseargs(args): + parser = argparse.ArgumentParser(description=_('extract packages metadata from RPM repositories')) + parser.add_argument("config", metavar="config", + help=_('path to repo-analyze-config.xml')) + opts = parser.parse_args() + return opts + +def to_string(rpm, tag, val): + if type(val) == type([]): + if not(val): + return None + try: + return str(val).decode('utf-8') + except: + print >> sys.stderr, 'Invalid UTF-8 string!\n(%s:\n%s = "%s")\n' % \ + (rpm, tag, val) + return str(val).decode('utf-8', 'replace') + +def init_database(conn): + conn.execute(""" +CREATE TABLE repodirs(id INTEGER PRIMARY KEY NOT NULL, + name TEXT UNIQUE, path TEXT, arch TEXT, sources TEXT)""") + conn.execute(""" +CREATE TABLE repodir_depends(id INTEGER PRIMARY KEY NOT NULL, + repodir_id INTEGER, depend_repodir_name TEXT)""") + conn.execute(""" +CREATE TABLE IF NOT EXISTS package_files(id INTEGER PRIMARY KEY NOT NULL, + package_id INTEGER NOT NULL, basename TEXT, path TEXT, size INTEGER, mode INTEGER, + link_to_file_id INTEGER, link_to_path TEXT, mark TEXT)""") + conn.execute(""" +CREATE TABLE so_needed(id INTEGER PRIMARY KEY NOT NULL, + obj_file_id INTEGER, name TEXT)""") + conn.execute(""" +CREATE TABLE so_needed_res(id INTEGER PRIMARY KEY NOT NULL, + so_needed_id INTEGER, dep_obj_file_id INTEGER, res_type INTEGER)""") + conn.execute(""" +CREATE TABLE obj_symbols(id INTEGER PRIMARY KEY NOT NULL, + obj_file_id INTEGER, name TEXT, sym_type INTEGER)""") + conn.execute(""" +CREATE TABLE obj_symbols_res(id INTEGER PRIMARY KEY NOT NULL, + obj_sym_id INTEGER, dep_obj_sym_id INTEGER, res_type INTEGER)""") + conn.execute("""PRAGMA synchronous = OFF""") + conn.execute("""PRAGMA journal_mode = OFF""") + +def index_database(conn): + print 'Indexing the database...' +# conn.execute("""CREATE INDEX IF NOT EXISTS rd_rd_id ON repodir_depends(repodir_id)""") +# conn.execute("""CREATE INDEX IF NOT EXISTS rd_drd_id ON repodir_depends(depend_repodir_id)""") + conn.execute('CREATE INDEX IF NOT EXISTS rd_name ON repodirs(name)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_name ON packages(name)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_arch ON packages(nvra)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_arch ON packages(arch)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_group ON packages(rpm_group)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_repodir ON packages(repodir_id)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_file_pkg_id ON package_files(package_id)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_file_name ON package_files(basename)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_file_path ON package_files(path)') + conn.execute('CREATE INDEX IF NOT EXISTS pkg_file_mark ON package_files(mark)') + conn.execute('CREATE INDEX IF NOT EXISTS so_needed_obj_id ON so_needed(obj_file_id)') + conn.execute('CREATE INDEX IF NOT EXISTS so_needed_res_sn ON so_needed_res(so_needed_id)') + conn.execute('CREATE INDEX IF NOT EXISTS symbols_obj_name_type ON obj_symbols(obj_file_id, name, sym_type)') + conn.execute('CREATE INDEX IF NOT EXISTS symbols_name_type ON obj_symbols(name, sym_type)') + conn.execute('CREATE INDEX IF NOT EXISTS symbols_res_sym ON obj_symbols_res(obj_sym_id)') + dep_tables = ['requires', 'provides', 'conflicts', 'obsoletes'] + for table in dep_tables: + conn.execute('CREATE INDEX IF NOT EXISTS %(tbl)s_pkg ON %(tbl)s(package_id)' % {'tbl': table}) + conn.execute('CREATE INDEX IF NOT EXISTS %(tbl)s_name ON %(tbl)s(name)' % {'tbl': table}) + conn.execute('CREATE INDEX IF NOT EXISTS %(tbl)s_dep_pkg ON %(tbl)s(dep_package_id)' % {'tbl': table}) + conn.commit() + +def add_repodir(xrepodir, conn): + c = conn.cursor() + c.execute("""INSERT INTO repodirs (name, path, sources) VALUES (?, ?, ?)""", + [xrepodir.get('name'), xrepodir.get('path'), xrepodir.get('sources')]) + repodir_id = c.lastrowid + for depend in xrepodir.findall('dependency'): + c.execute("""INSERT INTO repodir_depends(repodir_id, depend_repodir_name) + VALUES (?, ?)""", + [repodir_id, depend.text.strip()]) + conn.commit() + return repodir_id + +def get_build_archs(xrepodir, xrepodirs): + build_archs = [] + for depend in xrepodir.findall('dependency'): + arch_sign = '$arch' + depend_repo = depend.text.strip() + spos = depend_repo.find(arch_sign) + if spos >= 0: + drepo_prefix = depend_repo[:spos] + drepo_postfix = depend_repo[spos + len(arch_sign):] + for xrepodir in xrepodirs.findall('dir'): + repo_name = xrepodir.get('name') + if repo_name.startswith(drepo_prefix) and \ + repo_name.endswith(drepo_postfix): + repo_arch = repo_name[len(drepo_prefix) : + len(repo_name) - len(drepo_postfix)] + if repo_arch == 'SRPMS': + continue + if repo_arch not in build_archs: + build_archs.append(repo_arch) + if build_archs: + return build_archs + return [None] + +def get_rpm_header(rpm_ts, pkg): + hdr = None + try: + fdno = os.open(pkg, os.O_RDONLY) + except OSError, e: + raise Exception('Unable to open file %s.' % pkg) + try: + hdr = rpm_ts.hdrFromFdno(fdno) + except rpm.error, e: + raise Exception('Unable to read RPM header for %s.' % pkg) + finally: + os.close(fdno) + return hdr + +def generate_new_id(generator, gen_lock): + gen_lock.acquire() + last_id = generator.value + last_id += 1 + generator.value = last_id + gen_lock.release() + return last_id + +FILE_REC_ID_IDX = 0 +FILE_REC_PATH_IDX = 3 +FILE_REC_LINK_IDX = 6 +FILE_REC_MARK_IDX = 7 + +def register_object(data, pkg_id, pkg, object_file_record, temp_dir): +# print 'register_library ', obj_file_path + so_needed = data['so_needed'] + obj_symbols = data['obj_symbols'] + obj_id = object_file_record[0] + obj_file_path = object_file_record[3] + obj_file_basename = os.path.basename(obj_file_path) + temp_obj_file = os.path.join(temp_dir, obj_file_path.lstrip('/')) + + target_file = None + file_mark = None + od_out = '' + nmundef_out = '' + nmdef_out = '' + if os.path.islink(temp_obj_file): + target_file = os.path.join(os.path.dirname(obj_file_path), + os.readlink(temp_obj_file)) + file_mark = 'link' + elif not os.path.exists(temp_obj_file): + # print 'File %s was not extracted from the package %s.' % \ + # (obj_file_path, pkg) + file_mark = 'not-found' + else: + p = subprocess.Popen(['objdump', '-p', temp_obj_file], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + od_out = p.communicate()[0] + if p.returncode != 0: + file_mark = 'invalid-format' + else: + p = subprocess.Popen(['nm', '-p', '-D', '--undefined-only', + temp_obj_file], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + nmundef_out = p.communicate()[0] + if p.returncode != 0: + file_mark = 'no-symbols' + else: + p = subprocess.Popen(['nm', '-p', '-D', '--defined-only', + temp_obj_file], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + nmdef_out = p.communicate()[0] + if p.returncode != 0: + file_mark = 'no-symbols' + else: + file_mark = 'so' + + object_file_record[FILE_REC_LINK_IDX] = target_file + object_file_record[FILE_REC_MARK_IDX] = file_mark + + needed_list = [] + dynsection = False + for odline in od_out.split('\n'): + odls = odline.strip() + if odls == '': + dynsection = False + elif odls == 'Динамический раздел:' or odls == 'Dynamic section:': + dynsection = True + elif dynsection: + needrem = re.match(r'\s+NEEDED\s+(.*)', odline) + if needrem: + so_needed.append([obj_id, needrem.group(1)]) + + symbols_list = [] + for symline in nmundef_out.split('\n'): + smre = re.match('^.([\S]*)\s+(\w)\s(.*)$', symline) + if smre: + if smre.group(2) in ['v', 'w']: + continue + symname = smre.group(3) + obj_symbols.append([obj_id, symname, 0]) + + for symline in nmdef_out.split('\n'): + smre = re.match('^.([\S]*)\s+(\w)\s(.*)$', symline) + if smre: + symname = smre.group(3) + obj_symbols.append([obj_id, symname, 1]) + + return obj_id + +def extract_files(pkg, files_list, obj_so_files_idx, temp_dir): + #local_pkg = getLocalPackageName(pkg) + local_pkg = pkg + filelist = os.path.join(temp_dir, 'files.lst') + with open(filelist, 'w') as f: + for i in obj_so_files_idx: + f.write('.' + files_list[i][FILE_REC_PATH_IDX] + '\n') + + rpm_cpio_cmd = 'rpm2cpio ' + pkg + ' | cpio -ivdu -E ' + filelist + p = subprocess.Popen(rpm_cpio_cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + cwd=temp_dir, + shell=True) + output = p.communicate()[0] + if p.returncode != 0: + print >> sys.stderr, 'Couldn\'t extract files from package %s.' \ + '\n\t%s' % (pkg, output) + return False + return True + +def process_package_worker(num, queue_in, generator, gen_lock, db_struct, repodir_id, build_archs, temp_dir): + + rpm_ts = rpm.TransactionSet() + rpm_ts.setVSFlags(~(rpm.RPMVSF_NEEDPAYLOAD)) + data = {} + data['packages'] = [] + for table in db_struct['dep_tables']: + data[table] = [] + data['package_files'] = [] + data['so_needed'] = [] + data['obj_symbols'] = [] + + while True: + job = queue_in.get() + if job == None: + break + (pkg, ) = job + + pkg_id = generate_new_id(generator, gen_lock) + + hdr = get_rpm_header(rpm_ts, pkg) + package_values = [] + package_values.append(pkg_id) + + for tag in db_struct['packages_tags']: + hval = hdr[tag] + package_values.append( + sqlite3.Binary(hval) if tag in db_struct['blob_tags'] else \ + to_string(pkg, tag, hval) if type(hval) in [type([]), type('')] else \ + hval + ) + # sorted(packages_extra_fields.keys()) + package_values.append(repodir_id) + package_values.append(pkg) + package_values.append(None) + data['packages'].append(package_values) + for table in db_struct['dep_tables']: + table_data = data[table] + rpref = 'RPMTAG_' + table[:-1].upper() + (dep_name, dep_flags, dep_version) = \ + (hdr[rpref + 'NAME'], hdr[rpref + 'FLAGS'], hdr[rpref + 'VERSION']) + for i in xrange(0, len(hdr[rpref + 'NAME'])): + #print pkg, table, hdr[rpref + 'NAME'][i] + for build_arch in build_archs: + table_data.append([dep_name[i].decode('utf-8'), + dep_flags[i], + dep_version[i], + pkg_id, build_arch]) + # fonts-ttf-decoratives-1.3-27-rosa.lts2012.0.noarch.rpm provides font(derdämonschriftkegel) + (pkg_file_paths, pkg_file_names, pkg_file_sizes, pkg_file_modes) = \ + (hdr['RPMTAG_FILEPATHS'], hdr['RPMTAG_BASENAMES'], hdr['RPMTAG_FILESIZES'], hdr['RPMTAG_FILEMODES']) + files_list = data['package_files'] + obj_so_files_idx = [] + for i in xrange(0, len(pkg_file_paths)): + file_name = pkg_file_names[i] + file_path = pkg_file_paths[i] + pkg_file_id = generate_new_id(generator, gen_lock) + files_list.append([pkg_file_id, #FILE_REC_ID_IDX = 0 + pkg_id, + file_name.decode('utf-8'), + file_path.decode('utf-8'), #FILE_REC_PATH_IDX = 3 + pkg_file_sizes[i], + pkg_file_modes[i], + None, #link_to_path FILE_REC_LINK_IDX = 6 + None #mark FILE_REC_LINK_IDX = 7 + ]) + if pkg_file_modes[i] & RPMFILEMODE_DIRECTORY != 0: + continue + if os.path.splitext(file_name)[1] in \ + ['.debug', '.xz', '.conf', '.py', '.c', '.h', '.hpp', '.png', + '.cc', '.cpp', '.sh', '.java', '.pl', '.patch', '.desktop']: + continue + if file_path.startswith('/usr/lib/debug/.build-id') or + file_path.endswith('/ld.so.cache'): + continue + if re.search(r'\.so($|\.)', file_name) or \ + (pkg_file_modes[i] & RPMFILEMODE_EXECUTE) != 0: + obj_so_files_idx.append(len(files_list) - 1) + + if obj_so_files_idx: + pkg_temp_dir = os.path.join(temp_dir, os.path.basename(pkg)) + os.makedirs(pkg_temp_dir) + if extract_files(pkg, files_list, obj_so_files_idx, pkg_temp_dir): + for i in obj_so_files_idx: + register_object(data, pkg_id, pkg, files_list[i], pkg_temp_dir) + + shutil.rmtree(pkg_temp_dir, True) + + queue_in.task_done() + + conn = sqlite3.connect(DB, timeout=30) #, isolation_level='DEFERRED', timeout=30) + conn.executemany(""" +INSERT INTO packages (%s) VALUES (%s)""" % + (db_struct['packages_field_names'], + db_struct['packages_values_template']), + data['packages']) + + for table in db_struct['dep_tables']: + conn.executemany(""" +INSERT INTO %s (name, flags, version, package_id, build_arch) +VALUES (?, ?, ?, ?, ?)""" % table, data[table]) + + conn.executemany(""" +INSERT INTO package_files (id, package_id, basename, path, size, mode, link_to_path, mark) +VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", data['package_files']) + + conn.executemany(""" +INSERT INTO so_needed(obj_file_id, name) VALUES(?, ?) +""", data['so_needed']) + + conn.executemany(""" +INSERT INTO obj_symbols(obj_file_id, name, sym_type) VALUES(?, ?, ?) +""", data['obj_symbols']) + + conn.commit() + queue_in.task_done() + +generator_value = 0 + +def process_repodir(repodir_path, repodir_id, build_archs, conn, db_struct, tempdir): + + rpm_list = [] + rpm_list = getFileList(repodir_path, '.rpm', rpm_list) + if not rpm_list: + return + print repodir_path, ': ', len(rpm_list) + + if not db_struct.get('defined'): + rpm_ts = rpm.TransactionSet() + rpm_ts.setVSFlags(~(rpm.RPMVSF_NEEDPAYLOAD)) + # ts.setVSFlags(~(rpm.RPMVSF_NOMD5|rpm.RPMVSF_NEEDPAYLOAD)) + hdr = get_rpm_header(rpm_ts, rpm_list[0]) + + packages_extra_fields = {'repodir_id': 'INTEGER', + 'rpm_filepath': 'TEXT', + 'sourcerpm_package': 'TEXT'} + + file_tags_re = '^RPMTAG_(BASENAMES|FILE[\w\d]+)' + dir_tags_re = '^RPMTAG_DIR(INDEXES|NAMES)' + changelog_tags_re = '^RPMTAG_CHANGELOG\w+' + trigger_tags_re = '^RPMTAG_TRIGGER\w+' + + datetime_tags = ['RPMTAG_PACKAGETIME', 'RPMTAG_RPMLIBTIMESTAMP', ] + db_struct['blob_tags'] = ['RPMTAG_DSAHEADER', 'RPMTAG_HEADERIMMUTABLE', + 'RPMTAG_PKGID', 'RPMTAG_SIGMD5'] + + reserved_field_names = ['id', 'group'] + skip_tags_re = '^RPMTAG_(C|D|E|N|P|R|V|HEADERIMMUTABLE)$' + #C - CONFLICTNAME, D - DISTEPOCH, E - EPOCH, N - NAME, O - OBSOLETENAME + #P - PROVIDENAME, R - RELEASE, V - VERSION + + types = {"" : "TEXT", "": "INTEGER", + "": "TEXT", "": "TEXT"} + + dep_tags_re = '^RPMTAG_(CONFLICT|OBSOLETE|PROVIDE|REQUIRE)\w+' + + db_struct['dep_tables'] = ['requires', 'provides', + 'conflicts', 'obsoletes'] + + packages_field_names = 'id, ' + packages_values_template = '?,' + packages_tags = [] + packages_fields = '' + + rpmtags = [str(t) for t in dir(rpm) if t.startswith('RPMTAG_') ] + for tag in rpmtags: + if re.match(file_tags_re, tag) or re.match(dir_tags_re, tag) or \ + re.match(changelog_tags_re, tag) or \ + re.match(skip_tags_re, tag) or re.match(trigger_tags_re, tag) or \ + re.match(dep_tags_re, tag): # and tag < 'RPMTAG_DIRINDEXES': + continue + sqltype = "TIMESTAMP" if tag in datetime_tags else \ + "BLOB" if tag in db_struct['blob_tags'] else \ + types[str(type(hdr[tag]))] + fieldname = tag.replace('RPMTAG_', '').lower() + if fieldname in ['id', 'group']: + fieldname = 'rpm_' + fieldname + packages_tags.append(tag) + packages_field_names += fieldname + ', ' + packages_values_template += '?, ' + packages_fields += fieldname + ' ' + sqltype + ', ' + nef = 0 + for extra_field in sorted(packages_extra_fields.keys()): + packages_field_names += (', ' if nef > 0 else '') + extra_field + packages_values_template += (', ' if nef > 0 else '') + '?' + packages_fields += (', ' if nef > 0 else '') + extra_field + ' ' + packages_extra_fields[extra_field] + nef += 1 + conn.execute(""" +CREATE TABLE IF NOT EXISTS packages(id INTEGER PRIMARY KEY NOT NULL, %s) +""" % (packages_fields)) + for table in db_struct['dep_tables']: + conn.execute(""" +CREATE TABLE IF NOT EXISTS %s (id INTEGER PRIMARY KEY NOT NULL, + name TEXT, flags INTEGER, version TEXT, build_arch TEXT, + package_id INTEGER NOT NULL, dep_package_id INTEGER)""" % (table)) + conn.commit() + db_struct['packages_tags'] = packages_tags + db_struct['packages_field_names'] = packages_field_names + db_struct['packages_values_template'] = packages_values_template + db_struct['defined'] = True + + + queue_in = mp.JoinableQueue() + for pkg in rpm_list: + queue_in.put((pkg, )) + + for i in xrange(NUM_PROCESSES): + queue_in.put(None) + + # run workers + gc.collect() # Trying to prevent Exception AssertionError: AssertionError() in ignored + time.sleep(1) + gc.disable() + global generator_value + id_generator = mp.Value('i', generator_value) + generator_lock = mp.Lock() + workers = [] + for i in xrange(NUM_PROCESSES): + worker = mp.Process(target = process_package_worker, + args = (i, queue_in, id_generator, generator_lock, db_struct, + repodir_id, build_archs, tempdir)) + workers.append(worker) + worker.start() + queue_in.join() + gc.enable() + generator_value = id_generator.value + + +def main(args): + + if os.path.exists(DB): + os.unlink(DB) + + if hasattr(os, "sysconf"): + if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"): + n = os.sysconf("SC_NPROCESSORS_ONLN") + if isinstance(n, int) and n > 0: + NUM_PROCESSES = n + + conn = sqlite3.connect(DB) + init_database(conn) + conn.commit() + c = conn.cursor() + + options = parseargs(args) + parser = ET.XMLParser() + tree = ET.parse(options.config, parser=parser) + config_root = tree.getroot() + tempdir = '/dev/shm/rt-tmp/' #tempfile.mkdtemp() + shutil.rmtree(tempdir, True) + os.mkdir(tempdir) + rpm_db_struct = {} + for xrepodir in config_root.find('repositories').findall('dir'): + repodir_id = add_repodir(xrepodir, conn) + build_archs = [None] if xrepodir.get('sources') != '.' else \ + get_build_archs(xrepodir, + config_root.find('repositories')) + process_repodir(xrepodir.get('path'), repodir_id, build_archs, conn, rpm_db_struct, tempdir) + shutil.rmtree(tempdir, True) + index_database(conn) + + +if __name__ == "__main__": + main(sys.argv) diff --git a/i586kde.lst b/i586kde.lst new file mode 100644 index 0000000..71ede45 --- /dev/null +++ b/i586kde.lst @@ -0,0 +1,870 @@ +cups-pdf +lsb +xvfb +xlsfonts +qt3 +policycoreutils-sandbox +setools-console +policycoreutils-gui +openscap-extra-probes +openscap-content +openscap-content-sectool +openscap-utils +openscap +kmail +kernel-selinux-desktop-latest +mcstrans +rosa-test-suite +ccid +at-spi +freerdp +opensc +pam_pkcs11 +cgroup +gawk +policycoreutils-python +semanage +selinux-policy +selinux-policy-mls +selinux-policy-targeted +audit +openldap-servers +policycoreutils +ipsec-tools +netlabel_tools +stunnel +ebtables +#setroubleshoot +#setroubleshoot-plugins +system-config-services +star +lm_sensors +wine +socat +amtu +mcstrans +cups +aide +imagemagick-desktop +policycoreutils-newrole +policycoreutils-restorecond +vsftpd +#minicom +rosa-chrome-theme +amarok +mozilla-thunderbird +firefox +krfb +libreoffice +okular +gwenview +kolourpaint +rosa-media-player +xsane +ark +java-1.6.0-openjdk +wine +kcalc +konsole +dolphin +korganizer +kdebase4-workspace +stunnel +#minicom +gkermit +pcsc-lite +pcsc-tools +ntp +nfs-utils +tftp-server +openssh-server +vsftpd +bind +dhcp-server +util-linux +man +net-tools +dhcp-client +tftp +rsync +nfs-utils-clients +openssh-clients +lftp +ntp-client +systemd +dump +pam +audit +policycoreutils-restorecond +aide +bash +mc +sharutils +xz +star +findutils +sed +vim-enhanced +coreutils +dosfstools +e2fsprogs +cdrdao +cdrkit-genisoimage +shadow-utils +sudo +coreutils +policycoreutils-newrole +libsemanage +procps +util-linux +sysvinit-tools +coreutils +drakbackup +libreoffice-l10n-ru +libreoffice-help-ru +libxcb-glx0 + + +make +makedev +coreutils +livecd-tools +livecd-iso-to-disk +syslinux +strace +harddrake +mc +kernel-selinux-desktop-latest +kernel-selinux-desktop-devel-latest +dracut-017 +locales +libstdc++6 + +acl +acpi +acpid +alsa-plugins-doc +alsa-plugins-pulse-config +alsa-utils +aoss +apmd +aria2 +ark +as10k1 +at +atk1.0-common +#aumix-text +avahi +awesfx +b43-fwcutter +basesystem +basesystem-minimal +bash +#bluez +bootloader-utils +bootsplash +busybox-static +bzip2 +canberra-common +canberra-gtk +ccp +cdialog +cdrkit +cdrkit-genisoimage +chkconfig +comgt +common-licenses +consolekit +consolekit-x11 +coreutils +cpio +cracklib-dicts +crda +cronie +crontabs +cryptsetup +curl +dash +dash-static +davfs2 +dbus +dbus-x11 +desktop-common-data +desktop-file-utils +dhcp-client +dhcp-common +diffutils +dirmngr +dkms +dkms-minimal +dmidecode +dmraid +dmraid-events +dmsetup +dosfstools +drakconf +drakconf-icons +drakguard +draklive-install +#draksnapshot +drakx-finish-install +drakx-installer-binaries-probe +drakx-installer-matchbox +drakx-kbd-mouse-x11 +drakx-net +drakx-net-text +drakxtools +drakxtools-backend +drakxtools-curses +dump +dvb-apps +dvbsnoop +dvbtune +dvd+rw-tools +e2fsprogs +eject +enchant +etcskel +ethtool +ffmpeg +ffmpegthumbs +file +filesystem +findutils + +firefox +firefox-en_GB +firefox-ru + +fontconfig +fonts-ttf-decoratives +fonts-ttf-dejavu +fonts-ttf-liberation +fonts-ttf-west_european +font-tools +libfreetype6 +libfreetype2 +fuse +gamin +gawk +gcc-cpp +GConf2 +genhdlist2 +gettext-base +ghostscript +ghostscript-common +ghostscript-fonts +glib2.0-common +glibc +gnupg +gnupg2 +grep +groff +groff-for-man +#grub2 +gstreamer0.10-cdparanoia +gstreamer0.10-ffmpeg +gstreamer0.10-plugins-base +gstreamer0.10-plugins-good +gstreamer0.10-pulse +gstreamer0.10-python +gstreamer0.10-soup +gstreamer0.10-tools +gtk+2.0 +gtksourceview +gurpmi +gvfs +gvfs-archive +gvfs-fuse +gvfs-gphoto2 +gvfs-smb +#gwenview +gzip +#hal +#hal-info +harddrake +harddrake-ui +hcl +hdparm +hfsutils +hicolor-icon-theme +html2text +iceauth +ifmetric +ifplugd +indexhtml +info +info-install +initscripts +iproute2 +ipset +iptables +iputils +iso-codes +iw +jackit +jasper +jfsutils +kbd +bluedevil +kcalc +kcm_touchpad +kcron +kde4-audiocd +kde4-filesharing +kde4-nsplugins +kdeartwork4-kscreensaver +kdebase4-runtime +kdebase4-workspace + +kde-l10n-en_GB +kde-l10n-pl +kde-l10n-pt_BR +kde-l10n-ru +kde-l10n-uk +kde-l10n-es +kde-l10n-nn +kde-l10n-nl +kde-l10n-fr +kde-l10n-it +kde-l10n-ro +kde-l10n-de + +kdnssd +keychain +kfind +kfingermanager +kgamma +kget +kio4-imap +kio4-ldap +kio4-mbox +kio4-nntp +kio4-pop3 +kio4-sieve +kio4-smtp +kio-sysinfo +kipi-common +kmix +kmozillahelper +knotes +kolourpaint +konqueror +konsole +kopete +kpartx +kppp +krb5 +krdc +krfb +ksendemail +ksnapshot +#kttsd +kwallet +kwallet-daemon +kwrite +ld10k1 +ldetect +ldetect-lst +libldetect0.12 +less +lftp +lm_sensors +locales + +locales-en +locales-no +locales-pl +locales-pt +locales-ru +locales-uk +locales-es +locales-fr +locales-it +locales-nl +locales-de +locales-ro + +logrotate +lsb-release +lshw +lvm2 +mailcap +makedev +man +mandi +mandi-ifw +mandriva-doc-common +rosa-gfxboot-theme +mandriva-kde-icons +mandriva-kde4-config-common +mandriva-kde-translation +#rosa-release-common +#rosa-release-EE +mandriva-theme-common +mandriva-theme-Rosa +mandriva-theme-Rosa-screensaver +man-pages +mdadm +#mdkonline +mdv-rpm-summary +menu-messages +meta-task +migration-assistant +mingetty +mkfontdir +mkfontscale +mkxauth +mlocate +#module-init-tools +monitor-edid +mtools + +aspell +aspell-ru + +mozilla-thunderbird-ru + +myspell-ru_RU + +mysql-client +#mysql-common +#mysql-common-core +#mysql-core +nail +ncurses +ndiswrapper +net_monitor +netprofile +net-tools +nfs-utils-clients +notification-daemon +nss +nss_mdns +nss_tcb +ntfs-3g +#ntfsprogs +ntp +ntp-client +obex-data-server +okular +#free-kde4-config +one-kde4-config +open +openldap + +openssh +openssh-clients +openssh-server +openssl +ORBit2 +oxygen-icon-theme +pam +pam_tcb +pango +paprefs +passwd +pavucontrol +pciutils +pcmciautils +phonon-gstreamer + +pkgconfig + +plasma-dataengine-microblog +plasma-dataengine-ocs +plasma-dataengine-rtm +plasma-desktoptheme-aya +plasma-desktoptheme-default +plasma-krunner-powerdevil +plasma-runner-audioplayercontrol +plasma-runner-browserhistory +plasma-runner-contacts +plasma-runner-converter +plasma-runner-katesessions +plasma-runner-konquerorsessions +plasma-runner-konsolesessions +plasma-runner-kopete +plasma-runner-mediawiki +plasma-runner-spellchecker +plasma-wallpaper-mandelbrot +plasma-wallpaper-pattern +plasma-wallpaper-timeoftheday +plasma-wallpaper-virus +plasma-wallpaper-weather +plymouth +plymouth-plugin-label +plymouth-plugin-script +plymouth-scripts +plymouth-system-theme +pm-fallback-policy +pm-utils +policykit +polkit +polkit-kde-agent-1 +popt-data +ppp +ppp-pppoatm +pptp-linux +#prcsys +preload +prism2-utils +procps +psmisc +pulseaudio +pulseaudio-client-config +pulseaudio-esound-compat +pulseaudio-module-gconf +pulseaudio-module-x11 +pulseaudio-module-zeroconf +pulseaudio-utils +python +python-cairo +python-gobject +python-kde4 +python-ldap +python-notify +python-numpy +python-OpenSSL +python-pycrypto +python-qt4 +python-qt4-assistant +python-qt4-core +python-qt4-designer +python-qt4-gui +python-qt4-multimedia +python-qt4-network +python-qt4-opengl +python-qt4-script +python-qt4-sql +python-qt4-svg +python-qt4-test +python-qt4-webkit +python-qt4-xml +python-qt4-xmlpatterns +python-sip +python-twisted-core +python-twisted-web +python-zope-interface +pyxdg +qca2-plugin-openssl +qt4-common +qt4-database-plugin-mysql +qt4-qtdbus +qt4-style-iaora +qt4-xmlpatterns +qtscriptbindings +quota +radeontool +reiserfsprogs +resolvconf +rgb +rmt +rng-utils +rootcerts +rootfiles +rpcbind +rpm +rpmdrake +rpm-helper +rpmstats +rp-pppoe +rsnapshot +rsync +rsyslog +rtkit +run-parts +s2u +sane-backends +sane-backends-iscan +sash +sb16_csp +sdparm +sed +sessreg +setup +setxkbmap +shadow-utils +shared-desktop-ontologies +shared-mime-info +sharutils +shorewall +soprano +soprano-plugin-common +soprano-plugin-redland +soprano-plugin-virtuoso +sound-scripts +sound-theme-freedesktop +soundwrapper +sscape_ctl +strigi +sudo +suspend +sysfsutils +sysvinit-tools +t1utils +taglib-extras +tar +tcb +tcl +tcp_wrappers +termcap +time +timezone +tmpwatch +transfugdrake +uClibc +udev +udisks +unionfs-utils +unzip +update-alternatives +upower +urpmi +urw-fonts +us428control +usb_modeswitch +usbmuxd +usbutils +userdrake +usermode +usermode-consoleonly +utempter +util-linux +v4l-utils +vbetool +vim-minimal +vnstat +vte +webkit1.0 +webkit1.0-webinspector +wget +which +wireless-regdb +wireless-tools +wpa_supplicant +x11-data-cursor-themes +x11-data-xkbdata +#x11-driver-input +x11-driver-input-acecad +x11-driver-input-aiptek +x11-driver-input-evdev +x11-driver-input-fpit +x11-driver-input-hyperpen +x11-driver-input-joystick +x11-driver-input-keyboard +x11-driver-input-mouse +x11-driver-input-mutouch +x11-driver-input-penmount +x11-driver-input-synaptics +x11-driver-input-void +x11-driver-input-wacom +x11-driver-video +x11-driver-video-ati +x11-driver-video-cirrus +x11-driver-video-fbdev +x11-driver-video-glint +x11-driver-video-intel +x11-driver-video-mach64 +x11-driver-video-mga +x11-driver-video-neomagic +x11-driver-video-nouveau +x11-driver-video-nv +x11-driver-video-openchrome +x11-driver-video-r128 +x11-driver-video-radeonhd +x11-driver-video-s3 +x11-driver-video-s3virge +x11-driver-video-savage +x11-driver-video-sis +x11-driver-video-sisusb +x11-driver-video-tdfx +x11-driver-video-trident +x11-driver-video-v4l +x11-driver-video-vboxvideo +x11-driver-video-vesa +x11-driver-video-vmware +x11-driver-video-qxl +x11-font-adobe-75dpi +x11-font-alias +x11-font-bh-75dpi +x11-font-bh-lucidatypewriter-75dpi +x11-font-bitstream-75dpi +x11-font-cronyx-cyrillic +x11-font-cursor-misc +x11-font-cyrillic +x11-font-encodings +x11-font-misc-cyrillic +x11-font-misc-misc +x11-font-screen-cyrillic +x11-font-winitzki-cyrillic +x11-server-common +x11-server-xorg +xauth +xdg-user-dirs +xdg-user-dirs-gtk +xdg-utils +xdm +xdpyinfo +xev +xfsprogs +xhost +xinit +xinitrc +xkbcomp +xmessage +xmodmap +xorg-x11 +xprop +xrandr +xrdb +xset +xsetroot +xsettings-kde +xulrunner +xz +zcip +zip + +systemd-sysvinit +systemd +knetworkmanager +networkmanager-openvpn +networkmanager-vpnc +networkmanager-pptp +modemmanager +mobile-broadband-provider-info +plasma-applet-networkmanagement + +task-kde4 +task-x11 +x11-driver-input +x11-driver-video +task-pulseaudio + +kde4-style-qtcurve +qtcurve-gtk2 + +livestart-rosa +rosa-launcher + +#ktorrent +kde4-windeco-dekorator +rosa-elementary-theme +rosa-icons +kamera +aica-firmware +asihpi-firmware +emagic-firmware +emu1010-firmware +kernel-firmware +pcmcia-cis-firmware +turtlebeach-firmware +zd1211-firmware + +#x11-driver-video-fglrx +#x11-driver-video-nvidia-current +#x11-driver-video-nvidia173 +#x11-driver-video-nvidia96xx + +glxinfo +alsa-utils +libalsa-plugins-pulseaudio +mesa-demos + +#mandriva-control-center +qgtkstylealt +plasma-desktoptheme-rosa +kdepasswd + +sphere-client-rosa +fonts-ttf-droid +#psyncclient + +nut-server +samba-client +samba-server +nfs-utils +btrfs-progs +knetworkmanager-pptp +samba-client +cifs-utils +nss_wins +samba-common +comgt +madwimax +rp-pppoe +btrfs-progs +x11-driver-video-vboxvideo +x11-driver-input-vmmouse +whois +cups +task-printing +task-printing-hp +task-printing-server +system-config-printer +nfs-utils +#vpnpptp-allde +xl2tpd +wvdial +gksu +ozerocdoff +usb_modeswitch-data +cpufrequtils +libstdc++6 +bind-utils +#aumix +#kamera + +zenity +rosa-media-player +rosa-media-player-plugin +ffmpeg +gstreamer0.10-mpeg +rdesktop +amarok + +autofs + +ccid +krb5-workstation +libsasl2-plug-gssapi +nscd +nss_ldap +openldap-clients +opensc +pam_krb5 +pam_ldap +pcsc-lite +pcsc-tools +perl-Digest-SHA +perl-Net-DNS +samba-winbind +tigervnc-server +xl2tpd +lsof +vpnpptp-allde +kcm_license +lsb-release +libglibc_lsb +perl-CGI +perl-Pod-Perldoc +perl-Safe +perl-Class-ISA +perl-Pod-Plainer +glibc-i18ndata + +gstreamer0.10-plugins-ugly +htop +traceroute +pulseaudio-module-bluetooth +bluez-alsa +elementary-theme +plasma-applet-battery +plasma-applet-folderview +ktorrent +libalsa-plugins +autologin +bash-completion +k3b +akonadi-mailfilter-agent diff --git a/prepare-repodb.py b/prepare-repodb.py new file mode 100755 index 0000000..ba02c04 --- /dev/null +++ b/prepare-repodb.py @@ -0,0 +1,380 @@ +import os +import sys +import gettext +import argparse +import sqlite3 +import string +import re +from versutils import * + +DB = 'repo.db' + +def process_repodir_requires(dbc, repodir_id, repodir_name, repodir_depends, requires_build_arch): + global n + + print 'Processing repo %d: %s (with depends: %s)' % (repodir_id, repodir_name, str(repodir_depends)) + package_requires = dbc.execute(""" +SELECT packages.id AS package_id, packages.name AS package_name, packages.nvra, + requires.id, requires.name, flags, requires.version + FROM packages, requires + WHERE repodir_id = ? AND requires.package_id = packages.id %s + ORDER BY packages.name, requires.name +""" % ((" AND build_arch = '%s'" % requires_build_arch) + if requires_build_arch is not None else ""), + [repodir_id]).fetchall() + + search_repodirs = [repodir_id] + search_repodirs.extend(repodir_depends) + in_repodirs = ','.join(str(id) for id in search_repodirs) +# print 'package requires count: ', len(package_requires) + broken_dep = 0 + requires_cache = {} + # TODO: Reuse the cache for dependent repositories??? + + for packreq in package_requires: + (cpackage_id, package_nvra, requires_id, requires_name, requires_flags, requires_version) = \ + (packreq[0], packreq[2], packreq[3], packreq[4], packreq[5], packreq[6]) +# if requires_name != '/usr/sbin/glibc-post-wrapper': +# continue +# print packreq + requirement_uid = requires_name + '\0' + str(requires_flags) + '\0' + requires_version + pkg_id = requires_cache.get(requirement_uid) + if pkg_id is None: + if (re.match(r'\A(rpmlib|executable)\(.+\)\Z', requires_name)): + # see if($N=~/\A(rpmlib|executable)\(.+\)\Z/) in urpm_repoclosure.pl + pkg_id = -1 + if pkg_id is None: + depend_candidates = dbc.execute(""" +SELECT packages.id AS package_id, packages.name AS package_name, + provides.id, provides.name, flags, provides.version + FROM packages, provides + WHERE provides.package_id = packages.id AND repodir_id IN (%s) AND provides.name = ? +""" % in_repodirs, [requires_name]).fetchall() + provides_found_pkg_id = None + provides_found_id = None + provides_found_version = None + for dep_cand in depend_candidates: + (provides_pkg_id, provides_id, provides_flags, provides_version) = \ + (dep_cand[0], dep_cand[2], dep_cand[4], dep_cand[5]) + #print 'provides_version: ', provides_flags, ' ', provides_version + if provides_flags & RPMSENSE_SENSEMASK == 0: + if not provides_version: + provides_version = '*' + else: + raise Exception('Invalid provides version (flags = %d, version = %s)!' % + (provides_flags, provides_version)) + if version_ok(requires_version, + requires_flags & RPMSENSE_SENSEMASK, + provides_version): + better_version = provides_found_version is None or \ + provides_version == '*' + if not better_version: + better_version = version_ok(provides_version, + RPMSENSE_GREATER, + provides_found_version) + if better_version: + (provides_found_pkg_id, + provides_found_id, + provides_found_version) = \ + (provides_pkg_id, + provides_id, + provides_version) + pkg_id = provides_found_pkg_id + #print "->", provides_found_version, ' ->', provides_found_pkg_id + if pkg_id is None and (requires_flags & RPMSENSE_MISSINGOK) != 0: + pkg_id = -1 # TODO: Fix for valid foreign key + if pkg_id is None and requires_name.startswith('/'): # file dependency + if (requires_flags & (RPMSENSE_SCRIPT_POST | + RPMSENSE_SCRIPT_PREUN | + RPMSENSE_SCRIPT_POSTUN)) != 0: + internal_files = dbc.execute(""" +SELECT 1 FROM package_files WHERE package_id = ? AND path = ? +""", [cpackage_id, requires_name]).fetchall() + if len(internal_files) > 0: + pkg_id = cpackage_id + else: + #TODO: Check file dependencies (/usr/bin/python (required by ant-scripts-1.7.1-7.0.6.noarch), /usr/sbin/useradd (required by tomcat5-5.5.28-0.5.2.noarch))? + files_dependency = dbc.execute(""" +SELECT package_id FROM package_files + WHERE path = ? AND + package_id in (SELECT id FROM packages WHERE repodir_id IN (%s)) +""" % in_repodirs, [requires_name]).fetchall() + if len(files_dependency) > 0: + if len(files_dependency) == 1: + pkg_id = files_dependency[0][0] + else: + print "File dependency (%s) has multiple resolutions (%d)." % len(files_dependency) + if pkg_id is not None: + dbc.execute(""" +UPDATE requires SET dep_package_id = ? WHERE id = ? +""", [pkg_id, requires_id]) + requires_cache[requirement_uid] = pkg_id + else: + print requires_name, ' ', requires_version, ' (required by %s)' % package_nvra, ' not found!!!' + broken_dep += 1 + n = n + 1 + #print "n = ", n +# if n == 60000: +# break + print 'broken_deps: ', broken_dep + print '' + +def extract_arch(arch_template, repo_name): + arch_sign = '$arch' + spos = arch_template.find(arch_sign) + if spos >= 0: + repo_prefix= arch_template[:spos] + repo_postfix = arch_template[spos + len(arch_sign):] + if repo_name.startswith(repo_prefix) and \ + repo_name.endswith(repo_postfix): + return repo_name[len(repo_prefix) : + len(repo_name) - len(repo_postfix)] + return None + +def process_repodir_file_links(dbc, repodir_id, repodir_name, repodir_depends): + package_files_links = dbc.execute(""" +SELECT packages.id AS package_id, packages.name AS package_name, packages.nvra, + package_files.id AS object_id, package_files.path, package_files.link_to_path + FROM packages, package_files + WHERE repodir_id = ? AND package_files.package_id = packages.id AND + link_to_path IS NOT NULL + ORDER BY packages.name, link_to_path +""", [repodir_id]).fetchall() + for file_link in package_files_links: + pkg_id = file_link[0] + pkg_name = file_link[1] + object_id = file_link[3] + target_path = os.path.normpath(file_link[5]) + target_obj_id = None + tofile = dbc.execute(""" +SELECT id FROM package_files WHERE path = ? AND package_id = ? +""", [target_path, pkg_id]).fetchone() + if tofile: + target_obj_id = tofile[0] + if not target_obj_id: + tofile = dbc.execute(""" +SELECT id FROM package_files WHERE path = ? AND package_id IN (SELECT dep_package_id FROM requires WHERE package_id = ?) +""", [target_path, pkg_id]).fetchone() + if tofile: + target_obj_id = tofile[0] + + if target_obj_id: + dbc.execute(""" +UPDATE package_files SET link_to_file_id = ? WHERE id = ? +""", [target_obj_id, object_id]) + else: +# print 'target %s not found (%d: %s)' % (target_path, pkg_id, pkg_name) + pass + +def process_repodir_so_needed(dbc, repodir_id, repodir_name, repodir_depends): + print 'Searching object files resolutions (1)...' + dbc.execute(""" +INSERT INTO so_needed_res(so_needed_id, dep_obj_file_id, res_type) + SELECT so_needed.id, tpf.id, 1 FROM packages + CROSS JOIN package_files spf CROSS JOIN so_needed CROSS JOIN requires CROSS JOIN package_files tpf + WHERE so_needed.obj_file_id = spf.id AND spf.package_id = packages.id AND packages.repodir_id = ? AND + spf.package_id = requires.package_id AND so_needed.name = requires.name AND + requires.dep_package_id = tpf.package_id AND so_needed.name = tpf.basename +""", [repodir_id]) + + search_repodirs = [repodir_id] + search_repodirs.extend(repodir_depends) + in_repodirs = ','.join(str(id) for id in search_repodirs) + + objects_not_resolved1 = dbc.execute(""" +SELECT packages.id AS package_id, packages.nvra, + package_files.id AS object_id, package_files.basename AS object_name, + so_needed.id AS so_needed_id, so_needed.name AS so_needed_name + FROM packages CROSS JOIN package_files CROSS JOIN so_needed + WHERE repodir_id = ? AND package_files.package_id = packages.id AND + so_needed.obj_file_id = package_files.id AND + NOT EXISTS (SELECT 1 FROM so_needed_res WHERE so_needed_res.so_needed_id = so_needed.id) + ORDER BY packages.nvra, package_files.basename, so_needed.name +""", [repodir_id]).fetchall() + print 'object files not resolved by rpm requires-provides: ', len(objects_not_resolved1) + if objects_not_resolved1: + print 'Searching object files resolutions (2)...' + in_so_needed = ','.join(str(obj_rec[4]) for obj_rec in objects_not_resolved1) + dbc.execute(""" +INSERT INTO so_needed_res(so_needed_id, dep_obj_file_id, res_type) + SELECT so_needed.id, tpf.id, 2 FROM packages, package_files tpf, so_needed + WHERE packages.repodir_id IN (%s) AND packages.id = tpf.package_id AND + so_needed.id IN (%s) AND tpf.basename = so_needed.name +""" % (in_repodirs, in_so_needed)) + + objects_not_resolved2 = dbc.execute(""" +SELECT packages.id AS package_id, packages.nvra, + package_files.id AS object_id, package_files.basename AS object_name, + so_needed.id AS so_needed_id, so_needed.name AS so_needed_name + FROM packages, package_files, so_needed + WHERE repodir_id = ? AND package_files.package_id = packages.id AND + so_needed.obj_file_id = package_files.id AND + NOT EXISTS (SELECT 1 FROM so_needed_res WHERE so_needed_res.so_needed_id = so_needed.id) + ORDER BY packages.nvra, package_files.basename, so_needed.name +""", [repodir_id]).fetchall() + print 'Object files not resolved: ', len(objects_not_resolved2) + + +def process_repodir_obj_symbols(dbc, repodir_id, repodir_name, repodir_depends): + print 'Searching symbols resolutions (1)...' +# EXPLAIN QUERY PLAN + dbc.execute(""" +INSERT INTO obj_symbols_res(obj_sym_id, dep_obj_sym_id, res_type) +SELECT sos.id, tos.id, 1 FROM packages CROSS JOIN package_files CROSS JOIN obj_symbols sos CROSS JOIN + so_needed CROSS JOIN so_needed_res CROSS JOIN obj_symbols tos + WHERE packages.repodir_id = ? AND packages.id = package_files.package_id AND package_files.id = sos.obj_file_id AND + sos.sym_type = 0 AND sos.obj_file_id = so_needed.obj_file_id AND so_needed.id = so_needed_res.so_needed_id AND + so_needed_res.res_type = 1 AND so_needed_res.dep_obj_file_id = tos.obj_file_id AND + tos.sym_type = 1 AND tos.name = sos.name +""", [repodir_id]) + print 'Searching symbols resolutions (2)...' + dbc.execute(""" +INSERT INTO obj_symbols_res(obj_sym_id, dep_obj_sym_id, res_type) +SELECT sos.id, tos.id, 2 FROM packages CROSS JOIN package_files CROSS JOIN obj_symbols sos CROSS JOIN + so_needed CROSS JOIN so_needed_res CROSS JOIN obj_symbols tos + WHERE packages.repodir_id = ? AND packages.id = package_files.package_id AND package_files.id = sos.obj_file_id AND + sos.sym_type = 0 AND sos.obj_file_id = so_needed.obj_file_id AND so_needed.id = so_needed_res.so_needed_id AND + so_needed_res.res_type = 2 AND so_needed_res.dep_obj_file_id = tos.obj_file_id AND + tos.sym_type = 1 AND tos.name = sos.name +""", [repodir_id]) + print 'Searching symbols resolutions (3)...' + search_repodirs = [repodir_id] + search_repodirs.extend(repodir_depends) + in_repodirs = ','.join(str(id) for id in search_repodirs) + dbc.execute(""" +INSERT INTO obj_symbols_res(obj_sym_id, dep_obj_sym_id, res_type) +SELECT sos.id, tos.id, 3 FROM packages CROSS JOIN package_files CROSS JOIN obj_symbols sos CROSS JOIN + obj_symbols tos CROSS JOIN package_files tpf + WHERE repodir_id = ? AND packages.id = package_files.package_id AND package_files.id = sos.obj_file_id AND + sos.sym_type = 0 AND NOT EXISTS (SELECT 1 FROM obj_symbols_res WHERE obj_sym_id = sos.id) AND + sos.name = tos.name AND tos.sym_type = 1 AND tos.obj_file_id = tpf.id AND + tpf.package_id IN (SELECT id FROM packages WHERE repodir_id IN (%s)) +""" % in_repodirs, [repodir_id]) + + +def process_repodir(dbc, repo_id, repo_name, repo_sources, depend_repodir_list, repodirs_processed, dep_arch): + all_depends_ready = True + repodir_depends = [] + + in_repodirs = ','.join(str(id) for id in repodirs_processed) + for dr_name in depend_repodir_list: + repodir_depend_found = dbc.execute(""" +SELECT id, name FROM repodirs WHERE id IN (%s) AND name = ? +""" % in_repodirs, [dr_name]).fetchall() + if len(repodir_depend_found) == 0: + all_depends_ready = False + break + else: + for rdf in repodir_depend_found: + repodir_depends.append(rdf[0]) + if not all_depends_ready: + return False + print repo_name, ' ', depend_repodir_list, ' ', dep_arch + process_repodir_requires(dbc, repo_id, repo_name, repodir_depends, dep_arch) + process_repodir_file_links(dbc, repo_id, repo_name, repodir_depends) + process_repodir_so_needed(dbc, repo_id, repo_name, repodir_depends) + process_repodir_obj_symbols(dbc, repo_id, repo_name, repodir_depends) + + if repo_sources: + print 'Searching source rpms...' + dbc.execute(""" +UPDATE packages SET sourcerpm_package = NULL + WHERE repodir_id = ?""", [repo_id]) + dbc.execute(""" +UPDATE packages SET sourcerpm_package = + (SELECT id FROM packages ps + WHERE repodir_id IN (SELECT id FROM repodirs WHERE name = ?) AND + ps.nvra = substr(packages.sourcerpm, 1, length(packages.sourcerpm)-4) + ) + WHERE repodir_id = ? AND sourcerpm LIKE '%.rpm' +""", [repo_sources, repo_id]) + return True + +def main(args): + + conn = sqlite3.connect(DB) + dbc = conn.cursor() + + global n + n = 0 + dbc.execute(""" +PRAGMA cache_size = -1048576 + """) + dbc.execute(""" +DELETE FROM so_needed_res""") + dbc.execute(""" +DELETE FROM obj_symbols_res""") + dbc.execute(""" +ANALYZE""") + repodirs_processed = [] + #Process binary rpms + repodirs_processed_cnt = -1 + while repodirs_processed_cnt < len(repodirs_processed): + in_repodirs = ','.join(str(id) for id in repodirs_processed) + repodirs = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs WHERE sources <> '.' AND id NOT IN (%s) +""" % in_repodirs).fetchall() + for repodir in repodirs: + (repo_id, repo_name, repo_sources) = (repodir[0], repodir[1], repodir[2]) + depend_repodir_names = dbc.execute( +""" +SELECT depend_repodir_name FROM repodir_depends WHERE repodir_id = ? +""", [repo_id]).fetchall() + depend_repodir_list = [drn[0] for drn in depend_repodir_names] + if process_repodir(dbc, repo_id, repo_name, repo_sources, depend_repodir_list, repodirs_processed, None): + repodirs_processed.append(repo_id) + repodirs_processed_cnt = len(repodirs_processed) + + #Process SRPMS + repodirs_processed_cnt = -1 + while repodirs_processed_cnt < len(repodirs_processed): + repodirs = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs WHERE sources = '.' +""").fetchall() + for repodir in repodirs: + (repo_id, repo_name, repo_sources) = (repodir[0], repodir[1], repodir[2]) + src_build_archs = [] + depend_repodir_names = dbc.execute( +""" +SELECT depend_repodir_name FROM repodir_depends WHERE repodir_id = ? +""", [repo_id]).fetchall() + for drn in depend_repodir_names: + dr_name = drn[0] + if '$arch' in dr_name: + depend_repodir_found = dbc.execute( +""" +SELECT id, name FROM repodirs WHERE name LIKE ? +""", [dr_name.replace('$arch', '%')]).fetchall() + if len(depend_repodir_found) == 0: + raise Exception('Dependancy repositories not found!') + for drf in depend_repodir_found: + arch = extract_arch(dr_name, drf[1]) + if arch: + if arch == 'SRPMS': + continue + src_build_archs.append(arch) + else: + raise Exception('Source repository should depend on */$arch/* repo.') + for arch in src_build_archs: + depend_repodir_list = [drn[0].replace('$arch', arch) + for drn in depend_repodir_names] + if not process_repodir(dbc, repo_id, repo_name, None, depend_repodir_list, repodirs_processed, arch): + raise Exception('Couldn\'t process SRPMS repository!') + repodirs_processed.append(repo_id) + + repodirs_processed_cnt = len(repodirs_processed) + + in_repodirs = ','.join(str(id) for id in repodirs_processed) + repodirs_not_processed = dbc.execute(""" +SELECT id, name, sources, path FROM repodirs rd WHERE id NOT IN (%s) +""" % in_repodirs).fetchall() + if len(repodirs_not_processed) > 0: + print 'Repodirs not processed due to dependencies:' + for rdna in repodirs_not_processed: + print rdna[1] + dbc.execute(""" +ANALYZE""") + conn.commit() + +if __name__ == "__main__": + main(sys.argv) diff --git a/repo-analyze-config.xml b/repo-analyze-config.xml new file mode 100644 index 0000000..cde2d78 --- /dev/null +++ b/repo-analyze-config.xml @@ -0,0 +1,83 @@ + + + + + + + + + rosa-dx-chrome-1.0/i586/main/release + + + + rosa-dx-chrome-1.0/i586/main/release + + + rosa-dx-chrome-1.0/i586/main/release + + + + + + + rosa-dx-chrome-1.0/x86_64/main/release + + + + rosa-dx-chrome-1.0/x86_64/main/release + + + rosa-dx-chrome-1.0/x86_64/main/release + + + + rosa-dx-chrome-1.0/$arch/main/release + + + + rosa-dx-chrome-1.0/$arch/main/release + dx_rc_personal/$arch/main/release + + + + \ No newline at end of file diff --git a/versutils.py b/versutils.py new file mode 100644 index 0000000..a203989 --- /dev/null +++ b/versutils.py @@ -0,0 +1,150 @@ +# -*- coding: UTF-8 -*- + +import re +import rpm + +RPMSENSE_LESS = 0x02 +RPMSENSE_GREATER = 0x04 +RPMSENSE_EQUAL = 0x08 +RPMSENSE_SENSEMASK = 0x0f +RPMSENSE_FIND_PROVIDES = 0x8000 +RPMSENSE_MISSINGOK = 0x80000 +RPMSENSE_SCRIPT_POST = 0x400 +RPMSENSE_SCRIPT_PREUN = 0x800 +RPMSENSE_SCRIPT_POSTUN = 0x1000 + +def version_ok(required_version, compare_flag, candidate_version): + def sep_version(version): + vrem = re.match(r'\A(.+)(\-[^\-\:]+)(\:[^\:]+|)\Z', version) + if vrem: + return (vrem.group(1), vrem.group(2), vrem.group(3)) + return (version, '', '') + + def simple_version(version): + version = re.sub(r'[\-:]', '.', version) + version = re.sub(r'[a-z]+', '.', version, flags=re.I) + version = re.sub(r'\.\Z', '', version) + return version + + def format_versions(ver1, ver2): + #see urpm-repoclosure, formatVersions + # v1 - provided + # v2 - required + (e1, e2) = (None, None) + e1_m = re.match(r'\A([^\-\:]+)\:(.*)', ver1) + if e1_m: + (e1, ver1) = (e1_m.group(1), e1_m.group(2)) + e2_m = re.match(r'\A([^\-\:]+)\:(.*)', ver2) + if e2_m: + (e2, ver2) = (e2_m.group(1), e2_m.group(2)) + (ver1_m, ver1_r, ver1_rr) = sep_version(ver1) + (ver2_m, ver2_r, ver2_rr) = sep_version(ver2) + if not ver2_rr: + ver1_rr = '' + if not ver2_r: + ver1_r = '' + ver1 = ver1_m + ver1_r + ver1_rr + ver2 = ver2_m + ver2_r + ver2_rr + if e1_m and e2_m: + ver1 = e1 + '.' + ver1 + ver2 = e2 + '.' + ver2 + return (simple_version(ver1), simple_version(ver2)) + + def cmp_nums(num1, num2): + # 00503 + # 12 + if num1 == num2: + return 0 + lzeros1 = re.match(r'\A([0]+)([1-9].*)', num1) + if lzeros1: + (num1, num2) = (lzeros1.group(2), num2 + lzeros1.group(1)) + lzeros2 = re.match(r'\A([0]+)([1-9].*)', num2) + if lzeros2: + (num2, num1) = (lzeros2.group(2), num1 + lzeros2.group(1)) + diff = int(num1) - int(num2) + return 0 if diff == 0 else \ + (1 if diff > 0 else -1) + + def cmp_versions(version1, version2): + #see urpm-repoclosure, cmpVersions + # 3.2.5-5:2011.0 + # NOTE: perl 5.00503 and 5.12 + (v1, v2) = format_versions(version1, version2) + if v1 == v2: + return 0 + v1parts = v1.split('.') + v2parts = v2.split('.') + for i in xrange(0, min(len(v1parts), len(v2parts))): + (num1, num2)= (v1parts[i], v2parts[i]) + if (len(num1) > 0 and len(num2) == 0): + return 1 + if (len(num1) == 0 and len(num2) > 0): + return -1 + num_diff = cmp_nums(num1, num2) + if num_diff != 0: + return num_diff + if len(v1parts) < len(v2parts): + return -1 + if len(v1parts) > len(v2parts): + return 1 + return 0 + + def rpm_cmp_versions(version1, version2): + def stringToVersion(verstring): + # from rpmUtils + if verstring in [None, '']: + return (None, None, None) + e1_m = re.match(r'\A([^\-\:]+)\:(.*)', verstring) + epoch = None + if e1_m: + (epoch, verstring) = (e1_m.group(1), e1_m.group(2)) + j = verstring.find('-') + if j != -1: + if verstring[:j] == '': + version = None + else: + version = verstring[:j] + release = verstring[j + 1:] + else: + if verstring == '': + version = None + else: + version = verstring + release = None + return (epoch, version, release) + + (e1, v1, r1) = stringToVersion(version1) + (e2, v2, r2) = stringToVersion(version2) + if e1 is None or e2 is None: + e1 = '0' + e2 = '0' + result = rpm.labelCompare((e1, v1, r1), (e2, v2, r2)) + return result + +# print '===', required_version, compare_flag, candidate_version + if compare_flag == 0: + return True + if candidate_version == '*': + return True + #see urpm-repoclosure, checkDeps + if compare_flag == RPMSENSE_EQUAL and \ + candidate_version ==required_version: + return True + + cmp_res = cmp_versions(candidate_version, required_version) + rpm_cmp_res = rpm_cmp_versions(candidate_version, required_version) + #if (cmp_res != rpm_cmp_res): + #print >> sys.stderr, ('Invalid compare: "%s" vs "%s"! Results: rc: %d, rpm: %d.' % + #(candidate_version, required_version, cmp_res, rpm_cmp_res)) + if compare_flag == RPMSENSE_EQUAL: + return cmp_res == 0 + elif compare_flag == RPMSENSE_LESS | RPMSENSE_EQUAL: + return cmp_res <= 0 + elif compare_flag == RPMSENSE_GREATER | RPMSENSE_EQUAL: + return cmp_res >= 0 + elif compare_flag == RPMSENSE_LESS: + return cmp_res < 0 + elif compare_flag == RPMSENSE_GREATER: + return cmp_res > 0 + return False + diff --git a/x86_64.lst b/x86_64.lst new file mode 100644 index 0000000..bc67276 --- /dev/null +++ b/x86_64.lst @@ -0,0 +1,868 @@ +cups-pdf +lsb +xvfb +xlsfonts +qt3 +policycoreutils-sandbox +setools-console +policycoreutils-gui +openscap-extra-probes +openscap-content +openscap-content-sectool +openscap-utils +openscap +kmail +mcstrans +rosa-test-suite +ccid +at-spi +freerdp +opensc +pam_pkcs11 +cgroup +gawk +policycoreutils-python +python-semanage +selinux-policy +selinux-policy-mls +selinux-policy-targeted +audit +openldap-servers +policycoreutils +ipsec-tools +netlabel_tools +stunnel +ebtables +#setroubleshoot +#setroubleshoot-plugins +system-config-services +star +lm_sensors +wine64 +socat +amtu +mcstrans +cups +aide +imagemagick-desktop +policycoreutils-newrole +policycoreutils-restorecond +vsftpd +#minicom +rosa-chrome-theme +amarok +mozilla-thunderbird +firefox +krfb +libreoffice +okular +gwenview +kolourpaint +rosa-media-player +xsane +ark +java-1.6.0-openjdk +kcalc +konsole +dolphin +korganizer +kdebase4-workspace +stunnel +#minicom +gkermit +pcsc-lite +pcsc-tools +ntp +nfs-utils +tftp-server +openssh-server +vsftpd +bind +dhcp-server +util-linux +man +net-tools +dhcp-client +tftp +rsync +nfs-utils-clients +openssh-clients +lftp +ntp-client +systemd +glibc +dump +pam +audit +policycoreutils-restorecond +aide +bash +mc +sharutils +xz +star +findutils +sed +vim-enhanced +coreutils +dosfstools +e2fsprogs +cdrdao +cdrkit-genisoimage +shadow-utils +sudo +coreutils +policycoreutils-newrole +libsemanage +procps +util-linux +sysvinit-tools +coreutils +drakbackup +libreoffice-l10n-ru +libreoffice-help-ru +lib64xcb-glx0 + +make +makedev +coreutils +livecd-tools +livecd-iso-to-disk +syslinux +strace +harddrake +mc +kernel-selinux-desktop-latest +kernel-selinux-desktop-devel-latest +dracut-017 +locales +lib64stdc++6 + +acl +acpi +acpid +alsa-plugins-doc +alsa-plugins-pulse-config +alsa-utils +aoss +apmd +aria2 +ark +as10k1 +at +atk1.0-common +#aumix-text +avahi +awesfx +b43-fwcutter +basesystem +basesystem-minimal +bash +#bluez +bootloader-utils +bootsplash +busybox-static +bzip2 +canberra-common +canberra-gtk +ccp +cdialog +cdrkit +cdrkit-genisoimage +chkconfig +comgt +common-licenses +consolekit +consolekit-x11 +coreutils +cpio +cracklib-dicts +crda +cronie +crontabs +cryptsetup +curl +dash +dash-static +davfs2 +dbus +dbus-x11 +desktop-common-data +desktop-file-utils +dhcp-client +dhcp-common +diffutils +dirmngr +dkms +dkms-minimal +dmidecode +dmraid +dmraid-events +dmsetup +dosfstools +drakconf +drakconf-icons +drakguard +draklive-install +#draksnapshot +drakx-finish-install +drakx-installer-binaries-probe +drakx-installer-matchbox +drakx-kbd-mouse-x11 +drakx-net +drakx-net-text +drakxtools +drakxtools-backend +drakxtools-curses +dump +dvb-apps +dvbsnoop +dvbtune +dvd+rw-tools +e2fsprogs +eject +enchant +etcskel +ethtool +ffmpeg +ffmpegthumbs +file +filesystem +findutils + +firefox +firefox-en_GB +firefox-ru + +fontconfig +fonts-ttf-decoratives +fonts-ttf-dejavu +fonts-ttf-liberation +fonts-ttf-west_european +font-tools +lib64freetype6 +lib64freetype2 +fuse +gamin +gawk +gcc-cpp +GConf2 +genhdlist2 +gettext-base +ghostscript +ghostscript-common +ghostscript-fonts +glib2.0-common +glibc +gnupg +gnupg2 +grep +groff +groff-for-man +#grub2 +gstreamer0.10-cdparanoia +gstreamer0.10-ffmpeg +gstreamer0.10-plugins-base +gstreamer0.10-plugins-good +gstreamer0.10-pulse +gstreamer0.10-python +gstreamer0.10-soup +gstreamer0.10-tools +gtk+2.0 +gtksourceview +gurpmi +gvfs +gvfs-archive +gvfs-fuse +gvfs-gphoto2 +gvfs-smb +gwenview +gzip +#hal +#hal-info +harddrake +harddrake-ui +hcl +hdparm +hfsutils +hicolor-icon-theme +html2text +iceauth +ifmetric +ifplugd +indexhtml +info +info-install +initscripts +iproute2 +ipset +iptables +iputils +iso-codes +iw +jackit +jasper +jfsutils +kbd +bluedevil +kcalc +kcm_touchpad +kcron +kde4-audiocd +kde4-filesharing +kde4-nsplugins +kdeartwork4-kscreensaver +kdebase4-runtime +kdebase4-workspace + +kde-l10n-en_GB +kde-l10n-pl +kde-l10n-pt_BR +kde-l10n-ru +kde-l10n-uk +kde-l10n-es +kde-l10n-nn +kde-l10n-nl +kde-l10n-fr +kde-l10n-it +kde-l10n-ro +kde-l10n-de + +kdnssd +keychain +kfind +kfingermanager +kgamma +kget +kio4-imap +kio4-ldap +kio4-mbox +kio4-nntp +kio4-pop3 +kio4-sieve +kio4-smtp +kio-sysinfo +kipi-common +kmix +kmozillahelper +knotes +kolourpaint +konqueror +konsole +kopete +kpartx +kppp +krb5 +krdc +krfb +ksendemail +ksnapshot +#kttsd +kwallet +kwallet-daemon +kwrite +ld10k1 +ldetect +ldetect-lst +lib64ldetect0.12 +less +lftp +lm_sensors +locales + +locales-en +locales-no +locales-pl +locales-pt +locales-ru +locales-uk +locales-es +locales-fr +locales-it +locales-nl +locales-de +locales-ro + +logrotate +lsb-release +lshw +lvm2 +mailcap +makedev +man +mandi +mandi-ifw +mandriva-doc-common +rosa-gfxboot-theme +mandriva-kde-icons +mandriva-kde4-config-common +mandriva-kde-translation +mandriva-theme-common +mandriva-theme-Rosa +mandriva-theme-Rosa-screensaver +man-pages +mdadm +#mdkonline +mdv-rpm-summary +menu-messages +meta-task +migration-assistant +mingetty +mkfontdir +mkfontscale +mkxauth +mlocate +#module-init-tools +monitor-edid +mtools + +aspell +aspell-ru + +mozilla-thunderbird-ru +myspell-ru_RU + +mysql-client +#mysql-common +#mysql-common-core +#mysql-core +nail +ncurses +ndiswrapper +net_monitor +netprofile +net-tools +nfs-utils-clients +notification-daemon +nss +nss_mdns +nss_tcb +ntfs-3g +#ntfsprogs +ntp +ntp-client +obex-data-server +okular +#free-kde4-config +one-kde4-config +open +openldap + + +openssh +openssh-clients +openssh-server +openssl +ORBit2 +oxygen-icon-theme +pam +pam_tcb +pango +paprefs +passwd +pavucontrol +pciutils +pcmciautils +phonon-gstreamer + +pkgconfig + +plasma-dataengine-microblog +plasma-dataengine-ocs +plasma-dataengine-rtm +plasma-desktoptheme-aya +plasma-desktoptheme-default +plasma-krunner-powerdevil +plasma-runner-audioplayercontrol +plasma-runner-browserhistory +plasma-runner-contacts +plasma-runner-converter +plasma-runner-katesessions +plasma-runner-konquerorsessions +plasma-runner-konsolesessions +plasma-runner-kopete +plasma-runner-mediawiki +plasma-runner-spellchecker +plasma-wallpaper-mandelbrot +plasma-wallpaper-pattern +plasma-wallpaper-timeoftheday +plasma-wallpaper-virus +plasma-wallpaper-weather +plymouth +plymouth-plugin-label +plymouth-plugin-script +plymouth-scripts +plymouth-system-theme +pm-fallback-policy +pm-utils +policykit +polkit +polkit-kde-agent-1 +popt-data +ppp +ppp-pppoatm +pptp-linux +#prcsys +preload +prism2-utils +procps +psmisc +pulseaudio +pulseaudio-client-config +pulseaudio-esound-compat +pulseaudio-module-gconf +pulseaudio-module-x11 +pulseaudio-module-zeroconf +pulseaudio-utils +python +python-cairo +python-gobject +python-kde4 +python-ldap +python-notify +python-numpy +python-OpenSSL +python-pycrypto +python-qt4 +python-qt4-assistant +python-qt4-core +python-qt4-designer +python-qt4-gui +python-qt4-multimedia +python-qt4-network +python-qt4-opengl +python-qt4-script +python-qt4-sql +python-qt4-svg +python-qt4-test +python-qt4-webkit +python-qt4-xml +python-qt4-xmlpatterns +python-sip +python-twisted-core +python-twisted-web +python-zope-interface +pyxdg +qca2-plugin-openssl +qt4-common +qt4-database-plugin-mysql +qt4-qtdbus +qt4-style-iaora +qt4-xmlpatterns +qtscriptbindings +quota +radeontool +reiserfsprogs +resolvconf +rgb +rmt +rng-utils +rootcerts +rootfiles +rpcbind +rpm +rpmdrake +rpm-helper +rpmstats +rp-pppoe +rsnapshot +rsync +rsyslog +rtkit +run-parts +s2u +sane-backends +sane-backends-iscan +sash +sb16_csp +sdparm +sed +sessreg +setup +setxkbmap +shadow-utils +shared-desktop-ontologies +shared-mime-info +sharutils +shorewall +soprano +soprano-plugin-common +soprano-plugin-redland +soprano-plugin-virtuoso +sound-scripts +sound-theme-freedesktop +soundwrapper +sscape_ctl +strigi +sudo +suspend +sysfsutils +sysvinit-tools +t1utils +taglib-extras +tar +tcb +tcl +tcp_wrappers +termcap +time +timezone +tmpwatch +transfugdrake +uClibc +udev +udisks +unionfs-utils +unzip +update-alternatives +upower +urpmi +urw-fonts +us428control +usb_modeswitch +usbmuxd +usbutils +userdrake +usermode +usermode-consoleonly +utempter +util-linux +v4l-utils +vbetool +vim-minimal +vnstat +vte +webkit1.0 +webkit1.0-webinspector +wget +which +wireless-regdb +wireless-tools +wpa_supplicant +x11-data-cursor-themes +x11-data-xkbdata +#x11-driver-input +x11-driver-input-acecad +x11-driver-input-aiptek +x11-driver-input-evdev +x11-driver-input-fpit +x11-driver-input-hyperpen +x11-driver-input-joystick +x11-driver-input-keyboard +x11-driver-input-mouse +x11-driver-input-mutouch +x11-driver-input-penmount +x11-driver-input-synaptics +x11-driver-input-void +x11-driver-input-wacom +x11-driver-video +x11-driver-video-ati +x11-driver-video-cirrus +x11-driver-video-fbdev +x11-driver-video-glint +x11-driver-video-intel +x11-driver-video-mach64 +x11-driver-video-mga +x11-driver-video-neomagic +x11-driver-video-nouveau +x11-driver-video-nv +x11-driver-video-openchrome +x11-driver-video-r128 +x11-driver-video-radeonhd +x11-driver-video-s3 +x11-driver-video-s3virge +x11-driver-video-savage +x11-driver-video-sis +x11-driver-video-sisusb +x11-driver-video-tdfx +x11-driver-video-trident +x11-driver-video-v4l +x11-driver-video-vboxvideo +x11-driver-video-vesa +x11-driver-video-vmware +x11-driver-video-qxl +x11-font-adobe-75dpi +x11-font-alias +x11-font-bh-75dpi +x11-font-bh-lucidatypewriter-75dpi +x11-font-bitstream-75dpi +x11-font-cronyx-cyrillic +x11-font-cursor-misc +x11-font-cyrillic +x11-font-encodings +x11-font-misc-cyrillic +x11-font-misc-misc +x11-font-screen-cyrillic +x11-font-winitzki-cyrillic +x11-server-common +x11-server-xorg +xauth +xdg-user-dirs +xdg-user-dirs-gtk +xdg-utils +xdm +xdpyinfo +xev +xfsprogs +xhost +xinit +xinitrc +xkbcomp +xmessage +xmodmap +xorg-x11 +xprop +xrandr +xrdb +xset +xsetroot +xsettings-kde +xulrunner +xz +zcip +zip + +systemd-sysvinit +systemd +networkmanager +networkmanager-openvpn +networkmanager-vpnc +networkmanager-pptp +modemmanager +mobile-broadband-provider-info +plasma-applet-networkmanagement + +task-kde4 +task-x11 +x11-driver-input +x11-driver-video +task-pulseaudio + +kde4-style-qtcurve +qtcurve-gtk2 + +livestart-rosa +rosa-launcher + +#ktorrent +kde4-windeco-dekorator +rosa-elementary-theme +rosa-icons +kamera +aica-firmware +asihpi-firmware +emagic-firmware +emu1010-firmware +kernel-firmware +pcmcia-cis-firmware +turtlebeach-firmware +zd1211-firmware + +#x11-driver-video-fglrx +#x11-driver-video-nvidia-current +#x11-driver-video-nvidia173 +#x11-driver-video-nvidia96xx + + +glxinfo +alsa-utils +lib64alsa-plugins-pulseaudio +mesa-demos + +#mandriva-control-center +qgtkstylealt +plasma-desktoptheme-rosa +kdepasswd + +sphere-client-rosa +fonts-ttf-droid +#psyncclient + +nut-server +samba-client +samba-server +nfs-utils +btrfs-progs +knetworkmanager-pptp +samba-client +cifs-utils +nss_wins +samba-common +comgt +madwimax +rp-pppoe +btrfs-progs +x11-driver-video-vboxvideo +x11-driver-input-vmmouse +whois +cups +task-printing +task-printing-hp +task-printing-server +system-config-printer +nfs-utils +#vpnpptp-allde +xl2tpd +wvdial +gksu +ozerocdoff +usb_modeswitch-data +cpufrequtils +lib64stdc++6 +bind-utils +#aumix +kamera + +zenity +rosa-media-player +rosa-media-player-plugin +ffmpeg +gstreamer0.10-mpeg +rdesktop +amarok + +autofs + +ccid +krb5-workstation +lib64sasl2-plug-gssapi +nscd +nss_ldap +openldap-clients +opensc + +pam_krb5 +pam_ldap +pcsc-lite +pcsc-tools +perl-Digest-SHA +perl-Net-DNS +samba-winbind +tigervnc-server +xl2tpd +lsof +vpnpptp-allde +kcm_license +lsb-release +lib64glibc_lsb +perl-CGI +perl-Pod-Perldoc +perl-Safe +perl-Class-ISA +perl-Pod-Plainer +glibc-i18ndata + +gstreamer0.10-plugins-ugly +htop +traceroute +pulseaudio-module-bluetooth +bluez-alsa +elementary-theme +plasma-applet-battery +plasma-applet-folderview +ktorrent +lib64alsa-plugins +bash-completion +autologin +k3b +akonadi-mailfilter-agent