PackageKit/PackageKit-openSUSE-branch.patch

482 lines
17 KiB
Diff

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 746da82..4da636b 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -26,6 +26,7 @@
#include <pk-debug.h>
#include <string>
#include <set>
+#include <glib/gi18n.h>
#include <zypp/ZYppFactory.h>
#include <zypp/ResObject.h>
@@ -47,7 +48,6 @@
#include <zypp/target/rpm/RpmDb.h>
#include <zypp/target/rpm/RpmHeader.h>
#include <zypp/target/rpm/RpmException.h>
-#include <zypp/base/LogControl.h>
#include <zypp/TmpPath.h>
#include <zypp/sat/Solvable.h>
@@ -90,12 +90,13 @@ std::map<PkBackend *, std::vector<std::string> *> _signatures;
static void
backend_initialize (PkBackend *backend)
{
- zypp::base::LogControl::instance ().logfile("/var/log/pk_backend_zypp");
+ zypp_logging ();
pk_debug ("zypp_backend_initialize");
EventDirector *eventDirector = new EventDirector (backend);
_eventDirectors [backend] = eventDirector;
std::vector<std::string> *signature = new std::vector<std::string> ();
_signatures [backend] = signature;
+ _updating_self = FALSE;
}
/**
@@ -403,7 +404,7 @@ backend_get_depends_thread (PkBackend *backend)
package_id_temp = pk_package_id_build (it->second.name ().c_str(),
it->second.edition ().asString ().c_str(),
it->second.arch ().c_str(),
- it->second.repository ().name ().c_str());
+ it->second.repository ().alias ().c_str());
zypp::PoolItem item = zypp::ResPool::instance ().find (it->second);
@@ -570,6 +571,32 @@ backend_refresh_cache (PkBackend *backend, gboolean force)
pk_backend_thread_create (backend, backend_refresh_cache_thread);
}
+/* If a critical self update (see qualifying steps below) is available then only show/install that update first.
+ 1. there is a patch available with the <restart_suggested> tag set
+ 2. The patch contains the package "PackageKit" or "gnome-packagekit
+*/
+/*static gboolean
+check_for_self_update (PkBackend *backend, std::set<zypp::PoolItem> *candidates)
+{
+ std::set<zypp::PoolItem>::iterator cb = candidates->begin (), ce = candidates->end (), ci;
+ for (ci = cb; ci != ce; ++ci) {
+ zypp::ResObject::constPtr res = ci->resolvable();
+ if (zypp::isKind<zypp::Patch>(res)) {
+ zypp::Patch::constPtr patch = zypp::asKind<zypp::Patch>(res);
+ //pk_debug ("restart_suggested is %d",(int)patch->restartSuggested());
+ if (patch->restartSuggested ()) {
+ if (!strcmp (PACKAGEKIT_RPM_NAME, res->satSolvable ().name ().c_str ()) ||
+ !strcmp (GNOME_PACKAGKEKIT_RPM_NAME, res->satSolvable ().name ().c_str ())) {
+ g_free (update_self_patch_name);
+ update_self_patch_name = zypp_build_package_id_from_resolvable (res->satSolvable ());
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}*/
+
static gboolean
backend_get_updates_thread (PkBackend *backend)
{
@@ -586,12 +613,26 @@ backend_get_updates_thread (PkBackend *backend)
pk_backend_set_percentage (backend, 40);
// get all Packages and Patches for Update
- std::set<zypp::PoolItem> *candidates = zypp_get_updates ();
- std::set<zypp::PoolItem> *candidates2 = zypp_get_patches ();
+ std::set<zypp::PoolItem> *candidates = zypp_get_patches ();
+ std::set<zypp::PoolItem> *candidates2 = new std::set<zypp::PoolItem> ();
+
+ if (!_updating_self) {
+ //disabling patchrepo
+ zypp::RepoInfo patchRepo;
+ if (!candidates->empty ()) {
+ patchRepo = candidates->begin ()->resolvable ()->repoInfo ();
+ patchRepo.setEnabled (FALSE);
+ }
+
+ candidates2 = zypp_get_updates ();
+ //enable patchRepo
+ patchRepo.setEnabled (TRUE);
- candidates->insert (candidates2->begin (), candidates2->end ());
+ candidates->insert (candidates2->begin (), candidates2->end ());
+ }
pk_backend_set_percentage (backend, 80);
+
std::set<zypp::PoolItem>::iterator cb = candidates->begin (), ce = candidates->end (), ci;
for (ci = cb; ci != ce; ++ci) {
zypp::ResObject::constPtr res = ci->resolvable();
@@ -716,7 +757,7 @@ backend_install_files_thread (PkBackend *backend)
gboolean found = FALSE;
for (std::vector<zypp::sat::Solvable>::iterator it = solvables->begin (); it != solvables->end (); it ++) {
- if (it->repository ().name () == "PK_TMP_DIR") {
+ if (it->repository ().alias () == "PK_TMP_DIR") {
item = new zypp::PoolItem(*it);
found = TRUE;
break;
@@ -861,14 +902,31 @@ backend_update_system_thread (PkBackend *backend)
zypp::ResPool pool = zypp_build_pool (TRUE);
pk_backend_set_percentage (backend, 40);
- // get all Packages for Update
- std::set<zypp::PoolItem> *candidates = zypp_get_updates ();
//get all Patches for Update
- std::set<zypp::PoolItem> *candidates2 = zypp_get_patches ();
+ std::set<zypp::PoolItem> *candidates = zypp_get_patches ();
+ std::set<zypp::PoolItem> *candidates2 = new std::set<zypp::PoolItem> ();
+
+ if (_updating_self) {
+ pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, _("Package Management System updated - restart needed"));
+ _updating_self = FALSE;
+ }
+ else {
+ //disabling patchrepo
+ zypp::RepoInfo patchRepo;
+ if (!candidates->empty ()) {
+ patchRepo = candidates->begin ()->resolvable ()->repoInfo ();
+ patchRepo.setEnabled (FALSE);
+ }
+
+ //get all Updates
+ candidates2 = zypp_get_updates ();
+ //enable patchRepo
+ patchRepo.setEnabled (TRUE);// get all Packages for Update
- //concatenate these sets
+ //concatenate these sets
- candidates->insert (candidates->begin (), candidates->end ());
+ candidates->insert (candidates2->begin (), candidates2->end ());
+ }
pk_backend_set_percentage (backend, 80);
std::set<zypp::PoolItem>::iterator cb = candidates->begin (), ce = candidates->end (), ci;
@@ -1463,6 +1521,13 @@ backend_update_packages_thread (PkBackend *backend)
gchar **package_ids;
package_ids = pk_backend_get_strv (backend, "package_ids");
+ zypp_get_patches (); // make shure _updating_self is set
+
+ if (_updating_self) {
+ pk_debug ("updating self and setting restart");
+ pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, _("Package Management System updated - restart needed"));
+ _updating_self = FALSE;
+ }
for (guint i = 0; i < g_strv_length (package_ids); i++) {
zypp::sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]);
zypp::PoolItem item = zypp::ResPool::instance ().find (solvable);
diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index e25b5c3..2a84a3b 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -1,6 +1,8 @@
#include <sstream>
#include <stdlib.h>
#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
#include <zypp/ZYpp.h>
#include <zypp/ZYppFactory.h>
#include <zypp/RepoManager.h>
@@ -21,6 +23,7 @@
#include <zypp/target/rpm/RpmDb.h>
#include <zypp/target/rpm/RpmHeader.h>
#include <zypp/target/rpm/librpmDb.h>
+#include <zypp/base/LogControl.h>
#include <zypp/base/Logger.h>
@@ -29,6 +32,7 @@
#include "zypp-utils.h"
gchar * _repoName;
+gboolean _updating_self = FALSE;
/**
* Collect items, select best edition. This is used to find the best
* available or installed. The name of the class is a bit misleading though ...
@@ -74,6 +78,34 @@ get_zypp ()
return zypp;
}
+/**
+ * Enable and rotate zypp logging
+ */
+gboolean
+zypp_logging ()
+{
+ gchar *file = g_strdup ("/var/log/pk_backend_zypp");
+ gchar *file_old = g_strdup ("/var/log/pk_backend_zypp-1");
+
+ if (g_file_test (file, G_FILE_TEST_EXISTS)) {
+ struct stat buffer;
+ g_stat (file, &buffer);
+ // if the file is bigger than 10 MB rotate
+ if ((guint)buffer.st_size > 10485760) {
+ if (g_file_test (file_old, G_FILE_TEST_EXISTS))
+ g_remove (file_old);
+ g_rename (file, file_old);
+ }
+ }
+
+ zypp::base::LogControl::instance ().logfile(file);
+
+ g_free (file);
+ g_free (file_old);
+
+ return TRUE;
+}
+
gboolean
zypp_is_changeable_media (const zypp::Url &url)
{
@@ -96,13 +128,13 @@ zypp_build_pool (gboolean include_local)
zypp::ZYpp::Ptr zypp = get_zypp ();
if (include_local == TRUE) {
- //FIXME have to wait for fix in zypp (repeated loading of target)
- if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoName() ).solvablesEmpty ())
- {
- // Add local resolvables
- zypp::Target_Ptr target = zypp->target ();
- target->load ();
- }
+ //FIXME have to wait for fix in zypp (repeated loading of target)
+ if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoAlias() ).solvablesEmpty ())
+ {
+ // Add local resolvables
+ zypp::Target_Ptr target = zypp->target ();
+ target->load ();
+ }
}
// Add resolvables from enabled repos
@@ -139,16 +171,16 @@ zypp_build_pool (gboolean include_local)
zypp::ResPool
zypp_build_local_pool ()
{
- zypp::sat::Pool pool = zypp::sat::Pool::instance ();
+ zypp::sat::Pool pool = zypp::sat::Pool::instance ();
zypp::ZYpp::Ptr zypp = get_zypp ();
try {
for (zypp::detail::RepositoryIterator it = pool.reposBegin (); it != pool.reposEnd (); it++){
if (! it->isSystemRepo ())
- pool.reposErase(it->name ());
+ pool.reposErase(it->alias ());
}
- if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoName() ).solvablesEmpty ())
+ if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoAlias() ).solvablesEmpty ())
{
// Add local resolvables
zypp::Target_Ptr target = zypp->target ();
@@ -347,27 +379,49 @@ zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable)
package_id = pk_package_id_build (resolvable.name ().c_str (),
resolvable.edition ().asString ().c_str (),
resolvable.arch ().asString ().c_str (),
- resolvable.repository (). name().c_str ());
+ resolvable.repository (). alias().c_str ());
return package_id;
}
+zypp::RepoInfo
+zypp_get_Repository (PkBackend *backend, const gchar *alias)
+{
+ zypp::RepoInfo info;
+
+ try {
+ zypp::RepoManager manager;
+ info = manager.getRepositoryInfo (alias);
+ } catch (const zypp::repo::RepoNotFoundException &ex) {
+ pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, ex.asUserString().c_str() );
+ return zypp::RepoInfo ();
+ }
+
+ return info;
+}
+
gboolean
zypp_signature_required (PkBackend *backend, const zypp::PublicKey &key)
{
gboolean ok = FALSE;
if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), key.id ()) == _signatures[backend]->end ()) {
+ zypp::RepoInfo info = zypp_get_Repository (backend, _repoName);
+ if (info.type () == zypp::repo::RepoType::NONE) {
+ pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown");
+ return FALSE;
+ }
+
pk_backend_repo_signature_required (backend,
"dummy;0.0.1;i386;data",
_repoName,
- key.path ().c_str (),
- key.id ().c_str (),
+ info.baseUrlsBegin ()->asString ().c_str (),
+ key.name ().c_str (),
key.id ().c_str (),
key.fingerprint ().c_str (),
key.created ().asString ().c_str (),
PK_SIGTYPE_ENUM_GPG);
- pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed");
+ pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
}else{
ok = TRUE;
}
@@ -381,16 +435,22 @@ zypp_signature_required (PkBackend *backend, const std::string &file, const std:
gboolean ok = FALSE;
if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), id) == _signatures[backend]->end ()) {
+ zypp::RepoInfo info = zypp_get_Repository (backend, _repoName);
+ if (info.type () == zypp::repo::RepoType::NONE) {
+ pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown");
+ return FALSE;
+ }
+
pk_backend_repo_signature_required (backend,
"dummy;0.0.1;i386;data",
_repoName,
- file.c_str (),
+ info.baseUrlsBegin ()->asString ().c_str (),
id.c_str (),
id.c_str (),
"UNKNOWN",
"UNKNOWN",
PK_SIGTYPE_ENUM_GPG);
- pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed");
+ pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
}else{
ok = TRUE;
}
@@ -404,16 +464,22 @@ zypp_signature_required (PkBackend *backend, const std::string &file)
gboolean ok = FALSE;
if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), file) == _signatures[backend]->end ()) {
- pk_backend_repo_signature_required (backend,
+ zypp::RepoInfo info = zypp_get_Repository (backend, _repoName);
+ if (info.type () == zypp::repo::RepoType::NONE) {
+ pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown");
+ return FALSE;
+ }
+
+ pk_backend_repo_signature_required (backend,
"dummy;0.0.1;i386;data",
_repoName,
- file.c_str (),
+ info.baseUrlsBegin ()->asString ().c_str (),
"UNKNOWN",
file.c_str (),
"UNKNOWN",
"UNKNOWN",
PK_SIGTYPE_ENUM_GPG);
- pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed");
+ pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
}else{
ok = TRUE;
}
@@ -528,6 +594,7 @@ std::set<zypp::PoolItem> *
zypp_get_patches ()
{
std::set<zypp::PoolItem> *patches = new std::set<zypp::PoolItem> ();
+ _updating_self = FALSE;
zypp::ZYpp::Ptr zypp;
zypp = get_zypp ();
@@ -537,8 +604,18 @@ zypp_get_patches ()
for (zypp::ResPoolProxy::const_iterator it = zypp->poolProxy ().byKindBegin<zypp::Patch>();
it != zypp->poolProxy ().byKindEnd<zypp::Patch>(); it ++) {
// check if patch is needed
- if((*it)->candidateObj ().isBroken())
+ if((*it)->candidateObj ().isBroken()) {
patches->insert ((*it)->candidateObj ());
+ zypp::Patch::constPtr patch = zypp::asKind<zypp::Patch>((*it)->candidateObj ().resolvable ());
+
+ // check if the patch updates libzypp or packageKit and show only this one
+ if (patch->restartSuggested ()) {
+ _updating_self = TRUE;
+ patches->clear ();
+ patches->insert ((*it)->candidateObj ());
+ break;
+ }
+ }
}
diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h
index 01a972a..0282aa4 100644
--- a/backends/zypp/zypp-utils.h
+++ b/backends/zypp/zypp-utils.h
@@ -38,6 +38,11 @@ typedef enum {
*/
extern std::map<PkBackend *, std::vector<std::string> *> _signatures;
+/** Used to show/install only an update to ourself. This way if we find a critical bug
+ * in the way we update packages we will install the fix before any other updates.
+ */
+extern gboolean _updating_self;
+
/** A string to store the last refreshed repo
* this is needed for gpg-key handling stuff (UGLY HACK)
* FIXME
@@ -46,6 +51,11 @@ extern gchar *_repoName;
zypp::ZYpp::Ptr get_zypp ();
+/**
+ * Enable and rotate logging
+ */
+gboolean zypp_logging ();
+
gboolean zypp_is_changeable_media (const zypp::Url &url);
/**
@@ -101,6 +111,12 @@ zypp::sat::Solvable zypp_get_package_by_id (const gchar *package_id);
gchar * zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable);
/**
+ * Get the RepoInfo
+ */
+zypp::RepoInfo
+zypp_get_Repository (PkBackend *backend, const gchar *alias);
+
+/**
* Ask the User if it is OK to import an GPG-Key for a repo
*/
gboolean zypp_signature_required (PkBackend *backend, const zypp::PublicKey &key);
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index dd2387b..5d07e45 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -412,6 +412,10 @@ pk_client_finished_cb (DBusGProxy *proxy, const gchar *exit_text, guint runtime,
g_return_if_fail (PK_IS_CLIENT (client));
+ /* ref in case we unref the PkClient in ::finished --
+ * see https://bugzilla.novell.com/show_bug.cgi?id=390929 for rationale */
+ g_object_ref (client);
+
exit = pk_exit_enum_from_text (exit_text);
pk_debug ("emit finished %s, %i", exit_text, runtime);
@@ -420,16 +424,13 @@ pk_client_finished_cb (DBusGProxy *proxy, const gchar *exit_text, guint runtime,
g_signal_emit (client, signals [PK_CLIENT_FINISHED], 0, exit, runtime);
- /* check we are still valid */
- if (!PK_IS_CLIENT (client)) {
- pk_debug ("client was g_object_unref'd in finalise, object no longer valid");
- return;
- }
-
/* exit our private loop */
if (client->priv->synchronous) {
g_main_loop_quit (client->priv->loop);
}
+
+ /* unref what we previously ref'd */
+ g_object_unref (client);
}
/**