doc/client_api_versions.txt
author Shawn Walker <shawn.walker@oracle.com>
Fri, 16 Apr 2010 19:02:06 -0500
changeset 1859 6e6e866921e7
parent 1843 b9333a197e40
child 1895 0a260cc2a689
permissions -rw-r--r--
529 client can traceback with EBUSY during action removal 3286 file install fails if a parent directory has been replaced by a link or file 3644 directory/symlink ambiguity renders package uninstallable 13069 symlink found to be a directory causes traceback on upgrade 14927 directory install won't set mode if directory already exists 14940 testsuite could use client API for image creation

Version 37:
Compatible with clients using version 36.

    The pkg.client.api ImageInterface has changed as follows:
        * Whenever an unexpected change in the state or structure
          of the image is encountered during install, remove, or
          update operations (such as a missing file, directory,
          or inability to remove an item) and it cannot be
          recovered from without user intervention, an
          ActionExecutionError exception is raised.

Version 36:
Incompatible with clients using versions 0-35.

    The interface for pkg.client.api.remote_search has changed as follows:
        * A new parameter, prune_versions, has been added which, when true,
          causes remote search to remove versions a user is unlikely to be
          interested in.

        * The return type of remote_search and local_search has changed.  Where
          the string representation used to be returned, a FMRI object is now
          returned.

Version 35:
Compatible with clients using version 34.

    The ImageInterface class has changed as follows:
        * A new method named parse_fmri_patterns has been added to
          help clients parse user input and transform any valid patterns
          into FMRI objects that can be used for comparison.  See pydoc
          'pkg.client.api' for details.

        * New constants for the parse_fmri_patterns method were added:
          MATCH_EXACT, MATCH_FMRI, and MATCH_GLOB.

Version 34:
Incompatible with clients using versions 0-33.

    The pkg.client.publisher.Publisher class has changed as follows:
        * The deprecated get_ssl_creds() and set_origin() methods
          were removed.  These functions have been marked as
          deprecated since the client API was first versioned
          and should not have been used by any clients.

Version 33:
Compatible with clients using version 32.

    The ImageInterface class has changed as follows:
        * file and directory actions will now have their mode validated
          if failure occurs during plan execution to determine if bad
          package metadata was the cause of execution failure.  In
          addition, the client API will catch failures due to corrupt
          or invalid package metadata and re-raise them as an
          InvalidPackageErrors exception.

    The pkg.client.api_errors module has changed as follows:
        * The InvalidPackageErrors exception was added.  See 'pydoc
          pkg.client.api_errors' for details.

Version 32:
Incompatible with clients using versions 0-31.

    The ImageInterface class has changed as follows:
        * The add_publisher and update_publisher methods now validate
          the image's publisher configuration against the origins of
          the publisher.  If any of the origins are found to not match,
          an UnknownRepositoryPublishers exception will be raised.
          If one of the new repository origins does not provide
          publisher configuration information or it is incomplete,
          a RepoPubConfigUnavailable exception will be raised.

    The pkg.client.api module has changed as follows:
        * A new method named image_create has been added.  See 'pydoc
          pkg.client.api' for details.

    The pkg.client.api_errors module has changed as follows:
        * UnknownRepositoryPublishers, RepoPubConfigUnavailable, and
          UnknownErrors expections have been added for use by the
          pkg.client.api.  API consumers are reminded that they should
          catch all ApiException class exceptions, although catching
          specific exception subclasses for case-by-case handling in
          addition to that is acceptable.

Version 31:
Compatible with clients using version 30.
    All image-modifying operations now lock the image for exclusive use
    by the current thread and process.  If the lock cannot be obtained,
    an ImageLockedError exception will be raised.

    The ImageInterface class has changed as follows:
        * A new property named 'blocking_locks' has been added to allow
          clients to control image locking behaviour.  See 'pydoc
          pkg.client.api.ImageInterface' for details.

        * The prepare() and execute_plan() methods will now raise an
          InvalidPlanError if the image state has changed since the
          plan was originally created.  This is likely the result of
          another client or process modifying the image.

Version 30:
Incompatible with clients using versions 0-29:
    The ProgressTracker class has changed as follows:
        * ver_output_warning() and ver_output_info() were added so that
          callers can choose to output warning and info verification
          messages separately from errors.

