def calculate_conflicts(order, packagedb):
    B_0 = set(order)
    C = D = set()
    pkg_conflicts = {}

    for x in order:
        pkg = packagedb.get_package(x)

        # check if any package has conflicts with the installed packages
        conflicts = check_conflict(pkg, order)
        if conflicts:
            pkg_conflicts[x] = map(lambda c:str(c), conflicts)
            C = C.union(map(lambda c:c.package, conflicts))

        # now check if any package has conflicts with each other
        B_i = B_0.intersection(set(map(lambda c:c.package, pkg.conflicts)))
        D_i = set()
        for p in map(lambda x:packagedb.get_package(x), B_i):
            conflicted = pisi.conflict.package_conflicts(p, pkg.conflicts)
            if conflicted:
                D_i.add(str(conflicted))

        if D_i:
            D = D.union(D_i)
            D.add(pkg.name)

    return (C, D, pkg_conflicts)
def plan_upgrade(A, ignore_build = False):
    # try to construct a pisi graph of packages to
    # install / reinstall

    packagedb = ctx.packagedb

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the "install closure" graph of G_f by package
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A

    # TODO: conflicts

    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies():
                # add packages that can be upgraded
                if dependency.repo_satisfies_dep(dep):
                    if ctx.installdb.is_installed(dep.package):
                        if dependency.installed_satisfies_dep(dep):
                            continue
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
                else:
                    ctx.ui.error(_('Dependency %s of %s cannot be satisfied') % (dep, x))
                    raise Error(_("Upgrade is not possible."))
        B = Bp
    # now, search reverse dependencies to see if anything
    # should be upgraded
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            rev_deps = packagedb.get_rev_deps(x)
            for (rev_dep, depinfo) in rev_deps:
                # add only installed but unsatisfied reverse dependencies
                if ctx.installdb.is_installed(rev_dep) and \
                        (not dependency.installed_satisfies_dep(depinfo)):
                    if not dependency.repo_satisfies_dep(depinfo):
                        raise Error(_('Reverse dependency %s of %s cannot be satisfied') % (rev_dep, x))
                    if not rev_dep in G_f.vertices():
                        Bp.add(rev_dep)
                        G_f.add_plain_dep(rev_dep, x)
        B = Bp

    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    return G_f, order
Exemple #3
0
def configure_pending():
    # start with pending packages
    # configure them in reverse topological order of dependency
    A = ctx.installdb.list_pending()
    #print A
    G_f = pgraph.PGraph(packagedb)               # construct G_f
    for x in A:
        G_f.add_package(x)
    B = A
    #state = {}
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            #print pkg
            for dep in pkg.runtimeDeps:
                if dep.package in G_f.vertices():
                    G_f.add_dep(x, dep)
        B = Bp
    G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    #print order
    for x in order:
        comariface.run_postinstall(x)
Exemple #4
0
def install_pkg_names(A):
    """This is the real thing. It installs packages from
    the repository, trying to perform a minimum number of
    installs"""

    # A was a list, remove duplicates and expand components
    A_0 = A = expand_components(set(A))
    ctx.ui.debug("A = %s" % str(A))

    if len(A) == 0:
        ctx.ui.info(_("No packages to install."))
        return

    if ctx.config.get_option("ignore_dependency"):
        # simple code path then
        for x in A:
            atomicoperations.install_single_name(x)
        return  # short circuit

    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)  # construct G_f

    # find the "install closure" graph of G_f by package
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A

    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies():
                ctx.ui.debug("checking %s" % str(dep))
                # we don't deal with already *satisfied* dependencies
                if not dependency.installed_satisfies_dep(dep):
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
        B = Bp
    if ctx.config.get_option("debug"):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    check_conflicts(order)
    ctx.ui.info(
        _(
            """The following minimal list of packages will be installed
in the respective order to satisfy dependencies:
"""
        )
        + util.strlist(order)
    )
    if len(order) > len(A_0):
        if not ctx.ui.confirm(_("Do you want to continue?")):
            return False
    for x in order:
        atomicoperations.install_single_name(x)
Exemple #5
0
def package_graph(A):
    """Construct a package relations graph, containing
    all dependencies of packages A"""

    ctx.ui.debug('A = %s' % str(A))
  
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the "install closure" graph of G_f by package 
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    #state = {}
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            print pkg
            for dep in pkg.runtimeDeps:
                # we don't deal with already *satisfied* dependencies
                if not dep.package in G_f.vertices():
                    Bp.add(str(dep.package))
                G_f.add_dep(x, dep)
#               if not dependency.installed_satisfies_dep(dep):
#                   if not dep.package in G_f.vertices():
#                       Bp.add(str(dep.package))
#                   G_f.add_dep(x, dep)
        B = Bp
    return G_f
