1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

Merge branch 'node-uuid-unique' of git.rwth-aachen.de:acs/public/villas/node into node-uuid-unique

This commit is contained in:
Steffen Vogel 2020-10-16 11:39:51 +02:00
commit 48e4a4a736
10 changed files with 86 additions and 53 deletions

2
common

@ -1 +1 @@
Subproject commit 3f3296e01752eddc02c077cb9a7e43171f69c75e
Subproject commit db106f50e053dc48c739c65e352d8885415e460b

View file

@ -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.
*

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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");

View file

@ -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);

View file

@ -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();

View file

@ -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);