From c90085012c6586d19ecc6cc158f2018c9dbfdd06 Mon Sep 17 00:00:00 2001 From: Matt Spinler Date: Mon, 21 Jan 2019 12:21:25 -0600 Subject: REST: Refactor software image upload Make the following fixes to the image upload code to make it behave like the phosphor-rest implementation, which should work for both UBI and non-UBI image formats. 1) Subscribe to an intefacesAdded signal on /xyz/openbmc_project/software upon invocation. 2) If the signal callback happens within 10s, check that the xyz.openbmc_project.Software.Version interface was created, and if it was read the version ID from the last segment of the object path in the signal data and return it in the call response. 3) If the callback doesn't occur within 10s, return a 400 error. Resolves openbmc/bmcweb#30 Change-Id: Ic9572488c13cadfb19c0d57a97833a627cf45df5 Signed-off-by: Matt Spinler --- include/image_upload.hpp | 63 +++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 22 deletions(-) (limited to 'include/image_upload.hpp') diff --git a/include/image_upload.hpp b/include/image_upload.hpp index 2b84db8a33..6b87530c0d 100644 --- a/include/image_upload.hpp +++ b/include/image_upload.hpp @@ -32,7 +32,7 @@ inline void uploadImageHandler(const crow::Request& req, crow::Response& res, static boost::asio::deadline_timer timeout(*req.ioService, boost::posix_time::seconds(5)); - timeout.expires_from_now(boost::posix_time::seconds(5)); + timeout.expires_from_now(boost::posix_time::seconds(10)); timeout.async_wait([&res](const boost::system::error_code& ec) { fwUpdateMatcher = nullptr; @@ -41,7 +41,7 @@ inline void uploadImageHandler(const crow::Request& req, crow::Response& res, // expected, we were canceled before the timer completed. return; } - BMCWEB_LOG_ERROR << "Timed out waiting for log event"; + BMCWEB_LOG_ERROR << "Timed out waiting for Version interface"; if (ec) { @@ -49,39 +49,58 @@ inline void uploadImageHandler(const crow::Request& req, crow::Response& res, return; } - res.result(boost::beast::http::status::internal_server_error); + res.result(boost::beast::http::status::bad_request); + res.jsonValue = { + {"data", + {{"description", + "Version already exists or failed to be extracted"}}}, + {"message", "400 Bad Request"}, + {"status", "error"}}; res.end(); }); std::function callback = [&res](sdbusplus::message::message& m) { BMCWEB_LOG_DEBUG << "Match fired"; - boost::system::error_code ec; - timeout.cancel(ec); - if (ec) - { - BMCWEB_LOG_ERROR << "error canceling timer " << ec; - } - std::string versionInfo; - m.read( - versionInfo); // Read in the object path that was just created - std::size_t index = versionInfo.rfind('/'); - if (index != std::string::npos) + sdbusplus::message::object_path path; + std::vector>>>> + interfaces; + m.read(path, interfaces); + + if (std::find_if(interfaces.begin(), interfaces.end(), + [](const auto& i) { + return i.first == + "xyz.openbmc_project.Software.Version"; + }) != interfaces.end()) { - versionInfo.erase(0, index); + boost::system::error_code ec; + timeout.cancel(ec); + if (ec) + { + BMCWEB_LOG_ERROR << "error canceling timer " << ec; + } + + std::size_t index = path.str.rfind('/'); + if (index != std::string::npos) + { + path.str.erase(0, index + 1); + } + res.jsonValue = {{"data", std::move(path.str)}, + {"message", "200 OK"}, + {"status", "ok"}}; + BMCWEB_LOG_DEBUG << "ending response"; + res.end(); + fwUpdateMatcher = nullptr; } - res.jsonValue = {{"data", std::move(versionInfo)}, - {"message", "200 OK"}, - {"status", "ok"}}; - BMCWEB_LOG_DEBUG << "ending response"; - res.end(); - fwUpdateMatcher = nullptr; }; fwUpdateMatcher = std::make_unique( *crow::connections::systemBus, "interface='org.freedesktop.DBus.ObjectManager',type='signal'," - "member='InterfacesAdded',path='/xyz/openbmc_project/logging'", + "member='InterfacesAdded',path='/xyz/openbmc_project/software'", callback); std::string filepath( -- cgit v1.2.3