Compare commits

..
4 Commits
Author SHA1 Message Date
Juro Bystricky 49823eae83 configure.ac: bump version to v2.3.0
Bump due to switching from opt-out to opt-in.

Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
2019-11-12 10:26:30 -08:00
Juro Bystricky a12c1d8761 telemctl.c: validate privileges
Not all commands need to be run as root.
In particular "is-active".
While in there, some minor formatting fixes.

Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
2019-11-12 10:26:30 -08:00
Auke Kok eb1e670b5f Add github actions CI. 2019-11-07 14:04:14 -08:00
Alex Jaramillo 5cbd31cbf2 Require explicit telemctl opt-in
telemetrics-client installation starts when the package is installed,
this change makes sure that to start telemetry the first time two steps
are needed: 1- telemctl opt-in and 2- telemctl start

Signed-off-by: Alex Jaramillo <alex.jch@gmail.com>
2019-10-14 11:02:20 -07:00
24 changed files with 184 additions and 89 deletions
+29
View File
@@ -0,0 +1,29 @@
name: C/C++ CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: install dependencies
run: sudo apt-get install libcurl4-gnutls-dev valgrind libelf-dev libdw-dev
- name: install check
run: wget https://github.com/libcheck/check/releases/download/0.12.0/check-0.12.0.tar.gz &&
tar xf check-0.12.0.tar.gz &&
pushd check-0.12.0 &&
./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu &&
make -j8 && sudo make install && popd
- name: autogen
run: sh autogen.sh
- name: configure
run: ./configure
- name: make
run: make -j8
- name: check
run: make check
- name: make distcheck
run: make distcheck
+24 -15
View File
@@ -67,38 +67,47 @@ Descriptions of config options are listed below in the Usage section.
Starting the client
---------------------
To use the telemetrics client a one time explicit ```opt-in``` is required (this is
also true when the contents of the directory ```/etc/telemetrics/``` are removed).
To opt-in to telemetrics-client use the command:
```{r, engine='bash', count_lines}
telemctl opt-in
```
**Note** this is a change from previous versions, before 2.3.0 installation of
telemetrics client was enough to enable the client and if needed the client could
be disabled with ```telemctl opt-out```. This command in previous versions created
```/etc/telemetrics/opt-out``` file (after telemetrics-client version 2.3.0 this
file can be safely removed).
If the client was compiled with systemd support the respective activation units
should be already in place (after a ```make install``` invocation). In this case
the client wil start automatically when data is made available to it. i.e. when
executing an ```/usr/bin/hprobe``` command.
Method 1 (recommended):
executing an ```/usr/bin/hprobe``` command. Otherwise use the following command:
```{r, engine='bash', count_lines}
telemctl start
```
Note: the above invocation technically readies the service for both socket and
path activation, so you may not see an "active" status.
Method 2:
path activation, so you may not see an "active" status. To check the status of
telemetrics-client use:
```{r, engine='bash', count_lines}
systemctl start telemprobd.service
systemctl start telempostd.service
telemctl is-active
telemprobd : active
telempostd : active
```
Method 3:
```{r, engine='bash', count_lines}
telemprobd &
telempostd &
```
Starting individual service units ```telempostd.service``` or ```telemeprobd.service```
is discouraged.
Configure the client to autostart at boot
---------------------
As longs as the first time ```opt-in``` was performed, the following methods are valid:
Method 1 (recommended):
Enable the socket-activated service and path unit:
+1 -1
View File
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([telemetrics-client], [2.2.3], [https://clearlinux.org/])
AC_INIT([telemetrics-client], [2.3.0], [https://clearlinux.org/])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.14 -Wall -Werror -Wno-extra-portability foreign subdir-objects])
AM_SILENT_RULES([yes])
+6 -5
View File
@@ -34,7 +34,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.sp
\fBtelemctl\fP
.sp
\fB/etc/telemetrics/opt\-out\fP
\fB/etc/telemetrics/opt\-in\fP
.SH DESCRIPTION
.sp
Control actions for telemetry services. The command can be used to start,
@@ -48,12 +48,13 @@ restart, or stop \fBtelemprobd\fP(1) and \fBtelempostd\fP(1), or to opt\-in or o
Starts, stops or restarts all running telemetry services.
.IP \(bu 2
\fBopt\-in\fP:
Opts in to telemetry, and starts telemetry services. The opt\-out file
\fB/etc/telemetrics/opt\-out\fP is removed.
Opts in to telemetry and the opt\-in file \fB/etc/telemetrics/opt\-in\fP
is created. Note: this is a one time required operation before
telemetry can be used the first time.
.IP \(bu 2
\fBopt\-out\fP:
Opts out of telemetry, and stops telemetry services. The opt\-out file
\fB/etc/telemetrics/opt\-out\fP is created.
Opts out of telemetry, and stops telemetry services. The opt\-in file
\fB/etc/telemetrics/opt\-in\fP is deleted.
.IP \(bu 2
\fBis\-active\fP:
Checks if telemetry client daemons are active (telemprobd and telempostd).
+6 -5
View File
@@ -15,7 +15,7 @@ SYNOPSIS
``telemctl``
``/etc/telemetrics/opt-out``
``/etc/telemetrics/opt-in``
DESCRIPTION
@@ -32,12 +32,13 @@ OPTIONS
Starts, stops or restarts all running telemetry services.
* ``opt-in``:
Opts in to telemetry, and starts telemetry services. The opt-out file
``/etc/telemetrics/opt-out`` is removed.
Opts in to telemetry and the opt-in file ``/etc/telemetrics/opt-in``
is created. Note: this is a one time required operation before
telemetry can be used the first time.
* ``opt-out``:
Opts out of telemetry, and stops telemetry services. The opt-out file
``/etc/telemetrics/opt-out`` is created.
Opts out of telemetry, and stops telemetry services. The opt-in file
``/etc/telemetrics/opt-in`` is deleted.
* ``is-active``:
Checks if telemetry client daemons are active (telemprobd and telempostd).
+7 -1
View File
@@ -45,6 +45,8 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
\fBvoid tm_free_record(struct telem_ref *t_ref)\fP
.sp
\fBint tm_set_config_file(const char *c_file)\fP
.sp
\fBint tm_is_opted_in(void)\fP
.SH DESCRIPTION
.sp
The functions in the telemetry library facilitate the delivery of
@@ -64,11 +66,15 @@ The function \fBtm_send_record()\fP delivers the record to the local
.sp
The function \fBtm_set_config_file()\fP can be used to provide an alternate
configuration path to the telemetry library.
.sp
\fBtm_is_opted_in\fP is a utility provided to check if the one time opt\-in
has been performed.
.SH RETURN VALUES
.sp
All these functions return \fB0\fP on success, or a non\-zero return value
if an error occurred. The function \fBtm_free_record()\fP does not return
any value.
any value. \fBtm_is_opted_in\fP returns \fB1\fP when telemetry is opted\-in
otherwise \fB0\fP\&.
.SH SEE ALSO
.INDENT 0.0
.IP \(bu 2
+6 -1
View File
@@ -27,6 +27,8 @@ SYNOPSIS
``int tm_set_config_file(const char *c_file)``
``int tm_is_opted_in(void)``
DESCRIPTION
===========
@@ -49,13 +51,16 @@ The function ``tm_send_record()`` delivers the record to the local
The function ``tm_set_config_file()`` can be used to provide an alternate
configuration path to the telemetry library.
``tm_is_opted_in`` is a utility provided to check if the one time opt-in
has been performed.
RETURN VALUES
=============
All these functions return ``0`` on success, or a non-zero return value
if an error occurred. The function ``tm_free_record()`` does not return
any value.
any value. ``tm_is_opted_in`` returns ``1`` when telemetry is opted-in
otherwise ``0``.
SEE ALSO
+1 -1
View File
@@ -75,7 +75,7 @@ static const uint32_t RECORD_FORMAT_VERSION = 4;
#define TM_SITE_VERSION_FILE "/etc/os-release"
#define TM_DIST_VERSION_FILE "/usr/lib/os-release"
#define TM_OPT_OUT_FILE "/etc/telemetrics/opt-out"
#define TM_OPT_IN_FILE "/etc/telemetrics/opt-in"
/* Currently max supported payload size is 8kb */
#define MAX_PAYLOAD_LENGTH 8192
+1 -1
View File
@@ -2,7 +2,7 @@
Description=Telemetrics BERT Probe
Requires=telemprobd.socket
After=telemprobd.socket
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
ConditionPathExists=/sys/firmware/acpi/tables/data/BERT
[Service]
+1 -1
View File
@@ -2,7 +2,7 @@
Description=Telemetrics Heartbeat Probe
Requires=telemprobd.socket
After=telemprobd.socket
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
[Service]
ExecStart=@bindir@/hprobe -Hlu
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit]
Description=Daily Heartbeat for Telemetrics
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
[Timer]
OnCalendar=daily
+1 -1
View File
@@ -2,7 +2,7 @@
Description=Telemetrics Systemd Journal Probe
Requires=telemprobd.socket
After=telemprobd.socket
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
[Service]
ExecStart=@bindir@/journalprobe -t
+1 -1
View File
@@ -2,7 +2,7 @@
Description=Telemetrics Systemd Journal Probe
Requires=telemprobd.socket
After=telemprobd.socket
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
[Service]
ExecStart=@bindir@/journalprobe
+1
View File
@@ -2,6 +2,7 @@
Description=Telemetrics Pstore Probe
Requires=telemprobd.socket
After=telemprobd.socket
ConditionPathExists=/etc/telemetrics/opt-in
[Service]
ExecStart=@bindir@/pstoreprobe
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit]
Description=Telemetry Post Daemon staging
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
[Path]
DirectoryNotEmpty=@localstatedir@/spool/telemetry
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit]
Description=Telemetrics Post Daemon
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
[Service]
ExecStart=@bindir@/telempostd
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit]
Description=Telemetrics Daemon
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
[Service]
ExecStart=@bindir@/telemprobd
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit]
Description=Telemetrics Daemon
ConditionPathExists=!/etc/telemetrics/opt-out
ConditionPathExists=/etc/telemetrics/opt-in
[Socket]
ListenStream=@SOCKETDIR@/telem-0
+2 -2
View File
@@ -90,8 +90,8 @@ endif
# set library version info
SHAREDLIB_CURRENT=4
SHAREDLIB_REVISION=0
SHAREDLIB_AGE=1
SHAREDLIB_REVISION=1
SHAREDLIB_AGE=0
noinst_LTLIBRARIES = %D%/libtelem-shared.la
+47 -38
View File
@@ -31,7 +31,7 @@
#include <errno.h>
#define TELEM_DIR "/etc/telemetrics"
#define TM_OPT_OUT TELEM_DIR"/opt-out"
#define TM_OPT_IN TELEM_DIR"/opt-in"
#define TELEM_WRK_DIRS_CONF "/usr/lib/tmpfiles.d/telemetrics-dirs.conf"
@@ -69,6 +69,7 @@ static int telemctl_opt_in(void);
static int telemctl_journal(char *);
struct telemcmd {
bool root;
char *cmd;
union {
int (*f1)(void);
@@ -78,13 +79,13 @@ struct telemcmd {
};
static struct telemcmd commands[] = {
{"stop", {.f1=telemctl_stop}, "Stops all running telemetry services" },
{"start", {.f1=telemctl_start}, "Starts all telemetry services" },
{"restart", {.f1=telemctl_restart}, "Restarts all telemetry services" },
{"is-active", {.f1=telemctl_is_active},"Checks if telemprobd and telempostd are active" },
{"opt-in", {.f1=telemctl_opt_in}, "Opts in to telemetry, and starts telemetry services" },
{"opt-out", {.f1=telemctl_opt_out}, "Opts out of telemetry, and stops telemetry services" },
{"journal", {.f2=telemctl_journal}, "Prints telemetry journal contents. Use -h argument with\n command for more options"}
{true, "stop", {.f1=telemctl_stop}, "Stops all running telemetry services" },
{true, "start", {.f1=telemctl_start}, "Starts all telemetry services" },
{true, "restart", {.f1=telemctl_restart}, "Restarts all telemetry services" },
{false, "is-active", {.f1=telemctl_is_active},"Checks if telemprobd and telempostd are active" },
{true, "opt-in", {.f1=telemctl_opt_in}, "Opts in to telemetry, and starts telemetry services" },
{true, "opt-out", {.f1=telemctl_opt_out}, "Opts out of telemetry, and stops telemetry services" },
{true, "journal", {.f2=telemctl_journal}, "Prints telemetry journal contents. Use -h argument with\n command for more options"}
};
static int syscmd(char *cmd, char *buff, int bufflen)
@@ -151,14 +152,16 @@ telem_start() {
create_work_dirs
for_each_service "start" ${SPECIAL_UNITS[@]}
}
Modified to add explicit opt-in
*/
static int telemctl_start(void)
{
char buff[512];
int status, ret;
if (access(TM_OPT_OUT, F_OK) == 0) {
fprintf(stderr, "Opt out is enabled. Cannot start services.\n");
if (access(TM_OPT_IN, F_OK) != 0) {
fprintf(stderr, "Opt in to telemetry first.\n");
return 1;
}
@@ -386,28 +389,21 @@ telem_opt_out() {
*/
static int telemctl_opt_out(void)
{
/* Ensure TELEM_DIR exists */
if (mk_telem_dir() != 0) {
fprintf(stderr, "Failed to create %s\n", TELEM_DIR);
int ret;
/* Remove TM_OPT_IN file */
if (unlink(TM_OPT_IN) != 0) {
if (errno == ENOENT) {
fprintf(stderr, "Already opted out. Nothing to do.\n");
return 0;
}
fprintf(stderr, "Failed to remove %s.\n", TM_OPT_IN);
return 1;
}
/* Create a brand new file TM_OPT_OUT, we mai fail because the file exists already.
* In that case we are already opted out and we are done here. */
int fd = open(TM_OPT_OUT, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd == -1) {
if (errno == EEXIST) {
fprintf(stderr, "Already opted out. Nothing to do.\n");
return 0;
} else {
fprintf(stderr, "Failed to create %s.\n", TM_OPT_OUT);
return 1;
}
} else {
telemctl_stop();
close(fd);
return telemctl_remove_work_dirs();
}
ret = telemctl_stop();
ret |= telemctl_remove_work_dirs();
return ret;
}
/*
@@ -418,20 +414,33 @@ telem_opt_in() {
rm -f $OPT_OUT_FILE || exit_err "Failed to remove ${OPT_OUT_FILE}."
telem_start
}
Modified to add explicit opt-in
*/
static int telemctl_opt_in(void)
{
/* Delete the TM_OPT_OUT file */
if (unlink(TM_OPT_OUT) == -1) {
if (errno == ENOENT) {
fprintf(stderr, "Already opted in. Nothing to do.\n");
return 0;
}
fprintf(stderr, "Failed to remove %s.\n", TM_OPT_OUT);
/* Ensure TELEM_DIR exists */
if (mk_telem_dir() != 0) {
fprintf(stderr, "Failed to create %s\n", TELEM_DIR);
return 1;
}
return telemctl_start();
/* Create a brand new file TM_OPT_IN, we may fail because the file exists already.
* In that case we are already opted in and we are done here. */
int fd = open(TM_OPT_IN, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd == -1) {
if (errno == EEXIST) {
fprintf(stderr, "Already opted in. Nothing to do.\n");
return 0;
} else {
fprintf(stderr, "Failed to create %s.\n", TM_OPT_IN);
return 1;
}
}
close(fd);
return 0;
}
@@ -513,7 +522,7 @@ int main(int argc, char **argv)
for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
if (strcmp(commands[i].cmd, argv[1]) == 0) {
if (!is_root) {
if (commands[i].root == true && is_root == false) {
fprintf(stderr, "Must be root to run this command. Exiting...\n");
exit(1);
}
+13 -5
View File
@@ -1199,6 +1199,17 @@ out1:
return ret;
}
int tm_is_opted_in(void)
{
struct stat unused;
if (stat(TM_OPT_IN_FILE, &unused) == -1) {
return 0;
}
return 1;
}
int tm_send_record(struct telem_ref *t_ref)
{
int i;
@@ -1208,14 +1219,11 @@ int tm_send_record(struct telem_ref *t_ref)
char *data = NULL;
size_t offset = 0;
int ret = 0;
int k = 0;
struct stat unused;
size_t cfg_file_name_size = 0;
const char *cfg_file_name = NULL;
k = stat(TM_OPT_OUT_FILE, &unused);
if (k == 0) {
// Bail early if opt-out is enabled
if (tm_is_opted_in() == 0) {
// Bail early if opt-in is not existent
return -ECONNREFUSED;
}
+7
View File
@@ -120,6 +120,13 @@ int tm_set_payload(struct telem_ref *t_ref, char *payload);
*/
int tm_send_record(struct telem_ref *t_ref);
/**
* Checks if telemetry was opted in
*
* @return 1 when opt-in, or 0 when opt-out
*/
int tm_is_opted_in(void);
/**
* Release the memory allocated to a telemetrics record.
*
+5
View File
@@ -21,3 +21,8 @@ TM_4_0_0 {
global:
tm_set_event_id;
} TM_3_0_0;
TM_4_1_0 {
global:
tm_is_opted_in;
} TM_4_0_0;
+20 -6
View File
@@ -41,7 +41,7 @@ void create_setup(void)
* with the libcheck API...
*/
ck_assert_msg(ret != -ECONNREFUSED,
"Opt-out enabled. Opt in to run these tests");
"First time opt-in required to run test");
}
START_TEST(record_create_non_null)
@@ -98,12 +98,22 @@ void create_teardown(void)
}
}
START_TEST(is_opt_in)
{
int ret;
ret = tm_is_opted_in();
/* Smoke testing function */
ck_assert_msg(ret == 0 || ret == 1,
"Something wrong with opt-in check");
}
END_TEST
START_TEST(record_create_invalid_class1)
{
int ret;
ret = tm_create_record(&ref, 1, "t/t", 2000);
ck_assert_msg(ret != -ECONNREFUSED,
"Opt-out enabled. Opt in to run this test");
"First time opt-in required to run test");
ck_assert(ret == -EINVAL);
}
END_TEST
@@ -113,7 +123,7 @@ START_TEST(record_create_invalid_class2)
int ret;
ret = tm_create_record(&ref, 1, "t/t/t/t", 2000);
ck_assert_msg(ret != -ECONNREFUSED,
"Opt-out enabled. Opt in to run this test");
"First time opt-in required to run test");
ck_assert(ret == -EINVAL);
}
END_TEST
@@ -126,7 +136,7 @@ START_TEST(record_create_severity_underflow)
// Severity of 0 is too low; raise it to 1, the minimum
ret = tm_create_record(&ref, 0, "a/a/a", 2000);
ck_assert_msg(ret != -ECONNREFUSED,
"Opt-out enabled. Opt in to run this test");
"First time opt-in required to run test");
if (asprintf(&result, "%s: %u\n", TM_SEVERITY_STR, 1) < 0) {
return;
@@ -146,7 +156,7 @@ START_TEST(record_create_severity_overflow)
// Severity of 5 is too high; lower it to 4, the maximum
ret = tm_create_record(&ref, 5, "b/b/b", 2000);
ck_assert_msg(ret != -ECONNREFUSED,
"Opt-out enabled. Opt in to run this test");
"First time opt-in required to run test");
if (asprintf(&result, "%s: %u\n", TM_SEVERITY_STR, 4) < 0) {
return;
@@ -172,7 +182,7 @@ void event_id_setup(void)
return;
}
ck_assert_msg(ret != -ECONNREFUSED,
"Opt-out enabled. Opt in to run this test");
"First time opt-in required to run test");
}
START_TEST(record_set_event_id)
@@ -252,6 +262,10 @@ Suite *lib_suite(void)
tcase_add_test(t, record_create_version);
suite_add_tcase(s, t);
t = tcase_create("Opt-in");
tcase_add_test(t, is_opt_in);
suite_add_tcase(s, t);
t = tcase_create("invalid classification");
tcase_add_test(t, record_create_invalid_class1);
tcase_add_test(t, record_create_invalid_class2);