mirror of
https://github.com/clearlinux/swupd-client.git
synced 2026-10-03 23:38:25 +00:00
Function to perform actions on 3rd-party bundles
This commit provides a function to perform general actions on every 3rd-party bundle on a list. If a repo is not specified, the bundles are looked for in every existing repo. This function will be useful to reuse code when adding other 3rd-party commands like bundle-remove or bundle-info.
This commit is contained in:
committed by
Castulo J. Martinez
parent
2a2018744e
commit
bb43d47fd4
+20
-114
@@ -93,16 +93,27 @@ static bool parse_options(int argc, char **argv)
|
||||
return true;
|
||||
}
|
||||
|
||||
static enum swupd_code add_bundle(char *bundle)
|
||||
{
|
||||
|
||||
struct list *bundle_to_install = NULL;
|
||||
enum swupd_code ret = SWUPD_OK;
|
||||
|
||||
/* execute_bundle_add expects a list */
|
||||
bundle_to_install = list_append_data(bundle_to_install, bundle);
|
||||
|
||||
info("\nBundles added from a 3rd-party repository are forced to run with the --no-scripts flag for security reasons\n\n");
|
||||
globals.no_scripts = true;
|
||||
|
||||
ret = execute_bundle_add(bundle_to_install);
|
||||
|
||||
list_free_list(bundle_to_install);
|
||||
return ret;
|
||||
}
|
||||
|
||||
enum swupd_code third_party_bundle_add_main(int argc, char **argv)
|
||||
{
|
||||
struct list *bundles = NULL;
|
||||
struct list *iter1 = NULL;
|
||||
struct list *iter2 = NULL;
|
||||
struct list *repos = NULL;
|
||||
char *state_dir;
|
||||
char *path_prefix;
|
||||
int repo_version;
|
||||
int ret;
|
||||
enum swupd_code ret_code = SWUPD_OK;
|
||||
|
||||
/*
|
||||
@@ -132,9 +143,6 @@ enum swupd_code third_party_bundle_add_main(int argc, char **argv)
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/* load the existing 3rd-party repos from the repo.ini config file */
|
||||
repos = third_party_get_repos();
|
||||
|
||||
/* move the bundles provided in the command line into a
|
||||
* list so it is easier to handle them */
|
||||
for (; *cmdline_bundles; ++cmdline_bundles) {
|
||||
@@ -143,115 +151,13 @@ enum swupd_code third_party_bundle_add_main(int argc, char **argv)
|
||||
}
|
||||
bundles = list_head(bundles);
|
||||
|
||||
/* backup the original state_dir and path_prefix values */
|
||||
state_dir = strdup_or_die(globals.state_dir);
|
||||
path_prefix = strdup_or_die(globals.path_prefix);
|
||||
|
||||
/* try installing bundles one by one */
|
||||
for (iter1 = bundles; iter1; iter1 = iter1->next) {
|
||||
char *bundle = iter1->data;
|
||||
struct repo *selected_repo = NULL;
|
||||
int count = 0;
|
||||
ret_code = third_party_run_operation(bundles, cmdline_repo, add_bundle);
|
||||
|
||||
/* if the repo to be used was specified, use it, otherwise
|
||||
* search for the bundle in all the 3rd-party repos */
|
||||
if (cmdline_repo) {
|
||||
|
||||
selected_repo = list_search(repos, cmdline_repo, repo_name_cmp);
|
||||
|
||||
} else {
|
||||
|
||||
info("Searching for bundle %s in the 3rd-party repositories...\n", bundle);
|
||||
for (iter2 = repos; iter2; iter2 = iter2->next) {
|
||||
struct repo *repo = iter2->data;
|
||||
struct manifest *mom = NULL;
|
||||
struct file *file = NULL;
|
||||
|
||||
/* set the appropriate content_dir and state_dir for the selected 3rd-party repo */
|
||||
ret = third_party_set_repo(state_dir, path_prefix, repo);
|
||||
if (ret) {
|
||||
ret_code = ret;
|
||||
goto clean_and_exit;
|
||||
}
|
||||
|
||||
/* get repo's version */
|
||||
repo_version = get_current_version(globals.path_prefix);
|
||||
if (repo_version < 0) {
|
||||
error("Unable to determine current version for repository %s\n\n", repo->name);
|
||||
ret_code = SWUPD_CURRENT_VERSION_UNKNOWN;
|
||||
goto clean_and_exit;
|
||||
}
|
||||
|
||||
/* load the repo's MoM*/
|
||||
mom = load_mom(repo_version, false, NULL);
|
||||
if (!mom) {
|
||||
error("Cannot load manifest MoM for 3rd-party repository %s version %i\n", repo->name, repo_version);
|
||||
ret_code = SWUPD_COULDNT_LOAD_MOM;
|
||||
goto clean_and_exit;
|
||||
}
|
||||
|
||||
/* search for the bundle in the MoM */
|
||||
file = mom_search_bundle(mom, bundle);
|
||||
if (file) {
|
||||
/* the bundle was found in this repo, keep a pointer to the repo */
|
||||
info("Bundle %s found in 3rd-party repository %s\n", bundle, repo->name);
|
||||
count++;
|
||||
selected_repo = repo;
|
||||
}
|
||||
manifest_free(mom);
|
||||
}
|
||||
|
||||
/* if the bundle exists in only one repo, we can continue */
|
||||
if (count == 0) {
|
||||
error("bundle %s was not found in any 3rd-party repository\n\n", bundle);
|
||||
ret_code = SWUPD_INVALID_BUNDLE;
|
||||
continue;
|
||||
} else if (count > 1) {
|
||||
error("bundle %s was found in more than one 3rd-party repository\n", bundle);
|
||||
info("Please specify a repository using the --repo flag\n\n");
|
||||
ret_code = SWUPD_INVALID_OPTION;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!selected_repo) {
|
||||
error("3rd-party repository %s was not found\n\n", cmdline_repo);
|
||||
ret_code = SWUPD_INVALID_REPOSITORY;
|
||||
goto clean_and_exit;
|
||||
}
|
||||
|
||||
/* set the appropriate content_dir and state_dir for the selected 3rd-party repo */
|
||||
ret = third_party_set_repo(state_dir, path_prefix, selected_repo);
|
||||
if (ret) {
|
||||
ret_code = ret;
|
||||
goto clean_and_exit;
|
||||
}
|
||||
|
||||
/* execute_bundle_add expects a list so we can send a new list with only
|
||||
* the one bundle we want to install in this iteration */
|
||||
struct list *bundle_to_install = NULL;
|
||||
bundle_to_install = list_append_data(bundle_to_install, bundle);
|
||||
|
||||
info("\nBundles added from a 3rd-party repository are forced to run with the --no-scripts flag for security reasons\n\n");
|
||||
globals.no_scripts = true;
|
||||
|
||||
ret = execute_bundle_add(bundle_to_install);
|
||||
|
||||
if (ret != SWUPD_OK) {
|
||||
ret_code = ret;
|
||||
}
|
||||
list_free_list(bundle_to_install);
|
||||
info("\n");
|
||||
}
|
||||
|
||||
clean_and_exit:
|
||||
free_string(&state_dir);
|
||||
free_string(&path_prefix);
|
||||
list_free_list(bundles);
|
||||
list_free_list_and_data(repos, repo_free_data);
|
||||
|
||||
swupd_deinit();
|
||||
progress_finish_steps(ret_code);
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
|
||||
@@ -244,4 +244,161 @@ enum swupd_code third_party_set_repo(const char *state_dir, const char *path_pre
|
||||
return SWUPD_OK;
|
||||
}
|
||||
|
||||
static enum swupd_code third_party_find_bundle(const char *bundle, struct list *repos, struct repo **found_repo)
|
||||
{
|
||||
struct list *iter = NULL;
|
||||
char *state_dir;
|
||||
char *path_prefix;
|
||||
char *content_url;
|
||||
int count = 0;
|
||||
int version;
|
||||
enum swupd_code ret_code = SWUPD_OK;
|
||||
|
||||
/* backup the original state_dir and path_prefix values */
|
||||
state_dir = strdup_or_die(globals.state_dir);
|
||||
path_prefix = strdup_or_die(globals.path_prefix);
|
||||
content_url = strdup_or_die(globals.content_url);
|
||||
|
||||
info("Searching for bundle %s in the 3rd-party repositories...\n", bundle);
|
||||
for (iter = repos; iter; iter = iter->next) {
|
||||
struct repo *repo = iter->data;
|
||||
struct manifest *mom = NULL;
|
||||
struct file *file = NULL;
|
||||
|
||||
/* set the appropriate content_dir and state_dir for the selected 3rd-party repo */
|
||||
ret_code = third_party_set_repo(state_dir, path_prefix, repo);
|
||||
if (ret_code != SWUPD_OK) {
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
/* get repo's version */
|
||||
version = get_current_version(globals.path_prefix);
|
||||
if (version < 0) {
|
||||
error("Unable to determine current version for repository %s\n\n", repo->name);
|
||||
ret_code = SWUPD_CURRENT_VERSION_UNKNOWN;
|
||||
goto clean_and_exit;
|
||||
}
|
||||
|
||||
/* load the repo's MoM*/
|
||||
mom = load_mom(version, false, NULL);
|
||||
if (!mom) {
|
||||
error("Cannot load manifest MoM for 3rd-party repository %s version %i\n", repo->name, version);
|
||||
ret_code = SWUPD_COULDNT_LOAD_MOM;
|
||||
goto clean_and_exit;
|
||||
}
|
||||
|
||||
/* search for the bundle in the MoM */
|
||||
file = mom_search_bundle(mom, bundle);
|
||||
if (file) {
|
||||
/* the bundle was found in this repo, keep a pointer to the repo */
|
||||
info("Bundle %s found in 3rd-party repository %s\n", bundle, repo->name);
|
||||
count++;
|
||||
*found_repo = repo;
|
||||
}
|
||||
manifest_free(mom);
|
||||
}
|
||||
|
||||
/* if the bundle was not found or exists in more than one repo,
|
||||
* return NULL */
|
||||
if (count == 0) {
|
||||
error("bundle %s was not found in any 3rd-party repository\n\n", bundle);
|
||||
ret_code = SWUPD_INVALID_BUNDLE;
|
||||
} else if (count > 1) {
|
||||
error("bundle %s was found in more than one 3rd-party repository\n", bundle);
|
||||
info("Please specify a repository using the --repo flag\n\n");
|
||||
ret_code = SWUPD_INVALID_OPTION;
|
||||
}
|
||||
|
||||
clean_and_exit:
|
||||
set_path_prefix(path_prefix);
|
||||
set_state_dir(state_dir);
|
||||
set_content_url(content_url);
|
||||
free_string(&path_prefix);
|
||||
free_string(&state_dir);
|
||||
free_string(&content_url);
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
enum swupd_code third_party_run_operation(struct list *bundles, const char *repo, run_operation_fn_t run_operation_fn)
|
||||
{
|
||||
struct list *repos = NULL;
|
||||
struct list *iter = NULL;
|
||||
struct repo *selected_repo = NULL;
|
||||
char *state_dir;
|
||||
char *path_prefix;
|
||||
char *content_url;
|
||||
int ret;
|
||||
enum swupd_code ret_code = SWUPD_OK;
|
||||
|
||||
/* load the existing 3rd-party repos from the repo.ini config file */
|
||||
repos = third_party_get_repos();
|
||||
|
||||
/* backup the original global values */
|
||||
state_dir = strdup_or_die(globals.state_dir);
|
||||
path_prefix = strdup_or_die(globals.path_prefix);
|
||||
content_url = strdup_or_die(globals.content_url);
|
||||
|
||||
/* try action on the bundles one by one */
|
||||
for (iter = bundles; iter; iter = iter->next) {
|
||||
char *bundle = iter->data;
|
||||
|
||||
/* if the repo to be used was specified, use it, otherwise
|
||||
* search for the bundle in all the 3rd-party repos */
|
||||
if (repo) {
|
||||
|
||||
selected_repo = list_search(repos, repo, repo_name_cmp);
|
||||
if (!selected_repo) {
|
||||
error("3rd-party repository %s was not found\n\n", repo);
|
||||
ret_code = SWUPD_INVALID_REPOSITORY;
|
||||
goto clean_and_exit;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* search for the bundle in all repos */
|
||||
ret = third_party_find_bundle(bundle, repos, &selected_repo);
|
||||
if (ret) {
|
||||
ret_code = ret;
|
||||
/* something went wrong or wasn't found,
|
||||
* go to the next bundle */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected_repo) {
|
||||
|
||||
/* set the appropriate content_dir and state_dir for the selected 3rd-party repo */
|
||||
ret = third_party_set_repo(state_dir, path_prefix, selected_repo);
|
||||
if (ret) {
|
||||
ret_code = ret;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* perform appropriate action on the bundle */
|
||||
ret = run_operation_fn(bundle);
|
||||
if (ret) {
|
||||
/* if we have an error here it is ok to overwrite any previous error */
|
||||
ret_code = ret;
|
||||
}
|
||||
info("\n");
|
||||
|
||||
/* return the global variables to the original values */
|
||||
next:
|
||||
set_path_prefix(path_prefix);
|
||||
set_state_dir(state_dir);
|
||||
set_content_url(content_url);
|
||||
}
|
||||
}
|
||||
|
||||
/* free data */
|
||||
clean_and_exit:
|
||||
list_free_list_and_data(repos, repo_free_data);
|
||||
free_string(&path_prefix);
|
||||
free_string(&state_dir);
|
||||
free_string(&content_url);
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,9 @@ struct repo {
|
||||
char *url;
|
||||
};
|
||||
|
||||
/* @brief Definition of a function that performs an action on a given bundle */
|
||||
typedef enum swupd_code (*run_operation_fn_t)(char *bundle);
|
||||
|
||||
/**
|
||||
* @brief Free repo pointed by @c repo.
|
||||
*/
|
||||
@@ -77,6 +80,18 @@ enum swupd_code third_party_set_repo(const char *state_dir, const char *path_pre
|
||||
*/
|
||||
int repo_name_cmp(const void *repo, const void *name);
|
||||
|
||||
/**
|
||||
* @brief Performs an operation on every bundle from the list.
|
||||
*
|
||||
* @param repo the name of the 3rd-party repository where the bundles
|
||||
* should be looked for. If no repo is specified the bundles are searched for
|
||||
* in all existing repos.
|
||||
* @param run_operation_fn the function to be performed on the bundles
|
||||
*
|
||||
* @returns a swupd_code
|
||||
*/
|
||||
enum swupd_code third_party_run_operation(struct list *bundles, const char *repo, run_operation_fn_t run_operation_fn);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user