diff options
Diffstat (limited to 'src/lib/delivery')
-rw-r--r-- | src/lib/delivery/delivery.c | 4 | ||||
-rw-r--r-- | src/lib/delivery/delivery_artifactory.c | 37 | ||||
-rw-r--r-- | src/lib/delivery/delivery_init.c | 8 | ||||
-rw-r--r-- | src/lib/delivery/delivery_install.c | 4 | ||||
-rw-r--r-- | src/lib/delivery/delivery_populate.c | 52 | ||||
-rw-r--r-- | src/lib/delivery/delivery_postprocess.c | 26 |
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; } |