api_errors.py revision 3384
1516N/A#!/usr/bin/python
565N/A#
565N/A# CDDL HEADER START
565N/A#
565N/A# The contents of this file are subject to the terms of the
565N/A# Common Development and Distribution License (the "License").
565N/A# You may not use this file except in compliance with the License.
565N/A#
565N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
565N/A# or http://www.opensolaris.org/os/licensing.
565N/A# See the License for the specific language governing permissions
565N/A# and limitations under the License.
565N/A#
565N/A# When distributing Covered Code, include this CDDL HEADER in each
565N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
565N/A# If applicable, add the following below this CDDL HEADER, with the
565N/A# fields enclosed by brackets "[]" replaced with your own identifying
565N/A# information: Portions Copyright [yyyy] [name of copyright owner]
565N/A#
565N/A# CDDL HEADER END
565N/A#
926N/A
926N/A#
2197N/A# Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
926N/A#
565N/A
2026N/Aimport errno
1050N/Aimport operator
926N/Aimport os
926N/Aimport six
2339N/Aimport xml.parsers.expat as expat
2339N/Afrom functools import total_ordering
2339N/Afrom six.moves.urllib.parse import urlsplit
926N/A
926N/A# pkg classes
926N/Aimport pkg.client.pkgdefs as pkgdefs
838N/A
565N/A# EmptyI for argument defaults; can't import from misc due to circular
2034N/A# dependency.
2034N/AEmptyI = tuple()
2034N/A
1540N/Aclass ApiException(Exception):
1540N/A def __init__(self, *args):
1540N/A Exception.__init__(self)
1540N/A self.__verbose_info = []
1540N/A
1968N/A def add_verbose_info(self, info):
1540N/A self.__verbose_info.extend(info)
2034N/A
2034N/A @property
2200N/A def verbose_info(self):
2034N/A return self.__verbose_info
2034N/A
2034N/Aclass SuidUnsupportedError(ApiException):
565N/A def __str__(self):
2339N/A return _("""
2339N/AThe pkg client api module can not be invoked from an setuid executable.""")
2339N/A
2339N/A
2339N/Aclass HistoryException(ApiException):
2339N/A """Private base exception class for all History exceptions."""
2339N/A
2339N/A def __init__(self, *args):
2339N/A Exception.__init__(self, *args)
2339N/A self.error = args[0]
2339N/A
2339N/A def __str__(self):
2339N/A return str(self.error)
2339N/A
2339N/A
2339N/Aclass HistoryLoadException(HistoryException):
2339N/A """Used to indicate that an unexpected error occurred while loading
2339N/A History operation information.
1710N/A
1710N/A The first argument should be an exception object related to the
1710N/A error encountered.
1710N/A """
1710N/A def __init__(self, *args):
1710N/A HistoryException.__init__(self, *args)
1710N/A self.parse_failure = isinstance(self.error, expat.ExpatError)
1710N/A
1710N/A
1710N/Aclass HistoryRequestException(HistoryException):
1710N/A """Used to indicate that invalid time / range values were provided to
1710N/A history API functions."""
1710N/A pass
1710N/A
1710N/A
1710N/Aclass HistoryStoreException(HistoryException):
1710N/A """Used to indicate that an unexpected error occurred while storing
1710N/A History operation information.
1710N/A
1710N/A The first argument should be an exception object related to the
1710N/A error encountered.
1710N/A """
1710N/A pass
1710N/A
1710N/A
1710N/Aclass HistoryPurgeException(HistoryException):
1710N/A """Used to indicate that an unexpected error occurred while purging
1710N/A History operation information.
1710N/A
1710N/A The first argument should be an exception object related to the
1710N/A error encountered.
565N/A """
565N/A pass
565N/A
565N/A
565N/Aclass ImageLockedError(ApiException):
565N/A """Used to indicate that the image is currently locked by another thread
565N/A or process and cannot be modified."""
565N/A
2144N/A def __init__(self, hostname=None, pid=None, pid_name=None):
2158N/A ApiException.__init__(self)
2158N/A self.hostname = hostname
2158N/A self.pid = pid
2158N/A self.pid_name = pid_name
2158N/A
2158N/A def __str__(self):
2158N/A if self.pid is not None and self.pid_name is not None and \
2158N/A self.hostname is not None:
2158N/A return _("The image cannot be modified as it is "
2158N/A "currently in use by another package client: "
2158N/A "{pid_name} on {host}, pid {pid}.").format(
2158N/A pid_name=self.pid_name, pid=self.pid,
2158N/A host=self.hostname)
2158N/A if self.pid is not None and self.pid_name is not None:
2158N/A return _("The image cannot be modified as it is "
2158N/A "currently in use by another package client: "
2158N/A "{pid_name} on an unknown host, pid {pid}.").format(
2158N/A pid_name=self.pid_name, pid=self.pid)
2144N/A elif self.pid is not None:
2144N/A return _("The image cannot be modified as it is "
2144N/A "currently in use by another package client: "
2144N/A "pid {pid} on {host}.").format(
2144N/A pid=self.pid, host=self.hostname)
2144N/A return _("The image cannot be modified as it is currently "
2144N/A "in use by another package client.")
2144N/A
2144N/Aclass ImageNotFoundException(ApiException):
2144N/A """Used when an image was not found"""
2144N/A def __init__(self, user_specified, user_dir, root_dir):
2144N/A ApiException.__init__(self)
2144N/A self.user_specified = user_specified
2407N/A self.user_dir = user_dir
2407N/A self.root_dir = root_dir
2407N/A
2407N/A def __str__(self):
2407N/A return _("No image rooted at '{0}'").format(self.user_dir)
2407N/A
2407N/A
2407N/Aclass ImageFormatUpdateNeeded(ApiException):
2407N/A """Used to indicate that an image cannot be used until its format is
2407N/A updated."""
2407N/A
2407N/A def __init__(self, path):
2407N/A ApiException.__init__(self)
2407N/A self.path = path
2407N/A
2407N/A def __str__(self):
2144N/A return _("The image rooted at {0} is written in an older format "
565N/A "and must be updated before the requested operation can be "
565N/A "performed.").format(self.path)
565N/A
565N/Aclass ImageInsufficentSpace(ApiException):
565N/A """Used when insuffcient space exists for proposed operation"""
565N/A def __init__(self, needed, avail, use):
2144N/A self.needed = needed
565N/A self.avail = avail
565N/A self.use = use
565N/A
565N/A def __str__(self):
565N/A from pkg.misc import bytes_to_str
1618N/A return _("Insufficient disk space available ({avail}) "
1618N/A "for estimated need ({needed}) for {use}").format(
1618N/A avail=bytes_to_str(self.avail),
1618N/A needed=bytes_to_str(self.needed),
1618N/A use=self.use
1618N/A )
1755N/A
1755N/A
1755N/Aclass VersionException(ApiException):
1755N/A def __init__(self, expected_version, received_version):
1755N/A ApiException.__init__(self)
1755N/A self.expected_version = expected_version
1755N/A self.received_version = received_version
1755N/A
1755N/A
1755N/Aclass PlanExistsException(ApiException):
1755N/A def __init__(self, plan_type):
1755N/A ApiException.__init__(self)
1755N/A self.plan_type = plan_type
1755N/A
1755N/A
1755N/Aclass PlanPrepareException(ApiException):
1755N/A """Base exception class for plan preparation errors."""
1618N/A pass
1618N/A
1618N/A
1618N/Aclass InvalidPackageErrors(ApiException):
1618N/A """Used to indicate that the requested operation could not be completed
1618N/A as one or more packages contained invalid metadata."""
1618N/A
1618N/A def __init__(self, errors):
1618N/A """'errors' should be a list of exceptions or strings
1618N/A indicating what packages had errors and why."""
1618N/A
1618N/A ApiException.__init__(self)
1618N/A self.errors = errors
1618N/A
1618N/A def __str__(self):
1618N/A return _("The requested operation cannot be completed due "
1618N/A "to invalid package metadata. Details follow:\n\n"
1618N/A "{0}").format("\n".join(str(e) for e in self.errors))
1618N/A
1618N/A
1618N/Aclass LicenseAcceptanceError(ApiException):
1618N/A """Used to indicate that license-related errors occurred during
1618N/A plan evaluation or execution."""
1618N/A
1618N/A def __init__(self, pfmri, src=None, dest=None, accepted=None,
1618N/A displayed=None):
1618N/A ApiException.__init__(self)
1618N/A self.fmri = pfmri
1618N/A self.src = src
1618N/A self.dest = dest
1618N/A self.accepted = accepted
1618N/A self.displayed = displayed
1618N/A
1618N/A
1618N/Aclass PkgLicenseErrors(PlanPrepareException):
1618N/A """Used to indicate that plan evaluation or execution failed due
1618N/A to license-related errors for a package."""
1618N/A
1618N/A def __init__(self, errors):
1618N/A """'errors' should be a list of LicenseAcceptanceError
1618N/A exceptions."""
1618N/A
1618N/A PlanPrepareException.__init__(self)
1618N/A self.__errors = errors
1618N/A
1618N/A @property
1618N/A def errors(self):
1618N/A """A list of LicenseAcceptanceError exceptions."""
1618N/A return self.__errors
1618N/A
1618N/A
1618N/Aclass PlanLicenseErrors(PlanPrepareException):
1618N/A """Used to indicate that image plan evaluation or execution failed due
1618N/A to license-related errors."""
1618N/A
1618N/A def __init__(self, pp_errors):
1618N/A """'errors' should be a list of PkgLicenseErrors exceptions."""
1618N/A
1618N/A PlanPrepareException.__init__(self)
1618N/A self.__errors = pkgs = {}
1618N/A for pp_err in pp_errors:
1618N/A for e in pp_err.errors:
1618N/A pkgs.setdefault(str(e.fmri), []).append(e)
1618N/A
1618N/A @property
1618N/A def errors(self):
1618N/A """Returns a dictionary indexed by package FMRI string of
1618N/A lists of LicenseAcceptanceError exceptions."""
1618N/A
1618N/A return self.__errors
1019N/A
1019N/A def __str__(self):
1019N/A """Returns a string representation of the license errors."""
1019N/A
1019N/A output = ""
1019N/A for sfmri in self.__errors:
1019N/A output += ("-" * 40) + "\n"
1019N/A output += _("Package: {0}\n\n").format(sfmri)
1618N/A for e in self.__errors[sfmri]:
565N/A lic_name = e.dest.attrs["license"]
565N/A output += _("License: {0}\n").format(lic_name)
565N/A if e.dest.must_accept and not e.accepted:
1618N/A output += _(" License requires "
1618N/A "acceptance.")
565N/A if e.dest.must_display and not e.displayed:
565N/A output += _(" License must be viewed.")
1618N/A output += "\n"
565N/A return output
565N/A
565N/A
1618N/Aclass ActuatorException(ApiException):
565N/A def __init__(self, e):
565N/A ApiException.__init__(self)
565N/A self.exception = e
565N/A
565N/A def __str__(self):
1369N/A return str(self.exception)
1710N/A
1710N/A
1710N/Aclass PrematureExecutionException(ApiException):
1710N/A pass
1710N/A
1710N/A
1710N/Aclass AlreadyPreparedException(PlanPrepareException):
1710N/A pass
1710N/A
1710N/A
1372N/Aclass AlreadyExecutedException(ApiException):
1369N/A pass
1369N/A
1369N/A
1369N/Aclass ImageplanStateException(ApiException):
1369N/A def __init__(self, state):
1369N/A ApiException.__init__(self)
1369N/A self.state = state
1369N/A
1372N/A
1372N/Aclass InvalidPlanError(ApiException):
1369N/A """Used to indicate that the image plan is no longer valid, likely as a
1369N/A result of an image state change since the plan was created."""
565N/A
565N/A def __str__(self):
565N/A return _("The plan for the current operation is no longer "
565N/A "valid. The image has likely been modified by another "
565N/A "process or client. Please try the operation again.")
565N/A
1328N/A
1328N/Aclass ImagePkgStateError(ApiException):
1328N/A
565N/A def __init__(self, fmri, states):
565N/A ApiException.__init__(self)
565N/A self.fmri = fmri
565N/A self.states = states
565N/A
565N/A def __str__(self):
565N/A return _("Invalid package state change attempted '{states}' "
565N/A "for package '{fmri}'.").format(states=self.states,
565N/A fmri=self.fmri)
685N/A
685N/A
685N/Aclass IpkgOutOfDateException(ApiException):
685N/A def __str__(self):
685N/A return _("pkg(7) out of date")
685N/A
685N/A
926N/Aclass ImageUpdateOnLiveImageException(ApiException):
2126N/A def __str__(self):
2126N/A return _("Requested operation cannot be performed "
2126N/A "in live image.")
685N/A
685N/A
2126N/Aclass RebootNeededOnLiveImageException(ApiException):
2126N/A def __str__(self):
685N/A return _("Requested operation cannot be performed "
685N/A "in live image.")
879N/A
879N/A
879N/Aclass CanceledException(ApiException):
879N/A pass
879N/A
879N/Aclass PlanMissingException(ApiException):
879N/A pass
879N/A
879N/Aclass NoPackagesInstalledException(ApiException):
879N/A pass
1335N/A
1335N/Aclass PermissionsException(ApiException):
1945N/A def __init__(self, path):
1335N/A ApiException.__init__(self)
1335N/A self.path = path
1335N/A
1335N/A def __str__(self):
1335N/A if self.path:
1335N/A return _("Could not operate on {0}\nbecause of "
1335N/A "insufficient permissions. Please try the "
1335N/A "command again as a privileged user.").format(
1335N/A self.path)
1968N/A else:
1335N/A return _("""
1335N/ACould not complete the operation because of insufficient permissions.
1335N/APlease try the command again as a privileged user.
1335N/A""")
2301N/A
2301N/Aclass FileInUseException(PermissionsException):
2301N/A def __init__(self, path):
2301N/A PermissionsException.__init__(self, path)
2301N/A assert path
2301N/A
2301N/A def __str__(self):
2301N/A return _("Could not operate on {0}\nbecause the file is "
2301N/A "in use. Please stop using the file and try the\n"
2301N/A "operation again.").format(self.path)
2301N/A
2301N/A
2301N/Aclass UnprivilegedUserError(PermissionsException):
2301N/A def __init__(self, path):
2301N/A PermissionsException.__init__(self, path)
2301N/A
2301N/A def __str__(self):
2301N/A return _("Insufficient access to complete the requested "
2301N/A "operation.\nPlease try the operation again as a "
2301N/A "privileged user.")
2301N/A
2301N/A
2301N/Aclass ReadOnlyFileSystemException(PermissionsException):
2301N/A """Used to indicate that the operation was attempted on a
2301N/A read-only filesystem"""
2301N/A
2301N/A def __init__(self, path):
2301N/A ApiException.__init__(self)
2301N/A self.path = path
2301N/A
2301N/A def __str__(self):
2301N/A if self.path:
2301N/A return _("Could not complete the operation on {0}: "
2301N/A "read-only filesystem.").format(self.path)
2301N/A return _("Could not complete the operation: read-only "
2301N/A "filesystem.")
2301N/A
2301N/A
2301N/Aclass InvalidLockException(ApiException):
2301N/A def __init__(self, path):
2301N/A ApiException.__init__(self)
2301N/A self.path = path
565N/A
2339N/A def __str__(self):
2339N/A return _("Unable to obtain or operate on lock at {0}.\n"
2339N/A "Please try the operation again as a privileged "
2339N/A "user.").format(self.path)
2339N/A
2339N/A
2339N/Aclass PackageMatchErrors(ApiException):
2339N/A """Used to indicate which patterns were not matched or illegal during
2339N/A a package name matching operation."""
2339N/A
2339N/A def __init__(self, unmatched_fmris=EmptyI, multiple_matches=EmptyI,
2339N/A illegal=EmptyI, multispec=EmptyI):
2339N/A ApiException.__init__(self)
2339N/A self.unmatched_fmris = unmatched_fmris
2339N/A self.multiple_matches = multiple_matches
2339N/A self.illegal = illegal
2339N/A self.multispec = multispec
2339N/A
2339N/A def __str__(self):
2339N/A res = []
2339N/A if self.unmatched_fmris:
2339N/A s = _("The following pattern(s) did not match any "
565N/A "packages:")
2339N/A
2339N/A res += [s]
2339N/A res += ["\t{0}".format(p) for p in self.unmatched_fmris]
2339N/A
2339N/A if self.multiple_matches:
2339N/A s = _("'{0}' matches multiple packages")
2339N/A for p, lst in self.multiple_matches:
1505N/A res.append(s.format(p))
1505N/A for pfmri in lst:
2339N/A res.append("\t{0}".format(pfmri))
2339N/A
2339N/A if self.illegal:
2339N/A s = _("'{0}' is an illegal FMRI")
2207N/A res += [ s.format(p) for p in self.illegal ]
2339N/A
2339N/A if self.multispec:
2339N/A s = _("The following different patterns specify the "
2339N/A "same package(s):")
1505N/A res += [s]
2212N/A for t in self.multispec:
2339N/A res += [
565N/A ", ".join([t[i] for i in range(1, len(t))])
616N/A + ": {0}".format(t[0])
1141N/A ]
616N/A
2339N/A return "\n".join(res)
2339N/A
2339N/A
926N/Aclass PlanExecutionError(InvalidPlanError):
1141N/A """Used to indicate that the requested operation could not be executed
565N/A due to unexpected changes in image state after planning was completed.
2212N/A """
2212N/A
2212N/A def __init__(self, paths):
2212N/A self.paths = paths
2212N/A
2212N/A def __str__(self):
2212N/A return _("The files listed below were modified after operation "
1505N/A "planning was complete or were missing during plan "
1505N/A "execution; this may indicate an administrative issue or "
1505N/A "system configuration issue:\n{0}".format(
1505N/A "\n".join(list(self.paths))))
1505N/A
1505N/A
1505N/Aclass PlanCreationException(ApiException):
565N/A def __init__(self,
988N/A already_installed=EmptyI,
565N/A badarch=EmptyI,
922N/A illegal=EmptyI,
922N/A installed=EmptyI,
633N/A invalid_mediations=EmptyI,
616N/A linked_pub_error=EmptyI,
1505N/A missing_dependency=EmptyI,
1505N/A missing_matches=EmptyI,
1505N/A multiple_matches=EmptyI,
616N/A multispec=EmptyI,
1505N/A no_solution=False,
1505N/A no_tmp_origins=False,
1505N/A no_version=EmptyI,
655N/A not_avoided=EmptyI,
838N/A nofiles=EmptyI,
838N/A obsolete=EmptyI,
838N/A pkg_updates_required=EmptyI,
1027N/A rejected_pats=EmptyI,
838N/A solver_errors=EmptyI,
838N/A no_repo_pubs=EmptyI,
838N/A unmatched_fmris=EmptyI,
1461N/A would_install=EmptyI,
1461N/A wrong_publishers=EmptyI,
1461N/A wrong_variants=EmptyI):
1352N/A
1352N/A ApiException.__init__(self)
1352N/A self.already_installed = already_installed
1352N/A self.badarch = badarch
1352N/A self.illegal = illegal
1352N/A self.installed = installed
1352N/A self.invalid_mediations = invalid_mediations
1505N/A self.linked_pub_error = linked_pub_error
2224N/A self.missing_dependency = missing_dependency
1505N/A self.missing_matches = missing_matches
1505N/A self.multiple_matches = multiple_matches
1505N/A self.multispec = multispec
1505N/A self.no_solution = no_solution
1505N/A self.no_tmp_origins = no_tmp_origins
1505N/A self.no_version = no_version
1505N/A self.not_avoided = not_avoided
1945N/A self.nofiles = nofiles
1505N/A self.obsolete = obsolete
1505N/A self.pkg_updates_required = pkg_updates_required
2197N/A self.rejected_pats = rejected_pats
2197N/A self.solver_errors = solver_errors
2207N/A self.unmatched_fmris = unmatched_fmris
2339N/A self.no_repo_pubs = no_repo_pubs
2339N/A self.would_install = would_install
2339N/A self.wrong_publishers = wrong_publishers
2339N/A self.wrong_variants = wrong_variants
2339N/A
2339N/A def __str__(self):
2339N/A res = []
2339N/A if self.unmatched_fmris:
2339N/A s = _("""\
1505N/AThe following pattern(s) did not match any allowable packages. Try
1505N/Ausing a different matching pattern, or refreshing publisher information:
1505N/A""")
2339N/A res += [s]
2339N/A res += ["\t{0}".format(p) for p in self.unmatched_fmris]
2339N/A
2339N/A if self.rejected_pats:
2339N/A s = _("""\
2339N/AThe following pattern(s) only matched packages rejected by user request. Try
2339N/Ausing a different matching pattern, or refreshing publisher information:
2339N/A""")
2339N/A res += [s]
1505N/A res += ["\t{0}".format(p) for p in self.rejected_pats]
1945N/A
1945N/A if self.wrong_variants:
1945N/A s = _("""\
1945N/AThe following pattern(s) only matched packages that are not available
2200N/Afor the current image's architecture, zone type, and/or other variant:""")
2200N/A res += [s]
2200N/A res += ["\t{0}".format(p) for p in self.wrong_variants]
1945N/A
2207N/A if self.wrong_publishers:
2207N/A s = _("The following patterns only matched packages "
2207N/A "that are from publishers other than that which "
2207N/A "supplied the already installed version of this package")
2207N/A res += [s]
2228N/A res += ["\t{0}: {1}".format(p[0], ", ".join(p[1])) for p in self.wrong_publishers]
2339N/A
2339N/A if self.multiple_matches:
2339N/A s = _("'{0}' matches multiple packages")
2228N/A for p, lst in self.multiple_matches:
2228N/A res.append(s.format(p))
2228N/A for pfmri in lst:
2339N/A res.append("\t{0}".format(pfmri))
2339N/A
2339N/A if self.missing_matches:
2228N/A s = _("'{0}' matches no installed packages")
2228N/A res += [ s.format(p) for p in self.missing_matches ]
2339N/A
2339N/A if self.illegal:
2339N/A s = _("'{0}' is an illegal fmri")
2339N/A res += [ s.format(p) for p in self.illegal ]
2339N/A
2339N/A if self.badarch:
2339N/A s = _("'{p}' supports the following architectures: "
2339N/A "{archs}")
2339N/A a = _("Image architecture is defined as: {0}")
2339N/A res += [ s.format(p=self.badarch[0],
2339N/A archs=", ".join(self.badarch[1]))]
2339N/A res += [ a.format(self.badarch[2])]
2339N/A
2339N/A s = _("'{p}' depends on obsolete package '{op}'")
2339N/A res += [ s.format(p=p, op=op) for p, op in self.obsolete ]
2339N/A
2339N/A if self.installed:
2339N/A s = _("The proposed operation can not be performed for "
2364N/A "the following package(s) as they are already "
2339N/A "installed: ")
2339N/A res += [s]
2339N/A res += ["\t{0}".format(p) for p in self.installed]
2339N/A
2339N/A if self.invalid_mediations:
2339N/A s = _("The following mediations are not syntactically "
2339N/A "valid:")
2339N/A for m, entries in six.iteritems(self.invalid_mediations):
2339N/A for value, error in entries.values():
2339N/A res.append(error)
1352N/A
565N/A if self.multispec:
2228N/A s = _("The following patterns specify different "
2205N/A "versions of the same package(s):")
2205N/A res += [s]
2205N/A for t in self.multispec:
2205N/A res += [
2205N/A ", ".join(
2205N/A [t[i] for i in range(1, len(t))])
2205N/A + ": {0}".format(t[0])
2205N/A ]
2205N/A if self.no_solution:
2205N/A res += [_("No solution was found to satisfy constraints")]
2205N/A if isinstance(self.no_solution, list):
2205N/A res.extend(self.no_solution)
2205N/A
2205N/A if self.pkg_updates_required:
2205N/A s = _("""\
2205N/ASyncing this linked image would require the following package updates:
2205N/A""")
2205N/A res += [s]
2205N/A for (oldfmri, newfmri) in self.pkg_updates_required:
2205N/A res += ["{oldfmri} -> {newfmri}\n".format(
2205N/A oldfmri=oldfmri, newfmri=newfmri)]
2205N/A
2205N/A if self.no_version:
2205N/A res += self.no_version
2205N/A
2205N/A if self.no_tmp_origins:
2205N/A s = _("""
2205N/AThe proposed operation on this parent image can not be performed because
2205N/Atemporary origins were specified and this image has children. Please either
2205N/Aretry the operation again without specifying any temporary origins, or if
2205N/Apackages from additional origins are required, please configure those origins
2205N/Apersistently.""")
2205N/A res = [s]
2205N/A
2205N/A if self.missing_dependency:
2205N/A res += [_("Package {pkg} is missing a dependency: "
2205N/A "{dep}").format(
2205N/A pkg=self.missing_dependency[0],
2205N/A dep=self.missing_dependency[1])]
2205N/A if self.nofiles:
2205N/A res += [_("The following files are not packaged in this image:")]
2205N/A res += ["\t{0}".format(f) for f in self.nofiles]
2205N/A
2205N/A if self.solver_errors:
2205N/A res += ["\n"]
2205N/A res += [_("Solver dependency errors:")]
2205N/A res.extend(self.solver_errors)
2205N/A
2205N/A if self.already_installed:
2205N/A res += [_("The following packages are already "
2205N/A "installed in this image; use uninstall to "
2205N/A "avoid these:")]
2205N/A res += [ "\t{0}".format(s) for s in self.already_installed]
2205N/A
2205N/A if self.would_install:
2205N/A res += [_("The following packages are a target "
2205N/A "of group dependencies; use install to unavoid "
2205N/A "these:")]
2205N/A res += [ "\t{0}".format(s) for s in self.would_install]
2205N/A
2205N/A if self.not_avoided:
2205N/A res += [_("The following packages are not on the "
2205N/A "avoid list, so they\ncannot be removed from it.")]
2205N/A res += [ "\t{0}".format(s) for s in sorted(self.not_avoided)]
2205N/A
2205N/A def __format_li_pubs(pubs, res):
2205N/A i = 0
2205N/A for pub, sticky in pubs:
2205N/A s = " {0} {1:d}: {2}".format(_("PUBLISHER"),
2205N/A i, pub)
2205N/A mod = []
2205N/A if not sticky:
2205N/A mod.append(_("non-sticky"))
2205N/A if mod:
2205N/A s += " ({0})".format(",".join(mod))
2205N/A res.append(s)
2205N/A i += 1
2205N/A
2205N/A if self.linked_pub_error:
2205N/A res = []
2205N/A (pubs, parent_pubs) = self.linked_pub_error
2205N/A
2205N/A res.append(_("""
2205N/AInvalid child image publisher configuration. Child image publisher
2205N/Aconfiguration must be a superset of the parent image publisher configuration.
2205N/APlease update the child publisher configuration to match the parent. If the
2205N/Achild image is a zone this can be done automatically by detaching and
2205N/Aattaching the zone.
2205N/A
2205N/AThe parent image has the following enabled publishers:"""))
2205N/A __format_li_pubs(parent_pubs, res)
2205N/A res.append(_("""
2205N/AThe child image has the following enabled publishers:"""))
2205N/A __format_li_pubs(pubs, res)
2205N/A
2205N/A if self.no_repo_pubs:
2205N/A res += [_("The following publishers do not have any "
2205N/A "configured package repositories and cannot be "
2205N/A "used in package dehydration or rehydration "
2205N/A "operations:\n")]
2205N/A res += ["\t{0}".format(s) for s in sorted(
2205N/A self.no_repo_pubs)]
2400N/A
2400N/A return "\n".join(res)
2205N/A
2205N/A
2205N/Aclass ConflictingActionError(ApiException):
2205N/A """Used to indicate that the imageplan would result in one or more sets
2205N/A of conflicting actions, meaning that more than one action would exist on
2205N/A the system with the same key attribute value in the same namespace.
2232N/A There are three categories, each with its own subclass:
2232N/A
2205N/A - multiple files delivered to the same path or drivers, users, groups,
2205N/A etc, delivered with the same key attribute;
2205N/A
2205N/A - multiple objects delivered to the same path which aren't the same
2205N/A type;
2205N/A
2205N/A - multiple directories, links, or hardlinks delivered to the same path
2205N/A but with conflicting attributes.
2205N/A """
2205N/A
2205N/A def __init__(self, data):
2205N/A self._data = data
2205N/A
2205N/Aclass ConflictingActionErrors(ApiException):
2205N/A """A container for multiple ConflictingActionError exception objects
2205N/A that can be raised as a single exception."""
2205N/A
2205N/A def __init__(self, errors):
2205N/A self.__errors = errors
2205N/A
2205N/A def __str__(self):
2205N/A return "\n\n".join((str(err) for err in self.__errors))
2205N/A
2205N/Aclass DuplicateActionError(ConflictingActionError):
2205N/A """Multiple actions of the same type have been delivered with the same
2205N/A key attribute (when not allowed)."""
2239N/A
2205N/A def __str__(self):
2205N/A pfmris = set((a[1] for a in self._data))
2239N/A kv = self._data[0][0].attrs[self._data[0][0].key_attr]
2205N/A action = self._data[0][0].name
2205N/A if len(pfmris) > 1:
2205N/A s = _("The following packages all deliver {action} "
2205N/A "actions to {kv}:\n").format(**locals())
2205N/A for a, p in self._data:
2205N/A s += "\n {0}".format(p)
2205N/A s += _("\n\nThese packages cannot be installed "
2205N/A "together. Any non-conflicting subset\nof "
2205N/A "the above packages can be installed.")
2205N/A else:
2205N/A pfmri = pfmris.pop()
2205N/A s = _("The package {pfmri} delivers multiple copies "
2205N/A "of {action} {kv}").format(**locals())
2205N/A s += _("\nThis package must be corrected before it "
2205N/A "can be installed.")
2205N/A
2205N/A return s
2205N/A
2205N/Aclass InconsistentActionTypeError(ConflictingActionError):
2205N/A """Multiple actions of different types have been delivered with the same
2205N/A 'path' attribute. While this exception could represent other action
2205N/A groups which share a single namespace, none such exist."""
2205N/A
2205N/A def __str__(self):
2205N/A ad = {}
2205N/A pfmris = set()
2205N/A kv = self._data[0][0].attrs[self._data[0][0].key_attr]
2205N/A for a, p in self._data:
2205N/A ad.setdefault(a.name, []).append(p)
2205N/A pfmris.add(p)
2205N/A
2205N/A if len(pfmris) > 1:
1068N/A s = _("The following packages deliver conflicting "
1050N/A "action types to {0}:\n").format(kv)
1859N/A for name, pl in six.iteritems(ad):
1859N/A s += "\n {0}:".format(name)
1050N/A s += "".join("\n {0}".format(p) for p in pl)
1050N/A s += _("\n\nThese packages cannot be installed "
1859N/A "together. Any non-conflicting subset\nof "
1859N/A "the above packages can be installed.")
1859N/A else:
1859N/A pfmri = pfmris.pop()
1859N/A types = list_to_lang(list(ad.keys()))
1859N/A s = _("The package {pfmri} delivers conflicting "
1859N/A "action types ({types}) to {kv}").format(**locals())
1859N/A s += _("\nThis package must be corrected before it "
1859N/A "can be installed.")
1859N/A return s
1859N/A
1859N/Aclass InconsistentActionAttributeError(ConflictingActionError):
1859N/A """Multiple actions of the same type representing the same object have
1859N/A have been delivered, but with conflicting attributes, such as two
1859N/A directories at /usr with groups 'root' and 'sys', or two 'root' users
1050N/A with uids '0' and '7'."""
1859N/A
1859N/A def __str__(self):
1859N/A actions = self._data
1859N/A keyattr = actions[0][0].attrs[actions[0][0].key_attr]
1859N/A actname = actions[0][0].name
1859N/A
1859N/A # Trim the action's attributes to only those required to be
1050N/A # unique.
1859N/A def ou(action):
1050N/A ua = dict(
1859N/A (k, v)
1859N/A for k, v in six.iteritems(action.attrs)
1859N/A if ((k in action.unique_attrs and
1859N/A not (k == "preserve" and "overlay" in action.attrs)) or
1859N/A ((action.name == "link" or action.name == "hardlink") and
1859N/A k.startswith("mediator")))
1859N/A )
1859N/A action.attrs = ua
1050N/A return action
1050N/A
1050N/A d = {}
1859N/A for a in actions:
1859N/A if a[0].attrs.get("implicit", "false") == "false":
1859N/A d.setdefault(str(ou(a[0])), set()).add(a[1])
1859N/A l = sorted([
1050N/A (len(pkglist), action, pkglist)
1859N/A for action, pkglist in six.iteritems(d)
1050N/A ])
1050N/A
1050N/A s = _("The requested change to the system attempts to install "
1859N/A "multiple actions\nfor {a} '{k}' with conflicting "
1859N/A "attributes:\n\n").format(a=actname, k=keyattr)
1859N/A allpkgs = set()
1859N/A for num, action, pkglist in l:
1859N/A allpkgs.update(pkglist)
1050N/A if num <= 5:
1859N/A if num == 1:
1859N/A t = _(" {n:d} package delivers '{a}':\n")
1859N/A else:
1859N/A t = _(" {n:d} packages deliver '{a}':\n")
2073N/A s += t.format(n=num, a=action)
1859N/A for pkg in sorted(pkglist):
1859N/A s += _(" {0}\n").format(pkg)
1859N/A else:
1859N/A t = _(" {n:d} packages deliver '{a}', including:\n")
1050N/A s += t.format(n=num, a=action)
1050N/A for pkg in sorted(pkglist)[:5]:
1859N/A s += _(" {0}\n").format(pkg)
1050N/A
1068N/A if len(allpkgs) == 1:
565N/A s += _("\nThis package must be corrected before it "
1603N/A "can be installed.")
565N/A else:
565N/A s += _("\n\nThese packages cannot be installed "
565N/A "together. Any non-conflicting subset\nof "
565N/A "the above packages can be installed.")
1603N/A
565N/A return s
1068N/A
1352N/A
1352N/Aclass ImageBoundaryError(ApiException):
1352N/A """Used to indicate that a file is delivered to image dir"""
1352N/A
565N/A GENERIC = "generic" # generic image boundary violation
1352N/A OUTSIDE_BE = "outside_be" # deliver items outside boot environment
1352N/A RESERVED = "reserved" # deliver items to reserved dirs
1352N/A
1352N/A def __init__(self, fmri, actions=None):
1516N/A """fmri is the package fmri
1352N/A actions should be a dictionary of which key is the
1352N/A error type and value is a list of actions"""
1352N/A
1352N/A ApiException.__init__(self)
1352N/A self.fmri = fmri
1352N/A generic = _("The following items are outside the boundaries "
1352N/A "of the target image:\n\n")
1352N/A outside_be = _("The following items are delivered outside "
1352N/A "the target boot environment:\n\n")
1352N/A reserved = _("The following items are delivered to "
1352N/A "reserved directories:\n\n")
1352N/A
1352N/A self.message = {
1352N/A self.GENERIC: generic,
1352N/A self.OUTSIDE_BE: outside_be,
1352N/A self.RESERVED: reserved
1352N/A }
1352N/A
1352N/A if actions:
1352N/A self.actions = actions
1352N/A else:
1516N/A self.actions = {}
1352N/A
1352N/A def append_error(self, action, err_type=GENERIC):
1352N/A """This function is used to append errors in the error
1352N/A dictionary"""
1352N/A
1352N/A if action:
1352N/A self.actions.setdefault(err_type, []).append(action)
1352N/A
1352N/A def isEmpty(self):
1352N/A """Return whether error dictionary is empty"""
1352N/A
1352N/A return len(self.actions) == 0
1352N/A
1352N/A def __str__(self):
1352N/A error_list = [self.GENERIC, self.OUTSIDE_BE, self.RESERVED]
1352N/A s = _("The package {0} delivers items outside the boundaries of"
1516N/A " the target image and can not be "
1352N/A "installed.\n\n").format(self.fmri)
1352N/A for err_type in error_list:
1352N/A if not err_type in self.actions:
1352N/A continue
1352N/A if self.actions[err_type]:
1352N/A s += self.message[err_type]
1352N/A for action in self.actions[err_type]:
1352N/A s += (" {0} {1}\n").format(
1352N/A action.name, action.attrs["path"])
1352N/A return s
1352N/A
1352N/A
1352N/Aclass ImageBoundaryErrors(ApiException):
1352N/A """A container for multiple ImageBoundaryError exception objects
1352N/A that can be raised as a single exception."""
1352N/A
1352N/A def __init__(self, errors):
1352N/A ApiException.__init__(self)
1352N/A self.__errors = errors
1352N/A
1352N/A generic = _("The following packages deliver items outside "
1352N/A "the boundaries of the target image and can not be "
1352N/A "installed:\n\n")
1352N/A outside_be = _("The following packages deliver items outside "
1352N/A "the target boot environment and can not be "
1352N/A "installed:\n\n")
1352N/A reserved = _("The following packages deliver items to reserved "
1352N/A "directories and can not be installed:\n\n")
1352N/A
1352N/A self.message = {
1352N/A ImageBoundaryError.GENERIC: generic,
1352N/A ImageBoundaryError.OUTSIDE_BE: outside_be,
1352N/A ImageBoundaryError.RESERVED: reserved
1516N/A }
1516N/A
1352N/A def __str__(self):
1352N/A if len(self.__errors) <= 1:
1352N/A return "\n".join([str(err) for err in self.__errors])
1352N/A
1352N/A s = ""
1352N/A for err_type in self.message:
1352N/A cur_errs = []
1352N/A for err in self.__errors:
1352N/A # If err does not contain this error type
1352N/A # we just ignore this.
1352N/A if not err_type in err.actions or \
1352N/A not err.actions[err_type]:
1352N/A continue
1352N/A cur_errs.append(err)
1352N/A
1352N/A if not cur_errs:
1352N/A continue
1352N/A
1352N/A if len(cur_errs) == 1:
2022N/A fmri = cur_errs[0].fmri
2022N/A s += _("The package {0} delivers items outside "
2022N/A "the boundaries of the target image and can "
2022N/A "not be installed.\n\n").format(fmri)
2022N/A s += cur_errs[0].message[err_type]
2022N/A for action in cur_errs[0].actions[err_type]:
2022N/A s += (" {0} {1}\n").format(
2022N/A action.name, action.attrs["path"])
2022N/A s += "\n"
2022N/A continue
2022N/A
2022N/A s += self.message[err_type]
2022N/A for err in cur_errs:
2022N/A s += (" {0}\n").format(err.fmri)
1352N/A for action in err.actions[err_type]:
1352N/A s += (" {0} {1}\n").format(
1352N/A action.name, action.attrs["path"])
1352N/A s += "\n"
1352N/A return s
1352N/A
1352N/A
1352N/Adef list_to_lang(l):
1352N/A """Takes a list of items and puts them into a string, with commas in
1352N/A between items, and an "and" between the last two items. Special cases
1352N/A for lists of two or fewer items, and uses the Oxford comma."""
1352N/A
1352N/A if not l:
1352N/A return ""
1352N/A if len(l) == 1:
1352N/A return l[0]
1352N/A if len(l) == 2:
1352N/A # Used for a two-element list
1352N/A return _("{penultimate} and {ultimate}").format(
1352N/A penultimate=l[0],
1352N/A ultimate=l[1]
1352N/A )
1352N/A # In order to properly i18n this construct, we create two templates:
1352N/A # one for each element save the last, and one that tacks on the last
1352N/A # element.
1352N/A # 'elementtemplate' is for each element through the penultimate
1352N/A elementtemplate = _("{0}, ")
1431N/A # 'listtemplate' concatenates the concatenation of non-ultimate elements
1431N/A # and the ultimate element.
1431N/A listtemplate = _("{list}and {tail}")
1431N/A return listtemplate.format(
1431N/A list="".join(elementtemplate.format(i) for i in l[:-1]),
1431N/A tail=l[-1]
1431N/A )
1431N/A
1431N/Aclass ActionExecutionError(ApiException):
1352N/A """Used to indicate that action execution (such as install, remove,
1352N/A etc.) failed even though the action is valid.
1970N/A
1970N/A In particular, this exception indicates that something went wrong in the
1352N/A application (or unapplication) of the action to the system, and is most
1352N/A likely not an error in the pkg(7) code."""
1352N/A
1352N/A def __init__(self, action, details=None, error=None, fmri=None,
838N/A use_errno=None):
1352N/A """'action' is the object for the action that failed during the
1352N/A requested operation.
1352N/A
1352N/A 'details' is an optional message explaining what operation
1352N/A failed, why it failed, and why it cannot continue. It should
1352N/A also include a suggestion as to how to resolve the situation
1352N/A if possible.
1352N/A
1352N/A 'error' is an optional exception object that may have been
1352N/A raised when the operation failed.
1945N/A
565N/A 'fmri' is an optional package FMRI indicating what package
596N/A was being operated on at the time the error occurred.
596N/A
596N/A 'use_errno' is an optional boolean value indicating whether
596N/A the strerror() text of the exception should be used. If
596N/A 'details' is provided, the default value is False, otherwise
614N/A True."""
1352N/A
614N/A assert (details or error)
614N/A self.action = action
926N/A self.details = details
614N/A self.error = error
1352N/A self.fmri = fmri
1352N/A if use_errno == None:
1352N/A # If details were provided, don't use errno unless
1352N/A # explicitly requested.
1352N/A use_errno = not details
1352N/A self.use_errno = use_errno
1352N/A
596N/A def __str__(self):
565N/A errno = ""
1027N/A if self.use_errno and self.error and \
1191N/A hasattr(self.error, "errno"):
1191N/A errno = "[errno {0:d}: {1}]".format(self.error.errno,
1027N/A os.strerror(self.error.errno))
1027N/A
1027N/A details = self.details or ""
1027N/A
1027N/A # Fall back on the wrapped exception if we don't have anything
1191N/A # useful.
1191N/A if not errno and not details:
1191N/A return str(self.error)
1191N/A
1191N/A if errno and details:
1191N/A details = "{0}: {1}".format(errno, details)
1191N/A
1191N/A if details and not self.fmri:
1191N/A details = _("Requested operation failed for action "
1191N/A "{action}:\n{details}").format(
1191N/A action=self.action,
1191N/A details=details)
1191N/A elif details:
1191N/A details = _("Requested operation failed for package "
1191N/A "{fmri}:\n{details}").format(fmri=self.fmri,
1191N/A details=details)
1191N/A
1191N/A # If we only have one of the two, no need for the colon.
1191N/A return "{0}{1}".format(errno, details)
1191N/A
1191N/A
1191N/Aclass CatalogOriginRefreshException(ApiException):
1191N/A def __init__(self, failed, total, errmessage=None):
1191N/A ApiException.__init__(self)
1191N/A self.failed = failed
1191N/A self.total = total
1191N/A self.errmessage = errmessage
1191N/A
1191N/A
1191N/Aclass CatalogRefreshException(ApiException):
1191N/A def __init__(self, failed, total, succeeded, errmessage=None):
1191N/A ApiException.__init__(self)
1191N/A self.failed = failed
1191N/A self.total = total
1895N/A self.succeeded = succeeded
1191N/A self.errmessage = errmessage
1191N/A
1191N/A
1191N/Aclass CatalogError(ApiException):
1191N/A """Base exception class for all catalog exceptions."""
1191N/A
1191N/A def __init__(self, *args, **kwargs):
1895N/A ApiException.__init__(self)
1895N/A if args:
1191N/A self.data = args[0]
1191N/A else:
1191N/A self.data = None
1191N/A self._args = kwargs
1191N/A
1191N/A def __str__(self):
1191N/A return str(self.data)
1191N/A
1191N/A
1191N/Aclass AnarchicalCatalogFMRI(CatalogError):
1191N/A """Used to indicate that the specified FMRI is not valid for catalog
1191N/A operations because it is missing publisher information."""
1191N/A
1191N/A def __str__(self):
1191N/A return _("The FMRI '{0}' does not contain publisher information "
1191N/A "and cannot be used for catalog operations.").format(
1191N/A self.data)
1191N/A
1191N/A
1191N/Aclass BadCatalogMetaRoot(CatalogError):
1191N/A """Used to indicate an operation on the catalog's meta_root failed
1191N/A because the meta_root is invalid."""
1191N/A
1191N/A def __str__(self):
1191N/A return _("Catalog meta_root '{root}' is invalid; unable "
1191N/A "to complete operation: '{op}'.").format(root=self.data,
1895N/A op=self._args.get("operation", None))
1895N/A
1191N/A
1895N/Aclass BadCatalogPermissions(CatalogError):
1191N/A """Used to indicate the server catalog files do not have the expected
1191N/A permissions."""
1191N/A
1191N/A def __init__(self, files):
1191N/A """files should contain a list object with each entry consisting
1191N/A of a tuple of filename, expected_mode, received_mode."""
1945N/A if not files:
1191N/A files = []
1191N/A CatalogError.__init__(self, files)
1191N/A
1191N/A def __str__(self):
1191N/A msg = _("The following catalog files have incorrect "
1191N/A "permissions:\n")
1191N/A for f in self.data:
1191N/A fname, emode, fmode = f
1027N/A msg += _("\t{fname}: expected mode: {emode}, found "
565N/A "mode: {fmode}\n").format(fname=fname,
1027N/A emode=emode, fmode=fmode)
565N/A return msg
1027N/A
565N/A
565N/Aclass BadCatalogSignatures(CatalogError):
1027N/A """Used to indicate that the Catalog signatures are not valid."""
565N/A
565N/A def __str__(self):
565N/A return _("The signature data for the '{0}' catalog file is not "
565N/A "valid.").format(self.data)
1027N/A
1191N/A
1191N/Aclass BadCatalogUpdateIdentity(CatalogError):
1191N/A """Used to indicate that the requested catalog updates could not be
1191N/A applied as the new catalog data is significantly different such that
1191N/A the old catalog cannot be updated to match it."""
1191N/A
1191N/A def __str__(self):
1191N/A return _("Unable to determine the updates needed for "
1191N/A "the current catalog using the provided catalog "
1191N/A "update data in '{0}'.").format(self.data)
1191N/A
2028N/A
2028N/Aclass DuplicateCatalogEntry(CatalogError):
2028N/A """Used to indicate that the specified catalog operation could not be
2028N/A performed since it would result in a duplicate catalog entry."""
2028N/A
2028N/A def __str__(self):
2028N/A return _("Unable to perform '{op}' operation for catalog "
2028N/A "{name}; completion would result in a duplicate entry "
2028N/A "for package '{fmri}'.").format(op=self._args.get(
2028N/A "operation", None), name=self._args.get("catalog_name",
2028N/A None), fmri=self.data)
2028N/A
565N/A
565N/Aclass CatalogUpdateRequirements(CatalogError):
565N/A """Used to indicate that an update request for the catalog could not
565N/A be performed because update requirements were not satisfied."""
565N/A
565N/A def __str__(self):
565N/A return _("Catalog updates can only be applied to an on-disk "
565N/A "catalog.")
941N/A
1286N/A
1286N/Aclass InvalidCatalogFile(CatalogError):
2089N/A """Used to indicate a Catalog file could not be loaded."""
2089N/A
1286N/A def __str__(self):
1286N/A return _("Catalog file '{0}' is invalid.\nUse 'pkgrepo rebuild' "
1286N/A "to create a new package catalog.").format(self.data)
1286N/A
1286N/A
1286N/Aclass MismatchedCatalog(CatalogError):
1286N/A """Used to indicate that a Catalog's attributes and parts do not
1286N/A match. This is likely the result of an attributes file being
1286N/A retrieved which doesn't match the parts that were retrieved such
1286N/A as in a misconfigured or stale cache case."""
1286N/A
1286N/A def __str__(self):
1286N/A return _("The content of the catalog for publisher '{0}' "
1286N/A "doesn't match the catalog's attributes. This is "
1286N/A "likely the result of a mix of older and newer "
2089N/A "catalog files being provided for the publisher.").format(
2089N/A self.data)
1286N/A
1286N/A
1286N/Aclass ObsoleteCatalogUpdate(CatalogError):
1191N/A """Used to indicate that the specified catalog updates are for an older
1191N/A version of the catalog and cannot be applied."""
1191N/A
1191N/A def __str__(self):
1191N/A return _("Unable to determine the updates needed for the "
941N/A "catalog using the provided catalog update data in '{0}'. "
941N/A "The specified catalog updates are for an older version "
1191N/A "of the catalog and cannot be used.").format(self.data)
1191N/A
1191N/A
1191N/Aclass UnknownCatalogEntry(CatalogError):
1191N/A """Used to indicate that an entry for the specified package FMRI or
1191N/A pattern could not be found in the catalog."""
1191N/A
1191N/A def __str__(self):
1191N/A return _("'{0}' could not be found in the catalog.").format(
1191N/A self.data)
941N/A
941N/A
941N/Aclass UnknownUpdateType(CatalogError):
1027N/A """Used to indicate that the specified CatalogUpdate operation is
1027N/A unknown."""
565N/A
565N/A def __str__(self):
565N/A return _("Unknown catalog update type '{0}'").format(self.data)
1027N/A
565N/A
565N/Aclass UnrecognizedCatalogPart(CatalogError):
565N/A """Raised when the catalog finds a CatalogPart that is unrecognized
565N/A or invalid."""
565N/A
565N/A def __str__(self):
565N/A return _("Unrecognized, unknown, or invalid CatalogPart '{0}'").format(
565N/A self.data)
565N/A
565N/A
565N/Aclass InventoryException(ApiException):
835N/A """Used to indicate that some of the specified patterns to a catalog
2205N/A matching function did not match any catalog entries, or were invalid
2205N/A patterns."""
2205N/A
2205N/A def __init__(self, illegal=EmptyI, matcher=EmptyI, notfound=EmptyI,
2205N/A publisher=EmptyI, version=EmptyI):
2205N/A ApiException.__init__(self)
2205N/A self.illegal = illegal
2205N/A self.matcher = matcher
2205N/A self.notfound = set(notfound)
2205N/A self.publisher = publisher
2205N/A self.version = version
2205N/A
835N/A self.notfound.update(matcher)
835N/A self.notfound.update(publisher)
835N/A self.notfound.update(version)
835N/A self.notfound = sorted(list(self.notfound))
926N/A
835N/A assert self.illegal or self.notfound
835N/A
835N/A def __str__(self):
835N/A outstr = ""
2205N/A for x in self.illegal:
835N/A # Illegal FMRIs have their own __str__ method
2205N/A outstr += "{0}\n".format(x)
835N/A
2205N/A if self.matcher or self.publisher or self.version:
835N/A outstr += _("No matching package could be found for "
2205N/A "the following FMRIs in any of the catalogs for "
2205N/A "the current publishers:\n")
2205N/A
835N/A for x in self.matcher:
884N/A outstr += \
926N/A _("{0} (pattern did not match)\n").format(x)
926N/A for x in self.publisher:
926N/A outstr += _("{0} (publisher did not "
926N/A "match)\n").format(x)
926N/A for x in self.version:
926N/A outstr += \
926N/A _("{0} (version did not match)\n").format(x)
926N/A return outstr
926N/A
1516N/A
926N/A# SearchExceptions
926N/A
926N/Aclass SearchException(ApiException):
926N/A """Based class used for all search-related api exceptions."""
926N/A pass
926N/A
926N/A
926N/Aclass MalformedSearchRequest(SearchException):
1736N/A """Raised when the server cannot understand the format of the
926N/A search request."""
926N/A
1736N/A def __init__(self, url):
1736N/A SearchException.__init__(self)
926N/A self.url = url
926N/A
2310N/A def __str__(self):
2310N/A return str(self.url)
2310N/A
2310N/A
2310N/Aclass NegativeSearchResult(SearchException):
2310N/A """Returned when the search cannot find any matches."""
2310N/A
2310N/A def __init__(self, url):
2310N/A SearchException.__init__(self)
2310N/A self.url = url
2310N/A
2310N/A def __str__(self):
2310N/A return _("The search at url {0} returned no results.").format(
926N/A self.url)
926N/A
926N/A
926N/Aclass ProblematicSearchServers(SearchException):
926N/A """This class wraps exceptions which could appear while trying to
926N/A do a search request."""
926N/A
926N/A def __init__(self, failed=EmptyI, invalid=EmptyI, unsupported=EmptyI):
926N/A SearchException.__init__(self)
2310N/A self.failed_servers = failed
2310N/A self.invalid_servers = invalid
2310N/A self.unsupported_servers = unsupported
2310N/A
2310N/A def __str__(self):
2310N/A s = _("Some repositories failed to respond appropriately:\n")
2310N/A for pub, err in self.failed_servers:
2310N/A s += _("{o}:\n{msg}\n").format(
2310N/A o=pub, msg=err)
2310N/A for pub in self.invalid_servers:
2310N/A s += _("{0} did not return a valid "
2310N/A "response.\n".format(pub))
2310N/A if len(self.unsupported_servers) > 0:
2310N/A s += _("Some repositories don't support requested "
2310N/A "search operation:\n")
2310N/A for pub, err in self.unsupported_servers:
2310N/A s += _("{o}:\n{msg}\n").format(
2310N/A o=pub, msg=err)
2310N/A
2310N/A return s
2310N/A
926N/A
1191N/Aclass SlowSearchUsed(SearchException):
1191N/A """This exception is thrown when a local search is performed without
1191N/A an index. It's raised after all results have been yielded."""
1191N/A
1191N/A def __str__(self):
926N/A return _("Search performance is degraded.\n"
926N/A "Run 'pkg rebuild-index' to improve search speed.")
1540N/A
926N/A
2205N/A@total_ordering
2205N/Aclass UnsupportedSearchError(SearchException):
2205N/A """Returned when a search protocol is not supported by the
926N/A remote server."""
1191N/A
926N/A def __init__(self, url=None, proto=None):
926N/A SearchException.__init__(self)
926N/A self.url = url
1191N/A self.proto = proto
1191N/A
1191N/A def __str__(self):
1191N/A s = _("Search repository does not support the requested "
1191N/A "protocol:")
926N/A if self.url:
1191N/A s += "\nRepository URL: {0}".format(self.url)
926N/A if self.proto:
1191N/A s += "\nRequested operation: {0}".format(self.proto)
926N/A return s
926N/A
926N/A def __eq__(self, other):
926N/A if not isinstance(other, UnsupportedSearchError):
1191N/A return False
926N/A return self.url == other.url and \
926N/A self.proto == other.proto
1191N/A
1191N/A def __le__(self, other):
1191N/A if not isinstance(other, UnsupportedSearchError):
1191N/A return True
926N/A if self.url < other.url:
926N/A return True
926N/A if self.url != other.url:
941N/A return False
941N/A return self.proto < other.proto
941N/A
926N/A def __hash__(self):
884N/A return hash((self.url, self.proto))
884N/A
884N/A
884N/A# IndexingExceptions.
884N/A
884N/Aclass IndexingException(SearchException):
1076N/A """ The base class for all exceptions that can occur while indexing. """
1076N/A
1076N/A def __init__(self, private_exception):
1076N/A SearchException.__init__(self)
1945N/A self.cause = private_exception.cause
1076N/A
1076N/A
1076N/Aclass CorruptedIndexException(IndexingException):
1076N/A """This is used when the index is not in a correct state."""
1076N/A def __str__(self):
1076N/A return _("The search index appears corrupted.")
1076N/A
1076N/A
1076N/Aclass InconsistentIndexException(IndexingException):
884N/A """This is used when the existing index is found to have inconsistent
884N/A versions."""
884N/A def __init__(self, e):
884N/A IndexingException.__init__(self, e)
884N/A self.exception = e
884N/A
884N/A def __str__(self):
884N/A return str(self.exception)
884N/A
2089N/A
884N/Aclass IndexLockedException(IndexingException):
884N/A """This is used when an attempt to modify an index locked by another
884N/A process or thread is made."""
884N/A
884N/A def __init__(self, e):
884N/A IndexingException.__init__(self, e)
884N/A self.exception = e
884N/A
884N/A def __str__(self):
884N/A return str(self.exception)
884N/A
884N/A
884N/Aclass ProblematicPermissionsIndexException(IndexingException):
884N/A """ This is used when the indexer is unable to create, move, or remove
884N/A files or directories it should be able to. """
884N/A def __str__(self):
884N/A return "Could not remove or create " \
884N/A "{0} because of incorrect " \
884N/A "permissions. Please correct this issue then " \
884N/A "rebuild the index.".format(self.cause)
884N/A
884N/Aclass WrapIndexingException(ApiException):
884N/A """This exception is used to wrap an indexing exception during install,
884N/A uninstall, or update so that a more appropriate error message can be
884N/A displayed to the user."""
884N/A
884N/A def __init__(self, e, tb, stack):
884N/A ApiException.__init__(self)
884N/A self.wrapped = e
884N/A self.tb = tb
884N/A self.stack = stack
884N/A
884N/A def __str__(self):
884N/A tmp = self.tb.split("\n")
884N/A res = tmp[:1] + [s.rstrip("\n") for s in self.stack] + tmp[1:]
884N/A return "\n".join(res)
884N/A
884N/A
884N/Aclass WrapSuccessfulIndexingException(WrapIndexingException):
926N/A """This exception is used to wrap an indexing exception during install,
926N/A uninstall, or update which was recovered from by performing a full
917N/A reindex."""
917N/A pass
917N/A
917N/A
917N/A# Query Parsing Exceptions
917N/Aclass BooleanQueryException(ApiException):
917N/A """This exception is used when the children of a boolean operation
917N/A have different return types. The command 'pkg search foo AND <bar>'
917N/A is the simplest example of this."""
917N/A
926N/A def __init__(self, e):
941N/A ApiException.__init__(self)
941N/A self.e = e
941N/A
941N/A def __str__(self):
941N/A return str(self.e)
941N/A
926N/A
926N/Aclass ParseError(ApiException):
926N/A def __init__(self, e):
926N/A ApiException.__init__(self)
926N/A self.e = e
926N/A
926N/A def __str__(self):
926N/A return str(self.e)
926N/A
1516N/A
926N/Aclass NonLeafPackageException(ApiException):
926N/A """Removal of a package which satisfies dependencies has been attempted.
926N/A
926N/A The first argument to the constructor is the FMRI which we tried to
926N/A remove, and is available as the "fmri" member of the exception. The
1087N/A second argument is the list of dependent packages that prevent the
1087N/A removal of the package, and is available as the "dependents" member.
1087N/A """
1087N/A
1087N/A def __init__(self, *args):
1087N/A ApiException.__init__(self, *args)
1087N/A
1516N/A self.fmri = args[0]
1087N/A self.dependents = args[1]
1087N/A
2028N/A def __str__(self):
2028N/A s = _("Unable to remove '{0}' due to the following packages "
2028N/A "that depend on it:\n").format(self.fmri.get_short_fmri(
2028N/A anarchy=True, include_scheme=False))
2028N/A skey = operator.attrgetter('pkg_name')
2028N/A s += "\n".join(
2028N/A " {0}".format(f.get_short_fmri(anarchy=True,
926N/A include_scheme=False))
926N/A for f in sorted(self.dependents, key=skey)
926N/A )
926N/A return s
926N/A
926N/A
926N/Adef _str_autofix(self):
2339N/A
2339N/A if getattr(self, "_autofix_pkgs", []):
2339N/A s = _("\nThis is happening because the following "
2339N/A "packages needed to be repaired as\npart of this "
2339N/A "operation:\n\n ")
2339N/A s += "\n ".join(str(f) for f in self._autofix_pkgs)
2339N/A s += _("\n\nYou will need to reestablish your access to the "
2339N/A "repository or remove the\npackages in the list above.")
2339N/A return s
2339N/A return ""
926N/A
926N/A
926N/Aclass InvalidDepotResponseException(ApiException):
926N/A """Raised when the depot doesn't have versions of operations
926N/A that the client needs to operate successfully."""
926N/A def __init__(self, url, data):
926N/A ApiException.__init__(self)
1516N/A self.url = url
926N/A self.data = data
926N/A
926N/A def __str__(self):
926N/A s = _("Unable to contact valid package repository")
926N/A if self.url:
926N/A s += _(": {0}").format(self.url)
926N/A if self.data:
926N/A s += ("\nEncountered the following error(s):\n{0}").format(
926N/A self.data)
926N/A
926N/A s += _str_autofix(self)
926N/A
926N/A return s
926N/A
926N/A
926N/Aclass DataError(ApiException):
926N/A """Base exception class used for all data related errors."""
926N/A
926N/A def __init__(self, *args, **kwargs):
926N/A ApiException.__init__(self, *args)
926N/A if args:
926N/A self.data = args[0]
926N/A else:
926N/A self.data = None
926N/A self._args = kwargs
926N/A
926N/A
926N/Aclass InvalidP5IFile(DataError):
926N/A """Used to indicate that the specified location does not contain a
926N/A valid p5i-formatted file."""
926N/A
926N/A def __str__(self):
926N/A if self.data:
926N/A return _("The provided p5i data is in an unrecognized "
926N/A "format or does not contain valid publisher "
926N/A "information: {0}").format(self.data)
926N/A return _("The provided p5i data is in an unrecognized format "
926N/A "or does not contain valid publisher information.")
926N/A
926N/A
926N/Aclass InvalidP5SFile(DataError):
926N/A """Used to indicate that the specified location does not contain a
926N/A valid p5i-formatted file."""
926N/A
926N/A def __str__(self):
926N/A if self.data:
926N/A return _("The provided p5s data is in an unrecognized "
926N/A "format or does not contain valid publisher "
926N/A "information: {0}").format(self.data)
926N/A return _("The provided p5s data is in an unrecognized format "
926N/A "or does not contain valid publisher information.")
926N/A
926N/A
926N/Aclass UnsupportedP5IFile(DataError):
926N/A """Used to indicate that an attempt to read an unsupported version
926N/A of pkg(7) info file was attempted."""
926N/A
926N/A def __str__(self):
926N/A return _("Unsupported pkg(7) publisher information data "
926N/A "format.")
926N/A
926N/A
926N/Aclass UnsupportedP5SFile(DataError):
926N/A """Used to indicate that an attempt to read an unsupported version
926N/A of pkg(7) info file was attempted."""
926N/A
926N/A def __str__(self):
926N/A return _("Unsupported pkg(7) publisher and image information "
926N/A "data format.")
926N/A
926N/A
926N/Aclass UnsupportedP5SVersion(ApiException):
926N/A """Used to indicate that an attempt to read an unsupported version
926N/A of pkg(7) info file was attempted."""
926N/A
1504N/A def __init__(self, v):
926N/A self.version = v
926N/A
926N/A def __str__(self):
926N/A return _("{0} is not a supported version for creating a "
926N/A "syspub response.").format(self.version)
926N/A
926N/A
926N/Aclass TransportError(ApiException):
1504N/A """Abstract exception class for all transport exceptions.
1504N/A Specific transport exceptions should be implemented in the
1504N/A transport code. Callers wishing to catch transport exceptions
2322N/A should use this class. Subclasses must implement all methods
2219N/A defined here that raise NotImplementedError."""
2219N/A
1504N/A def __str__(self):
2322N/A raise NotImplementedError()
2322N/A
2322N/A def _str_autofix(self):
2322N/A return _str_autofix(self)
1504N/A
2219N/A
2219N/Aclass RetrievalError(ApiException):
2322N/A """Used to indicate that a a requested resource could not be
926N/A retrieved."""
926N/A
1505N/A def __init__(self, data, location=None):
1505N/A ApiException.__init__(self)
1505N/A self.data = data
1505N/A self.location = location
1505N/A
1505N/A def __str__(self):
1505N/A if self.location:
2409N/A return _("Error encountered while retrieving data from "
2409N/A "'{location}':\n{data}").format(
2409N/A location=self.location, data=self.data)
2409N/A return _("Error encountered while retrieving data from: {0}").format(
2409N/A self.data)
2409N/A
2409N/A
2409N/Aclass InvalidResourceLocation(ApiException):
2409N/A """Used to indicate that an invalid transport location was provided."""
2409N/A
2409N/A def __init__(self, data):
2409N/A ApiException.__init__(self)
926N/A self.data = data
926N/A
926N/A def __str__(self):
926N/A return _("'{0}' is not a valid location.").format(self.data)
926N/A
926N/Aclass BEException(ApiException):
926N/A def __init__(self):
926N/A ApiException.__init__(self)
926N/A
926N/Aclass InvalidBENameException(BEException):
926N/A def __init__(self, be_name):
926N/A BEException.__init__(self)
926N/A self.be_name = be_name
926N/A
926N/A def __str__(self):
926N/A return _("'{0}' is not a valid boot environment name.").format(
926N/A self.be_name)
926N/A
926N/Aclass DuplicateBEName(BEException):
926N/A """Used to indicate that there is an existing boot environment
926N/A with this name"""
926N/A
926N/A def __init__(self, be_name):
926N/A BEException.__init__(self)
926N/A self.be_name = be_name
1736N/A
1736N/A def __str__(self):
1736N/A return _("The boot environment '{0}' already exists.").format(
1736N/A self.be_name)
1736N/A
1736N/Aclass BENamingNotSupported(BEException):
1736N/A def __init__(self, be_name):
1736N/A BEException.__init__(self)
1736N/A self.be_name = be_name
1736N/A
1736N/A def __str__(self):
1736N/A return _("""\
1736N/ABoot environment naming during package install is not supported on this
1736N/Aversion of OpenSolaris. Please update without the --be-name option.""")
1736N/A
1736N/Aclass UnableToCopyBE(BEException):
1736N/A def __str__(self):
1736N/A return _("Unable to clone the current boot environment.")
1736N/A
1736N/Aclass UnableToRenameBE(BEException):
1736N/A def __init__(self, orig, dest):
1736N/A BEException.__init__(self)
1736N/A self.original_name = orig
1736N/A self.destination_name = dest
1736N/A
1736N/A def __str__(self):
1736N/A d = {
1736N/A "orig": self.original_name,
1736N/A "dest": self.destination_name
1736N/A }
1736N/A return _("""\
1736N/AA problem occurred while attempting to rename the boot environment
1736N/Acurrently named {orig} to {dest}.""").format(**d)
1736N/A
1736N/Aclass UnableToMountBE(BEException):
1736N/A def __init__(self, be_name, be_dir):
1736N/A BEException.__init__(self)
1736N/A self.name = be_name
1736N/A self.mountpoint = be_dir
1736N/A
926N/A def __str__(self):
926N/A return _("Unable to mount {name} at {mt}").format(
926N/A name=self.name, mt=self.mountpoint)
926N/A
926N/Aclass BENameGivenOnDeadBE(BEException):
926N/A def __init__(self, be_name):
926N/A BEException.__init__(self)
926N/A self.name = be_name
926N/A
926N/A def __str__(self):
926N/A return _("""\
926N/ANaming a boot environment when operating on a non-live image is
926N/Anot allowed.""")
926N/A
926N/A
926N/Aclass UnrecognizedOptionsToInfo(ApiException):
926N/A def __init__(self, opts):
926N/A ApiException.__init__(self)
926N/A self._opts = opts
926N/A
926N/A def __str__(self):
926N/A s = _("Info does not recognize the following options:")
926N/A for o in self._opts:
2316N/A s += _(" '") + str(o) + _("'")
1431N/A return s
1431N/A
1431N/Aclass IncorrectIndexFileHash(ApiException):
1431N/A """This is used when the index hash value doesn't match the hash of the
1431N/A packages installed in the image."""
1431N/A pass
1431N/A
1431N/A
1431N/Aclass PublisherError(ApiException):
1431N/A """Base exception class for all publisher exceptions."""
1431N/A
2316N/A def __init__(self, *args, **kwargs):
2316N/A ApiException.__init__(self, *args)
1736N/A if args:
1736N/A self.data = args[0]
1736N/A else:
1736N/A self.data = None
1736N/A self._args = kwargs
1736N/A
1736N/A def __str__(self):
1736N/A return str(self.data)
1736N/A
1736N/A
1736N/Aclass BadPublisherMetaRoot(PublisherError):
1736N/A """Used to indicate an operation on the publisher's meta_root failed
1736N/A because the meta_root is invalid."""
1736N/A
1736N/A def __str__(self):
1736N/A return _("Publisher meta_root '{root}' is invalid; unable "
1736N/A "to complete operation: '{op}'.").format(root=self.data,
1736N/A op=self._args.get("operation", None))
1736N/A
1736N/A
1736N/Aclass BadPublisherAlias(PublisherError):
1736N/A """Used to indicate that a publisher alias is not valid."""
1736N/A
1736N/A def __str__(self):
926N/A return _("'{0}' is not a valid publisher alias.").format(
926N/A self.data)
926N/A
926N/A
926N/Aclass BadPublisherPrefix(PublisherError):
926N/A """Used to indicate that a publisher name is not valid."""
926N/A
926N/A def __str__(self):
926N/A return _("'{0}' is not a valid publisher name.").format(
926N/A self.data)
926N/A
926N/A
926N/Aclass ReservedPublisherPrefix(PublisherError):
926N/A """Used to indicate that a publisher name is not valid."""
926N/A
926N/A def __str__(self):
926N/A fmri = self._args["fmri"]
2144N/A return _("'{pkg_pub}' is a reserved publisher and does not "
2144N/A "contain the requested package: pkg:/{pkg_name}").format(
2144N/A pkg_pub=fmri.publisher, pkg_name=fmri.pkg_name)
2144N/A
2144N/A
2144N/Aclass BadRepositoryAttributeValue(PublisherError):
926N/A """Used to indicate that the specified repository attribute value is
926N/A invalid."""
926N/A
926N/A def __str__(self):
926N/A return _("'{value}' is not a valid value for repository "
926N/A "attribute '{attribute}'.").format(
926N/A value=self._args["value"], attribute=self.data)
926N/A
1516N/A
926N/Aclass BadRepositoryCollectionType(PublisherError):
926N/A """Used to indicate that the specified repository collection type is
2310N/A invalid."""
2310N/A
2310N/A def __init__(self, *args, **kwargs):
2310N/A PublisherError.__init__(self, *args, **kwargs)
2310N/A
2310N/A def __str__(self):
2310N/A return _("'{0}' is not a valid repository collection type.").format(
2310N/A self.data)
2367N/A
2335N/A
2335N/Aclass BadRepositoryURI(PublisherError):
2310N/A """Used to indicate that a repository URI is not syntactically valid."""
2310N/A
2310N/A def __str__(self):
2310N/A return _("'{0}' is not a valid URI.").format(self.data)
2310N/A
2310N/A
2310N/Aclass BadRepositoryURIPriority(PublisherError):
2310N/A """Used to indicate that the priority specified for a repository URI is
2310N/A not valid."""
2310N/A
2310N/A def __str__(self):
2310N/A return _("'{0}' is not a valid URI priority; integer value "
2310N/A "expected.").format(self.data)
2310N/A
2026N/A
2026N/Aclass BadRepositoryURISortPolicy(PublisherError):
2026N/A """Used to indicate that the specified repository URI sort policy is
2026N/A invalid."""
2026N/A
2026N/A def __init__(self, *args, **kwargs):
2026N/A PublisherError.__init__(self, *args, **kwargs)
2026N/A
2026N/A def __str__(self):
2026N/A return _("'{0}' is not a valid repository URI sort policy.").format(
2026N/A self.data)
2026N/A
2026N/A
2026N/Aclass DisabledPublisher(PublisherError):
2026N/A """Used to indicate that an attempt to use a disabled publisher occurred
2026N/A during an operation."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Publisher '{0}' is disabled and cannot be used for "
2026N/A "packaging operations.").format(self.data)
2026N/A
2026N/A
2026N/Aclass DuplicatePublisher(PublisherError):
2026N/A """Used to indicate that a publisher with the same name or alias already
2026N/A exists for an image."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("A publisher with the same name or alias as '{0}' "
2026N/A "already exists.").format(self.data)
2026N/A
2026N/A
2026N/Aclass DuplicateRepository(PublisherError):
2200N/A """Used to indicate that a repository with the same origin uris
2026N/A already exists for a publisher."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("A repository with the same name or origin URIs "
2026N/A "already exists for publisher '{0}'.").format(self.data)
2026N/A
2026N/A
2026N/Aclass DuplicateRepositoryMirror(PublisherError):
2026N/A """Used to indicate that a repository URI is already in use by another
2026N/A repository mirror."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Mirror '{0}' already exists for the specified "
2026N/A "publisher.").format(self.data)
2026N/A
2026N/A
2026N/Aclass DuplicateSyspubMirror(PublisherError):
2026N/A """Used to indicate that a repository URI is already in use by the
2026N/A system publisher."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Mirror '{0}' is already accessible through the "
2026N/A "system repository.").format(self.data)
2026N/A
2026N/A
2026N/Aclass DuplicateRepositoryOrigin(PublisherError):
2026N/A """Used to indicate that a repository URI is already in use by another
2026N/A repository origin."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Origin '{0}' already exists for the specified "
2200N/A "publisher.").format(self.data)
2026N/A
2026N/A
2026N/Aclass DuplicateSyspubOrigin(PublisherError):
2026N/A """Used to indicate that a repository URI is already in use by the
2026N/A system publisher."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Origin '{0}' is already accessible through the "
2026N/A "system repository.").format(self.data)
2026N/A
2026N/A
2026N/Aclass RemoveSyspubOrigin(PublisherError):
2026N/A """Used to indicate that a system publisher origin may not be
2026N/A removed."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Unable to remove origin '{0}' since it is provided "
2026N/A "by the system repository.").format(self.data)
2026N/A
2026N/Aclass RemoveSyspubMirror(PublisherError):
2026N/A """Used to indicate that a system publisher mirror may not be
2200N/A removed."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Unable to remove mirror '{0}' since it is provided "
2026N/A "by the system repository.").format(self.data)
2026N/A
2026N/A
2026N/Aclass NoPublisherRepositories(TransportError):
2026N/A """Used to indicate that a Publisher has no repository information
2026N/A configured and so transport operations cannot be performed."""
2026N/A
2026N/A def __init__(self, prefix):
2026N/A TransportError.__init__(self)
2026N/A self.publisher = prefix
2026N/A
2026N/A def __str__(self):
2026N/A return _("""
2026N/AThe requested operation requires that one or more package repositories are
2026N/Aconfigured for publisher '{0}'.
2026N/A
2026N/AUse 'pkg set-publisher' to add new package repositories or restore previously
2026N/Aconfigured package repositories for publisher '{0}'.""").format(self.publisher)
2026N/A
2026N/A
2026N/Aclass MoveRelativeToSelf(PublisherError):
2026N/A """Used to indicate an attempt to search a repo before or after itself"""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Cannot search a repository before or after itself")
2026N/A
2026N/A
2026N/Aclass MoveRelativeToUnknown(PublisherError):
2026N/A """Used to indicate an attempt to order a publisher relative to an
2026N/A unknown publisher."""
2026N/A
2026N/A def __init__(self, unknown_pub):
2026N/A self.__unknown_pub = unknown_pub
2026N/A
2026N/A def __str__(self):
2026N/A return _("{0} is an unknown publisher; no other publishers can "
2026N/A "be ordered relative to it.").format(self.__unknown_pub)
2026N/A
2026N/A
2026N/Aclass SelectedRepositoryRemoval(PublisherError):
2026N/A """Used to indicate that an attempt to remove the selected repository
2026N/A for a publisher was made."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Cannot remove the selected repository for a "
2026N/A "publisher.")
2026N/A
2026N/A
2026N/Aclass UnknownLegalURI(PublisherError):
2026N/A """Used to indicate that no matching legal URI could be found using the
2026N/A provided criteria."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Unknown legal URI '{0}'.").format(self.data)
2026N/A
2026N/A
2026N/Aclass UnknownPublisher(PublisherError):
2026N/A """Used to indicate that no matching publisher could be found using the
2026N/A provided criteria."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("Unknown publisher '{0}'.").format(self.data)
2026N/A
2026N/A
2026N/Aclass UnknownRepositoryPublishers(PublisherError):
2026N/A """Used to indicate that one or more publisher prefixes are unknown by
2026N/A the specified repository."""
2026N/A
2026N/A def __init__(self, known=EmptyI, unknown=EmptyI, location=None,
2026N/A origins=EmptyI):
2026N/A ApiException.__init__(self)
2026N/A self.known = known
2026N/A self.location = location
2026N/A self.origins = origins
2026N/A self.unknown = unknown
2026N/A
2026N/A def __str__(self):
2026N/A if self.location:
2026N/A return _("The repository at {location} does not "
2026N/A "contain package data for {unknown}; only "
2026N/A "{known}.\n\nThis is either because the "
2026N/A "repository location is not valid, or because the "
2026N/A "provided publisher does not match those known by "
2026N/A "the repository.").format(
2026N/A unknown=", ".join(self.unknown),
2026N/A location=self.location,
2026N/A known=", ".join(self.known))
2026N/A if self.origins:
2026N/A return _("One or more of the repository origin(s) "
2026N/A "listed below contains package data for "
2026N/A "{known}; not {unknown}:\n\n{origins}\n\n"
2026N/A "This is either because one of the repository "
2026N/A "origins is not valid for this publisher, or "
2026N/A "because the list of known publishers retrieved "
2026N/A "from the repository origin does not match the "
2026N/A "client.").format(unknown=", ".join(self.unknown),
2026N/A known=", ".join(self.known),
2026N/A origins="\n".join(str(o) for o in self.origins))
2026N/A return _("The specified publisher repository does not "
2026N/A "contain any package data for {unknown}; only "
2026N/A "{known}.").format(unknown=", ".join(self.unknown),
2026N/A known=", ".join(self.known))
2026N/A
2026N/A
2026N/Aclass UnknownRelatedURI(PublisherError):
2215N/A """Used to indicate that no matching related URI could be found using
2215N/A the provided criteria."""
2215N/A
2215N/A def __str__(self):
2215N/A return _("Unknown related URI '{0}'.").format(self.data)
2215N/A
2215N/A
2215N/Aclass UnknownRepository(PublisherError):
2215N/A """Used to indicate that no matching repository could be found using the
2215N/A provided criteria."""
2215N/A
2215N/A def __str__(self):
2215N/A return _("Unknown repository '{0}'.").format(self.data)
2215N/A
2215N/A
2215N/Aclass UnknownRepositoryMirror(PublisherError):
2215N/A """Used to indicate that a repository URI could not be found in the
2215N/A list of repository mirrors."""
2215N/A
2215N/A def __str__(self):
2215N/A return _("Unknown repository mirror '{0}'.").format(self.data)
2215N/A
2215N/Aclass UnsupportedRepositoryOperation(TransportError):
2215N/A """The publisher has no active repositories that support the
2215N/A requested operation."""
2215N/A
2215N/A def __init__(self, pub, operation):
2215N/A ApiException.__init__(self)
2215N/A self.data = None
2215N/A self.kwargs = None
2215N/A self.pub = pub
2215N/A self.op = operation
2215N/A
2215N/A def __str__(self):
2215N/A return _("Publisher '{pub}' has no repositories that support "
2215N/A "the '{op}' operation.").format(**self.__dict__)
2215N/A
2215N/A
2215N/Aclass RepoPubConfigUnavailable(PublisherError):
2215N/A """Used to indicate that the specified repository does not provide
2215N/A publisher configuration information."""
2286N/A
2286N/A def __init__(self, location=None, pub=None):
2286N/A ApiException.__init__(self)
2286N/A self.location = location
2286N/A self.pub = pub
2286N/A
2286N/A def __str__(self):
2286N/A if not self.location and not self.pub:
2286N/A return _("The specified package repository does not "
2286N/A "provide publisher configuration information.")
2286N/A if self.location:
2286N/A return _("The package repository at {0} does not "
2286N/A "provide publisher configuration information or "
2286N/A "the information provided is incomplete.").format(
2286N/A self.location)
2286N/A return _("One of the package repository origins for {0} does "
2286N/A "not provide publisher configuration information or the "
2286N/A "information provided is incomplete.").format(self.pub)
2286N/A
2286N/A
2286N/Aclass UnknownRepositoryOrigin(PublisherError):
2286N/A """Used to indicate that a repository URI could not be found in the
2286N/A list of repository origins."""
2286N/A
2286N/A def __str__(self):
2286N/A return _("Unknown repository origin '{0}'").format(self.data)
2286N/A
2286N/A
2286N/Aclass UnsupportedRepositoryURI(PublisherError):
2286N/A """Used to indicate that the specified repository URI uses an
2286N/A unsupported scheme."""
2286N/A
2286N/A def __init__(self, uris=[]):
2286N/A if isinstance(uris, six.string_types):
2286N/A uris = [uris]
2286N/A
2286N/A assert isinstance(uris, (list, tuple, set))
2286N/A
2286N/A self.uris = uris
2286N/A
2286N/A def __str__(self):
2286N/A illegals = []
2286N/A
2286N/A for u in self.uris:
2286N/A assert isinstance(u, six.string_types)
2286N/A scheme = urlsplit(u,
2286N/A allow_fragments=0)[0]
2286N/A illegals.append((u, scheme))
2286N/A
2286N/A if len(illegals) > 1:
2286N/A msg = _("The follwing URIs use unsupported "
2286N/A "schemes. Supported schemes are "
2286N/A "file://, http://, and https://.")
2286N/A for i, s in illegals:
2286N/A msg += _("\n {uri} (scheme: "
2286N/A "{scheme})").format(uri=i, scheme=s)
2286N/A return msg
2286N/A elif len(illegals) == 1:
2286N/A i, s = illegals[0]
2286N/A return _("The URI '{uri}' uses the unsupported "
2286N/A "scheme '{scheme}'. Supported schemes are "
2286N/A "file://, http://, and https://.").format(
2286N/A uri=i, scheme=s)
2286N/A return _("The specified URI uses an unsupported scheme."
2286N/A " Supported schemes are: file://, http://, and "
2286N/A "https://.")
2286N/A
2286N/A
2026N/Aclass UnsupportedRepositoryURIAttribute(PublisherError):
2026N/A """Used to indicate that the specified repository URI attribute is not
2026N/A supported for the URI's scheme."""
2026N/A
2026N/A def __str__(self):
2026N/A return _("'{attr}' is not supported for '{scheme}'.").format(
2026N/A attr=self.data, scheme=self._args["scheme"])
2026N/A
2026N/A
2026N/Aclass UnsupportedProxyURI(PublisherError):
2026N/A """Used to indicate that the specified proxy URI is unsupported."""
926N/A
926N/A def __str__(self):
926N/A if self.data:
926N/A scheme = urlsplit(self.data,
926N/A allow_fragments=0)[0]
926N/A return _("The proxy URI '{uri}' uses the unsupported "
926N/A "scheme '{scheme}'. Currently the only supported "
926N/A "scheme is http://.").format(
926N/A uri=self.data, scheme=scheme)
1516N/A return _("The specified proxy URI uses an unsupported scheme."
926N/A " Currently the only supported scheme is: http://.")
926N/A
926N/Aclass BadProxyURI(PublisherError):
926N/A """Used to indicate that a proxy URI is not syntactically valid."""
926N/A
926N/A def __str__(self):
926N/A return _("'{0}' is not a valid URI.").format(self.data)
926N/A
926N/A
1516N/Aclass UnknownSysrepoConfiguration(ApiException):
1516N/A """Used when a pkg client needs to communicate with the system
926N/A repository but can't find the configuration for it."""
926N/A
926N/A def __str__(self):
926N/A return _("""\
926N/Apkg is configured to use the system repository (via the use-system-repo
926N/Aproperty) but it could not get the host and port from
1130N/Asvc:/application/pkg/zones-proxy-client nor svc:/application/pkg/system-repository, and
926N/Athe PKG_SYSREPO_URL environment variable was not set. Please try enabling one
926N/Aof those services or setting the PKG_SYSREPO_URL environment variable.
926N/A""")
926N/A
926N/A
926N/Aclass ModifyingSyspubException(ApiException):
926N/A """This exception is raised when a user attempts to modify a system
926N/A publisher."""
926N/A
926N/A def __init__(self, s):
926N/A self.s = s
926N/A
926N/A def __str__(self):
926N/A return self.s
926N/A
926N/A
1516N/Aclass SigningException(ApiException):
1516N/A """The base class for exceptions related to manifest signing."""
1516N/A
926N/A def __init__(self, pfmri=None, sig=None):
926N/A self.pfmri = pfmri
926N/A self.sig = sig
926N/A
926N/A # This string method is used by subclasses to fill in the details
926N/A # about the package and signature involved.
926N/A def __str__(self):
926N/A if self.pfmri:
926N/A if self.sig:
926N/A return _("The relevant signature action is "
926N/A "found in {pfmri} and has a hash of "
926N/A "{hsh}").format(
926N/A pfmri=self.pfmri, hsh=self.sig.hash)
926N/A return _("The package involved is {0}").format(
926N/A self.pfmri)
926N/A if self.sig:
926N/A return _("The relevant signature action's value "
926N/A "attribute is {0}").format(self.sig.attrs["value"])
926N/A return ""
926N/A
926N/A
926N/Aclass BadFileFormat(SigningException):
1516N/A """Exception used when a key, certificate or CRL file is not in a
1516N/A recognized format."""
926N/A
926N/A def __init__(self, txt):
926N/A self.txt = txt
926N/A
926N/A def __str__(self):
926N/A return self.txt
926N/A
926N/A
926N/Aclass UnsupportedSignatureVersion(SigningException):
926N/A """Exception used when a signature reports a version which this version
926N/A of pkg(7) doesn't support."""
926N/A
926N/A def __init__(self, version, *args, **kwargs):
926N/A SigningException.__init__(self, *args, **kwargs)
926N/A self.version = version
926N/A
1254N/A def __str__(self):
1254N/A return _("The signature action {act} was made using a "
1254N/A "version ({ver}) this version of pkg(7) doesn't "
1254N/A "understand.").format(act=self.sig, ver=self.version)
1516N/A
1516N/A
1254N/Aclass CertificateException(SigningException):
1254N/A """Base class for exceptions encountered while establishing the chain
1254N/A of trust."""
1254N/A
1254N/A def __init__(self, cert, pfmri=None):
1254N/A SigningException.__init__(self, pfmri)
1254N/A self.cert = cert
1254N/A
1254N/A
1254N/Aclass ModifiedCertificateException(CertificateException):
1254N/A """Exception used when a certificate does not match its expected hash
1254N/A value."""
1254N/A
1254N/A def __init__(self, cert, path, pfmri=None):
1254N/A CertificateException.__init__(self, cert, pfmri)
1254N/A self.path = path
926N/A
926N/A def __str__(self):
926N/A return _("Certificate {0} has been modified on disk. Its hash "
926N/A "value is not what was expected.").format(self.path)
1516N/A
1516N/A
926N/Aclass UntrustedSelfSignedCert(CertificateException):
926N/A """Exception used when a chain of trust is rooted in an untrusted
926N/A self-signed certificate."""
926N/A
926N/A def __str__(self):
926N/A return _("Chain was rooted in an untrusted self-signed "
926N/A "certificate.\n") + CertificateException.__str__(self)
926N/A
926N/A
926N/Aclass BrokenChain(CertificateException):
926N/A """Exception used when a chain of trust can not be established between
926N/A the leaf certificate and a trust anchor."""
926N/A
926N/A def __init__(self, cert, cert_exceptions, *args, **kwargs):
926N/A CertificateException.__init__(self, cert, *args, **kwargs)
926N/A self.ext_exs = cert_exceptions
926N/A
926N/A def __str__(self):
926N/A s = ""
926N/A if self.ext_exs:
926N/A s = _("The following problems were encountered:\n") + \
926N/A "\n".join([str(e) for e in self.ext_exs])
1516N/A return _("The certificate which issued this "
1516N/A "certificate: {subj} could not be found. The issuer "
926N/A "is: {issuer}\n").format(subj="/".join("{0}={1}".format(
926N/A sub.oid._name, sub.value) for sub in self.cert.subject),
926N/A issuer="/".join("{0}={1}".format(i.oid._name, i.value)
926N/A for i in self.cert.issuer)) + s + "\n" + \
926N/A CertificateException.__str__(self)
926N/A
926N/A
926N/Aclass RevokedCertificate(CertificateException):
926N/A """Exception used when a chain of trust contains a revoked certificate.
926N/A """
926N/A
926N/A def __init__(self, cert, reason, *args, **kwargs):
926N/A CertificateException.__init__(self, cert, *args, **kwargs)
926N/A self.reason = reason
926N/A
926N/A def __str__(self):
941N/A return _("This certificate was revoked:{cert} for this "
941N/A "reason:\n{reason}\n").format(cert="/".join("{0}={1}".format(
941N/A s.oid._name, s.value) for s in self.cert.subject),
2028N/A reason=self.reason) + CertificateException.__str__(self)
1100N/A
1100N/A
941N/Aclass UnverifiedSignature(SigningException):
941N/A """Exception used when a signature could not be verified by the
941N/A expected certificate."""
941N/A
941N/A def __init__(self, sig, reason, pfmri=None):
1027N/A SigningException.__init__(self, pfmri)
1337N/A self.sig = sig
1352N/A self.reason = reason
1337N/A
1337N/A def __str__(self):
1337N/A if self.pfmri:
1337N/A return _("A signature in {pfmri} could not be "
1337N/A "verified for "
1337N/A "this reason:\n{reason}\nThe signature's hash is "
1337N/A "{hash}").format(pfmri=self.pfmri,
1337N/A reason=self.reason,
1337N/A hash=self.sig.hash)
1352N/A return _("The signature with this signature value:\n"
1352N/A "{sigval}\n could not be verified for this reason:\n"
1352N/A "{reason}\n").format(reason=self.reason,
1352N/A sigval=self.sig.attrs["value"])
1352N/A
1352N/A
1352N/Aclass RequiredSignaturePolicyException(SigningException):
1352N/A """Exception used when signatures were required but none were found."""
1352N/A
1352N/A def __init__(self, pub, pfmri=None):
1352N/A SigningException.__init__(self, pfmri)
1516N/A self.pub = pub
1352N/A
1352N/A def __str__(self):
1352N/A pub_str = self.pub.prefix
1352N/A if self.pfmri:
1352N/A return _("The policy for {pub_str} requires "
1352N/A "signatures to be present but no signature was "
1352N/A "found in {fmri_str}.").format(
1352N/A pub_str=pub_str, fmri_str=self.pfmri)
1352N/A return _("The policy for {pub_str} requires signatures to be "
1352N/A "present but no signature was found.").format(
1352N/A pub_str=pub_str)
1352N/A
1352N/A
1370N/Aclass MissingRequiredNamesException(SigningException):
1736N/A """Exception used when a signature policy required names to be seen
1736N/A which weren't seen."""
1736N/A
1736N/A def __init__(self, pub, missing_names, pfmri=None):
1736N/A SigningException.__init__(self, pfmri)
1736N/A self.pub = pub
1736N/A self.missing_names = missing_names
1736N/A
1736N/A def __str__(self):
1736N/A pub_str = self.pub.prefix
1736N/A if self.pfmri:
1736N/A return _("The policy for {pub_str} requires certain "
1736N/A "CNs to be seen in a chain of trust. The following "
1736N/A "required names couldn't be found for this "
1736N/A "package:{fmri_str}.\n{missing}").format(
1736N/A pub_str=pub_str, fmri_str=self.pfmri,
1370N/A missing="\n".join(self.missing_names))
1370N/A return _("The policy for {pub_str} requires certain CNs to "
1370N/A "be seen in a chain of trust. The following required names "
1736N/A "couldn't be found.\n{missing}").format(pub_str=pub_str,
1370N/A missing="\n".join(self.missing_names))
1370N/A
1370N/Aclass UnsupportedCriticalExtension(SigningException):
1370N/A """Exception used when a certificate in the chain of trust uses a
1370N/A critical extension pkg doesn't understand."""
1370N/A
1370N/A def __init__(self, cert, ext):
1370N/A SigningException.__init__(self)
1370N/A self.cert = cert
1370N/A self.ext = ext
1370N/A
1370N/A def __str__(self):
2097N/A return _("The certificate whose subject is {cert} could not "
2097N/A "be verified because it uses an unsupported critical "
2097N/A "extension.\nExtension name: {name}\nExtension "
2097N/A "value: {val}").format(cert="/".join("{0}={1}".format(
2144N/A s.oid._name, s.value) for s in self.cert.subject),
2144N/A name=self.ext.oid._name, val=self.ext.value)
2144N/A
2144N/Aclass InvalidCertificateExtensions(SigningException):
2144N/A """Exception used when a certificate in the chain of trust has
2144N/A invalid extensions."""
2144N/A
2144N/A def __init__(self, cert, error):
2144N/A SigningException.__init__(self)
2144N/A self.cert = cert
2144N/A self.error = error
2144N/A
2144N/A def __str__(self):
2144N/A s = _("The certificate whose subject is {cert} could not be "
2144N/A "verified because it has invalid extensions:\n{error}"
2144N/A ).format(cert="/".join("{0}={1}".format(
2097N/A s.oid._name, s.value) for s in self.cert.subject),
2097N/A error=self.error)
1370N/A return s
1370N/A
1370N/Aclass InappropriateCertificateUse(SigningException):
1370N/A """Exception used when a certificate in the chain of trust has been used
2026N/A inappropriately. An example would be a certificate which was only
2026N/A supposed to be used to sign code being used to sign other certificates.
2073N/A """
2073N/A
2073N/A def __init__(self, cert, ext, use, val):
2073N/A SigningException.__init__(self)
2073N/A self.cert = cert
2073N/A self.ext = ext
2073N/A self.use = use
2073N/A self.val = val
2073N/A
2073N/A def __str__(self):
2073N/A return _("The certificate whose subject is {cert} could not "
2026N/A "be verified because it has been used inappropriately. "
2026N/A "The way it is used means that the value for extension "
2026N/A "{name} must include '{use}' but the value was "
2026N/A "'{val}'.").format(cert="/".join("{0}={1}".format(
2026N/A s.oid._name, s.value) for s in self.cert.subject),
2026N/A use=self.use, name=self.ext.oid._name,
2026N/A val=self.val)
2339N/A
2339N/Aclass PathlenTooShort(InappropriateCertificateUse):
2339N/A """Exception used when a certificate in the chain of trust has been used
2339N/A inappropriately. An example would be a certificate which was only
2339N/A supposed to be used to sign code being used to sign other certificates.
2339N/A """
2339N/A
2339N/A def __init__(self, cert, actual_length, cert_length):
2339N/A SigningException.__init__(self)
2339N/A self.cert = cert
2339N/A self.al = actual_length
2339N/A self.cl = cert_length
2339N/A
2339N/A def __str__(self):
2339N/A return _("The certificate whose subject is {cert} could not "
2339N/A "be verified because it has been used inappropriately. "
2339N/A "There can only be {cl} certificates between this "
2339N/A "certificate and the leaf certificate. There are {al} "
2410N/A "certificates between this certificate and the leaf in "
2339N/A "this chain.").format(
2339N/A cert="/".join("{0}={1}".format(
2339N/A s.oid._name, s.value) for s in self.cert.subject),
2339N/A al=self.al,
2339N/A cl=self.cl
2339N/A )
2339N/A
2339N/A
2339N/Aclass AlmostIdentical(ApiException):
2339N/A """Exception used when a package already has a signature action which is
2339N/A nearly identical to the one being added but differs on some
2339N/A attributes."""
2339N/A
2339N/A def __init__(self, hsh, algorithm, version, pkg=None):
2339N/A self.hsh = hsh
2339N/A self.algorithm = algorithm
2339N/A self.version = version
2339N/A self.pkg = pkg
2339N/A
2339N/A def __str__(self):
2339N/A s = _("The signature to be added to the package has the same "
2339N/A "hash ({hash}), algorithm ({algorithm}), and "
2339N/A "version ({version}) as an existing signature, but "
2339N/A "doesn't match the signature exactly. For this signature "
2339N/A "to be added, the existing signature must be removed.").format(
2339N/A hash=self.hsh,
2339N/A algorithm=self.algorithm,
2410N/A version=self.version
2339N/A )
2339N/A if self.pkg:
2339N/A s += _("The package being signed was {pkg}").format(
2339N/A pkg=self.pkg)
2339N/A return s
2339N/A
2339N/A
2339N/Aclass DuplicateSignaturesAlreadyExist(ApiException):
2339N/A """Exception used when a package already has a signature action which is
2339N/A nearly identical to the one being added but differs on some
2339N/A attributes."""
2339N/A
2339N/A def __init__(self, pfmri):
2339N/A self.pfmri = pfmri
2339N/A
2339N/A def __str__(self):
2339N/A return _("{0} could not be signed because it already has two "
2339N/A "copies of this signature in it. One of those signature "
2339N/A "actions must be removed before the package is given to "
2339N/A "users.").format(self.pfmri)
2339N/A
2339N/A
2339N/Aclass InvalidPropertyValue(ApiException):
2339N/A """Exception used when a property was set to an invalid value."""
2339N/A
2339N/A def __init__(self, s):
2339N/A ApiException.__init__(self)
2339N/A self.str = s
2339N/A
2339N/A def __str__(self):
2339N/A return self.str
2339N/A
2339N/A
2339N/Aclass CertificateError(ApiException):
2339N/A """Base exception class for all certificate exceptions."""
2339N/A
2339N/A def __init__(self, *args, **kwargs):
2339N/A ApiException.__init__(self, *args)
2339N/A if args:
2339N/A self.data = args[0]
2339N/A else:
2339N/A self.data = None
2339N/A self._args = kwargs
2339N/A
2339N/A def __str__(self):
2339N/A return str(self.data)
2339N/A
2339N/A
2339N/Aclass ExpiredCertificate(CertificateError):
2339N/A """Used to indicate that a certificate has expired."""
2339N/A
2339N/A def __init__(self, *args, **kwargs):
2339N/A CertificateError.__init__(self, *args, **kwargs)
2339N/A self.publisher = self._args.get("publisher", None)
2339N/A self.uri = self._args.get("uri", None)
2339N/A
2339N/A def __str__(self):
2339N/A if self.publisher:
2339N/A if self.uri:
2339N/A return _("Certificate '{cert}' for publisher "
2339N/A "'{pub}' needed to access '{uri}', "
2339N/A "has expired. Please install a valid "
2339N/A "certificate.").format(cert=self.data,
2339N/A pub=self.publisher, uri=self.uri)
2339N/A return _("Certificate '{cert}' for publisher "
2339N/A "'{pub}', has expired. Please install a valid "
2339N/A "certificate.").format(cert=self.data,
2339N/A pub=self.publisher)
2339N/A if self.uri:
2339N/A return _("Certificate '{cert}', needed to access "
2339N/A "'{uri}', has expired. Please install a valid "
2339N/A "certificate.").format(cert=self.data,
2339N/A uri=self.uri)
2339N/A return _("Certificate '{0}' has expired. Please install a "
2339N/A "valid certificate.").format(self.data)
2339N/A
2339N/A
2339N/Aclass ExpiredCertificates(CertificateError):
2339N/A """Used to collect ExpiredCertficate exceptions."""
2339N/A
2339N/A def __init__(self, errors):
2339N/A
2339N/A self.errors = []
2339N/A
2339N/A assert (isinstance(errors, (list, tuple,
2339N/A set, ExpiredCertificate)))
2339N/A
2339N/A if isinstance(errors, ExpiredCertificate):
2339N/A self.errors.append(errors)
2339N/A else:
2339N/A self.errors = errors
2339N/A
2339N/A def __str__(self):
2339N/A pdict = dict()
2339N/A for e in self.errors:
2339N/A if e.publisher in pdict:
2339N/A pdict[e.publisher].append(e.uri)
2339N/A else:
2339N/A pdict[e.publisher] = [e.uri]
2339N/A
2339N/A msg = ""
2339N/A for pub, uris in pdict.items():
2339N/A msg += "\n{0}:".format(_("Publisher"))
2339N/A msg += " {0}".format(pub)
2339N/A for uri in uris:
2339N/A msg += "\n {0}:\n".format(_("Origin URI"))
2339N/A msg += " {0}\n".format(uri)
2339N/A msg += " {0}:\n".format(_("Certificate"))
2339N/A msg += " {0}\n".format(uri.ssl_cert)
2339N/A msg += " {0}:\n".format(_("Key"))
2339N/A msg += " {0}\n".format(uri.ssl_key)
2339N/A return _("One or more client key and certificate files have "
2339N/A "expired. Please\nupdate the configuration for the "
2339N/A "publishers or origins listed below:\n {0}").format(msg)
2339N/A
2339N/A
2339N/Aclass ExpiringCertificate(CertificateError):
2339N/A """Used to indicate that a certificate has expired."""
2339N/A
2410N/A def __str__(self):
2410N/A publisher = self._args.get("publisher", None)
2410N/A uri = self._args.get("uri", None)
2410N/A days = self._args.get("days", 0)
2410N/A if publisher:
2410N/A if uri:
2410N/A return _("Certificate '{cert}' for publisher "
2410N/A "'{pub}', needed to access '{uri}', "
2410N/A "will expire in '{days}' days.").format(
2410N/A cert=self.data, pub=publisher,
2410N/A uri=uri, days=days)
2410N/A return _("Certificate '{cert}' for publisher "
2410N/A "'{pub}' will expire in '{days}' days.").format(
2410N/A cert=self.data, pub=publisher, days=days)
2410N/A if uri:
2410N/A return _("Certificate '{cert}', needed to access "
2410N/A "'{uri}', will expire in '{days}' days.").format(
2410N/A cert=self.data, uri=uri, days=days)
2410N/A return _("Certificate '{cert}' will expire in "
2410N/A "'{days}' days.").format(cert=self.data, days=days)
2339N/A
2339N/A
2339N/Aclass InvalidCertificate(CertificateError):
2339N/A """Used to indicate that a certificate is invalid."""
2339N/A
2339N/A def __str__(self):
2339N/A publisher = self._args.get("publisher", None)
2339N/A uri = self._args.get("uri", None)
2339N/A if publisher:
2339N/A if uri:
2339N/A return _("Certificate '{cert}' for publisher "
2339N/A "'{pub}', needed to access '{uri}', is "
2339N/A "invalid.").format(cert=self.data,
2339N/A pub=publisher, uri=uri)
2339N/A return _("Certificate '{cert}' for publisher "
2339N/A "'{pub}' is invalid.").format(cert=self.data,
2339N/A pub=publisher)
2339N/A if uri:
2339N/A return _("Certificate '{cert}' needed to access "
2339N/A "'{uri}' is invalid.").format(cert=self.data,
2339N/A uri=uri)
2339N/A return _("Invalid certificate '{0}'.").format(self.data)
2339N/A
2339N/A
2339N/Aclass NoSuchKey(CertificateError):
2339N/A """Used to indicate that a key could not be found."""
2339N/A
2339N/A def __str__(self):
2339N/A publisher = self._args.get("publisher", None)
2339N/A uri = self._args.get("uri", None)
2339N/A if publisher:
2339N/A if uri:
2339N/A return _("Unable to locate key '{key}' for "
2339N/A "publisher '{pub}' needed to access "
2339N/A "'{uri}'.").format(key=self.data,
2339N/A pub=publisher, uri=uri)
2339N/A return _("Unable to locate key '{key}' for publisher "
2339N/A "'{pub}'.").format(key=self.data, pub=publisher
2339N/A )
2339N/A if uri:
2339N/A return _("Unable to locate key '{key}' needed to "
2339N/A "access '{uri}'.").format(key=self.data,
2339N/A uri=uri)
2339N/A return _("Unable to locate key '{0}'.").format(self.data)
2339N/A
2339N/A
2339N/Aclass NoSuchCertificate(CertificateError):
2339N/A """Used to indicate that a certificate could not be found."""
2339N/A
2339N/A def __str__(self):
2339N/A publisher = self._args.get("publisher", None)
2339N/A uri = self._args.get("uri", None)
2339N/A if publisher:
2339N/A if uri:
2339N/A return _("Unable to locate certificate "
2339N/A "'{cert}' for publisher '{pub}' needed "
2339N/A "to access '{uri}'.").format(
2339N/A cert=self.data, pub=publisher,
2339N/A uri=uri)
2339N/A return _("Unable to locate certificate '{cert}' for "
2339N/A "publisher '{pub}'.").format(cert=self.data,
2339N/A pub=publisher)
2339N/A if uri:
2339N/A return _("Unable to locate certificate '{cert}' "
2339N/A "needed to access '{uri}'.").format(
2339N/A cert=self.data, uri=uri)
2339N/A return _("Unable to locate certificate '{0}'.").format(
2339N/A self.data)
2339N/A
2339N/A
2339N/Aclass NotYetValidCertificate(CertificateError):
2339N/A """Used to indicate that a certificate is not yet valid (future
2339N/A effective date)."""
2339N/A
2339N/A def __str__(self):
2339N/A publisher = self._args.get("publisher", None)
2339N/A uri = self._args.get("uri", None)
2339N/A if publisher:
2339N/A if uri:
2339N/A return _("Certificate '{cert}' for publisher "
2339N/A "'{pub}', needed to access '{uri}', "
2339N/A "has a future effective date.").format(
cert=self.data, pub=publisher,
uri=uri)
return _("Certificate '{cert}' for publisher "
"'{pub}' has a future effective date.").format(
cert=self.data, pub=publisher)
if uri:
return _("Certificate '{cert}' needed to access "
"'{uri}' has a future effective date.").format(
cert=self.data, uri=uri)
return _("Certificate '{0}' has a future effective date.").format(
self.data)
class ServerReturnError(ApiException):
"""This exception is used when the server returns a line which the
client cannot parse correctly."""
def __init__(self, line):
ApiException.__init__(self)
self.line = line
def __str__(self):
return _("Gave a bad response:{0}").format(self.line)
class MissingFileArgumentException(ApiException):
"""This exception is used when a file was given as an argument but
no such file could be found."""
def __init__(self, path):
ApiException.__init__(self)
self.path = path
def __str__(self):
return _("Could not find {0}").format(self.path)
class ManifestError(ApiException):
"""Base exception class for all manifest exceptions."""
def __init__(self, *args, **kwargs):
ApiException.__init__(self, *args, **kwargs)
if args:
self.data = args[0]
else:
self.data = None
self._args = kwargs
def __str__(self):
return str(self.data)
class BadManifestSignatures(ManifestError):
"""Used to indicate that the Manifest signatures are not valid."""
def __str__(self):
if self.data:
return _("The signature data for the manifest of the "
"'{0}' package is not valid.").format(self.data)
return _("The signature data for the manifest is not valid.")
class UnknownErrors(ApiException):
"""Used to indicate that one or more exceptions were encountered.
This is intended for use with where multiple exceptions for multiple
files are encountered and the errors have been condensed into a
single exception and re-raised. One example case would be rmtree()
with shutil.Error."""
def __init__(self, msg):
ApiException.__init__(self)
self.__msg = msg
def __str__(self):
return self.__msg
# Image creation exceptions
class ImageCreationException(ApiException):
def __init__(self, path):
ApiException.__init__(self)
self.path = path
def __str__(self):
raise NotImplementedError()
class ImageAlreadyExists(ImageCreationException):
def __str__(self):
return _("there is already an image at: {0}.\nTo override, use "
"the -f (force) option.").format(self.path)
class ImageCfgEmptyError(ApiException):
"""Used to indicate that the image configuration is invalid."""
def __str__(self):
return _("The configuration data for the image rooted at "
"{0} is empty or missing.").format(self.data)
class UnsupportedImageError(ApiException):
"""Used to indicate that the image at a specific location is in a format
not supported by this version of the pkg(7) API."""
def __init__(self, path):
ApiException.__init__(self)
self.path = path
def __str__(self):
return _("The image rooted at {0} is invalid or is not "
"supported by this version of the packaging system.").format(
self.path)
class CreatingImageInNonEmptyDir(ImageCreationException):
def __str__(self):
return _("the specified image path is not empty: {0}.\nTo "
"override, use the -f (force) option.").format(self.path)
def _convert_error(e, ignored_errors=EmptyI):
"""Converts the provided exception into an ApiException equivalent if
possible. Returns a new exception object if converted or the original
if not.
'ignored_errors' is an optional list of errno values for which None
should be returned.
"""
if not hasattr(e, "errno"):
return e
if e.errno in ignored_errors:
return None
if e.errno in (errno.EACCES, errno.EPERM):
return PermissionsException(e.filename)
if e.errno == errno.EROFS:
return ReadOnlyFileSystemException(e.filename)
return e
class LinkedImageException(ApiException):
def __init__(self, bundle=None, lin=None, exitrv=None,
attach_bad_prop=None,
attach_bad_prop_value=None,
attach_child_notsup=None,
attach_parent_notsup=None,
attach_root_as_child=None,
attach_with_curpath=None,
child_bad_img=None,
child_diverged=None,
child_dup=None,
child_not_in_altroot=None,
child_not_nested=None,
child_op_failed=None,
child_path_notabs=None,
child_unknown=None,
cmd_failed=None,
cmd_output_invalid=None,
detach_child_notsup=None,
detach_from_parent=None,
detach_parent_notsup=None,
img_linked=None,
intermediate_image=None,
lin_malformed=None,
link_to_self=None,
parent_bad_img=None,
parent_bad_notabs=None,
parent_bad_path=None,
parent_nested=None,
parent_not_in_altroot=None,
pkg_op_failed=None,
self_linked=None,
self_not_child=None,
unparsable_output=None):
self.attach_bad_prop = attach_bad_prop
self.attach_bad_prop_value = attach_bad_prop_value
self.attach_child_notsup = attach_child_notsup
self.attach_parent_notsup = attach_parent_notsup
self.attach_root_as_child = attach_root_as_child
self.attach_with_curpath = attach_with_curpath
self.child_bad_img = child_bad_img
self.child_diverged = child_diverged
self.child_dup = child_dup
self.child_not_in_altroot = child_not_in_altroot
self.child_not_nested = child_not_nested
self.child_op_failed = child_op_failed
self.child_path_notabs = child_path_notabs
self.child_unknown = child_unknown
self.cmd_failed = cmd_failed
self.cmd_output_invalid = cmd_output_invalid
self.detach_child_notsup = detach_child_notsup
self.detach_from_parent = detach_from_parent
self.detach_parent_notsup = detach_parent_notsup
self.img_linked = img_linked
self.intermediate_image = intermediate_image
self.lin_malformed = lin_malformed
self.link_to_self = link_to_self
self.parent_bad_img = parent_bad_img
self.parent_bad_notabs = parent_bad_notabs
self.parent_bad_path = parent_bad_path
self.parent_nested = parent_nested
self.parent_not_in_altroot = parent_not_in_altroot
self.pkg_op_failed = pkg_op_failed
self.self_linked = self_linked
self.self_not_child = self_not_child
self.unparsable_output = unparsable_output
# first deal with an error bundle
if bundle:
assert type(bundle) in [tuple, list, set]
for e in bundle:
assert isinstance(e, LinkedImageException)
# set default error return value
if exitrv == None:
exitrv = pkgdefs.EXIT_OOPS
self.lix_err = None
self.lix_bundle = bundle
self.lix_exitrv = exitrv
return
err = None
if attach_bad_prop is not None:
err = _("Invalid linked image attach property: {0}").format(
attach_bad_prop)
if attach_bad_prop_value is not None:
assert type(attach_bad_prop_value) in [tuple, list]
assert len(attach_bad_prop_value) == 2
err = _("Invalid linked image attach property "
"value: {0}").format(
"=".join(attach_bad_prop_value))
if attach_child_notsup is not None:
err = _("Linked image type does not support child "
"attach: {0}").format(attach_child_notsup)
if attach_parent_notsup is not None:
err = _("Linked image type does not support parent "
"attach: {0}").format(attach_parent_notsup)
if attach_root_as_child is not None:
err = _("Cannot attach root image as child: {0}".format(
attach_root_as_child))
if attach_with_curpath is not None:
path, curpath = attach_with_curpath
err = _("Cannot link images when an image is not at "
"its default location. The image currently "
"located at:\n {curpath}\n"
"is normally located at:\n {path}\n").format(
path=path,
curpath=curpath,
)
if child_bad_img is not None:
if exitrv == None:
exitrv = pkgdefs.EXIT_EACCESS
if lin:
err = _("Can't initialize child image "
"({lin}) at path: {path}").format(
lin=lin,
path=child_bad_img
)
else:
err = _("Can't initialize child image "
"at path: {0}").format(child_bad_img)
if child_diverged is not None:
if exitrv == None:
exitrv = pkgdefs.EXIT_DIVERGED
err = _("Linked image is diverged: {0}").format(
child_diverged)
if child_dup is not None:
err = _("A linked child image with this name "
"already exists: {0}").format(child_dup)
if child_not_in_altroot is not None:
path, altroot = child_not_in_altroot
err = _("Child image '{path}' is not located "
"within the parent's altroot '{altroot}'").format(
path=path,
altroot=altroot
)
if child_not_nested is not None:
cpath, ppath = child_not_nested
err = _("Child image '{cpath}' is not nested "
"within the parent image '{ppath}'").format(
cpath=cpath,
ppath=ppath,
)
if child_op_failed is not None:
op, cpath, e = child_op_failed
if exitrv == None:
exitrv = pkgdefs.EXIT_EACCESS
if lin:
err = _("Failed '{op}' for child image "
"({lin}) at path: {path}: "
"{strerror}").format(
op=op,
lin=lin,
path=cpath,
strerror=e,
)
else:
err = _("Failed '{op}' for child image "
"at path: {path}: {strerror}").format(
op=op,
path=cpath,
strerror=e,
)
if child_path_notabs is not None:
err = _("Child path not absolute: {0}").format(
child_path_notabs)
if child_unknown is not None:
err = _("Unknown child linked image: {0}").format(
child_unknown)
if cmd_failed is not None:
(rv, cmd, errout) = cmd_failed
err = _("The following subprocess returned an "
"unexpected exit code of {rv:d}:\n {cmd}").format(
rv=rv, cmd=cmd)
if errout:
err += _("\nAnd generated the following error "
"message:\n{errout}".format(errout=errout))
if cmd_output_invalid is not None:
(cmd, output) = cmd_output_invalid
err = _(
"The following subprocess:\n"
" {cmd}\n"
"Generated the following unexpected output:\n"
"{output}\n".format(
cmd=" ".join(cmd), output="\n".join(output)))
if detach_child_notsup is not None:
err = _("Linked image type does not support "
"child detach: {0}").format(detach_child_notsup)
if detach_from_parent is not None:
if exitrv == None:
exitrv = pkgdefs.EXIT_PARENTOP
err = _("Parent linked to child, can not detach "
"child: {0}").format(detach_from_parent)
if detach_parent_notsup is not None:
err = _("Linked image type does not support "
"parent detach: {0}").format(detach_parent_notsup)
if img_linked is not None:
err = _("Image already a linked child: {0}").format(
img_linked)
if intermediate_image is not None:
ppath, cpath, ipath = intermediate_image
err = _(
"Intermediate image '{ipath}' found between "
"child '{cpath}' and "
"parent '{ppath}'").format(
ppath=ppath,
cpath=cpath,
ipath=ipath,
)
if lin_malformed is not None:
err = _("Invalid linked image name '{0}'. "
"Linked image names have the following format "
"'<linked_image plugin>:<linked_image name>'").format(
lin_malformed)
if link_to_self is not None:
err = _("Can't link image to itself: {0}")
if parent_bad_img is not None:
if exitrv == None:
exitrv = pkgdefs.EXIT_EACCESS
err = _("Can't initialize parent image at path: {0}").format(
parent_bad_img)
if parent_bad_notabs is not None:
err = _("Parent path not absolute: {0}").format(
parent_bad_notabs)
if parent_bad_path is not None:
if exitrv == None:
exitrv = pkgdefs.EXIT_EACCESS
err = _("Can't access parent image at path: {0}").format(
parent_bad_path)
if parent_nested is not None:
ppath, cpath = parent_nested
err = _("A parent image '{ppath}' can not be nested "
"within a child image '{cpath}'").format(
ppath=ppath,
cpath=cpath,
)
if parent_not_in_altroot is not None:
path, altroot = parent_not_in_altroot
err = _("Parent image '{path}' is not located "
"within the child's altroot '{altroot}'").format(
path=path,
altroot=altroot
)
if pkg_op_failed is not None:
assert lin
(op, exitrv, errout, e) = pkg_op_failed
assert op is not None
if e is None:
err = _("""
A '{op}' operation failed for child '{lin}' with an unexpected
return value of {exitrv:d} and generated the following output:
{errout}
"""
).format(
lin=lin,
op=op,
exitrv=exitrv,
errout=errout,
)
else:
err = _("""
A '{op}' operation failed for child '{lin}' with an unexpected
exception:
{e}
The child generated the following output:
{errout}
"""
).format(
lin=lin,
op=op,
errout=errout,
e=e,
)
if self_linked is not None:
err = _("Current image already a linked child: {0}").format(
self_linked)
if self_not_child is not None:
if exitrv == None:
exitrv = pkgdefs.EXIT_NOPARENT
err = _("Current image is not a linked child: {0}").format(
self_not_child)
if unparsable_output is not None:
(op, errout, e) = unparsable_output
err = _("""
A '{op}' operation for child '{lin}' generated non-json output.
The json parser failed with the following error:
{e}
The child generated the following output:
{errout}
"""
).format(
lin=lin,
op=op,
e=e,
errout=errout,
)
# set default error return value
if exitrv == None:
exitrv = pkgdefs.EXIT_OOPS
self.lix_err = err
self.lix_bundle = None
self.lix_exitrv = exitrv
def __str__(self):
assert self.lix_err or self.lix_bundle
assert not (self.lix_err and self.lix_bundle), \
"self.lix_err = {0}, self.lix_bundle = {1}".format(
str(self.lix_err), str(self.lix_bundle))
# single error
if self.lix_err:
return self.lix_err
# concatenate multiple errors
bundle_str = []
for e in self.lix_bundle:
bundle_str.append(str(e))
return "\n".join(bundle_str)
class FreezePkgsException(ApiException):
"""Used if an argument to pkg freeze isn't valid."""
def __init__(self, multiversions=None, unmatched_wildcards=None,
version_mismatch=None, versionless_uninstalled=None):
ApiException.__init__(self)
self.multiversions = multiversions
self.unmatched_wildcards = unmatched_wildcards
self.version_mismatch = version_mismatch
self.versionless_uninstalled = versionless_uninstalled
def __str__(self):
res = []
if self.multiversions:
s = _("""\
The following packages were frozen at two different versions by
the patterns provided. The package stem and the versions it was frozen at are
provided:""")
res += [s]
res += ["\t{0}\t{1}".format(stem, " ".join([
str(v) for v in sorted(versions)]))
for stem, versions in sorted(self.multiversions)]
if self.unmatched_wildcards:
s = _("""\
The following patterns contained wildcards but matched no
installed packages.""")
res += [s]
res += ["\t{0}".format(pat) for pat in sorted(
self.unmatched_wildcards)]
if self.version_mismatch:
s = _("""\
The following patterns attempted to freeze the listed packages
at a version different from the version at which the packages are installed.""")
res += [s]
for pat in sorted(self.version_mismatch):
res += ["\t{0}".format(pat)]
if len(self.version_mismatch[pat]) > 1:
res += [
"\t\t{0}".format(stem)
for stem
in sorted(self.version_mismatch[pat])
]
if self.versionless_uninstalled:
s = _("""\
The following patterns don't match installed packages and
contain no version information. Uninstalled packages can only be frozen by
providing a version at which to freeze them.""")
res += [s]
res += ["\t{0}".format(p) for p in sorted(
self.versionless_uninstalled)]
return "\n".join(res)
class InvalidFreezeFile(ApiException):
"""Used to indicate the freeze state file could not be loaded."""
def __str__(self):
return _("The freeze state file '{0}' is invalid.").format(
self.data)
class UnknownFreezeFileVersion(ApiException):
"""Used when the version on the freeze state file isn't the version
that's expected."""
def __init__(self, found_ver, expected_ver, location):
self.found = found_ver
self.expected = expected_ver
self.loc = location
def __str__(self):
return _("The freeze state file '{loc}' was expected to have "
"a version of {exp}, but its version was {found}").format(
exp=self.expected,
found=self.found,
loc=self.loc,
)
class InvalidOptionError(ApiException):
"""Used to indicate an issue with verifying options passed to a certain
operation."""
GENERIC = "generic" # generic option violation
OPT_REPEAT = "opt_repeat" # option repetition is not allowed
ARG_REPEAT = "arg_repeat" # argument repetition is not allowed
ARG_INVALID = "arg_invalid" # argument is invalid
INCOMPAT = "incompat" # option 'a' can not be specified with option 'b'
REQUIRED = "required" # option 'a' requires option 'b'
REQUIRED_ANY = "required_any" # option 'a' requires option 'b', 'c' or more
XOR = "xor" # either option 'a' or option 'b' must be specified
def __init__(self, err_type=GENERIC, options=[], msg=None,
valid_args=[]):
self.err_type = err_type
self.options = options
self.msg = msg
self.valid_args = valid_args
def __str__(self):
# In case the user provided a custom message we just take it and
# append the according options.
if self.msg is not None:
if self.options:
self.msg += ": "
self.msg += " ".join(self.options)
return self.msg
if self.err_type == self.OPT_REPEAT:
assert len(self.options) == 1
return _("Option '{option}' may not be repeated.").format(
option=self.options[0])
elif self.err_type == self.ARG_REPEAT:
assert len(self.options) == 2
return _("Argument '{op1}' for option '{op2}' may "
"not be repeated.").format(op1=self.options[0],
op2=self.options[1])
elif self.err_type == self.ARG_INVALID:
assert len(self.options) == 2
s = _("Argument '{op1}' for option '{op2}' is "
"invalid.").format(op1=self.options[0],
op2=self.options[1])
if self.valid_args:
s += _("\nSupported: {0}").format(", ".join(
[str(va) for va in self.valid_args]))
return s
elif self.err_type == self.INCOMPAT:
assert len(self.options) == 2
return _("The '{op1}' and '{op2}' option may "
"not be combined.").format(op1=self.options[0],
op2=self.options[1])
elif self.err_type == self.REQUIRED:
assert len(self.options) == 2
return _("'{op1}' may only be used with "
"'{op2}'.").format(op1=self.options[0],
op2=self.options[1])
elif self.err_type == self.REQUIRED_ANY:
assert len(self.options) > 2
return _("'{op1}' may only be used with "
"'{op2}' or {op3}.").format(op1=self.options[0],
op2=", ".join(self.options[1:-1]),
op3=self.options[-1])
elif self.err_type == self.XOR:
assert len(self.options) == 2
return _("Either '{op1}' or '{op2}' must be "
"specified").format(op1=self.options[0],
op2=self.options[1])
else:
return _("invalid option(s): ") + " ".join(self.options)
class InvalidOptionErrors(ApiException):
def __init__(self, errors):
self.errors = []
assert (isinstance(errors, list) or isinstance(errors, tuple) or
isinstance(errors, set) or
isinstance(errors, InvalidOptionError))
if isinstance(errors, InvalidOptionError):
self.errors.append(errors)
else:
self.errors = errors
def __str__(self):
msgs = []
for e in self.errors:
msgs.append(str(e))
return "\n".join(msgs)
class UnexpectedLinkError(ApiException):
"""Used to indicate that an image state file has been replaced
with a symlink."""
def __init__(self, path, filename, errno):
self.path = path
self.filename = filename
self.errno = errno
def __str__(self):
return _("Cannot update file: '{file}' at path "
"'{path}', contains a symlink. "
"[Error '{errno:d}': '{error}']").format(
error=os.strerror(self.errno),
errno=self.errno,
path=self.path,
file=self.filename,
)
class InvalidConfigFile(ApiException):
"""Used to indicate that a configuration file is invalid
or broken"""
def __init__(self, path):
self.path = path
def __str__(self):
return _("Cannot parse configuration file "
"{path}'.").format(path=self.path)
class PkgUnicodeDecodeError(UnicodeDecodeError):
def __init__(self, obj, *args):
self.obj = obj
UnicodeDecodeError.__init__(self, *args)
def __str__(self):
s = UnicodeDecodeError.__str__(self)
return "{0}. You passed in {1!r} {2}".format(s, self.obj,
type(self.obj))