aboutsummaryrefslogtreecommitdiff
path: root/src/lib/delivery
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/delivery')
-rw-r--r--src/lib/delivery/delivery.c4
-rw-r--r--src/lib/delivery/delivery_artifactory.c37
-rw-r--r--src/lib/delivery/delivery_init.c8
-rw-r--r--src/lib/delivery/delivery_install.c4
-rw-r--r--src/lib/delivery/delivery_populate.c52
-rw-r--r--src/lib/delivery/delivery_postprocess.c26
6 files changed, 121 insertions, 10 deletions
diff --git a/src/lib/delivery/delivery.c b/src/lib/delivery/delivery.c
index aa3e51a..41be64c 100644
--- a/src/lib/delivery/delivery.c
+++ b/src/lib/delivery/delivery.c
@@ -40,6 +40,7 @@ void delivery_free(struct Delivery *ctx) {
guard_free(ctx->info.build_name);
guard_free(ctx->info.build_number);
guard_free(ctx->info.release_name);
+ guard_free(ctx->info.time_info);
guard_free(ctx->conda.installer_baseurl);
guard_free(ctx->conda.installer_name);
guard_free(ctx->conda.installer_version);
@@ -50,8 +51,10 @@ void delivery_free(struct Delivery *ctx) {
guard_free(ctx->conda.tool_build_version);
guard_strlist_free(&ctx->conda.conda_packages);
guard_strlist_free(&ctx->conda.conda_packages_defer);
+ guard_strlist_free(&ctx->conda.conda_packages_purge);
guard_strlist_free(&ctx->conda.pip_packages);
guard_strlist_free(&ctx->conda.pip_packages_defer);
+ guard_strlist_free(&ctx->conda.pip_packages_purge);
guard_strlist_free(&ctx->conda.wheels_packages);
for (size_t i = 0; i < sizeof(ctx->tests) / sizeof(ctx->tests[0]); i++) {
@@ -62,6 +65,7 @@ void delivery_free(struct Delivery *ctx) {
guard_free(ctx->tests[i].repository_info_tag);
guard_strlist_free(&ctx->tests[i].repository_remove_tags);
guard_free(ctx->tests[i].script);
+ guard_free(ctx->tests[i].script_setup);
guard_free(ctx->tests[i].build_recipe);
// test-specific runtime variables
guard_runtime_free(ctx->tests[i].runtime.environ);
diff --git a/src/lib/delivery/delivery_artifactory.c b/src/lib/delivery/delivery_artifactory.c
index e979b9a..97db752 100644
--- a/src/lib/delivery/delivery_artifactory.c
+++ b/src/lib/delivery/delivery_artifactory.c
@@ -193,11 +193,41 @@ int delivery_series_sync(struct Delivery *ctx) {
return -1; // error
}
+ char *r_fmt = strdup(ctx->rules.release_fmt);
+ if (!r_fmt) {
+ SYSERROR("%s", "Unable to allocate bytes for release format string");
+ return -1;
+ }
+
+ // Replace revision formatters with wildcards
+ const char *to_wild[] = {"%r", "%R"};
+ for (size_t i = 0; i < sizeof(to_wild) / sizeof(*to_wild); i++) {
+ const char *formatter = to_wild[i];
+ if (replace_text(r_fmt, formatter, "*", 0) < 0) {
+ SYSERROR("Failed to replace '%s' in delivery format string", formatter);
+ return -1;
+ }
+ }
+
+ char *release_pattern = NULL;
+ if (delivery_format_str(ctx, &release_pattern, r_fmt) < 0) {
+ SYSERROR("Unable to render delivery format string: %s", r_fmt);
+ guard_free(r_fmt);
+ return -1;
+ }
+ guard_free(r_fmt);
+
char *remote_dir = NULL;
- if (asprintf(&remote_dir, "%s/%s/%s/(*)", globals.jfrog.repo, ctx->meta.mission, ctx->info.build_name) < 0) {
+ if (asprintf(&remote_dir, "%s/%s/%s/(*/*%s*)",
+ globals.jfrog.repo,
+ ctx->meta.mission,
+ ctx->info.build_name,
+ release_pattern) < 0) {
SYSERROR("%s", "Unable to allocate bytes for remote directory path");
+ guard_free(release_pattern);
return -1;
}
+ guard_free(release_pattern);
char *dest_dir = NULL;
if (asprintf(&dest_dir, "%s/{1}", ctx->storage.output_dir) < 0) {
@@ -205,5 +235,8 @@ int delivery_series_sync(struct Delivery *ctx) {
return -1;
}
- return jfrog_cli_rt_download(&ctx->deploy.jfrog_auth, &dl, remote_dir, dest_dir);
+ int status = jfrog_cli_rt_download(&ctx->deploy.jfrog_auth, &dl, remote_dir, dest_dir);
+ guard_free(dest_dir);
+ guard_free(remote_dir);
+ return status;
}
diff --git a/src/lib/delivery/delivery_init.c b/src/lib/delivery/delivery_init.c
index 2fced03..fe60075 100644
--- a/src/lib/delivery/delivery_init.c
+++ b/src/lib/delivery/delivery_init.c
@@ -296,10 +296,12 @@ int bootstrap_build_info(struct Delivery *ctx) {
ctx->info.build_name = strdup(local.info.build_name);
ctx->info.build_number = strdup(local.info.build_number);
ctx->info.release_name = strdup(local.info.release_name);
- ctx->info.time_info = malloc(sizeof(*ctx->info.time_info));
if (!ctx->info.time_info) {
- SYSERROR("Unable to allocate %zu bytes for tm struct: %s", sizeof(*local.info.time_info), strerror(errno));
- return -1;
+ ctx->info.time_info = malloc(sizeof(*ctx->info.time_info));
+ if (!ctx->info.time_info) {
+ SYSERROR("Unable to allocate %zu bytes for tm struct: %s", sizeof(*local.info.time_info), strerror(errno));
+ return -1;
+ }
}
memcpy(ctx->info.time_info, local.info.time_info, sizeof(*local.info.time_info));
ctx->info.time_now = local.info.time_now;
diff --git a/src/lib/delivery/delivery_install.c b/src/lib/delivery/delivery_install.c
index d3aab01..15ad7e0 100644
--- a/src/lib/delivery/delivery_install.c
+++ b/src/lib/delivery/delivery_install.c
@@ -128,7 +128,7 @@ int delivery_purge_packages(struct Delivery *ctx, const char *env_name, int use_
char package_manager[100] = {0};
typedef int (fnptr)(const char *);
- const char *current_env = conda_get_active_environment();
+ char *current_env = conda_get_active_environment();
if (current_env) {
conda_activate(ctx->storage.conda_install_prefix, env_name);
}
@@ -171,10 +171,12 @@ int delivery_purge_packages(struct Delivery *ctx, const char *env_name, int use_
status = 1;
break;
}
+ guard_free(command);
}
if (current_env) {
conda_activate(ctx->storage.conda_install_prefix, current_env);
+ guard_free(current_env);
}
return status;
diff --git a/src/lib/delivery/delivery_populate.c b/src/lib/delivery/delivery_populate.c
index e9aea89..f242328 100644
--- a/src/lib/delivery/delivery_populate.c
+++ b/src/lib/delivery/delivery_populate.c
@@ -30,11 +30,21 @@ int populate_info(struct Delivery *ctx) {
if (!ctx->info.time_str_epoch) {
// Record timestamp used for release
time(&ctx->info.time_now);
- ctx->info.time_info = localtime(&ctx->info.time_now);
+ if (!ctx->info.time_info) {
+ ctx->info.time_info = malloc(sizeof(*ctx->info.time_info));
+ if (!ctx->info.time_info) {
+ msg(STASIS_MSG_ERROR, "%s: Unable to allocate memory for time_info\n", strerror(errno));
+ return -1;
+ }
+ if (!localtime_r(&ctx->info.time_now, ctx->info.time_info)) {
+ msg(STASIS_MSG_ERROR, "%s: localtime_r failed\n", strerror(errno));
+ return -1;
+ }
+ }
ctx->info.time_str_epoch = calloc(STASIS_TIME_STR_MAX, sizeof(*ctx->info.time_str_epoch));
if (!ctx->info.time_str_epoch) {
- msg(STASIS_MSG_ERROR, "Unable to allocate memory for Unix epoch string\n");
+ msg(STASIS_MSG_ERROR, "%s: Unable to allocate memory for Unix epoch string\n", strerror(errno));
return -1;
}
snprintf(ctx->info.time_str_epoch, STASIS_TIME_STR_MAX - 1, "%li", ctx->info.time_now);
@@ -59,16 +69,54 @@ int populate_delivery_cfg(struct Delivery *ctx, int render_mode) {
if (!globals.always_update_base_environment) {
globals.always_update_base_environment = ini_getval_bool(cfg, "default", "always_update_base_environment", render_mode, &err);
}
+ if (globals.conda_install_prefix) {
+ guard_free(globals.conda_install_prefix);
+ }
globals.conda_install_prefix = ini_getval_str(cfg, "default", "conda_install_prefix", render_mode, &err);
+
+ if (globals.conda_packages) {
+ guard_strlist_free(&globals.conda_packages);
+ }
globals.conda_packages = ini_getval_strlist(cfg, "default", "conda_packages", LINE_SEP, render_mode, &err);
+
+ if (globals.pip_packages) {
+ guard_strlist_free(&globals.pip_packages);
+ }
globals.pip_packages = ini_getval_strlist(cfg, "default", "pip_packages", LINE_SEP, render_mode, &err);
+ if (globals.jfrog.jfrog_artifactory_base_url) {
+ guard_free(globals.jfrog.jfrog_artifactory_base_url);
+ }
globals.jfrog.jfrog_artifactory_base_url = ini_getval_str(cfg, "jfrog_cli_download", "url", render_mode, &err);
+
+ if (globals.jfrog.jfrog_artifactory_product) {
+ guard_free(globals.jfrog.jfrog_artifactory_product);
+ }
globals.jfrog.jfrog_artifactory_product = ini_getval_str(cfg, "jfrog_cli_download", "product", render_mode, &err);
+
+ if (globals.jfrog.cli_major_ver) {
+ guard_free(globals.jfrog.cli_major_ver);
+ }
globals.jfrog.cli_major_ver = ini_getval_str(cfg, "jfrog_cli_download", "version_series", render_mode, &err);
+
+ if (globals.jfrog.version) {
+ guard_free(globals.jfrog.version);
+ }
globals.jfrog.version = ini_getval_str(cfg, "jfrog_cli_download", "version", render_mode, &err);
+
+ if (globals.jfrog.remote_filename) {
+ guard_free(globals.jfrog.remote_filename);
+ }
globals.jfrog.remote_filename = ini_getval_str(cfg, "jfrog_cli_download", "filename", render_mode, &err);
+
+ if (globals.jfrog.url) {
+ guard_free(globals.jfrog.url);
+ }
globals.jfrog.url = ini_getval_str(cfg, "deploy:artifactory", "url", render_mode, &err);
+
+ if (globals.jfrog.repo) {
+ guard_free(globals.jfrog.repo);
+ }
globals.jfrog.repo = ini_getval_str(cfg, "deploy:artifactory", "repo", render_mode, &err);
return 0;
diff --git a/src/lib/delivery/delivery_postprocess.c b/src/lib/delivery/delivery_postprocess.c
index 40ac43f..b43e247 100644
--- a/src/lib/delivery/delivery_postprocess.c
+++ b/src/lib/delivery/delivery_postprocess.c
@@ -66,7 +66,9 @@ void delivery_rewrite_spec(struct Delivery *ctx, char *filename, unsigned stage)
FILE *tp = NULL;
if (stage == DELIVERY_REWRITE_SPEC_STAGE_1) {
+ SYSDEBUG("%s", "Entering stage 1");
header = delivery_get_release_header(ctx);
+ SYSDEBUG("Release header:\n%s", header);
if (!header) {
msg(STASIS_MSG_ERROR, "failed to generate release header string\n", filename);
exit(1);
@@ -76,6 +78,7 @@ void delivery_rewrite_spec(struct Delivery *ctx, char *filename, unsigned stage)
msg(STASIS_MSG_ERROR, "%s: unable to create temporary file\n", strerror(errno));
exit(1);
}
+ SYSDEBUG("Writing header to temporary file: %s", tempfile);
fprintf(tp, "%s", header);
// Read the original file
@@ -88,19 +91,22 @@ void delivery_rewrite_spec(struct Delivery *ctx, char *filename, unsigned stage)
// Write temporary data
for (size_t i = 0; contents[i] != NULL; i++) {
if (startswith(contents[i], "channels:")) {
- // Allow for additional conda channel injection
if (ctx->conda.conda_packages_defer && strlist_count(ctx->conda.conda_packages_defer)) {
+ // Allow for additional conda channel injection
+ SYSDEBUG("Appending conda channel template on line %zu", i);
fprintf(tp, "%s - @CONDA_CHANNEL@\n", contents[i]);
continue;
}
} else if (strstr(contents[i], "- pip:")) {
if (ctx->conda.pip_packages_defer && strlist_count(ctx->conda.pip_packages_defer)) {
// Allow for additional pip argument injection
+ SYSDEBUG("Appending pip argument template on line %zu", i);
fprintf(tp, "%s - @PIP_ARGUMENTS@\n", contents[i]);
continue;
}
} else if (startswith(contents[i], "prefix:")) {
// Remove the prefix key
+ SYSDEBUG("Removing prefix key on line %zu", i);
if (strstr(contents[i], "/") || strstr(contents[i], "\\")) {
// path is on the same line as the key
continue;
@@ -118,38 +124,49 @@ void delivery_rewrite_spec(struct Delivery *ctx, char *filename, unsigned stage)
guard_free(header);
fflush(tp);
fclose(tp);
+ SYSDEBUG("Done writing temporary file: %s", tempfile);
// Replace the original file with our temporary data
if (copy2(tempfile, filename, CT_PERM) < 0) {
fprintf(stderr, "%s: could not rename '%s' to '%s'\n", strerror(errno), tempfile, filename);
exit(1);
}
+ SYSDEBUG("Removing file: %s", tempfile);
remove(tempfile);
guard_free(tempfile);
} else if (globals.enable_rewrite_spec_stage_2 && stage == DELIVERY_REWRITE_SPEC_STAGE_2) {
+ SYSDEBUG("%s", "Entering stage 2");
char output[PATH_MAX] = {0};
// Replace "local" channel with the staging URL
if (ctx->storage.conda_staging_url) {
+ SYSDEBUG("%s", "Will replace conda channel with staging area url");
file_replace_text(filename, "@CONDA_CHANNEL@", ctx->storage.conda_staging_url, 0);
} else if (globals.jfrog.repo) {
+ SYSDEBUG("%s", "Will replace conda channel with artifactory repo packages/conda url");
sprintf(output, "%s/%s/%s/%s/packages/conda", globals.jfrog.url, globals.jfrog.repo, ctx->meta.mission, ctx->info.build_name);
file_replace_text(filename, "@CONDA_CHANNEL@", output, 0);
} else {
+ SYSDEBUG("%s", "Will replace conda channel with local conda artifact directory");
msg(STASIS_MSG_WARN, "conda_staging_dir is not configured. Using fallback: '%s'\n", ctx->storage.conda_artifact_dir);
file_replace_text(filename, "@CONDA_CHANNEL@", ctx->storage.conda_artifact_dir, 0);
}
if (ctx->storage.wheel_staging_url) {
+ SYSDEBUG("%s", "Will replace pip arguments with wheel staging url");
+ sprintf(output, "--extra-index-url %s/%s/%s/packages/wheels", ctx->storage.wheel_staging_url, ctx->meta.mission, ctx->info.build_name);
file_replace_text(filename, "@PIP_ARGUMENTS@", ctx->storage.wheel_staging_url, 0);
} else if (globals.enable_artifactory && globals.jfrog.url && globals.jfrog.repo) {
+ SYSDEBUG("%s", "Will replace pip arguments with artifactory repo packages/wheel url");
sprintf(output, "--extra-index-url %s/%s/%s/%s/packages/wheels", globals.jfrog.url, globals.jfrog.repo, ctx->meta.mission, ctx->info.build_name);
file_replace_text(filename, "@PIP_ARGUMENTS@", output, 0);
} else {
+ SYSDEBUG("%s", "Will replace pip arguments with local wheel artifact directory");
msg(STASIS_MSG_WARN, "wheel_staging_dir is not configured. Using fallback: '%s'\n", ctx->storage.wheel_artifact_dir);
sprintf(output, "--extra-index-url file://%s", ctx->storage.wheel_artifact_dir);
file_replace_text(filename, "@PIP_ARGUMENTS@", output, 0);
}
}
+ SYSDEBUG("%s", "Rewriting finished");
}
int delivery_copy_conda_artifacts(struct Delivery *ctx) {
@@ -201,6 +218,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) {
// pip install --extra-index-url
char top_index[PATH_MAX] = {0};
sprintf(top_index, "%s/index.html", ctx->storage.wheel_artifact_dir);
+ SYSDEBUG("Opening top-level index for writing: %s", top_index);
FILE *top_fp = fopen(top_index, "w+");
if (!top_fp) {
closedir(dp);
@@ -215,6 +233,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) {
char bottom_index[PATH_MAX * 2] = {0};
sprintf(bottom_index, "%s/%s/index.html", ctx->storage.wheel_artifact_dir, rec->d_name);
+ SYSDEBUG("Opening bottom-level for writing: %s", bottom_index);
FILE *bottom_fp = fopen(bottom_index, "w+");
if (!bottom_fp) {
closedir(dp);
@@ -225,6 +244,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) {
printf("+ %s\n", rec->d_name);
}
// Add record to top level index
+ SYSDEBUG("Appending top-level link for %s", rec->d_name);
fprintf(top_fp, "<a href=\"%s/\">%s</a><br/>\n", rec->d_name, rec->d_name);
char dpath[PATH_MAX * 2] = {0};
@@ -238,7 +258,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) {
}
for (size_t i = 0; i < strlist_count(packages); i++) {
- char *package = strlist_item(packages, i);
+ char *package = path_basename(strlist_item(packages, i));
if (!endswith(package, ".whl")) {
continue;
}
@@ -246,6 +266,7 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) {
printf("`- %s\n", package);
}
// Write record to bottom level index
+ SYSDEBUG("Appending bottom-level link for %s", package);
fprintf(bottom_fp, "<a href=\"%s\">%s</a><br/>\n", package, package);
}
fclose(bottom_fp);
@@ -254,5 +275,6 @@ int delivery_index_wheel_artifacts(struct Delivery *ctx) {
}
closedir(dp);
fclose(top_fp);
+ SYSDEBUG("%s", "Wheel indexing complete");
return 0;
}