Exemple #6
0
def package_graph(A, ignore_installed = False):
    """Construct a package relations graph, containing
    all dependencies of packages A, if ignore_installed
    option is True, then only uninstalled deps will
    be added."""

    ctx.ui.debug('A = %s' % str(A))
  
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the "install closure" graph of G_f by package 
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    #state = {}
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            #print pkg
            for dep in pkg.runtimeDependencies():
                if ignore_installed:
                    if dependency.installed_satisfies_dep(dep):
                        continue
                if not dep.package in G_f.vertices():
                    Bp.add(str(dep.package))
                G_f.add_dep(x, dep)
        B = Bp
    return G_f
Exemple #7
0
def configure_pending():
    # start with pending packages
    # configure them in reverse topological order of dependency
    A = ctx.installdb.list_pending()
    G_f = pgraph.PGraph(packagedb)  # construct G_f
    for x in A:
        G_f.add_package(x)
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies:
                if dep.package in G_f.vertices():
                    G_f.add_dep(x, dep)
        B = Bp
    if ctx.get_option("debug"):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    try:
        import pisi.comariface as comariface

        for x in order:
            comariface.run_postinstall(x)
            ctx.installdb.clear_pending(x)
    except ImportError:
        raise Error(_("COMAR: comard not fully installed"))
    def run(self):
        """Remove a single package"""
        inst_packagedb = packagedb.inst_packagedb
        self.package = packagedb.get_package(self.package_name)
        self.files = ctx.installdb.files(self.package_name)
       
        ctx.ui.status(_('Removing package %s') % self.package_name)
        if not ctx.installdb.is_installed(self.package_name):
            raise Exception(_('Trying to remove nonexistent package ')
                            + self.package_name)
                            
        self.check_dependencies()
            
        self.run_preremove()
            
        for fileinfo in self.files.list:
            self.remove_file(fileinfo)

        txn = ctx.dbenv.txn_begin()
        try:
            self.remove_db(txn)
            txn.commit()
        except db.DBError, e:
            txn.abort()
            raise e
Exemple #9
0
def plan_remove(A):
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the (install closure) graph of G_f by package 
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            rev_deps = packagedb.get_rev_deps(x)
            for (rev_dep, depinfo) in rev_deps:
                # we don't deal with uninstalled rev deps
                # and unsatisfied dependencies (this is important, too)
                if packagedb.inst_packagedb.has_package(rev_dep) and \
                   dependency.installed_satisfies_dep(depinfo):
                    if not rev_dep in G_f.vertices():
                        Bp.add(rev_dep)
                        G_f.add_plain_dep(rev_dep, x)
        B = Bp
    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    return G_f, order
Exemple #10
0
def plan_install_pkg_names(A):
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the "install closure" graph of G_f by package 
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies():
                ctx.ui.debug('checking %s' % str(dep))
                # we don't deal with already *satisfied* dependencies
                if not dependency.installed_satisfies_dep(dep):
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
        B = Bp
    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    check_conflicts(order)
    return G_f, order
Exemple #11
0
def repo_satisfies_dep(depinfo):
    """determine if a package in *repository* satisfies given
dependency spec"""
    pkg_name = depinfo.package
    if not packagedb.has_package(pkg_name):
        return False
    else:
        pkg = packagedb.get_package(pkg_name)
        (version, release) = (pkg.version, pkg.release)
        return depinfo.satisfies(pkg_name, version, release)
Exemple #12
0
def remove(A):
    """remove set A of packages from system (A is a list of package names)"""
    
    # filter packages that are not installed
    A_0 = A = set(A)
    Ap = []
    for x in A:
        if ctx.installdb.is_installed(x):
            Ap.append(x)
        else:
            ctx.ui.info(_('Package %s does not exist. Cannot remove.') % x)
    A = set(Ap)

    if len(A)==0:
        ctx.ui.info(_('No packages to remove.'))
        return
        
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the (install closure) graph of G_f by package 
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            rev_deps = packagedb.get_rev_deps(x)
            for (rev_dep, depinfo) in rev_deps:
                # we don't deal with unsatisfied dependencies
                if packagedb.has_package(rev_dep) and \
                   dependency.installed_satisfies_dep(depinfo):
                    if not rev_dep in G_f.vertices():
                        Bp.add(rev_dep)
                        G_f.add_plain_dep(rev_dep, x)
        B = Bp
    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    ctx.ui.info(_("""The following minimal list of packages will be removed
in the respective order to satisfy dependencies:
""") + util.strlist(order))
    if len(order) > len(A_0):
        if not ctx.ui.confirm('Do you want to continue?'):
            ctx.ui.warning(_('Package removal declined'))
            return False
    for x in order:
        if ctx.installdb.is_installed(x):
            atomicoperations.remove_single(x)
        else:
            ctx.ui.info(_('Package %s is not installed. Cannot remove.') % x)
