Skip to content

Commit

Permalink
Merge pull request #1143 from grondo/cron-jansson
Browse files Browse the repository at this point in the history
cron: avoid use of json-c and xzmalloc
  • Loading branch information
garlick authored Aug 16, 2017
2 parents fc2a4ff + be2bfe2 commit 8e439c6
Show file tree
Hide file tree
Showing 15 changed files with 561 additions and 292 deletions.
35 changes: 35 additions & 0 deletions doc/man1/flux-cron.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ Options:
The '--options' option allows a comma separated list of extra options to be
passed to the flux-cron service. See EXTRA OPTIONS below.

--preserve-env:::
-E:::
The '--preserve-env' option allows the current environment to be exported
and used for the command being executed as part of the cron job. Normally,
the broker environment is used.

--working-dir='DIR':::
-d 'DIR':::
The '--working-dir' option allows the working directory to be set for the command
being executed as part of the cron job. Normally, the working directory of
the broker is used.

*event* [OPTIONS] 'topic' 'command'::

Create a cron entry to execute 'command' after every event matching 'topic'.
Expand Down Expand Up @@ -99,6 +111,18 @@ Create a cron entry to execute 'command' after every event matching 'topic'.
-o 'LIST':::
Set comma separated EXTRA OPTIONS for this cron entry.

--preserve-env:::
-E:::
The '--preserve-env' option allows the current environment to be exported
and used for the command being executed as part of the cron job. Normally,
the broker environment is used.

--working-dir='DIR':::
-d 'DIR':::
The '--working-dir' option allows the working directory to be set for the command
being executed as part of the cron job. Normally, the working directory of
the broker is used.

*tab* [OPTIONS] ['file'] ::
Process one or more lines containing crontab expressions from 'file'
(stdin by default) Each valid crontab line will result in a new cron
Expand All @@ -118,6 +142,17 @@ Run 'command' at specific date and time described by 'string'
-o 'LIST':::
Set comma separated EXTRA OPTIONS for all cron entries.

--preserve-env:::
-E:::
The '--preserve-env' option allows the current environment to be exported
and used for the command being executed as part of the cron job. Normally,
the broker environment is used.

--working-dir='DIR':::
-d 'DIR':::
The '--working-dir' option allows the working directory to be set for the command
being executed as part of the cron job. Normally, the working directory of
the broker is used.
*list*::
Display a list of current entries registered with the cron module and
their current state, last run time, etc.
Expand Down
38 changes: 34 additions & 4 deletions src/cmd/flux-cron
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ local function parse_time (s)
if suffix and m [suffix] then
n = (n * m [suffix])
end
return (n)
return tonumber (n)
end

local function now ()
Expand Down Expand Up @@ -129,14 +129,18 @@ function Command:request (type, typeargs, arg)
args = typeargs,
command = command,
name = self.opt.N or command:match("%S+"),
["repeat"] = self.opt.c
cwd = self.opt.d,
["repeat"] = tonumber (self.opt.c)
}
if self.opt.E then
req.environ = require 'posix'.getenv ()
end
-- Process comma-separated list of options to add undocumented
-- members to JSON request, e.g. `-o rank=1,task-history-count=5`
if self.opt.o then
for opt in self.opt.o:gmatch ("[^,]+") do
local k,v = opt:match("(.+)=(.+)")
req[k] = v
req[k] = tonumber (v)
end
end
return f:rpc ("cron.create", req)
Expand All @@ -160,6 +164,12 @@ program:SubCommand {
{ name = "options", char = "o", arg = "OPTS",
usage = "Comma separated list of key=value options to set in request"
},
{ name = "preserve-env", char = "E",
usage = "Use current environment for cron command"
},
{ name = "working-dir", char = "d", arg = "DIR",
usage = "Set working director for cron command"
}
},
handler = function (self, arg)
if #arg < 2 then self:die ("INTERVAL and COMMAND required") end
Expand Down Expand Up @@ -197,12 +207,20 @@ program:SubCommand {
},
{ name = "name", char = "N", arg = "S",
usage = "Name cron job string S instead of default"
},
{ name = "preserve-env", char = "E",
usage = "Use current environment for cron command"
},
{ name = "working-dir", char = "d", arg = "DIR",
usage = "Set working director for cron command"
}
},
handler = function (self, arg)
if #arg < 2 then self:die ("TOPIC and COMMAND args are required") end
local topic = table.remove (arg, 1)
local args = { topic = topic, nth = self.opt.n, after = self.opt.a }
local args = { topic = topic,
nth = tonumber (self.opt.n),
after = tonumber (self.opt.a) }
args.min_interval = parse_time (self.opt.i)

local resp, err = self:request ("event", args, arg)
Expand All @@ -219,6 +237,12 @@ program:SubCommand {
{ name = "options", char = "o", arg = "OPTS",
usage = "Comma separated list of key=value options to set in request"
},
{ name = "preserve-env", char = "E",
usage = "Use current environment for cron command"
},
{ name = "working-dir", char = "d", arg = "DIR",
usage = "Set working director for cron command"
}
},
handler = function (self, arg)
local fp = io.stdin
Expand Down Expand Up @@ -271,6 +295,12 @@ program:SubCommand {
{ name = "options", char = "o", arg = "OPTS",
usage = "Comma separated list of key=value options to set in request"
},
{ name = "preserve-env", char = "E",
usage = "Use current environment for cron command"
},
{ name = "working-dir", char = "d", arg = "DIR",
usage = "Set working director for cron command"
}
},
handler = function (self, arg)
if #arg < 2 then self:die ("TIME and COMMAND args are required") end
Expand Down
14 changes: 14 additions & 0 deletions src/common/libutil/cronodate.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,20 @@ int cronodate_set (cronodate_t *d, tm_unit_t item, const char *range)
return range_parse (n, item, range);
}

