aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2024-11-02 01:25:24 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2024-11-02 01:25:24 -0400
commitd66927f5fe32c1fc554bed691ad66dbbf07d37da (patch)
treeee8e31115d60fc1c666bba00803f990046157bca
parent35d0480f743abaa5c2c332f513043edd7c59081c (diff)
downloadstasis-d66927f5fe32c1fc554bed691ad66dbbf07d37da.tar.gz
Bug fixes:
* Remove PATH modification from check_pathvar * Rename check_pathvar to check_system_path * Add conda_prepend_bin function to handle PATH modification during activation * Add logic to handle first-run activation, and subsequent calls to change conda environments (otherwise conda clobbers its own shell functions) * Use $CONDA_PYTHON_EXE and $CONDA_EXE to ensure conda comes from the just-installed tree
-rw-r--r--src/cli/stasis/stasis_main.c3
-rw-r--r--src/cli/stasis/system_requirements.c7
-rw-r--r--src/cli/stasis/system_requirements.h2
-rw-r--r--src/lib/core/conda.c35
4 files changed, 38 insertions, 9 deletions
diff --git a/src/cli/stasis/stasis_main.c b/src/cli/stasis/stasis_main.c
index cda5fa6..e188b2e 100644
--- a/src/cli/stasis/stasis_main.c
+++ b/src/cli/stasis/stasis_main.c
@@ -133,6 +133,8 @@ int main(int argc, char *argv[]) {
printf(BANNER, VERSION, AUTHOR);
+ check_system_path();
+
msg(STASIS_MSG_L1, "Setup\n");
tpl_setup_vars(&ctx);
@@ -241,7 +243,6 @@ int main(int argc, char *argv[]) {
msg(STASIS_MSG_L2, "Installing: %s\n", ctx.conda.installer_name);
delivery_install_conda(ctx.conda.installer_path, ctx.storage.conda_install_prefix);
- check_pathvar(&ctx);
msg(STASIS_MSG_L2, "Configuring: %s\n", ctx.storage.conda_install_prefix);
delivery_conda_enable(&ctx, ctx.storage.conda_install_prefix);
diff --git a/src/cli/stasis/system_requirements.c b/src/cli/stasis/system_requirements.c
index 53ebbf7..d8d7df3 100644
--- a/src/cli/stasis/system_requirements.c
+++ b/src/cli/stasis/system_requirements.c
@@ -67,16 +67,11 @@ void check_requirements(struct Delivery *ctx) {
check_system_env_requirements();
}
-void check_pathvar(struct Delivery *ctx) {
+void check_system_path() {
char *pathvar = NULL;
pathvar = getenv("PATH");
if (!pathvar) {
msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "PATH variable is not set. Cannot continue.\n");
exit(1);
- } else {
- char pathvar_tmp[STASIS_BUFSIZ];
- sprintf(pathvar_tmp, "%s/bin:%s", ctx->storage.conda_install_prefix, pathvar);
- setenv("PATH", pathvar_tmp, 1);
- pathvar = NULL;
}
} \ No newline at end of file
diff --git a/src/cli/stasis/system_requirements.h b/src/cli/stasis/system_requirements.h
index 3a6fa25..ddc2705 100644
--- a/src/cli/stasis/system_requirements.h
+++ b/src/cli/stasis/system_requirements.h
@@ -5,9 +5,9 @@
#include "callbacks.h"
#include "envctl.h"
+void check_system_path();
void check_system_env_requirements();
void check_system_requirements(struct Delivery *ctx);
void check_requirements(struct Delivery *ctx);
-void check_pathvar(struct Delivery *ctx);
#endif //STASIS_SYSTEM_REQUIREMENTS_H
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c
index fa3052a..435af35 100644
--- a/src/lib/core/conda.c
+++ b/src/lib/core/conda.c
@@ -207,6 +207,24 @@ int conda_exec(const char *args) {
return system(command);
}
+static int conda_prepend_bin(const char *root) {
+ const char *system_path_old = getenv("PATH");
+ char conda_bin[PATH_MAX] = {0};
+
+ snprintf(conda_bin, sizeof(conda_bin) - 1, "%s/bin:%s/condabin", root, root);
+
+ if (!strstr(system_path_old, conda_bin)) {
+ // conda_bin is not present in PATH. Add it to the head.
+ char system_path_new[STASIS_BUFSIZ];
+ sprintf(system_path_new, "%s:%s", conda_bin, system_path_old);
+ if (setenv("PATH", system_path_new, 1) < 0) {
+ SYSERROR("Unable to prepend to PATH: %s", conda_bin);
+ return -1;
+ }
+ }
+ return 0;
+}
+
int conda_activate(const char *root, const char *env_name) {
FILE *fp = NULL;
const char *init_script_conda = "/etc/profile.d/conda.sh";
@@ -248,9 +266,24 @@ int conda_activate(const char *root, const char *env_name) {
return -1;
}
+ if (conda_prepend_bin(root)) {
+ remove(logfile);
+ return -1;
+ }
+
// Fully activate conda and record its effect on the runtime environment
char command[PATH_MAX * 3];
- snprintf(command, sizeof(command) - 1, "set -a; source %s; source %s; conda activate %s &>/dev/null; env -0", path_conda, path_mamba, env_name);
+ const char *conda_shlvl = getenv("CONDA_SHLVL");
+ if (conda_shlvl == NULL || strcmp(conda_shlvl, "0") == 0) {
+ // First-run initialization
+ snprintf(command, sizeof(command) - 1, "source %s; source %s; conda activate %s &>/dev/null; env -0", path_conda, path_mamba, env_name);
+ } else {
+ // Conda is already available and configured.
+ // Make calls directly to conda using conda's base interpreter.
+ // The shell functions generated by sourcing path_conda and path_mamba are extremely inconsistent
+ // in this environment. DO NOT USE THEM.
+ snprintf(command, sizeof(command) - 1, "$CONDA_PYTHON_EXE $CONDA_EXE activate %s &>/dev/null; env -0", env_name);
+ }
int retval = shell(&proc, command);
if (retval) {
// it didn't work; drop out for cleanup