Beispiel #1
0
gboolean
zypp_perform_execution (PkBackend *backend, PerformType type, gboolean force)
{
        try {
                zypp::ZYpp::Ptr zypp = get_zypp ();

                if (force)
                        zypp->resolver ()->setForceResolve (force);
		if (type == UPDATE) {
			//zypp->resolver ()->setOnlyRequires (TRUE);		
			zypp->resolver ()->setIgnoreAlreadyRecommended (TRUE);		
		}

                // Gather up any dependencies
		pk_backend_set_status (backend, PK_STATUS_ENUM_DEP_RESOLVE);
		if (zypp->resolver ()->resolvePool () == FALSE) {
                       // Manual intervention required to resolve dependencies
                       // TODO: Figure out what we need to do with PackageKit
                       // to pull off interactive problem solving.

			zypp::ResolverProblemList problems = zypp->resolver ()->problems ();
			gchar * emsg = NULL, * tempmsg = NULL;

			for (zypp::ResolverProblemList::iterator it = problems.begin (); it != problems.end (); it++){
				if (emsg == NULL) {
					emsg = g_strdup ((*it)->description ().c_str ());
				}
				else {
					tempmsg = emsg;
					emsg = g_strconcat (emsg, "\n", (*it)->description ().c_str (), NULL);
					g_free (tempmsg);
				}
			}

			// reset the status of all touched PoolItems
			zypp::ResPool pool = zypp::ResPool::instance ();
			for (zypp::ResPool::const_iterator it = pool.begin (); it != pool.end (); it++) {
				if (it->status ().isToBeInstalled ())
					it->statusReset ();
			}

			pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, emsg);
			g_free (emsg);
			zypp->resolver ()->setForceResolve (FALSE);
			return FALSE;
		}
        
                switch (type) {
                        case INSTALL:
                                pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
                                break;
                        case REMOVE:
                                pk_backend_set_status (backend, PK_STATUS_ENUM_REMOVE);
                                break;
                        case UPDATE:
                                pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE);
                                break;
                };

		// look for licenses to confirm

		zypp::ResPool pool = zypp::ResPool::instance ();
		for (zypp::ResPool::const_iterator it = pool.begin (); it != pool.end (); it++) {
			if (it->status ().isToBeInstalled () && !(it->satSolvable ().lookupStrAttribute (zypp::sat::SolvAttr::eula).empty ())) {
				gchar *eula_id = g_strdup ((*it)->name ().c_str ());
				gboolean has_eula = pk_backend_is_eula_valid (backend, eula_id);
				if (!has_eula) {
					gchar *package_id = zypp_build_package_id_from_resolvable (it->satSolvable ());
					pk_backend_eula_required (backend,
							eula_id,
							package_id,
							(*it)->vendor ().c_str (),
							it->satSolvable ().lookupStrAttribute (zypp::sat::SolvAttr::eula).c_str ()); 
					pk_backend_error_code (backend, PK_ERROR_ENUM_NO_LICENSE_AGREEMENT, "You've to agree/decline a license");
					g_free (package_id);
					g_free (eula_id);
					return FALSE;
				}
				g_free (eula_id);
			}
		}

                // Perform the installation
                zypp::ZYppCommitPolicy policy;
                policy.restrictToMedia (0);	// 0 - install all packages regardless to media

                zypp::ZYppCommitResult result = zypp->commit (policy);

                if(!result._errors.empty () || !result._remaining.empty () || !result._srcremaining.empty ()){
			
			zypp::ZYppCommitResult::PoolItemList errors = result._errors;
			gchar *emsg = NULL, *tmpmsg = NULL;

			for (zypp::ZYppCommitResult::PoolItemList::iterator it = errors.begin (); it != errors.end (); it++){
				if (emsg == NULL) {
					emsg = g_strdup ((*it)->name ().c_str ());
				}else{
					tmpmsg = emsg;
					emsg = g_strconcat (emsg, "\n", (*it)->name ().c_str (), NULL);
					g_free (tmpmsg);
				}
			}
			
			zypp::ZYppCommitResult::PoolItemList remaining = result._remaining;
			for (zypp::ZYppCommitResult::PoolItemList::iterator it = remaining.begin (); it != remaining.end (); it++){
				if (emsg == NULL) {
					emsg = g_strdup ((*it)->name ().c_str ());
				}else{
					tmpmsg = emsg;
					emsg = g_strconcat (emsg, "\n", (*it)->name ().c_str (), NULL);
					g_free (tmpmsg);
				}
			}
			
			zypp::ZYppCommitResult::PoolItemList srcremaining = result._srcremaining;
			for (zypp::ZYppCommitResult::PoolItemList::iterator it = srcremaining.begin (); it != srcremaining.end (); it++){
				if (emsg == NULL) {
					emsg = g_strdup ((*it)->name ().c_str ());
				}else{
					tmpmsg = emsg;
					emsg = g_strconcat (emsg, "\n", (*it)->name ().c_str (), NULL);
					g_free (tmpmsg);
				}
			}

                        pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_ERROR,
					"Transaction could not be completed.\n Theses packages could not be installed: %s",
					emsg);

			g_free (emsg);
			zypp->resolver ()->setForceResolve (FALSE);
                        return FALSE;
                }

		zypp->resolver ()->setForceResolve (FALSE);
		if (type == UPDATE) {
			zypp->resolver ()->setIgnoreAlreadyRecommended (FALSE);		
		}

        } catch (const zypp::repo::RepoNotFoundException &ex) {
		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, ex.asUserString().c_str() );
		return FALSE;
	} catch (const zypp::target::rpm::RpmException &ex) {
		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED, ex.asUserString().c_str () );
		return FALSE;
	} catch (const zypp::Exception &ex) {
		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, ex.asUserString().c_str() );
		return FALSE;
	}       
        
        return TRUE;
}
Beispiel #2
0
/**
 * pk_backend_spawn_parse_stdout:
 **/
