catalog.py revision 39
23N/A#!/usr/bin/python
23N/A#
23N/A# CDDL HEADER START
23N/A#
23N/A# The contents of this file are subject to the terms of the
23N/A# Common Development and Distribution License (the "License").
23N/A# You may not use this file except in compliance with the License.
23N/A#
23N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
23N/A# or http://www.opensolaris.org/os/licensing.
23N/A# See the License for the specific language governing permissions
23N/A# and limitations under the License.
23N/A#
23N/A# When distributing Covered Code, include this CDDL HEADER in each
23N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
23N/A# If applicable, add the following below this CDDL HEADER, with the
23N/A# fields enclosed by brackets "[]" replaced with your own identifying
23N/A# information: Portions Copyright [yyyy] [name of copyright owner]
23N/A#
23N/A# CDDL HEADER END
23N/A#
23N/A# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23N/A# Use is subject to license terms.
23N/A
23N/Aimport os
23N/Aimport re
23N/Aimport sha
23N/Aimport shutil
23N/Aimport time
23N/Aimport urllib
23N/A
23N/Aimport pkg.fmri as fmri
36N/Aimport pkg.package as package
23N/A
34N/Aclass Catalog(object):
34N/A """A Catalog is the representation of the package FMRIs available to
34N/A this client or repository. Both purposes utilize the same storage
34N/A format.
24N/A
26N/A The serialized structure of the repository is an unordered list of
26N/A available package versions, followed by an unordered list of
26N/A incorporation relationships between packages. This latter section
26N/A allows the graph to be topologically sorted by the client.
26N/A
37N/A XXX A authority mirror-uri ...
37N/A XXX ...
37N/A
26N/A V fmri
26N/A V fmri
26N/A ...
26N/A I fmri fmri
26N/A I fmri fmri
26N/A ...
26N/A
37N/A XXX Mirroring records also need to be allowed from client configuration,
37N/A and not just catalogs.
37N/A
30N/A XXX It would be nice to include available tags and package sizes,
30N/A although this could also be calculated from the set of manifests.
37N/A
37N/A XXX self.pkgs should be a dictionary, accessed by fmri string (or
37N/A package name). Current code is O(N_packages) O(M_versions), should be
37N/A O(1) O(M_versions), and possibly O(1) O(1).
26N/A """
23N/A
23N/A def __init__(self):
34N/A self.authority = None
34N/A self.catalog_root = ""
34N/A
26N/A self.pkgs = []
24N/A self.relns = {}
23N/A return
23N/A
34N/A def set_authority(self, authority):
34N/A self.authority = authority
34N/A
34N/A def set_catalog_root(self, croot):
34N/A self.catalog_root = croot
34N/A
36N/A def load(self, path):
36N/A self.path = path
36N/A cfile = file(path, "r")
36N/A centries = cfile.readlines()
36N/A
36N/A for entry in centries:
36N/A # each V line is an fmri
36N/A m = re.match("^V (pkg:[^ ]*)", entry)
36N/A if m == None:
36N/A continue
36N/A
36N/A pname = m.group(1)
36N/A self.add_fmri(fmri.PkgFmri(pname, None))
36N/A
34N/A return
34N/A
36N/A def add_fmri(self, pkgfmri):
36N/A name = pkgfmri.get_pkg_stem()
36N/A pfmri = fmri.PkgFmri(name, None)
36N/A
36N/A for pkg in self.pkgs:
39N/A if pkg.fmri.is_same_pkg(pfmri):
36N/A pkg.add_version(pkgfmri)
36N/A return
36N/A
36N/A pkg = package.Package(pfmri)
36N/A pkg.add_version(pkgfmri)
36N/A self.pkgs.append(pkg)
36N/A
26N/A def add_pkg(self, pkg):
36N/A for opkg in self.pkgs:
36N/A if pkg.fmri == opkg.fmri:
37N/A #
37N/A # XXX This package is already in the catalog
37N/A # with some version set. Are we updating the
37N/A # version set or merging the two?
37N/A #
37N/A opkg = pkg
37N/A return
26N/A
37N/A self.pkgs.append(pkg)
26N/A
24N/A return
24N/A
34N/A def add_package_fmri(self, pkg_fmri):
34N/A return
34N/A
34N/A def delete_package_fmri(self, pkg_fmri):
34N/A return
34N/A
36N/A def get_matching_pkgs(self, pfmri, constraint):
36N/A """Iterate through the catalog's, looking for an fmri match."""
36N/A
36N/A # XXX FMRI-based implementation doesn't do pattern matching, but
36N/A # exact matches only.
36N/A pf = fmri.PkgFmri(pfmri, None)
36N/A
30N/A for pkg in self.pkgs:
36N/A if pkg.fmri.is_similar(pf):
30N/A return pkg.matching_versions(pfmri, constraint)
30N/A
30N/A raise KeyError, "%s not found in catalog" % pfmri
30N/A
24N/A def __str__(self):
24N/A s = ""
26N/A for p in self.pkgs:
36N/A s = s + p.get_catalog_entry()
24N/A for r in self.relns:
26N/A s = s + "I %s\n" % r
24N/A return s
24N/A
34N/A def difference(self, catalog):
34N/A """Return a pair of lists, the first list being those package
34N/A FMRIs present in the current object but not in the presented
34N/A catalog, the second being those present in the presented catalog
34N/A but not in the current catalog."""
34N/A return