Version 29:
Incompatible with clients using versions 0-28:
    The ImageInterface class has changed as follows:
        * set_plan_license_status() was added.  This is used to indicate
          whether licenses for the packages being operated on have been
          accepted or displayed.  Clients must do this if the related
          license requires acceptance or display.

    The LicenseInfo class has changed as follows:
        * get_text() may now trigger a remote retrieval of the license
          payload if needed to return the text.

        * The related package FMRI and license attributes are now
          properties: fmri, license, must_accept, and must_display.

    The PlanDescription class has changed as follows:
        * get_changes() is now a generator function.

        * get_licenses() was added to allow clients to retrieve the
          list of licenses related to the plan's operations as well
          as the current accepted and displayed status of each.

Version 28:
Incompatible with clients using versions 0-27:
    CatalogRefreshException.message was changed to
    CatalogRefreshException.errmessage to work around a change
    introduced in python2.5 and removed in python2.6 (Exception.message,
    if used, triggers a deprecation warning).

Version 27:
Compatible with clients using versions 25-26:
    The get_manifest function has been added to the api to allow clients
    to retrieve the manifest directly.

Version 26:
Compatible with clients using version 25.
    The client API has changed such that an immediate refresh is always
    performed when the 'refresh_catalogs' parameter is True for install,
    update, and change variant operations.

Version 25:
Incompatible with clients using versions 0-24:
Changes:
    The PackageInfo class has changed as follows:
        * The NOT_INSTALLED constant has been removed as checking
          for the presence of INSTALLED should be sufficient.

        * A new constant named 'KNOWN' has been added.  It indicates
          that the package is currently available from a publisher's
           repository.
     
         * A new constant named 'UPGRADABLE' has been added. It
           indicates that a new version of the package is available.
 
     The following new api functions were added to ImageInterface (see
     'pydoc pkg.client.api.ImageInterface' for more information):
         * get_pkg_categories
 
         * get_pkg_list

Version 24:
Incompatible with clients using versions 0-23.
    The pkg.client.api module has changed as follows:
        * plan_install no longer takes a filters argument
	* plan_change_variant changed to plan_change_varcets.
	  w/ argument list changes.
	* Added get_pub_search_order
	* Added set_pub_search_after
	* Added set_pub_search_before

Version 23:
Incompatible with clients using versions 0-22.
    The pkg.client.api module has changed as follows:
        * PackageInfo objects no longer take a "state" parameter, but a
	  "states" parameter, and the corresponding "state" member is now
	  "states", and is a list of states, rather than a single value.

Version 22:
Compatible with clients using version 21.
Changes:
	Adds the description field to the PackageInfo class.

Version 21:
Incompatible with clients using versions 0-20.
Changes:
    The pkg.client.api_errors module has changed as follows:
        * All CatalogCacheError class exceptions were removed as the
          catalog cache no longer exists.

Version 20:
Compatible with clients using version 19.
Changes:
   The following exceptions were added to pkg.client.api_errors:

   class ReadOnlyFileSystemException(PermissionsException):
   """Used to indicate that the operation was attempted on a
   read-only filesystem"""

Version 19:
Incompatible with clients using versions 0-18.
Changes:
    The ImageInterface class changed as follows:
        * plan_update_all no longer returns a third value, the exception
          caught.  This value was never set.

        * plan_install no longer returns a second value, the exception
          caught.  This value was never set.

Version 18:
Compatible with clients using versions 15-17.
Changes:
   The following exceptions were added to pkg.client.api_errors:
    
    class SetDisabledPublisherPreferred(PublisherError):
        """Used to indicate an attempt to set a disabled publisher as
        the preferred publisher was made."""

Version 17:
Compatible with clients using versions 15-16.
Changes:
    The following properties were added to pkg.client.api
    ImageInterface class:

        root
            The absolute pathname of the filesystem root of the image.
            This property is read-only.

Version 16:
Compatible with clients using version 15.
Changes:
   The following exceptions were added to pkg.client.api_errors:
    
    class NoSuchKey(CertificateError):
        """Used to indicate that a key could not be found."""

Version 15:
Incompatible with clients using versions 1-14.
Changes:
    The unfound_fmris variable in the
    pkg.client.api_errors.PlanCreationException class is now called 
    unmatched_fmris.

Version 14:
Compatible with clients using versions 12-14.
Changes:
    The following methods were added to pkg.client.publisher.Publisher:

        def create_meta_root(self):
                """Create the publisher's meta_root."""

        def remove_meta_root(self):
                """Removes the publisher's meta_root."""

