From 559fbe0cbdb16f0c7c3a2f33e326a3b5930fd3f3 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 17 Apr 2019 22:46:39 +0300 Subject: Add support for overrides parameter in CI request handler --- mod/mod-ci.cxx | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 9 deletions(-) (limited to 'mod/mod-ci.cxx') diff --git a/mod/mod-ci.cxx b/mod/mod-ci.cxx index f5efaac..168b57c 100644 --- a/mod/mod-ci.cxx +++ b/mod/mod-ci.cxx @@ -103,6 +103,8 @@ handle (request& rq, response& rs) using namespace bpkg; using namespace xhtml; + using parser = manifest_parser; + using parsing = manifest_parsing; using serializer = manifest_serializer; using serialization = manifest_serialization; @@ -162,7 +164,10 @@ handle (request& rq, response& rs) if (!options_->ci_data_specified ()) return respond_manifest (404, "CI request submission disabled"); - // Parse the request form data. + // Parse the request form data and verify the submission size limit. + // + // Note that the submission may include the overrides upload that we don't + // expect to be large. // const name_values& rps (rq.parameters (64 * 1024)); @@ -280,6 +285,38 @@ handle (request& rq, response& rs) return respond_manifest (400, "invalid parameter " + nv.name); } + // Parse and validate overrides, if present. + // + vector overrides; + + if (params.overrides_specified ()) + try + { + istream& is (rq.open_upload ("overrides")); + parser mp (is, "overrides"); + overrides = parse_manifest (mp); + + package_manifest::validate_overrides (overrides, mp.name ()); + } + // Note that invalid_argument (thrown by open_upload() function call) can + // mean both no overrides upload or multiple overrides uploads. + // + catch (const invalid_argument&) + { + return respond_manifest (400, "overrides upload expected"); + } + catch (const parsing& e) + { + return respond_manifest (400, + string ("unable to parse overrides: ") + + e.what ()); + } + catch (const io_error& e) + { + error << "unable to read overrides: " << e; + return respond_error (); + } + try { // Note that from now on the result manifest we respond with will contain @@ -340,7 +377,7 @@ handle (request& rq, response& rs) s.next ("id", request_id); s.next ("repository", rl.string ()); - for (const string& p: params.package()) + for (const string& p: params.package ()) { if (!p.empty ()) // Skip empty package names (see above for details). s.next ("package", p); @@ -385,6 +422,7 @@ handle (request& rq, response& rs) if (n != "repository" && n != "_" && n != "package" && + n != "overrides" && n != "simulate") s.next (n, nv.value ? *nv.value : ""); } @@ -418,6 +456,39 @@ handle (request& rq, response& rs) return respond_error (); } + // Serialize the CI overrides manifest to a stream. On the stream error pass + // through the io_error exception. + // + // Note that it can't throw the serialization exception as the override + // manifest is parsed from the stream and so verified. + // + auto ovm = [&overrides] (ostream& os, bool long_lines = false) + { + try + { + serializer s (os, "overrides", long_lines); + serialize_manifest (s, overrides); + } + catch (const serialization&) {assert (false);} // See above. + }; + + // Serialize the CI overrides manifest to the submission directory. + // + path ovf (dd / "overrides.manifest"); + + if (!overrides.empty ()) + try + { + ofdstream os (ovf); + ovm (os); + os.close (); + } + catch (const io_error& e) + { + error << "unable to write to '" << ovf << "': " << e; + return respond_error (); + } + // Given that the submission data is now successfully persisted we are no // longer in charge of removing it, except for the cases when the submission // handler terminates with an error (see below for details). @@ -493,11 +564,9 @@ handle (request& rq, response& rs) rvs.emplace_back (move (nv)); }; - add ("", "1"); // Start of manifest. add ("status", "200"); add ("message", "CI request is queued"); add ("reference", request_id); - add ("", ""); // End of manifest. } assert (!rvs.empty ()); // Produced by the handler or is implied. @@ -512,9 +581,7 @@ handle (request& rq, response& rs) try { serializer s (os, "result", long_lines); - for (const manifest_name_value& nv: rvs) - s.next (nv.name, nv.value); - + serialize_manifest (s, rvs); return true; } catch (const serialization& e) @@ -592,12 +659,18 @@ handle (request& rq, response& rs) "CI request submission (" + request_id + ")", {options_->ci_email ()}); - // Write the submission request manifest. + // Write the CI request manifest. // bool r (rqm (sm.out, true /* long_lines */)); assert (r); // The serialization succeeded once, so can't fail now. - // Write the submission result manifest. + // Write the CI overrides manifest. + // + sm.out << "\n\n"; + + ovm (sm.out, true /* long_lines */); + + // Write the CI result manifest. // sm.out << "\n\n"; -- cgit v1.1