Skip to content

Commit 44dc1dd

Browse files
authored
Add --env: argument to plugin and more log messages for debugging environment variable related issues (#152)
* Add more debug messages - Dump environment variables of slurmstepd * add --env:key=value * describe --env: argument * minor update of README * minor update of README * add some comments
1 parent 1ccfa40 commit 44dc1dd

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

plugins/spank_qrmi/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ Note that administrator needs to create `qrmi_config.json` file and specify the
8888
optional /usr/lib64/slurm/spank_qrmi.so /etc/slurm/qrmi_config.json
8989
```
9090

91+
> [!NOTE]
92+
> There are optional argumentis available. It allows you to add environment variables to the Slurm process where the SPANK plugin is loaded. The format for specifying environment variables is defined as follows.
93+
> ```bash
94+
> --env:{variable name}={value}
95+
> ```
96+
>
97+
> For example, when interacting with Quantum resources via an HTTP proxy, the environment variables `http_proxy`, `https_proxy`, and `no_proxy` are required. These can be added as shown below.
98+
> ```bash
99+
> optional /usr/lib64/slurm/spank_qrmi.so /etc/slurm/qrmi_config.json --env:http_proxy=http://192.168.1.128:3128 --env:https_proxy=http://192.168.1.128:3128
100+
> ```
101+
91102
For allocator node, your don't need to specify the path to qrmi_config.json like below.
92103
93104
```bash

plugins/spank_qrmi/spank_qrmi.c

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "qrmi.h"
2727
#include "spank_qrmi.h"
2828

29+
extern char **environ;
30+
2931
/*
3032
* Spank plugin for QRMI.
3133
*/
@@ -54,6 +56,32 @@ static void acquired_resource_destroy(void *object);
5456
static qpu_resource_t *_acquire_qpu(spank_t spank_ctxt, char *name, QrmiResourceType type);
5557
static void _release_qpu(qpu_resource_t *res);
5658

59+
/*
60+
* @function _dump_environ
61+
*
62+
* Dumps all environment variables set for the current process.
63+
*/
64+
static void _dump_environ() {
65+
char **s = environ;
66+
int pid = (int)getpid();
67+
int uid = (int)getuid();
68+
69+
slurm_debug("%s(%d, %d): environment variables ---", plugin_name, pid, uid);
70+
for (; *s; s++) {
71+
slurm_debug("%s(%d, %d): %s", plugin_name, pid, uid, *s);
72+
}
73+
}
74+
75+
/*
76+
* @function _starts_with
77+
*
78+
* Tests if this string(`str`) starts with the specified `prefix`.
79+
*/
80+
static bool _starts_with(const char *str, const char *prefix)
81+
{
82+
return strncmp(prefix, str, strlen(prefix)) == 0;
83+
}
84+
5785
/*
5886
* @function _qpu_names_opt_cb
5987
*
@@ -183,11 +211,37 @@ int slurm_spank_init_post_opt(spank_t spank_ctxt, int argc, char **argv) {
183211

184212
QrmiConfig *cnf = qrmi_config_load(argv[0]);
185213
if (cnf == NULL) {
186-
slurm_error("%s, No QRMI config file (%s)", plugin_name, argv[0]);
214+
const char* last_error = qrmi_get_last_error();
215+
slurm_error("%s, Failed to load QRMI config file(%s). %s",
216+
plugin_name, argv[0], last_error);
217+
spank_setenv(spank_ctxt, "QRMI_PLUGIN_ERROR", last_error, KEEP_IF_EXISTS);
218+
qrmi_string_free((char*)last_error);
187219
return SLURM_ERROR;
188220
}
189221
slurm_debug("%s, config: %p", plugin_name, (void *)cnf);
190222

223+
/*
224+
* Parses optional plugin arguments.
225+
*
226+
* Currently, only environment variable settings prefixed with
227+
* --env:{variable name}={value} are supported.
228+
*/
229+
for (int i = 1; i < argc; i++) {
230+
if (_starts_with(argv[i], "--env:")) {
231+
const char *input = &argv[i][strlen("--env:")];
232+
const char *delimiter = strchr(input, '=');
233+
if (delimiter != NULL) {
234+
size_t key_len = (size_t)(delimiter - input);
235+
char env_name[key_len + 1];
236+
strncpy(env_name, input, key_len);
237+
env_name[key_len] = '\0';
238+
const char *env_value = delimiter + 1;;
239+
setenv(env_name, env_value, OVERWRITE);
240+
spank_setenv(spank_ctxt, env_name, env_value, OVERWRITE);
241+
}
242+
}
243+
}
244+
191245
size_t buflen = strlen(g_qpu_names_opt) + 1;
192246
char *bufp = (char *)malloc(buflen);
193247
char *rest = bufp;
@@ -258,6 +312,8 @@ int slurm_spank_init_post_opt(spank_t spank_ctxt, int argc, char **argv) {
258312
KEEP_IF_EXISTS);
259313
}
260314

315+
_dump_environ();
316+
261317
/*
262318
* Acquire QPU resource.
263319
*/
@@ -564,6 +620,7 @@ static qpu_resource_t *_acquire_qpu(spank_t spank_ctxt, char *name, QrmiResource
564620
if ((rc != QRMI_RETURN_CODE_SUCCESS) || (is_accessible == false)) {
565621
last_error = qrmi_get_last_error();
566622
slurm_error("%s, %s is not accessible. %s", plugin_name, name, last_error);
623+
spank_setenv(spank_ctxt, "QRMI_PLUGIN_ERROR", last_error, KEEP_IF_EXISTS);
567624
qrmi_string_free((char*)last_error);
568625
qrmi_resource_free(qrmi);
569626
return NULL;

0 commit comments

Comments
 (0)