int add_included_manifests(struct manifest *mom) { struct list *subbed = NULL; struct list *iter; int ret; iter = list_head(subs); while (iter) { subbed = list_prepend_data(subbed, ((struct sub *)iter->data)->component); iter = iter->next; } if (add_subscriptions(subbed, mom->version, mom) >= 0) { ret = 0; } else { ret = -1; } list_free_list(subbed); return ret; }
int install_bundles(struct list *bundles, int current_version, struct manifest *mom) { int ret; struct file *file; struct list *iter; struct list *to_install_bundles, *to_install_files; /* step 1: check bundle args are valid if so populate subs struct */ ret = add_subscriptions(bundles, current_version, mom); if (ret) { if (ret == 1) { printf("bundle(s) already installed, exiting now\n"); } ret = EBUNDLE_INSTALL; goto out; } subscription_versions_from_MoM(mom, 0); to_install_bundles = recurse_manifest(mom, NULL); if (!to_install_bundles) { printf("Error: Cannot load to install bundles\n"); ret = ERECURSE_MANIFEST; goto out; } to_install_files = files_from_bundles(to_install_bundles); to_install_files = consolidate_files(to_install_files); /* step 2: download neccessary packs */ (void)rm_staging_dir_contents("download"); printf("Downloading packs...\n"); (void)download_subscribed_packs(true); /* step 3: Add tracked bundles */ read_subscriptions_alt(); subscription_versions_from_MoM(mom, 0); mom->submanifests = recurse_manifest(mom, NULL); if (!mom->submanifests) { printf("Error: Cannot load installed bundles\n"); ret = ERECURSE_MANIFEST; goto out; } mom->files = files_from_bundles(mom->submanifests); mom->files = consolidate_files(mom->files); /* step 4: Install all bundle(s) files into the fs */ printf("Installing bundle(s) files...\n"); iter = list_head(to_install_files); while (iter) { file = iter->data; iter = iter->next; if (file->is_deleted || file->do_not_update || ignore(file)) { continue; } ret = do_staging(file, mom); if (ret) { ret = verify_fix_path(file->filename, mom); } if (ret) { ret = EBUNDLE_INSTALL; goto out; } } iter = list_head(to_install_files); while (iter) { file = iter->data; iter = iter->next; if (file->is_deleted || file->do_not_update || ignore(file)) { continue; } /* This was staged by verify_fix_path */ if (!file->staging) { file = search_file_in_manifest(mom, file->filename); } rename_staged_file_to_final(file); } sync(); /* step 5: Run any scripts that are needed to complete update */ run_scripts(); ret = 0; printf("Bundle(s) installation done.\n"); out: free_subscriptions(); return ret; }
/* tristate return, -1 for errors, 1 for no errors but no new subscriptions, 0 for no errors and new subscriptions */ int add_subscriptions(struct list *bundles, int current_version, struct manifest *mom) { bool new_bundles = false; char *bundle; int ret; int retries = 0; int timeout = 10; struct file *file; struct list *iter; struct manifest *manifest; srand(time(NULL)); iter = list_head(bundles); while (iter) { bundle = iter->data; iter = iter->next; file = search_bundle_in_manifest(mom, bundle); if (!file) { printf("%s bundle name is invalid, skipping it...\n", bundle); continue; } retry_manifest_download: manifest = load_manifest(current_version, file->last_change, file, mom); if (!manifest) { if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); goto retry_manifest_download; } printf("Unable to download manifest %s version %d, exiting now\n", bundle, file->last_change); ret = -1; goto out; } if (!manifest) { printf("Unable to load manifest %s version %d, exiting now\n", bundle, file->last_change); ret = -1; goto out; } if (manifest->includes) { ret = add_subscriptions(manifest->includes, current_version, mom); if (ret == -1) { free_manifest(manifest); goto out; } else if (ret == 0) { new_bundles = true; } } free_manifest(manifest); if (is_tracked_bundle(bundle)) { continue; } if (component_subscribed(bundle)) { continue; } create_and_append_subscription(bundle); new_bundles = true; } if (new_bundles) { ret = 0; } else { ret = 1; } out: return ret; }
int install_bundles(struct list *bundles, int current_version, struct manifest *mom) { int ret; struct file *file; struct list *iter; struct sub *sub; /* step 1: check bundle args are valid if so populate subs struct */ ret = add_subscriptions(bundles, current_version, mom); if (ret) { if (ret == 1) { printf("bundle(s) already installed, exiting now\n"); } ret = EBUNDLE_INSTALL; goto out; } subscription_versions_from_MoM(mom, 0); ret = recurse_manifest(mom, NULL); if (ret != 0) { printf("Error: Cannot load MoM sub-manifests (ret = %d)\n", ret); ret = ERECURSE_MANIFEST; goto out; } consolidate_submanifests(mom); /* step 2: download neccessary packs */ (void)rm_staging_dir_contents("download"); printf("Downloading required packs...\n"); ret = download_subscribed_packs(true); if (ret != 0) { printf("pack downloads failed, cannot proceed with the installation, exiting.\n"); goto out; } /* step 3: Install all bundle(s) files into the fs */ printf("Installing bundle(s) files...\n"); iter = list_head(mom->files); while (iter) { file = iter->data; iter = iter->next; if (file->is_deleted || file->do_not_update || ignore(file)) { continue; } ret = do_staging(file, mom); if (ret == 0) { rename_staged_file_to_final(file); } } sync(); /* step 4: create bundle(s) subscription entries to track them * * Strictly speaking each manifest has an entry to write its own bundle filename * and thus tracking automagically, here just making sure. */ iter = list_head(subs); while (iter) { sub = iter->data; iter = iter->next; printf("Tracking %s bundle on the system\n", sub->component); ret = track_bundle_in_system(sub->component); if (ret != 0) { printf("Cannot track %s bundle on the system\n", sub->component); } } /* step 5: Run any scripts that are needed to complete update */ run_scripts(); ret = 0; printf("Bundle(s) installation done.\n"); out: free_subscriptions(); return ret; }