mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
derive auto-generated uuid for nodes, paths and relay-sessions from instance uuid
This commit is contained in:
parent
1bd4d8b2d4
commit
7708980e2d
9 changed files with 85 additions and 52 deletions
|
@ -112,7 +112,7 @@ int node_prepare(struct vnode *n);
|
|||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int node_parse(struct vnode *n, json_t *cfg, const char *name);
|
||||
int node_parse(struct vnode *n, json_t *cfg, const uuid_t sn_uuid);
|
||||
|
||||
/** Parse an array or single node and checks if they exist in the "nodes" section.
|
||||
*
|
||||
|
|
|
@ -155,7 +155,7 @@ int path_reverse(struct vpath *p, struct vpath *r);
|
|||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes);
|
||||
int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t sn_uuid);
|
||||
|
||||
void path_parse_mask(struct vpath *p, json_t *json_mask, struct vlist *nodes);
|
||||
|
||||
|
|
|
@ -29,9 +29,7 @@
|
|||
#include <villas/api/request.hpp>
|
||||
#include <villas/api/response.hpp>
|
||||
|
||||
#ifndef UUID_STR_LEN
|
||||
#define UUID_STR_LEN 37
|
||||
#endif
|
||||
typedef char uuid_string_t[37];
|
||||
|
||||
namespace villas {
|
||||
namespace node {
|
||||
|
@ -73,10 +71,10 @@ public:
|
|||
auto *sn = session->getSuperNode();
|
||||
|
||||
uuid_t uuid;
|
||||
uuid_string_t uuid_str;
|
||||
struct utsname uts;
|
||||
struct sysinfo sinfo;
|
||||
char hname[128];
|
||||
char uuid_str[UUID_STR_LEN];
|
||||
|
||||
sn->getUUID(uuid);
|
||||
uuid_unparse_lower(uuid, uuid_str);
|
||||
|
|
19
lib/node.cpp
19
lib/node.cpp
|
@ -133,7 +133,7 @@ int node_prepare(struct vnode *n)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int node_parse(struct vnode *n, json_t *json, const char *name)
|
||||
int node_parse(struct vnode *n, json_t *json, const uuid_t sn_uuid)
|
||||
{
|
||||
int ret, enabled = n->enabled;
|
||||
|
||||
|
@ -141,18 +141,16 @@ int node_parse(struct vnode *n, json_t *json, const char *name)
|
|||
json_t *json_netem = nullptr;
|
||||
|
||||
const char *uuid_str = nullptr;
|
||||
const char *name_str = nullptr;
|
||||
|
||||
n->name = strdup(name);
|
||||
|
||||
ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: b }",
|
||||
ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s?: b }",
|
||||
"name", &name_str,
|
||||
"uuid", &uuid_str,
|
||||
"enabled", &enabled
|
||||
);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
n->enabled = enabled;
|
||||
|
||||
#ifdef __linux__
|
||||
ret = json_unpack_ex(json, &err, 0, "{ s?: { s?: o, s?: i } }",
|
||||
"out",
|
||||
|
@ -163,6 +161,13 @@ int node_parse(struct vnode *n, json_t *json, const char *name)
|
|||
return ret;
|
||||
#endif /* __linux__ */
|
||||
|
||||
n->enabled = enabled;
|
||||
|
||||
if (name_str)
|
||||
n->name = strdup(name_str);
|
||||
else
|
||||
n->name = strdup("<none>");
|
||||
|
||||
if (uuid_str) {
|
||||
ret = uuid_parse(uuid_str, n->uuid);
|
||||
if (ret)
|
||||
|
@ -170,7 +175,7 @@ int node_parse(struct vnode *n, json_t *json, const char *name)
|
|||
}
|
||||
else
|
||||
/* Generate UUID from hashed config including node name */
|
||||
uuid_generate_from_json(n->uuid, json, name);
|
||||
uuid_generate_from_json(n->uuid, json, sn_uuid);
|
||||
|
||||
if (json_netem) {
|
||||
#ifdef WITH_NETEM
|
||||
|
|
|
@ -386,7 +386,7 @@ int path_prepare(struct vpath *p, struct vlist *nodes)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes)
|
||||
int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t sn_uuid)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -442,7 +442,7 @@ int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes)
|
|||
}
|
||||
else
|
||||
/* Generate UUID from hashed config */
|
||||
uuid_generate_from_json(p->uuid, cfg);
|
||||
uuid_generate_from_json(p->uuid, cfg, sn_uuid);
|
||||
|
||||
/* Input node(s) */
|
||||
ret = mapping_list_parse(&p->mappings, json_in);
|
||||
|
|
|
@ -74,6 +74,7 @@ SuperNode::SuperNode() :
|
|||
if (ret)
|
||||
throw SystemError("Failed to determine hostname");
|
||||
|
||||
/* Default UUID is derived from hostname */
|
||||
uuid_generate_from_str(uuid, hname);
|
||||
|
||||
ret = vlist_init(&nodes);
|
||||
|
@ -163,6 +164,8 @@ void SuperNode::parse(json_t *root)
|
|||
if (ret)
|
||||
throw ConfigError(root, err, "node-config-node-type", "Failed to parse type of node '{}'", name);
|
||||
|
||||
json_object_set(json_node, "name", json_string(name));
|
||||
|
||||
nt = node_type_lookup(type);
|
||||
if (!nt)
|
||||
throw ConfigError(json_node, "node-config-node-type", "Invalid node type: {}", type);
|
||||
|
@ -175,7 +178,7 @@ void SuperNode::parse(json_t *root)
|
|||
if (ret)
|
||||
throw RuntimeError("Failed to initialize node");
|
||||
|
||||
ret = node_parse(n, json_node, name);
|
||||
ret = node_parse(n, json_node, uuid);
|
||||
if (ret) {
|
||||
auto config_id = fmt::format("node-config-node-{}", type);
|
||||
|
||||
|
@ -202,7 +205,7 @@ parse: auto *p = new vpath;
|
|||
if (ret)
|
||||
throw RuntimeError("Failed to initialize path");
|
||||
|
||||
ret = path_parse(p, json_path, &nodes);
|
||||
ret = path_parse(p, json_path, &nodes, uuid);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to parse path");
|
||||
|
||||
|
|
|
@ -30,21 +30,26 @@
|
|||
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <jansson.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <villas/node/config.h>
|
||||
#include <villas/compat.hpp>
|
||||
#include <villas/memory.h>
|
||||
#include <villas/tool.hpp>
|
||||
#include <villas/log.hpp>
|
||||
#include <villas/utils.hpp>
|
||||
|
||||
#include "villas-relay.hpp"
|
||||
|
||||
typedef char uuid_string_t[37];
|
||||
|
||||
using namespace villas::utils;
|
||||
|
||||
namespace villas {
|
||||
namespace node {
|
||||
namespace tools {
|
||||
|
||||
RelaySession::RelaySession(Identifier sid) :
|
||||
RelaySession::RelaySession(Relay *r, Identifier sid) :
|
||||
identifier(sid),
|
||||
connects(0)
|
||||
{
|
||||
|
@ -56,7 +61,7 @@ RelaySession::RelaySession(Identifier sid) :
|
|||
|
||||
created = time(nullptr);
|
||||
|
||||
uuid_generate(uuid);
|
||||
uuid_generate_from_str(uuid, identifier, r->uuid);
|
||||
}
|
||||
|
||||
RelaySession::~RelaySession()
|
||||
|
@ -68,7 +73,7 @@ RelaySession::~RelaySession()
|
|||
sessions.erase(identifier);
|
||||
}
|
||||
|
||||
RelaySession * RelaySession::get(lws *wsi)
|
||||
RelaySession * RelaySession::get(Relay *r, lws *wsi)
|
||||
{
|
||||
Logger logger = villas::logging.get("console");
|
||||
|
||||
|
@ -88,7 +93,7 @@ RelaySession * RelaySession::get(lws *wsi)
|
|||
|
||||
auto it = sessions.find(sid);
|
||||
if (it == sessions.end()) {
|
||||
auto *rs = new RelaySession(sid);
|
||||
auto *rs = new RelaySession(r, sid);
|
||||
if (!rs)
|
||||
throw MemoryAllocationError();
|
||||
|
||||
|
@ -111,7 +116,7 @@ json_t * RelaySession::toJson() const
|
|||
json_array_append(json_connections, conn->toJson());
|
||||
}
|
||||
|
||||
char uuid_str[UUID_STR_LEN];
|
||||
uuid_string_t uuid_str;
|
||||
uuid_unparse_lower(uuid, uuid_str);
|
||||
|
||||
return json_pack("{ s: s, s: s, s: o, s: I, s: i }",
|
||||
|
@ -125,7 +130,7 @@ json_t * RelaySession::toJson() const
|
|||
|
||||
std::map<std::string, RelaySession *> RelaySession::sessions;
|
||||
|
||||
RelayConnection::RelayConnection(lws *w, bool lo) :
|
||||
RelayConnection::RelayConnection(Relay *r, lws *w, bool lo) :
|
||||
wsi(w),
|
||||
currentFrame(std::make_shared<Frame>()),
|
||||
outgoingFrames(),
|
||||
|
@ -137,7 +142,7 @@ RelayConnection::RelayConnection(lws *w, bool lo) :
|
|||
{
|
||||
Logger logger = villas::logging.get("console");
|
||||
|
||||
session = RelaySession::get(wsi);
|
||||
session = RelaySession::get(r, wsi);
|
||||
session->connections[wsi] = this;
|
||||
session->connects++;
|
||||
|
||||
|
@ -232,13 +237,23 @@ Relay::Relay(int argc, char *argv[]) :
|
|||
{
|
||||
int ret;
|
||||
|
||||
char hname[128];
|
||||
ret = gethostname(hname, sizeof(hname));
|
||||
if (ret)
|
||||
throw SystemError("Failed to get hostname");
|
||||
|
||||
hostname = hname;
|
||||
|
||||
/* Default UUID is derived from hostname */
|
||||
uuid_generate_from_str(uuid, hname);
|
||||
|
||||
ret = memory_init(0);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize memory");
|
||||
|
||||
/* Initialize logging */
|
||||
spdlog::stdout_color_mt("lws");
|
||||
lws_set_log_level((1 << LLL_COUNT) - 1, logger_cb);
|
||||
lws_set_log_level((1 << LLL_COUNT) - 1, loggerCallback);
|
||||
|
||||
protocols = {
|
||||
{
|
||||
|
@ -249,13 +264,13 @@ Relay::Relay(int argc, char *argv[]) :
|
|||
},
|
||||
{
|
||||
.name = "http-api",
|
||||
.callback = http_protocol_cb,
|
||||
.callback = httpProtocolCallback,
|
||||
.per_session_data_size = 0,
|
||||
.rx_buffer_size = 1024
|
||||
},
|
||||
{
|
||||
.name = "live",
|
||||
.callback = protocol_cb,
|
||||
.callback = protocolCallback,
|
||||
.per_session_data_size = sizeof(RelayConnection),
|
||||
.rx_buffer_size = 0
|
||||
},
|
||||
|
@ -263,7 +278,7 @@ Relay::Relay(int argc, char *argv[]) :
|
|||
};
|
||||
}
|
||||
|
||||
void Relay::logger_cb(int level, const char *msg)
|
||||
void Relay::loggerCallback(int level, const char *msg)
|
||||
{
|
||||
auto log = spdlog::get("lws");
|
||||
|
||||
|
@ -294,7 +309,7 @@ void Relay::logger_cb(int level, const char *msg)
|
|||
}
|
||||
}
|
||||
|
||||
int Relay::http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
||||
int Relay::httpProtocolCallback(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
||||
{
|
||||
int ret;
|
||||
size_t json_len;
|
||||
|
@ -332,13 +347,14 @@ int Relay::http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *us
|
|||
json_array_append(json_sessions, session->toJson());
|
||||
}
|
||||
|
||||
char hname[128];
|
||||
gethostname(hname, 128);
|
||||
uuid_string_t uuid_str;
|
||||
uuid_unparse(r->uuid, uuid_str);
|
||||
|
||||
json_body = json_pack("{ s: o, s: s, s: s, s: { s: b, s: i, s: s } }",
|
||||
json_body = json_pack("{ s: o, s: s, s: s, s: s, s: { s: b, s: i, s: s } }",
|
||||
"sessions", json_sessions,
|
||||
"version", PROJECT_VERSION_STR,
|
||||
"hostname", hname,
|
||||
"hostname", r->hostname.c_str(),
|
||||
"uuid", uuid_str,
|
||||
"options",
|
||||
"loopback", r->loopback,
|
||||
"port", r->port,
|
||||
|
@ -363,7 +379,7 @@ int Relay::http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *us
|
|||
return lws_callback_http_dummy(wsi, reason, user, in, len);
|
||||
}
|
||||
|
||||
int Relay::protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
||||
int Relay::protocolCallback(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
|
||||
{
|
||||
lws_context *ctx = lws_get_context(wsi);
|
||||
void *user_ctx = lws_context_user(ctx);
|
||||
|
@ -375,7 +391,7 @@ int Relay::protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, v
|
|||
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
try {
|
||||
new (c) RelayConnection(wsi, r->loopback);
|
||||
new (c) RelayConnection(r, wsi, r->loopback);
|
||||
}
|
||||
catch (const InvalidUrlException &e) {
|
||||
lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, (unsigned char *) "Invalid URL", strlen("Invalid URL"));
|
||||
|
@ -411,6 +427,7 @@ void Relay::usage()
|
|||
<< " -p PORT the port number to listen on" << std::endl
|
||||
<< " -P PROT the websocket protocol" << std::endl
|
||||
<< " -l enable loopback of own data" << std::endl
|
||||
<< " -u UUID unique instance id" << std::endl
|
||||
<< " -V show version and exit" << std::endl
|
||||
<< " -h show usage and exit" << std::endl << std::endl;
|
||||
|
||||
|
@ -419,8 +436,9 @@ void Relay::usage()
|
|||
|
||||
void Relay::parse()
|
||||
{
|
||||
int ret;
|
||||
char c, *endptr;
|
||||
while ((c = getopt (argc, argv, "hVp:P:ld:")) != -1) {
|
||||
while ((c = getopt (argc, argv, "hVp:P:ld:u:")) != -1) {
|
||||
switch (c) {
|
||||
case 'd':
|
||||
spdlog::set_level(spdlog::level::from_str(optarg));
|
||||
|
@ -438,6 +456,14 @@ void Relay::parse()
|
|||
loopback = true;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
ret = uuid_parse(optarg, uuid);
|
||||
if (ret) {
|
||||
logger->error("Failed to parse UUID: {}", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
printVersion();
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
|
@ -27,10 +27,6 @@
|
|||
#include <spdlog/spdlog.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#ifndef UUID_STR_LEN
|
||||
#define UUID_STR_LEN 37
|
||||
#endif
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
namespace villas {
|
||||
|
@ -38,13 +34,14 @@ namespace node {
|
|||
namespace tools {
|
||||
|
||||
/* Forward declarations */
|
||||
lws_callback_function protocol_cb, http_protocol_cb;
|
||||
class Relay;
|
||||
class RelaySession;
|
||||
class RelayConnection;
|
||||
|
||||
class InvalidUrlException { };
|
||||
|
||||
typedef std::string Identifier;
|
||||
|
||||
class Frame : public std::vector<uint8_t> {
|
||||
public:
|
||||
Frame() {
|
||||
|
@ -66,14 +63,10 @@ class RelaySession {
|
|||
friend RelayConnection;
|
||||
friend Relay;
|
||||
|
||||
public:
|
||||
typedef std::string Identifier;
|
||||
|
||||
protected:
|
||||
time_t created;
|
||||
uuid_t uuid;
|
||||
|
||||
|
||||
Identifier identifier;
|
||||
|
||||
std::map<lws *, RelayConnection *> connections;
|
||||
|
@ -83,9 +76,9 @@ protected:
|
|||
static std::map<std::string, RelaySession *> sessions;
|
||||
|
||||
public:
|
||||
static RelaySession * get(lws *wsi);
|
||||
static RelaySession * get(Relay *r, lws *wsi);
|
||||
|
||||
RelaySession(Identifier sid);
|
||||
RelaySession(Relay *r, Identifier sid);
|
||||
|
||||
~RelaySession();
|
||||
|
||||
|
@ -116,7 +109,7 @@ protected:
|
|||
bool loopback;
|
||||
|
||||
public:
|
||||
RelayConnection(lws *w, bool lo);
|
||||
RelayConnection(Relay *r, lws *w, bool lo);
|
||||
~RelayConnection();
|
||||
|
||||
json_t * toJson() const;
|
||||
|
@ -128,6 +121,8 @@ public:
|
|||
class Relay : public Tool {
|
||||
|
||||
public:
|
||||
friend RelaySession;
|
||||
|
||||
Relay(int argc, char *argv[]);
|
||||
|
||||
protected:
|
||||
|
@ -142,6 +137,9 @@ protected:
|
|||
bool loopback;
|
||||
int port;
|
||||
std::string protocol;
|
||||
std::string hostname;
|
||||
|
||||
uuid_t uuid;
|
||||
|
||||
/** List of libwebsockets protocols. */
|
||||
std::vector<lws_protocols> protocols;
|
||||
|
@ -151,11 +149,11 @@ protected:
|
|||
|
||||
static const lws_http_mount mount;
|
||||
|
||||
static void logger_cb(int level, const char *msg);
|
||||
static void loggerCallback(int level, const char *msg);
|
||||
|
||||
static int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
static int httpProtocolCallback(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
|
||||
static int protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
static int protocolCallback(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
|
||||
void usage();
|
||||
|
||||
|
|
|
@ -235,7 +235,10 @@ check: if (optarg == endptr)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = node_parse(&n, cfg, "cli");
|
||||
uuid_t uuid;
|
||||
uuid_clear(uuid);
|
||||
|
||||
ret = node_parse(&n, cfg, uuid);
|
||||
if (ret) {
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
Loading…
Add table
Reference in a new issue