summaryrefslogtreecommitdiff
path: root/include/image_upload.hpp
diff options
context:
space:
mode:
authorEd Tanous <ed.tanous@intel.com>2018-05-01 22:58:27 +0300
committerEd Tanous <ed.tanous@intel.com>2018-06-29 21:49:17 +0300
commitc3ee522f9a2950d9ce21bd0c8962624476ffe343 (patch)
tree451624bcb7f03646a7191890408c109ae5744be3 /include/image_upload.hpp
parent729dae72826e58134ca4e49587427703ad0286db (diff)
downloadbmcweb-c3ee522f9a2950d9ce21bd0c8962624476ffe343.tar.xz
Make bmcweb image upload compatible with upstream.
This change moves the image upload logic out of the intel oem namespace, and makes it 1:1 compatible with phosphor rest dbus. This is to allow a seamless transition in the future. Change-Id: I243237357a672934c05bf072e7ff1a5955af0f5e
Diffstat (limited to 'include/image_upload.hpp')
-rw-r--r--include/image_upload.hpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/include/image_upload.hpp b/include/image_upload.hpp
new file mode 100644
index 0000000000..2a959677df
--- /dev/null
+++ b/include/image_upload.hpp
@@ -0,0 +1,103 @@
+#pragma once
+
+#include <dbus_singleton.hpp>
+#include <cstdio>
+#include <fstream>
+#include <memory>
+#include <crow/app.h>
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/uuid/uuid_io.hpp>
+
+namespace crow {
+namespace image_upload {
+
+std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher;
+
+inline void uploadImageHandler(const crow::request& req, crow::response& res,
+ const std::string& filename) {
+ // Only allow one FW update at a time
+ if (fwUpdateMatcher != nullptr) {
+ res.add_header("Retry-After", "30");
+ res.result(boost::beast::http::status::service_unavailable);
+ res.end();
+ return;
+ }
+ // Make this const static so it survives outside this method
+ static boost::asio::deadline_timer timeout(*req.io_service,
+ boost::posix_time::seconds(5));
+
+ timeout.expires_from_now(boost::posix_time::seconds(5));
+
+ timeout.async_wait([&res](const boost::system::error_code& ec) {
+ fwUpdateMatcher = nullptr;
+ if (ec == asio::error::operation_aborted) {
+ // expected, we were canceled before the timer completed.
+ return;
+ }
+ CROW_LOG_ERROR << "Timed out waiting for log event";
+
+ if (ec) {
+ CROW_LOG_ERROR << "Async_wait failed " << ec;
+ return;
+ }
+
+ res.result(boost::beast::http::status::internal_server_error);
+ res.end();
+ });
+
+ std::function<void(sdbusplus::message::message&)> callback =
+ [&res](sdbusplus::message::message& m) {
+ CROW_LOG_DEBUG << "Match fired";
+ boost::system::error_code ec;
+ timeout.cancel(ec);
+ if (ec) {
+ CROW_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) {
+ versionInfo.erase(0, index);
+ }
+ res.json_value = {{"data", std::move(versionInfo)},
+ {"message", "200 OK"},
+ {"status", "ok"}};
+ CROW_LOG_DEBUG << "ending response";
+ res.end();
+ fwUpdateMatcher = nullptr;
+ };
+ fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
+ *crow::connections::system_bus,
+ "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
+ "member='InterfacesAdded',path='/xyz/openbmc_project/logging'",
+ callback);
+
+ std::string filepath(
+ "/tmp/images/" +
+ boost::uuids::to_string(boost::uuids::random_generator()()));
+ CROW_LOG_DEBUG << "Writing file to " << filepath;
+ std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
+ std::ofstream::trunc);
+ out << req.body;
+ out.close();
+}
+
+template <typename... Middlewares>
+void requestRoutes(Crow<Middlewares...>& app) {
+ CROW_ROUTE(app, "/upload/image/<str>")
+ .methods("POST"_method,
+ "PUT"_method)([](const crow::request& req, crow::response& res,
+ const std::string& filename) {
+ uploadImageHandler(req, res, filename);
+ });
+
+ CROW_ROUTE(app, "/upload/image")
+ .methods("POST"_method,
+ "PUT"_method)([](const crow::request& req, crow::response& res) {
+ uploadImageHandler(req, res, "");
+ });
+}
+} // namespace image_upload
+} // namespace crow