aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/core/conda.c1
-rw-r--r--src/lib/core/download.c6
-rw-r--r--src/lib/core/environment.c50
-rw-r--r--src/lib/core/include/core.h2
-rw-r--r--src/lib/core/template.c4
-rw-r--r--src/lib/delivery/CMakeLists.txt1
-rw-r--r--src/lib/delivery/delivery_export.c58
-rw-r--r--src/lib/delivery/delivery_init.c8
-rw-r--r--src/lib/delivery/delivery_populate.c3
-rw-r--r--src/lib/delivery/include/delivery.h24
10 files changed, 137 insertions, 20 deletions
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c
index 268b433..de6130f 100644
--- a/src/lib/core/conda.c
+++ b/src/lib/core/conda.c
@@ -28,6 +28,7 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) {
const long http_code = download(url, installer_path, &errmsg);
if (HTTP_ERROR(http_code)) {
fprintf(stderr, "download failed: %ld: %s\n", http_code, errmsg);
+ guard_free(errmsg);
return -1;
}
}
diff --git a/src/lib/core/download.c b/src/lib/core/download.c
index c3f8dca..b021860 100644
--- a/src/lib/core/download.c
+++ b/src/lib/core/download.c
@@ -41,10 +41,10 @@ long download(char *url, const char *filename, char **errmsg) {
CURLcode curl_code = curl_easy_perform(c);
SYSDEBUG("curl status code: %d", curl_code);
if (curl_code != CURLE_OK) {
- if (errmsg) {
- strcpy(*errmsg, curl_easy_strerror(curl_code));
+ if (!*errmsg) {
+ *errmsg = strdup(curl_easy_strerror(curl_code));
} else {
- fprintf(stderr, "\nCURL ERROR: %s\n", curl_easy_strerror(curl_code));
+ strncpy(*errmsg, curl_easy_strerror(curl_code), strlen(curl_easy_strerror(curl_code) + 1));
}
goto failed;
}
diff --git a/src/lib/core/environment.c b/src/lib/core/environment.c
index f5e8566..7ece5e6 100644
--- a/src/lib/core/environment.c
+++ b/src/lib/core/environment.c
@@ -106,14 +106,13 @@ void runtime_export(RuntimeEnv *env, char **keys) {
if (keys != NULL) {
for (size_t j = 0; keys[j] != NULL; j++) {
if (strcmp(keys[j], key) == 0) {
- //sprintf(output, "%s=\"%s\"\n%s %s", key, value ? value : "", export_command, key);
- sprintf(output, "%s %s=\"%s\"", export_command, key, value ? value : "");
+ snprintf(output, sizeof(output), "%s %s=\"%s\"", export_command, key, value ? value : "");
puts(output);
}
}
}
else {
- sprintf(output, "%s %s=\"%s\"", export_command, key, value ? value : "");
+ snprintf(output, sizeof(output), "%s %s=\"%s\"", export_command, key, value ? value : "");
puts(output);
}
guard_free(value);
@@ -178,7 +177,7 @@ int runtime_replace(RuntimeEnv **dest, char **src) {
}
/**
- * Determine whether or not a key exists in the runtime environment
+ * Determine whether a key exists in the runtime environment
*
* Example:
*
@@ -245,7 +244,14 @@ char *runtime_get(RuntimeEnv *env, const char *key) {
ssize_t key_offset = runtime_contains(env, key);
if (key_offset != -1) {
char **pair = split(strlist_item(env, key_offset), "=", 0);
+ if (!pair) {
+ return NULL;
+ }
result = join(&pair[1], "=");
+ if (!result) {
+ guard_array_free(pair);
+ return NULL;
+ }
guard_array_free(pair);
}
return result;
@@ -285,8 +291,7 @@ char *runtime_expand_var(RuntimeEnv *env, char *input) {
// If there's no environment variables to process return the input string
if (strchr(input, delim) == NULL) {
- //return strdup(input);
- return input;
+ return strdup(input);
}
expanded = calloc(STASIS_BUFSIZ, sizeof(char));
@@ -336,7 +341,10 @@ char *runtime_expand_var(RuntimeEnv *env, char *input) {
if (env) {
tmp = runtime_get(env, var);
} else {
- tmp = getenv(var);
+ const char *v = getenv(var);
+ if (v) {
+ tmp = strdup(v);
+ }
}
if (tmp == NULL) {
// This mimics shell behavior in general.
@@ -348,9 +356,7 @@ char *runtime_expand_var(RuntimeEnv *env, char *input) {
}
// Append expanded environment variable to output
strncat(expanded, tmp, STASIS_BUFSIZ - 1);
- if (env) {
- guard_free(tmp);
- }
+ guard_free(tmp);
}
// Nothing to do so append input to output
@@ -400,13 +406,28 @@ char *runtime_expand_var(RuntimeEnv *env, char *input) {
* @param _value New environment variable value
*/
void runtime_set(RuntimeEnv *env, const char *_key, char *_value) {
+ const char *sep = "=";
if (_key == NULL) {
return;
}
+ const ssize_t key_offset = runtime_contains(env, _key);
char *key = strdup(_key);
- ssize_t key_offset = runtime_contains(env, key);
+ if (!key) {
+ SYSERROR("%s", "unable to allocate memory for key");
+ exit(1);
+ }
char *value = runtime_expand_var(env, _value);
- char *now = join((char *[]) {key, value, NULL}, "=");
+ if (!value) {
+ SYSERROR("%s", "unable to allocate memory for value");
+ exit(1);
+ }
+
+ lstrip(value);
+ char *now = join((char *[]) {key, value, NULL}, sep);
+ if (!now) {
+ SYSERROR("%s", "unable to allocate memory for join");
+ exit(1);
+ }
if (key_offset < 0) {
strlist_append(&env, now);
@@ -415,6 +436,7 @@ void runtime_set(RuntimeEnv *env, const char *_key, char *_value) {
}
guard_free(now);
guard_free(key);
+ guard_free(value);
}
/**
@@ -424,6 +446,10 @@ void runtime_set(RuntimeEnv *env, const char *_key, char *_value) {
void runtime_apply(RuntimeEnv *env) {
for (size_t i = 0; i < strlist_count(env); i++) {
char **pair = split(strlist_item(env, i), "=", 1);
+ if (!pair) {
+ SYSERROR("%s", "unable to allocate memory for runtime_apply");
+ return;
+ }
setenv(pair[0], pair[1], 1);
guard_array_free(pair);
}
diff --git a/src/lib/core/include/core.h b/src/lib/core/include/core.h
index 35a9506..92969d2 100644
--- a/src/lib/core/include/core.h
+++ b/src/lib/core/include/core.h
@@ -15,7 +15,7 @@
#define STASIS_NAME_MAX 255
#define STASIS_DIRSTACK_MAX 1024
#define STASIS_TIME_STR_MAX 128
-#define HTTP_ERROR(X) X >= 400
+#define HTTP_ERROR(X) (X >= 400 || X < 0)
#include "config.h"
#include "core_mem.h"
diff --git a/src/lib/core/template.c b/src/lib/core/template.c
index 68d20c9..dd3c7a2 100644
--- a/src/lib/core/template.c
+++ b/src/lib/core/template.c
@@ -280,8 +280,8 @@ char *tpl_render(char *str) {
output[z] = pos[off];
z++;
}
- SYSDEBUG("template output length: %zu", strlen(output));
- SYSDEBUG("template output bytes: %zu", output_bytes);
+ //SYSDEBUG("template output length: %zu", strlen(output));
+ //SYSDEBUG("template output bytes: %zu", output_bytes);
return output;
}
diff --git a/src/lib/delivery/CMakeLists.txt b/src/lib/delivery/CMakeLists.txt
index 78ed20f..559b2dc 100644
--- a/src/lib/delivery/CMakeLists.txt
+++ b/src/lib/delivery/CMakeLists.txt
@@ -1,4 +1,5 @@
add_library(stasis_delivery STATIC
+ delivery_export.c
delivery_postprocess.c
delivery_conda.c
delivery_docker.c
diff --git a/src/lib/delivery/delivery_export.c b/src/lib/delivery/delivery_export.c
new file mode 100644
index 0000000..d982ad5
--- /dev/null
+++ b/src/lib/delivery/delivery_export.c
@@ -0,0 +1,58 @@
+#include "delivery.h"
+
+static void delivery_export_configuration(const struct Delivery *ctx) {
+ msg(STASIS_MSG_L2, "Exporting delivery configuration\n");
+ if (!pushd(ctx->storage.cfgdump_dir)) {
+ char filename[PATH_MAX] = {0};
+ sprintf(filename, "%s.ini", ctx->info.release_name);
+ FILE *spec = fopen(filename, "w+");
+ if (!spec) {
+ msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", filename);
+ exit(1);
+ }
+ ini_write(ctx->_stasis_ini_fp.delivery, &spec, INI_WRITE_RAW);
+ fclose(spec);
+
+ memset(filename, 0, sizeof(filename));
+ sprintf(filename, "%s-rendered.ini", ctx->info.release_name);
+ spec = fopen(filename, "w+");
+ if (!spec) {
+ msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", filename);
+ exit(1);
+ }
+ ini_write(ctx->_stasis_ini_fp.delivery, &spec, INI_WRITE_PRESERVE);
+ fclose(spec);
+ popd();
+ } else {
+ SYSERROR("Failed to enter directory: %s", ctx->storage.delivery_dir);
+ exit(1);
+ }
+}
+
+void delivery_export(const struct Delivery *ctx, char *envs[]) {
+ delivery_export_configuration(ctx);
+
+ for (size_t i = 0; envs[i] != NULL; i++) {
+ char *name = envs[i];
+ msg(STASIS_MSG_L2, "Exporting %s\n", name);
+ if (conda_env_export(name, ctx->storage.delivery_dir, name)) {
+ msg(STASIS_MSG_ERROR | STASIS_MSG_L2, "failed %s\n", name);
+ exit(1);
+ }
+ }
+}
+
+void delivery_rewrite_stage1(struct Delivery *ctx, char *specfile) {
+ // Rewrite release environment output (i.e. set package origin(s) to point to the deployment server, etc.)
+ msg(STASIS_MSG_L3, "Rewriting release spec file (stage 1): %s\n", path_basename(specfile));
+ delivery_rewrite_spec(ctx, specfile, DELIVERY_REWRITE_SPEC_STAGE_1);
+
+ msg(STASIS_MSG_L1, "Rendering mission templates\n");
+ delivery_mission_render_files(ctx);
+}
+
+void delivery_rewrite_stage2(struct Delivery *ctx, char *specfile) {
+ msg(STASIS_MSG_L3, "Rewriting release spec file (stage 2): %s\n", path_basename(specfile));
+ delivery_rewrite_spec(ctx, specfile, DELIVERY_REWRITE_SPEC_STAGE_2);
+}
+
diff --git a/src/lib/delivery/delivery_init.c b/src/lib/delivery/delivery_init.c
index 56c591a..a60d6af 100644
--- a/src/lib/delivery/delivery_init.c
+++ b/src/lib/delivery/delivery_init.c
@@ -287,18 +287,25 @@ int delivery_init(struct Delivery *ctx, int render_mode) {
int bootstrap_build_info(struct Delivery *ctx) {
struct Delivery local = {0};
+ SYSDEBUG("ini_open(%s)", ctx->_stasis_ini_fp.cfg_path);
local._stasis_ini_fp.cfg = ini_open(ctx->_stasis_ini_fp.cfg_path);
+ SYSDEBUG("ini_open(%s)", ctx->_stasis_ini_fp.delivery_path);
local._stasis_ini_fp.delivery = ini_open(ctx->_stasis_ini_fp.delivery_path);
+
if (delivery_init_platform(&local)) {
+ SYSDEBUG("%s", "delivery_init_platform failed");
return -1;
}
if (populate_delivery_cfg(&local, INI_READ_RENDER)) {
+ SYSDEBUG("%s", "populate_delivery_cfg failed");
return -1;
}
if (populate_delivery_ini(&local, INI_READ_RENDER)) {
+ SYSDEBUG("%s", "populate_delivery_ini failed");
return -1;
}
if (populate_info(&local)) {
+ SYSDEBUG("%s", "populate_info failed");
return -1;
}
ctx->info.build_name = strdup(local.info.build_name);
@@ -314,6 +321,7 @@ int bootstrap_build_info(struct Delivery *ctx) {
memcpy(ctx->info.time_info, local.info.time_info, sizeof(*local.info.time_info));
ctx->info.time_now = local.info.time_now;
ctx->info.time_str_epoch = strdup(local.info.time_str_epoch);
+ SYSDEBUG("%s", "delivery_free local resources");
delivery_free(&local);
return 0;
}
diff --git a/src/lib/delivery/delivery_populate.c b/src/lib/delivery/delivery_populate.c
index 84676f1..28b2480 100644
--- a/src/lib/delivery/delivery_populate.c
+++ b/src/lib/delivery/delivery_populate.c
@@ -55,6 +55,7 @@ int populate_info(struct Delivery *ctx) {
int populate_delivery_cfg(struct Delivery *ctx, int render_mode) {
struct INIFILE *cfg = ctx->_stasis_ini_fp.cfg;
if (!cfg) {
+ SYSDEBUG("%s", "cfg is NULL");
return -1;
}
int err = 0;
@@ -162,8 +163,6 @@ int populate_delivery_ini(struct Delivery *ctx, int render_mode) {
// keys in the configuration
RuntimeEnv *rt = runtime_copy(__environ);
while ((rtdata = ini_getall(ini, "runtime")) != NULL) {
- char rec[STASIS_BUFSIZ];
- sprintf(rec, "%s=%s", lstrip(strip(rtdata->key)), lstrip(strip(rtdata->value)));
runtime_set(rt, rtdata->key, rtdata->value);
}
runtime_apply(rt);
diff --git a/src/lib/delivery/include/delivery.h b/src/lib/delivery/include/delivery.h
index 26a5499..69ec089 100644
--- a/src/lib/delivery/include/delivery.h
+++ b/src/lib/delivery/include/delivery.h
@@ -459,4 +459,28 @@ int delivery_series_sync(struct Delivery *ctx);
*/
int delivery_purge_packages(struct Delivery *ctx, const char *env_name, int use_pkg_manager);
+/**
+ * Export delivery environments
+ *
+ * @param ctx Delivery context
+ * @param envs array of conda environment names
+ */
+void delivery_export(const struct Delivery *ctx, char *envs[]);
+
+/**
+ * STAGE 1: Rewrite delivery-related strings in specfile
+ *
+ * @param ctx Delivery context
+ * @param specfile path to YAML spec file
+ */
+void delivery_rewrite_stage1(struct Delivery *ctx, char *specfile);
+
+/**
+ * STAGE 2: Rewrite delivery-related strings in specfile
+ *
+ * @param ctx Delivery context
+ * @param specfile path to YAML spec file
+ */
+void delivery_rewrite_stage2(struct Delivery *ctx, char *specfile);
+
#endif //STASIS_DELIVERY_H