Skip to content

Commit

Permalink
Merge pull request #6557 from grondo/flux-root-opt
Browse files Browse the repository at this point in the history
add `flux --root` option
  • Loading branch information
mergify[bot] authored Jan 17, 2025
2 parents 8ffa947 + a4a568c commit 8259a8f
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 17 deletions.
5 changes: 5 additions & 0 deletions doc/man1/flux.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ OPTIONS
:envvar:`FLUX_KVS_NAMESPACE` if current instance is confined to a KVS
namespace in the parent. This option may be specified multiple times.

.. option:: -r, --root

Like :option:`--parent`, but connect to the top-level, or root, instance.
This overrides any other uses of the :option:`--parent` option.

.. option:: -v, --verbose

Display command environment, and the path search for *CMD*.
Expand Down
78 changes: 61 additions & 17 deletions src/cmd/flux.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,29 @@ void setup_keydir (struct environment *env, int flags);
static void print_environment (struct environment *env);
static void register_builtin_subcommands (optparse_t *p);
static void push_parent_environment (optparse_t *p, struct environment *env);
static int current_instance_level (optparse_t *p);

static struct optparse_option opts[] = {
{ .name = "verbose", .key = 'v', .has_arg = 0,
{ .name = "verbose",
.key = 'v',
.has_arg = 0,
.usage = "Be verbose about environment and command search",
},
{ .name = "version", .key = 'V', .has_arg = 0,
{ .name = "version",
.key = 'V',
.has_arg = 0,
.usage = "Display command and component versions",
},
{ .name = "parent", .key = 'p', .has_arg = 0,
{ .name = "parent",
.key = 'p',
.has_arg = 0,
.usage = "Set environment of parent instead of current instance",
},
{ .name = "root",
.key = 'r',
.has_arg = 0,
.usage = "Set environment of root instead of current instance",
},
OPTPARSE_TABLE_END
};

Expand All @@ -64,7 +76,8 @@ void usage (optparse_t *p)
const char *val = getenv ("FLUX_CMDHELP_PATTERN");
const char *def = default_cmdhelp_pattern (p);

if (asprintf (&help_pattern, "%s%s%s",
if (asprintf (&help_pattern,
"%s%s%s",
def ? def : "",
val ? ":" : "",
val ? val : "") < 0)
Expand Down Expand Up @@ -121,6 +134,7 @@ int main (int argc, char *argv[])
const char *argv0 = argv[0];
int flags = FLUX_CONF_INSTALLED;
int optindex;
int n;

log_init ("flux");

Expand Down Expand Up @@ -221,9 +235,14 @@ int main (int argc, char *argv[])

environment_apply (env);

/* If --parent, push parent environment for each occurrence
/* If --parent, push parent environment for each occurrence.
* If --root, act as if --parent was used instance-level times.
*/
for (int n = optparse_getopt (p, "parent", NULL); n > 0; n--) {
if (optparse_hasopt (p, "root"))
n = current_instance_level (p);
else
n = optparse_getopt (p, "parent", NULL);
while (n-- > 0) {
push_parent_environment (p, env);
environment_apply (env);
}
Expand Down Expand Up @@ -317,8 +336,10 @@ void setup_path (struct environment *env, const char *argv0)
/* Check for a flux-<command>.py in dir and execute it under the configured
* PYTHON_INTERPRETER if found.
*/
void exec_subcommand_py (bool vopt, const char *dir,
int argc, char *argv[],
void exec_subcommand_py (bool vopt,
const char *dir,
int argc,
char *argv[],
const char *prefix)
{
char *path = xasprintf ("%s%s%s%s.py",
Expand All @@ -345,13 +366,16 @@ void exec_subcommand_py (bool vopt, const char *dir,
free (path);
}

void exec_subcommand_dir (bool vopt, const char *dir, char *argv[],
const char *prefix)
void exec_subcommand_dir (bool vopt,
const char *dir,
char *argv[],
const char *prefix)
{
char *path = xasprintf ("%s%s%s%s",
dir ? dir : "",
dir ? "/" : "",
prefix ? prefix : "", argv[0]);
prefix ? prefix : "",
argv[0]);
if (vopt)
log_msg ("trying to exec %s", path);
execvp (path, argv); /* no return if successful */
Expand Down Expand Up @@ -381,7 +405,7 @@ void exec_subcommand (const char *searchpath, bool vopt, int argc, char *argv[])
}
}

static flux_t *flux_open_internal (optparse_t *p, const char *uri)
static flux_t *flux_open_internal (optparse_t *p)
{
flux_t *h = NULL;
if ((h = optparse_get_data (p, "flux_t")))
Expand All @@ -400,11 +424,32 @@ static void flux_close_internal (optparse_t *p)
}
}

static int current_instance_level (optparse_t *p)
{
const char *s;
char *endptr;
long int l;
flux_t *h;

if (!(h = flux_open_internal (p)))
log_err_exit ("flux_open");

if (!(s = flux_attr_get (h, "instance-level")))
log_err_exit ("failed to get instance-level attribute");

errno = 0;
l = strtol (s, &endptr, 10);
if (errno != 0 || *endptr != '\0')
log_err_exit ("got invalid instance-level attribute: %s", s);

return (int) l;
}

static void push_parent_environment (optparse_t *p, struct environment *env)
{
const char *uri;
const char *ns;
flux_t *h = flux_open_internal (p, NULL);
flux_t *h = flux_open_internal (p);

if (h == NULL)
log_err_exit ("flux_open");
Expand All @@ -425,11 +470,10 @@ static void push_parent_environment (optparse_t *p, struct environment *env)
else
environment_unset (env, "FLUX_KVS_NAMESPACE");

/* Now close current handle and connect to parent URI.
/* Now close current handle. Next call to `flux_open()` will
* have FLUX_URI set to parent after environment_apply() is called.
*/
flux_close_internal (p);
if (!(h = flux_open_internal (p, uri)))
log_err_exit ("flux_open (parent)");
}

static void print_environment (struct environment *env)
Expand All @@ -442,7 +486,7 @@ static void print_environment (struct environment *env)

flux_t *builtin_get_flux_handle (optparse_t *p)
{
return flux_open_internal (p, NULL);
return flux_open_internal (p);
}

static void register_builtin_subcommands (optparse_t *p)
Expand Down
13 changes: 13 additions & 0 deletions t/t3100-flux-in-flux.t
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@ test_expect_success "flux --parent --parent works in subinstance" '
test_cmp guest2.test.exp guest2.test
'

test_expect_success "flux --root works in subinstance" '
id=$(flux batch -n1 --wrap \
flux run flux start ${ARGS} \
flux --root getattr instance-level) &&
flux job wait-event -vt 30 $id clean &&
test_debug "cat flux-${id}.out" &&
test "$(cat flux-${id}.out)" -eq 0
'

test_expect_success 'flux --root returns current instance at depth 0' '
test $(flux --root getattr instance-level) -eq 0
'

test_expect_success "instance-level attribute = 0 in new standalone instance" '
flux start ${ARGS} flux getattr instance-level >level_new.out &&
echo 0 >level_new.exp &&
Expand Down

0 comments on commit 8259a8f

Please sign in to comment.