Skip to content

Commit 2e4a13d

Browse files
authored
Merge pull request #5848 from grondo/post-event
add utility for posting job events manually if required
2 parents 6e82f81 + 0304022 commit 2e4a13d

File tree

8 files changed

+163
-3
lines changed

8 files changed

+163
-3
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ skip = [
1010
"src/bindings/python/flux/resource/__init__.py"]
1111

1212
[tool.mypy]
13-
python_version = 3.6
13+
python_version = "3.6"
1414
files = ["src/cmd/**/*.py", "src/bindings/python/flux", "t/python/*.py"]
1515
mypy_path = ["src/bindings/python", "t/python/tap", "t/python"]
1616
allow_redefinition = true

src/cmd/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ dist_fluxcmd_SCRIPTS = \
120120
flux-update.py \
121121
flux-imp-exec-helper \
122122
py-runner.py \
123-
flux-hostlist.py
123+
flux-hostlist.py \
124+
flux-post-job-event.py
124125

125126
fluxcmd_PROGRAMS = \
126127
flux-terminus \

src/cmd/flux-post-job-event.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/false
2+
##############################################################
3+
# Copyright 2024 Lawrence Livermore National Security, LLC
4+
# (c.f. AUTHORS, NOTICE.LLNS, COPYING)
5+
#
6+
# This file is part of the Flux resource manager framework.
7+
# For details, see https://github.com/flux-framework.
8+
#
9+
# SPDX-License-Identifier: LGPL-3.0
10+
##############################################################
11+
12+
import argparse
13+
import logging
14+
15+
import flux
16+
from flux.job import JobID
17+
from flux.util import TreedictAction
18+
19+
20+
def post_event(args):
21+
"""Post an event to the job-manager.post-event.post service"""
22+
23+
req = {"id": JobID(args.id), "name": args.name}
24+
if args.context:
25+
req["context"] = args.context
26+
27+
try:
28+
flux.Flux().rpc("job-manager.post-event.post", req).get()
29+
except FileNotFoundError:
30+
raise ValueError(f"No such job {args.id}")
31+
32+
33+
LOGGER = logging.getLogger("flux-job-post-event")
34+
35+
36+
@flux.util.CLIMain(LOGGER)
37+
def main():
38+
parser = argparse.ArgumentParser(prog="flux-job-post-event")
39+
parser.add_argument("id", help="jobid to which event shall be posted")
40+
parser.add_argument("name", help="name of event to post")
41+
parser.add_argument(
42+
"context",
43+
help="List of key=value pairs to set as event context",
44+
action=TreedictAction,
45+
nargs=argparse.REMAINDER,
46+
)
47+
parser.set_defaults(func=post_event)
48+
args = parser.parse_args()
49+
args.func(args)
50+
51+
52+
if __name__ == "__main__":
53+
main()
54+
55+
# vi: ts=4 sw=4 expandtab

src/modules/job-manager/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ libjob_manager_la_SOURCES = \
7474
plugins/begin-time.c \
7575
plugins/update-duration.c \
7676
plugins/validate-duration.c \
77-
plugins/history.c
77+
plugins/history.c \
78+
plugins/post-event.c
7879

7980
fluxinclude_HEADERS = \
8081
jobtap.h

src/modules/job-manager/jobtap.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ extern int begin_time_plugin_init (flux_plugin_t *p);
5151
extern int validate_duration_plugin_init (flux_plugin_t *p);
5252
extern int update_duration_plugin_init (flux_plugin_t *p);
5353
extern int history_plugin_init (flux_plugin_t *p);
54+
extern int post_event_init (flux_plugin_t *p);
5455