Exemple #13
0
 def __init__(self, package_name, ignore_dep = None):
     super(Remove, self).__init__(ignore_dep)
     self.package_name = package_name
     self.package = packagedb.get_package(self.package_name)
     try:
         self.files = ctx.installdb.files(self.package_name)
     except pisi.Error, e:
         # for some reason file was deleted, we still allow removes!
         ctx.ui.error(unicode(e))
         ctx.ui.warning(_('File list could not be read for package %s, continuing removal.') % package_name)
         self.files = Files()
Exemple #14
0
def install_pkg_names(A, reinstall = False):
    """This is the real thing. It installs packages from
    the repository, trying to perform a minimum number of
    installs"""

    # A was a list, remove duplicates and expand components
    A_0 = A = expand_components(set(A))
    ctx.ui.debug('A = %s' % str(A))

    # filter packages that are already installed
    if not reinstall:
        Ap = set(filter(lambda x: not ctx.installdb.is_installed(x), A))
        d = A - Ap
        if len(d) > 0:
            ctx.ui.warning(_('Not re-installing the following packages: ') +
                           util.strlist(d))
            A = Ap

    if len(A)==0:
        ctx.ui.info(_('No packages to install.'))
        return
        
    if not ctx.config.get_option('ignore_dependency'):
        G_f, order = plan_install_pkg_names(A)
    else:
        G_f = None
        order = A

    ctx.ui.info(_("""The following minimal list of packages will be installed
in the respective order to satisfy dependencies:
""") + util.strlist(order))

    #this silly try/except block will be removed soon..
    try:
        total_size = sum([packagedb.get_package(p).packageSize for p in order])
    except:
        total_size = 0

    if total_size:
        total_size, symbol = util.human_readable_size(total_size)
        ctx.ui.warning(_('Total size of packages: %.2f %s') % (total_size, symbol))

    if ctx.get_option('dry_run'):
        return

    if len(order) > len(A_0):
        if not ctx.ui.confirm(_('There are extra packages due to dependencies. Do you want to continue?')):
            return False
            
    ctx.ui.notify(ui.packagestogo, order = order)
            
    for x in order:
        atomicoperations.install_single_name(x)
Exemple #15
0
 def upgradable(dep):
     # pre dep.package is installed
     (v, r, b) = ctx.installdb.get_version(dep.package)
     rep_pkg = packagedb.get_package(dep.package)
     (vp, rp, bp) = (rep_pkg.version, rep_pkg.release, rep_pkg.build)
     if ignore_build or (not b) or (not bp):
         # if we can't look at build
         if r >= rp:  # installed already new
             return False
     elif b and bp and b >= bp:
         return False
     return True
Exemple #16
0
def remove(A):
    """remove set A of packages from system (A is a list of package names)"""
    
    # filter packages that are not installed
    Ap = []
    for x in A:
        if ctx.installdb.is_installed(x):
            Ap.append(x)
        else:
            ctx.ui.info(_('Package %s does not exist. Cannot remove.') % x)
    A = Ap

    if len(A)==0:
        ctx.ui.info(_('No packages to remove.'))
        return True
        
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the (install closure) graph of G_f by package 
    # set A using packagedb
    #print A
    for x in A:
        G_f.add_package(x)
    B = A
    #state = {}
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            #print 'processing', pkg.name
            rev_deps = packagedb.get_rev_deps(x)
            for (rev_dep, depinfo) in rev_deps:
                #print 'checking ', rev_dep
                # we don't deal with unsatisfied dependencies
                if dependency.installed_satisfies_dep(depinfo):
                    if not rev_dep in G_f.vertices():
                        Bp.add(rev_dep)
                        G_f.add_plain_dep(rev_dep, x)
        B = Bp
    #G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    #FIXME: do something more informative here
    #print order
    for x in order:
        if ctx.installdb.is_installed(x):
            operations.remove_single(x)
        else:
            ctx.ui.info(_('Package %s is not installed. Cannot remove.') % x)
        
    return True                         # everything went OK :)
