Beispiel #1
0
/* download_manifests()
 * Description: To search Clear bundles for a particular entry, a complete set of
 *		manifests must be downloaded. This function does so, asynchronously, using
 *		the curl_multi interface */
int download_manifests(struct manifest **MoM)
{
	struct list *list;
	struct file *file;
	char *tarfile, *untard_file, *url;
	struct manifest *subMan = NULL;
	int current_version;
	int ret = 0;
	double size;

	current_version = read_version_from_subvol_file(path_prefix);
	swupd_curl_set_current_version(current_version);

	ret = load_manifests(current_version, current_version, "MoM", NULL, MoM);
	if (ret != 0) {
		printf("Cannot load official manifest MoM for version %i\n", current_version);
		return ret;
	}

	subscription_versions_from_MoM(*MoM, 0);

	list = (*MoM)->manifests;
	size = query_total_download_size(list);
	if (size == -1) {
		printf("Downloading manifests. Expect a delay, up to 100MB may be downloaded\n");
	} else if (size > 0) {
		printf("Downloading Clear Linux manifests\n");
		printf("   %.2f MB total...\n\n", size);
	}

	while (list) {
		file = list->data;
		list = list->next;

		create_and_append_subscription(file->filename);

		string_or_die(&untard_file, "%s/%i/Manifest.%s", STATE_DIR, file->last_change,
			      file->filename);

		string_or_die(&tarfile, "%s/%i/Manifest.%s.tar", STATE_DIR, file->last_change,
			      file->filename);

		if (access(untard_file, F_OK) == -1) {
			/* Do download */
			printf(" '%s' manifest...\n", file->filename);

			ret = load_manifests(current_version, file->last_change, file->filename, NULL, &subMan);
			if (ret != 0) {
				printf("Cannot load official manifest MoM for version %i\n", current_version);
			}

			free_manifest(subMan);
		}

		if (access(untard_file, F_OK) == -1) {
			string_or_die(&url, "%s/%i/Manifest.%s.tar", preferred_content_url, current_version,
				      file->filename);

			printf("Error: Failure reading from %s\n", url);
			free(url);
		}

		unlink(tarfile);
		free(untard_file);
		free(tarfile);
	}

	return ret;
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
/* Bundle install one ore more bundles passed in bundles
 * param as a null terminated array of strings
 */
int install_bundles(char **bundles)
{
	int lock_fd;
	int ret = 0;
	int current_version;
	struct manifest *mom;
	struct list *iter;
	struct sub *sub;
	struct file *file;

	/* step 1: initialize swupd and get current version from OS */

	if (!init_globals()) {
		return EINIT_GLOBALS;
	}

	ret = swupd_init(&lock_fd);
	if (ret != 0) {
		printf("Failed updater initialization, exiting now.\n");
		return ret;
	}

	current_version = read_version_from_subvol_file(path_prefix);
	swupd_curl_set_current_version(current_version);

	/* first of all, make sure STATE_DIR is there, recreate if necessary*/
	ret = create_required_dirs();
	if (ret != 0) {
		printf("State directory %s cannot be recreated, aborting installation\n", STATE_DIR);
		goto clean_and_exit;
	}


	ret = load_manifests(current_version, current_version, "MoM", NULL, &mom);
	if (ret != 0) {
		printf("Cannot load official manifest MoM for version %i\n", current_version);
		ret = EMOM_NOTFOUND;
		goto clean_and_exit;
	}

	/* step 2: check bundle args are valid if so populate subs struct */

	int i;
	for (i = 0; *bundles; ++bundles) {
		if (is_tracked_bundle(*bundles)) {
			printf("%s bundle already installed, skipping it\n", *bundles);
			continue;
		}

		if (!manifest_has_component(mom, *bundles)) {
			printf("%s bundle name is invalid, skipping it...\n", *bundles);
			continue;
		}

		if (component_subscribed(*bundles)) {
			continue;
		}
		create_and_append_subscription(*bundles);
		i++;
		printf("Added bundle %s for installation\n", *bundles);
	}

	if (i == 0) {
		printf("There are no pending bundles to install, exiting now\n");
		ret = EBUNDLE_INSTALL;
		goto clean_manifest_and_exit;
	}

	subscription_versions_from_MoM(mom, 0);
	recurse_manifest(mom, NULL);
	consolidate_submanifests(mom);

	/* step 3: download neccessary packs */

	ret  = rm_staging_dir_contents("download");

	printf("Downloading required packs...\n");
	ret = download_subscribed_packs(0, current_version, true);
	if (ret != 0) {
		printf("pack downloads failed, cannot proceed with the installation, exiting.\n");
		goto clean_subs_and_exit;
	}

	/* step 4: 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);
		if (ret == 0) {
			rename_staged_file_to_final(file);
		}
	}

	sync();

	/* step 5: 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);
		}
	}

	/* Run any scripts that are needed to complete update */
	run_scripts();

	ret = 0;
	printf("Bundle(s) installation done.\n");

clean_subs_and_exit:
	free_subscriptions();
clean_manifest_and_exit:
	free_manifest(mom);
clean_and_exit:
	swupd_curl_cleanup();
	v_lockfile(lock_fd);
	dump_file_descriptor_leaks();
	free_globals();

	return ret;
}
Beispiel #4
0
/* download_manifests()
 * Description: To search Clear bundles for a particular entry, a complete set of
 *		manifests must be downloaded. This function does so, asynchronously, using
 *		the curl_multi interface */
static int download_manifests(struct manifest **MoM, struct list **subs)
{
	struct list *list = NULL;
	struct file *file = NULL;
	char *tarfile, *untard_file, *url = NULL;
	struct manifest *subMan = NULL;
	int current_version;
	int ret = 0;
	double size;
	bool did_download = false;

	current_version = get_current_version(path_prefix);
	if (current_version < 0) {
		fprintf(stderr, "Error: Unable to determine current OS version\n");
		return ECURRENT_VERSION;
	}

	*MoM = load_mom(current_version, false, false, NULL);
	if (!(*MoM)) {
		fprintf(stderr, "Cannot load official manifest MoM for version %i\n", current_version);
		return EMOM_LOAD;
	}

	list = (*MoM)->manifests;
	size = query_total_download_size(list);
	if (size == -1) {
		fprintf(stderr, "Downloading manifests. Expect a delay, up to 100MB may be downloaded\n");
	} else if (size > 0) {
		fprintf(stderr, "Downloading Clear Linux manifests\n");
		fprintf(stderr, "   %.2f MB total...\n\n", size);
	}

	while (list) {
		file = list->data;
		list = list->next;

		create_and_append_subscription(subs, file->filename);

		string_or_die(&untard_file, "%s/%i/Manifest.%s", state_dir, file->last_change,
			      file->filename);

		string_or_die(&tarfile, "%s/%i/Manifest.%s.tar", state_dir, file->last_change,
			      file->filename);

		if (access(untard_file, F_OK) == -1) {
			/* Do download */
			subMan = load_manifest(file->last_change, file, *MoM, false);
			if (!subMan) {
				fprintf(stderr, "Cannot load official manifest MoM for version %i\n", current_version);
			} else {
				did_download = true;
			}

			free_manifest(subMan);
		}

		if (access(untard_file, F_OK) == -1) {
			string_or_die(&url, "%s/%i/Manifest.%s.tar", content_url, current_version,
				      file->filename);

			fprintf(stderr, "Error: Failure reading from %s\n", url);
			free_string(&url);
		}

		unlink(tarfile);
		free_string(&untard_file);
		free_string(&tarfile);
	}

	if (did_download) {
		fprintf(stderr, "Completed manifests download.\n\n");
	}

	return ret;
}