2863 pkg install should have a way to disable indexing
3750 Api.py should differentiate between compatible and incompatible changes in versions
3963 typos introduced in b072bc027c543eb5d5b839b5a078446ffe939b54
3962 pkg info displays %s in size field
--- a/doc/api_versions.txt Fri Oct 17 08:13:16 2008 +0100
+++ b/doc/api_versions.txt Fri Oct 17 14:44:53 2008 -0700
@@ -1,3 +1,10 @@
+Version 2:
+Compatible with clients using Version 1
+Changes:
+Adds the optional argument update_index to plan_install, plan_uninstall, and
+plan_update_all. When the argument is false, no automatic update to the index
+occurs. By default, the argument is true.
+
Version 1:
Incompatible with clients using Version 0
Changes:
--- a/src/client.py Fri Oct 17 08:13:16 2008 +0100
+++ b/src/client.py Fri Oct 17 14:44:53 2008 -0700
@@ -83,7 +83,7 @@
from pkg.client.retrieve import ManifestRetrievalError
from pkg.client.retrieve import DatastreamRetrievalError
-CLIENT_API_VERSION = 1
+CLIENT_API_VERSION = 2
PKG_CLIENT_NAME = "pkg"
def error(text):
@@ -113,10 +113,10 @@
pkg [options] command [cmd_options] [operands]
Basic subcommands:
- pkg install [-nvq] package...
- pkg uninstall [-nrvq] package...
+ pkg install [-nvq] [--no-index] package...
+ pkg uninstall [-nrvq] [--no-index] package...
pkg list [-aHsuvf] [package...]
- pkg image-update [-nvq]
+ pkg image-update [-nvq] [--no-index]
pkg refresh [--full]
pkg version
pkg help
@@ -504,10 +504,10 @@
# XXX Are filters appropriate for an image update?
# XXX Leaf package refinements.
- opts, pargs = getopt.getopt(args, "b:fnvq", ["no-refresh"])
+ opts, pargs = getopt.getopt(args, "b:fnvq", ["no-refresh", "no-index"])
force = quiet = noexecute = verbose = False
- refresh_catalogs = True
+ refresh_catalogs = update_index = True
for opt, arg in opts:
if opt == "-n":
noexecute = True
@@ -521,6 +521,8 @@
force = True
elif opt == "--no-refresh":
refresh_catalogs = False
+ elif opt == "--no-index":
+ update_index = False
if verbose and quiet:
usage(_("image-update: -v and -q may not be combined"))
@@ -544,7 +546,8 @@
# caught while planning.
stuff_to_do, opensolaris_image, cre = \
api_inst.plan_update_all(sys.argv[0], refresh_catalogs,
- noexecute, force=force, verbose=verbose)
+ noexecute, force=force, verbose=verbose,
+ update_index=update_index)
if cre and not display_catalog_failures(cre):
raise RuntimeError("Catalog refresh failed during"
" image-update.")
@@ -633,10 +636,10 @@
# XXX Authority-catalog issues.
- opts, pargs = getopt.getopt(args, "nvb:f:q", ["no-refresh"])
+ opts, pargs = getopt.getopt(args, "nvb:f:q", ["no-refresh", "no-index"])
quiet = noexecute = verbose = False
- refresh_catalogs = True
+ refresh_catalogs = update_index = True
filters = []
for opt, arg in opts:
if opt == "-n":
@@ -651,6 +654,8 @@
quiet = True
elif opt == "--no-refresh":
refresh_catalogs = False
+ elif opt == "--no-index":
+ update_index = False
if not pargs:
usage(_("install: at least one package name required"))
@@ -678,7 +683,8 @@
# cre is either None or a catalog refresh exception which was
# caught while planning.
stuff_to_do, cre = api_inst.plan_install(pkg_list, filters,
- refresh_catalogs, noexecute, verbose=verbose)
+ refresh_catalogs, noexecute, verbose=verbose,
+ update_index=update_index)
if cre and not display_catalog_failures(cre):
raise RuntimeError("Catalog refresh failed during"
" install.")
@@ -754,9 +760,10 @@
def uninstall(img_dir, args):
"""Attempt to take package specified to DELETED state."""
- opts, pargs = getopt.getopt(args, "nrvq")
+ opts, pargs = getopt.getopt(args, "nrvq", ["no-index"])
quiet = noexecute = recursive_removal = verbose = False
+ update_index = True
for opt, arg in opts:
if opt == "-n":
noexecute = True
@@ -766,6 +773,8 @@
verbose = True
elif opt == "-q":
quiet = True
+ elif opt == "--no-index":
+ update_index = False
if not pargs:
usage(_("uninstall: at least one package name required"))
@@ -791,7 +800,7 @@
try:
if not api_inst.plan_uninstall(pkg_list, recursive_removal,
- noexecute, verbose=verbose):
+ noexecute, verbose=verbose, update_index=update_index):
assert 0
except api_errors.InventoryException, e:
error(_("uninstall failed (inventory exception):\n%s") % e)
@@ -1019,7 +1028,7 @@
msg(" Build Release:", pi.build_release)
msg(" Branch:", pi.branch)
msg("Packaging Date:", pi.packaging_date)
- msg(" Size: %s", misc.bytes_to_str(pi.size))
+ msg(" Size:", misc.bytes_to_str(pi.size))
msg(" FMRI:", pi.fmri)
# XXX add license/copyright info here?
@@ -1503,9 +1512,8 @@
ssl_key=ssl_key, ssl_cert=ssl_cert,
refresh_allowed=refresh_catalogs, uuid=uuid)
except api_errors.CatalogRefreshException, e:
- text = "Could not refresh the catalog for %s" % \
- auth
- error(_(text))
+ text = "Could not refresh the catalog for %s"
+ error(_(text) % auth)
return 1
if preferred:
--- a/src/man/pkg.1.txt Fri Oct 17 08:13:16 2008 +0100
+++ b/src/man/pkg.1.txt Fri Oct 17 14:44:53 2008 -0700
@@ -7,8 +7,8 @@
SYNOPSIS
/usr/bin/pkg [options] command [cmd_options] [operands]
- /usr/bin/pkg install [-nvq] [--no-refresh] pkg_fmri ...
- /usr/bin/pkg uninstall [-nrvq] pkg_fmri ...
+ /usr/bin/pkg install [-nvq] [--no-refresh] [--no-index] pkg_fmri ...
+ /usr/bin/pkg uninstall [-nrvq] [--no-index] pkg_fmri ...
/usr/bin/pkg verify [-Hvq] [pkg_fmri_pattern ...]
/usr/bin/pkg fix [pkg_fmri_pattern ...]
@@ -22,7 +22,7 @@
/usr/bin/pkg image-create [-FPUz] [--full|--partial|--user] [--zone]
[-k ssl_key] [-c ssl_cert] [--no-refresh] -a authority=origin_url dir
- /usr/bin/pkg image-update [-nvq] [--no-refresh]
+ /usr/bin/pkg image-update [-nvq] [--no-refresh] [--no-index]
/usr/bin/pkg set-property propname propvalue
/usr/bin/pkg unset-property propname ...
@@ -99,7 +99,7 @@
With -f (--force), force the creation of an image over an existing
image. This option should be used with care.
- image-update [-fnvq] [--no-refresh]
+ image-update [-fnvq] [--no-refresh] [--no-index]
Update all installed packages in the current image to the
latest available version. With the -f option, skip safety
checks. With the -n option, execute the requested operation
@@ -107,7 +107,8 @@
option, issue verbose progress messages during the requested
operation. With the -q option, be completely silent. With
--no-refresh, do not attempt to contact the image's authorities
- to retrieve their catalogs.
+ to retrieve their catalogs. With --no-index do not update the
+ search indices after the operation has completed successfully.
refresh [--full] [authority ...]
Retrieve updates to the catalogs for each authority specified.
@@ -115,8 +116,8 @@
registered within the image. With --full, retrieve the full
catalogs.
- install [-nvq] [--no-refresh] pkg_fmri ...
- uninstall [-nrvq] pkg_fmri ...
+ install [-nvq] [--no-refresh] [--no-index] pkg_fmri ...
+ uninstall [-nrvq] [--no-index] pkg_fmri ...
Install or remove the package specified by pkg_fmri or
matching pkg_fmri as a substring. With the -n option, execute
the requested operation but make no persistent changes to the
@@ -128,7 +129,8 @@
package.
With --no-refresh, do not attempt to contact the image's authorities
- to retrieve their catalogs.
+ to retrieve their catalogs. With --no-index do not update the
+ search indices after the operation has completed successfully.
info [-lr] [--license] [pkg_fmri_pattern ...]
Display information about packages in a human-readable form.
--- a/src/modules/client/api.py Fri Oct 17 08:13:16 2008 +0100
+++ b/src/modules/client/api.py Fri Oct 17 14:44:53 2008 -0700
@@ -33,7 +33,7 @@
import threading
-CURRENT_API_VERSION = 1
+CURRENT_API_VERSION = 2
class ImageInterface(object):
"""This class presents an interface to images that clients may use.
@@ -68,7 +68,9 @@
canceled changes. It can raise VersionException and
ImageNotFoundException."""
- if version_id != CURRENT_API_VERSION:
+ compatible_versions = set([1, 2])
+
+ if version_id not in compatible_versions:
raise api_errors.VersionException(CURRENT_API_VERSION,
version_id)
@@ -90,7 +92,7 @@
self.__activity_lock = threading.Lock()
def plan_install(self, pkg_list, filters, refresh_catalogs=True,
- noexecute=False, verbose=False):
+ noexecute=False, verbose=False, update_index=True):
"""Contructs a plan to install the packages provided in
pkg_list. pkg_list is a list of packages to install. filters
is a list of filters to apply to the actions of the installed
@@ -157,6 +159,7 @@
noexecute:
self.img.history.operation_result = \
history.RESULT_NOTHING_TO_DO
+ self.img.imageplan.update_index = update_index
res = not self.img.imageplan.nothingtodo()
except api_errors.CanceledException:
self.__reset_unlock()
@@ -176,11 +179,11 @@
finally:
self.__activity_lock.release()
- return (res, exception_caught)
+ return res, exception_caught
def plan_uninstall(self, pkg_list, recursive_removal, noexecute=False,
- verbose=False):
+ verbose=False, update_index=True):
"""Contructs a plan to uninstall the packages provided in
pkg_list. pkg_list is a list of packages to install.
recursive_removal controls whether recursive removal is
@@ -220,6 +223,7 @@
if noexecute:
self.img.history.operation_result = \
history.RESULT_NOTHING_TO_DO
+ self.img.imageplan.update_index = update_index
res = not self.img.imageplan.nothingtodo()
except api_errors.CanceledException:
self.__reset_unlock()
@@ -252,7 +256,7 @@
return res
def plan_update_all(self, actual_cmd, refresh_catalogs=True,
- noexecute=False, force=False, verbose=False):
+ noexecute=False, force=False, verbose=False, update_index=True):
"""Creates a plan to update all packages on the system to the
latest known versions. actual_cmd is the command used to start
the client. It is used to determine the image to check whether
@@ -354,6 +358,7 @@
noexecute:
self.img.history.operation_result = \
history.RESULT_NOTHING_TO_DO
+ self.img.imageplan.update_index = update_index
res = not self.img.imageplan.nothingtodo()
except api_errors.CanceledException:
self.__reset_unlock()
@@ -371,7 +376,7 @@
finally:
self.__activity_lock.release()
- return (res, opensolaris_image, exception_caught)
+ return res, opensolaris_image, exception_caught
def describe(self):
"""Returns None if no plan is ready yet, otherwise returns
--- a/src/modules/client/imageplan.py Fri Oct 17 08:13:16 2008 +0100
+++ b/src/modules/client/imageplan.py Fri Oct 17 14:44:53 2008 -0700
@@ -103,6 +103,8 @@
self.actuators = None
+ self.update_index = True
+
def __str__(self):
if self.state == UNEVALUATED:
s = "UNEVALUATED:\n"
@@ -590,26 +592,30 @@
# the function will work correctly. It also repairs the index
# for this BE so the user can boot into this BE and have a
# correct index.
- try:
- self.image.update_index_dir()
- ind = indexer.Indexer(self.image.index_dir,
- CLIENT_DEFAULT_MEM_USE_KB, progtrack=self.progtrack)
- if not ind.check_index_existence() or \
- not ind.check_index_has_exactly_fmris(
- self.image.gen_installed_pkg_names()):
- # XXX Once we have a framework for emitting a
- # message to the user in this spot in the
- # code, we should tell them something has gone
- # wrong so that we continue to get feedback to
- # allow us to debug the code.
- ind.rebuild_index_from_scratch(
- self.image.get_fmri_manifest_pairs())
- except se.IndexingException:
- # If there's a problem indexing, we want to attempt
- # to finish the installation anyway. If there's a
- # problem updating the index on the new image,
- # that error needs to be communicated to the user.
- pass
+ if self.update_index:
+ try:
+ self.image.update_index_dir()
+ ind = indexer.Indexer(self.image.index_dir,
+ CLIENT_DEFAULT_MEM_USE_KB,
+ progtrack=self.progtrack)
+ if not ind.check_index_existence() or \
+ not ind.check_index_has_exactly_fmris(
+ self.image.gen_installed_pkg_names()):
+ # XXX Once we have a framework for
+ # emitting a message to the user in
+ # this spot in the code, we should tell
+ # them something has gone wrong so that
+ # we continue to get feedback to
+ # allow us to debug the code.
+ ind.rebuild_index_from_scratch(
+ self.image.get_fmri_manifest_pairs())
+ except se.IndexingException:
+ # If there's a problem indexing, we want to
+ # attempt to finish the installation anyway. If
+ # there's a problem updating the index on the
+ # new image, that error needs to be
+ # communicated to the user.
+ pass
try:
for p in self.pkg_plans:
@@ -737,38 +743,43 @@
# Perform the incremental update to the search indexes
# for all changed packages
- plan_info = []
- for p in self.pkg_plans:
- d_fmri = p.destination_fmri
- d_manifest_path = None
- if d_fmri:
- d_manifest_path = \
- self.image.get_manifest_path(d_fmri)
- o_fmri = p.origin_fmri
- o_manifest_path = None
- o_filter_file = None
- if o_fmri:
- o_manifest_path = \
- self.image.get_manifest_path(o_fmri)
- plan_info.append((d_fmri, d_manifest_path, o_fmri,
- o_manifest_path))
- del self.pkg_plans
- self.progtrack.actions_set_goal("Index Phase", len(plan_info))
- try:
- self.image.update_index_dir()
- ind = indexer.Indexer(self.image.index_dir,
- CLIENT_DEFAULT_MEM_USE_KB, progtrack=self.progtrack)
- ind.client_update_index((self.filters, plan_info))
- except (KeyboardInterrupt,
- se.ProblematicPermissionsIndexException):
- # ProblematicPermissionsIndexException is included here
- # as there's little chance that trying again will fix
- # this problem.
- raise
- except Exception, e:
- del(ind)
- # XXX Once we have a framework for emitting a message
- # to the user in this spot in the code, we should tell
- # them something has gone wrong so that we continue to
- # get feedback to allow us to debug the code.
- self.image.rebuild_search_index(self.progtrack)
+ if self.update_index:
+ plan_info = []
+ for p in self.pkg_plans:
+ d_fmri = p.destination_fmri
+ d_manifest_path = None
+ if d_fmri:
+ d_manifest_path = \
+ self.image.get_manifest_path(d_fmri)
+ o_fmri = p.origin_fmri
+ o_manifest_path = None
+ o_filter_file = None
+ if o_fmri:
+ o_manifest_path = \
+ self.image.get_manifest_path(o_fmri)
+ plan_info.append((d_fmri, d_manifest_path,
+ o_fmri, o_manifest_path))
+ del self.pkg_plans
+ self.progtrack.actions_set_goal("Index Phase",
+ len(plan_info))
+ try:
+ self.image.update_index_dir()
+ ind = indexer.Indexer(self.image.index_dir,
+ CLIENT_DEFAULT_MEM_USE_KB,
+ progtrack=self.progtrack)
+ ind.client_update_index((self.filters,
+ plan_info))
+ except (KeyboardInterrupt,
+ se.ProblematicPermissionsIndexException):
+ # ProblematicPermissionsIndexException is
+ # included here as there's little chance that
+ # trying again will fix this problem.
+ raise
+ except Exception, e:
+ del(ind)
+ # XXX Once we have a framework for emitting a
+ # message to the user in this spot in the code,
+ # we should tell them something has gone wrong
+ # so that we continue to get feedback to allow
+ # us to debug the code.
+ self.image.rebuild_search_index(self.progtrack)
--- a/src/tests/baseline.txt Fri Oct 17 08:13:16 2008 +0100
+++ b/src/tests/baseline.txt Fri Oct 17 14:44:53 2008 -0700
@@ -341,6 +341,7 @@
cli.t_pkg_refresh.py TestPkgRefreshMulti.test_set_authority_induces_full_refresh|pass
cli.t_pkg_refresh.py TestPkgRefreshMulti.test_specific_refresh|pass
cli.t_pkg_search.py TestPkgSearchBasics.test_bug_2849|pass
+cli.t_pkg_search.py TestPkgSearchBasics.test_bug_2863|pass
cli.t_pkg_search.py TestPkgSearchBasics.test_bug_2989_1|pass
cli.t_pkg_search.py TestPkgSearchBasics.test_bug_2989_2|pass
cli.t_pkg_search.py TestPkgSearchBasics.test_bug_2989_3|pass
--- a/src/tests/cli/t_pkg_search.py Fri Oct 17 08:13:16 2008 +0100
+++ b/src/tests/cli/t_pkg_search.py Fri Oct 17 14:44:53 2008 -0700
@@ -479,6 +479,13 @@
fh.write("*")
fh.close()
+ def _check_no_index(self):
+ ind_dir, ind_dir_tmp = self._get_index_dirs()
+ if os.listdir(ind_dir):
+ self.assert_(0)
+ if os.path.exists(ind_dir_tmp):
+ self.assert_(0)
+
def test_pkg_search_cli(self):
"""Test search cli options."""
@@ -785,6 +792,39 @@
self.pkg("search with*")
self.pkg("search *space")
self.pkg("search foodir")
+
+ def test_bug_2863(self):
+ """Test local case sensitive search"""
+ durl = self.dc.get_depot_url()
+ self.pkgsend_bulk(durl, self.example_pkg10)
+
+ self.image_create(durl)
+ self._check_no_index()
+ self.pkg("install --no-index example_pkg")
+ self._check_no_index()
+ self.pkg("rebuild-index")
+ self._run_local_tests()
+ self.pkg("uninstall --no-index example_pkg")
+ # Running empty test because search will notice the index
+ # does not match the installed packages and complain.
+ self._run_local_empty_tests()
+ self.pkg("rebuild-index")
+ self._run_local_empty_tests()
+ self.pkg("install example_pkg")
+ self._run_local_tests()
+ self.pkgsend_bulk(durl, self.example_pkg11)
+ self.pkg("image-update --no-index")
+ # Running empty test because search will notice the index
+ # does not match the installed packages and complain.
+ self._run_local_empty_tests()
+ self.pkg("rebuild-index")
+ self._run_local_tests_example11_installed()
+ self.pkg("uninstall --no-index example_pkg")
+ # Running empty test because search will notice the index
+ # does not match the installed packages and complain.
+ self._run_local_empty_tests()
+ self.pkg("rebuild-index")
+ self._run_local_empty_tests()
class TestPkgSearchMulti(testutils.ManyDepotTestCase):