> > I have attached an hg exported patch of my changed, merged to tip and > > recommitted. > > You've some work to do to remove tabs from your indentation, and you've a > couple of whitespace-filled, but otherwise blank, lines. > > I'm happy to push your changeset, but you'll need to clean these things up > first.
Ok, fine, be picky. Err, I mean, "doh." Fixed. Including, per the attached patch, several preexisting occurences in the files I'm touching. --Mark
# HG changeset patch # User Mark J. Nelson <[email protected]> # Date 1252724388 21600 # Node ID 8406eda12b132a98f6f9a5ba3c62c406a1863858 # Parent 22d755acef3dcf2c8e9b88bdf8a44f2672512e7a 6572 ability to trigger repository index refresh desired 6573 ability to control publication refresh-index behaviour desired diff --git a/src/man/pkgsend.1.txt b/src/man/pkgsend.1.txt --- a/src/man/pkgsend.1.txt +++ b/src/man/pkgsend.1.txt @@ -13,7 +13,8 @@ /usr/bin/pkgsend import [-T pattern] bundlefile ... /usr/bin/pkgsend include [-d basedir] ... [manifest] ... /usr/bin/pkgsend publish [-d basedir] ... pkg_fmri [manifest] ... - /usr/bin/pkgsend close [-A] + /usr/bin/pkgsend close [-A | --no-index] + /usr/bin/pkgsend refresh-index DESCRIPTION pkgsend allows the publication of new packages and new package @@ -89,7 +90,8 @@ close [-A] Close current transaction. With -A, abandon the current - transaction. + transaction. With --no-index, do not update the repository's + search indices. publish [ -d basedir] ... fmri [manifest] ... Combines open, include and publish in a single operation. @@ -103,6 +105,10 @@ analyzed, added, etc before being passed to the publish or import subcommands. + refresh-index + Update the repository's search indices. Should be used after + closing one or more transactions using --no-index. + ENVIRONMENT VARIABLES The following environment variables are supported: diff --git a/src/modules/publish/transaction.py b/src/modules/publish/transaction.py --- a/src/modules/publish/transaction.py +++ b/src/modules/publish/transaction.py @@ -182,7 +182,7 @@ If 'abandon' is omitted or False, the package will be published; otherwise the server will discard the current transaction and its related data. - + If 'refresh_index' is True, the repository will be instructed to update its search indices after publishing. Has no effect if 'abandon' is True.""" @@ -339,7 +339,7 @@ If 'abandon' is omitted or False, the package will be published; otherwise the server will discard the current transaction and its related data. - + If 'refresh_index' is True, the repository will be instructed to update its search indices after publishing. Has no effect if 'abandon' is True.""" @@ -413,12 +413,34 @@ return self.trans_id - @staticmethod - def refresh_index(): - """Currently unsupported.""" + def refresh_index(self): + """Instructs the repository to refresh its search indices. + Returns nothing.""" - raise TransactionOperationError("refresh_index", - status=httplib.NOT_FOUND) + op = "index" + subop = "refresh" + + headers = {} + + try: + c, v = versioned_urlopen(self.origin_url, op, [0], + subop, headers=headers) + except (httplib.BadStatusLine, RuntimeError), e: + status = httplib.INTERNAL_SERVER_ERROR + msg = str(e) + except (urllib2.HTTPError, urllib2.URLError), e: + status, msg = self.__get_urllib_error(e) + except RuntimeError, e: + # Assume the server can't perform the operation. + status = httplib.NOT_FOUND + msg = str(e) + else: + msg = None + status = c.code + + if status / 100 == 4 or status / 100 == 5: + raise TransactionOperationError(op, + trans_id=self.trans_id, status=status, msg=msg) class NullTransaction(object): diff --git a/src/modules/server/depot.py b/src/modules/server/depot.py --- a/src/modules/server/depot.py +++ b/src/modules/server/depot.py @@ -86,7 +86,8 @@ "abandon", "add", "p5i", - "publisher" + "publisher", + "index" ] REPO_OPS_READONLY = [ @@ -243,7 +244,7 @@ query_args_lst = [str(Query(token, case_sensitive=False, return_type=Query.RETURN_ACTIONS, num_to_return=None, start_point=None))] - + try: res_list = self.__repo.search(query_args_lst) except repo.RepositorySearchUnavailableError, e: @@ -277,7 +278,7 @@ search_0._cp_config = { "response.stream": True } - + def search_1(self, *args, **params): """Based on the request path, return a list of packages that match the specified criteria.""" @@ -335,7 +336,7 @@ except StopIteration: cherrypy.response.status = httplib.NO_CONTENT return - + def output(): # Yield the string used to let the client know it's # talking to a valid search server. @@ -711,6 +712,25 @@ "response.timeout": 3600, } + def index_0(self, *tokens): + """Triggers a refresh of the search indices. + Returns no output.""" + + cmd = tokens[0] + + if cmd == "refresh": + try: + self.__repo.refresh_index() + except repo.RepositoryError, e: + # Assume a bad request was made. A 404 can't be + # returned here as misc.versioned_urlopen will interpret + # that to mean that the server doesn't support this + # operation. + raise cherrypy.HTTPError(httplib.BAD_REQUEST, str(e)) + else: + cherrypy.log("Unknown index subcommand: %s" % cmd) + raise cherrypy.HTTPError(httplib.NOT_FOUND, str(e)) + @cherrypy.tools.response_headers(headers = \ [("Content-Type", "text/plain")]) def info_0(self, *tokens): @@ -895,7 +915,7 @@ ] try: - pub = self.__get_publisher() + pub = self.__get_publisher() except Exception, e: # If the Publisher object creation fails, return a not # found error to the client so it will treat it as an @@ -950,7 +970,7 @@ retryable_errors = [httplib.REQUEST_TIMEOUT, httplib.BAD_GATEWAY, httplib.GATEWAY_TIMEOUT] - + # NASTY # emit error code that client should know how to retry if cherrypy.request.app.root.scfg.need_nasty_bonus(bonus): diff --git a/src/publish.py b/src/publish.py --- a/src/publish.py +++ b/src/publish.py @@ -85,9 +85,10 @@ pkgsend add action arguments pkgsend import [-T file_pattern] bundlefile ... pkgsend include [-d basedir] .. [manifest] ... - pkgsend close [-A] + pkgsend close [-A | --no-index] pkgsend publish [-d basedir] ... fmri [manifest] ... pkgsend generate [-T file_pattern] bundlefile .... + pkgsend refresh-index Options: -s repo_uri target repository URI @@ -141,14 +142,17 @@ def trans_close(repo_uri, args): abandon = False trans_id = None + refresh_index = True - opts, pargs = getopt.getopt(args, "At:") + opts, pargs = getopt.getopt(args, "At:", ["no-index"]) for opt, arg in opts: if opt == "-A": abandon = True - if opt == "-t": + elif opt == "-t": trans_id = arg + elif opt == "--no-index": + refresh_index = False if trans_id is None: try: @@ -158,7 +162,7 @@ "$PKG_TRANS_ID."), cmd="close") t = trans.Transaction(repo_uri, trans_id=trans_id) - pkg_state, pkg_fmri = t.close(abandon) + pkg_state, pkg_fmri = t.close(abandon, refresh_index) for val in (pkg_state, pkg_fmri): if val is not None: msg(val) @@ -205,9 +209,9 @@ if opt == "-d": include_opts += [opt, arg] if not pargs: - usage(_("No fmri argument specified for subcommand"), + usage(_("No fmri argument specified for subcommand"), cmd="publish") - + t = trans.Transaction(repo_uri, pkg_name=pargs[0]) t.open() del pargs[0] @@ -222,7 +226,7 @@ if abandon: return 1 return 0 - + def trans_include(repo_uri, fargs, transaction=None): basedirs = [] error_occurred = False @@ -315,7 +319,7 @@ if action.name == "set" and \ action.attrs["name"] == "fmri": continue - + t.add(action) if error_occurred: return 1 @@ -384,6 +388,20 @@ return 0 +def trans_refresh_index(repo_uri, args): + """Refreshes the indices at the location indicated by repo_uri.""" + + if args: + usage(_("command does not take operands"), + cmd="refresh-index") + + try: + t = trans.Transaction(repo_uri).refresh_index() + except trans.TransactionError, e: + error(e, cmd="refresh-index") + return 1 + return 0 + def main_func(): # XXX /usr/lib/locale is OpenSolaris-specific. @@ -434,6 +452,8 @@ ret = trans_publish(repo_uri, pargs) elif subcommand == "generate": ret = trans_generate(pargs) + elif subcommand == "refresh-index": + ret = trans_refresh_index(repo_uri, pargs) else: usage(_("unknown subcommand '%s'") % subcommand) except getopt.GetoptError, e: diff --git a/src/tests/baseline.txt b/src/tests/baseline.txt --- a/src/tests/baseline.txt +++ b/src/tests/baseline.txt @@ -439,13 +439,13 @@ cli.t_pkg_install.py TestPkgInstallBasics.test_recursive_uninstall|pass cli.t_pkg_install.py TestPkgInstallCircularDependencies.test_anchored_circular_dependencies|pass cli.t_pkg_install.py TestPkgInstallCircularDependencies.test_unanchored_circular_dependencies|pass +cli.t_pkg_install.py TestPkgInstallUpgrade.test_driver_policy_removal|pass cli.t_pkg_install.py TestPkgInstallUpgrade.test_incorp_install|pass cli.t_pkg_install.py TestPkgInstallUpgrade.test_upgrade1|pass cli.t_pkg_install.py TestPkgInstallUpgrade.test_upgrade2|pass cli.t_pkg_install.py TestPkgInstallUpgrade.test_upgrade3|pass cli.t_pkg_install.py TestPkgInstallUpgrade.test_upgrade4|pass cli.t_pkg_install.py TestPkgInstallUpgrade.test_upgrade_driver_conflicts|pass -cli.t_pkg_install.py TestPkgInstallUpgrade.test_driver_policy_removal|pass cli.t_pkg_install.py TestPkgInstallUpgrade.test_upgrade_liveroot|pass cli.t_pkg_intent.py TestPkgIntent.test_0_info|pass cli.t_pkg_intent.py TestPkgIntent.test_1_install_uninstall|pass @@ -498,8 +498,8 @@ cli.t_pkg_uninstall.py TestCommandLine.test_dependencies|pass cli.t_pkg_uninstall.py TestCommandLine.test_pkg_bogus_opts|pass cli.t_pkg_uninstall.py TestCommandLine.test_rmdir_cwd|pass +cli.t_pkg_verify.py TestPkgVerify.test_bug_1463|pass cli.t_pkg_verify.py TestPkgVerify.test_pkg_verify_bad_opts|pass -cli.t_pkg_verify.py TestPkgVerify.test_bug_1463|pass cli.t_pkg_version.py TestPkgVersion.test_pkg_version_bad_opts|pass cli.t_pkgdep.py TestPkgdepBasics.test_opts|pass cli.t_pkgdep.py TestPkgdepBasics.test_output|pass @@ -516,6 +516,10 @@ cli.t_pkgrecv.py TestPkgrecvMulti.test_4_timever|pass cli.t_pkgrecv.py TestPkgrecvMulti.test_5_recv_env|pass cli.t_pkgsend.py TestPkgsendBasics.test_0_pkgsend_bad_opts|pass +cli.t_pkgsend.py TestPkgsendBasics.test_10_bundle_dir|pass +cli.t_pkgsend.py TestPkgsendBasics.test_11_bundle_sysv_dir|pass +cli.t_pkgsend.py TestPkgsendBasics.test_12_bundle_sysv_datastream|pass +cli.t_pkgsend.py TestPkgsendBasics.test_13_pkgsend_indexcontrol|pass cli.t_pkgsend.py TestPkgsendBasics.test_1_pkgsend_abandon|pass cli.t_pkgsend.py TestPkgsendBasics.test_2_invalid_url|pass cli.t_pkgsend.py TestPkgsendBasics.test_3_bad_transaction|pass @@ -525,9 +529,6 @@ cli.t_pkgsend.py TestPkgsendBasics.test_7_create_repo|pass cli.t_pkgsend.py TestPkgsendBasics.test_8_bug_7908|pass cli.t_pkgsend.py TestPkgsendBasics.test_9_multiple_dirs|pass -cli.t_pkgsend.py TestPkgsendBasics.test_10_bundle_dir|pass -cli.t_pkgsend.py TestPkgsendBasics.test_11_bundle_sysv_dir|pass -cli.t_pkgsend.py TestPkgsendBasics.test_12_bundle_sysv_datastream|pass cli.t_setUp.py TestSetUp.test_first_depot_start|pass cli.t_setUp.py TestSetUp.test_second_depot_start|pass cli.t_variants.py TestPkgVariants.test_old_zones_pkgs|pass diff --git a/src/tests/cli/t_pkgsend.py b/src/tests/cli/t_pkgsend.py --- a/src/tests/cli/t_pkgsend.py +++ b/src/tests/cli/t_pkgsend.py @@ -31,6 +31,7 @@ import shutil import tempfile import unittest +import urllib class TestPkgsendBasics(testutils.SingleDepotTestCase): persistent_depot = False @@ -370,5 +371,52 @@ self.pkg("install nopkg") self.image_destroy() + def test_13_pkgsend_indexcontrol(self): + """Verify that "pkgsend close --no-index" suppresses + indexing and that "pkgsend refresh-index" triggers + indexing.""" + + dhurl = self.dc.get_depot_url() + dfurl = "file://%s" % urllib.pathname2url(self.dc.get_repodir()) + + fd, fpath = tempfile.mkstemp(dir=self.get_test_prefix()) + + self.image_create(dhurl) + + self.dc.stop() + self.dc.set_readonly() + + self.pkgsend(dfurl, "open [email protected]") + self.pkgsend(dfurl, "add file %s %s path=/tmp/f.foo" \ + % ( fpath, "mode=0755 owner=root group=bin" )) + self.pkgsend(dfurl, "close --no-index") + + self.dc.start() + self.pkg("search file:::", exit=1) + + self.dc.stop() + self.pkgsend(dfurl, "refresh-index") + self.dc.start() + self.pkg("search file:::") + + self.dc.stop() + self.dc.set_readwrite() + self.dc.start() + + self.pkgsend(dhurl, "open [email protected]") + self.pkgsend(dhurl, "add file %s %s path=/tmp/f.foo" \ + % ( fpath, "mode=0755 owner=root group=bin" )) + self.pkgsend(dhurl, "close --no-index") + + self.pkg("search http:::", exit=1) + + self.pkgsend(dhurl, "refresh-index") + + self.pkg("search http:::") + + self.image_destroy() + os.close(fd) + os.unlink(fpath) + if __name__ == "__main__": unittest.main()
_______________________________________________ pkg-discuss mailing list [email protected] http://mail.opensolaris.org/mailman/listinfo/pkg-discuss
