diff --git a/.gitignore b/.gitignore index 284fcda506..f94c5603a3 100644 --- a/.gitignore +++ b/.gitignore @@ -116,6 +116,7 @@ daemon/anonymous-statistics.sh daemon/get-kubernetes-labels.sh health/notifications/alarm-notify.sh +claim/netdata-claim.sh collectors/cgroups.plugin/cgroup-name.sh collectors/tc.plugin/tc-qos-helper.sh collectors/charts.d.plugin/charts.d.plugin diff --git a/BUILD.md b/BUILD.md index e22e6a2fff..5ad4bdbaef 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,4 +1,3 @@ - # The build system We are currently migrating from `autotools` to `CMake` as a build-system. This document diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ff64b1c38..fe221b9b0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -601,6 +601,11 @@ set(BACKENDS_PLUGIN_FILES backends/prometheus/backend_prometheus.h ) +set(CLAIM_PLUGIN_FILES + claim/claim.c + claim/claim.h + ) + set(EXPORTING_ENGINE_FILES exporting/exporting_engine.c exporting/exporting_engine.h @@ -667,6 +672,7 @@ set(NETDATA_FILES ${STATSD_PLUGIN_FILES} ${STREAMING_PLUGIN_FILES} ${WEB_PLUGIN_FILES} + ${CLAIM_PLUGIN_FILES} ) set(NETDATACLI_FILES diff --git a/Makefile.am b/Makefile.am index 1158cf073d..0a8c3e8800 100644 --- a/Makefile.am +++ b/Makefile.am @@ -99,6 +99,7 @@ SUBDIRS += \ registry \ streaming \ web \ + claim \ $(NULL) @@ -454,6 +455,11 @@ BACKENDS_PLUGIN_FILES = \ backends/prometheus/backend_prometheus.h \ $(NULL) +CLAIM_PLUGIN_FILES = \ + claim/claim.c \ + claim/claim.h \ + $(NULL) + EXPORTING_ENGINE_FILES = \ exporting/exporting_engine.c \ exporting/exporting_engine.h \ @@ -521,6 +527,7 @@ NETDATA_FILES = \ $(STREAMING_PLUGIN_FILES) \ $(STATSD_PLUGIN_FILES) \ $(WEB_PLUGIN_FILES) \ + $(CLAIM_PLUGIN_FILES) \ $(NULL) if FREEBSD diff --git a/claim/Makefile.am b/claim/Makefile.am new file mode 100644 index 0000000000..c838db9b66 --- /dev/null +++ b/claim/Makefile.am @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +AUTOMAKE_OPTIONS = subdir-objects +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +CLEANFILES = \ + netdata-claim.sh \ + $(NULL) + +include $(top_srcdir)/build/subst.inc +SUFFIXES = .in + +sbin_SCRIPTS = \ + netdata-claim.sh \ + $(NULL) + +dist_noinst_DATA = \ + netdata-claim.sh.in \ + README.md \ + $(NULL) + diff --git a/claim/README.md b/claim/README.md new file mode 100644 index 0000000000..05de636155 --- /dev/null +++ b/claim/README.md @@ -0,0 +1,72 @@ +# Agent claiming + +Agent claiming is part of the onboarding process when creating a workspace in Netdata Cloud. Each workspace gets its own +common invitation mechanism, which begins with the administrators of the workspace creating a **claiming-token**. They, +or other users is their organization, can then use the claiming-token to add an agent to their workspace. + +To claim a Netdata agent, you first send a claiming request to Netdata Cloud (from the agent node). Once the +Netdata Cloud validates the claiming request of the agent (based on the claiming token), and returns a successful +result, the node is considered claimed. + +## Claiming script + +The user can claim an agent by directly calling the `netdata-claim.sh` script **as the netdata user** and passing the +following arguments: + +```sh +-token=TOKEN + where TOKEN is the workspace claiming-token. +-rooms=ROOM1,ROOM2,... + where ROOMX is the workspace war-room to join. This list is optional. +-url=URL_BASE + where URL_BASE is the Netdata Cloud endpoint base URL. By default, this is https://netdata.cloud. +-id=AGENT_ID + where AGENT_ID is the unique identifier of the agent. This is the agent's MACHINE_GUID by default. +-hostname=HOSTNAME + where HOSTNAME is the result of the hostname command by default. +``` + +For example, the following command claims an agent and adds it to rooms `room1` and `room2`: + +```sh +netdata-claim.sh -token=MYTOKEN1234567 -rooms=room1,room2 +``` + +You should then update the `netdata` service about the result with `netdatacli`: + +```sh +netdatacli reload-claiming-state +``` + +This reloads the agent claiming state from disk. + +## Netdata agent command line + +The user can trigger agent claiming by calling the `netdata` service binary with the additional command line parameters: + +```sh +-W "claim -token=TOKEN -rooms=ROOM1,ROOM2" +``` + +For example: + +```sh +/usr/sbin/netdata -D -W "claim -token=MYTOKEN1234567 -rooms=room1,room2" +``` + +If need be, the user can override the agent's defaults by providing additional arguments like those described +[here](#claiming-script). + +## Claiming directory + +Netdata stores the agent claiming-related state in the user configuration directory under `claim.d`, e.g. in +`/etc/netdata/claim.d`. The user can put files in this directory to provide defaults to the `-token` and `-rooms` +arguments. These files should be owned **by the `netdata` user**. + +The `claim.d/token` file should contain the claiming-token and the `claim.d/rooms` file should contain the list of +war-rooms. + +The user can also put the Cloud endpoint's full certificate chain in `claim.d/cloud_fullchain.pem` so that the agent +can trust the endpoint if necessary. + +[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fclaim%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/claim/claim.c b/claim/claim.c new file mode 100644 index 0000000000..75f0a437d6 --- /dev/null +++ b/claim/claim.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "claim.h" +#include "../registry/registry_internals.h" + +char *claiming_pending_arguments = NULL; + +static char *claiming_errors[] = { + "Agent claimed successfully", // 0 + "Unknown argument", // 1 + "Problems with claiming working directory", // 2 + "Missing dependencies", // 3 + "Failure to connect to endpoint", // 4 + "Unknown HTTP error message", // 5 + "invalid agent id", // 6 + "invalid public key", // 7 + "token has expired", // 8 + "invalid token", // 9 + "duplicate agent id", // 10 + "claimed in another workspace", // 11 + "internal server error" // 12 +}; + +#define AGENT_UNCLAIMED 0 +#define AGENT_CLAIMED 1 +static uint8_t claiming_status = AGENT_UNCLAIMED; + +uint8_t is_agent_claimed(void) +{ + return (AGENT_CLAIMED == claiming_status); +} + +#define CLAIMING_COMMAND_LENGTH 16384 + +extern struct registry registry; + +/* rrd_init() must have been called before this function */ +void claim_agent(char *claiming_arguments) +{ + info("The claiming feature is under development and still subject to change before the next release"); + return; + + int exit_code; + pid_t command_pid; + char command_buffer[CLAIMING_COMMAND_LENGTH + 1]; + FILE *fp; + + snprintfz(command_buffer, + CLAIMING_COMMAND_LENGTH, + "exec netdata-claim.sh -hostname=%s -id=%s -url=%s %s", + netdata_configured_hostname, + localhost->machine_guid, + registry.cloud_base_url, + claiming_arguments); + + info("Executing agent claiming command 'netdata-claim.sh'"); + fp = mypopen(command_buffer, &command_pid); + if(!fp) { + error("Cannot popen(\"%s\").", command_buffer); + return; + } + info("Waiting for claiming command to finish."); + while (fgets(command_buffer, CLAIMING_COMMAND_LENGTH, fp) != NULL) {;} + exit_code = mypclose(fp, command_pid); + info("Agent claiming command returned with code %d", exit_code); + if (0 == exit_code) { + claiming_status = AGENT_CLAIMED; + info("Agent successfully claimed."); + return; + } + if (exit_code < 0) { + error("Agent claiming command failed to complete its run."); + return; + } + errno = 0; + unsigned maximum_known_exit_code = sizeof(claiming_errors) / sizeof(claiming_errors[0]); + + if ((unsigned)exit_code > maximum_known_exit_code) { + error("Agent failed to be claimed with an unknown error."); + return; + } + error("Agent failed to be claimed with the following error message:"); + error("\"%s\"", claiming_errors[exit_code]); +} + +void load_claiming_state(void) +{ + info("The claiming feature is under development and still subject to change before the next release"); + return; + + char filename[FILENAME_MAX + 1]; + struct stat statbuf; + + snprintfz(filename, FILENAME_MAX, "%s/claim.d/is_claimed", netdata_configured_user_config_dir); + // check if the file exists + if (lstat(filename, &statbuf) != 0) { + info("File '%s' was not found. Setting state to AGENT_UNCLAIMED.", filename); + claiming_status = AGENT_UNCLAIMED; + } else { + info("File '%s' was found. Setting state to AGENT_CLAIMED.", filename); + claiming_status = AGENT_CLAIMED; + } +} diff --git a/claim/claim.h b/claim/claim.h new file mode 100644 index 0000000000..3b2b867434 --- /dev/null +++ b/claim/claim.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef NETDATA_CLAIM_H +#define NETDATA_CLAIM_H 1 + +#include "../daemon/common.h" + +extern char *claiming_pending_arguments; + +void claim_agent(char *claiming_arguments); +uint8_t is_agent_claimed(void); +void load_claiming_state(void); + +#endif //NETDATA_CLAIM_H diff --git a/claim/netdata-claim.sh.in b/claim/netdata-claim.sh.in new file mode 100755 index 0000000000..e565e3de28 --- /dev/null +++ b/claim/netdata-claim.sh.in @@ -0,0 +1,216 @@ +#!/usr/bin/env bash +# netdata +# real-time performance and health monitoring, done right! +# (C) 2017 Costa Tsaousis +# SPDX-License-Identifier: GPL-3.0-or-later + +# Exit code: 0 - Success +# Exit code: 1 - Unknown argument +# Exit code: 2 - Problems with claiming working directory +# Exit code: 3 - Missing dependencies +# Exit code: 4 - Failure to connect to endpoint +# Exit code: 5 - Unknown HTTP error message +# +# OK: Agent claimed successfully +# HTTP Status code: 200 +# Exit code: 0 +# +# Error: The agent id is invalid; it does not fulfill the constraints +# HTTP Status code: 422 +# Error message: "invalid agent id" +# Exit code: 6 +# +# Error: Invalid public key; the public key is empty or not present +# HTTP Status code: 422 +# Error message: "invalid public key" +# Exit code: 7 +# +# Error: Expired token +# HTTP Status code: 403 +# Error message: "token has expired" +# Exit code: 8 +# +# Error: Invalid claiming token; missing, undecryptable, invalid payload... +# HTTP Status code: 422 +# Error message: "invalid token" +# Exit code: 9 +# +# Error: Duplicate agent id; an agent with the same id but a different public key is already registered in the cloud +# HTTP Status code: 409 +# Error message: "duplicate agent id" +# Exit code: 10 +# +# Error: Already claimed in another workspace; +# this agent (same id, same public key) already belongs to another workspace +# HTTP Status code: 403 +# Error message: "claimed in another workspace" +# Exit code: 11 +# +# Error: Internal server error. Any other unexpected error (DB problems, etc.) +# HTTP Status code: 500 +# Error message: "internal server error" +# Exit code: 12 + +if command -v curl >/dev/null 2>&1 ; then + URLTOOL="curl" +elif command -v wget >/dev/null 2>&1 ; then + URLTOOL="wget" +else + echo >&2 "I need curl or wget to proceed, but neither is available on this system." + exit 3 +fi +if ! command -v openssl >/dev/null 2>&1 ; then + echo >&2 "I need openssl to proceed, but neither is available on this system." + exit 3 +fi + + +# ----------------------------------------------------------------------------- +# defaults to allow running this script by hand + +[ -z "${NETDATA_USER_CONFIG_DIR}" ] && NETDATA_USER_CONFIG_DIR="@configdir_POST@" +MACHINE_GUID_FILE="@registrydir_POST@/netdata.public.unique.id" +CLAIMING_DIR="${NETDATA_USER_CONFIG_DIR}/claim.d" +TOKEN="unknown" +URL_BASE="https://netdata.cloud" +ID="unknown" +ROOMS="" +HOSTNAME=$(hostname) +CLOUD_CERTIFICATE_FILE="${CLAIMING_DIR}/cloud_fullchain.pem" + +# get the MACHINE_GUID by default +if [ -r "${MACHINE_GUID_FILE}" ]; then + ID="$(cat "${MACHINE_GUID_FILE}")" +fi + +# get token from file +if [ -r "${CLAIMING_DIR}/token" ]; then + TOKEN="$(cat "${CLAIMING_DIR}/token")" +fi + +# get rooms from file +if [ -r "${CLAIMING_DIR}/rooms" ]; then + ROOMS="$(cat "${CLAIMING_DIR}/rooms")" +fi + +for arg in "$@" +do + case $arg in + -token=*) TOKEN=${arg:7} ;; + -url=*) URL_BASE=${arg:5} ;; + -id=*) ID=${arg:4} ;; + -rooms=*) ROOMS=${arg:7} ;; + -hostname=*) HOSTNAME=${arg:10} ;; + *) echo >&2 "Unknown argument ${arg}" + exit 1 ;; + esac + shift 1 +done + +echo >&2 "Token: ****************" +echo >&2 "Base URL: $URL_BASE" +echo >&2 "Id: $ID" +echo >&2 "Rooms: $ROOMS" +echo >&2 "Hostname: $HOSTNAME" + +# create the claiming directory for this user +if [ ! -d "${CLAIMING_DIR}" ] ; then + mkdir -p "${CLAIMING_DIR}" && chmod 0770 "${CLAIMING_DIR}" +# shellcheck disable=SC2181 + if [ $? -ne 0 ] ; then + echo >&2 "Failed to create claiming working directory ${CLAIMING_DIR}" + exit 2 + fi +fi +if [ ! -w "${CLAIMING_DIR}" ] ; then + echo >&2 "No write permission in claiming working directory ${CLAIMING_DIR}" + exit 2 +fi + +if [ ! -f "${CLAIMING_DIR}/private.pem" ] ; then + echo >&2 "Generating private/public key for the first time." + if ! openssl genrsa -out "${CLAIMING_DIR}/private.pem" 2048 ; then + echo >&2 "Failed to generate private/public key pair." + exit 2 + fi +fi +if [ ! -f "${CLAIMING_DIR}/public.pem" ] ; then + echo >&2 "Extracting public key from private key." + if ! openssl rsa -in "${CLAIMING_DIR}/private.pem" -outform PEM -pubout -out "${CLAIMING_DIR}/public.pem" ; then + echo >&2 "Failed to extract public key." + exit 2 + fi +fi + +TARGET_URL="${URL_BASE}/api/v1/workspaces/agents/${ID}" +# shellcheck disable=SC2002 +KEY=$(cat "${CLAIMING_DIR}/public.pem" | tr '\n' '!' | sed -e 's/!/\\n/g') +# shellcheck disable=SC2001 +[ -n "$ROOMS" ] && ROOMS=\"$(echo "$ROOMS" | sed s'/,/", "/g')\" + +cat > "${CLAIMING_DIR}/tmpin.txt" <&2 "Failed to connect to ${URL_BASE}" + rm -f "${CLAIMING_DIR}/tmpout.txt" + exit 4 +fi + +HTTP_STATUS_CODE=$(grep "HTTP" "${CLAIMING_DIR}/tmpout.txt" | awk -F " " '{print $2}') +if [ "${HTTP_STATUS_CODE}" -ne 200 ] ; then + ERROR_MESSAGE=$(grep "\"error\":" "${CLAIMING_DIR}/tmpout.txt" | awk -F "error\":\"" '{print $2}' | sed s'/"}//g') + case ${ERROR_MESSAGE} in + "invalid agent id") EXIT_CODE=6 ;; + "invalid public key") EXIT_CODE=7 ;; + "token has expired") EXIT_CODE=8 ;; + "invalid token") EXIT_CODE=9 ;; + "duplicate agent id") EXIT_CODE=10 ;; + "claimed in another workspace") EXIT_CODE=11 ;; + "internal server error") EXIT_CODE=12 ;; + *) EXIT_CODE=5 ;; + esac + echo >&2 "Failed to claim agent." + rm -f "${CLAIMING_DIR}/tmpout.txt" + exit $EXIT_CODE +fi + +rm -f "${CLAIMING_DIR}/tmpout.txt" +touch "${CLAIMING_DIR}/is_claimed" +rm -f "${CLAIMING_DIR}/token" +echo >&2 "Agent was successfully claimed." \ No newline at end of file diff --git a/cli/README.md b/cli/README.md index 3872dac1c1..d39198f26d 100644 --- a/cli/README.md +++ b/cli/README.md @@ -19,6 +19,8 @@ shutdown-agent Cleanup and exit the netdata agent. fatal-agent Log the state and halt the netdata agent. +reload-claiming-state + Reload agent claiming state from disk. ``` Those commands are the same that can be sent to netdata via [signals](../daemon#command-line-options). diff --git a/configure.ac b/configure.ac index 6fcb3baeba..ad35aa61cc 100644 --- a/configure.ac +++ b/configure.ac @@ -1282,6 +1282,7 @@ AC_CONFIG_FILES([ web/gui/Makefile web/server/Makefile web/server/static/Makefile + claim/Makefile ]) AC_OUTPUT diff --git a/daemon/commands.c b/daemon/commands.c index 5eb22a6693..b12c19216b 100644 --- a/daemon/commands.c +++ b/daemon/commands.c @@ -40,6 +40,7 @@ static cmd_status_t cmd_save_database_execute(char *args, char **message); static cmd_status_t cmd_reopen_logs_execute(char *args, char **message); static cmd_status_t cmd_exit_execute(char *args, char **message); static cmd_status_t cmd_fatal_execute(char *args, char **message); +static cmd_status_t cmd_reload_claiming_state_execute(char *args, char **message); static cmd_status_t cmd_reload_labels_execute(char *args, char **message); static command_info_t command_info_array[] = { @@ -49,6 +50,7 @@ static command_info_t command_info_array[] = { {"reopen-logs", cmd_reopen_logs_execute, CMD_TYPE_ORTHOGONAL}, // Close and reopen log files {"shutdown-agent", cmd_exit_execute, CMD_TYPE_EXCLUSIVE}, // exit cleanly {"fatal-agent", cmd_fatal_execute, CMD_TYPE_HIGH_PRIORITY}, // exit with fatal error + {"reload-claiming-state", cmd_reload_claiming_state_execute, CMD_TYPE_ORTHOGONAL}, // reload claiming state {"reload-labels", cmd_reload_labels_execute, CMD_TYPE_ORTHOGONAL}, // reload the labels }; @@ -108,7 +110,9 @@ static cmd_status_t cmd_help_execute(char *args, char **message) "shutdown-agent\n" " Cleanup and exit the netdata agent.\n" "fatal-agent\n" - " Log the state and halt the netdata agent.\n", + " Log the state and halt the netdata agent.\n" + "reload-claiming-state\n" + " Reload agent claiming state from disk.\n", MAX_COMMAND_LENGTH - 1); return CMD_STATUS_SUCCESS; } @@ -176,6 +180,21 @@ static cmd_status_t cmd_fatal_execute(char *args, char **message) return CMD_STATUS_SUCCESS; } +static cmd_status_t cmd_reload_claiming_state_execute(char *args, char **message) +{ + (void)args; + (void)message; + + info("The claiming feature is still in development and subject to change before the next release"); + return CMD_STATUS_FAILURE; + + error_log_limit_unlimited(); + info("COMMAND: Reloading Agent Claiming configuration."); + load_claiming_state(); + error_log_limit_reset(); + return CMD_STATUS_SUCCESS; +} + static cmd_status_t cmd_reload_labels_execute(char *args, char **message) { (void)args; diff --git a/daemon/commands.h b/daemon/commands.h index 6de4084217..cb879c2a8c 100644 --- a/daemon/commands.h +++ b/daemon/commands.h @@ -19,6 +19,7 @@ typedef enum cmd { CMD_REOPEN_LOGS, CMD_EXIT, CMD_FATAL, + CMD_RELOAD_CLAIMING_STATE, CMD_RELOAD_LABELS, CMD_TOTAL_COMMANDS } cmd_t; diff --git a/daemon/common.h b/daemon/common.h index 5202a53082..6ac3cb3c87 100644 --- a/daemon/common.h +++ b/daemon/common.h @@ -60,6 +60,9 @@ // netdata unit tests #include "unit_test.h" +// netdata agent claiming +#include "claim/claim.h" + // the netdata deamon #include "daemon.h" #include "main.h" diff --git a/daemon/daemon.c b/daemon/daemon.c index 4ad082b95e..77448c0e73 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -4,6 +4,7 @@ #include char pidfile[FILENAME_MAX + 1] = ""; +char claimingdirectory[FILENAME_MAX + 1]; static void chown_open_file(int fd, uid_t uid, gid_t gid) { if(fd == -1) return; @@ -50,6 +51,7 @@ int become_user(const char *username, int pid_fd) { create_needed_dir(netdata_configured_cache_dir, uid, gid); create_needed_dir(netdata_configured_varlib_dir, uid, gid); + create_needed_dir(claimingdirectory, uid, gid); if(pidfile[0]) { if(chown(pidfile, uid, gid) == -1) @@ -434,6 +436,9 @@ int become_daemon(int dont_fork, const char *user) // never become a problem sched_setscheduler_set(); + // Set claiming directory based on user config directory with correct ownership + snprintfz(claimingdirectory, FILENAME_MAX, "%s/claim.d", netdata_configured_user_config_dir); + if(user && *user) { if(become_user(user, pidfd) != 0) { error("Cannot become user '%s'. Continuing as we are.", user); @@ -443,6 +448,7 @@ int become_daemon(int dont_fork, const char *user) else { create_needed_dir(netdata_configured_cache_dir, getuid(), getgid()); create_needed_dir(netdata_configured_varlib_dir, getuid(), getgid()); + create_needed_dir(claimingdirectory, getuid(), getgid()); } if(pidfd != -1) diff --git a/daemon/main.c b/daemon/main.c index b00de00628..1dcdb6edd2 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -351,6 +351,8 @@ int help(int exitcode) { " set netdata.conf option from the command line.\n\n" " -W simple-pattern pattern string\n" " Check if string matches pattern and exit.\n\n" + " -W \"claim -token=TOKEN -rooms=ROOM1,ROOM2\"\n" + " Claim the agent to the workspace rooms pointed to by TOKEN and ROOM*.\n\n" ); fprintf(stream, "\n Signals netdata handles:\n\n" @@ -926,6 +928,7 @@ int main(int argc, char **argv) { { char* stacksize_string = "stacksize="; char* debug_flags_string = "debug_flags="; + char* claim_string = "claim"; #ifdef ENABLE_DBENGINE char* createdataset_string = "createdataset="; char* stresstest_string = "stresstest="; @@ -1086,6 +1089,10 @@ int main(int argc, char **argv) { printf("%s\n", value); return 0; } + else if(strncmp(optarg, claim_string, strlen(claim_string)) == 0) { + /* will trigger a claiming attempt when the agent is initialized */ + claiming_pending_arguments = optarg + strlen(claim_string); + } else { fprintf(stderr, "Unknown -W parameter '%s'\n", optarg); return help(1); @@ -1271,6 +1278,14 @@ int main(int argc, char **argv) { get_system_info(system_info); rrd_init(netdata_configured_hostname, system_info); + + // ------------------------------------------------------------------------ + // Claim netdata agent to a cloud endpoint + + if (claiming_pending_arguments) + claim_agent(claiming_pending_arguments); + load_claiming_state(); + // ------------------------------------------------------------------------ // enable log flood protection diff --git a/netdata-installer.sh b/netdata-installer.sh index 442b28e87e..e6affc36e5 100755 --- a/netdata-installer.sh +++ b/netdata-installer.sh @@ -617,6 +617,7 @@ NETDATA_LOG_DIR="$(config_option "global" "log directory" "${NETDATA_PREFIX}/var NETDATA_USER_CONFIG_DIR="$(config_option "global" "config directory" "${NETDATA_PREFIX}/etc/netdata")" NETDATA_STOCK_CONFIG_DIR="$(config_option "global" "stock config directory" "${NETDATA_PREFIX}/usr/lib/netdata/conf.d")" NETDATA_RUN_DIR="${NETDATA_PREFIX}/var/run" +NETDATA_CLAIMING_DIR="${NETDATA_USER_CONFIG_DIR}/claim.d" cat <&2 "Creating directory '${NETDATA_CLAIMING_DIR}'" + run mkdir -p "${NETDATA_CLAIMING_DIR}" || exit 1 +fi +run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_CLAIMING_DIR}" +run chmod 770 "${NETDATA_CLAIMING_DIR}" + # --- plugins ---- if [ "${UID}" -eq 0 ]; then diff --git a/packaging/installer/netdata-uninstaller.sh b/packaging/installer/netdata-uninstaller.sh index 424367b595..dc3a0eabb0 100755 --- a/packaging/installer/netdata-uninstaller.sh +++ b/packaging/installer/netdata-uninstaller.sh @@ -313,6 +313,7 @@ if [ -n "${NETDATA_PREFIX}" ] && [ -d "${NETDATA_PREFIX}" ]; then else rm_file "/usr/sbin/netdata" rm_file "/usr/sbin/netdatacli" + rm_file "/usr/sbin/netdata-claim.sh" rm_dir "/usr/share/netdata" rm_dir "/usr/libexec/netdata" rm_dir "/var/lib/netdata"