Version 13:
Compatible with clients using version 12.
Changes:
    By default, publisher repositories will be checked for new metadata no more
    than once every four hours unless otherwise requested.  Each time a
    publisher's selected repository is checked for updates, the client will
    store a timestamp (in UTC) marking when the refresh was performed.

    ImageInterface.refresh() has changed as follows:
        * Changed 'full_refresh' to an optional keyword argument that defaults
          to False.

        * Added optional boolean keyword 'immediate' that allows the client to
          request that a publisher be checked for updates even if a check is
          not yet needed.

        * Changed to properly use progress tracker for refreshing of publisher
          metadata.

        * Now only refreshes publisher metadata based on the update interval
          specified by the refresh_seconds property on the publisher's
          selected_repository.

    ImageInterface.update_publisher() has changed as follows:
        * When updating a publisher with 'refresh_allowed' set to False, its
          catalog will no longer be removed.  Instead, it is marked as needing
          refresh, and the next time the client can do so, it will.

    pkg.client.publisher.Publisher has changed as follows:
        * New property 'last_refreshed':
                A datetime object representing the time (in UTC) the
                publisher's selected repository was last refreshed for new
                metadata (such as catalog updates).  'None' if the publisher
                hasn't been refreshed yet or the time is not available.

          The above property will be automatically set by the api as needed
          although api consumers are free to retrieve its value.  Manually
          setting this value is not recommended.

        * New property 'meta_root':
                The absolute pathname of the directory where the publisher's
                metadata should be written to and read from.

          The above property will be automatically set by the api as needed
          although api consumers are free to retrieve its value.  Manually
          setting this value is not recommended.

        * New property 'needs_refresh':
                A boolean value indicating whether the publisher's metadata for
                the currently selected repository needs to be refreshed.

Version 12:
Incompatible with clients using versions 1-12
Changes:
    This versions adds local_search and remote_search to the api and removes
    those functions from pkg.client.image.

Version 11:
Incompatible with clients using versions 1-10
Changes:
   This version changes all parameter names and property names from 'authority'
   to 'publisher'.  For example, parameters named 'auths' were changed to
   'pubs'; parameters named 'authent' were changed to 'pubent' and so forth.

   In addition, the following new api functions were added to ImageInterface:
        def add_publisher(self, pub, refresh_allowed=True):
                """Add the provided publisher object to the image
                configuration."""

        def get_preferred_publisher(self):
                """Returns the preferred publisher object for the image."""

        def get_publisher(self, prefix=None, alias=None, duplicate=False):
                """Retrieves a publisher object matching the provided prefix
                (name) or alias.

                'duplicate' is an optional boolean value indicating whether
                a copy of the publisher object should be returned instead
                of the original.
                """

        def get_publishers(self, duplicate=False):
                """Returns a list of the publisher objects for the current
                image.

                'duplicate' is an optional boolean value indicating whether
                copies of the publisher objects should be returned instead
                of the originals.
                """

        def get_publisher_last_update_time(self, prefix=None, alias=None):
                """Returns a datetime object representing the last time the
                catalog for a publisher was modified or None."""

        def has_publisher(self, prefix=None, alias=None):
                """Retrieves a publisher object matching the provided prefix
                (name) or alias."""

        def remove_publisher(self, prefix=None, alias=None):
                """Removes a publisher object matching the provided prefix
                (name) or alias."""

        def set_preferred_publisher(self, prefix=None, alias=None):
                """Sets the preferred publisher for the image."""

        def update_publisher(self, pub, refresh_allowed=True):
                """Replaces an existing publisher object with the provided one
                using the _source_object_id identifier set during copy."""

        def update_publisher(self, pub, refresh_allowed=True):
                """Replaces an existing publisher object with the provided one
                using the _source_object_id identifier set during copy.

                'refresh_allowed' is an optional boolean value indicating
                whether a refresh of publisher metadata (such as its catalog)
                should be performed if transport information is changed for a
                repository, mirror, or origin.  If False, no attempt will be
                made to retrieve publisher metadata."""


        def log_operation_end(self, error=None, result=None):
                """Marks the end of an operation to be recorded in image
                history.

                'result' should be a pkg.client.history constant value
                representing the outcome of an operation.  If not provided,
                and 'error' is provided, the final result of the operation will
                be based on the class of 'error' and 'error' will be recorded
                for the current operation.  If 'result' and 'error' is not
                provided, success is assumed."""

        def log_operation_error(self, error):
                """Adds an error to the list of errors to be recorded in image
                history for the current opreation."""

        def log_operation_start(self, name):
                """Marks the start of an operation to be recorded in image
                history."""
 
        def parse_p5i(self, fileobj=None, location=None):
                """Reads the pkg(5) publisher json formatted data at 'location'
                or from the provided file-like object 'fileobj' and returns a
                list of tuples of the format (publisher object, pkg_names).
                pkg_names is a list of strings representing package names or
                FMRIs.  If any pkg_names not specific to a publisher were
                provided, the last tuple returned will be of the format (None,
                pkg_names).

                'fileobj' is an optional file-like object that must support a
                'read' method for retrieving data.

                'location' is an optional string value that should either start
                with a leading slash and be pathname of a file or a URI string.

                'fileobj' or 'location' must be provided."""

        def write_p5i(self, fileobj, pkg_names=None, pubs=None):
                """Writes the publisher, repository, and provided package names
                to the provided file-like object 'fileobj' in json p5i format.

                'fileobj' is only required to have a 'write' method that accepts
                data to be written as a parameter.

                'pkg_names' is a dict of lists, tuples, or sets indexed by
                publisher prefix that contain package names, FMRI strings, or
                package info objects.  A prefix of "" can be used for packages
                that are not specific to a publisher.

                'pubs' is an optional list of publisher prefixes or Publisher
                objects.  If not provided, the information for all publishers
                (excluding those disabled) will be output."""