static gboolean
pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line, GError **error)
{
	gchar **sections;
	guint size;
	gchar *command;
	gchar *text;
	gboolean ret = TRUE;
	guint64 speed;
	PkInfoEnum info;
	PkRestartEnum restart;
	PkGroupEnum group;
	gulong package_size;
	gint percentage;
	PkErrorEnum error_enum;
	PkStatusEnum status_enum;
	PkMessageEnum message_enum;
	PkRestartEnum restart_enum;
	PkSigTypeEnum sig_type;
	PkUpdateStateEnum update_state_enum;
	PkMediaTypeEnum media_type_enum;
	PkDistroUpgradeEnum distro_upgrade_enum;
	PkBackendSpawnPrivate *priv = backend_spawn->priv;

	g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE);

	/* check if output line */
	if (line == NULL)
		return FALSE;

	/* split by tab */
	sections = g_strsplit (line, "\t", 0);
	command = sections[0];

	/* get size */
	size = g_strv_length (sections);

	if (g_strcmp0 (command, "package") == 0) {
		if (size != 4) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (pk_package_id_check (sections[2]) == FALSE) {
			g_set_error_literal (error, 1, 0, "invalid package_id");
			ret = FALSE;
			goto out;
		}
		info = pk_info_enum_from_string (sections[1]);
		if (info == PK_INFO_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Info enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		pk_backend_package (priv->backend, info, sections[2], sections[3]);
	} else if (g_strcmp0 (command, "details") == 0) {
		if (size != 7) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		group = pk_group_enum_from_string (sections[3]);

		/* ITS4: ignore, checked for overflow */
		package_size = atol (sections[6]);
		if (package_size > 1073741824) {
			g_set_error_literal (error, 1, 0, "package size cannot be larger than one Gb");
			ret = FALSE;
			goto out;
		}
		text = g_strdup (sections[4]);
		/* convert ; to \n as we can't emit them on stdout */
		g_strdelimit (text, ";", '\n');
		pk_backend_details (priv->backend, sections[1], sections[2],
					group, text, sections[5], package_size);
		g_free (text);
	} else if (g_strcmp0 (command, "finished") == 0) {
		if (size != 1) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		pk_backend_finished (priv->backend);

		/* from this point on, we can start the kill timer */
		pk_backend_spawn_start_kill_timer (backend_spawn);

	} else if (g_strcmp0 (command, "files") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		pk_backend_files (priv->backend, sections[1], sections[2]);
	} else if (g_strcmp0 (command, "repo-detail") == 0) {
		if (size != 4) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (g_strcmp0 (sections[3], "true") == 0) {
			pk_backend_repo_detail (priv->backend, sections[1], sections[2], TRUE);
		} else if (g_strcmp0 (sections[3], "false") == 0) {
			pk_backend_repo_detail (priv->backend, sections[1], sections[2], FALSE);
		} else {
			g_set_error (error, 1, 0, "invalid qualifier '%s'", sections[3]);
			ret = FALSE;
			goto out;
		}
	} else if (g_strcmp0 (command, "updatedetail") == 0) {
		if (size != 13) {
			g_set_error (error, 1, 0, "invalid command '%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		restart = pk_restart_enum_from_string (sections[7]);
		if (restart == PK_RESTART_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[7]);
			ret = FALSE;
			goto out;
		}
		update_state_enum = pk_update_state_enum_from_string (sections[10]);
		/* convert ; to \n as we can't emit them on stdout */
		g_strdelimit (sections[8], ";", '\n');
		g_strdelimit (sections[9], ";", '\n');
		pk_backend_update_detail (priv->backend, sections[1],
					  sections[2], sections[3], sections[4],
					  sections[5], sections[6], restart, sections[8],
					  sections[9], update_state_enum,
					  sections[11], sections[12]);
	} else if (g_strcmp0 (command, "percentage") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		ret = pk_strtoint (sections[1], &percentage);
		if (!ret) {
			g_set_error (error, 1, 0, "invalid percentage value %s", sections[1]);
			ret = FALSE;
		} else if (percentage < 0 || percentage > 100) {
			g_set_error (error, 1, 0, "invalid percentage value %i", percentage);
			ret = FALSE;
		} else {
			pk_backend_set_percentage (priv->backend, percentage);
		}
	} else if (g_strcmp0 (command, "subpercentage") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		ret = pk_strtoint (sections[1], &percentage);
		if (!ret) {
			g_set_error (error, 1, 0, "invalid subpercentage value %s", sections[1]);
			ret = FALSE;
		} else if (percentage < 0 || percentage > 100) {
			g_set_error (error, 1, 0, "invalid subpercentage value %i", percentage);
			ret = FALSE;
		} else {
			pk_backend_set_sub_percentage (priv->backend, percentage);
		}
	} else if (g_strcmp0 (command, "item-percentage") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (!pk_package_id_check (sections[1])) {
			g_set_error (error, 1, 0, "invalid package_id");
			ret = FALSE;
			goto out;
		}
		ret = pk_strtoint (sections[2], &percentage);
		if (!ret) {
			g_set_error (error, 1, 0, "invalid item-percentage value %s", sections[1]);
			ret = FALSE;
		} else if (percentage < 0 || percentage > 100) {
			g_set_error (error, 1, 0, "invalid item-percentage value %i", percentage);
			ret = FALSE;
		} else {
			pk_backend_set_item_progress (priv->backend,
							sections[1],
							percentage);
		}
	} else if (g_strcmp0 (command, "error") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		error_enum = pk_error_enum_from_string (sections[1]);
		if (error_enum == PK_ERROR_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Error enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		/* convert back all the ;'s to newlines */
		text = g_strdup (sections[2]);

		/* convert ; to \n as we can't emit them on stdout */
		g_strdelimit (text, ";", '\n');

		/* convert % else we try to format them */
		g_strdelimit (text, "%", '$');

		pk_backend_error_code (priv->backend, error_enum, text);
		g_free (text);
	} else if (g_strcmp0 (command, "requirerestart") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		restart_enum = pk_restart_enum_from_string (sections[1]);
		if (restart_enum == PK_RESTART_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		if (!pk_package_id_check (sections[2])) {
			g_set_error (error, 1, 0, "invalid package_id");
			ret = FALSE;
			goto out;
		}
		pk_backend_require_restart (priv->backend, restart_enum, sections[2]);
	} else if (g_strcmp0 (command, "message") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		message_enum = pk_message_enum_from_string (sections[1]);
		if (message_enum == PK_MESSAGE_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Message enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		text = g_strdup (sections[2]);
		/* convert ; to \n as we can't emit them on stdout */
		g_strdelimit (text, ";", '\n');
		pk_backend_message (priv->backend, message_enum, text);
		g_free (text);
	} else if (g_strcmp0 (command, "change-transaction-data") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		pk_backend_set_transaction_data (priv->backend, sections[1]);
	} else if (g_strcmp0 (command, "status") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		status_enum = pk_status_enum_from_string (sections[1]);
		if (status_enum == PK_STATUS_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		pk_backend_set_status (priv->backend, status_enum);
	} else if (g_strcmp0 (command, "speed") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		ret = pk_strtouint64 (sections[1], &speed);
		if (!ret) {
			g_set_error (error, 1, 0,
				     "failed to parse speed: '%s'",
				     sections[1]);
			ret = FALSE;
			goto out;
		}
		pk_backend_set_speed (priv->backend, speed);
	} else if (g_strcmp0 (command, "allow-cancel") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (g_strcmp0 (sections[1], "true") == 0) {
			pk_backend_set_allow_cancel (priv->backend, TRUE);
		} else if (g_strcmp0 (sections[1], "false") == 0) {
			pk_backend_set_allow_cancel (priv->backend, FALSE);
		} else {
			g_set_error (error, 1, 0, "invalid section '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
	} else if (g_strcmp0 (command, "no-percentage-updates") == 0) {
		if (size != 1) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		pk_backend_set_percentage (priv->backend, PK_BACKEND_PERCENTAGE_INVALID);
	} else if (g_strcmp0 (command, "repo-signature-required") == 0) {

		if (size != 9) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}

		sig_type = pk_sig_type_enum_from_string (sections[8]);
		if (sig_type == PK_SIGTYPE_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Sig enum not recognised, and hence ignored: '%s'", sections[8]);
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[1])) {
			g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[2])) {
			g_set_error (error, 1, 0, "repository name blank, and hence ignored: '%s'", sections[2]);
			ret = FALSE;
			goto out;
		}

		/* pass _all_ of the data */
		ret = pk_backend_repo_signature_required (priv->backend, sections[1],
							  sections[2], sections[3], sections[4],
							  sections[5], sections[6], sections[7], sig_type);
		goto out;

	} else if (g_strcmp0 (command, "eula-required") == 0) {

		if (size != 5) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}

		if (pk_strzero (sections[1])) {
			g_set_error (error, 1, 0, "eula_id blank, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}

		if (pk_strzero (sections[2])) {
			g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[2]);
			ret = FALSE;
			goto out;
		}

		if (pk_strzero (sections[4])) {
			g_set_error (error, 1, 0, "agreement name blank, and hence ignored: '%s'", sections[4]);
			ret = FALSE;
			goto out;
		}

		ret = pk_backend_eula_required (priv->backend, sections[1], sections[2], sections[3], sections[4]);
		goto out;

	} else if (g_strcmp0 (command, "media-change-required") == 0) {

		if (size != 4) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}

		media_type_enum = pk_media_type_enum_from_string (sections[1]);
		if (media_type_enum == PK_MEDIA_TYPE_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "media type enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}

		ret = pk_backend_media_change_required (priv->backend, media_type_enum, sections[2], sections[3]);
		goto out;
	} else if (g_strcmp0 (command, "distro-upgrade") == 0) {

		if (size != 4) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}

		distro_upgrade_enum = pk_distro_upgrade_enum_from_string (sections[1]);
		if (distro_upgrade_enum == PK_DISTRO_UPGRADE_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "distro upgrade enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}

		ret = pk_backend_distro_upgrade (priv->backend, distro_upgrade_enum, sections[2], sections[3]);
		goto out;
	} else if (g_strcmp0 (command, "category") == 0) {

		if (size != 6) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (g_strcmp0 (sections[1], sections[2]) == 0) {
			g_set_error_literal (error, 1, 0, "cat_id cannot be the same as parent_id");
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[2])) {
			g_set_error_literal (error, 1, 0, "cat_id cannot not blank");
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[3])) {
			g_set_error_literal (error, 1, 0, "name cannot not blank");
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[5])) {
			g_set_error_literal (error, 1, 0, "icon cannot not blank");
			ret = FALSE;
			goto out;
		}
		if (g_str_has_prefix (sections[5], "/")) {
			g_set_error (error, 1, 0, "icon '%s' should be a named icon, not a path", sections[5]);
			ret = FALSE;
			goto out;
		}
		ret = pk_backend_category (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]);
		goto out;
	} else {
		ret = FALSE;
		g_set_error (error, 1, 0, "invalid command '%s'", command);
	}
out:
	g_strfreev (sections);
	return ret;
}