diff options
| author | Joseph Hunkeler <jhunkeler@gmail.com> | 2024-11-02 01:25:24 -0400 | 
|---|---|---|
| committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2024-11-02 01:25:24 -0400 | 
| commit | d66927f5fe32c1fc554bed691ad66dbbf07d37da (patch) | |
| tree | ee8e31115d60fc1c666bba00803f990046157bca /src | |
| parent | 35d0480f743abaa5c2c332f513043edd7c59081c (diff) | |
| download | stasis-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
Diffstat (limited to 'src')
| -rw-r--r-- | src/cli/stasis/stasis_main.c | 3 | ||||
| -rw-r--r-- | src/cli/stasis/system_requirements.c | 7 | ||||
| -rw-r--r-- | src/cli/stasis/system_requirements.h | 2 | ||||
| -rw-r--r-- | src/lib/core/conda.c | 35 | 
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 | 