Version 10:
Incompatible with clients using versions 1-9
Changes:
    This version changes the interface to info. It removes the action info
    and licenses flag and replaces them with a set of options to allow
    the caller control over which information is retrieved.

Version 9:
Compatible with clients using versions 1-8
Changes:
    This version adds an optional argument to plan_update_all to allow the
    specification of a name for the clone of the BE which is made. It also
    exposes check_be_name as part of the api.

Version 8:
Compatible with clients using versions 1-7
Changes:
    This version introduces InvalidDepotResponseException.  The
    exception is thrown when operations that refresh the catalog
    discover that the server is not a pkg depot.  Clients of the api
    should catch this exception and respond appropriately.

Version 7:
Compatible with clients using versions 1-6
Changes:
    Ignore the pkg_client_name parameter passed to api.ImageInterface() if
    pkg.client.global_settings.client_name isn't None.  This latter object
    is now the preferred way to set the client name, and the
    pkg_client_name parameter may be ignored or removed in the future.

Version 6:
Compatible with clients using versions 1-5
Changes:
Adds a new field to PackageInfo, category_info_list, which is a list of 
     PackageCategory objects. These objects contain the scheme and category
     information for packages.

Version 5:
Compatible with clients using versions 1-4 as long as they have a generic
APIException. This is the case for PackageManager and UpdateManaget.
Changes:
plan_install and plan_update_all can now raise PermissionsException.

Version 4:
Compatible with clients using versions 1, 2, and 3
Changes:
Modifies where certain progress tracking calls were made, calling 
    evaluate_start much sooner.
Adds refresh tracking to progress.py. This allows for active feedback when
    the catalogs of authorities are being refreshed.

Version 3:
Compatible with clients using Versions 1 and 2
Changes:
Adds an optional argument to info which determines whether detailed information
    about actions will be returned
Adds the following new fields to PackageInfo objects: links, hardlinks,
    files, dirs, dependencies

Version 2:
Compatible with clients using Version 1
Changes:
Adds the optional argument update_index to plan_install, plan_uninstall, and 
    plan_update_all. When the argument is false, no automatic update to the
    index occurs. By default, the argument is true.

Version 1:
Incompatible with clients using Version 0
Changes:
plan_install now returns a tuple of whether there is anything to do and 
    a catalog refresh exception, if one was caught. In this, it mirrors the
    first and third return values from plan_update_all.

