diff options
-rw-r--r-- | include/core.h | 1 | ||||
-rw-r--r-- | include/delivery.h | 7 | ||||
-rw-r--r-- | src/delivery.c | 17 | ||||
-rw-r--r-- | src/stasis_main.c | 12 |
4 files changed, 37 insertions, 0 deletions
diff --git a/include/core.h b/include/core.h index 1ea9650..cea7a16 100644 --- a/include/core.h +++ b/include/core.h @@ -67,6 +67,7 @@ struct STASIS_GLOBAL { bool enable_docker; //!< Enable docker image builds bool enable_artifactory; //!< Enable artifactory uploads bool enable_testing; //!< Enable package testing + bool enable_overwrite; //!< Enable release file clobbering struct StrList *conda_packages; //!< Conda packages to install after initial activation struct StrList *pip_packages; //!< Pip packages to install after initial activation char *tmpdir; //!< Path to temporary storage directory diff --git a/include/delivery.h b/include/delivery.h index 971705f..969c803 100644 --- a/include/delivery.h +++ b/include/delivery.h @@ -391,4 +391,11 @@ int *bootstrap_build_info(struct Delivery *ctx); int delivery_dump_metadata(struct Delivery *ctx); +/** + * Determine whether a release on-disk matches the release name in use + * @param ctx Delivery context + * @return 0=no, 1=yes + */ +int delivery_exists(struct Delivery *ctx); + #endif //STASIS_DELIVERY_H diff --git a/src/delivery.c b/src/delivery.c index 8828266..7bedef3 100644 --- a/src/delivery.c +++ b/src/delivery.c @@ -2163,4 +2163,21 @@ int delivery_fixup_test_results(struct Delivery *ctx) { closedir(dp); return 0; +} + +int delivery_exists(struct Delivery *ctx) { + // TODO: scan artifactory repo for the same information + char release_pattern[PATH_MAX] = {0}; + sprintf(release_pattern, "*%s*", ctx->info.release_name); + struct StrList *files = listdir(ctx->storage.delivery_dir); + for (size_t i = 0; i < strlist_count(files); i++) { + char *filename = strlist_item(files, i); + int release_exists = fnmatch(release_pattern, filename, FNM_PATHNAME); + if (!globals.enable_overwrite && !release_exists) { + guard_strlist_free(&files); + return 1; + } + } + guard_strlist_free(&files); + return 0; }
\ No newline at end of file diff --git a/src/stasis_main.c b/src/stasis_main.c index 2abcbc4..e25681f 100644 --- a/src/stasis_main.c +++ b/src/stasis_main.c @@ -9,6 +9,7 @@ #define OPT_NO_DOCKER 1001 #define OPT_NO_ARTIFACTORY 1002 #define OPT_NO_TESTING 1003 +#define OPT_OVERWRITE 1004 static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, @@ -18,6 +19,7 @@ static struct option long_options[] = { {"verbose", no_argument, 0, 'v'}, {"unbuffered", no_argument, 0, 'U'}, {"update-base", no_argument, 0, OPT_ALWAYS_UPDATE_BASE}, + {"overwrite", no_argument, 0, OPT_OVERWRITE}, {"no-docker", no_argument, 0, OPT_NO_DOCKER}, {"no-artifactory", no_argument, 0, OPT_NO_ARTIFACTORY}, {"no-testing", no_argument, 0, OPT_NO_TESTING}, @@ -33,6 +35,7 @@ const char *long_options_help[] = { "Increase output verbosity", "Disable line buffering", "Update conda installation prior to STASIS environment creation", + "Overwrite an existing release", "Do not build docker images", "Do not upload artifacts to Artifactory", "Do not execute test scripts", @@ -193,6 +196,9 @@ int main(int argc, char *argv[]) { case 'v': globals.verbose = true; break; + case OPT_OVERWRITE: + globals.enable_overwrite = true; + break; case OPT_NO_DOCKER: globals.enable_docker = false; user_disabled_docker = true; @@ -351,6 +357,12 @@ int main(int argc, char *argv[]) { //delivery_runtime_show(&ctx); } + // Safety gate: Avoid clobbering a delivery unless the user wants that behavior + if (delivery_exists(&ctx)) { + msg(STASIS_MSG_ERROR | STASIS_MSG_L1, "Refusing to overwrite delivery: %s\nUse --overwrite to enable release clobbering.\n", ctx.info.release_name); + exit(1); + } + msg(STASIS_MSG_L1, "Conda setup\n"); delivery_get_installer_url(&ctx, installer_url); msg(STASIS_MSG_L2, "Downloading: %s\n", installer_url); |