Skip to content

Commit

Permalink
Implement nbd-proxy as a part of bmcweb
Browse files Browse the repository at this point in the history
Nbd-proxy is responsible for exposing websocket endpoint in bmcweb.
It matches WS endpoints with unix socket paths using configuration
exposed on D-Bus by Virtual-Media.

Virtual-Media is then notified about unix socket availability through
mount/unmount D-Bus methods.

Currently, this feature is disabled by default.

Tested: Integrated with initial version of Virtual-Media.

Change-Id: I9c572e9841b16785727e5676fea1bb63b0311c63
Signed-off-by: Iwona Klimaszewska <iwona.klimaszewska@intel.com>
Signed-off-by: Przemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com>
  • Loading branch information
Iwona Klimaszewska committed Nov 21, 2019
1 parent e6604b1 commit c0a1c8a
Show file tree
Hide file tree
Showing 10 changed files with 446 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Expand Up @@ -22,6 +22,11 @@ option (
See https://github.com/openbmc/jsnbd/blob/master/README."
ON
)
option (
BMCWEB_ENABLE_VM_NBDPROXY
"Enable the Virtual Media WebSocket."
OFF
)
option (
BMCWEB_ENABLE_DBUS_REST
"Enable Phosphor REST (D-Bus) APIs. Paths directly map Phosphor D-Bus
Expand Down Expand Up @@ -360,6 +365,7 @@ target_compile_definitions (
bmcweb PRIVATE $<$<BOOL:${BMCWEB_ENABLE_KVM}>: -DBMCWEB_ENABLE_KVM>
$<$<BOOL:${BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION}>: -DBMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION>
$<$<BOOL:${BMCWEB_ENABLE_VM_WEBSOCKET}>: -DBMCWEB_ENABLE_VM_WEBSOCKET>
$<$<BOOL:${BMCWEB_ENABLE_VM_NBDPROXY}>: -DBMCWEB_ENABLE_VM_NBDPROXY>
$<$<BOOL:${BMCWEB_ENABLE_DBUS_REST}>: -DBMCWEB_ENABLE_DBUS_REST>
$<$<BOOL:${BMCWEB_ENABLE_REDFISH}>: -DBMCWEB_ENABLE_REDFISH>
$<$<BOOL:${BMCWEB_ENABLE_STATIC_HOSTING}>: -DBMCWEB_ENABLE_STATIC_HOSTING>
Expand Down
13 changes: 8 additions & 5 deletions http/routing.h
Expand Up @@ -3,6 +3,7 @@
#include "privileges.hpp"
#include "sessions.hpp"

#include <async_resp.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/small_vector.hpp>
#include <boost/lexical_cast.hpp>
Expand Down Expand Up @@ -323,27 +324,27 @@ class WebSocketRule : public BaseRule
res.end();
}

void handleUpgrade(const Request& req, Response&,
void handleUpgrade(const Request& req, Response& res,
boost::asio::ip::tcp::socket&& adaptor) override
{
std::shared_ptr<
crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>
myConnection = std::make_shared<
crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>(
req, std::move(adaptor), openHandler, messageHandler,
req, res, std::move(adaptor), openHandler, messageHandler,
closeHandler, errorHandler);
myConnection->start();
}
#ifdef BMCWEB_ENABLE_SSL
void handleUpgrade(const Request& req, Response&,
void handleUpgrade(const Request& req, Response& res,
boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&&
adaptor) override
{
std::shared_ptr<crow::websocket::ConnectionImpl<
boost::beast::ssl_stream<boost::asio::ip::tcp::socket>>>
myConnection = std::make_shared<crow::websocket::ConnectionImpl<
boost::beast::ssl_stream<boost::asio::ip::tcp::socket>>>(
req, std::move(adaptor), openHandler, messageHandler,
req, res, std::move(adaptor), openHandler, messageHandler,
closeHandler, errorHandler);
myConnection->start();
}
Expand Down Expand Up @@ -374,7 +375,9 @@ class WebSocketRule : public BaseRule
}

protected:
std::function<void(crow::websocket::Connection&)> openHandler;
std::function<void(crow::websocket::Connection&,
std::shared_ptr<bmcweb::AsyncResp>)>
openHandler;
std::function<void(crow::websocket::Connection&, const std::string&, bool)>
messageHandler;
std::function<void(crow::websocket::Connection&, const std::string&)>
Expand Down
23 changes: 16 additions & 7 deletions http/websocket.h
@@ -1,5 +1,6 @@
#pragma once
#include <array>
#include <async_resp.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/beast/websocket.hpp>
Expand All @@ -15,10 +16,11 @@ namespace crow
{
namespace websocket
{

struct Connection : std::enable_shared_from_this<Connection>
{
public:
explicit Connection(const crow::Request& reqIn) :
explicit Connection(const crow::Request& reqIn, crow::Response& res) :
req(reqIn), userdataPtr(nullptr){};

virtual void sendBinary(const std::string_view msg) = 0;
Expand All @@ -39,6 +41,7 @@ struct Connection : std::enable_shared_from_this<Connection>
}

crow::Request req;
crow::Response res;

private:
void* userdataPtr;
Expand All @@ -48,13 +51,14 @@ template <typename Adaptor> class ConnectionImpl : public Connection
{
public:
ConnectionImpl(
const crow::Request& reqIn, Adaptor adaptorIn,
std::function<void(Connection&)> open_handler,
const crow::Request& reqIn, crow::Response& res, Adaptor adaptorIn,
std::function<void(Connection&, std::shared_ptr<bmcweb::AsyncResp>)>
open_handler,
std::function<void(Connection&, const std::string&, bool)>
message_handler,
std::function<void(Connection&, const std::string&)> close_handler,
std::function<void(Connection&)> error_handler) :
Connection(reqIn),
Connection(reqIn, res),
ws(std::move(adaptorIn)), inString(), inBuffer(inString, 131088),
openHandler(std::move(open_handler)),
messageHandler(std::move(message_handler)),
Expand Down Expand Up @@ -158,11 +162,15 @@ template <typename Adaptor> class ConnectionImpl : public Connection
{
BMCWEB_LOG_DEBUG << "Websocket accepted connection";

auto asyncResp = std::make_shared<bmcweb::AsyncResp>(
res, [this, self(shared_from_this())]() { doRead(); });

asyncResp->res.result(boost::beast::http::status::ok);

if (openHandler)
{
openHandler(*this);
openHandler(*this, asyncResp);
}
doRead();
}

void doRead()
Expand Down Expand Up @@ -241,7 +249,8 @@ template <typename Adaptor> class ConnectionImpl : public Connection
std::vector<std::string> outBuffer;
bool doingWrite = false;

std::function<void(Connection&)> openHandler;
std::function<void(Connection&, std::shared_ptr<bmcweb::AsyncResp>)>
openHandler;
std::function<void(Connection&, const std::string&, bool)> messageHandler;
std::function<void(Connection&, const std::string&)> closeHandler;
std::function<void(Connection&)> errorHandler;
Expand Down
16 changes: 15 additions & 1 deletion include/async_resp.hpp
@@ -1,25 +1,39 @@
#pragma once

#include <functional>

namespace bmcweb
{

/**
* AsyncResp
* Gathers data needed for response processing after async calls are done
*/

class AsyncResp
{
public:
AsyncResp(crow::Response& response) : res(response)
{
}

AsyncResp(crow::Response& response, std::function<void()>&& function) :
res(response), func(std::move(function))
{
}

~AsyncResp()
{
if (func && res.result() == boost::beast::http::status::ok)
{
func();
}

res.end();
}

crow::Response& res;
std::function<void()> func = 0;
};

} // namespace bmcweb
} // namespace bmcweb
4 changes: 3 additions & 1 deletion include/dbus_monitor.hpp
Expand Up @@ -2,6 +2,7 @@
#include <app.h>
#include <websocket.h>

#include <async_resp.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <dbus_singleton.hpp>
Expand Down Expand Up @@ -116,7 +117,8 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
BMCWEB_ROUTE(app, "/subscribe")
.requires({"Login"})
.websocket()
.onopen([&](crow::websocket::Connection& conn) {
.onopen([&](crow::websocket::Connection& conn,
std::shared_ptr<bmcweb::AsyncResp> asyncResp) {
BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";
sessions[&conn] = DbusWebsocketSession();
})
Expand Down
4 changes: 3 additions & 1 deletion include/kvm_websocket.hpp
Expand Up @@ -3,6 +3,7 @@
#include <sys/socket.h>
#include <websocket.h>

#include <async_resp.hpp>
#include <boost/container/flat_map.hpp>
#include <webserver_common.hpp>

Expand Down Expand Up @@ -161,7 +162,8 @@ inline void requestRoutes(CrowApp& app)
BMCWEB_ROUTE(app, "/kvm/0")
.requires({"ConfigureComponents", "ConfigureManager"})
.websocket()
.onopen([](crow::websocket::Connection& conn) {
.onopen([](crow::websocket::Connection& conn,
std::shared_ptr<bmcweb::AsyncResp> asyncResp) {
BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";

if (sessions.size() == maxSessions)
Expand Down

0 comments on commit c0a1c8a

Please sign in to comment.