From 27bd4bf8abd7e9a29ca89f67503fd9291757a97b Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 2 Apr 2025 14:49:33 -0400 Subject: base and "based_on" installations shall hardcode the requested python version in the YAML config instead of trusting it --- src/cli/stasis/stasis_main.c | 7 ++----- src/lib/core/conda.c | 29 ++++++++++++++++++++++++++--- src/lib/core/include/conda.h | 2 +- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/cli/stasis/stasis_main.c b/src/cli/stasis/stasis_main.c index 36dfecc..7f0b88a 100644 --- a/src/cli/stasis/stasis_main.c +++ b/src/cli/stasis/stasis_main.c @@ -325,9 +325,6 @@ int main(int argc, char *argv[]) { exit(1); } copy2(mission_base_orig, mission_base, CT_OWNER | CT_PERM); - char spec[255] = {0}; - snprintf(spec, sizeof(spec) - 1, "- python=%s\n", ctx.meta.python); - file_replace_text(mission_base, "- python\n", spec, 0); ctx.meta.based_on = mission_base; } guard_free(mission_base_orig); @@ -340,7 +337,7 @@ int main(int argc, char *argv[]) { } msg(STASIS_MSG_L2, "Based on: %s\n", ctx.meta.based_on); - if (conda_env_create_from_uri(env_name, ctx.meta.based_on)) { + if (conda_env_create_from_uri(env_name, ctx.meta.based_on, ctx.meta.python)) { msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "unable to install release environment using configuration file\n"); exit(1); } @@ -349,7 +346,7 @@ int main(int argc, char *argv[]) { msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed to remove testing environment %s\n", env_name_testing); exit(1); } - if (conda_env_create_from_uri(env_name_testing, ctx.meta.based_on)) { + if (conda_env_create_from_uri(env_name_testing, ctx.meta.based_on, ctx.meta.python)) { msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "unable to install testing environment using configuration file\n"); exit(1); } diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c index 9b5c77c..c81e6cc 100644 --- a/src/lib/core/conda.c +++ b/src/lib/core/conda.c @@ -498,10 +498,11 @@ int conda_setup_headless() { return 0; } -int conda_env_create_from_uri(char *name, char *uri) { +int conda_env_create_from_uri(char *name, char *uri, char *python_version) { char env_command[PATH_MAX]; char *uri_fs = NULL; + // Convert a bare system path to a file:// path if (!strstr(uri, "://")) { uri_fs = calloc(strlen(uri) + strlen("file://") + 1, sizeof(*uri_fs)); @@ -510,9 +511,31 @@ int conda_env_create_from_uri(char *name, char *uri) { } snprintf(uri_fs, strlen(uri) + strlen("file://") + 1, "%s%s", "file://", uri); } - sprintf(env_command, "env create -n '%s' --file='%s'", name, uri_fs ? uri_fs : uri); + + char tempfile[PATH_MAX] = {0}; + sprintf(tempfile, "%s/remote_XXXXXX", globals.tmpdir); + + // Touch a temporary file + int fd = mkstemp(tempfile); + close(fd); + unlink(tempfile); + + // We'll create a new file with the same random bits, ending with .yml + strcat(tempfile, ".yml"); + char *errmsg = NULL; + download(uri_fs ? uri_fs : uri, tempfile, &errmsg); guard_free(uri_fs); - return conda_exec(env_command); + + // Rewrite python version + char spec[255] = {0}; + snprintf(spec, sizeof(spec) - 1, "- python=%s\n", python_version); + file_replace_text(tempfile, "- python\n", spec, 0); + + sprintf(env_command, "env create -n '%s' --file='%s'", name, tempfile); + int status = conda_exec(env_command); + unlink(tempfile); + + return status; } int conda_env_create(char *name, char *python_version, char *packages) { diff --git a/src/lib/core/include/conda.h b/src/lib/core/include/conda.h index 8b4a0bd..ea8613f 100644 --- a/src/lib/core/include/conda.h +++ b/src/lib/core/include/conda.h @@ -127,7 +127,7 @@ int conda_setup_headless(); * @param uri ftp://myserver.tld/environment.yml * @return exit code from "conda" */ -int conda_env_create_from_uri(char *name, char *uri); +int conda_env_create_from_uri(char *name, char *uri, char *python_version); /** * Create a Conda environment using generic package specs -- cgit From 90755c85131cceb9f6d628703042129dc10dfca9 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 2 Apr 2025 15:22:47 -0400 Subject: base and "based_on" installations shall hardcode the requested python version in the YAML config instead of trusting it --- tests/test_conda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_conda.c b/tests/test_conda.c index 81f593f..4d437e4 100644 --- a/tests/test_conda.c +++ b/tests/test_conda.c @@ -111,7 +111,7 @@ void test_conda_setup_headless() { void test_conda_env_create_from_uri() { const char *url = "https://ssb.stsci.edu/jhunk/stasis_test/test_conda_env_create_from_uri.yml"; char *name = strdup(__FUNCTION__); - STASIS_ASSERT(conda_env_create_from_uri(name, (char *) url) == 0, "creating an environment from a remote source failed"); + STASIS_ASSERT(conda_env_create_from_uri(name, (char *) url, "3.11") == 0, "creating an environment from a remote source failed"); free(name); } -- cgit