api_common.py revision 1638
1638N/A#!/usr/bin/python
1638N/A#
1638N/A# CDDL HEADER START
1638N/A#
1638N/A# The contents of this file are subject to the terms of the
1638N/A# Common Development and Distribution License (the "License").
1638N/A# You may not use this file except in compliance with the License.
1638N/A#
1638N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1638N/A# or http://www.opensolaris.org/os/licensing.
1638N/A# See the License for the specific language governing permissions
1638N/A# and limitations under the License.
1638N/A#
1638N/A# When distributing Covered Code, include this CDDL HEADER in each
1638N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1638N/A# If applicable, add the following below this CDDL HEADER, with the
1638N/A# fields enclosed by brackets "[]" replaced with your own identifying
1638N/A# information: Portions Copyright [yyyy] [name of copyright owner]
1638N/A#
1638N/A# CDDL HEADER END
1638N/A#
1638N/A
1638N/A#
2616N/A# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
1638N/A# Use is subject to license terms.
1638N/A#
1638N/A# Visible changes to classes here require an update to
1638N/A# doc/client_api_versions.txt and/or doc/server_api_versions.txt.
1638N/A
1638N/A"""Contains API functions and classes common to both pkg.client.api and
1638N/Apkg.server.api."""
2616N/A
1638N/Aimport pkg.client.image as image
1638N/Aimport pkg.fmri as fmri
1638N/Aimport pkg.misc as misc
1638N/A
1638N/Aclass LicenseInfo(object):
1638N/A """A class representing the license information a package
1638N/A provides. Not intended for instantiation by API consumers."""
2313N/A
1638N/A def __init__(self, pfmri, act, img=None, text=None):
2313N/A self.__action = act
1638N/A self.__fmri = pfmri
1638N/A self.__img = img
1638N/A self.__text = text
1638N/A
1638N/A def __str__(self):
1638N/A return self.get_text()
1638N/A
1638N/A def get_text(self):
1638N/A """Retrieves and returns the payload of the license (which
1638N/A should be text). This may require remote retrieval of
1638N/A resources and so this could raise a TransportError or other
1638N/A ApiException."""
1638N/A
1638N/A if not self.__img:
1638N/A return self.__text
2313N/A return self.__action.get_text(self.__img, self.__fmri)
2313N/A
1638N/A @property
1638N/A def fmri(self):
1638N/A """The FMRI of the package this license is for."""
1638N/A
1638N/A return self.__fmri
1638N/A
1638N/A @property
1638N/A def license(self):
1638N/A """The keyword identifying this license within its related
1638N/A package."""
1638N/A
1638N/A return self.__action.attrs["license"]
1638N/A
1638N/A @property
1638N/A def must_accept(self):
1638N/A """A boolean value indicating whether the license requires
1638N/A acceptance."""
1638N/A
1638N/A return self.__action.must_accept
1638N/A
1638N/A @property
1638N/A def must_display(self):
1638N/A """A boolean value indicating whether the license must be
1638N/A displayed during install or update operations."""
1638N/A
1638N/A return self.__action.must_display
1638N/A
1638N/A
1638N/Aclass PackageCategory(object):
1638N/A """Represents the scheme and category of an info.classification entry
1638N/A for a package."""
1638N/A
1638N/A scheme = None
1638N/A category = None
1638N/A
1638N/A def __init__(self, scheme, category):
1638N/A self.scheme = scheme
1638N/A self.category = category
1638N/A
1638N/A def __str__(self, verbose=False):
1638N/A if verbose:
1638N/A return "%s (%s)" % (self.category, self.scheme)
1638N/A else:
1638N/A return "%s" % self.category
1638N/A
1638N/A
1638N/Aclass PackageInfo(object):
1638N/A """A class capturing the information about packages that a client
1638N/A could need. The fmri is guaranteed to be set. All other values may
1638N/A be None, depending on how the PackageInfo instance was created."""
1638N/A
1638N/A # Possible package installation states; these constants should match
1970N/A # the values used by the Image class. Constants with negative values
1970N/A # are not currently available.
1970N/A FROZEN = -1
1638N/A INCORPORATED = -2
1638N/A EXCLUDES = -3
2616N/A KNOWN = image.Image.PKG_STATE_KNOWN
2616N/A INSTALLED = image.Image.PKG_STATE_INSTALLED
2616N/A UPGRADABLE = image.Image.PKG_STATE_UPGRADABLE
2616N/A OBSOLETE = image.Image.PKG_STATE_OBSOLETE
2616N/A RENAMED = image.Image.PKG_STATE_RENAMED
2616N/A
2616N/A __NUM_PROPS = 13
1638N/A IDENTITY, SUMMARY, CATEGORIES, STATE, PREF_PUBLISHER, SIZE, LICENSES, \
2493N/A LINKS, HARDLINKS, FILES, DIRS, DEPENDENCIES, DESCRIPTION = \
1970N/A range(__NUM_PROPS)
2493N/A ALL_OPTIONS = frozenset(range(__NUM_PROPS))
2493N/A ACTION_OPTIONS = frozenset([LINKS, HARDLINKS, FILES, DIRS,
1638N/A DEPENDENCIES])
1638N/A
1638N/A def __init__(self, pfmri, pkg_stem=None, summary=None,
1638N/A category_info_list=None, states=None, publisher=None,
1638N/A preferred_publisher=None, version=None, build_release=None,
1638N/A branch=None, packaging_date=None, size=None, licenses=None,
1970N/A links=None, hardlinks=None, files=None, dirs=None,
1970N/A dependencies=None, description=None):
2493N/A self.pkg_stem = pkg_stem
1638N/A self.summary = summary
1970N/A if category_info_list is None:
1638N/A category_info_list = []
1638N/A self.category_info_list = category_info_list
1638N/A self.states = states
1638N/A self.publisher = publisher
1638N/A self.preferred_publisher = preferred_publisher
1638N/A self.version = version
1638N/A self.build_release = build_release
1638N/A self.branch = branch
1638N/A self.packaging_date = packaging_date
1638N/A self.size = size
1638N/A self.fmri = pfmri
1638N/A self.licenses = licenses
1638N/A self.links = links
1638N/A self.hardlinks = hardlinks
1638N/A self.files = files
1638N/A self.dirs = dirs
1638N/A self.dependencies = dependencies
1638N/A self.description = description
1638N/A
2493N/A def __str__(self):
1638N/A return self.fmri
1638N/A
2500N/A @staticmethod
1638N/A def build_from_fmri(f):
1638N/A if not f:
1638N/A return f
1638N/A pub, name, version = f.tuple()
1638N/A pub = fmri.strip_pub_pfx(pub)
1638N/A return PackageInfo(pkg_stem=name, publisher=pub,
1638N/A version=version.release,
1638N/A build_release=version.build_release, branch=version.branch,
1638N/A packaging_date=version.get_timestamp().strftime("%c"),
1638N/A pfmri=str(f))
1638N/A
2446N/A
1638N/Adef _get_pkg_cat_data(cat, info_needed, actions=None,
2493N/A excludes=misc.EmptyI, pfmri=None):
2493N/A """This is a private method and not intended for
2493N/A external consumers."""
2493N/A
2493N/A # XXX this doesn't handle locale.
2493N/A get_summ = summ = desc = cat_info = deps = None
2493N/A cat_data = []
2493N/A get_summ = PackageInfo.SUMMARY in info_needed
2493N/A if PackageInfo.CATEGORIES in info_needed:
2493N/A cat_info = []
2493N/A if PackageInfo.DEPENDENCIES in info_needed:
2493N/A cat_data.append(cat.DEPENDENCY)
2493N/A deps = []
2493N/A
2493N/A if deps is None or len(info_needed) != 1:
2493N/A # Anything other than dependency data
2493N/A # requires summary data.
2493N/A cat_data.append(cat.SUMMARY)
2493N/A
2493N/A if actions is None:
2493N/A actions = cat.get_entry_actions(pfmri, cat_data,
2493N/A excludes=excludes)
1638N/A
1638N/A for a in actions:
1638N/A if deps is not None and a.name == "depend":
1638N/A deps.append(a.attrs.get(a.key_attr))
1638N/A continue
1638N/A elif a.name != "set":
1638N/A continue
1638N/A
1638N/A attr_name = a.attrs["name"]
1638N/A if attr_name == "pkg.summary":
1638N/A if get_summ:
1638N/A summ = a.attrs["value"]
1638N/A elif attr_name in ("description", "pkg.description"):
1638N/A desc = a.attrs["value"]
1638N/A elif cat_info != None and a.has_category_info():
1638N/A cat_info.extend(a.parse_category_info())
1638N/A
1638N/A if get_summ and summ is None:
1638N/A if desc is None:
1638N/A summ = ""
1638N/A else:
1638N/A summ = desc
1638N/A if not PackageInfo.DESCRIPTION in info_needed:
1638N/A desc = None
1638N/A return summ, desc, cat_info, deps
1638N/A