Exemple #17
0
def configure_pending():
    # start with pending packages
    # configure them in reverse topological order of dependency
    A = ctx.installdb.list_pending()
    G_f = pgraph.PGraph(packagedb)               # construct G_f
    for x in A.keys():
        G_f.add_package(x)
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B.keys():
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies():
                if dep.package in G_f.vertices():
                    G_f.add_dep(x, dep)
        B = Bp
    if ctx.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    try:
        import pisi.comariface as comariface
        for x in order:
            if ctx.installdb.is_installed(x):
                pkginfo = A[x]
                pkgname = util.package_name(x, pkginfo.version,
                                        pkginfo.release,
                                        False,
                                        False)
                pkg_path = util.join_path(ctx.config.lib_dir(),
                                          'package', pkgname)
                m = MetaData()
                metadata_path = util.join_path(pkg_path, ctx.const.metadata_xml)
                m.read(metadata_path)
                for pcomar in m.package.providesComar:
                    scriptPath = util.join_path(pkg_path,
                                            ctx.const.comar_dir,
                                            pcomar.script)
                    comariface.register(pcomar, x, scriptPath)
                    # FIXME: we need a full package info here!
                    # Eray, please fix this
                    # your wish is a command, darling -- eray
                    pkginfo.name = x
                    ctx.ui.notify(pisi.ui.configuring, package = pkginfo, files = None)
                    comariface.run_postinstall(x)
                    ctx.ui.notify(pisi.ui.configured, package = pkginfo, files = None)
            ctx.installdb.clear_pending(x)
    except ImportError:
        raise Error(_("COMAR: comard not fully installed"))
Exemple #18
0
def install_pkg_names(A):
    """This is the real thing. It installs packages from
    the repository, trying to perform a minimum number of
    installs"""

    A = set(A) # A was a list, remove duplicates

    ctx.ui.debug('A = %s' % str(A))

    if len(A)==0:
        ctx.ui.info(_('No packages to install.'))
        return True
    
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the "install closure" graph of G_f by package 
    # set A using packagedb
    #print A
    for x in A:
        G_f.add_package(x)
    B = A
    #state = {}
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            #print pkg
            for dep in pkg.runtimeDeps:
                ctx.ui.debug('checking %s' % str(dep))
                # we don't deal with already *satisfied* dependencies
                if not dependency.installed_satisfies_dep(dep):
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
        B = Bp
    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    #print order
    for x in order:
        operations.install_single_name(x)
        
    return True                         # everything went OK :)
Exemple #19
0
def info_name(package_name):
    """fetch package information for a package"""
    if packagedb.has_package(package_name):
        package = packagedb.get_package(package_name)
        from pisi.metadata import MetaData
        metadata = MetaData()
        metadata.package = package
        #FIXME: get it from sourcedb
        metadata.source = None
        #TODO: fetch the files from server if possible
        if ctx.installdb.is_installed(package.name):
            files = ctx.installdb.files(package.name)
        else:
            files = None
        return metadata, files
    else:
        raise Error(_('Package %s not found') % package_name)
Exemple #20
0
def list_upgradable():
    ignore_build = ctx.get_option('ignore_build_no')

    A = ctx.installdb.list_installed()
    # filter packages that are not upgradable
    Ap = []
    for x in A:
        (version, release, build) = ctx.installdb.get_version(x)
        pkg = packagedb.get_package(x)
        if ignore_build or (not build):
            if release < pkg.release:
                Ap.append(x)
        elif build < pkg.build:
                Ap.append(x)
        else:
            pass
            #ctx.ui.info('Package %s cannot be upgraded. ' % x)
    return Ap
Exemple #21
0
 def run(self):
     """Remove a single package"""
     inst_packagedb = packagedb.inst_packagedb
     self.package = packagedb.get_package(self.package_name)
    
     ctx.ui.info(_('Removing package %s') % self.package_name)
     if not ctx.installdb.is_installed(self.package_name):
         raise Exception(_('Trying to remove nonexistent package ')
                         + self.package_name)
                         
     self.check_dependencies()
         
     self.run_preremove()
         
     for fileinfo in ctx.installdb.files(self.package_name).list:
         self.remove_file(fileinfo)
 
     self.remove_db()
     self.remove_pisi_files()
Exemple #22
0
def calculate_conflicts(order, packagedb):
    B_0 = set(order)
    C = D = set()
    pkg_conflicts = {}

    for x in order:
        pkg = packagedb.get_package(x)
        B_p = set(check_conflict(pkg))
        if B_p:
            pkg_conflicts[x] = B_p
            C = C.union(B_p)

        B_i = B_0.intersection(set(pkg.conflicts))
        # check if there are any conflicts within the packages that are
        # going to be installed
        if B_i:
            D = D.union(B_i)
            D.add(pkg.name)

    return (C, D, pkg_conflicts)
Exemple #23
0
def calculate_conflicts(order, packagedb):
    B_0 = set(order)
    C = D = set()
    pkg_conflicts = {}

    for x in order:
        pkg = packagedb.get_package(x)
        B_p = set(check_conflict(pkg))
        if B_p:
            pkg_conflicts[x] = B_p
            C = C.union(B_p)

        B_i = B_0.intersection(set(pkg.conflicts))
        # check if there are any conflicts within the packages that are
        # going to be installed
        if B_i:
            D = D.union(B_i)
            D.add(pkg.name)

    return (C, D, pkg_conflicts)
