aboutsummaryrefslogtreecommitdiff
path: root/src/lib/core
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2026-04-06 12:31:05 -0400
committerGitHub <noreply@github.com>2026-04-06 12:31:05 -0400
commitd01b465eee667e8efa4aa7c3088dc7af18ea2ab2 (patch)
treebf63c1378044c446f62dd20ce956a5a6d5e1973a /src/lib/core
parent83831af6502e68fe6199c29614e2df68ffbca170 (diff)
parentdfe3420de345a7d4c6a529e1c240138ca9852c86 (diff)
downloadstasis-next.tar.gz
Merge pull request #128 from jhunkeler/manylinuxHEADnextmaster
Manylinux
Diffstat (limited to 'src/lib/core')
-rw-r--r--src/lib/core/docker.c21
-rw-r--r--src/lib/core/envctl.c17
-rw-r--r--src/lib/core/globals.c2
-rw-r--r--src/lib/core/include/core.h4
-rw-r--r--src/lib/core/include/docker.h4
-rw-r--r--src/lib/core/include/strlist.h1
-rw-r--r--src/lib/core/include/utils.h12
-rw-r--r--src/lib/core/strlist.c23
-rw-r--r--src/lib/core/template_func_proto.c2
-rw-r--r--src/lib/core/utils.c54
-rw-r--r--src/lib/core/wheel.c3
11 files changed, 128 insertions, 15 deletions
diff --git a/src/lib/core/docker.c b/src/lib/core/docker.c
index 4723446..39357ad 100644
--- a/src/lib/core/docker.c
+++ b/src/lib/core/docker.c
@@ -1,17 +1,30 @@
#include "docker.h"
-int docker_exec(const char *args, unsigned flags) {
+int docker_exec(const char *args, const unsigned flags) {
struct Process proc;
char cmd[PATH_MAX];
memset(&proc, 0, sizeof(proc));
memset(cmd, 0, sizeof(cmd));
snprintf(cmd, sizeof(cmd) - 1, "docker %s", args);
+
+ unsigned final_flags = 0;
if (flags & STASIS_DOCKER_QUIET) {
+ final_flags |= STASIS_DOCKER_QUIET_STDOUT;
+ final_flags |= STASIS_DOCKER_QUIET_STDERR;
+ } else {
+ final_flags = flags;
+ }
+
+ if (final_flags & STASIS_DOCKER_QUIET_STDOUT) {
strcpy(proc.f_stdout, "/dev/null");
+ }
+ if (final_flags & STASIS_DOCKER_QUIET_STDERR) {
strcpy(proc.f_stderr, "/dev/null");
- } else {
+ }
+
+ if (!final_flags) {
msg(STASIS_MSG_L2, "Executing: %s\n", cmd);
}
@@ -19,11 +32,11 @@ int docker_exec(const char *args, unsigned flags) {
return proc.returncode;
}
-int docker_script(const char *image, char *data, unsigned flags) {
+int docker_script(const char *image, char *args, char *data, const unsigned flags) {
(void)flags; // TODO: placeholder
char cmd[PATH_MAX] = {0};
- snprintf(cmd, sizeof(cmd) - 1, "docker run --rm -i %s /bin/sh -", image);
+ snprintf(cmd, sizeof(cmd) - 1, "docker run -i %s \"%s\" /bin/sh -", args ? args : "", image);
FILE *outfile = popen(cmd, "w");
if (!outfile) {
diff --git a/src/lib/core/envctl.c b/src/lib/core/envctl.c
index b036611..d8d1b3d 100644
--- a/src/lib/core/envctl.c
+++ b/src/lib/core/envctl.c
@@ -92,23 +92,28 @@ unsigned envctl_get_flags(const struct EnvCtl *envctl, const char *name) {
}
void envctl_do_required(const struct EnvCtl *envctl, int verbose) {
+ int failed = 0;
for (size_t i = 0; i < envctl->num_used; i++) {
- struct EnvCtl_Item *item = envctl->item[i];
+ const struct EnvCtl_Item *item = envctl->item[i];
const char *name = item->name;
envctl_except_fn *callback = item->callback;
if (verbose) {
- msg(STASIS_MSG_L2, "Verifying %s\n", name);
+ msg(STASIS_MSG_L2, "Verifying %s [%s]\n", name, item->flags & STASIS_ENVCTL_REQUIRED ? "required" : "optional");
}
- int code = callback((const void *) item, (const void *) name);
+ const int code = callback((const void *) item, (const void *) name);
if (code == STASIS_ENVCTL_RET_IGNORE || code == STASIS_ENVCTL_RET_SUCCESS) {
continue;
}
if (code == STASIS_ENVCTL_RET_FAIL) {
- fprintf(stderr, "\n%s must be set. Exiting.\n", name);
- exit(1);
+ msg(STASIS_MSG_ERROR, "\n%s%s must be defined.\n", name, STASIS_COLOR_RESET);
+ failed++;
}
- fprintf(stderr, "\nan unknown envctl callback code occurred: %d\n", code);
+ msg(STASIS_MSG_ERROR, "\nan unknown envctl callback code occurred: %d\n", code);
+ }
+
+ if (failed) {
+ msg(STASIS_MSG_ERROR, "Environment check failed with %d error(s)\n", failed);
exit(1);
}
}
diff --git a/src/lib/core/globals.c b/src/lib/core/globals.c
index 834213b..63555a2 100644
--- a/src/lib/core/globals.c
+++ b/src/lib/core/globals.c
@@ -53,6 +53,8 @@ void globals_free() {
guard_free(globals.conda_install_prefix);
guard_strlist_free(&globals.conda_packages);
guard_strlist_free(&globals.pip_packages);
+ guard_free(globals.wheel_builder);
+ guard_free(globals.wheel_builder_manylinux_image);
guard_free(globals.jfrog.arch);
guard_free(globals.jfrog.os);
guard_free(globals.jfrog.url);
diff --git a/src/lib/core/include/core.h b/src/lib/core/include/core.h
index 5a3fa85..c895267 100644
--- a/src/lib/core/include/core.h
+++ b/src/lib/core/include/core.h
@@ -51,7 +51,9 @@ struct STASIS_GLOBAL {
char *tmpdir; //!< Path to temporary storage directory
char *conda_install_prefix; //!< Path to install conda
char *sysconfdir; //!< Path where STASIS reads its configuration files (mission directory, etc)
- int task_timeout; ///< Time in seconds before task is terminated
+ int task_timeout; ///!< Time in seconds before task is terminated
+ char *wheel_builder; ///!< Backend to build wheels (build, cibuildwheel, manylinux)
+ char *wheel_builder_manylinux_image; ///!< Image to use for a Manylinux build
struct {
char *tox_posargs;
char *conda_reactivate;
diff --git a/src/lib/core/include/docker.h b/src/lib/core/include/docker.h
index 7585d86..dd67f21 100644
--- a/src/lib/core/include/docker.h
+++ b/src/lib/core/include/docker.h
@@ -6,6 +6,8 @@
//! Flag to squelch output from docker_exec()
#define STASIS_DOCKER_QUIET 1 << 1
+#define STASIS_DOCKER_QUIET_STDOUT 1 << 2
+#define STASIS_DOCKER_QUIET_STDERR 1 << 3
//! Flag for older style docker build
#define STASIS_DOCKER_BUILD 1 << 1
@@ -83,7 +85,7 @@ int docker_exec(const char *args, unsigned flags);
* @return
*/
int docker_build(const char *dirpath, const char *args, int engine);
-int docker_script(const char *image, char *data, unsigned flags);
+int docker_script(const char *image, char *args, char *data, unsigned flags);
int docker_save(const char *image, const char *destdir, const char *compression_program);
void docker_sanitize_tag(char *str);
int docker_validate_compression_program(char *prog);
diff --git a/src/lib/core/include/strlist.h b/src/lib/core/include/strlist.h
index 18c60eb..1aaae3e 100644
--- a/src/lib/core/include/strlist.h
+++ b/src/lib/core/include/strlist.h
@@ -46,6 +46,7 @@ void strlist_append_strlist(struct StrList *pStrList1, struct StrList *pStrList2
void strlist_append(struct StrList **pStrList, char *str);
void strlist_append_array(struct StrList *pStrList, char **arr);
void strlist_append_tokenize(struct StrList *pStrList, char *str, char *delim);
+int strlist_appendf(struct StrList **pStrList, const char *fmt, ...);
struct StrList *strlist_copy(struct StrList *pStrList);
int strlist_cmp(struct StrList *a, struct StrList *b);
void strlist_free(struct StrList **pStrList);
diff --git a/src/lib/core/include/utils.h b/src/lib/core/include/utils.h
index ea98faf..335a7e4 100644
--- a/src/lib/core/include/utils.h
+++ b/src/lib/core/include/utils.h
@@ -27,6 +27,15 @@
#define LINE_SEP "\n"
#endif
+#if defined(STASIS_OS_LINUX)
+#define STASIS_RANDOM_GENERATOR_FILE "/dev/urandom"
+#elif defined(STASIS_OS_DARWIN)
+#define STASIS_RANDOM_GENERATOR_FILE "/dev/random"
+#else
+#define STASIS_RANDOM_GENERATOR_FILE NULL
+#define NEED_SRAND 1
+#endif
+
#define STASIS_XML_PRETTY_PRINT_PROG "xmllint"
#define STASIS_XML_PRETTY_PRINT_ARGS "--format"
@@ -470,4 +479,7 @@ void seconds_to_human_readable(int v, char *result, size_t maxlen);
#define STR_TO_TIMEOUT_INVALID_TIME_SCALE (-2)
int str_to_timeout(char *s);
+const char *get_random_generator_file();
+int get_random_bytes(char *result, size_t maxlen);
+
#endif //STASIS_UTILS_H
diff --git a/src/lib/core/strlist.c b/src/lib/core/strlist.c
index a0db5f3..3479c44 100644
--- a/src/lib/core/strlist.c
+++ b/src/lib/core/strlist.c
@@ -47,7 +47,6 @@ void strlist_append(struct StrList **pStrList, char *str) {
(*pStrList)->data = tmp;
(*pStrList)->data[(*pStrList)->num_inuse] = strdup(str);
(*pStrList)->data[(*pStrList)->num_alloc] = NULL;
- strcpy((*pStrList)->data[(*pStrList)->num_inuse], str);
(*pStrList)->num_inuse++;
(*pStrList)->num_alloc++;
}
@@ -231,6 +230,28 @@ void strlist_append_strlist(struct StrList *pStrList1, struct StrList *pStrList2
}
/**
+ * Append a formatted string
+ * Behavior is identical to asprintf-family of functions
+ * @param pStrList `StrList`
+ * @param fmt printf format string
+ * @param ... format arguments
+ * @return same as vasnprintf
+ */
+int strlist_appendf(struct StrList **pStrList, const char *fmt, ...) {
+ char *s = NULL;
+ va_list ap;
+ va_start(ap, fmt);
+ const int len = vasprintf(&s, fmt, ap);
+ va_end(ap);
+
+ if (pStrList && *pStrList && len >= 0) {
+ strlist_append(pStrList, s);
+ }
+ guard_free(s);
+ return len;
+}
+
+/**
* Produce a new copy of a `StrList`
* @param pStrList `StrList`
* @return `StrList` copy
diff --git a/src/lib/core/template_func_proto.c b/src/lib/core/template_func_proto.c
index 8324389..3e1cd99 100644
--- a/src/lib/core/template_func_proto.c
+++ b/src/lib/core/template_func_proto.c
@@ -55,8 +55,8 @@ int get_github_release_notes_auto_tplfunc_entrypoint(void *frame, void *data_out
strlist_append(&notes_list, note);
guard_free(note);
}
- guard_free(repository);
}
+ guard_free(repository);
}
}
// Return all notes as a single string
diff --git a/src/lib/core/utils.c b/src/lib/core/utils.c
index 00d747f..e106193 100644
--- a/src/lib/core/utils.c
+++ b/src/lib/core/utils.c
@@ -376,7 +376,8 @@ char *git_describe(const char *path) {
return NULL;
}
- FILE *pp = popen("git describe --first-parent --always --tags", "r");
+ // TODO: Use `-C [path]` if the version of git installed supports it
+ FILE *pp = popen("git describe --first-parent --long --always --tags", "r");
if (!pp) {
return NULL;
}
@@ -401,6 +402,7 @@ char *git_rev_parse(const char *path, char *args) {
return NULL;
}
+ // TODO: Use `-C [path]` if the version of git installed supports it
sprintf(cmd, "git rev-parse %s", args);
FILE *pp = popen(cmd, "r");
if (!pp) {
@@ -1120,3 +1122,53 @@ void seconds_to_human_readable(const int v, char *result, const size_t maxlen) {
snprintf(result + strlen(result), maxlen, "%ds", seconds);
}
+const char *get_random_generator_file() {
+ return STASIS_RANDOM_GENERATOR_FILE;
+}
+
+#ifdef NEED_SRAND
+static char stasis_srand_initialized = 0;
+#endif
+
+int get_random_bytes(char *result, size_t maxlen) {
+#ifdef NEED_SRAND
+ if (!srand_initialized) {
+ srand(time(NULL));
+ srand_initialized = 1;
+ }
+#endif
+ size_t bytes = 0;
+ const char *filename = get_random_generator_file();
+ FILE *fp = NULL;
+ if (filename != NULL) {
+ fp = fopen(filename, "rb");
+ if (!fp) {
+ SYSERROR("%s", "unable to open random generator");
+ return -1;
+ }
+ }
+
+ do {
+ int ch = 0;
+ if (fp) {
+ ch = fgetc(fp);
+ } else {
+ ch = rand() % 255;
+ }
+ if (fp && ferror(fp)) {
+ SYSERROR("%s", "unable to read from random generator");
+ return -1;
+ }
+ if (isalnum(ch)) {
+ result[bytes] = (char) ch;
+ bytes++;
+ }
+ } while (bytes < maxlen);
+
+ if (fp) {
+ fclose(fp);
+ }
+ result[bytes ? bytes - 1 : 0] = '\0';
+ return 0;
+}
+
diff --git a/src/lib/core/wheel.c b/src/lib/core/wheel.c
index c7e485a..79b5a21 100644
--- a/src/lib/core/wheel.c
+++ b/src/lib/core/wheel.c
@@ -113,6 +113,9 @@ struct Wheel *get_wheel_info(const char *basepath, const char *name, char *to_ma
void wheel_free(struct Wheel **wheel) {
struct Wheel *w = (*wheel);
+ if (!w) {
+ return;
+ }
guard_free(w->path_name);
guard_free(w->file_name);
guard_free(w->distribution);