int cronodate_set_integer (cronodate_t *d, tm_unit_t item, int value)
{
nodeset_t *n = d->item [item];
assert (n != NULL);
if (value > tm_unit_max (item) || value < tm_unit_min (item)) {
errno = ERANGE;
return -1;
}
/* Clear all members before setting the new value */
nodeset_delete_range (n, tm_unit_min (item), tm_unit_max (item));
nodeset_add_rank (n, value);
return 0;
}

const char *cronodate_get (cronodate_t *d, tm_unit_t u)
{
return (nodeset_string (d->item [u]));
Expand Down
8 changes: 7 additions & 1 deletion src/common/libutil/cronodate.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ void cronodate_emptyset (cronodate_t *);
*/
int cronodate_set (cronodate_t *d, tm_unit_t u, const char *range);

/* Set cronodate field for time unit u to a single value
* Returns EINVAL if value is outside of [min, max] for time unit u.
* Returns 0 on success.
*/
int cronodate_set_integer (cronodate_t *d, tm_unit_t u, int value);

/* Get the current set/range for time unit `u` in cronodate object `d`
* in the form of a nodeset range string.
*/
Expand All @@ -73,7 +79,7 @@ const char *cronodate_get (cronodate_t *d, tm_unit_t u);
*/
bool cronodate_match (cronodate_t *d, struct tm *tm);

/*
/*
* Advance `now` to the next date/time that will match `m`.
*/
int cronodate_next (cronodate_t *d, struct tm *now);
Expand Down
11 changes: 0 additions & 11 deletions src/common/libutil/shortjson.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,6 @@ Jput (json_object *o)
json_object_put (o);
}

/* Add bool to JSON.
*/
static __inline__ void
Jadd_bool (json_object *o, const char *name, bool b)
{
json_object *n = json_object_new_boolean (b);
if (!n)
oom ();
json_object_object_add (o, (char *)name, n);
}

/* Add integer to JSON.
*/
static __inline__ void
Expand Down
41 changes: 41 additions & 0 deletions src/common/libutil/test/cronodate.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,47 @@ int main (int argc, char *argv[])
ok (cronodate_check_next (d, "2016-06-06 08:00:00", "2016-06-13 08:00:00"),
"cronodate_next returns next matching date when current matches ");

cronodate_fillset (d);
// Same as above, but use cronodate_set_integer()
ok (cronodate_set_integer (d, TM_SEC, 0) >= 0, "set integer, sec = 0");
ok (cronodate_set_integer (d, TM_MIN, 0) >= 0, "set integer, min = 0");
ok (cronodate_set_integer (d, TM_HOUR, 8) >= 0, "set integer, hour = 0");
ok (cronodate_set_integer (d, TM_WDAY, 1) >= 0, "set integer, wday = 1 (Mon)");
ok (cronodate_check_next (d, "2016-06-01 10:45:00", "2016-06-06 08:00:00"),
"cronodate_next worked for next monday");
ok (cronodate_check_next (d, "2016-06-06 08:00:00", "2016-06-13 08:00:00"),
"cronodate_next returns next matching date when current matches ");

// ERANGE test for cronodate_set_integer
ok (cronodate_set_integer (d, TM_SEC, -1) < 0 && errno == ERANGE,
"TM_SEC == -1 returns ERANGE");
ok (cronodate_set_integer (d, TM_SEC, 61) < 0 && errno == ERANGE,
"TM_SEC == 61 returns ERANGE");
ok (cronodate_set_integer (d, TM_MIN, -1) < 0 && errno == ERANGE,
"TM_MIN == -1 returns ERANGE");
ok (cronodate_set_integer (d, TM_MIN, 60) < 0 && errno == ERANGE,
"TM_MIN == 60 returns ERANGE");
ok (cronodate_set_integer (d, TM_HOUR, -1) < 0 && errno == ERANGE,
"TM_HOUR == 0 returns ERANGE");
ok (cronodate_set_integer (d, TM_HOUR, 24) < 0 && errno == ERANGE,
"TM_HOUR == 24 returns ERANGE");
ok (cronodate_set_integer (d, TM_WDAY, -1) < 0 && errno == ERANGE,
"TM_WDAY == -1 returns ERANGE");
ok (cronodate_set_integer (d, TM_WDAY, 7) < 0 && errno == ERANGE,
"TM_WDAY == 24 returns ERANGE");
ok (cronodate_set_integer (d, TM_MON, -1) < 0 && errno == ERANGE,
"TM_MON == -1 returns ERANGE");
ok (cronodate_set_integer (d, TM_MON, 12) < 0 && errno == ERANGE,
"TM_MON == 12 returns ERANGE");
ok (cronodate_set_integer (d, TM_MDAY, 0) < 0 && errno == ERANGE,
"TM_MDAY == 0 returns ERANGE");
ok (cronodate_set_integer (d, TM_MDAY, 32) < 0 && errno == ERANGE,
"TM_MDAY == 32 returns ERANGE");
ok (cronodate_set_integer (d, TM_YEAR, -1) < 0 && errno == ERANGE,
"TM_YEAR == -1 returns ERANGE");
ok (cronodate_set_integer (d, TM_YEAR, 3001-1900) < 0 && errno == ERANGE,
"TM_YEAR == %d returns ERANGE", 3001-1900);

ok (cronodate_set (d, TM_MON, "6") >= 0, "date glob set, mon = 6");
ok (cronodate_set (d, TM_MDAY, "6") >= 0, "date glob set, mday = 6");
ok (cronodate_set (d, TM_YEAR, "*") >= 0, "date glob set, year = *");
Expand Down
Loading

0 comments on commit 8e439c6

Please sign in to comment.