5556
struct jobtap_builtin {
5657
const char *name;
@@ -72,6 +73,7 @@ static struct jobtap_builtin jobtap_builtins [] = {
7273
{ ".validate-duration", &validate_duration_plugin_init },
7374
{ ".update-duration", &update_duration_plugin_init },
7475
{ ".history", &history_plugin_init },
76+
{ ".post-event", &post_event_init },
7577
{ 0 },
7678
};
7779

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/************************************************************\
2+
* Copyright 2024 Lawrence Livermore National Security, LLC
3+
* (c.f. AUTHORS, NOTICE.LLNS, COPYING)
4+
*
5+
* This file is part of the Flux resource manager framework.
6+
* For details, see https://github.com/flux-framework.
7+
*
8+
* SPDX-License-Identifier: LGPL-3.0
9+
\************************************************************/
10+
11+
/* post-event.c - post manual events to job eventlog
12+
*/
13+
14+
#if HAVE_CONFIG_H
15+
#include "config.h"
16+
#endif
17+
18+
#include <jansson.h>
19+
#include <flux/core.h>
20+
#include <flux/jobtap.h>
21+
22+
static void post_event_cb (flux_t *h,
23+
flux_msg_handler_t *mh,
24+
const flux_msg_t *msg,
25+
void *arg)
26+
{
27+
flux_plugin_t *p = arg;
28+
flux_jobid_t id;
29+
const char *name;
30+
json_t *context = NULL;
31+
32+
if (flux_msg_unpack (msg,
33+
"{s:I s:s s?o}",
34+
"id", &id,
35+
"name", &name,
36+
"context", &context) < 0)
37+
goto error;
38+
if (context) {
39+
if (flux_jobtap_event_post_pack (p, id, name, "O", context) < 0)
40+
goto error;
41+
}
42+
else if (flux_jobtap_event_post_pack (p, id, name, NULL) < 0)
43+
goto error;
44+
if (flux_respond (h, msg, NULL) < 0)
45+
flux_log_error (h, "error responding to job-manager.post-event");
46+
error:
47+
if (flux_respond_error (h, msg, errno, NULL) < 0)
48+
flux_log_error (h, "error responding to job-manager.post-event");
49+
}
50+
51+
52+
int post_event_init (flux_plugin_t *p)
53+
{
54+
if (flux_jobtap_service_register_ex (p, "post", 0, post_event_cb, p) < 0)
55+
return -1;
56+
return 0;
57+
}
58+
59+
// vi:ts=4 sw=4 expandtab

t/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ TESTSCRIPTS = \
233233
t2812-flux-job-last.t \
234234
t2813-flux-watch.t \
235235
t2814-hostlist-cmd.t \
236+
t2815-post-job-event.t \
236237
t2900-job-timelimits.t \
237238
t3000-mpi-basic.t \
238239
t3001-mpi-personalities.t \

t/t2815-post-job-event.t

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/sh
2+
3+
test_description='Test flux post-job-event command'
4+
5+
. $(dirname $0)/sharness.sh
6+
7+
test_under_flux 1
8+
9+
test_expect_success 'run a test job' '
10+
JOBID=$(flux submit --wait-event=start sleep inf)
11+
'
12+
test_expect_success 'flux-post-job-event --help works' '
13+
flux post-job-event --help >help.out &&
14+
test_debug "cat help.out" &&
15+
grep "name of event to post" help.out
16+
'
17+
test_expect_success 'flux-post-job-event can post a simple event' '
18+
flux post-job-event $JOBID test &&
19+
flux job wait-event -t15 $JOBID test
20+
'
21+
test_expect_success 'flux-post-job-event can post an event with context' '
22+
flux post-job-event $JOBID test note=testing &&
23+
flux job wait-event -m note=testing -t15 $JOBID test
24+
'
25+
test_expect_success 'flux-post-job-event can post multiple context keys' '
26+
flux post-job-event $JOBID test note=test2 status=0 &&
27+
flux job wait-event -m note=test2 -t15 $JOBID test &&
28+
flux job wait-event -m status=0 -t15 $JOBID test
29+
'
30+
test_expect_success 'flux-post-job-event fails for invalid job' '
31+
test_must_fail flux post-job-event f123 test note="test event"
32+
'
33+
test_expect_success 'flux-post-job-event fails for inactive job' '
34+
flux cancel $JOBID &&
35+
flux job wait-event $JOBID clean &&
36+
test_must_fail flux post-job-event $JOBID test note="test event"
37+
'
38+
test_expect_success 'flux-post-job-event fails with invalid id' '
39+
test_must_fail flux post-job-event baz test
40+
'
41+
test_done

0 commit comments

Comments
 (0)