Commit a020e7b1 authored by ale's avatar ale

Read default options from system-wide configuration file

parent 80ebeee5
Pipeline #1314 passed with stages
in 53 seconds
......@@ -19,6 +19,7 @@
*/
#define _GNU_SOURCE
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <math.h>
......@@ -36,6 +37,7 @@
#include "config.h"
/* Global options */
char *config_file = "/etc/runcron.conf";
char *job_name = NULL;
char *node_exporter_dir = "/var/lib/prometheus/node-exporter";
int splay_time = 0;
......@@ -46,7 +48,7 @@ int locking = 1;
int lock_timeout = 0;
int lock_wait = 0;
char *lock_dir = "/var/tmp";
char *lock_dir = "/var/lock";
struct timespec one_second = {.tv_sec = 1, .tv_nsec = 0};
......@@ -98,21 +100,36 @@ int usage() {
"default),\n"
" wait forever. Specifying this option implies "
"--wait.\n"
" --lock-dir PATH Directory where to create lock files (default "
"/var/lock).\n"
"\n"
"Options for Prometheus integration:\n"
"\n"
" --node-exporter-dir PATH\n"
" Look for the prometheus-node-exporter state directory "
" Look for the prometheus-node-exporter state "
"directory "
"in PATH\n"
" (default /var/lib/prometheus/node-exporter). If the "
"directory\n"
" exists, the program will write a small node-exporter "
" exists, the program will write a small "
"node-exporter "
"textfile\n"
" snippet in there.\n"
"\n"
"If you are passing options to COMMAND, remember to use `--' to tell the "
"runcron\n"
"option parser to stop interpreting options for itself.\n"
"\n"
"On startup, runcron will load a system-wide configuration file from \n"
"/etc/runcron.conf (overridable by setting the environment variable\n"
"RUNCRON_CONFIG). This file can contain command-line options (without "
"the "
"leading\n"
"--), one per line, with the optional argument separated by a space. "
"Options set\n"
"on the command line take precedence over those specified in the "
"configuration\n"
"file.\n"
"\n",
PACKAGE, PACKAGE_VERSION, PACKAGE);
return 2;
......@@ -187,7 +204,7 @@ void lock_with_timeout() {
sighandler_t old_handler = NULL;
int fd, r, lock_flags;
if (asprintf(&lockfile, "%s/runcron.lock.%s", lock_dir, job_name) < 0) {
if (asprintf(&lockfile, "%s/runcron.%s.lock", lock_dir, job_name) < 0) {
fprintf(stderr, "Error: could not allocate memory\n");
exit(1);
}
......@@ -459,11 +476,13 @@ int export_metrics(int exit_status) {
return 0;
}
if (asprintf(&tmp_file, "%s/.cron-%s.prom.tmp~", node_exporter_dir, job_name) < 0) {
if (asprintf(&tmp_file, "%s/.cron-%s.prom.tmp~", node_exporter_dir,
job_name) < 0) {
fprintf(stderr, "Error: could not allocate memory for metrics\n");
return -1;
}
if (asprintf(&metrics_file, "%s/cron-%s.prom", node_exporter_dir, job_name) < 0) {
if (asprintf(&metrics_file, "%s/cron-%s.prom", node_exporter_dir, job_name) <
0) {
fprintf(stderr, "Error: could not allocate memory for metrics\n");
return -1;
}
......@@ -473,15 +492,19 @@ int export_metrics(int exit_status) {
fp = fopen(tmp_file, "w");
if (fp == NULL) {
fprintf(stderr, "Error: could not open %s: %s\n", metrics_file, strerror(errno));
fprintf(stderr, "Error: could not open %s: %s\n", metrics_file,
strerror(errno));
return -1;
}
fprintf(fp, "cronjob_status{cronjob=\"%s\"} %d\n", job_name, (exit_status == 0) ? 1 : 0);
fprintf(fp, "cronjob_status{cronjob=\"%s\"} %d\n", job_name,
(exit_status == 0) ? 1 : 0);
fprintf(fp, "cronjob_last_start{cronjob=\"%s\"} %ld\n", job_name, start_time);
fprintf(fp, "cronjob_last_end{cronjob=\"%s\"} %ld\n", job_name, end_time);
fprintf(fp, "cronjob_runtime_seconds{cronjob=\"%s\"} %d\n", job_name, elapsed);
fprintf(fp, "cronjob_runtime_seconds{cronjob=\"%s\"} %d\n", job_name,
elapsed);
if (exit_status == 0) {
fprintf(fp, "cronjob_last_success{cronjob=\"%s\"} %ld\n", job_name, end_time);
fprintf(fp, "cronjob_last_success{cronjob=\"%s\"} %ld\n", job_name,
end_time);
}
fclose(fp);
......@@ -493,9 +516,85 @@ int export_metrics(int exit_status) {
return 0;
}
char *trim(char *s) {
char *tail;
while (isspace(*s))
s++;
tail = s + strlen(s);
tail--;
while (tail > s && isspace(*tail))
*(tail--) = '\0';
return s;
}
int read_config() {
FILE *fp;
char *s, linebuf[1024];
int r = -1, lineno = 0;
if ((s = getenv("RUNCRON_CONFIG")) != NULL) {
config_file = s;
}
fp = fopen(config_file, "r");
if (fp == NULL) {
return -1;
}
while (fgets(linebuf, sizeof(linebuf) - 1, fp) != NULL) {
char *sep, *key, *val;
lineno++;
if (linebuf[0] == '\0' || linebuf[0] == '#') {
continue;
}
key = trim(linebuf);
sep = strchr(linebuf, ' ');
if (sep == NULL) {
// Value is the empty string (but not NULL).
val = linebuf + strlen(linebuf);
} else {
*sep = '\0';
val = trim(++sep);
}
if (!strcmp(key, "timeout")) {
run_timeout = to_int(val);
if (run_timeout < 0) {
fprintf(stderr, "Error: %s:%d: timeout value must be an integer\n",
config_file, lineno);
}
} else if (!strcmp(key, "lock-timeout")) {
lock_timeout = to_int(val);
if (lock_timeout < 0) {
fprintf(stderr, "Error: %s:%d: lock-timeout value must be an integer\n",
config_file, lineno);
}
} else if (!strcmp(key, "lock-dir")) {
lock_dir = strdup(val);
} else if (!strcmp(key, "no-lock")) {
locking = 0;
} else if (!strcmp(key, "quiet")) {
log_on_failure = 1;
} else if (!strcmp(key, "syslog")) {
syslog = 1;
} else if (!strcmp(key, "node-exporter-dir")) {
node_exporter_dir = strdup(val);
} else {
fprintf(stderr, "Error: %s:%d: unknown attribute %s\n", config_file,
lineno, key);
}
}
fclose(fp);
return r;
}
int main(int argc, char **argv) {
int c, r;
read_config();
while (1) {
int option_index = 0;
const char *opt_name = NULL;
......@@ -509,6 +608,7 @@ int main(int argc, char **argv) {
{"no-lock", no_argument, &locking, 0},
{"nolock", no_argument, &locking, 0},
{"lock-timeout", required_argument, 0, 0},
{"lock-dir", required_argument, 0, 0},
{"wait", no_argument, &lock_wait, 1},
{"node-exporter-dir", required_argument, 0, 0},
{0, 0, 0, 0}};
......@@ -540,6 +640,8 @@ int main(int argc, char **argv) {
"Error: --lock-timeout argument must be an integer\n");
exit(2);
}
} else if (!strcmp(opt_name, "lock-dir")) {
lock_dir = optarg;
} else if (!strcmp(opt_name, "node-exporter-dir")) {
node_exporter_dir = optarg;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment