12130 install/update operations should always refresh publisher metadata (when allowed)
4419 misleading error message when pkg not found because refresh failed
10976 operations should report when refresh failed if appropriate
--- a/doc/client_api_versions.txt Wed Dec 02 19:21:44 2009 -0600
+++ b/doc/client_api_versions.txt Wed Dec 02 22:07:06 2009 -0600
@@ -1,3 +1,9 @@
+Version 26:
+Compatible with clients using version 25.
+ The client API has changed such that an immediate refresh is always
+ performed when the 'refresh_catalogs' parameter is True for install,
+ update, and change variant operations.
+
Version 25:
Incompatible with clients using versions 0-24:
Changes:
--- a/src/client.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/client.py Wed Dec 02 22:07:06 2009 -0600
@@ -80,7 +80,7 @@
RESULT_FAILED_OUTOFMEMORY)
from pkg.misc import EmptyI, msg, PipeError
-CLIENT_API_VERSION = 25
+CLIENT_API_VERSION = 26
PKG_CLIENT_NAME = "pkg"
JUST_UNKNOWN = 0
@@ -300,8 +300,21 @@
# changing (such as an origin uri, etc.).
try:
api_inst.refresh()
- except KeyboardInterrupt:
- raise
+ except api_errors.PermissionsException:
+ # Ignore permission exceptions with the
+ # assumption that an unprivileged user is
+ # executing this command and that the
+ # refresh doesn't matter.
+ pass
+ except api_errors.CatalogRefreshException, e:
+ succeeded = display_catalog_failures(e,
+ ignore_perms_failure=True)
+ if succeeded != e.total:
+ # If total number of publishers does
+ # not match 'successful' number
+ # refreshed, abort.
+ return EXIT_OOPS
+
except:
# Ignore the above error and just use what
# already exists.
@@ -607,10 +620,10 @@
error(_("%s cannot be done on live image") % operation)
return EXIT_NOTLIVE
except api_errors.RebootNeededOnLiveImageException:
- error(_("Requested \"%s\" operation would affect files that cannot be "
- "modified in live image.\n"
- "Please retry this operation on an alternate boot environment.") %
- operation)
+ error(_("Requested \"%s\" operation would affect files that "
+ "cannot be modified in live image.\n"
+ "Please retry this operation on an alternate boot "
+ "environment.") % operation)
return EXIT_NOTLIVE
except api_errors.CorruptedIndexException, e:
error(INCONSISTENT_INDEX_ERROR_MESSAGE)
@@ -638,7 +651,7 @@
raise
except api_errors.ActionExecutionError, e:
if not raise_ActionExecutionError:
- return 1
+ return EXIT_OOPS
error(_("An unexpected error happened during " \
"%s: %s") % (operation, e))
raise
@@ -685,16 +698,13 @@
return False
if e_type == api_errors.CatalogRefreshException:
if display_catalog_failures(e) != 0:
- raise RuntimeError("Catalog refresh failed during %s." %
- op)
+ return False
if noexecute:
return True
return False
-
if issubclass(e_type, api_errors.BEException):
error(_(e))
return False
-
if e_type in (api_errors.CertificateError,
api_errors.PlanCreationException,
api_errors.PermissionsException):
@@ -755,7 +765,7 @@
api_inst = __api_alloc(img, quiet)
if api_inst == None:
- return 1
+ return EXIT_OOPS
try:
stuff_to_do = api_inst.plan_change_varcets(variants, facets=None,
@@ -849,7 +859,7 @@
be_name=be_name)
except:
if not __api_plan_exception(op, noexecute=noexecute):
- return 1
+ return EXIT_OOPS
if not stuff_to_do:
msg(_("Facet change has no effect on image"))
@@ -929,7 +939,7 @@
return EXIT_OK
if not __api_prepare(op, api_inst, verbose=verbose):
- return 1
+ return EXIT_OOPS
ret_code = __api_execute_plan(op, api_inst)
@@ -1211,7 +1221,7 @@
if not misc.valid_pub_url(arg):
error(_("%s is not a valid "
"server URL.") % orig_arg)
- return 1
+ return EXIT_OOPS
remote = True
servers.append({"origin": arg})
elif opt == "-I":
@@ -1667,9 +1677,9 @@
try:
int(v)
return JUST_RIGHT
- # attribute is non-numeric or is something like
- # a list.
except (ValueError, TypeError):
+ # attribute is non-numeric or is something like
+ # a list.
return JUST_LEFT
def create_output_format(display_headers, widths, justs, line):
@@ -1951,7 +1961,7 @@
img.cleanup_downloads()
return err
-def display_catalog_failures(cre):
+def display_catalog_failures(cre, ignore_perms_failure=False):
total = cre.total
succeeded = cre.succeeded
@@ -1964,6 +1974,19 @@
msg(txt)
for pub, err in cre.failed:
+ if ignore_perms_failure and \
+ not isinstance(err, api_errors.PermissionsException):
+ # If any errors other than a permissions exception are
+ # found, then don't ignore them.
+ ignore_perms_failure = False
+ break
+
+ if cre.failed and ignore_perms_failure:
+ # Consider those that failed to have succeeded and add them
+ # to the actual successful total.
+ return succeeded + len(cre.failed)
+
+ for pub, err in cre.failed:
if isinstance(err, urllib2.HTTPError):
logger.error(" %s: %s - %s" % \
(err.filename, err.code, err.msg))
@@ -2012,7 +2035,7 @@
error(e)
error(_("'pkg publisher' will show a list of publishers."))
return EXIT_OOPS
- except (api_errors.PermissionsException), e:
+ except api_errors.PermissionsException, e:
# Prepend a newline because otherwise the exception will
# be printed on the same line as the spinner.
error("\n" + str(e))
@@ -2154,7 +2177,7 @@
ssl_key = uri.ssl_key
break
- origin = repo.reset_origins()
+ repo.reset_origins()
repo.add_origin(origin_url)
# XXX once image configuration supports storing this
@@ -2756,11 +2779,9 @@
{ "image_dir": image_dir, "reason": e.args[1] },
cmd="image-create")
return EXIT_OOPS
-
except api_errors.PublisherError, e:
error(e, cmd="image-create")
return EXIT_OOPS
-
except api_errors.PermissionsException, e:
# Ensure messages are displayed after the spinner.
img.cleanup_downloads()
--- a/src/gui/modules/misc_non_gui.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/gui/modules/misc_non_gui.py Wed Dec 02 22:07:06 2009 -0600
@@ -31,7 +31,7 @@
# The current version of the Client API the PM, UM and
# WebInstall GUIs have been tested against and are known to work with.
-CLIENT_API_VERSION = 25
+CLIENT_API_VERSION = 26
def get_cache_dir(api_object):
img = api_object.img
--- a/src/modules/client/api.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/modules/client/api.py Wed Dec 02 22:07:06 2009 -0600
@@ -50,7 +50,7 @@
from pkg.client.imageplan import EXECUTED_OK
from pkg.client import global_settings
-CURRENT_API_VERSION = 25
+CURRENT_API_VERSION = 26
CURRENT_P5I_VERSION = 1
logger = global_settings.logger
@@ -95,7 +95,7 @@
canceled changes. It can raise VersionException and
ImageNotFoundException."""
- compatible_versions = set([CURRENT_API_VERSION])
+ compatible_versions = set([25, CURRENT_API_VERSION])
if version_id not in compatible_versions:
raise api_errors.VersionException(CURRENT_API_VERSION,
@@ -186,19 +186,8 @@
# attempting network operations.
#
self.__cert_verify()
-
- try:
- self.__img.refresh_publishers(
- progtrack=self.__progresstracker)
- except KeyboardInterrupt:
- raise
- except api_errors.InvalidDepotResponseException:
- raise
- except:
- # Since this is not a refresh
- # that was explicitly requested,
- # it doesn't matter if it fails.
- pass
+ self.__img.refresh_publishers(immediate=True,
+ progtrack=self.__progresstracker)
def __plan_common_start(self, operation):
"""Start planning an operation. Aquire locks and log
--- a/src/modules/client/image.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/modules/client/image.py Wed Dec 02 22:07:06 2009 -0600
@@ -1508,6 +1508,11 @@
if pub.refresh(full_refresh=full_refresh,
immediate=immediate):
updated += 1
+ except api_errors.PermissionsException, e:
+ failed.append((pub, e))
+ # No point in continuing since no data can
+ # be written.
+ break
except api_errors.ApiException, e:
failed.append((pub, e))
continue
--- a/src/pkgdep.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/pkgdep.py Wed Dec 02 22:07:06 2009 -0600
@@ -42,7 +42,7 @@
import pkg.publish.dependencies as dependencies
from pkg.misc import msg, emsg, PipeError
-CLIENT_API_VERSION = 25
+CLIENT_API_VERSION = 26
PKG_CLIENT_NAME = "pkgdep"
DEFAULT_SUFFIX = ".res"
--- a/src/tests/cli/t_api.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_api.py Wed Dec 02 22:07:06 2009 -0600
@@ -40,7 +40,7 @@
import time
import unittest
-API_VERSION = 25
+API_VERSION = 26
PKG_CLIENT_NAME = "pkg"
class TestPkgApi(testutils.SingleDepotTestCase):
--- a/src/tests/cli/t_api_info.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_api_info.py Wed Dec 02 22:07:06 2009 -0600
@@ -40,7 +40,7 @@
import pkg.client.api_errors as api_errors
import pkg.client.progress as progress
-API_VERSION = 25
+API_VERSION = 26
PKG_CLIENT_NAME = "pkg"
class TestApiInfo(testutils.SingleDepotTestCase):
--- a/src/tests/cli/t_api_list.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_api_list.py Wed Dec 02 22:07:06 2009 -0600
@@ -46,7 +46,7 @@
import pkg.misc as misc
import pkg.version as version
-API_VERSION = 25
+API_VERSION = 26
PKG_CLIENT_NAME = "pkg"
class TestApiList(testutils.ManyDepotTestCase):
--- a/src/tests/cli/t_api_search.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_api_search.py Wed Dec 02 22:07:06 2009 -0600
@@ -47,7 +47,7 @@
import pkg.portable as portable
import pkg.search_storage as ss
-API_VERSION = 25
+API_VERSION = 26
PKG_CLIENT_NAME = "pkg"
class TestApiSearchBasics(testutils.SingleDepotTestCase):
--- a/src/tests/cli/t_pkg_api_install.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_pkg_api_install.py Wed Dec 02 22:07:06 2009 -0600
@@ -38,7 +38,7 @@
import pkg.client.api_errors as api_errors
import pkg.client.progress as progress
-API_VERSION = 25
+API_VERSION = 26
PKG_CLIENT_NAME = "pkg"
class TestPkgApiInstall(testutils.SingleDepotTestCase):
--- a/src/tests/cli/t_pkg_install.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_pkg_install.py Wed Dec 02 22:07:06 2009 -0600
@@ -2458,7 +2458,8 @@
def test_08_install_repository_access(self):
"""Verify that packages can still be installed from a repository
- even when any of the other repositories are not reachable."""
+ even when any of the other repositories are not reachable and
+ --no-refresh is used."""
# Change the second publisher to point to an unreachable URI.
self.pkg("set-publisher --no-refresh -O http://test.invalid7 test2")
@@ -2466,9 +2467,15 @@
# Verify that no packages are installed.
self.pkg("list", exit=1)
- # Verify moo can be installed (as only depot1 has it) even though
+ # Verify moo can not be installed (as only depot1 has it) since
# test2 cannot be reached (and needs a refresh).
- self.pkg("install moo")
+ self.pkg("install moo", exit=1)
+
+ # Verify moo can be installed (as only depot1 has it) even though
+ # test2 cannot be reached (and needs a refresh) if --no-refresh
+ # is used.
+ self.pkg("install --no-refresh moo")
+
self.pkg("uninstall moo")
# Reset the test2 publisher.
@@ -2487,9 +2494,14 @@
durl4 = self.dcs[4].get_depot_url()
self.pkg("set-publisher -O %s test2" % durl4)
+ # Verify image-update does not work since test1 is unreachable
+ # even though [email protected] is available from test2.
+ self.pkg("image-update", exit=1)
+
# Verify image-update works even though test1 is unreachable
- # since [email protected] is available from test2.
- self.pkg("image-update")
+ # since [email protected] is available from test2 if --no-refresh
+ # is used.
+ self.pkg("image-update --no-refresh")
# Now reset everything for the next test.
self.pkg("uninstall upgrade-np")
--- a/src/tests/cli/t_pkg_intent.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_pkg_intent.py Wed Dec 02 22:07:06 2009 -0600
@@ -39,7 +39,7 @@
import pkg.client.api_errors as api_errors
import pkg.client.progress as progress
-API_VERSION = 25
+API_VERSION = 26
PKG_CLIENT_NAME = "pkg"
class TestPkgIntent(testutils.SingleDepotTestCase):
--- a/src/tests/cli/t_pkg_list.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_pkg_list.py Wed Dec 02 22:07:06 2009 -0600
@@ -378,15 +378,19 @@
def test_list_10_all_known_failed_refresh(self):
"""Verify that a failed implicit refresh will not prevent pkg
- list from working properly."""
+ list from working properly when appropriate."""
# Set test2's origin to an unreachable URI.
- self.pkg("set-publisher --no-refresh -O http://test.invalid2 test2")
+ self.pkg("set-publisher --no-refresh -O http://test.invalid2 "
+ "test2")
- # Verify pkg list -a works as expected for both an unprivileged
- # user and a privileged one when a publisher needs a refresh.
+ # Verify pkg list -a works as expected for an unprivileged user
+ # when a permissions failure is encountered.
self.pkg("list -a", su_wrap=True)
- self.pkg("list -a")
+
+ # Verify pkg list -a fails for a privileged user when a
+ # publisher's repository is unreachable.
+ self.pkg("list -a", exit=1)
# Reset test2's origin.
durl2 = self.dcs[2].get_depot_url()
--- a/src/tests/cli/t_pkgdep_resolve.py Wed Dec 02 19:21:44 2009 -0600
+++ b/src/tests/cli/t_pkgdep_resolve.py Wed Dec 02 22:07:06 2009 -0600
@@ -40,7 +40,7 @@
import pkg.portable as portable
import pkg.publish.dependencies as dependencies
-API_VERSION = 25
+API_VERSION = 26
PKG_CLIENT_NAME = "pkg"
class TestApiDependencies(testutils.SingleDepotTestCase):