Exemple #24
0
 def from_name(name):
     # download package and return an installer object
     # find package in repository
     repo = packagedb.which_repo(name)
     if repo:
         repo = ctx.repodb.get_repo(repo)
         pkg = packagedb.get_package(name)
 
         # FIXME: let pkg.packageURI be stored as URI type rather than string
         pkg_uri = URI(pkg.packageURI)
         if pkg_uri.is_absolute_path():
             pkg_path = str(pkg.packageURI)
         else:
             pkg_path = os.path.join(os.path.dirname(repo.indexuri.get_uri()),
                                     str(pkg_uri.path()))
 
         ctx.ui.debug(_("Package URI: %s") % pkg_path)
 
         return Install(pkg_path)
     else:
         raise Error(_("Package %s not found in any active repository.") % name)
def install_single_name(name, upgrade = False):
    """install a single package from ID"""
    # find package in repository
    repo = packagedb.which_repo(name)
    if repo:
        repo = ctx.repodb.get_repo(repo)
        pkg = packagedb.get_package(name)

        # FIXME: let pkg.packageURI be stored as URI type rather than string
        pkg_uri = URI(pkg.packageURI)
        if pkg_uri.is_absolute_path():
            pkg_path = str(pkg.packageURI)
        else:
            pkg_path = os.path.join(os.path.dirname(repo.indexuri.get_uri()),
                                    str(pkg_uri.path()))

        ctx.ui.debug(_("Package URI: %s") % pkg_path)

        # Package will handle remote file for us!
        install_single_file(pkg_path, upgrade)
    else:
        raise Error(_("Package %s not found in any active repository.") % name)
Exemple #26
0
def check_conflicts(order):
    """check if upgrading to the latest versions will cause havoc
    done in a simple minded way without regard for dependencies of
    conflicts, etc."""
    B_0 = B = set(order)
    C = set()
    # calculate conflict closure
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x) # get latest version!
            #TODO: read conflicts from a conflicts db...
            for conflict in pkg.conflicts:
                if ctx.installdb.is_installed(self.pkginfo):
                    Bp.add(conflict)
                    C.add(conflict)
        B = Bp
    if B_0.intersection(C):
        raise Error(_("Selected packages %s and %s are in conflict.") % (x, pkg))
    if C:
        if not ctx.ui.confirm(_('Remove the following conflicting packages?')):
            #raise Error(_("Package %s conflicts installed package %s") % (x, pkg))
            raise Error(_("Conflicts remain"))
Exemple #27
0
def install_pkg_files(package_URIs):
    """install a number of pisi package files"""
    from package import Package

    ctx.ui.debug('A = %s' % str(package_URIs))

    for x in package_URIs:
        if not x.endswith(ctx.const.package_suffix):
            raise Error(_('Mixing file names and package names not supported yet.'))

    if ctx.config.get_option('ignore_dependency'):
        # simple code path then
        for x in package_URIs:
            atomicoperations.install_single_file(x)
        return # short circuit
            
    # read the package information into memory first
    # regardless of which distribution they come from
    d_t = {}
    dfn = {}
    for x in package_URIs:
        package = Package(x)
        package.read()
        name = str(package.metadata.package.name)
        d_t[name] = package.metadata.package
        dfn[name] = x

    def satisfiesDep(dep):
        # is dependency satisfied among available packages
        # or packages to be installed?
        return dependency.installed_satisfies_dep(dep) \
               or dependency.dict_satisfies_dep(d_t, dep)
            
    # for this case, we have to determine the dependencies
    # that aren't already satisfied and try to install them 
    # from the repository
    dep_unsatis = []
    for name in d_t.keys():
        pkg = d_t[name]
        deps = pkg.runtimeDependencies()
        for dep in deps:
            if not satisfiesDep(dep):
                dep_unsatis.append(dep)

    # now determine if these unsatisfied dependencies could
    # be satisfied by installing packages from the repo

    # if so, then invoke install_pkg_names
    extra_packages = [x.package for x in dep_unsatis]
    if extra_packages:
        ctx.ui.info(_("""The following packages will be installed
in the respective order to satisfy extra dependencies:
""") + util.strlist(extra_packages))
        if not ctx.ui.confirm(_('Do you want to continue?')):
            raise Error(_('External dependencies not satisfied'))
        install_pkg_names(extra_packages)

    class PackageDB:
        def get_package(self, key, repo = None):
            return d_t[str(key)]
    
    packagedb = PackageDB()
   
    A = d_t.keys()
   
    if len(A)==0:
        ctx.ui.info(_('No packages to install.'))
        return
    
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the "install closure" graph of G_f by package 
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies():
                if dependency.dict_satisfies_dep(d_t, dep):
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
        B = Bp
    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    if not ctx.get_option('ignore_file_conflicts'):
        check_conflicts(order, packagedb)
    order.reverse()
    ctx.ui.info(_('Installation order: ') + util.strlist(order) )

    if ctx.get_option('dry_run'):
        return

    ctx.ui.notify(ui.packagestogo, order = order)
        
    for x in order:
        atomicoperations.install_single_file(dfn[x])

    pisi_installed = ctx.installdb.is_installed('pisi')
    
    if 'pisi' in order and pisi_installed:
        upgrade_pisi()
