Exemplo n.º 1
0
int rename_all_files_to_final(struct list *updates)
{
	int ret, update_errs = 0, update_good = 0, skip = 0;
	struct list *list;

	list = list_head(updates);
	while (list) {
		struct file *file;
		file = list->data;
		list = list->next;
		if (file->do_not_update) {
			skip += 1;
			continue;
		}

		ret = rename_staged_file_to_final(file);
		if (ret != 0) {
			update_errs += 1;
		} else {
			update_good += 1;
		}
	}

	return update_count - update_good - update_errs - (update_skip - skip);
}
Exemplo n.º 2
0
int rename_all_files_to_final(struct list *updates)
{
	int ret, update_errs = 0, update_good = 0, skip = 0;
	struct list *list;
	unsigned int complete = 0;
	unsigned int list_length = list_len(updates);

	list = list_head(updates);
	while (list) {
		struct file *file;
		file = list->data;
		list = list->next;
		complete++;
		if (file->do_not_update) {
			skip += 1;
			continue;
		}

		ret = rename_staged_file_to_final(file);
		if (ret != 0) {
			update_errs += 1;
		} else {
			update_good += 1;
		}

		print_progress(complete, list_length);
	}

	print_progress(list_length, list_length); /* Force out 100% */
	printf("\n");
	return update_count - update_good - update_errs - (update_skip - skip);
}
Exemplo n.º 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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
static void deal_with_hash_mismatches(struct manifest *official_manifest, bool repair)
{
	int ret;
	struct list *iter;

	/* for each expected and present file which hash-mismatches vs the manifest, replace the file */
	iter = list_head(official_manifest->files);
	while (iter) {
		struct file *file;
		char *fullname;

		file = iter->data;
		iter = iter->next;

		// Note: boot files not marked as deleted are candidates for verify/fix
		if (file->is_deleted ||
		    ignore(file)) {
			continue;
		}

		file_checked_count++;

		// do_not_update set by earlier check, so account as checked
		if (file->do_not_update) {
			continue;
		}

		/* compare the hash and report mismatch */
		fullname = mk_full_filename(path_prefix, file->filename);
		if (fullname == NULL) {
			abort();
		}
		if (verify_file(file, fullname)) {
			free(fullname);
			continue;
		} else {
			file_mismatch_count++;
			printf("Hash mismatch for file: %s\n", fullname);
		}

		/* if not repairing, we're done */
		if (!repair) {
			free(fullname);
			continue;
		}

		/* install the new file (on miscompare + fix) */
		ret = do_staging(file, official_manifest);
		if (ret == 0) {
			rename_staged_file_to_final(file);
		}

		/* at the end of all this, verify the hash again to judge success */
		if (verify_file(file, fullname)) {
			file_fixed_count++;
			printf("\tfixed\n");
		} else {
			file_not_fixed_count++;
			printf("\tnot fixed\n");
		}
		free(fullname);
	}
}
Exemplo n.º 7
0
/* for each missing but expected file, (re)add the file */
static void add_missing_files(struct manifest *official_manifest)
{
	int ret;
	struct file local;
	struct list *iter;

	iter = list_head(official_manifest->files);
	while (iter) {
		struct file *file;
		char *fullname;

		file = iter->data;
		iter = iter->next;

		if ((file->is_deleted) ||
		    (file->do_not_update)) {
			continue;
		}

		fullname = mk_full_filename(path_prefix, file->filename);
		if (fullname == NULL) {
			abort();
		}
		memset(&local, 0, sizeof(struct file));
		local.filename = file->filename;
		populate_file_struct(&local, fullname);
		ret = compute_hash_lazy(&local, fullname);
		if (ret != 0) {
			file_not_replaced_count++;
			free(fullname);
			continue;
		}

		/* compare the hash and report mismatch */
		if (hash_is_zeros(local.hash)) {
			file_missing_count++;
			if (cmdline_option_install == false) {
				printf("Missing file: %s\n", fullname);
			}
		} else {
			free(fullname);
			continue;
		}

		/* install the new file (on miscompare + fix) */
		ret = do_staging(file, official_manifest);
		if (ret == 0) {
			rename_staged_file_to_final(file);
		}

		/* verify the hash again to judge success */
		populate_file_struct(&local, fullname);
		if (cmdline_option_quick) {
			ret = compute_hash_lazy(&local, fullname);
		} else {
			ret = compute_hash(&local, fullname);
		}
		if ((ret != 0) || hash_needs_work(file, local.hash)) {
			file_not_replaced_count++;
			printf("\tnot fixed\n");
		} else {
			file_replaced_count++;
			file->do_not_update = 1;
			if (cmdline_option_install == false) {
				printf("\tfixed\n");
			}
		}
		free(fullname);
	}
}