diff --git a/.travis.yml b/.travis.yml
index 121b3ac..64b0ee6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,17 +2,24 @@ sudo: required
dist: trusty
language: c
install:
- - sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe multiverse"
- - sudo apt-get update -qq
- - sudo apt-get install -y --force-yes autoconf automake libtool xutils-dev gcc make cmake libglib2.0-dev
+ - sudo apt-get install -y --force-yes gcc make cmake libglib2.0-dev
+ - sudo apt-get install -y --force-yes autoconf automake libtool xutils-dev
+ - sudo apt-get install -y --force-yes jq
env:
matrix:
- BUILD_TYPE=Debug
- BUILD_TYPE=Release
-script:
+before_script:
- set -e
- mkdir /tmp/oio
- - export CMAKE_OPTS='-DCMAKE_INSTALL_PREFIX=/tmp/oio -DLD_LIBDIR=lib'
+ - export CMAKE_OPTS='-DCMAKE_INSTALL_PREFIX=/tmp/ROOT'
- cmake ${CMAKE_OPTS} -DCMAKE_BUILD_TYPE=$BUILD_TYPE .
- make all
- make install
+script:
+ - set -e
+ - export PATH="$PATH:/tmp/ROOT/bin" TMPDIR=/tmp
+ - ./tools/gridinit-genconf.sh 15
+ - gridinit -d -s gridinit /tmp/gridinit/gridinit.conf
+ - ./tools/cycle.sh
+ - pkill gridinit
diff --git a/CMakeLists.txt b/CMakeLists.txt
index faaed13..c5ac640 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,18 +1,15 @@
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 3.0)
project (GridInit C)
include(CheckIncludeFile)
include(CheckLibraryExists)
include(CheckTypeSize)
-set(GridInit_VERSION_MAJOR 1)
-set(GridInit_VERSION_MINOR 1)
-set(GridInit_RELEASE 5)
+set(GridInit_VERSION_MAJOR 2)
+set(GridInit_VERSION_MINOR 0)
+set(GridInit_RELEASE 1)
set(API_VERSION "${GridInit_VERSION_MAJOR}.${GridInit_VERSION_MINOR}.${GridInit_RELEASE}")
set(SHORT_API_VERSION "${GridInit_VERSION_MAJOR}.${GridInit_VERSION_MINOR}")
-if (NOT ABI_VERSION)
- set(ABI_VERSION 0)
-endif()
add_definitions(-DAPI_VERSION="${API_VERSION}")
add_definitions(-DSHORT_API_VERSION="${SHORT_API_VERSION}")
@@ -129,7 +126,6 @@ add_dependencies(gridinit
add_executable(gridinit_cmd
main/gridinit_cmd.c
- main/format_output.c
main/utils.c)
target_link_libraries(gridinit_cmd ${GLIB2_LIBRARIES})
diff --git a/main/format_output.c b/main/format_output.c
deleted file mode 100644
index 9c23559..0000000
--- a/main/format_output.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-Copyright (C) 2015 OpenIO SAS, as part of OpenIO SDS
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-*/
-
-#include
-#include
-#include "./format_output.h"
-
-FORMAT
-parse_format(gchar *format)
-{
- if (g_strcmp0(format, "json") == 0)
- return JSON;
- if (g_strcmp0(format, "csv") == 0)
- return CSV;
- else
- return DEFAULT;
-}
-
-void
-print_as_json(gchar *status, gchar *start, gchar *error, gboolean first)
-{
- gchar header[] = " {\n";
- gchar footer[] = " }";
- gchar tab[] = " ";
-
- if(!first)
- fprintf(stdout, ",\n");
-
- fprintf(stdout, "%s", header);
- fprintf(stdout, "%s\"status\": \"%s\",\n", tab, status);
- fprintf(stdout, "%s\"start\": \"%s\",\n", tab, start);
- fprintf(stdout, "%s\"error\": \"%s\"\n", tab, error);
- fprintf(stdout, "%s", footer);
-}
-
-void
-print_as_csv(gchar *status, gchar *start, gchar *error)
-{
- fprintf(stdout, "%s,%s,%s\n", status, start, error);
-}
-
-
-void
-print_header(FORMAT format)
-{
- switch (format) {
- case JSON:
- fprintf(stdout, "[\n");
- break;
- case CSV:
- fprintf(stdout, "status,start,error\n");
- break;
- default:
- break;
- }
-}
-
-void
-print_footer(FORMAT format)
-{
- switch (format) {
- case JSON:
- fprintf(stdout, "\n]\n");
- break;
- default:
- break;
- }
- return;
-}
-
-void
-print_body(FORMAT format, gchar *status, gchar *start, gchar *error, gboolean first)
-{
- switch (format) {
- case JSON:
- print_as_json(status, start, error, first);
- break;
- case CSV:
- print_as_csv(status, start, error);
- break;
- default:
- fprintf(stdout, "%s\t%s\t%s\n", status, start, error);
- }
-}
-
-void
-print_status_header(FORMAT format)
-{
- switch (format) {
- case JSON:
- case CSV:
- fprintf(stdout,
- "key,status,pid,#start,#died,csz,ssz,mfd,since,group,cmd\n");
- break;
- default:
- break;
- }
-}
-
-void
-status_body_json(gchar *fmt_line, int size)
-{
- g_snprintf(fmt_line, size,
- " {\n \"key\":\"%%s\",\n \"status\":\"%%s\","
- "\n \"pid\":\"%%d\",\n \"#start\":\"%%d\","
- "\n \"#died\":\"%%d\",\n \"csz\":\"%%ld\","
- "\n \"ssz\":\"%%ld\",\n \"mfd\":\"%%ld\","
- "\n \"since\":\"%%s\",\n \"group\":\"%%s\","
- "\n \"cmd\":\"%%s\"\n }");
-}
-
-
-void
-status_body_csv(gchar *fmt_line, int size)
-{
- g_snprintf(fmt_line, size,
- "%%s,%%s,%%d,%%d,%%d,%%ld,%%ld,%%ld,%%s,%%s,%%s\n");
-}
-
-void
-print_status_sep(FORMAT format, int count)
-{
- switch (format) {
- case JSON:
- if(count)
- fprintf(stdout, ",\n");
- default:
- break;
- }
-}
-
-void
-get_line_format(FORMAT format, gchar *fmt_line, int size)
-{
- switch (format) {
- case JSON:
- status_body_json(fmt_line, size);
- break;
- case CSV:
- status_body_csv(fmt_line, size);
- break;
- default:
- break;
- }
-}
diff --git a/main/format_output.h b/main/format_output.h
deleted file mode 100644
index cbc393a..0000000
--- a/main/format_output.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-Copyright (C) 2015 OpenIO SAS, as part of OpenIO SDS
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-*/
-
-#ifndef __FORMAT_OUTPUT__
-#define __FORMAT_OUTPUT__
-
-# include
-
-typedef enum FORMAT FORMAT;
-enum FORMAT {DEFAULT = 0, CSV = 1, JSON = 2};
-
-FORMAT parse_format(gchar *format);
-void print_as_json(gchar *status, gchar *start, char *error, gboolean first);
-void print_as_csv(gchar *status, gchar *start, char *error);
-void print_header(FORMAT format);
-void print_footer(FORMAT format);
-void print_body(FORMAT format, gchar *status, gchar *start, gchar *error, gboolean first);
-void print_status_header(FORMAT format);
-void status_body_json(gchar *fmt_line, int size);
-void status_body_csv(gchar *fmt_line, int size);
-void print_status_sep(FORMAT format, int count);
-void get_line_format(FORMAT format, gchar *fmt_line, int size);
-
-#endif
diff --git a/main/gridinit_cmd.c b/main/gridinit_cmd.c
index 72f4db7..1bfcb9b 100644
--- a/main/gridinit_cmd.c
+++ b/main/gridinit_cmd.c
@@ -29,7 +29,6 @@ along with this program. If not, see .
#include
-#include "./format_output.h"
#include "./gridinit_internals.h"
#define MINI 0
@@ -148,6 +147,21 @@ static const gchar description[] =
"with ID the key of a process, or '@GROUP', with GROUP the name of a process\n"
"group\n";
+typedef enum FORMAT FORMAT;
+
+enum FORMAT {DEFAULT = 0, CSV = 1, JSON = 2};
+
+static FORMAT
+parse_format(const gchar *cfg_format)
+{
+ if (g_strcmp0(cfg_format, "json") == 0)
+ return JSON;
+ if (g_strcmp0(cfg_format, "csv") == 0)
+ return CSV;
+ else
+ return DEFAULT;
+}
+
static int
__open_unix_client(const char *path)
@@ -292,8 +306,19 @@ dump_as_is(FILE *in_stream, void *udata)
else
kw = &KEYWORDS_NORMAL;
- print_header(format_t);
+ /* Prin tthe title */
+ switch (format_t) {
+ case JSON:
+ fputs("[", stdout);
+ break;
+ case CSV:
+ fputs("status,start,error\n", stdout);
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+ /* Print the lines */
while (!feof(in_stream) && !ferror(in_stream)) {
bzero(line, sizeof(line));
if (NULL != fgets(line, sizeof(line), in_stream)) {
@@ -308,13 +333,27 @@ dump_as_is(FILE *in_stream, void *udata)
dump_args->count_errors ++;
}
gchar *status = (gchar *) (code==0 ? kw->done :
- (code==EALREADY?kw->already:kw->failed));
- gchar *error = strerror(code);
- print_body(format_t, status, start, error,first);
+ (code==EALREADY?kw->already:kw->failed));
+ const char *error = strerror(code);
+
+ switch (format_t) {
+ case JSON:
+ if(!first)
+ fprintf(stdout, ",\n");
+ fprintf(stdout, "{\"status\": \"%s\",\"start\": \"%s\",\"error\": \"%s\"}\n", status, start, error);
+ break;
+ case CSV:
+ fprintf(stdout, "%s,%s,%s\n", status, start, error);
+ break;
+ default:
+ fprintf(stdout, "%s\t%s\t%s\n", status, start, error);
+ }
first = FALSE;
}
}
- print_footer(format_t);
+
+ if (format_t == JSON)
+ fputs("]", stdout);
fflush(stdout);
}
@@ -410,7 +449,7 @@ _filter_services(GList *original, char **filters, int *counters)
static int
command_status(int lvl, int argc, char **args)
{
- char fmt_title[256], fmt_line[256];
+ char fmt_line[256];
int *counters = alloca(sizeof(int) * (argc+1));
memset(counters, 0, sizeof(int) * (argc+1));
@@ -418,53 +457,59 @@ command_status(int lvl, int argc, char **args)
GList *all_jobs = _fetch_services();
GList *jobs = _filter_services(all_jobs, args, counters);
FORMAT format_t = parse_format(format);
- /* compute the max length of several variable field, for well aligned
- * columns on the output. */
- const size_t maxkey = get_longest_key(jobs);
- const size_t maxgroup = get_longest_group(jobs);
-
- if (format_t != DEFAULT) {
- print_status_header(format_t);
- get_line_format(format_t, fmt_line, sizeof(fmt_line));
- goto print_lines;
- }
- /* write the title */
- switch (lvl) {
- case 0:
- g_snprintf(fmt_title, sizeof(fmt_title),
- "%%-%us %%-8s %%6s %%s\n",
- (guint)maxkey);
- g_snprintf(fmt_line, sizeof(fmt_line),
- "%%-%us %%s %%6d %%s\n",
- (guint)maxkey);
- fprintf(stdout, fmt_title, "KEY", "STATUS", "PID", "GROUP");
- break;
- case 1:
- g_snprintf(fmt_title, sizeof(fmt_title),
- "%%-%us %%-8s %%5s %%6s %%5s %%19s %%%us %%s\n",
- (guint)maxkey, (guint)maxgroup);
+ /* Print the header and compute the format for each line */
+ if (format_t == DEFAULT) {
+ const size_t maxkey = get_longest_key(jobs);
+ const size_t maxgroup = get_longest_group(jobs);
+ char fmt_title[256];
+ switch (lvl) {
+ case 0:
+ g_snprintf(fmt_title, sizeof(fmt_title),
+ "%%-%us %%-8s %%6s %%s\n",
+ (guint)maxkey);
+ g_snprintf(fmt_line, sizeof(fmt_line),
+ "%%-%us %%s %%6d %%s\n",
+ (guint)maxkey);
+ fprintf(stdout, fmt_title, "KEY", "STATUS", "PID", "GROUP");
+ break;
+ case 1:
+ g_snprintf(fmt_title, sizeof(fmt_title),
+ "%%-%us %%-8s %%5s %%6s %%5s %%19s %%%us %%s\n",
+ (guint)maxkey, (guint)maxgroup);
+ g_snprintf(fmt_line, sizeof(fmt_line),
+ "%%-%us %%s %%5d %%6d %%5d %%19s %%%us %%s\n",
+ (guint)maxkey, (guint)maxgroup);
+ fprintf(stdout, fmt_title, "KEY", "STATUS", "PID", "#START",
+ "#DIED", "SINCE", "GROUP", "CMD");
+ break;
+ default:
+ g_snprintf(fmt_title, sizeof(fmt_title),
+ "%%-%us %%-8s %%5s %%6s %%5s %%8s %%8s %%8s %%19s %%%us %%s\n",
+ (guint)maxkey, (guint)maxgroup);
+ g_snprintf(fmt_line, sizeof(fmt_line),
+ "%%-%us %%s %%5d %%6d %%5d %%8ld %%8ld %%8ld %%19s %%%us %%s\n",
+ (guint)maxkey, (guint)maxgroup);
+
+ fprintf(stdout, fmt_title, "KEY", "STATUS", "PID", "#START",
+ "#DIED", "CSZ", "SSZ", "MFD", "SINCE", "GROUP", "CMD");
+ break;
+ }
+ } else if (format_t == CSV) {
g_snprintf(fmt_line, sizeof(fmt_line),
- "%%-%us %%s %%5d %%6d %%5d %%19s %%%us %%s\n",
- (guint)maxkey, (guint)maxgroup);
- fprintf(stdout, fmt_title, "KEY", "STATUS", "PID", "#START",
- "#DIED", "SINCE", "GROUP", "CMD");
- break;
- default:
- g_snprintf(fmt_title, sizeof(fmt_title),
- "%%-%us %%-8s %%5s %%6s %%5s %%8s %%8s %%8s %%19s %%%us %%s\n",
- (guint)maxkey, (guint)maxgroup);
+ "%%s,%%s,%%d,%%d,%%d,%%ld,%%ld,%%ld,%%s,%%s,%%s\n");
+ /* Print the title */
+ fputs("key,status,pid,#start,#died,csz,ssz,mfd,since,group,cmd\n", stdout);
+ } else if (format_t == JSON) {
g_snprintf(fmt_line, sizeof(fmt_line),
- "%%-%us %%s %%5d %%6d %%5d %%8ld %%8ld %%8ld %%19s %%%us %%s\n",
- (guint)maxkey, (guint)maxgroup);
-
- fprintf(stdout, fmt_title, "KEY", "STATUS", "PID", "#START",
- "#DIED", "CSZ", "SSZ", "MFD", "SINCE", "GROUP", "CMD");
- break;
+ "{\"key\":\"%%s\",\"status\":\"%%s\",\"pid\":%%d,"
+ "\"#start\":%%d,\"#died\":%%d,\"csz\":%%ld,\"ssz\":%%ld,\"mfd\":%%ld,"
+ "\"since\":\"%%s\",\"group\":\"%%s\","
+ "\"cmd\":\"%%s\"}\n");
+ /* Print the opening of the object */
+ fputs("[", stdout);
}
- print_lines:;
-
int count_misses = 0, count_broken = 0, count_down = 0, count_all = 0;
struct keyword_set_s *kw;
@@ -479,56 +524,55 @@ command_status(int lvl, int argc, char **args)
for (GList *l=jobs; l ;l=l->next) {
char str_time[20] = "---------- --------";
const char * str_status = "-";
- struct child_info_s *ci = NULL;
-
- ci = l->data;
+ struct child_info_s *ci = ci = l->data;
/* Prepare some fields */
- if (ci->pid > 0)
- strftime(str_time, sizeof(str_time), "%Y-%m-%d %H:%M:%S",
+ strftime(str_time, sizeof(str_time), "%Y-%m-%d %H:%M:%S",
gmtime(&(ci->last_start_attempt)));
str_status = get_child_status(ci, kw);
/* Manage counters */
-
if (str_status == kw->down)
count_down ++;
if (str_status == kw->broken)
count_broken ++;
count_all ++;
+
/* Print now! */
if (format_t != DEFAULT) {
- print_status_sep(format_t, count_all-1);
+ if (format_t == JSON && count_all > 1)
+ fputs(",", stdout);
fprintf(stdout, fmt_line, ci->key, str_status, ci->pid,
ci->counter_started, ci->counter_died,
ci->rlimits.core_size, ci->rlimits.stack_size,
ci->rlimits.nb_files, str_time, ci->group, ci->cmd);
- goto end;
- }
- switch (lvl) {
- case 0:
- fprintf(stdout, fmt_line, ci->key, str_status, ci->pid, ci->group);
- break;
- case 1:
- fprintf(stdout, fmt_line,
- ci->key, str_status, ci->pid,
- ci->counter_started, ci->counter_died,
- str_time, ci->group, ci->cmd);
- break;
- default:
- fprintf(stdout, fmt_line,
- ci->key, str_status, ci->pid,
- ci->counter_started, ci->counter_died,
- ci->rlimits.core_size, ci->rlimits.stack_size, ci->rlimits.nb_files,
- str_time, ci->group, ci->cmd);
- break;
+ } else {
+ switch (lvl) {
+ case 0:
+ fprintf(stdout, fmt_line, ci->key, str_status, ci->pid, ci->group);
+ break;
+ case 1:
+ fprintf(stdout, fmt_line,
+ ci->key, str_status, ci->pid,
+ ci->counter_started, ci->counter_died,
+ str_time, ci->group, ci->cmd);
+ break;
+ default:
+ fprintf(stdout, fmt_line,
+ ci->key, str_status, ci->pid,
+ ci->counter_started, ci->counter_died,
+ ci->rlimits.core_size, ci->rlimits.stack_size, ci->rlimits.nb_files,
+ str_time, ci->group, ci->cmd);
+ break;
+ }
}
- end:;
}
+ g_list_free_full(all_jobs, (GDestroyNotify)child_info_free);
+ g_list_free(jobs);
- if (format_t != DEFAULT)
- print_footer(format_t);
+ if (format_t == JSON)
+ fputs("]", stdout);
fflush(stdout);
/* If patterns have been specified, we must find items (the user
@@ -537,20 +581,7 @@ command_status(int lvl, int argc, char **args)
if (!counters[i])
count_misses ++;
}
-
- g_list_free_full(all_jobs, (GDestroyNotify)child_info_free);
- g_list_free(jobs);
-
- int rc = 0;
-
- if (count_down)
- rc |= 1;
- if (count_misses)
- rc |= 2;
- if (count_broken)
- rc |= 4;
-
- return rc;
+ return (count_down ? 1 : 0) | (count_misses ? 2 : 0) | (count_broken ? 4 : 0);
}
diff --git a/tools/cycle.sh b/tools/cycle.sh
new file mode 100755
index 0000000..44b2181
--- /dev/null
+++ b/tools/cycle.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+set -e
+set -x
+
+CMD="gridinit_cmd -S /tmp/gridinit/gridinit.sock"
+
+$CMD -f json status | jq
+
+for G in @test-0 @test-1 '' '@test-0 @test-1' ; do
+ $CMD status $G
+ $CMD stop $G
+ $CMD start $G
+ $CMD status $G
+done
+
+$CMD -f json status | jq
+
diff --git a/tools/gridinit-genconf.sh b/tools/gridinit-genconf.sh
index f81a5f1..65fe75d 100755
--- a/tools/gridinit-genconf.sh
+++ b/tools/gridinit-genconf.sh
@@ -1,30 +1,42 @@
#!/usr/bin/env bash
set -e
-MAX=$1
-shift
+set -x
+MAX=$1 ; shift
[[ -n "$MAX" ]]
-cat > /tmp/gridinit.conf < "$BASEDIR/gridinit.conf" <> /tmp/gridinit.conf <> $BASEDIR/$sub/service-${i}.conf <