Exemple #28
0
def plan_upgrade(A, ignore_build=False):
    # try to construct a pisi graph of packages to
    # install / reinstall

    packagedb = ctx.packagedb

    G_f = pgraph.PGraph(packagedb)  # construct G_f

    # find the "install closure" graph of G_f by package
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A

    # TODO: conflicts

    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies():
                # add packages that can be upgraded
                if dependency.repo_satisfies_dep(dep):
                    if ctx.installdb.is_installed(dep.package):
                        if ctx.get_option('eager'):
                            if not is_upgradable(dep.package):
                                continue
                        else:
                            if dependency.installed_satisfies_dep(dep):
                                continue
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
                else:
                    ctx.ui.error(
                        _('Dependency %s of %s cannot be satisfied') %
                        (dep, x))
                    raise Error(_("Upgrade is not possible."))
        B = Bp
    # now, search reverse dependencies to see if anything
    # should be upgraded
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            rev_deps = packagedb.get_rev_deps(x)
            for (rev_dep, depinfo) in rev_deps:
                if ctx.get_option('eager'):
                    # add all upgradable reverse deps
                    if is_upgradable(rev_dep):
                        if not rev_dep in G_f.vertices():
                            Bp.add(rev_dep)
                            G_f.add_plain_dep(rev_dep, x)
                else:
                    # add only installed but unsatisfied reverse dependencies
                    if ctx.installdb.is_installed(rev_dep) and \
                       (not dependency.installed_satisfies_dep(depinfo)):
                        if not dependency.repo_satisfies_dep(depinfo):
                            raise Error(
                                _('Reverse dependency %s of %s cannot be satisfied'
                                  ) % (rev_dep, x))
                        if not rev_dep in G_f.vertices():
                            Bp.add(rev_dep)
                            G_f.add_plain_dep(rev_dep, x)
        B = Bp

    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    if not ctx.get_option('ignore_file_conflicts'):
        check_conflicts(order, ctx.packagedb)
    return G_f, order
Exemple #29
0
def install_pkg_files(package_URIs):
    """install a number of pisi package files"""
    from package import Package

    ctx.ui.debug('A = %s' % str(package_URIs))

    for x in package_URIs:
        if not x.endswith(ctx.const.package_suffix):
            raise Error(
                _('Mixing file names and package names not supported yet.'))

    if ctx.config.get_option('ignore_dependency'):
        # simple code path then
        for x in package_URIs:
            atomicoperations.install_single_file(x)
        return  # short circuit

    # read the package information into memory first
    # regardless of which distribution they come from
    d_t = {}
    dfn = {}
    for x in package_URIs:
        package = Package(x)
        package.read()
        name = str(package.metadata.package.name)
        d_t[name] = package.metadata.package
        dfn[name] = x

    def satisfiesDep(dep):
        # is dependency satisfied among available packages
        # or packages to be installed?
        return dependency.installed_satisfies_dep(dep) \
               or dependency.dict_satisfies_dep(d_t, dep)

    # for this case, we have to determine the dependencies
    # that aren't already satisfied and try to install them
    # from the repository
    dep_unsatis = []
    for name in d_t.keys():
        pkg = d_t[name]
        deps = pkg.runtimeDependencies()
        for dep in deps:
            if not satisfiesDep(dep):
                dep_unsatis.append(dep)

    # now determine if these unsatisfied dependencies could
    # be satisfied by installing packages from the repo

    # if so, then invoke install_pkg_names
    extra_packages = [x.package for x in dep_unsatis]
    if extra_packages:
        ctx.ui.info(
            _("""The following packages will be installed
in the respective order to satisfy extra dependencies:
""") + util.strlist(extra_packages))
        if not ctx.ui.confirm(_('Do you want to continue?')):
            raise Error(_('External dependencies not satisfied'))
        install_pkg_names(extra_packages)

    class PackageDB:
        def get_package(self, key, repo=None):
            return d_t[str(key)]

    packagedb = PackageDB()

    A = d_t.keys()

    if len(A) == 0:
        ctx.ui.info(_('No packages to install.'))
        return

    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)  # construct G_f

    # find the "install closure" graph of G_f by package
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies():
                if dependency.dict_satisfies_dep(d_t, dep):
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
        B = Bp
    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    if not ctx.get_option('ignore_file_conflicts'):
        check_conflicts(order, packagedb)
    order.reverse()
    ctx.ui.info(_('Installation order: ') + util.strlist(order))

    if ctx.get_option('dry_run'):
        return

    ctx.ui.notify(ui.packagestogo, order=order)

    for x in order:
        atomicoperations.install_single_file(dfn[x])
Exemple #30
0
def install_pkg_files(package_URIs):
    """install a number of pisi package files"""
    from package import Package

    ctx.ui.debug('A = %s' % str(package_URIs))

    for x in package_URIs:
        if not x.endswith(ctx.const.package_prefix):
            ctx.ui.error('Mixing file names and package names not supported YET.\n')
            return False

    # read the package information into memory first
    # regardless of which distribution they come from
    d_t = {}
    dfn = {}
    for x in package_URIs:
        package = Package(x)
        package.read()
        name = str(package.metadata.package.name)
        d_t[name] = package.metadata.package
        dfn[name] = x

    def satisfiesDep(dep):
        return dependency.installed_satisfies_dep(dep) \
               or dependency.dict_satisfies_dep(d_t, dep)
            
    # for this case, we have to determine the dependencies
    # that aren't already satisfied and try to install them 
    # from the repository
    dep_unsatis = []
    for name in d_t.keys():
        pkg = d_t[name]
        deps = pkg.runtimeDeps
        for dep in deps:
            if not satisfiesDep(dep):
                dep_unsatis.append(dep)

    # now determine if these unsatisfied dependencies could
    # be satisfied by installing packages from the repo

    # if so, then invoke install_pkg_names
    extra_packages = [x.package for x in dep_unsatis]
    if (extra_packages and install_pkg_names(extra_packages)) or \
           (not extra_packages):
    
        class PackageDB:
            def __init__(self):
                self.d = d_t
            
            def get_package(self, key):
                return d_t[str(key)]
        
        packagedb = PackageDB()
       
        A = d_t.keys()
       
        if len(A)==0:
            ctx.ui.info('No packages to install.')
            return True
        
        # try to construct a pisi graph of packages to
        # install / reinstall
    
        G_f = pgraph.PGraph(packagedb)               # construct G_f
    
        # find the "install closure" graph of G_f by package 
        # set A using packagedb
        print A
        for x in A:
            G_f.add_package(x)
        B = A
        #state = {}
        while len(B) > 0:
            Bp = set()
            for x in B:
                pkg = packagedb.get_package(x)
                print pkg
                for dep in pkg.runtimeDeps:
                    print 'checking ', dep
                    if dependency.dict_satisfies_dep(d_t, dep):
                        if not dep.package in G_f.vertices():
                            Bp.add(str(dep.package))
                        G_f.add_dep(x, dep)
            B = Bp
        G_f.write_graphviz(sys.stdout)
        order = G_f.topological_sort()
        order.reverse()
        print order

        for x in order:
            operations.install_single_file(dfn[x])
    else:
        raise Error('External dependencies not satisfied')

    return True # everything went OK.
Exemple #31
0
def upgrade_pkg_names(A):
    """Re-installs packages from the repository, trying to perform
    a maximum number of upgrades."""
    
    ignore_build = ctx.config.options and ctx.config.options.ignore_build_no

    # filter packages that are not upgradable
    Ap = []
    for x in A:
        if not ctx.installdb.is_installed(x):
            ctx.ui.info('Package %s is not installed.' % x)
            continue
        (version, release, build) = ctx.installdb.get_version(x)
        pkg = packagedb.get_package(x)
        if ignore_build or (not build):
            if release < pkg.release:
                Ap.append(x)
        elif build < pkg.build:
                Ap.append(x)
        else:
            #ctx.ui.info('Package %s cannot be upgraded. ' % x)
            ctx.ui.info('Package %s is already at its latest version %s,\
 release %s, build %s.'
                    % (x, pkg.version, pkg.release, pkg.build))
    A = Ap

    if len(A)==0:
        ctx.ui.info('No packages to upgrade.')
        return True

    ctx.ui.debug('A = %s' % str(A))
    
    # try to construct a pisi graph of packages to
    # install / reinstall

    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the "install closure" graph of G_f by package 
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    #state = {}
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            print pkg
            for dep in pkg.runtimeDeps:
                print 'checking ', dep
                # add packages that can be upgraded
                if dependency.repo_satisfies_dep(dep):
                    if ctx.installdb.is_installed(dep.package):
                        (v,r,b) = ctx.installdb.get_version(dep.package)
                        rep_pkg = packagedb.get_package(dep.package)
                        (vp,rp,bp) = (rep_pkg.version, rep_pkg.release, 
                                      rep_pkg.build)
                        if ignore_build or (not b) or (not bp):
                            # if we can't look at build
                            if r >= rp:     # installed already new
                                continue
                        elif b and bp and b >= bp:
                            continue
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
        B = Bp
    G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    print order
    for x in order:
        operations.install_single_name(x, True)
        
    return True                         # everything went OK :)