Version 0:
        def __init__(self, img_path, version_id, progesstracker,
            cancel_state_callable, pkg_client_name):
                """Constructs an ImageInterface. img_path should point to an
                existing image. version_id indicates the version of the api
                the client is expecting to use. progesstracker is the
                progresstracker the client wants the api to use for UI
                callbacks. cancel_state_callable is a function which the client
                wishes to have called each time whether the operation can be
                canceled changes. It can raise VersionException and
                ImageNotFoundException."""

        def plan_install(self, pkg_list, filters, refresh_catalogs=True,
            noexecute=False, verbose=False):
                """Contructs a plan to install the packages provided in
                pkg_list. pkg_list is a list of packages to install. filters
                is a list of filters to apply to the actions of the installed
                packages. refresh_catalogs controls whether the catalogs will
                automatically be refreshed. noexecute determines whether the
                history will be recorded after planning is finished. verbose
                controls whether verbose debugging output will be printed to the
                terminal. Its existence is temporary. If there are things to do
                to complete the install, it returns True, otherwise it returns
                False. It can raise InvalidCertException, PlanCreationException,
                NetworkUnavailableException, and InventoryException. The
                noexecute argument is included for compatibility with
                operational history. The hope is it can be removed in the
                future."""

        def plan_uninstall(self, pkg_list, recursive_removal, noexecute=False,
            verbose=False):
                """Contructs a plan to uninstall the packages provided in
                pkg_list. pkg_list is a list of packages to install.
                recursive_removal controls whether recursive removal is
                allowed. noexecute determines whether the history will be
                recorded after planning is finished. verbose controls whether
                verbose debugging output will be printed to the terminal. Its
                existence is temporary. If there are things to do to complete
                the uninstall, it returns True, otherwise it returns False. It
                can raise NonLeafPackageException and PlanCreationException."""

        def plan_update_all(self, actual_cmd, refresh_catalogs=True,
            noexecute=False, force=False, pkgs_must_be_up_to_date=None,
            verbose=False):
                """Creates a plan to update all packages on the system to the
                latest known versions. actual_cmd is the command used to start
                the client. It is used to determine the image to check whether
                SUNWipkg is up to date. refresh_catalogs controls whether the
                catalogs will automatically be refreshed. noexecute determines
                whether the history will be recorded after planning is finished.
                force controls whether update should proceed even if ipkg is not
                up to date. verbose controls whether verbose debugging output
                will be printed to the terminal. Its existence is temporary. It
                returns a tuple of three things. The first is a boolean which
                tells the client whether there is anything to do. The second
                tells whether the image is an opensolaris image. The third is
                either None, or an exception which indicates partial success.
                This is currently used to indicate a failure in refreshing
                catalogs. It can raise CatalogRefreshException,
                IpkgOutOfDateException, NetworkUnavailableException, and
                PlanCreationException."""

        def describe(self):
                """Returns None if no plan is ready yet, otherwise returns
                a PlanDescription"""

        def prepare(self):
                """Takes care of things which must be done before the plan
                can be executed. This includes downloading the packages to
                disk and preparing the indexes to be updated during
                execution. It can raise ProblematicPermissionsIndexException,
                and PlanMissingException. Should only be called once a
                plan_X method has been called."""

        def execute_plan(self, be_name=None):
                """Executes the plan. This is uncancelable one it begins. It
                can raise  CorruptedIndexException,
                ProblematicPermissionsIndexException, ImageplanStateException,
                ImageUpdateOnLiveImageException, and PlanMissingException.
                Should only be called after the prepare method has been
                called."""

        def refresh(self, full_refresh, auths=None):
                """Refreshes the catalogs. full_refresh controls whether to do
                a full retrieval of the catalog from the publisher or only
                update the existing catalog. auths is a list of authorities to
                refresh. Passing an empty list or using the default value means
                all known authorities will be refreshed. While it currently
                returns an image object, this is an expedient for allowing
                existing code to work while the rest of the API is put into
                place."""

        def info(self, fmri_strings, local, get_licenses):
                """Gathers information about fmris. fmri_strings is a list
                of fmri_names for which information is desired. local
                determines whether to retrieve the information locally.
                get_licenses determines whether to retrieve the text of
                the licenses. It returns a dictionary of lists. The keys
                for the dictionary are the constants specified in the class
                definition. The values are lists of PackageInfo objects or
                strings."""

        def can_be_canceled(self):
                """Returns true if the API is in a cancelable state."""

        def reset(self):
                """Resets the API back the the initial state. Note:
                this does not necessarily return the disk to its initial state
                since the indexes or download cache may have been changed by
                the prepare method."""

        def cancel(self):
                """Used for asynchronous cancelation. It returns the API
                to the state it was in prior to the current method being
                invoked.  Canceling during a plan phase returns the API to
                its initial state. Canceling during prepare puts the API
                into the state it was in just after planning had completed.
                Plan execution cannot be canceled. A call to this method blocks
                until the canelation has happened. Note: this does not
                necessarily return the disk to its initial state since the
                indexes or download cache may have been changed by the
                prepare method."""

class PlanDescription(object):
        """A class which describes the changes the plan will make. It
        provides a list of tuples of PackageInfo's. The first item in the
        tuple is the package that is being changed. The second item in the
        tuple is the package that will be in the image after the change."""

        def get_changes(self):

class LicenseInfo(object):
        """A class representing the license information a package
        provides."""

        def get_text(self):

class PackageInfo(object):
        """A class capturing the information about packages that a client
        could need. The fmri is guaranteed to be set. All other values may
        be None, depending on how the PackageInfo instance was created."""

        # Possible package installation states
        INSTALLED = 1
        NOT_INSTALLED = 2

        self.pkg_stem
        self.summary
        self.state
        self.authority
        self.preferred_authority
        self.version
        self.build_release
        self.branch
        self.packaging_date
        self.size
        self.fmri
        self.licenses

        def __str__(self):