Skip to content

Commit 7083ce3

Browse files
authored
Merge pull request #5156 from chu11/issue5119_job_list_cwd
job-list: support retrieving current working directory for jobs
2 parents 89c42aa + c04f46a commit 7083ce3

File tree

13 files changed

+225
-6
lines changed

13 files changed

+225
-6
lines changed

doc/man1/flux-jobs.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ The field names that can be specified are:
302302
**name**
303303
job name
304304

305+
**cwd**
306+
job current working directory
307+
305308
**queue**
306309
job queue
307310

src/bindings/python/flux/job/info.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ class JobInfo:
281281
"duration": 0.0,
282282
"expiration": 0.0,
283283
"name": "",
284+
"cwd": "",
284285
"queue": "",
285286
"ntasks": "",
286287
"ncores": "",
@@ -559,6 +560,7 @@ def job_fields_to_attrs(fields):
559560
"state_single": ("state",),
560561
"state_emoji": ("state",),
561562
"name": ("name",),
563+
"cwd": ("cwd",),
562564
"queue": ("queue",),
563565
"ntasks": ("ntasks",),
564566
"ncores": ("ncores",),
@@ -641,6 +643,7 @@ class JobInfoFormat(flux.util.OutputFormat):
641643
"state_single": "S",
642644
"state_emoji": "STATE",
643645
"name": "NAME",
646+
"cwd": "CWD",
644647
"queue": "QUEUE",
645648
"ntasks": "NTASKS",
646649
"ncores": "NCORES",

src/modules/job-list/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ EXTRA_DIST = \
9494
test/jobspec/4slot.jobspec \
9595
test/jobspec/4slot_perresourcecore4.jobspec \
9696
test/jobspec/duration_alt.jobspec \
97+
test/jobspec/queue_specified.jobspec \
98+
test/jobspec/cwd_not_specified.jobspec \
9799
test/jobspec/invalid_attributes_system_job.jobspec \
98100
test/jobspec/invalid_command_array.jobspec \
99101
test/jobspec/invalid_command_string.jobspec \