Exemple #32
0
def plan_upgrade(A):
    # try to construct a pisi graph of packages to
    # install / reinstall

    packagedb = ctx.packagedb
    
    G_f = pgraph.PGraph(packagedb)               # construct G_f

    # find the "install closure" graph of G_f by package 
    # set A using packagedb
    for x in A:
        G_f.add_package(x)
    B = A
    
    def upgradable(dep):
        #pre dep.package is installed
        (v,r,b) = ctx.installdb.get_version(dep.package)
        rep_pkg = packagedb.get_package(dep.package)
        (vp,rp,bp) = (rep_pkg.version, rep_pkg.release, 
                      rep_pkg.build)
        if ignore_build or (not b) or (not bp):
            # if we can't look at build
            if r >= rp:     # installed already new
                return False
        elif b and bp and b >= bp:
            return False
        return True

    # TODO: conflicts

    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            for dep in pkg.runtimeDependencies():
                # add packages that can be upgraded
                if dependency.repo_satisfies_dep(dep):
                    #TODO: distinguish must upgrade and upgradable
                    if ctx.installdb.is_installed(dep.package):
                        if not ctx.get_option('eager'):
                            if dependency.installed_satisfies_dep(dep):
                                continue
                        else:
                            if not upgradable(dep):
                                continue
                    if not dep.package in G_f.vertices():
                        Bp.add(str(dep.package))
                    G_f.add_dep(x, dep)
                else:
                    raise Error(_("Reverse dependency %s cannot be satisfied") % rev_dep)
        B = Bp
    # now, search reverse dependencies to see if anything
    # should be upgraded
    B = A
    while len(B) > 0:
        Bp = set()
        for x in B:
            pkg = packagedb.get_package(x)
            rev_deps = packagedb.get_rev_deps(x)
            for (rev_dep, depinfo) in rev_deps:
                if not ctx.get_option('eager'):
                    # add unsatisfied reverse dependencies
                    if packagedb.has_package(rev_dep) and \
                       (not dependency.installed_satisfies_dep(depinfo)):
                        if not dependency.repo_satisfies_dep(depinfo):
                            raise Error(_("Reverse dependency %s cannot be satisfied") % rev_dep)
                        if not rev_dep in G_f.vertices():
                            Bp.add(rev_dep)
                            G_f.add_plain_dep(rev_dep, x)
                else:
                    if not rev_dep in G_f.vertices():
                        Bp.add(rev_dep)
                        G_f.add_plain_dep(rev_dep, x)
        B = Bp

    if ctx.config.get_option('debug'):
        G_f.write_graphviz(sys.stdout)
    order = G_f.topological_sort()
    order.reverse()
    check_conflicts(order, ctx.packagedb)
    return G_f, order
Exemple #33
0
def upgrade_pkg_names(A = []):
    """Re-installs packages from the repository, trying to perform
    a maximum number of upgrades."""
    
    ignore_build = ctx.get_option('ignore_build_no')

    if not A:
        # if A is empty, then upgrade all packages
        A = ctx.installdb.list_installed()

    # filter packages that are not upgradable
    A_0 = A = expand_components(set(A))
    Ap = []
    for x in A:
        if x.endswith(ctx.const.package_suffix):
            ctx.ui.debug(_("Warning: package *name* ends with '.pisi'"))
        if not ctx.installdb.is_installed(x):
            ctx.ui.info(_('Package %s is not installed.') % x)
            continue
        (version, release, build) = ctx.installdb.get_version(x)
        pkg = packagedb.get_package(x)

        if ignore_build or (not build) or (not pkg.build):
            if release < pkg.release:
                Ap.append(x)
            else:
                ctx.ui.info(_('Package %s is already at the latest release %s.')
                            % (pkg.name, pkg.release))
        else:
            if build < pkg.build:
                Ap.append(x)
            else:
                ctx.ui.info(_('Package %s is already at the latest build %s.')
                            % (pkg.name, pkg.build))
    A = set(Ap)

    if len(A)==0:
        ctx.ui.info(_('No packages to upgrade.'))
        return True

    ctx.ui.debug('A = %s' % str(A))
    
    if not ctx.config.get_option('ignore_dependency'):
        G_f, order = plan_upgrade(A)
    else:
        G_f = None
        order = A

    ctx.ui.info(_("""The following packages will be upgraded:\n""") +
                util.strlist(order))

    if ctx.get_option('dry_run'):
        return

    if len(order) > len(A_0):
        if not ctx.ui.confirm(_('There are extra packages due to dependencies. Do you want to continue?')):
            return False

    install_ops = [atomicoperations.Install.from_name(x) for x in order]
    
    for install in install_ops:
        install.install(True)