Revert operation when theres an error adding repos

When adding 3rd-party repositories, errors may occur, in these cases the
operation has to be reverted completely because we don't want to be left
with an invalid repo.

Signed-off-by: Castulo Martinez <castulo.martinez@intel.com>
This commit is contained in:
Castulo Martinez
2019-12-16 11:24:35 -08:00
committed by Castulo J. Martinez
parent 24de99dfcc
commit 0172989717
4 changed files with 80 additions and 24 deletions
+48 -1
View File
@@ -69,6 +69,23 @@ static bool parse_options(int argc, char **argv)
return false;
}
static int remove_repo(const char *repo_name)
{
int ret;
ret = third_party_remove_repo(repo_name);
if (ret != 0 && ret != -ENOENT) {
return ret;
}
ret = third_party_remove_repo_directory(repo_name);
if (ret != 0 && ret != -ENOENT) {
return ret;
}
return 0;
}
enum swupd_code third_party_add_main(int argc, char **argv)
{
@@ -77,6 +94,9 @@ enum swupd_code third_party_add_main(int argc, char **argv)
const char *name, *url;
struct list *repos = NULL;
struct repo *repo = NULL;
char *path_prefix = NULL;
char *state_dir = NULL;
bool revert = false;
int repo_version;
int ret;
@@ -95,9 +115,14 @@ enum swupd_code third_party_add_main(int argc, char **argv)
url = argv[argc - 1];
if (!is_url_allowed(url)) {
return SWUPD_INVALID_OPTION;
ret_code = SWUPD_INVALID_OPTION;
goto finish;
}
/* backup the original global values */
path_prefix = strdup_or_die(globals.path_prefix);
state_dir = strdup_or_die(globals.state_dir);
/* The last two in reverse are the repo-name, repo-url */
ret = third_party_add_repo(name, url);
if (ret) {
@@ -117,12 +142,14 @@ enum swupd_code third_party_add_main(int argc, char **argv)
if (!repo) {
/* this should not happen */
ret_code = SWUPD_UNEXPECTED_CONDITION;
revert = true;
goto finish;
}
/* set the appropriate content_dir and state_dir for the selected 3rd-party repo */
ret_code = third_party_set_repo(globals.state_dir, globals.path_prefix, repo);
if (ret_code) {
revert = true;
goto finish;
}
@@ -131,6 +158,7 @@ enum swupd_code third_party_add_main(int argc, char **argv)
if (repo_version < 0) {
error("Unable to determine the latest version for repository %s\n\n", repo->name);
ret_code = SWUPD_INVALID_REPOSITORY;
revert = true;
goto finish;
}
@@ -142,12 +170,31 @@ enum swupd_code third_party_add_main(int argc, char **argv)
struct list *bundle_to_install = NULL;
bundle_to_install = list_append_data(bundle_to_install, "os-core");
ret_code = bundle_add(bundle_to_install, repo_version);
if (ret_code) {
revert = true;
}
list_free_list(bundle_to_install);
finish:
if (revert) {
/* there was an error adding the repo, revert the action,
* we don't want to keep a corrupt repo */
info("There was an error adding 3rd-party repository %s, reverting...\n", name);
set_path_prefix(path_prefix);
set_state_dir(state_dir);
ret = remove_repo(name);
if (!ret) {
info("Operation reverted\n");
} else {
error("There was an error removing the repository (errno: %d)\n", ret);
}
}
list_free_list_and_data(repos, repo_free_data);
free_string(&path_prefix);
free_string(&state_dir);
swupd_deinit();
progress_finish_steps(ret_code);
return ret_code;
}
+1 -20
View File
@@ -25,25 +25,6 @@
#ifdef THIRDPARTY
static int remove_repo_directory(char *repo_name)
{
char *repo_dir;
int ret = 0;
//TODO: use a global function to get this value
repo_dir = str_or_die("%s/%s/%s", globals.path_prefix, "opt/3rd_party", repo_name);
ret = sys_rm_recursive(repo_dir);
if (ret == -ENOENT) {
ret = 0;
}
if (ret < 0) {
error("Failed to delete repository directory\n");
}
free(repo_dir);
return ret;
}
static void print_help(void)
{
print("Usage:\n");
@@ -112,7 +93,7 @@ enum swupd_code third_party_remove_main(int argc, char **argv)
goto exit;
}
if (remove_repo_directory(argv[argc - 1]) < 0) {
if (third_party_remove_repo_directory(argv[argc - 1]) < 0) {
ret = SWUPD_COULDNT_REMOVE_FILE;
goto exit;
}
+21 -2
View File
@@ -193,14 +193,14 @@ exit:
return ret;
}
int third_party_remove_repo(char *repo_name)
int third_party_remove_repo(const char *repo_name)
{
struct repo *repo;
struct list *repos;
int ret = 0;
repos = third_party_get_repos();
repo = list_remove(repo_name, &repos, repo_name_cmp);
repo = list_remove((void *)repo_name, &repos, repo_name_cmp);
if (!repo) {
error("Repository not found\n");
@@ -219,6 +219,25 @@ exit:
return ret;
}
int third_party_remove_repo_directory(const char *repo_name)
{
char *repo_dir;
int ret = 0;
//TODO: use a global function to get this value
repo_dir = str_or_die("%s/%s/%s", globals.path_prefix, "opt/3rd_party", repo_name);
ret = sys_rm_recursive(repo_dir);
if (ret == -ENOENT) {
ret = 0;
}
if (ret < 0) {
error("Failed to delete repository directory\n");
}
free(repo_dir);
return ret;
}
enum swupd_code third_party_set_repo(const char *state_dir, const char *path_prefix, struct repo *repo)
{
char *repo_state_dir;
+10 -1
View File
@@ -63,7 +63,16 @@ int third_party_add_repo(const char *repo_name, const char *repo_url);
* @returns 0 on success ie: a repo is found, removed & repo config is adjusted
* otherwise a -1 on any failure
*/
int third_party_remove_repo(char *repo_name);
int third_party_remove_repo(const char *repo_name);
/**
* @brief This function removes the directory where the content of a repo is installed.
*
* @param repo_name A string containing repo_name
*
* @returns 0 on success, otherwise a negative errno on any failure
*/
int third_party_remove_repo_directory(const char *repo_name);
/**
* @brief This function sets up swupd to use a specific 3rd-party repo.