src/modules/job-list/job-list.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
static const char *attrs[] = {
2626
"userid", "urgency", "priority", "t_submit",
2727
"t_depend", "t_run", "t_cleanup", "t_inactive",
28-
"state", "name", "queue", "ntasks", "ncores", "duration", "nnodes",
28+
"state", "name", "cwd", "queue", "ntasks", "ncores", "duration", "nnodes",
2929
"ranks", "nodelist", "success", "exception_occurred",
3030
"exception_type", "exception_severity",
3131
"exception_note", "result", "expiration",

src/modules/job-list/job_data.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,10 @@ static int parse_jobspec (struct job *job, const char *s, bool allow_nonfatal)
308308
goto nonfatal_error;
309309

310310
if (json_unpack_ex (job->jobspec, &error, 0,
311-
"{s:{s:{s?:s}}}",
311+
"{s:{s:{s?:s s?s}}}",
312312
"attributes",
313313
"system",
314+
"cwd", &job->cwd,
314315
"queue", &job->queue) < 0) {
315316
flux_log (job->h, LOG_ERR,
316317
"%s: job %ju invalid jobspec: %s",

src/modules/job-list/job_data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct job {
4444
flux_job_state_t state;
4545
const char *name;
4646
const char *queue;
47+
const char *cwd;
4748
int ntasks;
4849
int ntasks_per_core_on_node_count; /* flag for ntasks calculation */
4950
int ncores;

src/modules/job-list/job_util.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ static int store_attr (struct job *job,
9595
return 0;
9696
val = json_string (job->name);
9797
}
98+
else if (streq (attr, "cwd")) {
99+
/* job->cwd potentially NULL, is optional in jobspec */
100+
if (!job->cwd)
101+
return 0;
102+
val = json_string (job->cwd);
103+
}
98104
else if (streq (attr, "queue")) {
99105
/* job->queue potentially NULL if:
100106
* - unspecified

src/modules/job-list/test/job_data.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ struct test_jobspec_job_name {
5858
{ NULL, 0 },
5959
};
6060

61+
struct test_jobspec_cwd {
62+
const char *filename;
63+
const char *cwd;
64+
} jobspec_cwd_tests[] = {
65+
{ TEST_SRCDIR "/jobspec/1slot.jobspec", "/tmp/job" },
66+
{ TEST_SRCDIR "/jobspec/cwd_not_specified.jobspec", NULL },
67+
{ NULL, 0 },
68+
};
69+
70+
struct test_jobspec_queue {
71+
const char *filename;
72+
const char *queue;
73+
} jobspec_queue_tests[] = {
74+
{ TEST_SRCDIR "/jobspec/1slot.jobspec", NULL },
75+
{ TEST_SRCDIR "/jobspec/queue_specified.jobspec", "batch" },
76+
{ NULL, 0 },
77+
};
78+
6179
struct test_jobspec_duration {
6280
const char *filename;
6381
double duration;
@@ -347,6 +365,68 @@ static void test_jobspec_job_name (void)
347365
}
348366
}
349367

368+
static void test_jobspec_cwd (void)
369+
{
370+
struct test_jobspec_cwd *test;
371+
372+
test = jobspec_cwd_tests;
373+
while (test->filename) {
374+
struct job *job = job_create (NULL, FLUX_JOBID_ANY);
375+
const char *filename = test->filename;
376+
const char *cwd = test->cwd;
377+
int ret;
378+
379+
if (!job)
380+
BAIL_OUT ("job_create failed");
381+
382+
ret = parse_jobspec (job, filename);
383+
ok (ret == 0, "job_parse_jobspec parsed %s", filename);
384+
if (cwd) {
385+
ok (streq (cwd, job->cwd),
386+
"job_parse_jobspec correctly parsed job cwd %s=%s",
387+
cwd, job->cwd);
388+
}
389+
else {
390+
ok (job->cwd == NULL,
391+
"job_parse_jobspec correctly parsed no job cwd");
392+
}
393+
394+
job_destroy (job);
395+
test++;
396+
}
397+
}
398+
399+
static void test_jobspec_queue (void)
400+
{
401+
struct test_jobspec_queue *test;
402+
403+
test = jobspec_queue_tests;
404+
while (test->filename) {
405+
struct job *job = job_create (NULL, FLUX_JOBID_ANY);
406+
const char *filename = test->filename;
407+
const char *queue = test->queue;
408+
int ret;
409+
410+
if (!job)
411+
BAIL_OUT ("job_create failed");
412+
413+
ret = parse_jobspec (job, filename);
414+
ok (ret == 0, "job_parse_jobspec parsed %s", filename);
415+
if (queue) {
416+
ok (streq (queue, job->queue),
417+
"job_parse_jobspec correctly parsed job queue %s=%s",
418+
queue, job->queue);
419+
}
420+
else {
421+
ok (job->queue == NULL,
422+
"job_parse_jobspec correctly parsed no job queue");
423+
}
424+
425+
job_destroy (job);
426+
test++;
427+
}
428+
}
429+
350430
static void test_jobspec_duration (void)
351431
{
352432
struct test_jobspec_duration *test;
@@ -555,6 +635,8 @@ int main (int argc, char *argv[])
555635

556636
test_jobspec_corner_case ();
557637
test_jobspec_job_name ();
638+
test_jobspec_cwd ();
639+
test_jobspec_queue ();
558640
test_jobspec_duration ();
559641
test_R_corner_case ();
560642
test_R_ranks ();
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"resources": [
3+
{
4+
"type": "slot",
5+
"count": 1,
6+
"with": [
7+
{
8+
"type": "core",
9+
"count": 1
10+
}
11+
],
12+
"label": "task"
13+
}
14+
],
15+
"tasks": [
16+
{
17+
"command": [
18+
"hostname"
19+
],
20+
"slot": "task",
21+
"count": {
22+
"per_slot": 1
23+
}
24+
}
25+
],
26+
"attributes": {
27+
"system": {
28+
"duration": 0
29+
}
30+
},
31+
"version": 1
32+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"resources": [
3+
{
4+
"type": "slot",
5+
"count": 1,
6+
"with": [
7+
{
8+
"type": "core",
9+
"count": 1
10+
}
11+
],
12+
"label": "task"
13+
}
14+
],
15+
"tasks": [
16+
{
17+
"command": [
18+
"hostname"
19+
],
20+
"slot": "task",
21+
"count": {
22+
"per_slot": 1
23+
}
24+
}
25+
],
26+
"attributes": {
27+
"system": {
28+
"duration": 0,
29+
"cwd": "/tmp/job",
30+
"queue": "batch"
31+
}
32+
},
33+
"version": 1
34+
}

0 commit comments

Comments
 (0)