From 8b3ecf893299808b5323a782c24371e6b81b8e92 Mon Sep 17 00:00:00 2001 From: "Dong H. Ahn" Date: Thu, 4 Nov 2021 20:39:23 -0700 Subject: [PATCH] jobspec: add level 0 support for moldable jobspecs Problem: job-list and jobshell currently assume an integer value for the "count" key within a jobspec. While this complies with RFC 25 (Jobspec V1), this disallows users to submit a moldable jobspec that contains a dictionary instead with min/max/operator/operand with the count key. Because moldability will soon be required to enable node-exclusive scheduling for our system instance work, we need level 0 support. Modify parse_res_level() functions within job-list and jobshell where this assumption is made. Unpack the "count" key as a json_t object instead of an integer object in those functions and subsequently handle the moldable jobspec case where its value is a dictionary. Does not change semantics whatsoever since this is level-0 support. As such, the min count is used for these components when a moldable jobspec is given. --- src/modules/job-list/job_state.c | 16 ++++++++++++++-- src/shell/jobspec.c | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/modules/job-list/job_state.c b/src/modules/job-list/job_state.c index 12ea94da05a3..2feeac139e10 100644 --- a/src/modules/job-list/job_state.c +++ b/src/modules/job-list/job_state.c @@ -357,20 +357,32 @@ static int parse_res_level (struct list_ctx *ctx, { json_error_t error; struct res_level res; + json_t *cnt_o = NULL; res.with = NULL; /* For jobspec version 1, expect exactly one array element per level. */ if (json_unpack_ex (o, &error, 0, - "[{s:s s:i s?o}]", + "[{s:s s:o s?o}]", "type", &res.type, - "count", &res.count, + "count", &cnt_o, "with", &res.with) < 0) { flux_log (ctx->h, LOG_ERR, "%s: job %ju invalid jobspec: %s", __FUNCTION__, (uintmax_t)job->id, error.text); return -1; } + if (json_is_integer (cnt_o)) + res.count = json_integer_value (cnt_o); + else if (json_unpack_ex (cnt_o, &error, 0, + "{s:i}", + "min", &res.count)) { + flux_log (ctx->h, LOG_ERR, + "%s: job %ju invalid count format in jobspec: %s", + __FUNCTION__, (uintmax_t)job->id, error.text); + return -1; + } + *resp = res; return 0; } diff --git a/src/shell/jobspec.c b/src/shell/jobspec.c index 317e60ec7e92..1eda186255e9 100644 --- a/src/shell/jobspec.c +++ b/src/shell/jobspec.c @@ -40,6 +40,7 @@ static int parse_res_level (json_t *o, { json_error_t loc_error; struct res_level res; + json_t *cnt_o = NULL; if (o == NULL) { set_error (error, "level %d: missing", level); @@ -49,13 +50,22 @@ static int parse_res_level (json_t *o, /* For jobspec version 1, expect exactly one array element per level. */ if (json_unpack_ex (o, &loc_error, 0, - "{s:s s:i s?o}", + "{s:s s:o s?o}", "type", &res.type, - "count", &res.count, + "count", &cnt_o, "with", &res.with) < 0) { set_error (error, "level %d: %s", level, loc_error.text); return -1; } + if (json_is_integer (cnt_o)) + res.count = json_integer_value (cnt_o); + else if (json_unpack_ex (cnt_o, &loc_error, 0, + "{s:i}", + "min", &res.count)) { + set_error (error, "level %d (count): %s", level, loc_error.text); + return -1; + } + *resp = res; return 0; }