aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/GitVersion.cmake2
-rw-r--r--src/cli/stasis_indexer/helpers.c1
-rw-r--r--src/cli/stasis_indexer/stasis_indexer_main.c8
-rw-r--r--src/lib/core/conda.c51
-rw-r--r--src/lib/core/include/conda.h4
-rw-r--r--src/lib/core/ini.c62
-rw-r--r--src/lib/delivery/delivery.c4
-rw-r--r--src/lib/delivery/delivery_export.c18
-rw-r--r--src/lib/delivery/delivery_init.c11
-rw-r--r--tests/test_conda.c14
10 files changed, 126 insertions, 49 deletions
diff --git a/cmake/GitVersion.cmake b/cmake/GitVersion.cmake
index c9c6159..005667d 100644
--- a/cmake/GitVersion.cmake
+++ b/cmake/GitVersion.cmake
@@ -15,7 +15,7 @@ function(get_version_from_git)
endif()
execute_process(
- COMMAND ${GIT_EXECUTABLE} describe --first-parent --long --dirty --tags --always
+ COMMAND ${GIT_EXECUTABLE} describe --long --dirty --tags --always
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
diff --git a/src/cli/stasis_indexer/helpers.c b/src/cli/stasis_indexer/helpers.c
index 86a20e4..425d209 100644
--- a/src/cli/stasis_indexer/helpers.c
+++ b/src/cli/stasis_indexer/helpers.c
@@ -156,6 +156,7 @@ int micromamba_configure(const struct Delivery *ctx, struct MicromambaInfo *m) {
}
m->conda_prefix = globals.conda_install_prefix;
m->micromamba_prefix = micromamba_prefix;
+ m->download_dir = ctx->storage.tmpdir;
const size_t pathvar_len = strlen(getenv("PATH")) + strlen(m->micromamba_prefix) + strlen(m->conda_prefix) + 3 + 4 + 1;
// ^^^^^^^^^^^^^^^^^^
diff --git a/src/cli/stasis_indexer/stasis_indexer_main.c b/src/cli/stasis_indexer/stasis_indexer_main.c
index d71c341..ed938b7 100644
--- a/src/cli/stasis_indexer/stasis_indexer_main.c
+++ b/src/cli/stasis_indexer/stasis_indexer_main.c
@@ -212,6 +212,10 @@ int main(const int argc, char *argv[]) {
if (optind < argc) {
rootdirs_total = argc - current_index;
rootdirs = calloc(rootdirs_total + 1, sizeof(*rootdirs));
+ if (!rootdirs) {
+ SYSERROR("%s", "unable to allocate memory for rootdirs array");
+ exit(1);
+ }
int i = 0;
while (optind < argc) {
@@ -223,6 +227,10 @@ int main(const int argc, char *argv[]) {
}
// use first positional argument
rootdirs[i] = realpath(argv[optind], NULL);
+ if (!rootdirs[i]) {
+ SYSERROR("%s", "Unable to allocate memory for root directory");
+ exit(1);
+ }
optind++;
break;
}
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c
index 731cf80..4557c5c 100644
--- a/src/lib/core/conda.c
+++ b/src/lib/core/conda.c
@@ -19,11 +19,22 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
sys.machine[sizeof(sys.machine) - 1] = '\0';
}
+ if (!info->download_dir || isempty(info->download_dir)) {
+ SYSERROR("%s", "micromamba inf->download_dir is NULL, or empty");
+ return -1;
+ }
+
+ if (mkdirs(info->download_dir, 0755) < 0) {
+ SYSERROR("Unable to create info->download_dir: %s", info->download_dir);
+ return -1;
+ }
+
char url[PATH_MAX] = {0};
snprintf(url, sizeof(url), "https://micro.mamba.pm/api/micromamba/%s-%s/latest", sys.sysname, sys.machine);
- char installer_path[PATH_MAX];
- snprintf(installer_path, sizeof(installer_path), "%s/latest", getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
+ const char installer_name[] = "mm_latest";
+ char installer_path[PATH_MAX] = {0};
+ snprintf(installer_path, sizeof(installer_path), "%s/%s", info->download_dir, installer_name);
if (access(installer_path, F_OK)) {
char *errmsg = NULL;
@@ -41,7 +52,9 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
if (access(mmbin, F_OK)) {
char untarcmd[PATH_MAX * 2];
mkdirs(info->micromamba_prefix, 0755);
- snprintf(untarcmd, sizeof(untarcmd), "tar -xvf %s -C %s --strip-components=1 bin/micromamba 1>/dev/null", installer_path, info->micromamba_prefix);
+ snprintf(untarcmd, sizeof(untarcmd),
+ "tar -xvf %s -C %s --strip-components=1 bin/micromamba 1>/dev/null",
+ installer_path, info->micromamba_prefix);
int untarcmd_status = system(untarcmd);
if (untarcmd_status) {
return -1;
@@ -137,7 +150,7 @@ const char *pkg_index_provides_strerror(int code) {
return PKG_ERROR_STR[code];
}
-int pkg_index_provides(int mode, const char *index, const char *spec) {
+int pkg_index_provides(int mode, const char *index, const char *spec, const char *logdir) {
char cmd[PATH_MAX] = {0};
char spec_local[255] = {0};
@@ -153,7 +166,14 @@ int pkg_index_provides(int mode, const char *index, const char *spec) {
lstrip(spec_local);
strip(spec_local);
- char logfile[] = "/tmp/stasis/STASIS-package_exists.XXXXXX";
+ if (mkdirs(logdir, 0700) < 0) {
+ SYSERROR("Unable to create log directory: %s", logdir ? logdir : "NULL");
+ return -1;
+ }
+ const char logfile_template[] = "STASIS-package_exists.XXXXXX";
+ char logfile[PATH_MAX] = {0};
+ snprintf(logfile, sizeof(logfile), "%s/%s", logdir, logfile_template);
+
int logfd = mkstemp(logfile);
if (logfd < 0) {
perror(logfile);
@@ -187,11 +207,24 @@ int pkg_index_provides(int mode, const char *index, const char *spec) {
return PKG_INDEX_PROVIDES_E_INTERNAL_MODE_UNKNOWN;
}
+#if defined(DEBUG)
+ const int debug_log = 1;
+#else
+ const debug_log = 0;
+#endif
+
// Print errors only when shell() itself throws one
// If some day we want to see the errors thrown by pip too, use this
// condition instead: (status != 0)
+ if (debug_log) {
+ SYSDEBUG("Executing: %s", cmd);
+ }
status = shell(&proc, cmd);
- if (status < 0) {
+
+ if (debug_log) {
+ SYSDEBUG("Log file: %s", logfile);
+ }
+ if (status < 0 || debug_log) {
FILE *fp = fdopen(logfd, "r");
if (!fp) {
remove(logfile);
@@ -201,7 +234,11 @@ int pkg_index_provides(int mode, const char *index, const char *spec) {
fflush(stdout);
fflush(stderr);
while (fgets(line, sizeof(line) - 1, fp) != NULL) {
- fprintf(stderr, "%s", line);
+ if (debug_log) {
+ SYSDEBUG("%s", strip(line));
+ } else {
+ fprintf(stderr, "%s", line);
+ }
}
fflush(stderr);
fclose(fp);
diff --git a/src/lib/core/include/conda.h b/src/lib/core/include/conda.h
index f3d481c..cc9426d 100644
--- a/src/lib/core/include/conda.h
+++ b/src/lib/core/include/conda.h
@@ -29,6 +29,7 @@
struct MicromambaInfo {
char *micromamba_prefix; //!< Path to write micromamba binary
char *conda_prefix; //!< Path to install conda base tree
+ char *download_dir; //!< Path to store micromamba installer
};
/**
@@ -219,12 +220,13 @@ int conda_index(const char *path);
* @param mode USE_CONDA
* @param index a file system path or url pointing to a simple index or conda channel
* @param spec a pip package specification (e.g. `name==1.2.3`)
+ * @param logdir the directory to store the output log
* @param spec a conda package specification (e.g. `name=1.2.3`)
* @return PKG_NOT_FOUND, if not found
* @return PKG_FOUND, if found
* @return PKG_E_INDEX_PROVIDES_{ERROR}, on error (see conda.h)
*/
-int pkg_index_provides(int mode, const char *index, const char *spec);
+int pkg_index_provides(int mode, const char *index, const char *spec, const char *logdir);
const char *pkg_index_provides_strerror(int code);
char *conda_get_active_environment();
diff --git a/src/lib/core/ini.c b/src/lib/core/ini.c
index 12541f5..c37030c 100644
--- a/src/lib/core/ini.c
+++ b/src/lib/core/ini.c
@@ -347,6 +347,10 @@ int ini_data_append(struct INIFILE **ini, char *section_name, char *key, char *v
section->data_count++;
} else {
struct INIData *data = ini_data_get(*ini, section_name, key);
+ if (!data) {
+ SYSERROR("%s:%s: key does not exist", section_name, key);
+ return -1;
+ }
size_t value_len_old = strlen(data->value);
size_t value_len = strlen(value);
size_t value_len_new = value_len_old + value_len;
@@ -355,9 +359,9 @@ int ini_data_append(struct INIFILE **ini, char *section_name, char *key, char *v
if (!value_tmp) {
SYSERROR("Unable to increase data->value size to %zu bytes", value_len_new + 2);
return -1;
- } else {
- data->value = value_tmp;
}
+ data->value = value_tmp;
+
strncat(data->value, value, value_len_new - strlen(data->value));
}
return 0;
@@ -422,6 +426,7 @@ int ini_write(struct INIFILE *ini, FILE **stream, unsigned mode) {
for (size_t x = 0; x < ini->section_count; x++) {
struct INISection *section = ini->section[x];
char *section_name = section->key;
+
fprintf(*stream, "[%s]" LINE_SEP, section_name);
for (size_t y = 0; y < ini->section[x]->data_count; y++) {
@@ -430,6 +435,7 @@ int ini_write(struct INIFILE *ini, FILE **stream, unsigned mode) {
char *key = data->key;
char *value = data->value;
unsigned *hint = &data->type_hint;
+
memset(outvalue, 0, sizeof(outvalue));
if (key && value) {
@@ -442,6 +448,9 @@ int ini_write(struct INIFILE *ini, FILE **stream, unsigned mode) {
xvalue = ini_getval_str(ini, section_name, key, (int) mode, &err);
value = xvalue;
}
+
+ const size_t buf_size = sizeof(outvalue);
+ size_t buf_len = 0;
char **parts = split(value, LINE_SEP, 0);
for (size_t p = 0; parts && parts[p] != NULL; p++) {
char *render = NULL;
@@ -456,19 +465,16 @@ int ini_write(struct INIFILE *ini, FILE **stream, unsigned mode) {
return -1;
}
- size_t len = 0;
+ buf_len = strlen(outvalue);
if (*hint == INIVAL_TYPE_STR_ARRAY) {
- int leading_space = isspace(*render);
+ const int leading_space = isspace(*render);
if (leading_space) {
- len = sizeof(outvalue) - (size_t) snprintf(NULL, 0, "%s" LINE_SEP, render);
- snprintf(outvalue + strlen(outvalue), len, "%s" LINE_SEP, render);
+ snprintf(outvalue + buf_len, buf_size - buf_len, "%s" LINE_SEP, render);
} else {
- len = sizeof(outvalue) - (size_t) snprintf(NULL, 0, " %s" LINE_SEP, render);
- snprintf(outvalue + strlen(outvalue), len, " %s" LINE_SEP, render);
+ snprintf(outvalue + buf_len, buf_size - buf_len, " %s" LINE_SEP, render);
}
} else {
- len = sizeof(outvalue) - (size_t) snprintf(NULL, 0, "%s", render);
- snprintf(outvalue + strlen(outvalue), len, "%s", render);
+ snprintf(outvalue + buf_len, buf_size - buf_len, "%s", render);
}
if (mode == INI_WRITE_PRESERVE) {
guard_free(render);
@@ -476,7 +482,12 @@ int ini_write(struct INIFILE *ini, FILE **stream, unsigned mode) {
}
guard_array_free(parts);
strip(outvalue);
- strncat(outvalue, LINE_SEP, sizeof(outvalue) - strlen(outvalue) - 1);
+
+ // update length of outvalue
+ buf_len = strlen(outvalue);
+
+ snprintf(outvalue + buf_len, buf_size - buf_len, "%s", LINE_SEP);
+
fprintf(*stream, "%s = %s%s", ini->section[x]->data[y]->key, *hint == INIVAL_TYPE_STR_ARRAY ? LINE_SEP : "", outvalue);
guard_free(value);
} else {
@@ -499,12 +510,9 @@ char *unquote(char *s) {
void ini_free(struct INIFILE **ini) {
for (size_t section = 0; section < (*ini)->section_count; section++) {
- SYSDEBUG("freeing section: %s", (*ini)->section[section]->key);
for (size_t data = 0; data < (*ini)->section[section]->data_count; data++) {
if ((*ini)->section[section]->data[data]) {
- SYSDEBUG("freeing data key: %s", (*ini)->section[section]->data[data]->key);
guard_free((*ini)->section[section]->data[data]->key);
- SYSDEBUG("freeing data value: %s", (*ini)->section[section]->data[data]->value);
guard_free((*ini)->section[section]->data[data]->value);
guard_free((*ini)->section[section]->data[data]);
}
@@ -545,15 +553,15 @@ struct INIFILE *ini_open(const char *filename) {
unsigned hint = 0;
int multiline_data = 0;
int no_data = 0;
- char inikey[2][255];
+ char inikey[2][255] = {0};
char *key = inikey[0];
char *key_last = inikey[1];
char value[STASIS_BUFSIZ] = {0};
- memset(inikey, 0, sizeof(inikey));
-
// Read file
for (size_t i = 0; fgets(line, sizeof(line), fp) != NULL; i++) {
+ const size_t key_last_size = sizeof(inikey[1]);
+ const size_t key_size = sizeof(inikey[0]);
if (no_data && multiline_data) {
if (!isempty(line)) {
no_data = 0;
@@ -562,7 +570,7 @@ struct INIFILE *ini_open(const char *filename) {
}
memset(value, 0, sizeof(value));
} else {
- memset(key, 0, sizeof(inikey[0]));
+ memset(key, 0, key_size);
}
// Find pointer to first comment character
char *comment = strpbrk(line, ";#");
@@ -586,7 +594,7 @@ struct INIFILE *ini_open(const char *filename) {
// Test for section header: [string]
if (startswith(line, "[")) {
// The previous key is irrelevant now
- memset(key_last, 0, sizeof(inikey[1]));
+ memset(key_last, 0, key_last_size);
char *section_name = substring_between(line, "[]");
if (!section_name) {
@@ -628,15 +636,16 @@ struct INIFILE *ini_open(const char *filename) {
if (operator) {
size_t key_len = operator - line;
- memset(key, 0, sizeof(inikey[0]));
+ memset(key, 0, key_size);
+
strncpy(key, line, key_len);
- key[key_len] = '\0';
+ key[key_size - 1] = '\0';
lstrip(key);
strip(key);
- memset(key_last, 0, sizeof(inikey[1]));
- strncpy(key_last, key, sizeof(inikey[1]) - 1);
- key_last[sizeof(inikey[1]) - 1] = '\0';
+ memset(key_last, 0, key_last_size);
+ strncpy(key_last, key, key_last_size - 1);
+ key_last[key_last_size - 1] = '\0';
reading_value = 1;
if (strlen(operator) > 1) {
@@ -645,6 +654,7 @@ struct INIFILE *ini_open(const char *filename) {
strncpy(value, "", sizeof(value) - 1);
}
value[sizeof(value) - 1] = '\0';
+
if (isempty(value)) {
//printf("%s is probably long raw data\n", key);
hint = INIVAL_TYPE_STR_ARRAY;
@@ -657,8 +667,8 @@ struct INIFILE *ini_open(const char *filename) {
}
strip(value);
} else {
- strncpy(key, key_last, sizeof(inikey[0]) - 1);
- key[sizeof(inikey[0]) - 1] = '\0';
+ strncpy(key, key_last, key_size - 1);
+ key[key_size - 1] = '\0';
strncpy(value, line, sizeof(value) - 1);
value[sizeof(value) - 1] = '\0';
}
diff --git a/src/lib/delivery/delivery.c b/src/lib/delivery/delivery.c
index d4fe08c..45b3b35 100644
--- a/src/lib/delivery/delivery.c
+++ b/src/lib/delivery/delivery.c
@@ -453,9 +453,9 @@ void delivery_defer_packages(struct Delivery *ctx, int type) {
int upstream_exists = 0;
if (DEFER_PIP == type) {
- upstream_exists = pkg_index_provides(PKG_USE_PIP, PYPI_INDEX_DEFAULT, name);
+ upstream_exists = pkg_index_provides(PKG_USE_PIP, PYPI_INDEX_DEFAULT, name, ctx->storage.tmpdir);
} else if (DEFER_CONDA == type) {
- upstream_exists = pkg_index_provides(PKG_USE_CONDA, NULL, name);
+ upstream_exists = pkg_index_provides(PKG_USE_CONDA, NULL, name, ctx->storage.tmpdir);
}
if (PKG_INDEX_PROVIDES_FAILED(upstream_exists)) {
diff --git a/src/lib/delivery/delivery_export.c b/src/lib/delivery/delivery_export.c
index c12a365..e67fdfb 100644
--- a/src/lib/delivery/delivery_export.c
+++ b/src/lib/delivery/delivery_export.c
@@ -2,26 +2,44 @@
static void delivery_export_configuration(const struct Delivery *ctx) {
msg(STASIS_MSG_L2, "Exporting delivery configuration\n");
+
+ SYSDEBUG("Entering configuration directory: %s", ctx->storage.delivery_dir);
if (!pushd(ctx->storage.cfgdump_dir)) {
char filename[PATH_MAX] = {0};
+ SYSDEBUG("%s", "Populating filename");
snprintf(filename, sizeof(filename), "%s.ini", ctx->info.release_name);
+ SYSDEBUG("filename: %s", filename);
+
+ SYSDEBUG("%s: opening", filename);
FILE *spec = fopen(filename, "w+");
if (!spec) {
msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", filename);
exit(1);
}
+ SYSDEBUG("%s: writing", filename);
ini_write(ctx->_stasis_ini_fp.delivery, &spec, INI_WRITE_RAW);
+ SYSDEBUG("%s: writing done", filename);
fclose(spec);
+ SYSDEBUG("%s: closing", filename);
+ SYSDEBUG("%s", "Zeroing filename");
memset(filename, 0, sizeof(filename));
+ SYSDEBUG("%s", "Populating rendered filename");
snprintf(filename, sizeof(filename), "%s-rendered.ini", ctx->info.release_name);
+ SYSDEBUG("filename: %s", filename);
+
+ SYSDEBUG("%s: opening", filename);
spec = fopen(filename, "w+");
if (!spec) {
msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", filename);
exit(1);
}
+ SYSDEBUG("%s: writing", filename);
ini_write(ctx->_stasis_ini_fp.delivery, &spec, INI_WRITE_PRESERVE);
+ SYSDEBUG("%s: writing done", filename);
+ SYSDEBUG("%s: closing", filename);
fclose(spec);
+ SYSDEBUG("Returning from %s", ctx->storage.cfgdump_dir);
popd();
} else {
SYSERROR("Failed to enter directory: %s", ctx->storage.delivery_dir);
diff --git a/src/lib/delivery/delivery_init.c b/src/lib/delivery/delivery_init.c
index 17f3899..ec05a0f 100644
--- a/src/lib/delivery/delivery_init.c
+++ b/src/lib/delivery/delivery_init.c
@@ -14,7 +14,7 @@ int delivery_init_tmpdir(struct Delivery *ctx) {
int unusable = 1;
errno = 0;
- int need_setenv = 0;
+ //int need_setenv = 0;
const char *x = getenv("TMPDIR");
if (x) {
guard_free(ctx->storage.tmpdir);
@@ -30,7 +30,7 @@ int delivery_init_tmpdir(struct Delivery *ctx) {
SYSERROR("%s", "unable to allocate tmpdir");
goto l_delivery_init_tmpdir_fatal;
}
- need_setenv = 1;
+ //need_setenv = 1;
}
if (!ctx->storage.tmpdir) {
@@ -95,9 +95,10 @@ int delivery_init_tmpdir(struct Delivery *ctx) {
}
}
unusable = 0;
- if (need_setenv) {
- setenv("TMPDIR", ctx->storage.tmpdir, 1);
- }
+ // TODO: Figure out why this breaks EVERYTHING
+ //if (need_setenv) {
+ // setenv("TMPDIR", ctx->storage.tmpdir, 1);
+ //}
l_delivery_init_tmpdir_fatal:
guard_free(tmpdir);
diff --git a/tests/test_conda.c b/tests/test_conda.c
index 9f0e718..e32c9f2 100644
--- a/tests/test_conda.c
+++ b/tests/test_conda.c
@@ -18,10 +18,10 @@ void test_micromamba() {
int result;
};
struct testcase tc[] = {
- {.mminfo = {.micromamba_prefix = mm_prefix, .conda_prefix = c_prefix}, .cmd = "info", .result = 0},
- {.mminfo = {.micromamba_prefix = mm_prefix, .conda_prefix = c_prefix}, .cmd = "env list", .result = 0},
- {.mminfo = {.micromamba_prefix = mm_prefix, .conda_prefix = c_prefix}, .cmd = "run python3 -V", .result = 0},
- {.mminfo = {.micromamba_prefix = mm_prefix, .conda_prefix = c_prefix}, .cmd = "no_such_option", .result = 109},
+ {.mminfo = {.download_dir = cwd_workspace, .micromamba_prefix = mm_prefix, .conda_prefix = c_prefix}, .cmd = "info", .result = 0},
+ {.mminfo = {.download_dir = cwd_workspace, .micromamba_prefix = mm_prefix, .conda_prefix = c_prefix}, .cmd = "env list", .result = 0},
+ {.mminfo = {.download_dir = cwd_workspace, .micromamba_prefix = mm_prefix, .conda_prefix = c_prefix}, .cmd = "run python3 -V", .result = 0},
+ {.mminfo = {.download_dir = cwd_workspace, .micromamba_prefix = mm_prefix, .conda_prefix = c_prefix}, .cmd = "no_such_option", .result = 109},
};
for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) {
@@ -31,7 +31,7 @@ void test_micromamba() {
result = result >> 8;
}
STASIS_ASSERT(result == item->result, "unexpected exit value");
- SYSERROR("micromamba command: '%s' (returned: %d)", item->cmd, result);
+ SYSDEBUG("micromamba command: '%s' (returned: %d)", item->cmd, result);
}
}
@@ -143,7 +143,7 @@ void test_pip_index_provides() {
};
for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) {
struct testcase *test = &tc[i];
- int result = pkg_index_provides(PKG_USE_PIP, test->pindex, test->name);
+ int result = pkg_index_provides(PKG_USE_PIP, test->pindex, test->name, ".");
STASIS_ASSERT(result == test->expected, "Unexpected result");
if (PKG_INDEX_PROVIDES_FAILED(result)) {
fprintf(stderr, "error: %s\n", pkg_index_provides_strerror(result));
@@ -175,7 +175,7 @@ void test_conda_provides() {
for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) {
struct testcase *test = &tc[i];
- int result = pkg_index_provides(PKG_USE_CONDA, NULL, test->name);
+ int result = pkg_index_provides(PKG_USE_CONDA, NULL, test->name, ".");
printf("%s returned %d, expecting %d\n", test->name, result, test->expected);
STASIS_ASSERT(result == test->expected, "Unexpected result");
}