Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.3
PackageKit
0004-zypp-use-the-right-functions-to-get-solvab...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0004-zypp-use-the-right-functions-to-get-solvables.patch of Package PackageKit
From 3d07320cd618f4a6edb7bf806d144f39a31c8245 Mon Sep 17 00:00:00 2001 From: Stephan Kulow <coolo@suse.de> Date: Fri, 18 Jan 2013 11:25:14 +0100 Subject: [PATCH] zypp: use the right functions to get solvables package_ids are unique in the system, so there is no need to have special logic to find the pool items matching in most threads. Smaller fixes here and there too. --- backends/zypp/pk-backend-zypp.cpp | 450 ++++++++++---------------------------- backends/zypp/zypp-events.h | 48 ++-- backends/zypp/zypp-utils.cpp | 118 +++++----- backends/zypp/zypp-utils.h | 20 +- 4 files changed, 220 insertions(+), 416 deletions(-) diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp index 493ca6c..05a3662 100644 --- a/backends/zypp/pk-backend-zypp.cpp +++ b/backends/zypp/pk-backend-zypp.cpp @@ -129,12 +129,6 @@ pk_backend_initialize (PkBackend *backend) priv->currentJob = 0; zypp_logging (); - /* BACKEND MAINTAINER: feel free to remove this when you've - * added support for ONLY_DOWNLOAD and merged the simulate - * methods as specified in backends/PORTING.txt */ - /*g_error ("Backend needs to be ported to 0.8.x -- " - "see backends/PORTING.txt for details"); */ - g_debug ("zypp_backend_initialize"); //_updating_self = FALSE; } @@ -152,6 +146,13 @@ pk_backend_destroy (PkBackend *backend) delete priv; } + +static bool +zypp_is_no_solvable (const sat::Solvable &solv) +{ + return solv.id() == sat::detail::noSolvableId; +} + /** * backend_get_requires_thread: */ @@ -162,13 +163,11 @@ backend_get_requires_thread (PkBackendJob *job, GVariant *params, gpointer user_ PkBitfield _filters; gchar **package_ids; - bool recursive; + gboolean recursive; g_variant_get(params, "(t^a&sb)", - &_filters, - &package_ids, - &recursive); - - PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); + &_filters, + &package_ids, + &recursive); ZyppJob zjob(job); ZYpp::Ptr zypp = zjob.get_zypp(); @@ -178,57 +177,29 @@ backend_get_requires_thread (PkBackendJob *job, GVariant *params, gpointer user_ return; } - if (!pk_package_ids_check (package_ids)) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); - return; - } - pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); - //TODO repair percentages - //pk_backend_job_set_percentage (job, 0); + pk_backend_job_set_percentage (job, 10); PoolStatusSaver saver; ResPool pool = zypp_build_pool (zypp, true); for (uint i = 0; package_ids[i]; i++) { - sat::Solvable solvable = zypp_get_package_by_id (backend, package_ids[i]); - PoolItem package; - - if (solvable.isSystem ()) { - gboolean found = FALSE; - gchar **id_parts = pk_package_id_split (package_ids[i]); - - for (ResPool::byIdent_iterator it = pool.byIdentBegin (ResKind::package, id_parts[PK_PACKAGE_ID_NAME]); - it != pool.byIdentEnd (ResKind::package, id_parts[PK_PACKAGE_ID_NAME]); ++it) { - if (it->status ().isInstalled ()) { - package = (*it); - found = TRUE; - } - } - g_strfreev (id_parts); + sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]); - if (!found) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, - "Package is not installed"); - return; - } + if (zypp_is_no_solvable(solvable)) { + zypp_backend_finished_error (job, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, + "Package couldn't be found"); + return; + } - // set Package as to be uninstalled - package.status ().setToBeUninstalled (ResStatus::USER); - } else { - if (solvable == sat::Solvable::noSolvable) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, - "Package couldn't be found"); - return; - } + PoolItem package = PoolItem(solvable); - package = PoolItem(solvable); - //set Package as to be installed - package.status ().setToBeInstalled (ResStatus::USER); - } + // get-requires only works for installed packages. It's meaningless for stuff in the repo + // same with yum backend + if (!solvable.isSystem ()) + continue; + // set Package as to be uninstalled + package.status ().setToBeUninstalled (ResStatus::USER); // solver run ResPool pool = ResPool::instance (); @@ -238,13 +209,14 @@ backend_get_requires_thread (PkBackendJob *job, GVariant *params, gpointer user_ solver.setIgnoreAlreadyRecommended (TRUE); if (!solver.resolvePool ()) { + string problem = "Resolution failed: "; list<ResolverProblem_Ptr> problems = solver.problems (); for (list<ResolverProblem_Ptr>::iterator it = problems.begin (); it != problems.end (); ++it){ - g_warning("Solver problem (This should never happen): '%s'", (*it)->description ().c_str ()); + problem += (*it)->description (); } zypp_backend_finished_error ( job, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, - "Resolution failed"); + problem.c_str()); return; } @@ -313,12 +285,6 @@ pk_backend_get_filters (PkBackend *backend) -1); } -static bool -zypp_is_no_solvable (const sat::Solvable &solv) -{ - return solv.id() == sat::detail::noSolvableId; -} - /* * This method is a bit of a travesty of the complexity of * solving dependencies. We try to give a simple answer to @@ -328,8 +294,6 @@ zypp_is_no_solvable (const sat::Solvable &solv) static void backend_get_depends_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { - MIL << endl; - PkBitfield _filters; gchar **package_ids; gboolean recursive; @@ -341,13 +305,6 @@ backend_get_depends_thread (PkBackendJob *job, GVariant *params, gpointer user_d pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); pk_backend_job_set_percentage (job, 0); - if (!pk_package_ids_check (package_ids)) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, - "invalid package id"); - return; - } - ZyppJob zjob(job); ZYpp::Ptr zypp = zjob.get_zypp(); @@ -355,42 +312,16 @@ backend_get_depends_thread (PkBackendJob *job, GVariant *params, gpointer user_d pk_backend_job_finished (job); return; } - - g_debug ("get_depends with filter '%s'", pk_filter_bitfield_to_string (_filters)); + + MIL << pk_filter_bitfield_to_string (_filters) << endl; try { - gchar **id_parts = pk_package_id_split (package_ids[0]); + sat::Solvable solvable = zypp_get_package_by_id(package_ids[0]); + pk_backend_job_set_percentage (job, 20); - // Load resolvables from all the enabled repositories - ResPool pool = zypp_build_pool (zypp, true); - - PoolItem pool_item; - gboolean pool_item_found = FALSE; - // Iterate over the resolvables and mark the one we want to check its dependencies - for (ResPool::byIdent_iterator it = pool.byIdentBegin (ResKind::package, id_parts[PK_PACKAGE_ID_NAME]); - it != pool.byIdentEnd (ResKind::package, id_parts[PK_PACKAGE_ID_NAME]); ++it) { - PoolItem selectable = *it; - if (strcmp (selectable->name().c_str(), id_parts[PK_PACKAGE_ID_NAME]) == 0) { - // This package matches the name we're looking - char *edition_str = g_strdup (selectable->edition ().asString ().c_str()); - - if (strcmp (edition_str, id_parts[PK_PACKAGE_ID_VERSION]) == 0) { - g_free (edition_str); - // this is the one, mark it to be installed - pool_item = selectable; - pool_item_found = TRUE; - pk_backend_job_set_percentage (job, 20); - break; // Found it, get out of the for loop - } - g_free (edition_str); - } - } - g_strfreev (id_parts); - pk_backend_job_set_percentage (job, 40); - - if (!pool_item_found) { + if (zypp_is_no_solvable(solvable)) { zypp_backend_finished_error ( job, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, "Did not find the specified package."); @@ -402,8 +333,6 @@ backend_get_depends_thread (PkBackendJob *job, GVariant *params, gpointer user_d pk_backend_job_set_percentage (job, 60); // get dependencies - - sat::Solvable solvable = pool_item.satSolvable (); Capabilities req = solvable[Dep::REQUIRES]; // which package each capability @@ -518,8 +447,6 @@ backend_get_details_thread (PkBackendJob *job, GVariant *params, gpointer user_d g_variant_get (params, "(^a&s)", &package_ids); - PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); - ZyppJob zjob(job); ZYpp::Ptr zypp = zjob.get_zypp(); @@ -528,36 +455,11 @@ backend_get_details_thread (PkBackendJob *job, GVariant *params, gpointer user_d return; } - if (!pk_package_ids_check (package_ids)) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); - return; - } pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); for (uint i = 0; package_ids[i]; i++) { - gchar **id_parts = pk_package_id_split (package_ids[i]); - - vector<sat::Solvable> v; - vector<sat::Solvable> v2; - vector<sat::Solvable> v3; - zypp_get_packages_by_name (backend, (const gchar *)id_parts[PK_PACKAGE_ID_NAME], ResKind::package, v); - zypp_get_packages_by_name (backend, (const gchar *)id_parts[PK_PACKAGE_ID_NAME], ResKind::patch, v2); - zypp_get_packages_by_name (backend, (const gchar *)id_parts[PK_PACKAGE_ID_NAME], ResKind::srcpackage, v3); - v.insert (v.end (), v2.begin (), v2.end ()); - v.insert (v.end (), v3.begin (), v3.end ()); - - sat::Solvable solv; - for (vector<sat::Solvable>::iterator it = v.begin (); - it != v.end (); ++it) { - if (zypp_ver_and_arch_equal (*it, id_parts[PK_PACKAGE_ID_VERSION], - id_parts[PK_PACKAGE_ID_ARCH])) { - solv = *it; - break; - } - } - g_strfreev (id_parts); + sat::Solvable solv = zypp_get_package_by_id( package_ids[i] ); ResObject::constPtr obj = make<ResObject>( solv ); if (obj == NULL) { @@ -924,8 +826,6 @@ backend_get_update_detail_thread (PkBackendJob *job, GVariant *params, gpointer g_variant_get (params, "(^a&s)", &package_ids); - PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); - if (zypp == NULL){ pk_backend_job_finished (job); return; @@ -939,7 +839,8 @@ backend_get_update_detail_thread (PkBackendJob *job, GVariant *params, gpointer pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); for (uint i = 0; package_ids[i]; i++) { - sat::Solvable solvable = zypp_get_package_by_id (backend, package_ids[i]); + sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]); + MIL << package_ids[i] << " " << solvable << endl; Capabilities obs = solvable.obsoletes (); @@ -1018,10 +919,10 @@ backend_install_packages_thread (PkBackendJob *job, GVariant *params, gpointer u PkBitfield transaction_flags = 0; gchar **package_ids; - + g_variant_get(params, "(t^a&s)", - &transaction_flags, - &package_ids); + &transaction_flags, + &package_ids); ZyppJob zjob(job); ZYpp::Ptr zypp = zjob.get_zypp(); @@ -1039,12 +940,6 @@ backend_install_packages_thread (PkBackendJob *job, GVariant *params, gpointer u pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); pk_backend_job_set_percentage (job, 0); - if (!pk_package_ids_check (package_ids)) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); - return; - } - try { ResPool pool = zypp_build_pool (zypp, TRUE); @@ -1053,58 +948,17 @@ backend_install_packages_thread (PkBackendJob *job, GVariant *params, gpointer u guint to_install = 0; for (guint i = 0; package_ids[i]; i++) { - gchar **id_parts = pk_package_id_split (package_ids[i]); - - // Iterate over the selectables and mark the one with the right name - ui::Selectable::constPtr selectable; - string name = id_parts[PK_PACKAGE_ID_NAME]; - - // Do we have this installed ? - gboolean system = false; - for (ResPool::byName_iterator it = pool.byNameBegin (name); - it != pool.byNameEnd (name); ++it) { - - g_debug ("PoolItem '%s'", it->satSolvable().asString().c_str()); - - if (!it->satSolvable().isSystem()) - continue; - - if (zypp_ver_and_arch_equal (it->satSolvable(), id_parts[PK_PACKAGE_ID_VERSION], - id_parts[PK_PACKAGE_ID_ARCH])) { - system = true; - break; - } - } - - if (!system) { - gboolean hit = false; - - // Choose the PoolItem with the right architecture and version - for (ResPool::byName_iterator it = pool.byNameBegin (name); - it != pool.byNameEnd (name); ++it) { - - if (zypp_ver_and_arch_equal (it->satSolvable(), id_parts[PK_PACKAGE_ID_VERSION], - id_parts[PK_PACKAGE_ID_ARCH])) { - hit = true; - to_install++; - // set status to ToBeInstalled - it->status ().setToBeInstalled (ResStatus::USER); - items->push_back (*it); - break; - } - } - if (!hit) { - g_strfreev (id_parts); - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, - "Couldn't find the package '%s'.", package_ids[i]); - return; - } - - } - g_strfreev (id_parts); + MIL << package_ids[i] << endl; + sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]); + + to_install++; + PoolItem item(solvable); + // set status to ToBeInstalled + item.status ().setToBeInstalled (ResStatus::USER); + items->push_back (item); + } - + pk_backend_job_set_percentage (job, 40); if (!to_install) { @@ -1187,10 +1041,10 @@ backend_remove_packages_thread (PkBackendJob *job, GVariant *params, gpointer us vector<PoolItem> *items = new vector<PoolItem> (); g_variant_get(params, "(t^a&sbb)", - &transaction_flags, - &package_ids, - &allow_deps, - &autoremove); + &transaction_flags, + &package_ids, + &allow_deps, + &autoremove); pk_backend_job_set_status (job, PK_STATUS_ENUM_REMOVE); pk_backend_job_set_percentage (job, 0); @@ -1211,27 +1065,21 @@ backend_remove_packages_thread (PkBackendJob *job, GVariant *params, gpointer us target->load (); pk_backend_job_set_percentage (job, 10); - if (!pk_package_ids_check (package_ids)) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); - return; - } for (guint i = 0; package_ids[i]; i++) { - gchar **id_parts = pk_package_id_split (package_ids[i]); - - // Iterate over the resolvables and mark the ones we want to remove - ResPool pool = ResPool::instance (); - for (ResPool::byIdent_iterator it = pool.byIdentBegin (ResKind::package, id_parts[PK_PACKAGE_ID_NAME]); - it != pool.byIdentEnd (ResKind::package, id_parts[PK_PACKAGE_ID_NAME]); ++it) { - if ((*it)->isSystem ()) { - it->status ().setToBeUninstalled (ResStatus::USER); - items->push_back (*it); - break; - } else { - it->status ().resetTransact (ResStatus::USER); - } + sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]); + + if (zypp_is_no_solvable(solvable)) { + zypp_backend_finished_error (job, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, + "couldn't find package"); + return; + } + PoolItem item(solvable); + if (solvable.isSystem ()) { + item.status ().setToBeUninstalled (ResStatus::USER); + items->push_back (item); + } else { + item.status ().resetTransact (ResStatus::USER); } - g_strfreev (id_parts); } pk_backend_job_set_percentage (job, 40); @@ -1280,14 +1128,12 @@ static void backend_resolve_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { MIL << endl; - gchar **package_ids; + gchar **search; PkBitfield _filters; g_variant_get(params, "(t^a&s)", &_filters, - &package_ids); - - PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); + &search); ZyppJob zjob(job); ZYpp::Ptr zypp = zjob.get_zypp(); @@ -1296,27 +1142,31 @@ backend_resolve_thread (PkBackendJob *job, GVariant *params, gpointer user_data) pk_backend_job_finished (job); return; } - + pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); zypp_build_pool (zypp, TRUE); - for (uint i = 0; package_ids[i]; i++) { + for (uint i = 0; search[i]; i++) { vector<sat::Solvable> v; - + /* build a list of packages with this name */ - zypp_get_packages_by_name (backend, package_ids[i], ResKind::package, v); + zypp_get_packages_by_name (search[i], ResKind::package, v); /* add source packages */ if (!pk_bitfield_contain (_filters, PK_FILTER_ENUM_NOT_SOURCE)) { vector<sat::Solvable> src; - zypp_get_packages_by_name (backend, package_ids[i], ResKind::srcpackage, src); + zypp_get_packages_by_name (search[i], ResKind::srcpackage, src); v.insert (v.end (), src.begin (), src.end ()); } /* include patches too */ vector<sat::Solvable> v2; - zypp_get_packages_by_name (backend, package_ids[i], ResKind::patch, v2); + zypp_get_packages_by_name (search[i], ResKind::patch, v2); + v.insert (v.end (), v2.begin (), v2.end ()); + + /* include patterns too */ + zypp_get_packages_by_name (search[i], ResKind::pattern, v2); v.insert (v.end (), v2.begin (), v2.end ()); sat::Solvable newest; @@ -1326,19 +1176,19 @@ backend_resolve_thread (PkBackendJob *job, GVariant *params, gpointer user_data) for (vector<sat::Solvable>::iterator it = v.begin (); it != v.end (); ++it) { if (zypp_filter_solvable (_filters, *it) || - *it == sat::Solvable::noSolvable) + zypp_is_no_solvable(*it)) continue; - - if (newest == sat::Solvable::noSolvable) { + + if (zypp_is_no_solvable(newest)) { newest = *it; } else if (it->edition() > newest.edition() || Arch::compare(it->arch(), newest.arch()) > 0) { newest = *it; } pkgs.push_back (*it); } - - if (newest != sat::Solvable::noSolvable) { - + + if (!zypp_is_no_solvable(newest)) { + /* 'newest' filter support */ if (pk_bitfield_contain (_filters, PK_FILTER_ENUM_NEWEST)) { pkgs.clear(); @@ -1568,7 +1418,7 @@ pk_backend_get_repo_list (PkBackend *backend, PkBackendJob *job, PkBitfield filt } for (list <RepoInfo>::iterator it = repos.begin(); it != repos.end(); ++it) { - if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT) && zypp_is_development_repo (backend, *it)) + if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT) && zypp_is_development_repo (*it)) continue; // RepoInfo::alias - Unique identifier for this source. // RepoInfo::name - Short label or description of the @@ -1635,9 +1485,7 @@ backend_get_files_thread (PkBackendJob *job, GVariant *params, gpointer user_dat gchar **package_ids; g_variant_get(params, "(^a&s)", - &package_ids); - - PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); + &package_ids); ZyppJob zjob(job); ZYpp::Ptr zypp = zjob.get_zypp(); @@ -1647,40 +1495,11 @@ backend_get_files_thread (PkBackendJob *job, GVariant *params, gpointer user_dat return; } - if (!pk_package_ids_check (package_ids)) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); - return; - } - for (uint i = 0; package_ids[i]; i++) { - gchar **id_parts = pk_package_id_split (package_ids[i]); pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); - - vector<sat::Solvable> v; - vector<sat::Solvable> v2; - vector<sat::Solvable> v3; - zypp_get_packages_by_name (backend, (const gchar *)id_parts[PK_PACKAGE_ID_NAME], ResKind::package, v); - zypp_get_packages_by_name (backend, (const gchar *)id_parts[PK_PACKAGE_ID_NAME], ResKind::srcpackage, v2); - zypp_get_packages_by_name (backend, (const gchar *)id_parts[PK_PACKAGE_ID_NAME], ResKind::patch, v3); - - v.insert (v.end (), v2.begin (), v2.end ()); - v.insert (v.end (), v3.begin (), v3.end ()); - - sat::Solvable package; - for (vector<sat::Solvable>::iterator it = v.begin (); - it != v.end (); ++it) { - char *version = g_strdup (it->edition ().asString ().c_str ()); - if (strcmp (id_parts[PK_PACKAGE_ID_VERSION], version) == 0) { - g_free (version); - package = *it; - break; - } - g_free (version); - } - g_strfreev (id_parts); - - if (package == NULL) { + sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]); + + if (zypp_is_no_solvable(solvable)) { zypp_backend_finished_error ( job, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "couldn't find package"); @@ -1688,9 +1507,9 @@ backend_get_files_thread (PkBackendJob *job, GVariant *params, gpointer user_dat } string temp; - if (package.isSystem ()){ + if (solvable.isSystem ()){ try { - target::rpm::RpmHeader::constPtr rpmHeader = zypp_get_rpmHeader (package.name (), package.edition ()); + target::rpm::RpmHeader::constPtr rpmHeader = zypp_get_rpmHeader (solvable.name (), solvable.edition ()); list<string> files = rpmHeader->tag_filenames (); for (list<string>::iterator it = files.begin (); it != files.end (); ++it) { @@ -1699,10 +1518,9 @@ backend_get_files_thread (PkBackendJob *job, GVariant *params, gpointer user_dat } } catch (const target::rpm::RpmException &ex) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_REPO_NOT_FOUND, - "Couldn't open rpm-database"); - return; + zypp_backend_finished_error (job, PK_ERROR_ENUM_REPO_NOT_FOUND, + "Couldn't open rpm-database"); + return; } } else { temp = "Only available for installed packages"; @@ -1771,11 +1589,9 @@ backend_update_packages_thread (PkBackendJob *job, GVariant *params, gpointer us PkBitfield transaction_flags = 0; gchar **package_ids; g_variant_get(params, "(t^a&s)", - &transaction_flags, - &package_ids); - - PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); - + &transaction_flags, + &package_ids); + ZyppJob zjob(job); ZYpp::Ptr zypp = zjob.get_zypp(); @@ -1787,24 +1603,7 @@ backend_update_packages_thread (PkBackendJob *job, GVariant *params, gpointer us PkRestartEnum restart = PK_RESTART_ENUM_NONE; for (guint i = 0; package_ids[i]; i++) { - gchar **id_parts = pk_package_id_split (package_ids[i]); - string name = id_parts[PK_PACKAGE_ID_NAME]; - - // Do we have already the latest version. - gboolean system = false; - for (ResPool::byName_iterator it = pool.byNameBegin (name); - it != pool.byNameEnd (name); ++it) { - if (!it->satSolvable().isSystem()) - continue; - if (zypp_ver_and_arch_equal (it->satSolvable(), id_parts[PK_PACKAGE_ID_VERSION], - id_parts[PK_PACKAGE_ID_ARCH])) { - system = true; - break; - } - } - if (system == true) - continue; - sat::Solvable solvable = zypp_get_package_by_id (backend, package_ids[i]); + sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]); PoolItem item(solvable); item.status ().setToBeInstalled (ResStatus::USER); Patch::constPtr patch = asKind<Patch>(item.resolvable ()); @@ -2065,8 +1864,8 @@ backend_download_packages_thread (PkBackendJob *job, GVariant *params, gpointer const gchar *tmpDir; g_variant_get(params, "(^a&ss)", - &package_ids, - &tmpDir); + &package_ids, + &tmpDir); ZyppJob zjob(job); ZYpp::Ptr zypp = zjob.get_zypp(); @@ -2081,63 +1880,52 @@ backend_download_packages_thread (PkBackendJob *job, GVariant *params, gpointer return; } - if (!pk_package_ids_check (package_ids)) { - zypp_backend_finished_error ( - job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); - return; - } - try { ResPool pool = zypp_build_pool (zypp, FALSE); - PoolItem item; pk_backend_job_set_status (job, PK_STATUS_ENUM_DOWNLOAD); for (guint i = 0; package_ids[i]; i++) { - gchar **id_parts = pk_package_id_split (package_ids[i]); - string name = id_parts[PK_PACKAGE_ID_NAME]; - - for (ResPool::byName_iterator it = pool.byNameBegin (name); it != pool.byNameEnd (name); ++it) { - if (zypp_ver_and_arch_equal (it->satSolvable(), id_parts[PK_PACKAGE_ID_VERSION], - id_parts[PK_PACKAGE_ID_ARCH])) { - size += 2 * it->resolvable()->downloadSize(); - item = *it; - break; - } + sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]); + + if (zypp_is_no_solvable(solvable)) { + zypp_backend_finished_error (job, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, + "couldn't find package"); + return; } - sat::Solvable solvable = item.resolvable()->satSolvable(); + PoolItem item(solvable); + size += 2 * make<ResObject>(solvable)->downloadSize(); filesystem::Pathname repo_dir = solvable.repository().info().packagesPath(); struct statfs stat; statfs(repo_dir.c_str(), &stat); if (size > stat.f_bavail * 4) { - g_strfreev (id_parts); pk_backend_job_error_code (job, PK_ERROR_ENUM_NO_SPACE_ON_DEVICE, "Insufficient space in download directory '%s'.", repo_dir.c_str()); pk_backend_job_finished (job); return; } - filesystem::Pathname tmp_file; repo::RepoMediaAccess access; repo::DeltaCandidates deltas; - if (strcmp (id_parts[PK_PACKAGE_ID_ARCH], "source") == 0) { + ManagedFile tmp_file; + if (isKind<SrcPackage>(solvable)) { SrcPackage::constPtr package = asKind<SrcPackage>(item.resolvable()); repo::SrcPackageProvider pkgProvider(access); - pkgProvider.provideSrcPackage(package); - tmp_file = solvable.repository().info().packagesPath()+ package->location().filename(); - + tmp_file = pkgProvider.provideSrcPackage(package); } else { Package::constPtr package = asKind<Package>(item.resolvable()); repo::PackageProvider pkgProvider(access, package, deltas); - pkgProvider.providePackage(); - tmp_file = solvable.repository().info().packagesPath()+ package->location().filename(); + tmp_file = pkgProvider.providePackage(); } - pk_backend_job_files (job, package_ids[i], tmp_file.c_str()); - zypp_backend_package (job, PK_INFO_ENUM_DOWNLOADING, solvable, item->summary ().c_str()); - - g_strfreev (id_parts); + string target = tmpDir; + // be sure it ends with / + target += "/"; + target += tmp_file->basename(); + filesystem::hardlinkCopy(tmp_file, target); + pk_backend_job_files (job, package_ids[i], target.c_str()); + pk_backend_job_package (job, PK_INFO_ENUM_DOWNLOADING, package_ids[i], item->summary ().c_str()); } } catch (const Exception &ex) { zypp_backend_finished_error ( diff --git a/backends/zypp/zypp-events.h b/backends/zypp/zypp-events.h index 4794783..b18bf94 100644 --- a/backends/zypp/zypp-events.h +++ b/backends/zypp/zypp-events.h @@ -84,9 +84,15 @@ public: // fact that libzypp may skip over a "divisible by ten" // value (i.e., 28, 29, 31, 32). + MIL << percentage << " " << _sub_percentage << std::endl; if (percentage <= _sub_percentage) return; + if (!_package_id) { + MIL << "percentage without package" << std::endl; + return; + } + _sub_percentage = percentage; pk_backend_job_set_item_progress(_job, _package_id, PK_STATUS_ENUM_UNKNOWN, _sub_percentage); } @@ -105,26 +111,40 @@ protected: struct InstallResolvableReportReceiver : public zypp::callback::ReceiveReport<zypp::target::rpm::InstallResolvableReport>, ZyppBackendReceiver { zypp::Resolvable::constPtr _resolvable; + bool preparing; + int last_value; virtual void start (zypp::Resolvable::constPtr resolvable) { clear_package_id (); _package_id = zypp_build_package_id_from_resolvable (resolvable->satSolvable ()); + MIL << resolvable << " " << _package_id << std::endl; gchar* summary = g_strdup(zypp::asKind<zypp::ResObject>(resolvable)->summary().c_str ()); - g_debug ("InstallResolvableReportReceiver::start(): %s", _package_id == NULL ? "unknown" : _package_id); if (_package_id != NULL) { pk_backend_job_set_status (_job, PK_STATUS_ENUM_INSTALL); pk_backend_job_package (_job, PK_INFO_ENUM_INSTALLING, _package_id, summary); reset_sub_percentage (); } + // first we prepare then we install + preparing = true; + last_value = 0; g_free (summary); } virtual bool progress (int value, zypp::Resolvable::constPtr resolvable) { - //g_debug ("InstallResolvableReportReceiver::progress(), %s:%d", _package_id == NULL ? "unknown" : _package_id, value); - if (_package_id != NULL) - update_sub_percentage (value); + // we need to have extra logic here as progress is reported twice + // and PackageKit does not like percentages going back + if (preparing && value < last_value) + preparing = false; + last_value = value; + MIL << preparing << " " << value << " " << _package_id << std::endl; + int perc = 0; + if (preparing) + perc = value * 30 / 100; + else + perc = 30 + value * 70 / 100; + update_sub_percentage (perc); return true; } @@ -136,7 +156,7 @@ struct InstallResolvableReportReceiver : public zypp::callback::ReceiveReport<zy virtual void finish (zypp::Resolvable::constPtr resolvable, Error error, const std::string &reason, RpmLevel level) { - //g_debug ("InstallResolvableReportReceiver::finish(): %s", _package_id == NULL ? "unknown" : _package_id); + MIL << reason << " " << _package_id << " " << resolvable << std::endl; if (_package_id != NULL) { //pk_backend_job_package (_backend, PK_INFO_ENUM_INSTALLED, _package_id, "TODO: Put the package summary here if possible"); clear_package_id (); @@ -161,8 +181,7 @@ struct RemoveResolvableReportReceiver : public zypp::callback::ReceiveReport<zyp virtual bool progress (int value, zypp::Resolvable::constPtr resolvable) { - if (_package_id != NULL) - update_sub_percentage (value); + update_sub_percentage (value); return true; } @@ -227,6 +246,7 @@ struct DownloadProgressReportReceiver : public zypp::callback::ReceiveReport<zyp { virtual void start (zypp::Resolvable::constPtr resolvable, const zypp::Url &file) { + MIL << resolvable << " " << file << std::endl; clear_package_id (); _package_id = zypp_build_package_id_from_resolvable (resolvable->satSolvable ()); gchar* summary = g_strdup(zypp::asKind<zypp::ResObject>(resolvable)->summary().c_str ()); @@ -243,17 +263,16 @@ struct DownloadProgressReportReceiver : public zypp::callback::ReceiveReport<zyp virtual bool progress (int value, zypp::Resolvable::constPtr resolvable) { - //fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::progress(), %s:%d\n\n", _package_id == NULL ? "unknown" : _package_id, value); - if (_package_id != NULL) { - update_sub_percentage (value); - //pk_backend_job_set_speed (_job, static_cast<guint>(dbps_current)); - } + MIL << resolvable << " " << value << " " << _package_id << std::endl; + update_sub_percentage (value); + //pk_backend_job_set_speed (_job, static_cast<guint>(dbps_current)); return true; } virtual void finish (zypp::Resolvable::constPtr resolvable, Error error, const std::string &konreason) { - //fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::finish(): %s\n", _package_id == NULL ? "unknown" : _package_id); + MIL << resolvable << " " << error << " " << _package_id << std::endl; + update_sub_percentage (100); clear_package_id (); } }; @@ -272,17 +291,20 @@ struct ProgressReportReceiver : public zypp::callback::ReceiveReport<zypp::Progr { virtual void start (const zypp::ProgressData &progress) { + MIL << std::endl; reset_sub_percentage (); } virtual bool progress (const zypp::ProgressData &progress) { + MIL << progress.val() << std::endl; update_sub_percentage ((int)progress.val ()); return true; } virtual void finish (const zypp::ProgressData &progress) { + MIL << progress.val() << std::endl; update_sub_percentage ((int)progress.val ()); } }; diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp index 0647499..d898f8c 100644 --- a/backends/zypp/zypp-utils.cpp +++ b/backends/zypp/zypp-utils.cpp @@ -147,7 +147,7 @@ zypp_logging () } gboolean -zypp_is_changeable_media (PkBackend *backend, const Url &url) +zypp_is_changeable_media (const Url &url) { gboolean is_cd = false; try { @@ -184,7 +184,7 @@ namespace { } gboolean -zypp_is_development_repo (PkBackend *backend, RepoInfo repo) +zypp_is_development_repo (RepoInfo repo) { return ( name_ends_or_contains( repo.alias(), "-debuginfo" ) || name_ends_or_contains( repo.alias(), "-debug" ) @@ -354,8 +354,7 @@ get_enum_group (const string &group_) } void -zypp_get_packages_by_name (PkBackend *backend, - const gchar *package_name, +zypp_get_packages_by_name (const gchar *package_name, const ResKind kind, vector<sat::Solvable> &result, gboolean include_local) @@ -402,35 +401,55 @@ zypp_get_packages_by_file (ZYpp::Ptr zypp, } } +// gnome-packagekit;3.6.1-132.1;x86_64;G:F sat::Solvable -zypp_get_package_by_id (PkBackend *backend, const gchar *package_id) +zypp_get_package_by_id (const gchar *package_id) { + MIL << package_id << endl; if (!pk_package_id_check(package_id)) { // TODO: Do we need to do something more for this error? return sat::Solvable::noSolvable; } gchar **id_parts = pk_package_id_split(package_id); - vector<sat::Solvable> v; - vector<sat::Solvable> v2; + const gchar *arch = id_parts[PK_PACKAGE_ID_ARCH]; + if (!arch) + arch = "noarch"; + bool want_source = !g_strcmp0 (arch, "source"); + + sat::Solvable package; - zypp_get_packages_by_name (backend, id_parts[PK_PACKAGE_ID_NAME], ResKind::package, v); - zypp_get_packages_by_name (backend, id_parts[PK_PACKAGE_ID_NAME], ResKind::patch, v2); + ResPool pool = ResPool::instance(); - v.insert (v.end (), v2.begin (), v2.end ()); + // Iterate over the resolvables and mark the one we want to check its dependencies + for (ResPool::byName_iterator it = pool.byNameBegin (id_parts[PK_PACKAGE_ID_NAME]); + it != pool.byNameEnd (id_parts[PK_PACKAGE_ID_NAME]); ++it) { + + sat::Solvable pkg = it->satSolvable(); + MIL << "match " << package_id << " " << pkg << endl; - if (v.empty()) - return sat::Solvable::noSolvable; + if (want_source && !isKind<SrcPackage>(pkg)) + continue; - sat::Solvable package; + if (!want_source && (isKind<SrcPackage>(pkg) || g_strcmp0 (pkg.arch().c_str(), arch))) + continue; - for (vector<sat::Solvable>::iterator it = v.begin (); - it != v.end (); ++it) { - if (zypp_ver_and_arch_equal (*it, id_parts[PK_PACKAGE_ID_VERSION], - id_parts[PK_PACKAGE_ID_ARCH])) { - package = *it; - break; - } + const string &ver = pkg.edition ().asString(); + if (g_strcmp0 (ver.c_str (), id_parts[PK_PACKAGE_ID_VERSION])) + continue; + + if (!strncmp(id_parts[PK_PACKAGE_ID_DATA], "installed", 9) && !pkg.isSystem()) + continue; + + if (pkg.isSystem() && strncmp(id_parts[PK_PACKAGE_ID_DATA], "installed", 9)) + continue; + + if (g_strcmp0(pkg.repository().alias().c_str(), id_parts[PK_PACKAGE_ID_DATA])) + continue; + + MIL << "found " << pkg << endl; + package = pkg; + break; } g_strfreev (id_parts); @@ -476,9 +495,8 @@ gboolean zypp_refresh_meta_and_cache (RepoManager &manager, RepoInfo &repo, bool force) { try { - if (manager.checkIfToRefreshMetadata (repo, repo.url(), - RepoManager::RefreshIfNeededIgnoreDelay) - != RepoManager::REFRESH_NEEDED) + if (manager.checkIfToRefreshMetadata (repo, repo.url()) //RepoManager::RefreshIfNeededIgnoreDelay) + != RepoManager::REFRESH_NEEDED) return TRUE; sat::Pool pool = sat::Pool::instance (); @@ -506,24 +524,24 @@ zypp_signature_required (PkBackendJob *job, const PublicKey &key) RepoInfo info = zypp_get_Repository (job, _repoName); if (info.type () == repo::RepoType::NONE) pk_backend_job_error_code (job, PK_ERROR_ENUM_INTERNAL_ERROR, - "Repository unknown"); + "Repository unknown"); else { pk_backend_job_repo_signature_required (job, - "dummy;0.0.1;i386;data", - _repoName, - 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); + "dummy;0.0.1;i386;data", + _repoName, + 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_job_error_code (job, PK_ERROR_ENUM_GPG_FAILURE, - "Signature verification for Repository %s failed", _repoName); + "Signature verification for Repository %s failed", _repoName); } throw AbortTransactionException(); } else ok = TRUE; - + return ok; } @@ -844,6 +862,7 @@ zypp_check_restart (PkRestartEnum *restart, Patch::constPtr patch) gboolean zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gboolean force, PkBitfield transaction_flags) { + MIL << force << pk_filter_bitfield_to_string(transaction_flags) << endl; gboolean ret = FALSE; PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); @@ -1022,7 +1041,7 @@ zypp_build_package_id_capabilities (Capabilities caps, gboolean terminate) gboolean zypp_refresh_cache (PkBackendJob *job, ZYpp::Ptr zypp, gboolean force) { - PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); + MIL << force << endl; // This call is needed as it calls initializeTarget which appears to properly setup the keyring if (zypp == NULL) @@ -1064,9 +1083,13 @@ zypp_refresh_cache (PkBackendJob *job, ZYpp::Ptr zypp, gboolean force) if (repo.enabled () == false) continue; + // do as zypper does + if (!force && !repo.autorefresh()) + continue; + // skip changeable meda (DVDs and CDs). Without doing this, // the disc would be required to be physically present. - if (zypp_is_changeable_media (backend, *repo.baseUrlsBegin ()) == true) + if (zypp_is_changeable_media (*repo.baseUrlsBegin ()) == true) continue; try { @@ -1161,29 +1184,14 @@ zypp_build_package_id_from_resolvable (const sat::Solvable &resolvable) else arch = resolvable.arch ().asString ().c_str (); + string repo = resolvable.repository ().alias(); + if (resolvable.isSystem()) + repo = "installed"; package_id = pk_package_id_build ( resolvable.name ().c_str (), resolvable.edition ().asString ().c_str (), - arch, resolvable.repository ().alias().c_str ()); + arch, repo.c_str ()); return package_id; } -gboolean -zypp_ver_and_arch_equal (const sat::Solvable &pkg, - const char *name, const char *arch) -{ - const string &ver = pkg.edition ().asString(); - if (g_strcmp0 (ver.c_str (), name)) - return FALSE; - - if (arch && !strcmp (arch, "source")) { - return isKind<SrcPackage>(pkg); - } - - const Arch &parch = pkg.arch(); - if (g_strcmp0 (parch.c_str(), arch)) - return FALSE; - - return TRUE; -} diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h index d001733..797ac2e 100644 --- a/backends/zypp/zypp-utils.h +++ b/backends/zypp/zypp-utils.h @@ -83,9 +83,7 @@ class ZyppJob { */ gboolean zypp_logging (); -gboolean zypp_is_changeable_media (PkBackend *backend, const zypp::Url &url); - -gboolean zypp_is_development_repo (PkBackend *backend, zypp::RepoInfo repo); +gboolean zypp_is_development_repo (zypp::RepoInfo repo); gboolean zypp_is_valid_repo (PkBackendJob *job, zypp::RepoInfo repo); /** @@ -112,7 +110,7 @@ PkGroupEnum get_enum_group (const std::string &group); /** * Returns a list of packages that match the specified package_name. */ -void zypp_get_packages_by_name (PkBackend *backend, const gchar *package_name, +void zypp_get_packages_by_name (const gchar *package_name, const zypp::ResKind kind, std::vector<zypp::sat::Solvable> &result, gboolean include_local = TRUE); @@ -124,7 +122,7 @@ void zypp_get_packages_by_file (zypp::ZYpp::Ptr zypp, const gchar *search_file, /** * Returns the Resolvable for the specified package_id. */ -zypp::sat::Solvable zypp_get_package_by_id (PkBackend *backend, const gchar *package_id); +zypp::sat::Solvable zypp_get_package_by_id (const gchar *package_id); /** * Build a package_id from the specified resolvable. The returned @@ -133,12 +131,6 @@ zypp::sat::Solvable zypp_get_package_by_id (PkBackend *backend, const gchar *pac gchar * zypp_build_package_id_from_resolvable (const 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 (PkBackendJob *job, const zypp::PublicKey &key); @@ -216,12 +208,6 @@ gboolean zypp_backend_pool_item_notify (PkBackendJob *job, gboolean sanity_check = FALSE); /** - * helper to compare a version + architecture, with source arch mangling. - */ -gboolean zypp_ver_and_arch_equal (const zypp::sat::Solvable &pkg, - const char *name, const char *arch); - -/** * helper to refresh a repo's metadata and cache, catching signature * exceptions in a safe way. */ -- 1.8.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor