Skip to content

Commit

Permalink
Add agent CLI command to remove a stale node (netdata#17691)
Browse files Browse the repository at this point in the history
* Mark the node as ephemeral in the database
Remove node command

* Do not unregister the localhost
Do not unregister a live node
Make sure we rewrite the ephemeral value when a child reconnects
  • Loading branch information
stelfrag authored May 20, 2024
1 parent 05dd823 commit 9726ca1
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 4 deletions.
8 changes: 5 additions & 3 deletions src/collectors/plugins.d/pluginsd_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,10 +649,12 @@ static inline PARSER_RC pluginsd_label(char **words, size_t num_words, PARSER *p

if (strcmp(name,HOST_LABEL_IS_EPHEMERAL) == 0) {
int is_ephemeral = appconfig_test_boolean_value((char *) value);
if (is_ephemeral) {
RRDHOST *host = pluginsd_require_scope_host(parser, PLUGINSD_KEYWORD_LABEL);
if (likely(host))
RRDHOST *host = pluginsd_require_scope_host(parser, PLUGINSD_KEYWORD_LABEL);
if (host) {
if (is_ephemeral)
rrdhost_option_set(host, RRDHOST_OPTION_EPHEMERAL_HOST);
else
rrdhost_option_clear(host, RRDHOST_OPTION_EPHEMERAL_HOST);
}
}

Expand Down
54 changes: 53 additions & 1 deletion src/daemon/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ static cmd_status_t cmd_ping_execute(char *args, char **message);
static cmd_status_t cmd_aclk_state(char *args, char **message);
static cmd_status_t cmd_version(char *args, char **message);
static cmd_status_t cmd_dumpconfig(char *args, char **message);
static cmd_status_t cmd_remove_node(char *args, char **message);

static command_info_t command_info_array[] = {
{"help", cmd_help_execute, CMD_TYPE_HIGH_PRIORITY}, // show help menu
Expand All @@ -61,7 +62,8 @@ static command_info_t command_info_array[] = {
{"ping", cmd_ping_execute, CMD_TYPE_ORTHOGONAL},
{"aclk-state", cmd_aclk_state, CMD_TYPE_ORTHOGONAL},
{"version", cmd_version, CMD_TYPE_ORTHOGONAL},
{"dumpconfig", cmd_dumpconfig, CMD_TYPE_ORTHOGONAL}
{"dumpconfig", cmd_dumpconfig, CMD_TYPE_ORTHOGONAL},
{"remove-stale-node", cmd_remove_node, CMD_TYPE_ORTHOGONAL}
};

/* Mutexes for commands of type CMD_TYPE_ORTHOGONAL */
Expand Down Expand Up @@ -129,6 +131,8 @@ static cmd_status_t cmd_help_execute(char *args, char **message)
" Returns current state of ACLK and Cloud connection. (optionally in json).\n"
"dumpconfig\n"
" Returns the current netdata.conf on stdout.\n"
"remove-stale-node node_id|machine_guid\n"
" Unregisters and removes a node from the cloud.\n"
"version\n"
" Returns the netdata version.\n",
MAX_COMMAND_LENGTH - 1);
Expand Down Expand Up @@ -326,6 +330,54 @@ static cmd_status_t cmd_dumpconfig(char *args, char **message)
return CMD_STATUS_SUCCESS;
}

static cmd_status_t cmd_remove_node(char *args, char **message)
{
(void)args;

BUFFER *wb = buffer_create(1024, NULL);
if (strlen(args) == 0) {
buffer_sprintf(wb, "Please specify a machine or node UUID");
goto done;
}

RRDHOST *host = NULL;
host = rrdhost_find_by_guid(args);
if (!host)
host = find_host_by_node_id(args);

if (!host)
buffer_sprintf(wb, "Node with machine or node UUID \"%s\" not found", args);
else {

if (host == localhost) {
buffer_sprintf(wb, "You cannot unregister the parent node");
goto done;
}

if (rrdhost_is_online(host)) {
buffer_sprintf(wb, "Cannot unregister a live node");
goto done;
}

if (!rrdhost_option_check(host, RRDHOST_OPTION_EPHEMERAL_HOST)) {
rrdhost_option_set(host, RRDHOST_OPTION_EPHEMERAL_HOST);
sql_set_host_label(&host->host_uuid, "_is_ephemeral", "true");
aclk_host_state_update(host, 0, 0);
unregister_node(host->machine_guid);
freez(host->node_id);
host->node_id = NULL;
buffer_sprintf(wb, "Unregistering node with machine guid %s, hostname = %s", host->machine_guid, rrdhost_hostname(host));
}
else
buffer_sprintf(wb, "Node with machine guid %s, hostname = %s is already unregistered", host->machine_guid, rrdhost_hostname(host));
}

done:
*message = strdupz(buffer_tostring(wb));
buffer_free(wb);
return CMD_STATUS_SUCCESS;
}

static void cmd_lock_exclusive(unsigned index)
{
(void)index;
Expand Down
1 change: 1 addition & 0 deletions src/daemon/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ typedef enum cmd {
CMD_ACLK_STATE,
CMD_VERSION,
CMD_DUMPCONFIG,
CMD_REMOVE_NODE,
CMD_TOTAL_COMMANDS
} cmd_t;

Expand Down
34 changes: 34 additions & 0 deletions src/database/sqlite/sqlite_metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,40 @@ static inline void set_host_node_id(RRDHOST *host, nd_uuid_t *node_id)
uuid_unparse_lower(*node_id, wc->node_id);
}

#define SQL_SET_HOST_LABEL \
"INSERT INTO host_label (host_id, source_type, label_key, label_value, date_created) " \
"VALUES (@host_id, @source_type, @label_key, @label_value, UNIXEPOCH()) ON CONFLICT (host_id, label_key) " \
" DO UPDATE SET source_type = excluded.source_type, label_value=excluded.label_value, date_created=UNIXEPOCH()"

bool sql_set_host_label(nd_uuid_t *host_id, const char *label_key, const char *label_value)
{
sqlite3_stmt *res = NULL;
bool status = false;

if (!label_key || !label_value || !host_id)
return false;

if (!PREPARE_STATEMENT(db_meta, SQL_SET_HOST_LABEL, &res))
return 1;

int param = 0;
SQLITE_BIND_FAIL(done, sqlite3_bind_blob(res, ++param, host_id, sizeof(*host_id), SQLITE_STATIC));
SQLITE_BIND_FAIL(done, sqlite3_bind_int(res, ++param, RRDLABEL_SRC_AUTO));
SQLITE_BIND_FAIL(done, sqlite3_bind_text(res, ++param, label_key, -1, SQLITE_STATIC));
SQLITE_BIND_FAIL(done, sqlite3_bind_text(res, ++param, label_value, -1, SQLITE_STATIC));

param = 0;
int rc = execute_insert(res);
status = (rc == SQLITE_DONE);
if (false == status)
error_report("Failed to store node instance information, rc = %d", rc);
done:
REPORT_BIND_FAIL(res, param);
SQLITE_FINALIZE(res);
return status;
}


#define SQL_UPDATE_NODE_ID "UPDATE node_instance SET node_id = @node_id WHERE host_id = @host_id"

int update_node_id(nd_uuid_t *host_id, nd_uuid_t *node_id)
Expand Down
1 change: 1 addition & 0 deletions src/database/sqlite/sqlite_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void sql_load_node_id(RRDHOST *host);
void sql_build_host_system_info(nd_uuid_t *host_id, struct rrdhost_system_info *system_info);
void invalidate_node_instances(nd_uuid_t *host_id, nd_uuid_t *claim_id);
RRDLABELS *sql_load_host_labels(nd_uuid_t *host_id);
bool sql_set_host_label(nd_uuid_t *host_id, const char *label_key, const char *label_value);

uint64_t sqlite_get_meta_space(void);
int sql_init_meta_database(db_check_action_type_t rebuild, int memory);
Expand Down

0 comments on commit 9726ca1

Please sign in to comment.