[yast-commit] r63940 - /branches/tmp/dmacvicar/zc10/pkg-bindings/src/
Author: dmacvicar Date: Tue May 10 20:10:47 2011 New Revision: 63940 URL: http://svn.opensuse.org/viewcvs/yast?rev=63940&view=rev Log: More porting Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.h branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.h branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.h branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.loT branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.h branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.h branches/tmp/dmacvicar/zc10/pkg-bindings/src/log.h Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Makefile.am branches/tmp/dmacvicar/zc10/pkg-bindings/src/Package.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.h branches/tmp/dmacvicar/zc10/pkg-bindings/src/Resolvable.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/Selection.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/Target.cc branches/tmp/dmacvicar/zc10/pkg-bindings/src/ycpTools.h Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Makefile.am URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Makefile.am?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Makefile.am (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Makefile.am Tue May 10 20:10:47 2011 @@ -22,7 +22,11 @@ Y2CCPkg.cc Y2CCPkg.h \ ycpTools.cc ycpTools.h \ PkgModule.cc PkgModule.h \ - YRepo.h YRepo.cc + YRepo.h YRepo.cc \ + PkgProgress.cc PkgProgress.h \ + Utils.h Utils.cc \ + ServiceManager.cc ServiceManager.h \ + PkgService.cc PkgService.h \ PkgModuleFunctions.h \ PkgModuleFunctions.cc \ Package.cc \ Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Package.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Package.cc?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Package.cc (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Package.cc Tue May 10 20:10:47 2011 @@ -32,9 +32,9 @@ #include <ycp/YCPList.h> #include <ycp/YCPMap.h> +#include <zypp/base/Regex.h> #include <zypp/base/Algorithm.h> #include <zypp/ResFilters.h> -#include <zypp/CapFilters.h> #include <zypp/ResStatus.h> #include <zypp/base/String.h> @@ -43,12 +43,9 @@ #include <zypp/Patch.h> #include <zypp/SrcPackage.h> #include <zypp/Product.h> -#include <zypp/SourceManager.h> -#include <zypp/UpgradeStatistics.h> #include <zypp/target/rpm/RpmDb.h> #include <zypp/target/TargetException.h> #include <zypp/ZYppCommit.h> -#include <zypp/ResPoolManager.h> #include <fstream> #include <sstream> @@ -59,6 +56,118 @@ typedef std::list<PoolItem> PoolItemList; } +// helper function - create a symbolic link to the created base product (by SourceCreateBase() function) +// returns 'true' on success +// see http://en.opensuse.org/Product_Management/Code11/installed +bool PkgModuleFunctions::CreateBaseProductSymlink() +{ + if (base_product) + { + y2milestone("Creating symlink for the base product..."); + + // get the package + zypp::sat::Solvable refsolvable = base_product->referencePackage(); + + if (refsolvable != zypp::sat::Solvable::noSolvable) + { + // create a package pointer from the SAT solvable + zypp::Package::Ptr refpkg(zypp::make<zypp::Package>(refsolvable)); + + if (refpkg) + { + y2milestone("Found reference package for the base product: %s-%s", + refpkg->name().c_str(), refpkg->edition().asString().c_str()); + + // get the package files + zypp::Package::FileList files( refpkg->filelist() ); + y2milestone("The reference package has %d files", files.size()); + + std::string product_file; + zypp::str::smatch what; + const zypp::str::regex product_file_regex("^/etc/products\\.d/(.*\\.prod)$"); + + // find the product file + for_(iter, files.begin(), files.end()) + { + if (zypp::str::regex_match(*iter, what, product_file_regex)) + { + product_file = what[1]; + break; + } + } + + if (product_file.empty()) + { + y2error("The product file has not been found"); + return false; + } + else + { + y2milestone("Found product file %s", product_file.c_str()); + + // check and remove the existing link (refresh the link after upgrade) + const zypp::Pathname base_link(_target_root / "/etc/products.d/baseproduct"); + + struct stat stat_buf; + if (::stat(base_link.asString().c_str(), &stat_buf) == 0) + { + // the file exists, remove it + if (::unlink(base_link.asString().c_str()) != 0) + { + y2error("Cannot remove base link file %s: %s", + base_link.asString().c_str(), + ::strerror(errno) + ); + + return false; + } + } + // ENOENT == "No such file or directory", see 'man errno' + else if (errno != ENOENT) + { + y2error("Cannot stat %s file: %s", base_link.asString().c_str(), ::strerror(errno)); + return false; + } + else + { + y2debug("Link %s does not exist", base_link.asString().c_str()); + } + + if (::symlink(product_file.c_str(), base_link.asString().c_str()) != 0) + { + y2error("Cannot create symlink %s -> %s: %s", + base_link.asString().c_str(), + product_file.c_str(), + ::strerror(errno) + ); + + return false; + } + else + { + y2milestone("Symlink %s -> %s has been created", base_link.asString().c_str(), product_file.c_str()); + } + } + } + else + { + y2error("The reference solvable is not a package"); + return false; + } + } + else + { + y2milestone("The base product doesn't have any reference package"); + } + } + else + { + y2debug("A base product has not been added"); + } + + return true; +} + // ------------------------ /** * @builtin PkgQueryProvides @@ -252,8 +361,8 @@ return res; } -static YCPValue -PkgMediaSizesOrCount (bool sizes, bool download_size) +YCPValue +PkgModuleFunctions::PkgMediaSizesOrCount (bool sizes, bool download_size) { // all enabled sources std::list<RepoId> source_ids; @@ -513,310 +622,21 @@ return YCPBoolean(false); } - -struct ProvideProcess -{ - zypp::PoolItem_Ref item; - zypp::Arch _architecture; - zypp::ResStatus::TransactByValue whoWantsIt; - std::string version; - bool onlyNeeded; - - ProvideProcess( zypp::Arch arch, const std::string &vers, const bool oNeeded) - : _architecture( arch ), whoWantsIt(zypp::ResStatus::APPL_HIGH), version(vers), onlyNeeded(oNeeded) - { } - - bool operator()( zypp::PoolItem provider ) - { - // 1. compatible arch - // 2. best arch - // 3. best edition - // see QueueItemRequire in zypp/solver/detail, RequireProcess - - // check the version if it's specified - if (!version.empty() && version != provider->edition().asString()) - { - y2milestone("Skipping version %s (requested: %s)", provider->edition().asString().c_str(), version.c_str()); - return true; - } - - if (!provider.status().isInstalled() - && (!onlyNeeded || provider.status().isNeeded()) ) // take only needed items (e.G. needed patches) - { - // deselect the item if it's already selected, - // only one item should be selected - if (provider.status().isToBeInstalled()) - { - provider.status().resetTransact(whoWantsIt); - } - - // regarding items which are installable only - if (!provider->arch().compatibleWith( _architecture )) { - y2milestone ("provider %s has incompatible arch '%s'", provider->name().c_str(), provider->arch().asString().c_str()); - } - else if (!item) { // no provider yet - item = provider; - } - else if (item->arch().compare( provider->arch() ) < 0) { // provider has better arch - item = provider; - } - else if (item->edition().compare( provider->edition() ) < 0) { - item = provider; // provider has better edition - } - } - - return true; - } - -}; - - -/** - * helper function, install a resolvable with a specific name and kind -*/ - -bool -PkgModuleFunctions::DoProvideNameKind( const std::string & name, zypp::Resolvable::Kind kind, zypp::Arch architecture, - const std::string & version ,const bool onlyNeeded) -{ - try - { - ProvideProcess info( architecture, version, onlyNeeded); - info.whoWantsIt = whoWantsIt; - - invokeOnEach( zypp_ptr()->pool().byNameBegin( name ), - zypp_ptr()->pool().byNameEnd( name ), - zypp::resfilter::ByKind( kind ), - zypp::functor::functorRef<bool,zypp::PoolItem> (info) - ); - - if (!info.item) - return false; - - bool result = info.item.status().setToBeInstalled( whoWantsIt ); - if (!result) { - std::ostringstream os; - os << info.item; - y2milestone( "DoProvideNameKind failed for %s\n", os.str().c_str() ); - } - return true; - } - catch (...) - { - } - - return false; -} - -/* - * Helper function - */ -bool -PkgModuleFunctions::DoAllKind(zypp::Resolvable::Kind kind, bool provide) -{ - bool ret = true; - - try - { - for (zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(kind); - it != zypp_ptr()->pool().byKindEnd(kind); ++it) - { - bool res = provide ? it->status().setToBeInstalled( whoWantsIt ) - : (it->status().isInstalled() && it->status().setToBeUninstalled( whoWantsIt )); - - y2milestone ("%s %s -> %s\n", (provide ? "Install" : "Remove"), (*it)->name().c_str(), (res ? "Ok" : "Failed")); - ret = ret && res; - } - } - catch (...) - { - ret = false; - } - - return ret; -} - -bool -PkgModuleFunctions::DoProvideAllKind(zypp::Resolvable::Kind kind) -{ - return DoAllKind(kind, true); -} - -bool -PkgModuleFunctions::DoRemoveAllKind(zypp::Resolvable::Kind kind) -{ - return DoAllKind(kind, false); -} - - - -/** - * helper function, deinstall a kind which provides tag (as a - * kind name, a provided tag, or a provided file - * - * !!!!**** WARNING: This is different from DoProvideNameKind ****!!!! -*/ - -bool -PkgModuleFunctions::DoRemoveNameKind( const std::string & name, zypp::Resolvable::Kind kind) -{ - zypp::Dep dep( zypp::Dep::PROVIDES ); - CaIMatch match; - - try - { - // look for installed packages - invokeOnEach( zypp_ptr()->pool().byCapabilityIndexBegin( name, dep ), - zypp_ptr()->pool().byCapabilityIndexEnd( name, dep ), - zypp::functor::chain( zypp::resfilter::ByCaIInstalled(), - zypp::resfilter::ByCaIKind( kind ) ), - zypp::functor::functorRef<bool,zypp::CapAndItem>( match ) ); - } - catch (...) - { - return false; - } - - if (!match.item) - return false; - - bool result = match.item.status().setToBeUninstalled( whoWantsIt ); - y2milestone ("DoRemoveNameKind %s -> %s\n", name.c_str(), (result ? "Ok" : "Bad")); - - return true; -} - -// ------------------------ -/** - @builtin DoProvide - @short Install a list of packages to the system - @description - Provides (read: installs) a list of tags to the system - - tag is a package name - - returns a map of tag,reason pairs if tags could not be provided. - Usually this map should be empty (all required packages are - installed) - - If tags could not be provided (due to package install failures or - conflicts), the tag is listed as a key and the value describes - the reason for the failure (as an already translated string). - @param list tags - @return map -*/ -YCPValue -PkgModuleFunctions::DoProvide (const YCPList& tags) -{ - YCPMap ret; - if (tags->size() > 0) - { - for (int i = 0; i < tags->size(); ++i) - { - if (tags->value(i)->isString()) - { - DoProvideNameKind (tags->value(i)->asString()->value(), zypp::ResTraits<zypp::Package>::kind, zypp_ptr()->architecture(), ""); - } - else - { - y2error ("Pkg::DoProvide not string '%s'", tags->value(i)->toString().c_str()); - } - } - } -# warning error handling - return value - return ret; -} - - -// ------------------------ -/** - @builtin DoRemove - - @short Removes a list of packges from the system - @description - tag is a package name - - returns a map of tag,reason pairs if tags could not be removed. - Usually this map should be empty (all required packages are - removed) - - If a tag could not be removed (because other packages still - require it), the tag is listed as a key and the value describes - the reason for the failure (as an already translated string). - @param list tags - @return list Result -*/ -YCPValue -PkgModuleFunctions::DoRemove (const YCPList& tags) -{ - YCPMap ret; - if (tags->size() > 0) - { - for (int i = 0; i < tags->size(); ++i) - { - if (tags->value(i)->isString()) - { - DoRemoveNameKind( tags->value(i)->asString()->value(), zypp::ResTraits<zypp::Package>::kind); - } - else - { - y2error ("Pkg::DoRemove not string '%s'", tags->value(i)->toString().c_str()); - } - } - } - return ret; -} - -// ------------------------ - -struct ItemMatch -{ - zypp::PoolItem_Ref item; - - bool operator() (const zypp::PoolItem_Ref i ) - { - item = i; - return false; - } -}; - -static zypp::Package::constPtr -find_package( const string & name, zypp::PoolItem_Ref & item, zypp::ResPool pool ) +static zypp::Package::constPtr find_package(const string &name) { if (name.empty()) return NULL; - ItemMatch match; - - // look for uninstalled packages first, because they probably have - // translated summary - - invokeOnEach( pool.byNameBegin( name ), - pool.byNameEnd( name ), - zypp::functor::chain( zypp::resfilter::ByUninstalled(), - zypp::resfilter::ByKind( zypp::ResTraits<zypp::Package>::kind ) ), - zypp::functor::functorRef<bool,zypp::PoolItem_Ref>( match ) ); + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(name); - // if no match yet, try again with installed package - // (but those only provide an english summary) - - if (!match.item) { - invokeOnEach( pool.byNameBegin( name ), - pool.byNameEnd( name ), - zypp::functor::chain( zypp::resfilter::ByInstalled(), - zypp::resfilter::ByKind( zypp::ResTraits<zypp::Package>::kind ) ), - zypp::functor::functorRef<bool,zypp::PoolItem_Ref>( match ) ); + if (s) + { + return zypp::dynamic_pointer_cast<const zypp::Package>(s->theObj().resolvable()); } - if (!match.item) - return NULL; - - item = match.item; - - return zypp::asKind<zypp::Package>( match.item.resolvable() ); + return NULL; } - /** @builtin PkgSummary @@ -826,22 +646,19 @@ @usage Pkg::PkgSummary (string package) -> "This is a nice package" */ -#warning This is bogus, as we have multiple matching packages - YCPValue PkgModuleFunctions::PkgSummary (const YCPString& p) { try { - zypp::PoolItem_Ref item; - zypp::Package::constPtr pkg = find_package( p->value(), item, zypp_ptr()->pool() ); + zypp::Package::constPtr pkg = find_package(p->value()); if (pkg == NULL) { return YCPVoid(); } - return YCPString( pkg->summary() ); + return YCPString(pkg->summary()); } catch (...) { @@ -861,15 +678,12 @@ */ -#warning This is bogus, as we have multiple matching packages - YCPValue PkgModuleFunctions::PkgVersion (const YCPString& p) { try { - zypp::PoolItem_Ref item; - zypp::Package::constPtr pkg = find_package( p->value(), item, zypp_ptr()->pool() ); + zypp::Package::constPtr pkg = find_package(p->value()); if (pkg == NULL) { @@ -895,22 +709,20 @@ @usage Pkg::PkgSize (string package) -> 12345678 */ -#warning This is bogus, as we have multiple matching packages YCPValue PkgModuleFunctions::PkgSize (const YCPString& p) { try { - zypp::PoolItem_Ref item; - zypp::Package::constPtr pkg = find_package( p->value(), item, zypp_ptr()->pool() ); + zypp::Package::constPtr pkg = find_package(p->value()); if (pkg == NULL) { return YCPVoid(); } - return YCPInteger( pkg->size() ); + return YCPInteger( pkg->installSize() ); } catch (...) { @@ -929,15 +741,13 @@ @usage Pkg::PkgGroup (string package) -> string */ -#warning This is bogus, as we have multiple matching packages YCPValue PkgModuleFunctions::PkgGroup (const YCPString& p) { try { - zypp::PoolItem_Ref item; - zypp::Package::constPtr pkg = find_package( p->value(), item, zypp_ptr()->pool() ); + zypp::Package::constPtr pkg = find_package(p->value()); if (pkg == NULL) { @@ -953,24 +763,40 @@ return YCPVoid(); } +PkgModuleFunctions::RepoId PkgModuleFunctions::logFindAlias(const std::string &alias) const +{ + RepoId index = 0LL; + + for(RepoCont::const_iterator it = repos.begin(); it != repos.end() ; ++it, ++index) + { + if (!(*it)->isDeleted() && (*it)->repoInfo().alias() == alias) + return index; + } + + return -1LL; +} YCPValue -PkgModuleFunctions::PkgProp( zypp::PoolItem_Ref item ) +PkgModuleFunctions::PkgProp(const zypp::PoolItem &item) { YCPMap data; - zypp::Package::constPtr pkg = zypp::asKind<zypp::Package>( item.resolvable() ); + + zypp::Package::constPtr pkg = zypp::dynamic_pointer_cast<const zypp::Package>(item.resolvable()); + if (pkg == NULL) { - y2error( "Not a package: %s", item->name().c_str() ); - return data; + y2error("NULL pkg"); + return YCPVoid(); } data->add( YCPString("arch"), YCPString( pkg->arch().asString() ) ); - data->add( YCPString("medianr"), YCPInteger( pkg->sourceMediaNr() ) ); + data->add( YCPString("medianr"), YCPInteger( pkg->mediaNr() ) ); - y2debug("srcId: %ld", pkg->source().numericId() ); - data->add( YCPString("srcid"), YCPInteger( pkg->source().numericId() ) ); + long long sid = logFindAlias(pkg->repoInfo().alias()); + y2debug("srcId: %lld", sid ); + data->add( YCPString("srcid"), YCPInteger( sid ) ); std::string status("available"); + if (item.status().isInstalled()) { status = "installed"; @@ -983,10 +809,11 @@ { status = "removed"; } + data->add( YCPString("status"), YCPSymbol(status)); - data->add( YCPString("location"), YCPString( pkg->location().basename() ) ); - data->add( YCPString("path"), YCPString( pkg->location().asString() ) ); + data->add( YCPString("location"), YCPString( pkg->location().filename().basename() ) ); + data->add( YCPString("path"), YCPString( pkg->location().filename().asString() ) ); return data; } @@ -1011,19 +838,22 @@ * @usage Pkg::PkgProperties (string package) -> map */ -#warning This is bogus, as we have multiple matching packages - YCPValue PkgModuleFunctions::PkgProperties (const YCPString& p) { + if (p.isNull()) + { + return YCPVoid(); + } + try { - YCPMap data; - zypp::PoolItem_Ref item; - zypp::Package::constPtr pkg = find_package( p->value(), item, zypp_ptr()->pool() ); + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(p->value()); - if (item) - return PkgProp( item ); + if (s) + { + return PkgProp(s->theObj()); + } } catch (...) { @@ -1042,13 +872,27 @@ { try { - for (zypp::ResPool::byName_iterator it = zypp_ptr()->pool().byNameBegin(pkgname); - it != zypp_ptr()->pool().byNameEnd(pkgname); ++it) + // access to the Pool of Selectables + zypp::ResPoolProxy selectablePool(zypp::ResPool::instance().proxy()); + + for_(it, selectablePool.byKindBegin<zypp::Package>(), + selectablePool.byKindEnd<zypp::Package>()) { - // is it a package? - if (zypp::isKind<zypp::Package>(it->resolvable())) + zypp::ui::Selectable::Ptr s = (*it); + + if (s) { - data->add( PkgProp( *it ) ); + // iterate over installed packages + for_(inst_it, s->installedBegin(), s->installedEnd()) + { + data->add(PkgProp(*inst_it)); + } + + // iterate over available packages + for_(avail_it, s->availableBegin(), s->availableEnd()) + { + data->add(PkgProp(*avail_it)); + } } } } @@ -1064,17 +908,13 @@ YCPValue PkgModuleFunctions::GetPkgLocation (const YCPString& p, bool full_path) { - zypp::PoolItem_Ref item; - try { - zypp::Package::constPtr pkg = find_package( p->value(), item, zypp_ptr()->pool() ); - - YCPMap data; + zypp::Package::constPtr pkg = find_package(p->value()); - if (item) { - return (full_path) ? YCPString( pkg->location().asString() ) - : YCPString( pkg->location().basename() ); + if (pkg) { + return (full_path) ? YCPString( pkg->location().filename().asString() ) + : YCPString( pkg->location().filename().basename() ); } } catch (...) @@ -1117,7 +957,29 @@ return GetPkgLocation(p, true); } +// a helper function +YCPList _create_filelist(const zypp::PoolItem &pi) +{ + zypp::Package::constPtr package = zypp::dynamic_pointer_cast<const zypp::Package>(pi.resolvable()); + + YCPList ret; + + if (!package) + { + y2error("Not a package"); + return ret; + } + + zypp::Package::FileList files( package->filelist() ); + // insert the file names + for_( it, files.begin(), files.end() ) + { + ret->add(YCPString(*it)); + } + + return ret; +} /** * @builtin PkgGetFilelist @@ -1141,61 +1003,84 @@ { std::string pkgname = package->value(); std::string type = which->symbol(); - YCPList ret; if (type != "any" && type != "installed" && type != "candidate") { y2error("PkgGetFilelist: Unknown parameter, use `any, `installed or `candidate"); - return ret; + return YCPList(); } if (!pkgname.empty()) { try { - for (zypp::ResPool::byName_iterator it = zypp_ptr()->pool().byNameBegin(pkgname); - it != zypp_ptr()->pool().byNameEnd(pkgname); ++it) + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(pkgname); + + if (s) { - // is it a package? - if (zypp::isKind<zypp::Package>(it->resolvable())) + if (type == "any") { - if (type == "any" || - (type == "installed" && it->status().isInstalled()) || - (type == "candidate" && it->status().isToBeInstalled()) - ) + if (s->hasInstalledObj()) { - // cast to Package object - zypp::Package::constPtr package = zypp::dynamic_pointer_cast<const zypp::Package>(it->resolvable()); - std::list<std::string> files = package->filenames(); - - // insert the file names - for (std::list<string>::iterator it = files.begin(); it != files.end(); ++it) - { - ret->add(YCPString(*it)); - } - -#warning PkgGetFilelist has different semantics for `any optinon - the result depends on item order in the pool, first found is returned - // finish the loop, we have found required package - break; + return _create_filelist(s->installedObj()); + } + else if (s->hasCandidateObj()) + { + return _create_filelist(s->candidateObj()); + } + else + { + y2milestone("Package %s is not installed and is not available", pkgname.c_str()); } } - } - } - catch (...) - { - } - } - - return ret; -} - -// ------------------------ + else if (type == "installed") + { + if (s->hasInstalledObj()) + { + return _create_filelist(s->installedObj()); + } + else + { + y2milestone("Package %s is not installed", pkgname.c_str()); + } + } + else if (type == "candidate") + { + if (s->hasCandidateObj()) + { + return _create_filelist(s->candidateObj()); + } + else + { + y2milestone("Package %s is not available", pkgname.c_str()); + } + } + else + { + y2internal("Unhandled package type %s", type.c_str()); + } + } + else + { + y2warning("Package %s was not found", pkgname.c_str()); + } + } + catch (...) + { + } + } + + return YCPList(); +} + +bool state_saved = false; + +// ------------------------ /** @builtin SaveState - @short Save the current selection state - do not use, not implemented + @short Save the current selection state, can be restored later using Pkg::RestoreState() @description - save the current package selection status for later - retrieval via Pkg::RestoreState() + Save the current status of all resolvables for later restoration via Pkg::RestoreState() function. Only one state is stored, the following call will rewrite the saved status. @return boolean @see Pkg::RestoreState @@ -1204,15 +1089,24 @@ YCPValue PkgModuleFunctions::SaveState () { -# warning SaveState is not implemented - return YCPBoolean (true); + // a state has been already saved, it will be lost... + if (state_saved) + { + y2warning("Pkg::SaveState() has been already called, rewriting the saved state..."); + } + + y2milestone("Saving status..."); + zypp_ptr()->poolProxy().saveState(); + state_saved = true; + + return YCPBoolean(true); } // ------------------------ /** @builtin RestoreState - @short Restore Saved state - do not use, not implemented + @short Restore Saved state - restore the state saved by Pkg::SaveState() @description restore the package selection status from a former call to Pkg::SaveState() @@ -1228,26 +1122,41 @@ YCPValue PkgModuleFunctions::RestoreState (const YCPBoolean& ch) { -# warning RestoreState is not implemented + bool ret = false; + if (!ch.isNull () && ch->value () == true) { - // return YCPBoolean (_y2pm.packageSelectionDiffState()); + // check only + ret = zypp_ptr()->poolProxy().diffState(); } - return YCPBoolean(false /*_y2pm.packageSelectionRestoreState()*/); + else + { + if (!state_saved) + { + y2error("No previous state saved, state cannot be restored"); + } + else + { + y2milestone("Restoring the saved status..."); + zypp_ptr()->poolProxy().restoreState(); + ret = true; + } + } + + return YCPBoolean(ret); } // ------------------------ /** @builtin ClearSaveState - @short clear a saved state (to reduce memory consumption) - do not use, not implemented + @short Clear the saved state - do not use, does nothing (the saved state cannot be removed, it is part of each resolvable object) @return boolean */ YCPValue PkgModuleFunctions::ClearSaveState () { -# warning ClearSaveState is not implemented return YCPBoolean (true); } @@ -1267,12 +1176,15 @@ { try { - for (zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(zypp::ResTraits<zypp::Package>::kind); - it != zypp_ptr()->pool().byKindEnd(zypp::ResTraits<zypp::Package>::kind); - ++it) + // access to the Pool of Selectables + zypp::ResPoolProxy selectablePool(zypp::ResPool::instance().proxy()); + + for_(it, selectablePool.byKindBegin<zypp::Package>(), + selectablePool.byKindEnd<zypp::Package>()) { - // return true if there is a package installed/removed by user - if ((it->status().isToBeInstalled() || it->status().isToBeUninstalled()) && it->status().isByUser()) + zypp::ui::Selectable::Ptr s = (*it); + + if (s && s->fate() != zypp::ui::Selectable::UNMODIFIED && s->modifiedBy() == zypp::ResStatus::USER) { return YCPBoolean(true); } @@ -1289,7 +1201,7 @@ /** @builtin PkgAnyToDelete - @short Check if there are any package to be deleted + @short Check if there are any package to be deleted - obsoleted @description return true if any packages are to be deleted @return boolean @@ -1298,35 +1210,15 @@ YCPValue PkgModuleFunctions::PkgAnyToDelete () { - bool ret = false; - y2warning("Pkg::PkgAnyToDelete() is obsoleted, use Pkg::IsAnyResolvable(`package, `to_remove) instead"); - - try - { - for (zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(zypp::ResTraits<zypp::Package>::kind); - it != zypp_ptr()->pool().byKindEnd(zypp::ResTraits<zypp::Package>::kind); - ++it) - { - if (it->status().isToBeUninstalled()) - { - ret = true; - break; - } - } - } - catch (...) - { - } - - return YCPBoolean(ret); + return IsAnyResolvable(YCPSymbol("package"), YCPSymbol("to_remove")); } // ------------------------ /** @builtin AnyToInstall - @short Check if there are any package to be installed + @short Check if there are any package to be installed - obsoleted @description return true if any packages are to be installed @return boolean @@ -1335,33 +1227,12 @@ YCPValue PkgModuleFunctions::PkgAnyToInstall () { - bool ret = false; - y2warning("Pkg::PkgAnyToInstall() is obsoleted, use Pkg::IsAnyResolvable(`package, `to_install) instead"); - - try - { - for (zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(zypp::ResTraits<zypp::Package>::kind); - it != zypp_ptr()->pool().byKindEnd(zypp::ResTraits<zypp::Package>::kind); - ++it) - { - if (it->status().isToBeInstalled()) - { - ret = true; - break; - } - } - } - catch (...) - { - } - - return YCPBoolean(ret); + return IsAnyResolvable(YCPSymbol("package"), YCPSymbol("to_install")); } // ------------------------ - /* helper function */ static void pkg2list (YCPList &list, const zypp::ResPool::byKind_iterator& it, bool names_only) @@ -1381,7 +1252,6 @@ return; } - /** @builtin FilterPackages @@ -1517,60 +1387,18 @@ return packages; } - /** * @builtin PkgUpdateAll - * @param map<string,any> update_options Options for the solver. All parameters are optional, if a parameter is missing the default value from the package manager (libzypp) is used. Currently supported options: <tt>$["delete_unmaintained":boolean, "silent_downgrades":boolean, "keep_installed_patches":boolean]</tt> + * @param map<string,any> update_options Options for the solver. All parameters are optional, + * if a parameter is missing the default value from the package manager (libzypp) is used. + * Currently supported options: <tt>NONE</tt> + * * @short Update installed packages * @description - * Mark all packages for installation which are installed and have - * an available candidate for update. - * - * This will mark packages for installation *and* for deletion (if a - * package provides/obsoletes another package) - * - * This function does not solve dependencies. - * - * Symbols and integer values returned: - * - * <b>ProblemListSze</b>: Number of taboo and dropped packages found. - * - * <b>DeleteUnmaintained</b>: Whether delete_unmaintained arg was true or false. - * Dependent on this, <b>SumDropped</b> below either denotes packages to delete - * (if true) or packages to keep (if false). - * - * <b>SumProcessed</b>: TOTAL number of installed packages we processed. - * - * <b>SumToInstall</b>: TOTAL number of packages now tagged as to install. - * Summs <b>Ipreselected</b>, <b>Iupdate</b>, <b>Idowngrade</b>, <b>Ireplaced</b>. - * - * <b>Ipreselected</b>: Packages which were already taged to install. - * - * <b>Iupdate</b>: Packages set to install as update to a newer version. - * - * <b>Idowngrade</b>: Packages set to install performing a version downgrade. - * - * <b>Ireplaced</b>: Packages set to install as they replace an installed package. + * Perform a distribution upgrade. This function solves + * dependencies. * - * <b>SumToDelete</b>: TOTAL number of packages now tagged as to delete. - * Summs <b>Dpreselected</b>, <b>SumDropped</b> if <b>DeleteUnmaintained</b> - * was set. - * - * <b>Dpreselected</b>: Packages which were already taged to delete. - * - * <b>SumToKeep</b>: TOTAL number of packages which remain unchanged. - * Summs <b>Ktaboo</b>, <b>Knewer</b>, <b>Ksame</b>, <b>SumDropped</b> - * if <b>DeleteUnmaintained</b> was not set. - * - * <b>Ktaboo</b>: Packages which are set taboo. - * - * <b>Knewer</b>: Packages kept because only older versions are available. - * - * <b>Ksame</b>: Packages kept because they are up to date. - * - * <b>SumDropped</b>: TOTAL number of dropped packages found. Dependent - * on the delete_unmaintained arg, they are either tagged as to delete or - * remain unchanged. + * Symbols and integer values returned: <tt>NONE</tt> * * @return map<symbol,integer> summary of the update */ @@ -1578,48 +1406,30 @@ YCPValue PkgModuleFunctions::PkgUpdateAll (const YCPMap& options) { - zypp::UpgradeStatistics stats; + // NOTE(ma): Since libzypp switched to use libsatsolver for distribution upgrade, + // there are no more in-/output arguments to doUpgrade. The statistics previously + // returned from resolver()->doUpgrade(stats) via the UpgradeStatistics argument + // no longer exist. If some feedback is required here, libzypp could offer sort of + // transaction summary. Such a summary woulfd not be tied to the distribution upgrade, + // but would be available all the time and reflect the status of the zypp pool. + YCPValue delete_unmaintained = options->value(YCPString("delete_unmaintained")); if(!delete_unmaintained.isNull()) { - if (delete_unmaintained->isBoolean()) - { - stats.delete_unmaintained = delete_unmaintained->asBoolean()->value(); - } - else - { - y2error("unexpected type of 'delete_unmaintained' key: %s, must be a boolean!", - Type::vt2type(delete_unmaintained->valuetype())->toString().c_str()); - } + y2error("'delete_unmaintained' flag is obsoleted and should not be used, check the code!"); } YCPValue silent_downgrades = options->value(YCPString("silent_downgrades")); if(!silent_downgrades.isNull()) { - if (silent_downgrades->isBoolean()) - { - stats.silent_downgrades = silent_downgrades->asBoolean()->value(); - } - else - { - y2error("unexpected type of 'silent_downgrades' key: %s, must be a boolean!", - Type::vt2type(silent_downgrades->valuetype())->toString().c_str()); - } + y2error("'silent_downgrades' flag is obsoleted and should not be used, check the code!"); } YCPValue keep_installed_patches = options->value(YCPString("keep_installed_patches")); if(!keep_installed_patches.isNull()) { - if (keep_installed_patches->isBoolean()) - { - stats.keep_installed_patches = keep_installed_patches->asBoolean()->value(); - } - else - { - y2error("unexpected type of 'keep_installed_patches' key: %s, must be a boolean!", - Type::vt2type(keep_installed_patches->valuetype())->toString().c_str()); - } + y2error("'keep_installed_patches' flag is obsoleted and should not be used, check the code!"); } @@ -1628,46 +1438,14 @@ try { // solve upgrade, get statistics - zypp_ptr()->resolver()->doUpgrade(stats); + zypp_ptr()->resolver()->doUpgrade(); } catch (...) - { - return data; - } - - data->add( YCPSymbol("ProblemListSze"), YCPInteger(stats.chk_is_taboo + stats.chk_dropped)); - - // packages to install; sum and details - data->add( YCPSymbol("SumToInstall"), YCPInteger( stats.totalToInstall() ) ); - data->add( YCPSymbol("Ipreselected"), YCPInteger( stats.chk_already_toins ) ); - data->add( YCPSymbol("Iupdate"), YCPInteger( stats.chk_to_update ) ); - data->add( YCPSymbol("Idowngrade"), YCPInteger( stats.chk_to_downgrade ) ); - data->add( YCPSymbol("Ireplaced"), YCPInteger( stats.chk_replaced - + stats.chk_replaced_guessed - + stats.chk_add_split ) ); - // packages to delete; sum and details (! see dropped packages) - data->add( YCPSymbol("SumToDelete"), YCPInteger( stats.totalToDelete() ) ); - data->add( YCPSymbol("Dpreselected"), YCPInteger( stats.chk_already_todel ) ); - - // packages to delete; sum and details (! see dropped packages) - data->add( YCPSymbol("SumToKeep"), YCPInteger( stats.totalToKeep() ) ); - data->add( YCPSymbol("Ktaboo"), YCPInteger( stats.chk_is_taboo ) ); - data->add( YCPSymbol("Knewer"), YCPInteger( stats.chk_to_keep_downgrade ) ); - data->add( YCPSymbol("Ksame"), YCPInteger( stats.chk_to_keep_installed ) ); - - // dropped packages; dependent on the delete_unmaintained - // option set for doUpdate, dropped packages count as ToDelete - // or ToKeep. - data->add( YCPSymbol("SumDropped"), YCPInteger( stats.chk_dropped ) ); - data->add( YCPSymbol("DeleteUnmaintained"),YCPInteger( stats.delete_unmaintained ) ); - - // Total mumber of installed packages processed - data->add( YCPSymbol("SumProcessed"), YCPInteger( stats.chk_installed_total ) ); + {} return data; } - /** @builtin PkgInstall @short Select package for installation @@ -1712,21 +1490,29 @@ if (name.empty()) return YCPBoolean (false); - // ensure installation of the 'best' architecture + bool ret = false; + zypp::ui::Selectable::Ptr selectable = zypp::ui::Selectable::get(zypp::ResKind::srcpackage, name); - return YCPBoolean( DoProvideNameKind( name, zypp::ResTraits<zypp::SrcPackage>::kind, zypp_ptr()->architecture(), "" ) ); -} + if (selectable) + { + ret = selectable->setToInstall(whoWantsIt); + } + else + { + y2error("Source package %s is not available", name.c_str()); + } + return YCPBoolean(ret); +} /** @builtin PkgDelete - @short Select package for deletion + @short Select package for deletion (deletes all installed instances of the package) @param string package @return boolean */ -#warning This is bogus, as we have multiple matching (kernel) packages YCPValue PkgModuleFunctions::PkgDelete (const YCPString& p) @@ -1735,31 +1521,24 @@ if (name.empty()) return YCPBoolean (false); + bool ret = false; + try { - // find the package - zypp::ResPool::byName_iterator it = std::find_if ( - zypp_ptr()->pool().byNameBegin(name) - , zypp_ptr()->pool().byNameEnd(name) - , zypp::functor::chain ( - zypp::resfilter::ByInstalled (), - zypp::resfilter::ByKind( zypp::ResTraits<zypp::Package>::kind ) - ) - ); - + zypp::ui::Selectable::Ptr selectable = zypp::ui::Selectable::get(name); - // set the status to uninstalled - return YCPBoolean( (it != zypp_ptr()->pool().byNameEnd(name)) - && it->status().setToBeUninstalled(whoWantsIt) ); + if (selectable) + { + ret = selectable->setToDelete(whoWantsIt); + } } catch (...) { } - return YCPBoolean (false); + return YCPBoolean(ret); } - /** @builtin PkgTaboo @@ -1776,38 +1555,20 @@ if (name.empty()) return YCPBoolean (false); - bool ret = true; + bool ret = false; try { - bool found = false; - - for (zypp::ResPool::byName_iterator it = zypp_ptr()->pool().byNameBegin(name); - it != zypp_ptr()->pool().byNameEnd(name); ++it) - { - // is it a package? - // installed package cannot be set to taboo - if (zypp::isKind<zypp::Package>(it->resolvable()) && !it->status().isInstalled()) - { - found = true; - - bool res = it->status().resetTransact(whoWantsIt) - // lock the package at the USER level (bug #186205) - && it->status().resetTransact(zypp::ResStatus::USER) - && it->status().setLock(true, zypp::ResStatus::USER); - - ret = ret && res; - } - } + zypp::ui::Selectable::Ptr selectable = zypp::ui::Selectable::get(name); - if (!found) + if (selectable) { - ret = false; + // lock the package at the USER level (bug #186205) + ret = selectable->setStatus(zypp::ui::S_Taboo, zypp::ResStatus::USER); } } catch (...) { - ret = false; } return YCPBoolean(ret); @@ -1829,39 +1590,53 @@ if (name.empty()) return YCPBoolean (false); - bool ret = true; + bool ret = false; try { - bool found = false; + zypp::ui::Selectable::Ptr selectable = zypp::ui::Selectable::get(name); - for (zypp::ResPool::byName_iterator it = zypp_ptr()->pool().byNameBegin(name); - it != zypp_ptr()->pool().byNameEnd(name); ++it) + if (selectable) { - // is it a package? - if (zypp::isKind<zypp::Package>(it->resolvable())) - { - found = true; - ret = it->status().resetTransact(whoWantsIt) && ret; - } - } - - if (!found) - { - ret = false; + ret = selectable->unset(whoWantsIt); } } catch (...) { - ret = false; } return YCPBoolean(ret); } +template <class T> +inline void ResetAllKind(zypp::ResPoolProxy &proxy, const zypp::ResStatus::TransactByValue &level) +{ + for_(it, proxy.byKindBegin<T>(), proxy.byKindEnd<T>()) + { + zypp::ui::Selectable::Ptr s = (*it); + if (s && (level == zypp::ResStatus::USER || s->theObj().status().transacts())) + { + s->theObj().status().resetTransact(level); + } + } +} + + +void ResetAll(const zypp::ResStatus::TransactByValue &level) +{ + // access to the Pool of Selectables + zypp::ResPoolProxy selectablePool(zypp::ResPool::instance().proxy()); + + // unset all packages, patterns... + ResetAllKind<zypp::Package>(selectablePool, level); + ResetAllKind<zypp::Pattern>(selectablePool, level); + ResetAllKind<zypp::Patch>(selectablePool, level); + ResetAllKind<zypp::Product>(selectablePool, level); + ResetAllKind<zypp::SrcPackage>(selectablePool, level); +} /** - * @builtin Reset + * @builtin PkgReset * * @short Reset most internal stuff on the package manager. @return boolean @@ -1872,14 +1647,7 @@ { try { - for (zypp::ResPool::const_iterator it = zypp_ptr()->pool().begin() - ; it != zypp_ptr()->pool().end() - ; ++it) - { - // reset all transaction flags - it->statusReset(); - } - + ResetAll(zypp::ResStatus::USER); return YCPBoolean (true); } catch (...) @@ -1889,9 +1657,8 @@ return YCPBoolean (false); } - /** - * @builtin Reset + * @builtin PkgApplReset * * @short Reset most internal stuff on the package manager. Reset only packages set by the application, not by the user @@ -1903,14 +1670,7 @@ { try { - for (zypp::ResPool::const_iterator it = zypp_ptr()->pool().begin() - ; it != zypp_ptr()->pool().end() - ; ++it) - { - // reset all transaction flags - it->status().resetTransact(zypp::ResStatus::APPL_HIGH); - } - + ResetAll(whoWantsIt); return YCPBoolean (true); } catch (...) @@ -1920,11 +1680,35 @@ return YCPBoolean (false); } +void SaveProblemList(const zypp::ResolverProblemList &problems, const std::string &filename) +{ + try + { + int problem_size = problems.size(); + + if (problem_size > 0) + { + y2error ("PkgSolve: %d packages failed (see %s)", problem_size, filename.c_str()); + + std::ofstream out (filename.c_str()); + + out << problem_size << " packages failed" << std::endl; + for(zypp::ResolverProblemList::const_iterator p = problems.begin(); + p != problems.end(); ++p ) + { + out << (*p)->description() << std::endl; + } + } + } + catch (...) + { + } +} /** @builtin PkgSolve @short Solve current package dependencies - @optarg booean filter filter all conflicts with installed packages + @optarg boolean filter unused, only for backward compatibility (installed packages will be preferred) @return boolean @@ -1940,54 +1724,24 @@ } catch (const zypp::Exception& excpt) { - y2error("An error occurred during Pkg::PkgSolve."); + y2error("An error occurred during Pkg::Solve."); _last_error.setLastError(excpt.asUserString(), "See /var/log/YaST2/badlist for more information."); + result = false; } // save information about failed dependencies to file if (!result) { -# warning PkgSolve: filter option is not used -/* bool filter_conflicts_with_installed = false; - - if (! filter.isNull()) - { - filter_conflicts_with_installed = filter->value(); - } -*/ - - try - { - zypp::ResolverProblemList problems = zypp_ptr()->resolver()->problems(); - int problem_size = problems.size(); - - if (problem_size > 0) - { - y2error ("PkgSolve: %d packages failed (see /var/log/YaST2/badlist)", problem_size); - - std::ofstream out ("/var/log/YaST2/badlist"); - - out << problem_size << " packages failed" << std::endl; - for(zypp::ResolverProblemList::const_iterator p = problems.begin(); - p != problems.end(); ++p ) - { - out << (*p)->description() << std::endl; - } - } - } - catch (...) - { - return YCPBoolean(false); - } + zypp::ResolverProblemList problems = zypp_ptr()->resolver()->problems(); + SaveProblemList(problems, "/var/log/YaST2/badlist"); } return YCPBoolean(result); } - /** @builtin PkgEstablish - @short establish the pool state + @short establish the pool state - obsoleted, not needed @return boolean Returns true. (If no pool item 'transacts') @@ -2000,53 +1754,12 @@ YCPBoolean PkgModuleFunctions::PkgEstablish () { - bool result = false; - - try - { - result = zypp_ptr()->resolver()->establishPool(); - } - catch (const zypp::Exception& excpt) - { - y2error("An error occurred during Pkg::PkgEstablish."); - _last_error.setLastError(excpt.asUserString(), "See /var/log/YaST2/badlist for more information."); - } - - // save information about failed dependencies to file - if (!result) - { - try - { - zypp::ResolverProblemList problems = zypp_ptr()->resolver()->problems(); - int problem_size = problems.size(); - - if (problem_size > 0) - { - y2error ("PkgSolve: %d packages failed (see /var/log/YaST2/badlist)", problem_size); - - std::ofstream out ("/var/log/YaST2/badlist"); - - out << problem_size << " packages failed" << std::endl; - for(zypp::ResolverProblemList::const_iterator p = problems.begin(); - p != problems.end(); ++p ) - { - out << (*p)->description() << std::endl; - } - } - } - catch (...) - { - return YCPBoolean(false); - } - } - - return YCPBoolean(result); + return YCPBoolean(false); } - /** @builtin PkgFreshen - @short check all package freshens and schedule matching ones for installation + @short check all package freshens and schedule matching ones for installation - obsoleted, not needed @return boolean Returns true. (If no pool item 'transacts') @@ -2056,103 +1769,51 @@ If it has, dependencies will be solved and the returned result might be false. */ - +#warning Freshens is obsolete YCPBoolean PkgModuleFunctions::PkgFreshen() { - bool result = false; - - try - { - result = zypp_ptr()->resolver()->freshenPool(); - } - catch (const zypp::Exception& excpt) - { - y2error("An error occurred during Pkg::PkgFreshen."); - _last_error.setLastError(excpt.asUserString(), "See /var/log/YaST2/badlist for more information."); - } - - // save information about failed dependencies to file - if (!result) - { - try - { - zypp::ResolverProblemList problems = zypp_ptr()->resolver()->problems(); - int problem_size = problems.size(); - - if (problem_size > 0) - { - y2error ("PkgSolve: %d packages failed (see /var/log/YaST2/badlist)", problem_size); - - std::ofstream out ("/var/log/YaST2/badlist"); - - out << problem_size << " packages failed" << std::endl; - for(zypp::ResolverProblemList::const_iterator p = problems.begin(); - p != problems.end(); ++p ) - { - out << (*p)->description() << std::endl; - } - } - } - catch (...) - { - return YCPBoolean(false); - } - } - - return YCPBoolean(result); + return YCPBoolean(true); } - /** @builtin PkgSolveCheckTargetOnly @short Solve packages currently installed on target system. @description - Solve packages currently installed on target system. Packages status - remains unchanged, i.e. does not select/deselect any packages to - resolve failed dependencies. + Solve packages currently installed on target system. + All transactions are reset after the call! @return boolean */ YCPBoolean PkgModuleFunctions::PkgSolveCheckTargetOnly() { - // create pool just with objects from target - zypp::ResStore store; - try { - store = zypp_ptr()->target()->resolvables(); + zypp_ptr()->target()->load(); } catch (...) { return YCPBoolean(false); } - zypp::ResPoolManager pool; - pool.insert(store.begin(), store.end(), true); - - // create resolver - zypp::Resolver solver(pool.accessor()); - bool result = false; try { // verify consistency of system - result = solver.verifySystem(); + result = zypp_ptr()->resolver()->verifySystem(); } catch (const zypp::Exception& excpt) { y2error("An error occurred during Pkg::PkgSolveCheckTargetOnly"); - _last_error.setLastError(excpt.asUserString()); + _last_error.setLastError(ExceptionAsString(excpt)); } return YCPBoolean(result); } - /** @builtin PkgSolveErrors @short Returns number of fails @@ -2176,31 +1837,8 @@ return YCPVoid(); } -/** - @builtin PkgCommit - - @short Commit package changes (actually install/delete packages) - @description - - if medianr == 0, all packages regardless of media are installed - - if medianr > 0, only packages from this media are installed - - @param integer medianr Media Number - @return list [ int successful, list failed, list remaining, list srcremaining ] - The 'successful' value will be negative, if installation was aborted ! - -*/ -YCPValue -PkgModuleFunctions::PkgCommit (const YCPInteger& media) +YCPValue PkgModuleFunctions::CommitHelper(const zypp::ZYppCommitPolicy &policy) { - int medianr = media->value (); - - if (medianr < 0) - { - return YCPError ("Bad args to Pkg::PkgCommit"); - } - zypp::ZYpp::CommitResult result; // clean the last reported source @@ -2209,32 +1847,30 @@ try { - zypp::ZYppCommitPolicy policy; - policy.restrictToMedia( medianr ); + // reset the values for SourceChanged callback + last_reported_repo = -1; + last_reported_mediumnr = 1; + result = zypp_ptr()->commit(policy); } catch (const zypp::target::TargetAbortedException & excpt) { y2milestone ("Installation aborted by user"); YCPList ret; - ret->add(YCPInteger(-1LL)); + ret->add(YCPInteger(-1)); return ret; } catch (const zypp::Exception& excpt) { y2error("Pkg::Commit has failed: ZYpp::commit has failed"); - _last_error.setLastError(excpt.asUserString()); + _last_error.setLastError(ExceptionAsString(excpt)); return YCPVoid(); } - try { - zypp::SourceManager::sourceManager()->releaseAllSources(); - } - catch (const zypp::Exception& excpt) - { - y2error("Pkg::Commit has failed: cannot release all sources"); - _last_error.setLastError(excpt.asUserString()); - } + SourceReleaseAll(); + + // create the base product link (bnc#413444) + CreateBaseProductSymlink(); YCPList ret; @@ -2257,12 +1893,6 @@ resolvable->add (YCPString ("kind"), YCPSymbol ("product")); else if (zypp::isKind<zypp::Pattern>(it->resolvable())) resolvable->add (YCPString ("kind"), YCPSymbol ("pattern")); - else if (zypp::isKind<zypp::Selection>(it->resolvable())) - resolvable->add (YCPString ("kind"), YCPSymbol ("selection")); - else if (zypp::isKind<zypp::Script>(it->resolvable())) - resolvable->add (YCPString ("kind"), YCPSymbol ("script")); - else if (zypp::isKind<zypp::Message>(it->resolvable())) - resolvable->add (YCPString ("kind"), YCPSymbol ("message")); else if (zypp::isKind<zypp::Patch>(it->resolvable())) resolvable->add (YCPString ("kind"), YCPSymbol ("patch")); else @@ -2286,6 +1916,37 @@ } /** + @builtin PkgCommit + + @short Commit package changes (actually install/delete packages), see also Pkg::Commit() + @description + + if medianr == 0, all packages regardless of media are installed + + if medianr > 0, only packages from this media are installed + + @param integer medianr Media Number + @return list [ int successful, list failed, list remaining, list srcremaining ] + The 'successful' value will be negative, if installation was aborted ! + +*/ +YCPValue +PkgModuleFunctions::PkgCommit (const YCPInteger& media) +{ + int medianr = media->value (); + + if (medianr < 0) + { + return YCPError ("Bad args to Pkg::PkgCommit"); + } + + zypp::ZYppCommitPolicy policy; + policy.restrictToMedia( medianr ); + + return CommitHelper(policy); +} + +/** @builtin GetBackupPath @short get current path for update backup of rpm config files @@ -2327,7 +1988,6 @@ return YCPVoid(); } - /** @builtin CreateBackups @short whether to create package backups during install or removal @@ -2348,7 +2008,6 @@ return YCPVoid (); } - /** @builtin PkgGetLicenseToConfirm @@ -2367,23 +2026,15 @@ { try { - // find the uninstalled (!) package - zypp::ResPool::byName_iterator it = std::find_if ( - zypp_ptr()->pool().byNameBegin(pkgname) - , zypp_ptr()->pool().byNameEnd(pkgname) - , zypp::functor::chain( - zypp::resfilter::ByUninstalled (), - zypp::resfilter::ByKind( zypp::ResTraits<zypp::Package>::kind ) ) - ); + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(pkgname); - if (it != zypp_ptr()->pool().byNameEnd(pkgname) && !it->status().isLicenceConfirmed()) + if (s && s->toInstall() && !s->hasLicenceConfirmed()) { - // cast to Package object - zypp::Package::constPtr package = zypp::dynamic_pointer_cast<const zypp::Package>(it->resolvable()); - - // get the license - zypp::License license = package->licenseToConfirm(); - return YCPString(license); + zypp::Package::constPtr package = zypp::dynamic_pointer_cast<const zypp::Package>(s->candidateObj().resolvable()); + if (package) + { + return YCPString(package->licenseToConfirm()); + } } } catch (...) @@ -2410,38 +2061,12 @@ YCPMap ret; for ( int i = 0; i < packages->size(); ++i ) { - std::string pkgname = packages->value(i)->asString()->value(); + YCPString license = PkgGetLicenseToConfirm(packages->value(i)->asString()); - if (!pkgname.empty()) + // found a license to confirm? + if (!license->value().empty()) { - try - { - // find the uninstalled (!) package - zypp::ResPool::byName_iterator it = std::find_if( - zypp_ptr()->pool().byNameBegin(pkgname) - , zypp_ptr()->pool().byNameEnd(pkgname) - , zypp::functor::chain( - zypp::resfilter::ByUninstalled (), - zypp::resfilter::ByKind( zypp::ResTraits<zypp::Package>::kind ) ) - ); - - // found a package? - if (it != zypp_ptr()->pool().byNameEnd(pkgname)) - { - // cast to Package object - zypp::Package::constPtr package = zypp::dynamic_pointer_cast<const zypp::Package>(it->resolvable()); - zypp::License license = package->licenseToConfirm(); - - // has the license already been confirmed? - if (!license.empty() && !it->status().isLicenceConfirmed()) - { - ret->add(packages->value(i), YCPString(license)); - } - } - } - catch (...) - { - } + ret->add(packages->value(i), license); } } @@ -2455,7 +2080,6 @@ @param string name of a package @return boolean true if the license has been successfuly confirmed */ -#warning This is bogus, as we have multiple matching packages YCPBoolean PkgModuleFunctions::PkgMarkLicenseConfirmed (const YCPString & package) { std::string pkgname = package->value(); @@ -2464,20 +2088,12 @@ { try { - // find the package - zypp::ResPool::byName_iterator it = std::find_if( - zypp_ptr()->pool().byNameBegin(pkgname) - , zypp_ptr()->pool().byNameEnd(pkgname) - , zypp::functor::chain( - zypp::resfilter::ByUninstalled (), - zypp::resfilter::ByKind( zypp::ResTraits<zypp::Package>::kind ) ) - ); + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(pkgname); - if (it != zypp_ptr()->pool().byNameEnd(pkgname)) + if (s && s->toInstall() && !s->hasLicenceConfirmed()) { - // confirm the license - it->status().setLicenceConfirmed(true); - return YCPBoolean( true ); + s->setLicenceConfirmed(); + return YCPBoolean(true); } } catch (...) @@ -2506,3 +2122,4 @@ return YCPBoolean(false); } + Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.cc?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.cc (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.cc Tue May 10 20:10:47 2011 @@ -175,7 +175,10 @@ : Y2Namespace() , _target_root( "/" ) , zypp_pointer(NULL) + , last_reported_repo(-1) + , last_reported_mediumnr(-1) ,_callbackHandler( *new CallbackHandler( ) ) + , _target_loaded(false) { registerFunctions (); @@ -230,6 +233,15 @@ return zypp_pointer; } +zypp::RepoManager PkgModuleFunctions::CreateRepoManager() +{ + // set path option, use root dir as a prefix for the default directory + zypp::RepoManagerOptions repo_options(_target_root); + + y2milestone("Path to repository files: %s", repo_options.knownReposPath.asString().c_str()); + + return zypp::RepoManager(repo_options); +} /** * Destructor. Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.h?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.h (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgModuleFunctions.h Tue May 10 20:10:47 2011 @@ -42,9 +42,12 @@ #include <zypp/Pathname.h> #include <zypp/Url.h> #include <zypp/Arch.h> +#include <zypp/RepoManager.h> #include <zypp/DiskUsageCounter.h> #include "PkgError.h" - +#include "YRepo.h" +#include "Utils.h" +#include "ServiceManager.h" // textdomain extern "C" { @@ -59,7 +62,6 @@ // define new _ macro #define _(MSG) ::dgettext("pkg-bindings", MSG) - /** * A simple class for package management access */ @@ -75,6 +77,16 @@ protected: + // container for the internal structure + typedef std::vector<YRepo_Ptr> RepoCont; + + zypp::RepoManager CreateRepoManager(); + ServiceManager service_manager; + + public: + typedef RepoCont::size_type RepoId; + protected: + zypp::Pathname _target_root; std::set<std::string> _broken_sources; @@ -94,6 +106,20 @@ private: // source related + YCPValue CommitHelper(const zypp::ZYppCommitPolicy &policy); + + zypp::Product::constPtr base_product; + RepoId last_reported_repo; + int last_reported_mediumnr; + + bool CreateBaseProductSymlink(); + + // all known installation sources + RepoCont repos; + + // helper + YCPValue PkgMediaSizesOrCount (bool sizes, bool download_size=false); + bool DoProvideNameKind( const std::string & name, zypp::Resolvable::Kind kind, zypp::Arch architecture, const std::string& version, const bool onlyNeeded = false); bool DoRemoveNameKind( const std::string & name, zypp::Resolvable::Kind kind); @@ -101,7 +127,7 @@ bool DoRemoveAllKind(zypp::Resolvable::Kind kind); bool DoAllKind(zypp::Resolvable::Kind kind, bool provide); YCPValue GetPkgLocation(const YCPString& p, bool full_path); - YCPValue PkgProp( zypp::PoolItem item ); + YCPValue PkgProp( const zypp::PoolItem &item ); void SetCurrentDU(); @@ -128,16 +154,30 @@ **/ CallbackHandler & _callbackHandler; + bool _target_loaded; + PkgError _last_error; /** * Logging helper: - * call zypp::SourceManager::sourceManager()->findSource - * and in case of exception, log error and setLastError AND RETHROW + * search for a repository and in case of exception, log error + * and setLastError AND RETHROW */ - //zypp::Source_Ref logFindSource (zypp::SourceManager::SourceId id); + YRepo_Ptr logFindRepository(RepoId id); + + RepoId logFindAlias(const std::string &alias) const; + + YCPMap Resolvable2YCPMap(const zypp::PoolItem &item, const std::string &req_kind, bool dependencies); + + YCPValue SourceProvideDirectoryInternal(const YCPInteger& id, const YCPInteger& mid, const YCPString& d, const YCPBoolean &optional, const YCPBoolean &recursive, bool check_signatures); + YCPValue SourceProvideFileCommon(const YCPInteger &id, + const YCPInteger &mid, + const YCPString& f, + const bool optional, + const bool check_signatures, + const bool digested); +public: - public: // general /* TYPEINFO: void() */ YCPValue InstSysMode (); Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.cc?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.cc (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.cc Tue May 10 20:10:47 2011 @@ -0,0 +1,25 @@ + + +#include "PkgProgress.h" +#include "log.h" + +#include <y2/Y2Function.h> + +void PkgProgress::Start( const std::string &process, const std::list<std::string> &stages, + const std::string &help) +{ +} + + +void PkgProgress::NextStage() +{ +} + +void PkgProgress::Done() +{ +} + +PkgProgress::~PkgProgress() +{ +} + Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.h?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.h (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgProgress.h Tue May 10 20:10:47 2011 @@ -0,0 +1,38 @@ +/* + File: PkgProgress.h + + Author: Ladislav Slezák <lslezak@novell.com> +/-*/ + +#ifndef PkgProgress_h +#define PkgProgress_h + +#include <string> +#include <list> + +//class PkgFunctions::CallbackHandler; +#include <PkgModuleFunctions.h> +#include <Callbacks.YCP.h> + + +#include <zypp/ProgressData.h> +#include <boost/bind.hpp> + +class PkgProgress +{ + public: + + PkgProgress(PkgModuleFunctions::CallbackHandler &handler_ref) + {} + + void Start( const std::string &process, const std::list<std::string> &stages, const std::string &help); + + void NextStage(); + + void Done(); + + ~PkgProgress(); +}; + +#endif + Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.cc?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.cc (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.cc Tue May 10 20:10:47 2011 @@ -0,0 +1,56 @@ +/* ------------------------------------------------------------------------------ + * Copyright (c) 2008 Novell, Inc. All Rights Reserved. + * + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of version 2 of the GNU General Public License as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may find + * current contact information at www.novell.com. + * ------------------------------------------------------------------------------ + */ + + +#include "PkgService.h" + +PkgService::PkgService() : _deleted(false), _old_alias() +{ +} + +PkgService::PkgService(const zypp::ServiceInfo &s, const std::string &old_alias) : + zypp::ServiceInfo(s), _deleted(false), _old_alias(old_alias) +{ +} + +PkgService::PkgService(const PkgService &s) : + zypp::ServiceInfo(s), _deleted(s._deleted), _old_alias(s._old_alias) +{ +} + +PkgService::~PkgService() +{ +} + +bool PkgService::isDeleted() const +{ + return _deleted; +} + +void PkgService::setDeleted() +{ + _deleted = true; +} + +std::string PkgService::origAlias() const +{ + return _old_alias; +} + Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.h?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.h (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/PkgService.h Tue May 10 20:10:47 2011 @@ -0,0 +1,50 @@ +/* ------------------------------------------------------------------------------ + * Copyright (c) 2008 Novell, Inc. All Rights Reserved. + * + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of version 2 of the GNU General Public License as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may find + * current contact information at www.novell.com. + * ------------------------------------------------------------------------------ + */ + +#include <string> +#include <zypp/ServiceInfo.h> + +// Extend zypp::ServiceInfo class to contain "deleted" flag and original service alias +class PkgService : public zypp::ServiceInfo +{ + public: + + PkgService(); + + PkgService(const zypp::ServiceInfo &s, const std::string &old_alias = ""); + + PkgService(const PkgService &s); + + ~PkgService(); + + bool isDeleted() const; + + void setDeleted(); + + std::string origAlias() const; + + + private: + + bool _deleted; + std::string _old_alias; +}; + + Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Resolvable.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Resolvable.cc?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Resolvable.cc (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Resolvable.cc Tue May 10 20:10:47 2011 @@ -33,36 +33,45 @@ #include <ycp/YCPList.h> #include <ycp/YCPMap.h> -#include <zypp/SourceManager.h> +#include <zypp/Url.h> +#include <zypp/Package.h> #include <zypp/Product.h> #include <zypp/Patch.h> #include <zypp/Pattern.h> -#include <zypp/Language.h> #include <zypp/base/PtrTypes.h> #include <zypp/Dep.h> -#include <zypp/CapSet.h> #include <zypp/PoolItem.h> #include <zypp/base/Algorithm.h> +#include <zypp/sat/LocaleSupport.h> +#include <zypp/parser/ProductFileReader.h> +#include <zypp/base/Regex.h> #include <set> /////////////////////////////////////////////////////////////////// -// ------------------------ /** @builtin ResolvableInstallArchVersion @short Install all resolvables with selected name, architecture and kind. Use it only in a special case, ResolvableInstall() should be prefrerred. - @param name_r name of the resolvable, if empty ("") install all resolvables of the kind - @param kind_r kind of resolvable, can be `product, `patch, `package, `selection or `pattern - @param arch architecture of the resolvable - @param vers Required version of the resolvable, empty string means any version + @param name_r name of the resolvable + @param kind_r kind of resolvable, can be `product, `patch, `package, `srcpackage or `pattern + @param arch architecture of the resolvable, empty means the best architecture + @param vers Required version of the resolvable, empty string means the best version @return boolean false if failed */ YCPValue PkgModuleFunctions::ResolvableInstallArchVersion( const YCPString& name_r, const YCPSymbol& kind_r, const YCPString& arch, const YCPString& vers ) { + std::string name(name_r.isNull() ? "" : name_r->value()); + + if (name.empty()) + { + y2error("Empty name"); + return YCPBoolean(false); + } + zypp::Resolvable::Kind kind; - + std::string req_kind = kind_r->symbol (); std::string arch_str = arch->value(); @@ -73,19 +82,19 @@ zypp::Arch architecture(arch_str); if( req_kind == "product" ) { - kind = zypp::ResTraits<zypp::Product>::kind; + kind = zypp::ResKind::product; } else if ( req_kind == "patch" ) { - kind = zypp::ResTraits<zypp::Patch>::kind; + kind = zypp::ResKind::patch; } else if ( req_kind == "package" ) { - kind = zypp::ResTraits<zypp::Package>::kind; + kind = zypp::ResKind::package; } - else if ( req_kind == "selection" ) { - kind = zypp::ResTraits<zypp::Selection>::kind; + else if ( req_kind == "srcpackage" ) { + kind = zypp::ResKind::srcpackage; } else if ( req_kind == "pattern" ) { - kind = zypp::ResTraits<zypp::Pattern>::kind; + kind = zypp::ResKind::pattern; } else { @@ -93,78 +102,130 @@ return YCPBoolean(false); } - std::string version_str = vers->value(); + std::string version_str = vers->value(); + bool ret = false; + + zypp::ResPoolProxy selectablePool(zypp::ResPool::instance().proxy()); + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(kind, name); + + if (s) + { + // install the required version and arch + for_(avail_it, s->availableBegin(), s->availableEnd()) + { + // get the resolvable + zypp::Resolvable::constPtr res = avail_it->resolvable(); - return YCPBoolean( - (name_r->value().empty()) - ? DoProvideAllKind(kind) - : DoProvideNameKind (name_r->value(), kind, architecture, version_str) - ); + // check version and arch + if (res->arch() == architecture && res->edition() == version_str) + { + // install the preselected candidate + s->setCandidate(*avail_it); + ret = s->setToInstall(whoWantsIt); + break; + } + } + + if (!ret) + { + y2error("Required version and arch of %s:%s was not found", req_kind.c_str(), name.c_str()); + } + } + else + { + y2error("Required selectable %s:%s was not found", req_kind.c_str(), name.c_str()); + } + + return YCPBoolean(ret); +} + +bool ResolvableInstallOrDelete(const YCPString& name_r, const YCPSymbol& kind_r, bool install) +{ + zypp::Resolvable::Kind kind; + + std::string req_kind = kind_r->symbol (); + + if( req_kind == "product" ) { + kind = zypp::ResKind::product; + } + else if ( req_kind == "patch" ) { + kind = zypp::ResKind::patch; + } + else if ( req_kind == "package" ) { + kind = zypp::ResKind::package; + } + else if ( req_kind == "srcpackage" ) { + kind = zypp::ResKind::srcpackage; + } + else if ( req_kind == "pattern" ) { + kind = zypp::ResKind::pattern; + } + else + { + y2error("Unknown symbol: %s", req_kind.c_str()); + return false; + } + + std::string name(name_r.isNull() ? "" : name_r->value()); + + if (name.empty()) + { + y2error("Empty resolvable name"); + return false; + } + + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(kind, name); + + if (s) + { + y2milestone("%s: %s:%s ", install ? "Installing" : "Removing", req_kind.c_str(), name.c_str()); + return install ? s->setToInstall(zypp::ResStatus::APPL_HIGH): + s->setToDelete(zypp::ResStatus::APPL_HIGH); + } + else + { + y2error("Resolvable %s:%s was not found", req_kind.c_str(), name.c_str()); + } + + return false; } // ------------------------ /** @builtin ResolvableInstall @short Install all resolvables with selected name and kind - @param name_r name of the resolvable, if empty ("") install all resolvables of the kind - @param kind_r kind of resolvable, can be `product, `patch, `package, `selection or `pattern + @param name_r name of the resolvable + @param kind_r kind of resolvable, can be `product, `patch, `package, `srcpackage or `pattern @return boolean false if failed */ YCPValue PkgModuleFunctions::ResolvableInstall( const YCPString& name_r, const YCPSymbol& kind_r ) { - return ResolvableInstallArchVersion(name_r, kind_r, YCPString(zypp_ptr()->architecture().asString()), YCPString("")); + // true = install + return YCPBoolean(ResolvableInstallOrDelete(name_r, kind_r, true)); } // ------------------------ /** @builtin ResolvableRemove @short Removes all resolvables with selected name and kind - @param name_r name of the resolvable, if empty ("") remove all resolvables of the kind - @param kind_r kind of resolvable, can be `product, `patch, `package, `selection or `pattern + @param name_r name of the resolvable + @param kind_r kind of resolvable, can be `product, `patch, `package, `srcpackage or `pattern @return boolean false if failed */ YCPValue PkgModuleFunctions::ResolvableRemove ( const YCPString& name_r, const YCPSymbol& kind_r ) { - zypp::Resolvable::Kind kind; - - std::string req_kind = kind_r->symbol (); - - if( req_kind == "product" ) { - kind = zypp::ResTraits<zypp::Product>::kind; - } - else if ( req_kind == "patch" ) { - kind = zypp::ResTraits<zypp::Patch>::kind; - } - else if ( req_kind == "package" ) { - kind = zypp::ResTraits<zypp::Package>::kind; - } - else if ( req_kind == "selection" ) { - kind = zypp::ResTraits<zypp::Selection>::kind; - } - else if ( req_kind == "pattern" ) { - kind = zypp::ResTraits<zypp::Pattern>::kind; - } - else - { - y2error("Pkg::ResolvableRemove: unknown symbol: %s", req_kind.c_str()); - return YCPBoolean(false); - } - - return YCPBoolean( - (name_r->value().empty()) - ? DoRemoveAllKind(kind) - : DoRemoveNameKind (name_r->value(), kind) - ); + // false = remove + return YCPBoolean(ResolvableInstallOrDelete(name_r, kind_r, false)); } // ------------------------ /** @builtin ResolvableNeutral @short Remove all transactions from all resolvables with selected name and kind - @param name_r name of the resolvable, if empty ("") use all resolvables of the kind - @param kind_r kind of resolvable, can be `product, `patch, `package, `selection or `pattern + @param name_r name of the resolvable, if empty ("") use all resolvables of the kind + @param kind_r kind of resolvable, can be `product, `patch, `package, `srcpackage or `pattern @param force_r remove the transactions even on USER level - default is APPL_HIGH (use true value only if really needed!) @return boolean false if failed */ @@ -172,25 +233,25 @@ PkgModuleFunctions::ResolvableNeutral ( const YCPString& name_r, const YCPSymbol& kind_r, const YCPBoolean& force_r ) { zypp::Resolvable::Kind kind; - + std::string req_kind = kind_r->symbol(); std::string name = name_r->value(); bool force = force_r->value(); if( req_kind == "product" ) { - kind = zypp::ResTraits<zypp::Product>::kind; + kind = zypp::ResKind::product; } else if ( req_kind == "patch" ) { - kind = zypp::ResTraits<zypp::Patch>::kind; + kind = zypp::ResKind::patch; } else if ( req_kind == "package" ) { - kind = zypp::ResTraits<zypp::Package>::kind; + kind = zypp::ResKind::package; } - else if ( req_kind == "selection" ) { - kind = zypp::ResTraits<zypp::Selection>::kind; + else if ( req_kind == "srcpackage" ) { + kind = zypp::ResKind::srcpackage; } else if ( req_kind == "pattern" ) { - kind = zypp::ResTraits<zypp::Pattern>::kind; + kind = zypp::ResKind::pattern; } else { @@ -202,24 +263,20 @@ try { - for (zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(kind); - it != zypp_ptr()->pool().byKindEnd(kind); - ++it) + if (name.empty()) { - if (name.empty() || (*it)->name() == name) + for (zypp::ResPoolProxy::const_iterator it = zypp_ptr()->poolProxy().byKindBegin(kind); + it != zypp_ptr()->poolProxy().byKindEnd(kind); + ++it) { - if (!it->status().resetTransact(whoWantsIt)) - { - ret = false; - } - - // force neutralization on the user level - if (force && !it->status().resetTransact(zypp::ResStatus::USER)) - { - ret = false; - } + ret = (*it)->unset(force ? zypp::ResStatus::USER : whoWantsIt) && ret; } } + else + { + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(kind, name); + ret = s ? s->unset(force ? zypp::ResStatus::USER : whoWantsIt) : false; + } } catch (...) { @@ -234,32 +291,32 @@ @builtin ResolvableSetSoftLock @short Soft lock - it prevents the solver from re-selecting item if it's recommended (if it's required it will be selected). - @param name_r name of the resolvable, if empty ("") use all resolvables of the kind - @param kind_r kind of resolvable, can be `product, `patch, `package, `selection or `pattern + @param name_r name of the resolvable, if empty ("") use all resolvables of the kind + @param kind_r kind of resolvable, can be `product, `patch, `package, `srcpackage or `pattern @return boolean false if failed */ YCPValue PkgModuleFunctions::ResolvableSetSoftLock ( const YCPString& name_r, const YCPSymbol& kind_r ) { zypp::Resolvable::Kind kind; - + std::string req_kind = kind_r->symbol(); std::string name = name_r->value(); if( req_kind == "product" ) { - kind = zypp::ResTraits<zypp::Product>::kind; + kind = zypp::ResKind::product; } else if ( req_kind == "patch" ) { - kind = zypp::ResTraits<zypp::Patch>::kind; + kind = zypp::ResKind::patch; } else if ( req_kind == "package" ) { - kind = zypp::ResTraits<zypp::Package>::kind; + kind = zypp::ResKind::package; } - else if ( req_kind == "selection" ) { - kind = zypp::ResTraits<zypp::Selection>::kind; + else if ( req_kind == "srcpackage" ) { + kind = zypp::ResKind::package; } else if ( req_kind == "pattern" ) { - kind = zypp::ResTraits<zypp::Pattern>::kind; + kind = zypp::ResKind::pattern; } else { @@ -271,18 +328,20 @@ try { - for (zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(kind); - it != zypp_ptr()->pool().byKindEnd(kind); - ++it) + if (name.empty()) { - if (name.empty() || (*it)->name() == name) + for (zypp::ResPoolProxy::const_iterator it = zypp_ptr()->poolProxy().byKindBegin(kind); + it != zypp_ptr()->poolProxy().byKindEnd(kind); + ++it) { - if (!it->status().setSoftLock(whoWantsIt)) - { - ret = false; - } + ret = (*it)->theObj().status().setSoftLock(whoWantsIt) && ret; } } + else + { + zypp::ui::Selectable::Ptr s = zypp::ui::Selectable::get(kind, name); + ret = s ? s->theObj().status().setSoftLock(whoWantsIt) : false; + } } catch (...) { @@ -292,22 +351,92 @@ return YCPBoolean(ret); } - /** @builtin ResolvableProperties @short Return properties of resolvable @description return list of resolvables of selected kind with required name - + @param name name of the resolvable, if empty returns all resolvables of the kind - @param kind_r kind of resolvable, can be `product, `patch, `package, `selection, `pattern or `language + @param kind_r kind of resolvable, can be `product, `patch, `package, `pattern or `language @param version version of the resolvable, if empty all versions are returned @return list<map<string,any>> list of $[ "name":string, "version":string, "arch":string, "source":integer, "status":symbol, "locked":boolean ] maps - status is `installed, `selected or `available, source is source ID or -1 if the resolvable is installed in the target + status is `installed, `removed, `selected or `available, source is source ID or -1 if the resolvable is installed in the target if status is `available and locked is true then the object is set to taboo, if status is `installed and locked is true then the object locked + if status is `selected or `removed there is extra key "transact_by" : symbol, where symbol is `user (the highest level), + `app_high (selected by Yast), `app_low and `solver (the lowest level) + + @example + Additionally to keys returned for all resolvables, there also some + resolvable-specific ones: + + `product keys: + + "category" + + "display_name" + + "short_name" + + "update_urls" + + "flags" + + "extra_urls" + + "optional_urls" + + "register_urls" + + "relnotes_urls" + + "smolt_urls" + + "register_target" + + "register_release" + + "flavor" + + "replaces" + + "name" + + "version" + + "arch" + + "description" + + "display_name" + + "short_name" + + "product_file" -> string : product file (full file name with target root prefix) + + "upgrades" -> list<map> : parsed data from the product file (upgrades section) + + "name" -> string + + "summary" -> string + + "repository" -> string : URL path + + "notify" -> boolean + + "status" -> string + `patch keys: + + "interactive" + + "reboot_needed" + + "relogin_needed" + + "affects_pkg_manager" + + "is_needed" + `package keys: + + "path" + + "location" + `pattern keys: + + "category" + + "user_visible" + + "default" + + "icon" + + "script" + + "order" + `language keys: + + "code" + + "packages" + + "requested" + + If dependencies are requested, this keys are additionally used: + + "provides" + + "prerequires" + + "requires" + + "conflicts" + + "obsoletes" + + "recommends" + + "suggests" + + "enhances" + + "supplements" + + All the dependencies use maps with these keys: + + "res_kind" + + "name" + + "dep_kind" */ YCPValue @@ -329,211 +458,485 @@ return ResolvablePropertiesEx (name, kind_r, version, true); } -YCPValue -PkgModuleFunctions::ResolvablePropertiesEx(const YCPString& name, const YCPSymbol& kind_r, const YCPString& version, bool dependencies) +static std::string TransactToString(zypp::ResStatus::TransactByValue trans) { - zypp::Resolvable::Kind kind; - std::string req_kind = kind_r->symbol (); - std::string nm = name->value(); - std::string vers = version->value(); - YCPList ret; + std::string ret; - if( req_kind == "product" ) { - kind = zypp::ResTraits<zypp::Product>::kind; - } - else if ( req_kind == "patch" ) { - kind = zypp::ResTraits<zypp::Patch>::kind; - } - else if ( req_kind == "package" ) { - kind = zypp::ResTraits<zypp::Package>::kind; + switch(trans) + { + case zypp::ResStatus::USER : ret = "user"; break; + case zypp::ResStatus::APPL_HIGH : ret = "app_high"; break; + case zypp::ResStatus::APPL_LOW : ret = "app_low"; break; + case zypp::ResStatus::SOLVER : ret = "solver"; break; } - else if ( req_kind == "selection" ) { - kind = zypp::ResTraits<zypp::Selection>::kind; + + return ret; +} + +YCPMap PkgModuleFunctions::Resolvable2YCPMap(const zypp::PoolItem &item, const std::string &req_kind, bool dependencies) +{ + YCPMap info; + + info->add(YCPString("name"), YCPString(item->name())); + info->add(YCPString("version"), YCPString(item->edition().asString())); + info->add(YCPString("arch"), YCPString(item->arch().asString())); + info->add(YCPString("description"), YCPString(item->description())); + + std::string resolvable_summary = item->summary(); + if (resolvable_summary.size() > 0) + { + info->add(YCPString("summary"), YCPString(resolvable_summary)); } - else if ( req_kind == "pattern" ) { - kind = zypp::ResTraits<zypp::Pattern>::kind; + + // status + std::string stat; + + zypp::ResStatus status = item.status(); + + if (status.isToBeInstalled()) + { + stat = "selected"; } - else if ( req_kind == "language" ) { - kind = zypp::ResTraits<zypp::Language>::kind; + else if (status.isInstalled() || status.isSatisfied()) + { + if (status.isToBeUninstalled()) + { + stat = "removed"; + } + else + { + stat = "installed"; + } } else { - y2error("Pkg::ResolvableProperties: unknown symbol: %s", req_kind.c_str()); - return ret; + stat = "available"; } - std::list<zypp::SourceManager::SourceId> source_ids = zypp::SourceManager::sourceManager()->enabledSources(); - - try - { - for (zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(kind); - it != zypp_ptr()->pool().byKindEnd(kind); - ++it) + info->add(YCPString("transact_by"), YCPSymbol(TransactToString(status.getTransactByValue()))); + + info->add(YCPString("status"), YCPSymbol(stat)); + + // is the resolvable locked? (Locked or Taboo in the UI) + info->add(YCPString("locked"), YCPBoolean(status.isLocked())); + + // source + info->add(YCPString("source"), YCPInteger(logFindAlias(item->repoInfo().alias()))); + + // add license info if it is defined + std::string license = item->licenseToConfirm(); + if (!license.empty()) + { + info->add(YCPString("license_confirmed"), YCPBoolean(item.status().isLicenceConfirmed())); + info->add(YCPString("license"), YCPString(license)); + } + + info->add(YCPString("download_size"), YCPInteger(item->downloadSize())); + info->add(YCPString("inst_size"), YCPInteger(item->installSize())); + + info->add(YCPString("medium_nr"), YCPInteger(item->mediaNr())); + info->add(YCPString("vendor"), YCPString(item->vendor())); + + + // package specific info + if( req_kind == "package" ) + { + zypp::Package::constPtr pkg = boost::dynamic_pointer_cast<const zypp::Package>(item.resolvable()); + if ( pkg ) { - if ((nm.empty() || nm == (*it)->name()) - && (vers.empty() || vers == (*it)->edition().asString())) + std::string tmp = pkg->location().filename().asString(); + if (!tmp.empty()) { - YCPMap info; + info->add(YCPString("path"), YCPString(tmp)); + } + + tmp = pkg->location().filename().basename(); + if (!tmp.empty()) + { + info->add(YCPString("location"), YCPString(tmp)); + } + } else + { + y2error("package %s is not a package", item->name().c_str() ); + } + } + // product specific info + else if( req_kind == "product" ) { + zypp::Product::constPtr product = boost::dynamic_pointer_cast<const zypp::Product>(item.resolvable()); + if ( !product ) + { + y2error("product %s is not a product", item->name().c_str() ); + return YCPMap(); + } - info->add(YCPString("name"), YCPString((*it)->name())); - info->add(YCPString("version"), YCPString((*it)->edition().asString())); - info->add(YCPString("arch"), YCPString((*it)->arch().asString())); - info->add(YCPString("description"), YCPString((*it)->description())); + std::string category(product->isTargetDistribution() ? "base" : "addon"); - std::string resolvable_summary = (*it)->summary(); - if (resolvable_summary.size() > 0) - { - info->add(YCPString("summary"), YCPString((*it)->summary())); - } + info->add(YCPString("category"), YCPString(category)); + info->add(YCPString("type"), YCPString(category)); + info->add(YCPString("relnotes_url"), YCPString(product->releaseNotesUrls().first().asString())); + + std::string product_summary = product->summary(); + if (product_summary.size() > 0) + { + info->add(YCPString("display_name"), YCPString(product_summary)); + } + + std::string product_shortname = product->shortName(); + if (product_shortname.size() > 0) + { + info->add(YCPString("short_name"), YCPString(product_shortname)); + } + // use summary for the short name if it's defined + else if (product_summary.size() > 0) + { + info->add(YCPString("short_name"), YCPString(product_summary)); + } + + YCPList updateUrls(asYCPList(product->updateUrls())); + info->add(YCPString("update_urls"), updateUrls); + + YCPList flags; + std::list<std::string> pflags = product->flags(); + for (std::list<std::string>::const_iterator flag_it = pflags.begin(); + flag_it != pflags.end(); ++flag_it) + { + flags->add(YCPString(*flag_it)); + } + info->add(YCPString("flags"), flags); + + YCPList extraUrls( asYCPList(product->extraUrls()) ); + if ( extraUrls.size() ) + { + info->add(YCPString("extra_urls"), extraUrls); + } + + YCPList optionalUrls( asYCPList(product->optionalUrls()) ); + if ( optionalUrls.size() ) + { + info->add(YCPString("optional_urls"), optionalUrls); + } + + YCPList registerUrls( asYCPList(product->registerUrls()) ); + if ( registerUrls.size() ) + { + info->add(YCPString("register_urls"), registerUrls); + } + + YCPList smoltUrls( asYCPList(product->smoltUrls()) ); + if ( smoltUrls.size() ) + { + info->add(YCPString("smolt_urls"), smoltUrls); + } + + YCPList relNotesUrls(asYCPList(product->releaseNotesUrls())); + if ( relNotesUrls.size() ) + { + info->add(YCPString("relnotes_urls"), relNotesUrls); + } + + // registration data + info->add(YCPString("register_target"), YCPString(product->registerTarget())); + info->add(YCPString("register_release"), YCPString(product->registerRelease())); + + // Live CD, FTP Edition... + info->add(YCPString("flavor"), YCPString(product->flavor())); + + // get the installed Products it would replace. + zypp::Product::ReplacedProducts replaced(product->replacedProducts()); + + if (!replaced.empty()) + { + YCPList rep_prods; + + // add the products to the list + for_( it, replaced.begin(), replaced.end() ) + { + // The current replaced Product. + zypp::Product::constPtr replacedProduct(*it); - // status - std::string stat; + if (!replacedProduct) continue; - if (it->status().isToBeInstalled()) + YCPMap rprod; + rprod->add(YCPString("name"), YCPString(replacedProduct->name())); + rprod->add(YCPString("version"), YCPString(replacedProduct->edition().asString())); + rprod->add(YCPString("arch"), YCPString(replacedProduct->arch().asString())); + rprod->add(YCPString("description"), YCPString(replacedProduct->description())); + + std::string product_summary = replacedProduct->summary(); + if (product_summary.size() > 0) { - stat = "selected"; + rprod->add(YCPString("display_name"), YCPString(product_summary)); } - else if (it->status().isInstalled() || it->status().isSatisfied()) + + std::string product_shortname = replacedProduct->shortName(); + if (product_shortname.size() > 0) { - stat = it->status().isToBeUninstalled() ? "removed" : "installed"; + rprod->add(YCPString("short_name"), YCPString(product_shortname)); } - else + // use summary for the short name if it's defined + else if (product_summary.size() > 0) { - stat = "available"; + rprod->add(YCPString("short_name"), YCPString(product_summary)); } + } - info->add(YCPString("status"), YCPSymbol(stat)); + info->add(YCPString("replaces"), rep_prods); + } - // is the resolvable locked? (Locked or Taboo in the UI) - info->add(YCPString("locked"), YCPBoolean(it->status().isLocked())); + std::string product_file; - // source - zypp::Source_Ref res_src = (*it)->source(); - info->add(YCPString("source"), YCPInteger(res_src.numericId())); - - // product specific info - if( req_kind == "product" ) { - zypp::Product::constPtr product = boost::dynamic_pointer_cast<const zypp::Product>(it->resolvable()); - info->add(YCPString("category"), YCPString(product->category())); - info->add(YCPString("vendor"), YCPString(product->vendor())); - info->add(YCPString("relnotes_url"), YCPString(product->releaseNotesUrl().asString())); + // add reference file in /etc/products.d + if (status.isInstalled()) + { + product_file = (_target_root + "/etc/products.d/" + product->referenceFilename()).asString(); + y2milestone("Parsing product file %s", product_file.c_str()); + const zypp::parser::ProductFileData productFileData = zypp::parser::ProductFileReader::scanFile(product_file); - std::string product_summary = product->summary(); - if (product_summary.size() > 0) - { - info->add(YCPString("display_name"), YCPString(product_summary)); - } + YCPList upgrade_list; - std::string product_shortname = product->shortName(); - if (product_shortname.size() > 0) - { - info->add(YCPString("short_name"), YCPString(product_shortname)); - } - // use summary for the short name if it's defined - else if (product_summary.size() > 0) - { - info->add(YCPString("short_name"), YCPString(product_summary)); - } + for_( upit, productFileData.upgrades().begin(), productFileData.upgrades().end() ) + { + const zypp::parser::ProductFileData::Upgrade & upgrade( *upit ); + YCPMap upgrades; + upgrades->add(YCPString("name"), YCPString(upgrade.name())); + upgrades->add(YCPString("summary"), YCPString(upgrade.summary())); + upgrades->add(YCPString("repository"), YCPString(upgrade.repository())); + upgrades->add(YCPString("notify"), YCPBoolean(upgrade.notify())); + upgrades->add(YCPString("status"), YCPString(upgrade.status())); + upgrades->add(YCPString("product"), YCPString(upgrade.product())); - YCPList updateUrls; - std::list<zypp::Url> pupdateUrls = product->updateUrls(); - for (std::list<zypp::Url>::const_iterator it = pupdateUrls.begin(); it != pupdateUrls.end(); ++it) - { - updateUrls->add(YCPString(it->asString())); - } - info->add(YCPString("update_urls"), updateUrls); + upgrade_list->add(upgrades); + } - YCPList flags; - std::list<std::string> pflags = product->flags(); - for (std::list<std::string>::const_iterator flag_it = pflags.begin(); - flag_it != pflags.end(); ++flag_it) - { - flags->add(YCPString(*flag_it)); - } - info->add(YCPString("flags"), flags); + info->add(YCPString("upgrades"), upgrade_list); + } + else + { + // get the package + zypp::sat::Solvable refsolvable = product->referencePackage(); + + if (refsolvable != zypp::sat::Solvable::noSolvable) + { + // create a package pointer from the SAT solvable + zypp::Package::Ptr refpkg(zypp::make<zypp::Package>(refsolvable)); + + if (refpkg) + { + // get the package files + zypp::Package::FileList files( refpkg->filelist() ); + y2milestone("The reference package has %d files", files.size()); + + zypp::str::smatch what; + const zypp::str::regex product_file_regex("^/etc/products\\.d/(.*\\.prod)$"); - std::list<zypp::Url> pextraUrls = product->extraUrls(); - if (pextraUrls.size() > 0) + // find the product file + for_(iter, files.begin(), files.end()) { - YCPList extraUrls; - for (std::list<zypp::Url>::const_iterator it = pextraUrls.begin(); it != pextraUrls.end(); ++it) + if (zypp::str::regex_match(*iter, what, product_file_regex)) { - extraUrls->add(YCPString(it->asString())); + product_file = what[1]; + break; } - info->add(YCPString("extra_urls"), extraUrls); } + } + } + } + + if (product_file.empty()) + { + y2warning("The product file has not been found"); + } + else + { + y2milestone("Found product file %s", product_file.c_str()); + info->add(YCPString("product_file"), YCPString(product_file)); + } + } + // pattern specific info + else if ( req_kind == "pattern" ) { + zypp::Pattern::constPtr pattern = boost::dynamic_pointer_cast<const zypp::Pattern>(item.resolvable()); + info->add(YCPString("category"), YCPString(pattern->category())); + info->add(YCPString("user_visible"), YCPBoolean(pattern->userVisible())); + info->add(YCPString("default"), YCPBoolean(pattern->isDefault())); + info->add(YCPString("icon"), YCPString(pattern->icon().asString())); + info->add(YCPString("script"), YCPString(pattern->script().asString())); + info->add(YCPString("order"), YCPString(pattern->order())); + } + // patch specific info + else if ( req_kind == "patch" ) + { + zypp::Patch::constPtr patch_ptr = boost::dynamic_pointer_cast<const zypp::Patch>(item.resolvable()); + + info->add(YCPString("interactive"), YCPBoolean(patch_ptr->interactive())); + info->add(YCPString("reboot_needed"), YCPBoolean(patch_ptr->rebootSuggested())); + info->add(YCPString("relogin_needed"), YCPBoolean(patch_ptr->reloginSuggested())); + info->add(YCPString("affects_pkg_manager"), YCPBoolean(patch_ptr->restartSuggested())); + info->add(YCPString("is_needed"), YCPBoolean(item.isBroken())); + } + + // dependency info + if (dependencies) + { + std::set<std::string> _kinds; + _kinds.insert("provides"); + _kinds.insert("prerequires"); + _kinds.insert("requires"); + _kinds.insert("conflicts"); + _kinds.insert("obsoletes"); + _kinds.insert("recommends"); + _kinds.insert("suggests"); + _kinds.insert("enhances"); + _kinds.insert("supplements"); + YCPList ycpdeps; + YCPList rawdeps; + for (std::set<std::string>::const_iterator kind_it = _kinds.begin(); + kind_it != _kinds.end(); ++kind_it) + { + try { + zypp::Dep depkind(*kind_it); + zypp::Capabilities deps = item.resolvable()->dep(depkind); + + // add raw dependencies + for_(it, deps.begin(), deps.end()) + { + YCPMap rawdep; + rawdep->add(YCPString(*kind_it), YCPString(it->asString())); + rawdeps->add(rawdep); + } + + zypp::sat::WhatProvides prv(deps); - std::list<zypp::Url> poptionalUrls = product->optionalUrls(); - if (poptionalUrls.size() > 0) + // resolve dependencies + for (zypp::sat::WhatProvides::const_iterator d = prv.begin(); d != prv.end(); ++d) + { + if (d->kind().asString().empty() || d->name().empty()) + { + y2debug("Empty kind or name: kind: %s, name: %s", d->kind().asString().c_str(), d->name().c_str()); + } + else { - YCPList optionalUrls; - for (std::list<zypp::Url>::const_iterator it = poptionalUrls.begin(); it != poptionalUrls.end(); ++it) + YCPMap ycpdep; + ycpdep->add (YCPString ("res_kind"), YCPString (d->kind().asString())); + ycpdep->add (YCPString ("name"), YCPString (d->name())); + ycpdep->add (YCPString ("dep_kind"), YCPString (*kind_it)); + + if (!ycpdeps.contains(ycpdep)) { - optionalUrls->add(YCPString(it->asString())); + ycpdeps->add (ycpdep); } - info->add(YCPString("optional_urls"), optionalUrls); } } + } + catch (...) + {} + } - // pattern specific info - if ( req_kind == "pattern" ) { - zypp::Pattern::constPtr pattern = boost::dynamic_pointer_cast<const zypp::Pattern>(it->resolvable()); - info->add(YCPString("category"), YCPString(pattern->category())); - info->add(YCPString("user_visible"), YCPBoolean(pattern->userVisible())); - info->add(YCPString("default"), YCPBoolean(pattern->isDefault())); - info->add(YCPString("icon"), YCPString(pattern->icon().asString())); - info->add(YCPString("script"), YCPString(pattern->script().asString())); - } + if (ycpdeps.size() > 0) + { + info->add (YCPString ("dependencies"), ycpdeps); + } + + if (rawdeps.size() > 0) + { + info->add (YCPString ("deps"), rawdeps); + } + } + + return info; +} + +YCPValue +PkgModuleFunctions::ResolvablePropertiesEx(const YCPString& name, const YCPSymbol& kind_r, const YCPString& version, bool dependencies) +{ + zypp::Resolvable::Kind kind; + std::string req_kind = kind_r->symbol (); + std::string nm = name->value(); + std::string vers = version->value(); + YCPList ret; + + if( req_kind == "product" ) { + kind = zypp::ResKind::product; + } + else if ( req_kind == "patch" ) { + kind = zypp::ResKind::patch; + } + else if ( req_kind == "package" ) { + kind = zypp::ResKind::package; + } + else if ( req_kind == "pattern" ) { + kind = zypp::ResKind::pattern; + } + else if ( req_kind == "language" ) + { + try + { + const zypp::LocaleSet &avlocales( zypp::ResPool::instance().getAvailableLocales() ); + + for_( it, avlocales.begin(), avlocales.end() ) + { + zypp::sat::LocaleSupport myLocale( *it ); + + YCPMap lang_map; + + lang_map->add(YCPString("name"), YCPString(myLocale.locale().name())); + lang_map->add(YCPString("code"), YCPString(myLocale.locale().code())); + lang_map->add(YCPString("packages"), YCPBoolean(myLocale.isAvailable())); + lang_map->add(YCPString("requested"), YCPBoolean(myLocale.isRequested())); + + ret->add(lang_map); + } + } + catch(const zypp::Exception &expt) + { + y2error("Caught exception: %s", expt.asString().c_str()); + _last_error.setLastError(ExceptionAsString(expt)); + return YCPVoid(); + } + + return ret; + } + else + { + y2error("Pkg::ResolvableProperties: unknown symbol: %s", req_kind.c_str()); + return ret; + } - // patch specific info - if ( req_kind == "patch" ) + try + { + for (zypp::ResPoolProxy::const_iterator it = zypp_ptr()->poolProxy().byKindBegin(kind); + it != zypp_ptr()->poolProxy().byKindEnd(kind); + ++it) + { + zypp::ui::Selectable::Ptr s = (*it); + + if (nm.empty() || nm == s->name()) + { + if (!s->installedEmpty()) { - zypp::Patch::constPtr patch_ptr = boost::dynamic_pointer_cast<const zypp::Patch>(it->resolvable()); - - info->add(YCPString("interactive"), YCPBoolean(patch_ptr->interactive())); - info->add(YCPString("reboot_needed"), YCPBoolean(patch_ptr->reboot_needed())); - info->add(YCPString("affects_pkg_manager"), YCPBoolean(patch_ptr->affects_pkg_manager())); - info->add(YCPString("is_needed"), YCPBoolean(it->status().isNeeded())); + // iterate over all installed packages + for_(inst_it, s->installedBegin(), s->installedEnd()) + { + // check version if required + if (vers.empty() || vers == inst_it->resolvable()->edition().asString()) + { + ret->add(Resolvable2YCPMap(*inst_it, req_kind, dependencies)); + } + } } - // dependency info - if (dependencies) + if (!s->availableEmpty()) { - std::set<std::string> _kinds; - _kinds.insert("provides"); - _kinds.insert("prerequires"); - _kinds.insert("requires"); - _kinds.insert("conflicts"); - _kinds.insert("obsoletes"); - _kinds.insert("recommends"); - _kinds.insert("suggests"); - _kinds.insert("freshens"); - _kinds.insert("enhances"); - _kinds.insert("supplements"); - YCPList ycpdeps; - for (std::set<std::string>::const_iterator kind_it = _kinds.begin(); - kind_it != _kinds.end(); ++kind_it) + // iterate over all available packages + for_(avail_it, s->availableBegin(), s->availableEnd()) { - try { - zypp::Dep depkind(*kind_it); - zypp::CapSet deps = it->resolvable()->dep(depkind); - for (zypp::CapSet::const_iterator d = deps.begin(); d != deps.end(); ++d) - { - YCPMap ycpdep; - ycpdep->add (YCPString ("res_kind"), YCPString (d->refers().asString())); - ycpdep->add (YCPString ("name"), YCPString (d->asString())); - ycpdep->add (YCPString ("dep_kind"), YCPString (*kind_it)); - ycpdeps->add (ycpdep); - } - + // check version if required + if (vers.empty() || vers == avail_it->resolvable()->edition().asString()) + { + ret->add(Resolvable2YCPMap(*avail_it, req_kind, dependencies)); } - catch (...) - {} } - info->add (YCPString ("dependencies"), ycpdeps); } - ret->add(info); } } } @@ -544,12 +947,33 @@ return ret; } +bool AnyResolvableHelper(zypp::Resolvable::Kind kind, bool to_install) +{ + for (zypp::ResPoolProxy::const_iterator it = zypp::ResPool::instance().proxy().byKindBegin(kind); + it != zypp::ResPool::instance().proxy().byKindEnd(kind); + ++it) + { + zypp::ui::Selectable::Fate fate = (*it)->fate(); + + if (to_install && fate == zypp::ui::Selectable::TO_INSTALL) + { + return true; + } + else if (!to_install && fate == zypp::ui::Selectable::TO_DELETE) + { + return true; + } + } + + return false; +} + /** @builtin ResolvableCountPatches @short Count patches which will be selected by ResolvablePreselectPatches() function @description Only non-optional patches are selected (even when `all parameter is passed!) - @param kind_r kind of preselected patches, can be `all, `interactive, `reboot_needed or `affects_pkg_manager + @param kind_r kind of preselected patches, can be `all, `interactive, `reboot_needed, `relogin_needed or `affects_pkg_manager @return integer number of preselected patches */ YCPValue @@ -581,81 +1005,59 @@ std::string kind = kind_r->symbol(); if (kind != "all" && kind != "interactive" && kind != "reboot_needed" - && kind != "affects_pkg_manager") + && kind != "affects_pkg_manager" && kind != "relogin_needed") { - return YCPError("Pkg::ResolvablePreselectPatches: Wrong parameter '" + kind + "', use: `all, `interactive, `reboot_needed or `affects_pkg_manager", YCPInteger(0LL)); + return YCPError("Pkg::ResolvablePreselectPatches: Wrong parameter '" + kind + "', use: `all, `interactive, `reboot_needed, `relogin_needed or `affects_pkg_manager", YCPInteger(0LL)); } y2milestone("Required kind of patches: %s", kind.c_str()); - std::set<zypp::PoolItem> patches_toinst; - - const zypp::ResPool & pool = zypp_ptr()->pool(); + long long needed_patches = 0LL; try { - zypp::ResPool::byKind_iterator - b = pool.byKindBegin<zypp::Patch>(), - e = pool.byKindEnd<zypp::Patch>(), - i = pool.byKindBegin<zypp::Patch>(); + // access to the Pool of Selectables + zypp::ResPoolProxy selectablePool(zypp::ResPool::instance().proxy()); - for (; i != e; ++i) + // Iterate it's Products... + for_(it, selectablePool.byKindBegin<zypp::Patch>(), selectablePool.byKindEnd<zypp::Patch>()) { - zypp::Patch::constPtr pch = zypp::asKind<zypp::Patch>(i->resolvable()); - std::string name(pch->name()); + y2milestone("Procesing patch %s", (*it)->name().c_str()); + zypp::ui::Selectable::Ptr s = *it; - // the best patch for the current arch, no preferred version, only needed patches - ProvideProcess info(zypp_ptr()->architecture(), "", true); - - // search the best version of the patch to install - try + if (s && s->isNeeded() && !s->isUnwanted()) { - info.whoWantsIt = whoWantsIt; - - invokeOnEach( pool.byNameBegin( name ), - pool.byNameEnd( name ), - zypp::resfilter::ByKind( zypp::ResTraits<zypp::Patch>::kind ), - zypp::functor::functorRef<bool,zypp::PoolItem> (info) - ); + zypp::Patch::constPtr patch = zypp::dynamic_pointer_cast<const zypp::Patch> + (s->candidateObj().resolvable()); - if (!info.item) + // dont auto-install optional patches + if (patch->category() != "optional") { - y2milestone("Patch %s is not applicable", name.c_str()); - continue; - } - else - { - MIL << "Best version of patch " << i->resolvable() << ": " << info.item.resolvable() << std::endl; - } - } - catch (...) - { - y2error("Search for best patch '%s' failed", name.c_str()); - continue; - } - - zypp::Patch::constPtr patch = zypp::asKind<zypp::Patch>(info.item.resolvable()); + if (kind == "all" + || (kind == "interactive" && patch->interactive()) + || (kind == "affects_pkg_manager" && patch->restartSuggested()) + || (kind == "reboot_needed" && patch->rebootSuggested()) + || (kind == "relogin_needed" && patch->reloginSuggested()) + ) + { + if (preselect) + { + s->setToInstall(whoWantsIt); + } - // dont auto-install optional patches - if (patch->category () != "optional") - { - if (kind == "all" - || (kind == "interactive" && patch->interactive()) - || (kind == "affects_pkg_manager" && patch->affects_pkg_manager()) - || (kind == "reboot_needed" && patch->reboot_needed()) - ) - { - patches_toinst.insert(info.item); + // count the patch + needed_patches++; + } + else + { + y2milestone("Patch %s has not required flag", s->name().c_str()); + } } else { - y2milestone("Patch (id) %s has not required flag", patch->id().c_str()); + y2milestone("Ignoring optional patch : %s", s->name().c_str()); } } - else - { - y2milestone("Ignoring optional patch (id): %s", patch->id().c_str()); - } } } catch (...) @@ -663,32 +1065,13 @@ y2error("An error occurred during patch selection."); } - y2milestone("Found %d patches", patches_toinst.size()); - - if (preselect) - { - std::set<zypp::PoolItem>::iterator - b(patches_toinst.begin()), - e(patches_toinst.end()), - i(patches_toinst.begin()); - - for (i = b; i != e; ++i) - { - if (i->status().setToBeInstalled(whoWantsIt)) - { - MIL << "Selecting patch " << i->resolvable() << std::endl; - } - } - } - - return YCPInteger(patches_toinst.size()); + return YCPInteger(needed_patches); } - /** @builtin IsAnyResolvable @short Is there any resolvable in the requried state? - @param symbol kind_r kind of resolvable, can be `product, `patch, `package, `selection, `pattern, `language or `any for any kind of resolvable + @param symbol kind_r kind of resolvable, can be `product, `patch, `package, `pattern or `any for any kind of resolvable @param symbol status status of resolvable, can be `to_install or `to_remove @return boolean true if a resolvable with the requested status was found */ @@ -697,80 +1080,64 @@ { zypp::Resolvable::Kind kind; + if (kind_r.isNull() || status.isNull()) + { + y2error("Invalid nil parameter!"); + return YCPVoid(); + } + std::string req_kind = kind_r->symbol (); std::string stat_str = status->symbol(); + if (stat_str != "to_install" && stat_str != "to_remove") + { + y2error("Invalid status parameter: %s", stat_str.c_str()); + return YCPVoid(); + } + + bool to_install = stat_str == "to_install"; + if( req_kind == "product" ) { - kind = zypp::ResTraits<zypp::Product>::kind; + kind = zypp::ResKind::product; } else if ( req_kind == "patch" ) { - kind = zypp::ResTraits<zypp::Patch>::kind; + kind = zypp::ResKind::patch; } else if ( req_kind == "package" ) { - kind = zypp::ResTraits<zypp::Package>::kind; - } - else if ( req_kind == "selection" ) { - kind = zypp::ResTraits<zypp::Selection>::kind; + kind = zypp::ResKind::package; } else if ( req_kind == "pattern" ) { - kind = zypp::ResTraits<zypp::Pattern>::kind; - } - else if ( req_kind == "language" ) { - kind = zypp::ResTraits<zypp::Language>::kind; + kind = zypp::ResKind::pattern; } else if ( req_kind == "any" ) { try - { - for (zypp::ResPool::const_iterator it = zypp_ptr()->pool().begin(); - it != zypp_ptr()->pool().end(); - ++it) - { - if (stat_str == "to_install" && it->status().isToBeInstalled()) - { - return YCPBoolean(true); - } - else if (stat_str == "to_remove" && it->status().isToBeUninstalled()) - { - return YCPBoolean(true); - } - } + { + return YCPBoolean( + AnyResolvableHelper(zypp::ResKind::package, to_install) + || AnyResolvableHelper(zypp::ResKind::patch, to_install) + || AnyResolvableHelper(zypp::ResKind::product, to_install) + || AnyResolvableHelper(zypp::ResKind::pattern, to_install) + ); } catch (...) { y2error("An error occurred during resolvable search."); - return YCPNull(); + return YCPVoid(); } - - return YCPBoolean(false); } else { y2error("Pkg::IsAnyResolvable: unknown symbol: %s", req_kind.c_str()); - return YCPNull(); + return YCPVoid(); } - try - { - for (zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(kind); - it != zypp_ptr()->pool().byKindEnd(kind); - ++it) - { - if (stat_str == "to_install" && it->status().isToBeInstalled()) - { - return YCPBoolean(true); - } - else if (stat_str == "to_remove" && it->status().isToBeUninstalled()) - { - return YCPBoolean(true); - } - } + { + return YCPBoolean(AnyResolvableHelper(kind, to_install)); } catch (...) { y2error("An error occurred during resolvable search."); - return YCPNull(); + return YCPVoid(); } - - return YCPBoolean(false); } Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Selection.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Selection.cc?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Selection.cc (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Selection.cc Tue May 10 20:10:47 2011 @@ -39,9 +39,7 @@ #include <zypp/ResPool.h> #include <zypp/ResTraits.h> #include <zypp/Resolvable.h> -#include <zypp/Selection.h> #include <zypp/Pattern.h> -#include <zypp/SourceManager.h> using std::string; @@ -76,78 +74,8 @@ YCPValue PkgModuleFunctions::GetSelections (const YCPSymbol& stat, const YCPString& cat) { - string status = stat->symbol(); - string category = cat->value(); - - // FIXME: this should be done more nicely - if ( category == "base" ) - category = "baseconf"; - YCPList selections; - - try - { - for (zypp::ResPool::byKind_iterator it - = zypp_ptr()->pool().byKindBegin(zypp::ResTraits<zypp::Selection>::kind); - it != zypp_ptr()->pool().byKindEnd(zypp::ResTraits<zypp::Selection>::kind) ; ++it ) - { - string selection; - - if (status == "all") - { - selection = it->resolvable()->name(); - } - else if (status == "available") - { - // ignore installed selections - zypp::Source_Ref src = (*it)->source(); - - if (src != zypp::Source_Ref::noSource) - selection = it->resolvable()->name(); - } - else if (status == "selected") - { - if( it->status().isToBeInstalled() ) - selection = it->resolvable()->name(); - } - else if (status == "installed") - { - if( it->status().wasInstalled() ) - selection = it->resolvable()->name(); - } - else - { - y2warning (string ("Unknown status in Pkg::GetSelections(" + status + ", ...)").c_str()); - break; - } - - if (selection.empty()) - { - continue; - } - - string selection_cat = zypp::dynamic_pointer_cast<const zypp::Selection>(it->resolvable())->category(); - if (category != "") - { - if ( selection_cat != category) - { - continue; // asked for explicit category - } - } - else // category == "" - { - if (selection_cat == "baseconf") - { - continue; // asked for non-base - } - } - selections->add (YCPString (selection)); - } - } - catch (...) - { - } - + y2warning("Pkg::GetSelections is obsoleted, selections have been replaced by patterns"); return selections; } @@ -181,60 +109,34 @@ YCPValue PkgModuleFunctions::GetPatterns(const YCPSymbol& stat, const YCPString& cat) { - std::string status = stat->symbol(); + std::string status = stat->symbol(); std::string category = cat->value(); YCPList patterns; try { - for (zypp::ResPool::byKind_iterator it - = zypp_ptr()->pool().byKindBegin(zypp::ResTraits<zypp::Pattern>::kind); - it != zypp_ptr()->pool().byKindEnd(zypp::ResTraits<zypp::Pattern>::kind) ; ++it ) + for (zypp::ResPoolProxy::const_iterator it = zypp_ptr()->poolProxy().byKindBegin(zypp::ResKind::pattern); + it != zypp_ptr()->poolProxy().byKindEnd(zypp::ResKind::pattern); + ++it) { - std::string pattern; - - if (status == "all") - { - pattern = it->resolvable()->name(); - } - else if (status == "available") - { - // ignore installed patterns - zypp::Source_Ref src = (*it)->source(); - - if (src != zypp::Source_Ref::noSource) - pattern = it->resolvable()->name(); - } - else if (status == "selected") - { - if( it->status().isToBeInstalled() ) - pattern = it->resolvable()->name(); - } - else if (status == "installed") - { - if( it->status().wasInstalled() ) - pattern = it->resolvable()->name(); - } - else - { - y2warning (string ("Unknown status in Pkg::GetPatterns(" + status + ", ...)").c_str()); - break; - } - if (pattern.empty()) + if (status == "all" || (status == "available" && (*it)->hasCandidateObj()) + // TODO FIXME isSatified() should be here??? + || (status == "installed" && (*it)->hasInstalledObj()) + || (status == "selected" && (*it)->fate() == zypp::ui::Selectable::TO_INSTALL) + ) { - continue; - } + // check the required category + std::string pattern_cat = zypp::dynamic_pointer_cast<const zypp::Pattern>((*it)->theObj().resolvable())->category(); - std::string pattern_cat = zypp::dynamic_pointer_cast<const zypp::Pattern>(it->resolvable())->category(); + if (!category.empty() && pattern_cat != category) + { + continue; // asked for explicit category, but it doesn't match + } - if (!category.empty() && pattern_cat != category) - { - continue; // asked for explicit category, but it doesn't match + patterns->add(YCPString((*it)->name())); } - - patterns->add (YCPString (pattern)); } } catch (...) @@ -280,45 +182,50 @@ YCPValue PkgModuleFunctions::PatternData (const YCPString& pat) { - YCPMap data; - std::string name = pat->value(); + YCPMap ret; try { - zypp::ResPool::byName_iterator it = std::find_if ( - zypp_ptr()->pool().byNameBegin(name) - , zypp_ptr()->pool().byNameEnd(name) - , zypp::resfilter::ByKind(zypp::ResTraits<zypp::Pattern>::kind) - ); + YCPValue value = ResolvableProperties(pat, YCPSymbol("pattern"), YCPString("")); + YCPList lst; - if ( it != zypp_ptr()->pool().byNameEnd(name) ) + if (!value.isNull() && value->isList()) { - zypp::Pattern::constPtr pattern = - zypp::dynamic_pointer_cast<const zypp::Pattern>(it->resolvable ()); + lst = value->asList(); + } - // pattern found - data->add (YCPString ("summary"), YCPString (pattern->summary())); - data->add (YCPString ("category"), YCPString (pattern->category())); - data->add (YCPString ("visible"), YCPBoolean (pattern->userVisible())); - data->add (YCPString ("order"), YCPString (pattern->order())); - data->add (YCPString ("description"), YCPString (pattern->description())); - data->add (YCPString ("default"), YCPBoolean (pattern->isDefault())); - data->add (YCPString ("icon"), YCPString (pattern->icon().asString())); - data->add (YCPString ("script"), YCPString (pattern->script().asString())); - data->add (YCPString ("version"), YCPString((*it)->edition().asString())); - data->add (YCPString ("arch"), YCPString((*it)->arch().asString())); - data->add (YCPString ("srcid"), YCPInteger((*it)->source().numericId())); + if (lst->size() >= 1) + { + YCPValue first = lst->value(0); + + if (!first.isNull() && first->isMap()) + { + ret = first->asMap(); + } + + if (!ret.isNull()) + { + YCPValue val = ret->value(YCPString("source")); + ret->add(YCPString("srcid"), val); + + val = ret->value(YCPString("user_visible")); + ret->add(YCPString("visible"), val); + } + else + { + return YCPError ("Pattern '" + pat->value() + "' not found", ret); + } } else { - return YCPError ("Pattern '" + name + "' not found", data); + return YCPError ("Pattern '" + pat->value() + "' not found", ret); } } catch (...) { } - return data; + return ret; } @@ -361,75 +268,6 @@ PkgModuleFunctions::SelectionData (const YCPString& sel) { YCPMap data; - string name = sel->value(); - - /* TODO FIXME - - data->add (YCPString ("archivesize"), YCPInteger ((long long) (selection->archivesize()))); - - tiny_helper_no1 (&data, "requires", selection->requires ()); - tiny_helper_no1 (&data, "conflicts", selection->conflicts ()); - tiny_helper_no1 (&data, "provides", selection->provides ()); - tiny_helper_no1 (&data, "obsoletes", selection->obsoletes ()); - */ - - try - { - zypp::ResPool::byName_iterator it = std::find_if ( - zypp_ptr()->pool().byNameBegin(name) - , zypp_ptr()->pool().byNameEnd(name) - , zypp::resfilter::ByKind(zypp::ResTraits<zypp::Selection>::kind) - ); - - if ( it != zypp_ptr()->pool().byNameEnd(name) ) - { - zypp::Selection::constPtr selection = - zypp::dynamic_pointer_cast<const zypp::Selection>(it->resolvable ()); - - // selection found - data->add (YCPString ("summary"), YCPString (selection->summary())); - data->add (YCPString ("category"), YCPString (selection->category())); - data->add (YCPString ("visible"), YCPBoolean (selection->visible())); - data->add (YCPString ("order"), YCPString (selection->order())); - data->add (YCPString ("description"), YCPString (selection->description())); - - /* YCPList recommendslist; - std::set<std::string> recommends = selection->recommends(); - - for (std::set<std::string>::const_iterator rec = recommends.begin(); - rec != recommends.end(); rec++) - { - if (!((*rec).empty())) - { - recommendslist->add(YCPString(*rec)); - } - } - data->add (YCPString("recommends"), recommendslist); - - YCPList suggestslist; - std::set<std::string> suggests = selection->suggests(); - - for (std::set<std::string>::const_iterator sug = suggests.begin(); - sug != suggests.end(); sug++) - { - if (!((*sug).empty())) - { - suggestslist->add(YCPString(*sug)); - } - } - data->add (YCPString("suggests"), recommendslist); - */ -#warning Report also archivesize, requires, provides, conflicts and obsoletes - } - else - { - return YCPError ("Selection '" + name + "' not found", data); - } - } - catch (...) - { - } - return data; } @@ -451,47 +289,7 @@ YCPValue PkgModuleFunctions::SelectionContent (const YCPString& sel, const YCPBoolean& to_delete, const YCPString& lang) { -#warning Pkg::SelectionContent to_delete is not supported - YCPList data; - std::string name = sel->value(); - std::string locale = lang->value(); - - try - { - zypp::ResPool::byName_iterator it = std::find_if ( - zypp_ptr()->pool().byNameBegin(name) - , zypp_ptr()->pool().byNameEnd(name) - , zypp::resfilter::ByKind(zypp::ResTraits<zypp::Selection>::kind) - ); - - if ( it != zypp_ptr()->pool().byNameEnd(name) ) - { - zypp::Selection::constPtr selection = - zypp::dynamic_pointer_cast<const zypp::Selection>(it->resolvable ()); - -#warning implemented correctly? - // is it correct? - std::set<std::string> inst = selection->install_packages(zypp::Locale(locale)); - - for (std::set<std::string>::const_iterator inst_it = inst.begin(); - inst_it != inst.end(); inst_it++) - { - if (!((*inst_it).empty())) - { - data->add(YCPString(*inst_it)); - } - } - } - else - { - return YCPError ("Selection '" + name + "' not found", data); - } - } - catch (...) - { - } - return data; } @@ -512,7 +310,8 @@ YCPBoolean PkgModuleFunctions::SetSelection (const YCPString& selection) { - return DoProvideNameKind( selection->value(), zypp::ResTraits<zypp::Selection>::kind, zypp_ptr()->architecture(), ""); + y2warning("Pkg::SetSelection is obsoleted, selections have been replaced by patterns"); + return YCPBoolean(false); } // ------------------------ @@ -526,8 +325,8 @@ YCPValue PkgModuleFunctions::ClearSelection (const YCPString& selection) { - ycpwarning( "Pkg::ClearSelection does not reset add-on selections anymore"); - return YCPBoolean( DoRemoveNameKind( selection->value(), zypp::ResTraits<zypp::Selection>::kind ) ); + y2warning( "Pkg::ClearSelection does not reset add-on selections anymore"); + return YCPBoolean(false); } @@ -538,14 +337,13 @@ @short Activate all selected selections - obsoleted, use PkgSolve() instead @return boolean true - + @deprecated Use Pkg::PkgSolve instead, selections are solvable now */ YCPBoolean PkgModuleFunctions::ActivateSelections () { y2warning ("Pkg::ActivateSelections is obsolete. Use Pkg::PkgSolve instead"); - return YCPBoolean (true); } Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.cc?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.cc (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.cc Tue May 10 20:10:47 2011 @@ -0,0 +1,315 @@ +/* ------------------------------------------------------------------------------ + * Copyright (c) 2008 Novell, Inc. All Rights Reserved. + * + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of version 2 of the GNU General Public License as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may find + * current contact information at www.novell.com. + * ------------------------------------------------------------------------------ + */ + + +#include "log.h" +#include "ServiceManager.h" + +#include <zypp/RepoManager.h> +#include <y2util/Y2SLog.h> + +ServiceManager::ServiceManager() : _services_loaded(false) +{ +} + +ServiceManager::~ServiceManager() +{ +} + +void ServiceManager::LoadServices(const zypp::RepoManager &repomgr) +{ + if (!_services_loaded) + { + for_ (it, repomgr.serviceBegin(), repomgr.serviceEnd()) + { + // set the original alias to the current one + PkgService s(*it, it->alias()); + y2milestone("Loaded service %s (%s)", s.alias().c_str(), s.url().asString().c_str()); + _known_services.insert(std::make_pair(s.alias(), s)); + } + + _services_loaded = true; + } + else + { + y2warning("Services have already been loaded, skipping load"); + } +} + +void ServiceManager::SaveServices(zypp::RepoManager &repomgr) const +{ + for_ (it, _known_services.begin(), _known_services.end()) + { + // delete + if (it->second.isDeleted()) + { + std::string alias(it->second.alias()); + y2milestone("Removing service %s", alias.c_str()); + repomgr.removeService(alias); + } + } + + for_ (it, _known_services.begin(), _known_services.end()) + { + if (!it->second.isDeleted()) + { + SavePkgService(it->second, repomgr); + } + } +} + +bool ServiceManager::SaveService(const std::string &alias, zypp::RepoManager &repomgr) const +{ + PkgServices::const_iterator serv_it = _known_services.find(alias); + + if (serv_it == _known_services.end()) + { + y2error("Service '%s' does not exist", alias.c_str()); + return false; + } + + if (serv_it->second.isDeleted()) + { + y2error("Service '%s' has been deleted", alias.c_str()); + return false; + } + + SavePkgService(serv_it->second, repomgr); + + return true; +} + +bool ServiceManager::RefreshService(const std::string &alias, zypp::RepoManager &repomgr) +{ + PkgServices::iterator serv_it = _known_services.find(alias); + + if (serv_it == _known_services.end() || serv_it->second.isDeleted()) + { + y2error("Service '%s' does not exist", alias.c_str()); + return false; + } + + repomgr.refreshService(serv_it->second); + + // load the service from disk + PkgService new_service(repomgr.getService(alias), alias); + DBG << "Reloaded service: " << new_service; + + // remove the old service + _known_services.erase(serv_it); + // insert new + _known_services.insert(std::make_pair(alias, new_service)); + + return true; +} + +ServiceManager::Services ServiceManager::GetServices() const +{ + Services ret; + + for_ (it, _known_services.begin(), _known_services.end()) + { + // return only valid services + if (!it->second.isDeleted()) + { + ret.push_back(it->second); + } + } + + return ret; +} + +bool ServiceManager::AddService(const std::string &alias, const std::string &url) +{ + if (alias.empty()) + { + y2error("Empty alias for service %s", url.c_str()); + return false; + } + + PkgServices::iterator serv_it = _known_services.find(alias); + std::string orig_alias; + + if (serv_it != _known_services.end()) + { + if (serv_it->second.isDeleted()) + { + // remember the original alias + // adding a removed service is the same as changing existing one + orig_alias = serv_it->second.alias(); + + // we are adding an already removed service, + // remove the existing service + _known_services.erase(serv_it); + } + else + { + y2error("Service with alias %s already exists", alias.c_str()); + return false; + } + } + + zypp::ServiceInfo info; + info.setAlias(alias); + info.setUrl(url); + + PkgService srv(info, orig_alias); + y2milestone("Adding service %s (orig alias: %s)", alias.c_str(), srv.origAlias().c_str()); + + _known_services.insert(std::make_pair(alias, srv)); + + return true; +} + +bool ServiceManager::RemoveService(const std::string &alias) +{ + PkgServices::iterator serv_it = _known_services.find(alias); + + if (serv_it != _known_services.end()) + { + if (serv_it->second.isDeleted()) + { + y2warning("Service %s has been already removed", alias.c_str()); + return true; + } + else + { + serv_it->second.setDeleted(); + y2milestone("Service %s has been marked as deleted", alias.c_str()); + return true; + } + } + else + { + y2error("Service %s does not exist", alias.c_str()); + return false; + } +} + +void ServiceManager::Reset() +{ + y2milestone("Resetting known services..."); + // reset the internal structures + _known_services.clear(); + _services_loaded = false; +} + + +zypp::ServiceInfo ServiceManager::GetService(const std::string &alias) const +{ + PkgServices::const_iterator serv_it = _known_services.find(alias); + + if (serv_it != _known_services.end()) + { + if (serv_it->second.isDeleted()) + { + y2warning("Service %s has been removed", alias.c_str()); + return zypp::ServiceInfo::noService; + } + else + { + return serv_it->second; + } + } + else + { + y2error("Service %s does not exist", alias.c_str()); + return zypp::ServiceInfo::noService; + } + + return zypp::ServiceInfo::noService; +} + +bool ServiceManager::SetService(const std::string &old_alias, const zypp::ServiceInfo &srv) +{ + PkgServices::const_iterator serv_it = _known_services.find(old_alias); + + if (serv_it != _known_services.end()) + { + if (serv_it->second.isDeleted()) + { + y2warning("Service %s has been removed", old_alias.c_str()); + return false; + } + else + { + // if the alias has been already changed then keep the original alias + y2milestone("Setting service: %s (orig alias: %s)", old_alias.c_str(), serv_it->second.origAlias().c_str()); + DBG << "Properties: " << srv << std::endl; + PkgService s(srv, serv_it->second.origAlias()); + _known_services[srv.alias()] = s; + return true; + } + } + else + { + y2error("Service %s does not exist", old_alias.c_str()); + return false; + } + + return false; +} + +std::string ServiceManager::Probe(const zypp::Url &url, const zypp::RepoManager &repomgr) const +{ + y2milestone("Probing service at %s...", url.asString().c_str()); + std::string ret(repomgr.probeService(url).asString()); + y2milestone("Detected service type: %s", ret.c_str()); + + return ret; +} + +bool ServiceManager::empty() const +{ + return _known_services.empty(); +} + + +ServiceManager::Services::size_type ServiceManager::size() const +{ + return _known_services.size(); +} + +void ServiceManager::SavePkgService(const PkgService &s_known, zypp::RepoManager &repomgr) const +{ + const std::string alias(s_known.alias()); + const zypp::ServiceInfo s_stored = repomgr.getService(alias); + + DBG << "Known Service: " << s_known << std::endl; + DBG << "Stored Service: " << s_stored << std::endl; + + std::string orig_alias(s_known.origAlias()); + + y2internal("orig_alias: %s", orig_alias.c_str()); + + // the old alias is empty for new services + if (orig_alias.empty()) + { + y2milestone("Adding new service %s", alias.c_str()); + // add the service + repomgr.addService(s_known); + } + else + { + y2milestone("Saving service %s", alias.c_str()); + // use the old alias + repomgr.modifyService(orig_alias, s_known); + } +} Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.h?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.h (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/ServiceManager.h Tue May 10 20:10:47 2011 @@ -0,0 +1,85 @@ +/* ------------------------------------------------------------------------------ + * Copyright (c) 2008 Novell, Inc. All Rights Reserved. + * + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of version 2 of the GNU General Public License as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may find + * current contact information at www.novell.com. + * ------------------------------------------------------------------------------ + */ + + +#include <map> +#include <string> +#include "PkgService.h" + +namespace zypp +{ + class RepoManager; +} + +class ServiceManager +{ + public: + + typedef std::list<zypp::ServiceInfo> Services; + + ServiceManager(); + + ~ServiceManager(); + + Services GetServices() const; + + void LoadServices(const zypp::RepoManager &repomgr); + + void SaveServices(zypp::RepoManager &repomgr) const; + + bool SaveService(const std::string &alias, zypp::RepoManager &repomgr) const; + + bool AddService(const std::string &alias, const std::string &url); + + bool RemoveService(const std::string &alias); + + zypp::ServiceInfo GetService(const std::string &alias) const; + + bool SetService(const std::string &old_alias, const zypp::ServiceInfo &srv); + + bool RefreshService(const std::string &alias, zypp::RepoManager &repomgr); + + std::string Probe(const zypp::Url &url, const zypp::RepoManager &repomgr) const; + + void Reset(); + + // is there any service? (incl. deleted!) + bool empty() const; + + // number of services (incl. deleted!) + Services::size_type size() const; + + + private: + + // internal helper method + void SavePkgService(const PkgService &s_known, zypp::RepoManager &repomgr) const; + + // current alias -> PkgService for convenient search by alias + typedef std::map<std::string, PkgService> PkgServices; + + // services have been loaded from system + bool _services_loaded; + + // all known services (even deleted) + PkgServices _known_services; +}; + + Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.cc?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.cc (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.cc Tue May 10 20:10:47 2011 @@ -37,11 +37,8 @@ #include <Callbacks.h> #include <Callbacks.YCP.h> -#include <zypp/SourceManager.h> -#include <zypp/SourceFactory.h> -#include <zypp/Source.h> +#include <zypp/RepoManager.h> #include <zypp/Product.h> -#include <zypp/target/store/PersistentStorage.h> #include <zypp/media/MediaManager.h> #include <zypp/Pathname.h> @@ -113,26 +110,45 @@ ycp_handler->evaluateCall(); } } + /** * Logging helper: * call zypp::SourceManager::sourceManager()->findSource * and in case of exception, log error and setLastError AND RETHROW */ -zypp::Source_Ref PkgModuleFunctions::logFindSource (zypp::SourceManager::SourceId id) +YRepo_Ptr PkgModuleFunctions::logFindRepository(RepoId id) { - zypp::Source_Ref src; - try { - src = zypp::SourceManager::sourceManager()->findSource(id); + if (id < 0 || id >= repos.size()) + { + // not found + throw(std::exception()); + } + + if (!repos[id]) + { + // not found + throw(std::exception()); + } + + if (repos[id]->isDeleted()) + { + y2error("Source %zd has been deleted, the ID is not valid", id); + return YRepo_Ptr(); + } + + return repos[id]; } - catch (const zypp::Exception& excpt) + catch (...) { - y2error("Cannot find source %ld: %s",id, excpt.msg().c_str() ); - _last_error.setLastError(excpt.asUserString()); - throw; + y2error("Cannot find source with ID: %zd", id); + // TODO: improve the error message + _last_error.setLastError(_("Cannot find source")); } - return src; + + // not found, return empty pointer + return YRepo_Ptr(); } /**************************************************************************************** @@ -148,7 +164,6 @@ return YCPBoolean( true ); } - /**************************************************************************************** * @builtin SourceRestore * @@ -161,46 +176,92 @@ * @return boolean True on success **/ YCPValue -PkgModuleFunctions::SourceRestore() +PkgFunctions::SourceRestore() { - CallSourceReportInit(); - CallSourceReportStart(_("Downloading files...")); - + // return value bool success = true; - try { - // we always use the configured caches - if( !zypp::SourceManager::sourceManager()->restore(_target_root, true) ) - { - y2error( "Unable to restore all sources" ); - - success = false; - } - } - catch (const zypp::FailedSourcesRestoreException& excpt) + if (repos.size() > 0) { - // FIXME: assuming the sources are already initialized - y2error ("Error in SourceRestore: %s", excpt.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); - _broken_sources = excpt.aliases(); - success = false; + y2warning("Number of registered repositories: %zd, skipping repository load!", repos.size()); + return YCPBoolean(success); } - catch (const zypp::SourcesAlreadyRestoredException& excpt) + + try { - y2milestone ("At least one source already registered, SourceManager already started."); - success = true; + zypp::RepoManager repomanager = CreateRepoManager(); + + if (!service_manager.empty()) + { + y2warning("Number of known services: %zd, skipping service load!", service_manager.size()); + } + else + { + try + { + service_manager.LoadServices(repomanager); + + if (!service_manager.empty()) + { + // refresh services at first + ServiceManager::Services services(service_manager.GetServices()); + bool network_is_running = NetworkDetected(); + + for_(srv_it, services.begin(), services.end()) + { + try + { + if (srv_it->enabled() && srv_it->autorefresh()) + { + zypp::Url url(srv_it->url()); + + if (!network_is_running && remoteRepo(url)) + { + y2warning("No network connection, skipping autorefresh of remote service %s (%s)", + srv_it->alias().c_str(), url.asString().c_str()); + } + else + { + y2milestone("Autorefreshing service %s (%s)...", srv_it->alias().c_str(), url.asString().c_str()); + service_manager.RefreshService(srv_it->alias(), repomanager); + } + } + } + catch (const zypp::Exception& excpt) + { + // service refresh is not fatal, let's continue + y2error ("Error in service refresh: %s", excpt.asString().c_str()); + // error message, service name and URL is appened at the end of the string + _last_error.setLastError(std::string(_("Error refreshing service")) + " " + srv_it->name() + " (" + + srv_it->url().asString() + "):\n\n" + ExceptionAsString(excpt)); + success = false; + } + } + } + } + catch (const zypp::Exception& excpt) + { + _last_error.setLastError(ExceptionAsString(excpt)); + success = false; + } + } + + std::list<zypp::RepoInfo> reps = repomanager.knownRepositories(); + + for (std::list<zypp::RepoInfo>::iterator it = reps.begin(); + it != reps.end(); ++it) + { + repos.push_back(new YRepo(*it)); + } } catch (const zypp::Exception& excpt) { // FIXME: assuming the sources are already initialized y2error ("Error in SourceRestore: %s", excpt.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); + _last_error.setLastError(ExceptionAsString(excpt)); success = false; } - CallSourceReportEnd(_("Downloading files...")); - CallSourceReportDestroy(); - return YCPBoolean(success); } @@ -212,17 +273,10 @@ * Get list of all sources which could not have been restored. * @return list<string> list of aliases (product names or URLs) **/ -YCPValue PkgModuleFunctions::SourceGetBrokenSources() +YCPValue PkgFunctions::SourceGetBrokenSources() { - YCPList ret; - - for( std::set<std::string>::const_iterator it = _broken_sources.begin() ; - it != _broken_sources.end() ; ++it ) - { - ret->add(YCPString(*it)); - } - - return ret; + y2warning("Pkg::SourceGetBrokenSources() is obsoleted, it's not needed anymore."); + return YCPList(); } /**************************************************************************************** @@ -234,77 +288,25 @@ * @return boolean True on success **/ YCPValue -PkgModuleFunctions::SourceLoad() +PkgFunctions::SourceLoad() { - bool success = true; + std::list<std::string> stages; + stages.push_back(_("Refresh Sources")); + stages.push_back(_("Rebuild Cache")); + stages.push_back(_("Load Data")); - CallSourceReportInit(); - CallSourceReportStart(_("Parsing files...")); + PkgProgress pkgprogress(_callbackHandler); - std::list<zypp::SourceManager::SourceId> ids; + // 3 steps per repository (download, cache rebuild, load resolvables) + pkgprogress.Start(_("Loading the Package Manager..."), stages, _(HelpTexts::load_resolvables)); - // get all enabled sources - try - { - ids = zypp::SourceManager::sourceManager()->enabledSources(); - } - catch (const zypp::Exception& excpt) - { - y2error ("Error in SourceLoad: %s", excpt.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); - success = false; - } - - // load resolvables the enabled sources - for( std::list<zypp::SourceManager::SourceId>::iterator it = ids.begin(); it != ids.end(); ++it) - { - try - { - zypp::Source_Ref src = logFindSource(*it); - try - { - if( src.enabled() ) - { - zypp_ptr()->addResolvables (src.resolvables()); - } - else - { - // remove the resolvables if they have been added - if (src.resStoreInitialized ()) - { - zypp_ptr()->removeResolvables(src.resolvables()); - } - } - - } - catch (const zypp::Exception& excpt) - { - std::string url = src.url().asString(); - y2error ("Error for %s: %s", url.c_str(), excpt.asString().c_str()); - _last_error.setLastError(url + ": " + excpt.asUserString()); - success = false; + YCPValue ret = SourceLoadImpl(pkgprogress); - // disable the source - y2error("Disabling source %s", url.c_str()); - src.disable(); + pkgprogress.Done(); - // remember the broken source for SourceCleanupBroken - _broken_sources.insert(src.alias()); - } - } - catch (const zypp::Exception& excpt) - { - success = false; - } - } - - CallSourceReportEnd(_("Parsing files...")); - CallSourceReportDestroy(); - - return YCPBoolean(success); + return ret; } - /**************************************************************************************** * @builtin SourceStartManager * @@ -316,22 +318,31 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceStartManager (const YCPBoolean& enable) +PkgFunctions::SourceStartManager (const YCPBoolean& enable) { - YCPValue success = SourceRestore(); + PkgProgress pkgprogress(_callbackHandler); - if( enable->value() ) + // display the progress only when sources will be loaded + if (enable->value() && repos.size() == 0) { - if (!success->asBoolean()->value()) - { - y2warning("SourceStartManager: Some sources have not been restored, loading only the active sources..."); - } + std::list<std::string> stages; + stages.push_back(_("Load Sources")); + stages.push_back(_("Refresh Sources")); + stages.push_back(_("Rebuild Cache")); + stages.push_back(_("Load Data")); + + // 3 steps per repository (download, cache rebuild, load resolvables) + pkgprogress.Start(_("Loading the Package Manager..."), stages, _(HelpTexts::load_resolvables)); + } + + YCPValue ret = SourceStartManagerImpl(enable, pkgprogress); - // enable all sources and load the resolvables - success = YCPBoolean(SourceLoad()->asBoolean()->value() && success->asBoolean()->value()); + if (enable->value()) + { + pkgprogress.Done(); } - return success; + return ret; } /**************************************************************************************** @@ -354,7 +365,7 @@ * @return list<integer> list of SrcIds **/ YCPValue -PkgModuleFunctions::SourceStartCache (const YCPBoolean& enabled) +PkgFunctions::SourceStartCache (const YCPBoolean& enabled) { try { @@ -365,7 +376,7 @@ catch (const zypp::Exception& excpt) { y2error ("Error in SourceStartCache: %s", excpt.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); + _last_error.setLastError(ExceptionAsString(excpt)); } // catch an exception from boost (e.g. a file cannot be read by non-root user) catch (const std::exception& err) @@ -382,7 +393,7 @@ } /**************************************************************************************** - * @builtin SourceCleanupBroken + * @builtin SourceCleanupBroken - obsoleted, do not use! * * @short Clean up all sources that were not properly restored on the last * call of SourceStartManager or SourceStartCache. @@ -390,27 +401,10 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceCleanupBroken () +PkgFunctions::SourceCleanupBroken () { - bool success = true; - - zypp::storage::PersistentStorage store; - store.init( _target_root ); - - for( std::set<std::string>::const_iterator it = _broken_sources.begin() ; - it != _broken_sources.end() ; ++it ) - { - try { - store.deleteSource( *it ); - } catch( const zypp::Exception& excpt ) - { - success = false; - } - } - - _broken_sources.clear(); - - return YCPBoolean(success); + y2warning("Pkg::SourceCleanupBroken() is obsoleted, it's not needed anymore."); + return YCPBoolean(true); } /**************************************************************************************** @@ -424,17 +418,37 @@ * @return list<integer> list of SrcIds (integer) **/ YCPValue -PkgModuleFunctions::SourceGetCurrent (const YCPBoolean& enabled) +PkgFunctions::SourceGetCurrent (const YCPBoolean& enabled) { - std::list<zypp::SourceManager::SourceId> ids = (enabled->value()) ? - zypp::SourceManager::sourceManager()->enabledSources() - : zypp::SourceManager::sourceManager()->allSources(); - YCPList res; - for( std::list<zypp::SourceManager::SourceId>::const_iterator it = ids.begin(); it != ids.end() ; ++it ) + RepoId index = 0LL; + for( RepoCont::const_iterator it = repos.begin(); it != repos.end() ; ++it, ++index ) { - res->add( YCPInteger( *it ) ); + // ignore disabled sources if requested + if (enabled->value()) + { + // Note: enabled() is tribool! + if ((*it)->repoInfo().enabled()) + { + } + else if (!(*it)->repoInfo().enabled()) + { + continue; + } + else + { + continue; + } + } + + // ignore deleted sources + if ((*it)->isDeleted()) + { + continue; + } + + res->add( YCPInteger(index) ); } return res; @@ -444,26 +458,33 @@ * @builtin SourceReleaseAll * * @short Release all medias hold by all sources + * Warning: It also deletes the downloaded files! * @return boolean **/ YCPValue -PkgModuleFunctions::SourceReleaseAll () +PkgFunctions::SourceReleaseAll () { - try - { - y2milestone( "Relesing all sources") ; - zypp::SourceManager::sourceManager()->releaseAllSources (); - } - catch (zypp::Exception & excpt) + y2milestone("Releasing all sources..."); + bool ret = true; + + y2milestone("Removing all tmp directories"); + tmp_dirs.clear(); + + for (RepoCont::iterator it = repos.begin(); + it != repos.end(); ++it) { - _last_error.setLastError(excpt.asUserString()); - y2error("Pkg::SourceReleaseAll has failed: %s", excpt.msg().c_str() ); - return YCPBoolean(false); + try + { + (*it)->mediaAccess()->release(); + } + catch (const zypp::media::MediaException & ex) + { + y2warning("Failed to release media for repo: %s", ex.msg().c_str()); + ret = false; + } } - y2milestone( "All sources released"); - - return YCPBoolean(true); + return YCPBoolean(ret); } /****************************************************************************** @@ -473,58 +494,203 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceSaveAll () +PkgFunctions::SourceSaveAll () { + y2milestone("Saving the source setup..."); + bool ret = true; + + // nothing to save, return success + if (repos.empty() && service_manager.empty()) + { + y2debug("No repository or service defined, saving skipped"); + return YCPBoolean(ret); + } + + zypp::RepoManager repomanager = CreateRepoManager(); + + // save the services try { - y2milestone( "Storing the source setup in %s", _target_root.asString().c_str()) ; - zypp::SourceManager::sourceManager()->store( _target_root, true ); + service_manager.SaveServices(repomanager); + y2milestone("All services have been saved"); } - catch (zypp::Exception & excpt) + catch (const zypp::Exception& excpt) { - y2error("Pkg::SourceSaveAll has failed: %s", excpt.msg().c_str() ); - _last_error.setLastError(excpt.asUserString()); - return YCPBoolean(false); + _last_error.setLastError(ExceptionAsString(excpt)); + ret = false; + } + + // count removed repos + int removed_repos = 0; + for (RepoCont::iterator it = repos.begin(); + it != repos.end(); ++it) + { + // the repo has been removed + if ((*it)->isDeleted()) + { + removed_repos++; + } } - y2milestone( "All sources saved"); + y2debug("Found %d removed repositories", removed_repos); - return YCPBoolean(true); + // number of steps: + // for removed repository: 3 (remove metadata, remove from cache, remove .repo file) + // for other repositories: 1 (just save/update .repo file) + // (so there are 2 extra steps for removed repos) + int save_steps = 2*removed_repos + repos.size(); + + PkgProgress pkgprogress(_callbackHandler); + std::list<std::string> stages; + + if (removed_repos > 0) + { + stages.push_back(_("Remove Repositories")); + } + + + // stages: "download", "build cache" + stages.push_back(_("Save Repositories")); + + // set number of step + zypp::ProgressData prog_total(save_steps); + // set the receiver + prog_total.sendTo(pkgprogress.Receiver()); + + // start the process + pkgprogress.Start(_("Saving Repositories..."), stages, _(HelpTexts::save_help)); + + // remove deleted repos (the old configurations) at first + for (RepoCont::iterator it = repos.begin(); + it != repos.end(); ++it) + { + // the repo has been removed + if ((*it)->isDeleted()) + { + std::string repo_alias = (*it)->repoInfo().alias(); + + try + { + // remove the metadata + zypp::RepoStatus raw_metadata_status = repomanager.metadataStatus((*it)->repoInfo()); + if (!raw_metadata_status.empty()) + { + y2milestone("Removing metadata for source '%s'...", repo_alias.c_str()); + repomanager.cleanMetadata((*it)->repoInfo()); + } + prog_total.incr(); + + // remove the cache + if (repomanager.isCached((*it)->repoInfo())) + { + y2milestone("Removing cache for '%s'...", repo_alias.c_str()); + repomanager.cleanCache((*it)->repoInfo()); + } + prog_total.incr(); + + // does the repository exist? + repomanager.getRepositoryInfo(repo_alias); + y2milestone("Removing repository '%s'", repo_alias.c_str()); + repomanager.removeRepository((*it)->repoInfo()); + prog_total.incr(); + } + catch (const zypp::repo::RepoNotFoundException &ex) + { + // repository not found -- not critical, continue + y2warning("No such repository: %s", repo_alias.c_str()); + } + catch (const zypp::Exception & excpt) + { + y2error("Pkg::SourceSaveAll has failed: %s", excpt.msg().c_str() ); + _last_error.setLastError(ExceptionAsString(excpt)); + return YCPBoolean(false); + } + } + } + + if (removed_repos > 0) + { + pkgprogress.NextStage(); + } + + // save all repos (the current configuration) + for (RepoCont::iterator it = repos.begin(); + it != repos.end(); ++it) + { + if (!(*it)->isDeleted()) + { + std::string current_alias = (*it)->repoInfo().alias(); + + try + { + try + { + // if the repository already exists then just modify it + repomanager.getRepositoryInfo(current_alias); + y2milestone("Modifying repository '%s'", current_alias.c_str()); + repomanager.modifyRepository(current_alias, (*it)->repoInfo()); + } + catch (const zypp::repo::RepoNotFoundException &ex) + { + // the repository was not found, add it + y2milestone("Adding repository '%s'", current_alias.c_str()); + repomanager.addRepository((*it)->repoInfo()); + } + } + catch (zypp::Exception & excpt) + { + y2error("Pkg::SourceSaveAll has failed: %s", excpt.msg().c_str() ); + _last_error.setLastError(ExceptionAsString(excpt)); + return YCPBoolean(false); + } + + prog_total.incr(); + } + } + + y2milestone("All sources have been saved"); + + return YCPBoolean(ret); } /**************************************************************************************** * @builtin SourceFinishAll * - * @short Save and then disable all InstSrces. + * @short Release all instalation sources * @description - * If there are no enabled sources, do nothing - * (idempotence hack, broken design: #155459, #176013, use SourceSaveAll). - * @return boolean + * Release all known installation repositories. Releasing is done automaticaly in Pkg:: + * destructor, but can be done explicitly to force reloading of registered repositories. + * Use SourceSaveAll() to not loose the new registered sources before calling SourceFinishAll()! + * @return boolean true on success **/ YCPValue -PkgModuleFunctions::SourceFinishAll () +PkgFunctions::SourceFinishAll () { try { - // look if there are any enabled sources - std::list<zypp::SourceManager::SourceId> enabled_sources = zypp::SourceManager::sourceManager()->enabledSources(); - if (enabled_sources.empty()) { - y2milestone( "No enabled sources." ); - return YCPBoolean( true ); - } - y2milestone( "Storing the source setup in %s", _target_root.asString().c_str()) ; - zypp::SourceManager::sourceManager()->store( _target_root, true ); - y2milestone( "Disabling all sources") ; - zypp::SourceManager::sourceManager()->disableAllSources (); + y2milestone( "Unregistering all sources...") ; + + // remove all resolvables + for (RepoCont::iterator it = repos.begin(); + it != repos.end(); ++it) + { + RemoveResolvablesFrom(*it); + } + + // release all repositories + repos.clear(); + + // release all services + service_manager.Reset(); } catch (zypp::Exception & excpt) { y2error("Pkg::SourceFinishAll has failed: %s", excpt.msg().c_str() ); - _last_error.setLastError(excpt.asUserString()); + _last_error.setLastError(ExceptionAsString(excpt)); return YCPBoolean(false); } - y2milestone( "All sources finished"); + y2milestone("All sources and services have been unregistered"); return YCPBoolean(true); } @@ -548,6 +714,10 @@ * "type" : YCPString, * "url" : YCPString (without password, but see SourceURL), * "alias" : YCPString, + * "name" : YCPString, + * "service" : YCPString, (service to which the repo belongs, empty if there is no service assigned) + * "keeppackages" : YCPBoolean, + * "is_update_repo" : YCPBoolean, (true if this is an update repo - this requires loaded objects in pool otherwise the flag is not returned! The value is stored in repo metadata, not in .repo file!) * ]; * * </code> @@ -555,26 +725,55 @@ * @return map **/ YCPValue -PkgModuleFunctions::SourceGeneralData (const YCPInteger& id) +PkgFunctions::SourceGeneralData (const YCPInteger& id) { YCPMap data; - zypp::Source_Ref src; - try + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) + return YCPVoid (); + + // convert type to the old strings ("YaST", "YUM" or "Plaindir") + std::string srctype = zypp2yastType(repo->repoInfo().type().asString()); + + data->add( YCPString("enabled"), YCPBoolean(repo->repoInfo().enabled())); + data->add( YCPString("autorefresh"), YCPBoolean(repo->repoInfo().autorefresh())); + data->add( YCPString("type"), YCPString(srctype)); + data->add( YCPString("product_dir"), YCPString(repo->repoInfo().path().asString())); + + // check if there is an URL + if (repo->repoInfo().baseUrlsBegin() != repo->repoInfo().baseUrlsEnd()) { - src = logFindSource(id->value()); + data->add( YCPString("url"), YCPString(repo->repoInfo().baseUrlsBegin()->asString())); } - catch (const zypp::Exception& excpt) + + data->add( YCPString("alias"), YCPString(repo->repoInfo().alias())); + data->add( YCPString("name"), YCPString(repo->repoInfo().name())); + + YCPList base_urls; + for( zypp::RepoInfo::urls_const_iterator it = repo->repoInfo().baseUrlsBegin(); it != repo->repoInfo().baseUrlsEnd(); ++it) { - return YCPVoid (); + base_urls->add(YCPString(it->asString())); + } + data->add( YCPString("base_urls"), base_urls); + + data->add( YCPString("mirror_list"), YCPString(repo->repoInfo().mirrorListUrl().asString())); + + data->add( YCPString("priority"), YCPInteger(repo->repoInfo().priority())); + + data->add( YCPString("service"), YCPString(repo->repoInfo().service())); + + data->add( YCPString("keeppackages"), YCPBoolean(repo->repoInfo().keepPackages())); + + // add Repository data + zypp::Repository repository(zypp::ResPool::instance().reposFind(repo->repoInfo().alias())); + + if (repository != zypp::Repository::noRepository) + { + y2debug("adding zypp::Repository info"); + data->add( YCPString("is_update_repo"), YCPBoolean(repository.isUpdateRepo())); } - data->add( YCPString("enabled"), YCPBoolean(src.enabled())); - data->add( YCPString("autorefresh"), YCPBoolean(src.autorefresh())); - data->add( YCPString("type"), YCPString(src.type())); - data->add( YCPString("product_dir"), YCPString(src.path().asString())); - data->add( YCPString("url"), YCPString(src.url().asString())); - data->add( YCPString("alias"), YCPString(src.alias())); return data; } @@ -586,21 +785,63 @@ * @return string or nil on failure **/ YCPValue -PkgModuleFunctions::SourceURL (const YCPInteger& id) +PkgFunctions::SourceURL (const YCPInteger& id) { - zypp::Source_Ref src; - try - { - src = logFindSource(id->value()); - } - catch (const zypp::Exception& excpt) + const YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) + return YCPVoid(); + + zypp::Url url; + + if (repo->repoInfo().baseUrlsBegin() != repo->repoInfo().baseUrlsEnd()) { - return YCPVoid (); + // #186842 + url = *(repo->repoInfo().baseUrlsBegin()); + + // add authentication data if exist + zypp::media::CredentialManager cm; + + zypp::media::AuthData_Ptr auth = cm.getCred(url); + + if (auth) + { + y2milestone("Authentication data found, adding to URL..."); + + if (auth->valid()) + { + if (!auth->username().empty()) + { + y2debug("Adding username..."); + url.setUsername(auth->username()); + } + + if (!auth->password().empty()) + { + y2debug("Adding password..."); + url.setPassword(auth->password()); + } + } + else + { + y2warning("Invalid authentication data, returning URL without username and password"); + } + + // does the url contain credentials query? + zypp::url::ParamMap params = url.getQueryStringMap(); + zypp::url::ParamMap::iterator map_it = params.find("credentials"); + + if (map_it != params.end()) + { + y2milestone("Removing credentials query from URL"); + params.erase(map_it); + url.setQueryStringMap(params); + } + } + } - // #186842 - return YCPString(src.url().asCompleteString()); + return YCPString(url.asCompleteString()); } /**************************************************************************************** @@ -621,26 +862,74 @@ * @return map **/ YCPValue -PkgModuleFunctions::SourceMediaData (const YCPInteger& id) +PkgFunctions::SourceMediaData (const YCPInteger& id) { YCPMap data; - zypp::Source_Ref src; + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) + return YCPVoid (); + + std::string alias = repo->repoInfo().alias(); + bool found_resolvable = false; + int max_medium = 1; + // search the maximum source number of a package in the repository try { - src = logFindSource(id->value()); + for (zypp::ResPoolProxy::const_iterator it = zypp_ptr()->poolProxy().byKindBegin(zypp::ResKind::package); + it != zypp_ptr()->poolProxy().byKindEnd(zypp::ResKind::package); + ++it) + { + // search in available products + for (zypp::ui::Selectable::available_iterator aval_it = (*it)->availableBegin(); + aval_it != (*it)->availableEnd(); + ++aval_it) + { + zypp::Package::constPtr pkg = boost::dynamic_pointer_cast<const zypp::Package>(aval_it->resolvable()); + + if (pkg && pkg->repoInfo().alias() == alias) + { + found_resolvable = true; + + int medium = pkg->mediaNr(); + + if (medium > max_medium) + { + max_medium = medium; + } + } + } + } + } + catch (...) + { } - catch (const zypp::Exception& excpt) + + if (found_resolvable) { - return YCPVoid (); + data->add( YCPString("media_count"), YCPInteger(max_medium)); } + else + { + y2error("No resolvable from repository '%s' found, cannot get number of media (use Pkg::SourceLoad() to load the resolvables)", alias.c_str()); + } + + y2warning("Pkg::SourceMediaData() doesn't return \"media_id\" and \"media_vendor\" values anymore."); - data->add( YCPString("media_count"), YCPInteger(src.numberOfMedia())); - data->add( YCPString("media_id"), YCPString(src.unique_id())); - data->add( YCPString("media_vendor"), YCPString(src.vendor())); + // SourceMediaData returns URLs without password + if (repo->repoInfo().baseUrlsBegin() != repo->repoInfo().baseUrlsEnd()) + { + data->add( YCPString("url"), YCPString(repo->repoInfo().baseUrlsBegin()->asString())); + + // add all base URLs + YCPList base_urls; + for( zypp::RepoInfo::urls_const_iterator it = repo->repoInfo().baseUrlsBegin(); it != repo->repoInfo().baseUrlsEnd(); ++it) + { + base_urls->add(YCPString(it->asString())); + } + data->add( YCPString("base_urls"), base_urls); + } -#warning SourceMediaData returns URL without password - data->add( YCPString("url"), YCPString(src.url().asString())); return data; } @@ -653,54 +942,76 @@ * * <code> * $[ - * "label" : YCPString, - * "vendor" : YCPString, - * "productname" : YCPString, - * "productversion" : YCPString, - * "relnotesurl" : YCPString, + * "label" : string, + * "vendor" : string, + * "productname" : string, + * "productversion" : string, + * "relnotesurl" : string, + * "relnotes_urls" : list<string> + * "register_urls" : list<string> + * "smolt_urls" : list<string> + * "update_urls" : list<string> + * "extra_urls" : list<string> + * "optional_urls" : list<string> * ]; * </code> * * @return map **/ YCPValue -PkgModuleFunctions::SourceProductData (const YCPInteger& src_id) +PkgFunctions::SourceProductData (const YCPInteger& src_id) { YCPMap ret; - try - { - zypp::Source_Ref src = logFindSource(src_id->value()); + YRepo_Ptr repo = logFindRepository(src_id->value()); + if (!repo) + return YCPVoid (); - // find a product for the given source - zypp::ResPool::byKind_iterator it = zypp_ptr()->pool().byKindBegin(zypp::ResTraits<zypp::Product>::kind); + std::string alias = repo->repoInfo().alias(); - for( ; it != zypp_ptr()->pool().byKindEnd(zypp::ResTraits<zypp::Product>::kind) ; ++it) - { - zypp::Product::constPtr product = boost::dynamic_pointer_cast<const zypp::Product>( it->resolvable() ); + try + { + for (zypp::ResPoolProxy::const_iterator it = zypp_ptr()->poolProxy().byKindBegin(zypp::ResKind::product); + it != zypp_ptr()->poolProxy().byKindEnd(zypp::ResKind::product); + ++it) + { + zypp::Product::constPtr product = NULL; + + // search in available products + for (zypp::ui::Selectable::available_iterator aval_it = (*it)->availableBegin(); + aval_it != (*it)->availableEnd(); + ++aval_it) + { + zypp::Product::constPtr prod = boost::dynamic_pointer_cast<const zypp::Product>(aval_it->resolvable()); + if (prod && prod->repoInfo().alias() == alias) + { + product = prod; + break; + } + } - if( product->source() == src ) + if (product) { ret->add( YCPString("label"), YCPString( product->summary() ) ); ret->add( YCPString("vendor"), YCPString( product->vendor() ) ); ret->add( YCPString("productname"), YCPString( product->name() ) ); ret->add( YCPString("productversion"), YCPString( product->edition().version() ) ); - ret->add( YCPString("relnotesurl"), YCPString( product->releaseNotesUrl().asString())); + ret->add( YCPString("relnotesurl"), YCPString( product->releaseNotesUrls().first().asString())); - #warning SourceProductData not finished - /* - data->add( YCPString("datadir"), YCPString( descr->content_datadir().asString() ) ); - TODO (?): "baseproductname", "baseproductversion", "defaultbase", "architectures", - "requires", "linguas", "labelmap", "language", "timezone", "descrdir", "datadir" - */ + ret->add( YCPString("relnotes_urls"), asYCPList(product->releaseNotesUrls())); + ret->add( YCPString("register_urls"), asYCPList(product->registerUrls())); + ret->add( YCPString("smolt_urls"), asYCPList(product->smoltUrls())); + ret->add( YCPString("update_urls"), asYCPList(product->updateUrls())); + ret->add( YCPString("extra_urls"), asYCPList(product->extraUrls())); + ret->add( YCPString("optional_urls"), asYCPList(product->optionalUrls())); break; } } - if( it == zypp_ptr()->pool().byKindEnd(zypp::ResTraits<zypp::Product>::kind) ) + if(ret->size() == 0) { - y2error ("Product for source '%lld' not found", src_id->value()); + y2warning("Product for source '%lld' not found", src_id->value()); } } catch (...) @@ -718,60 +1029,113 @@ * @return map empty map **/ YCPValue -PkgModuleFunctions::SourceProduct (const YCPInteger& id) +PkgFunctions::SourceProduct (const YCPInteger& id) { - /* TODO FIXME */ - y2warning("Pkg::SourceProduct() is obsoleted!"); - return YCPMap(); + y2error("Pkg::SourceProduct() is obsoleted, use Pkg::SourceProductData() instead!"); + return SourceProductData(id); } -/**************************************************************************************** - * @builtin SourceProvideFile - * - * @short Make a file available at the local filesystem - * @description - * Let an InstSrc provide some file (make it available at the local filesystem). - * - * @param integer SrcId Specifies the InstSrc . - * @param integer medianr Number of the media the file is located on ('1' for the 1st media). - * @param string file Filename relative to the media root. - * - * @return string local path as string - **/ -YCPValue -PkgModuleFunctions::SourceProvideFile (const YCPInteger& id, const YCPInteger& mid, const YCPString& f) +YCPValue PkgFunctions::SourceProvideFileCommon(const YCPInteger &id, + const YCPInteger &mid, + const YCPString& f, + const bool optional, + const bool check_signatures, + const bool digested) { - CallSourceReportInit(); - CallSourceReportStart(_("Downloading file...")); + if (id.isNull() || mid.isNull() || f.isNull()) + { + y2error("ProvideFile: nil argument!"); + return YCPVoid(); + } + + CallInitDownload(std::string(_("Downloading ") + f->value())); - zypp::Source_Ref src; bool found = true; + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) + found = false; - try { - src = logFindSource(id->value()); - } - catch (const zypp::Exception& excpt) - { - found = false; - } + extern ZyppRecipients::MediaChangeSensitivity _silent_probing; + // remember the current value + ZyppRecipients::MediaChangeSensitivity _silent_probing_old = _silent_probing; - zypp::filesystem::Pathname path; + // disable media change callback for optional file + if (optional) + _silent_probing = ZyppRecipients::MEDIA_CHANGE_OPTIONALFILE; + + y2milestone("Downloading %s%sfile %s from repository %lld, medium %lld", + (optional ? "optional " : ""), + (check_signatures ? (digested ? "digested " : "signed ") : ""), + f->value().c_str(), + id->value(), + mid->value() + ); + zypp::filesystem::Pathname path; // FIXME use ManagedMedia if (found) { - try { - path = src.provideFile(f->value(), mid->asInteger()->value()); + try + { + if (check_signatures) + { + // use a Fetcher for downloading signed files (see bnc#409927) + zypp::Fetcher fch; + fch.reset(); + fch.setOptions(zypp::Fetcher::AutoAddIndexes); + + // path - add "/" to the beginning if it's missing there + std::string media_path(f->value()); + if (media_path.size() >= 1 && media_path[0] != '/') + { + media_path = "/" + media_path; + } + + zypp::OnMediaLocation mloc(media_path, mid->value()); + // the file is never optional for zypp (it cannot tell whether an optional file failed) + mloc.setOptional(false); + + // create the tmpdir in <_download_area>/var/tmp + zypp::filesystem::TmpDir tmpdir(_download_area / zypp::filesystem::TmpDir::defaultLocation()); + + // keep a reference to the tmpdir so the directory is not deleted at the and of the block + tmp_dirs.push_back(tmpdir); + path = tmpdir.path(); + + if (digested) + { + fch.enqueueDigested(mloc); + } + else + { + fch.addIndex(mloc); + } + + fch.start(path, *repo->mediaAccess()); // uses MediaAccess to retrieve + fch.reset(); + path /= f->value(); + } + else + { + path = repo->mediaAccess()->provideFile(f->value(), mid->value()); + y2milestone("local path: '%s'", path.asString().c_str()); + } } catch (const zypp::Exception& excpt) { - _last_error.setLastError(excpt.asUserString()); - y2milestone ("File not found: %s", f->value_cstr()); found = false; + + if (!optional) + { + _last_error.setLastError(ExceptionAsString(excpt)); + y2milestone("File not found: %s", f->value_cstr()); + } } } - CallSourceReportEnd(_("Downloading file...")); - CallSourceReportDestroy(); + // set the original probing value + _silent_probing = _silent_probing_old; + + CallDestDownload(); if (found) { @@ -781,7 +1145,27 @@ { return YCPVoid(); } +} + +/**************************************************************************************** + * @builtin SourceProvideFile + * + * @short Make a file available at the local filesystem + * @description + * Let an InstSrc provide some file (make it available at the local filesystem). + * Warning: The downloaded files are removed in Pkg::SourceReleaseAll()! + * + * @param integer SrcId Specifies the InstSrc . + * @param integer medianr Number of the media the file is located on ('1' for the 1st media). + * @param string file Filename relative to the media root. + * + * @return string local path as string + **/ +YCPValue +PkgFunctions::SourceProvideFile (const YCPInteger& id, const YCPInteger& mid, const YCPString& f) +{ + return SourceProvideFileCommon(id, mid, f, false /*optional*/, false /* signed */, true /* digested, doesn't matter in this case*/); } /**************************************************************************************** @@ -791,6 +1175,7 @@ * @description * Let an InstSrc provide some file (make it available at the local filesystem). * If the file doesn't exist don't ask user for another medium and return nil + * Warning: The downloaded files are removed in Pkg::SourceReleaseAll()! * * @param integer SrcId Specifies the InstSrc . * @param integer medianr Number of the media the file is located on ('1' for the 1st media). @@ -799,53 +1184,92 @@ * @return string local path as string **/ YCPValue -PkgModuleFunctions::SourceProvideOptionalFile (const YCPInteger& id, const YCPInteger& mid, const YCPString& f) +PkgFunctions::SourceProvideOptionalFile (const YCPInteger& id, const YCPInteger& mid, const YCPString& f) { - CallSourceReportInit(); - CallSourceReportStart(_("Downloading files...")); + return SourceProvideFileCommon(id, mid, f, true /*optional*/, false /* signed */, true /* digested, doesn't matter in this case*/); +} - YCPValue ret; - extern ZyppRecipients::MediaChangeSensitivity _silent_probing; - - // remember the current value - ZyppRecipients::MediaChangeSensitivity _silent_probing_old = _silent_probing; +/**************************************************************************************** + * @builtin SourceProvideDir + * @short make a directory available at the local filesystem + * @description + * Let an InstSrc provide some directory (make it available at the local filesystem) and + * all the files within it (non recursive). + * Warning: The downloaded files are removed in Pkg::SourceReleaseAll()! + * + * @param integer SrcId Specifies the InstSrc . + * @param integer medianr Number of the media the file is located on ('1' for the 1st media). + * @param string dir Directoryname relative to the media root. + * @return string local path as string + */ +YCPValue +PkgFunctions::SourceProvideDir (const YCPInteger& id, const YCPInteger& mid, const YCPString& d) +{ + y2warning("Pkg::SourceProvideDir() is obsoleted use Pkg::SourceProvideDirectory() instead"); + // non optional, non recursive + return SourceProvideDirectory(id, mid, d, false, false); + return SourceProvideDirectoryInternal(id, mid, d, false, false, false); +} - // disable media change callback - _silent_probing = ZyppRecipients::MEDIA_CHANGE_OPTIONALFILE; +YCPValue +PkgFunctions::SourceProvideDirectoryInternal(const YCPInteger& id, const YCPInteger& mid, const YCPString& d, const YCPBoolean &optional, const YCPBoolean &recursive, bool check_signatures) +{ + CallInitDownload(std::string(_("Downloading ") + d->value())); - zypp::Source_Ref src; bool found = true; + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) + found = false; - try { - src = logFindSource(id->value()); - } - catch (const zypp::Exception& excpt) - { - found = false; - } + zypp::filesystem::Pathname path; // FIXME user ManagedMedia + + extern ZyppRecipients::MediaChangeSensitivity _silent_probing; + // remember the current value + ZyppRecipients::MediaChangeSensitivity _silent_probing_old = _silent_probing; - zypp::filesystem::Pathname path; + // disable media change callback for optional file + if (optional->value()) + _silent_probing = ZyppRecipients::MEDIA_CHANGE_OPTIONALFILE; if (found) { - try { - path = src.provideFile(f->value(), mid->asInteger()->value()); + try + { + if (check_signatures) + { + // use a Fetcher for downloading signed files (see bnc#409927) + zypp::Fetcher f; + f.reset(); + zypp::OnMediaLocation mloc(d->value(), mid->value()); + // create the tmpdir in <_root>/var/tmp + zypp::filesystem::TmpDir tmpdir(_download_area / zypp::filesystem::TmpDir::defaultLocation() ); + + // keep the reference to the tmpdir so the directory is not deleted at the and of the block + tmp_dirs.push_back(tmpdir); + path = tmpdir.path(); + f.setOptions(zypp::Fetcher::AutoAddIndexes); + f.enqueueDigestedDir(mloc, recursive->value()); + f.start(path, *repo->mediaAccess()); // uses MediaAccess to retrieve + f.reset(); + } + else + { + path = repo->mediaAccess()->provideDir(d->value(), recursive->value(), mid->value()); + } } catch (const zypp::Exception& excpt) { - found = false; - // the file is optional, don't set error flag here + _last_error.setLastError(ExceptionAsString(excpt)); + y2milestone ("Directory not found: %s", d->value_cstr()); + found = false; } } - // set the original probing value _silent_probing = _silent_probing_old; - - CallSourceReportEnd(_("Downloading files...")); - CallSourceReportDestroy(); + CallDestDownload(); if (found) { @@ -858,48 +1282,6 @@ } /**************************************************************************************** - * @builtin SourceProvideDir - * @short make a directory available at the local filesystem - * @description - * Let an InstSrc provide some directory (make it available at the local filesystem) and - * all the files within it (non recursive). - * - * @param integer SrcId Specifies the InstSrc . - * @param integer medianr Number of the media the file is located on ('1' for the 1st media). - * @param string dir Directoryname relative to the media root. - * @return string local path as string - */ -YCPValue -PkgModuleFunctions::SourceProvideDir (const YCPInteger& id, const YCPInteger& mid, const YCPString& d) -{ - zypp::Source_Ref src; - - try - { - src = logFindSource(id->value()); - } - catch (const zypp::Exception& excpt) - { - return YCPVoid (); - } - - zypp::filesystem::Pathname path; - - try - { - path = src.provideDirTree(d->value(), mid->asInteger()->value()); - } - catch (const zypp::Exception& excpt) - { - _last_error.setLastError(excpt.asUserString()); - y2milestone ("Directory not found: %s", d->value_cstr()); - return YCPVoid(); - } - - return YCPString(path.asString()); -} - -/**************************************************************************************** * @builtin SourceChangeUrl * @short Change Source URL * @description @@ -910,33 +1292,42 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceChangeUrl (const YCPInteger& id, const YCPString& u) +PkgFunctions::SourceChangeUrl (const YCPInteger& id, const YCPString& u) { - zypp::Source_Ref src; - try { - src = logFindSource(id->value()); - } - catch (const zypp::Exception& excpt) - { + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) return YCPBoolean(false); - } - try { - zypp::Pathname pth = src.path(); - zypp::Url url = zypp::Url(u->value ()); - zypp::media::MediaManager media_mgr; - zypp::media::MediaAccessId media_id = media_mgr.open(url); - src.changeMedia(media_id, pth); + try + { + if (repo->repoInfo().baseUrlsSize() > 1) + { + // store current urls + std::set<zypp::Url> baseUrls (repo->repoInfo().baseUrlsBegin(), repo->repoInfo().baseUrlsEnd()); + + // reset url list and store the new one there + repo->repoInfo().setBaseUrl(zypp::Url(u->value())); + + // add the rest of base urls + for (std::set<zypp::Url>::const_iterator i = baseUrls.begin(); + i != baseUrls.end(); ++i) + repo->repoInfo().addBaseUrl(*i); + } + else + repo->repoInfo().setBaseUrl(zypp::Url(u->value())); } catch (const zypp::Exception & excpt) { - _last_error.setLastError(excpt.asUserString()); - y2error ("Cannot change media for source %lld: %s", id->asInteger()->value(), excpt.msg().c_str()); + _last_error.setLastError(ExceptionAsString(excpt)); + y2error ("Cannot set the new URL for source %s (%lld): %s", + repo->repoInfo().alias().c_str(), id->asInteger()->value(), excpt.msg().c_str()); return YCPBoolean(false); } + return YCPBoolean(true); } + /**************************************************************************************** * @builtin SourceInstallOrder * @@ -946,65 +1337,11 @@ YCPValue PkgModuleFunctions::SourceInstallOrder (const YCPMap& ord) { - /* TODO FIXME - YCPList args; - args->add (ord); - - //-------------------------------------------------------------------------------------// - YcpArgLoad decl(__FUNCTION__); - - YCPMap & order_map( decl.arg<YT_MAP, YCPMap>() ); - - if ( ! decl.load( args ) ) { - return pkgError_bad_args; - } - //-------------------------------------------------------------------------------------// - - InstSrcManager::InstOrder order; - order.reserve( order_map->size() ); - bool error = false; - - for ( YCPMapIterator it = order_map->begin(); it != order_map->end(); ++it ) { - - if ( it.value()->isInteger() ) { - InstSrc::UniqueID uId( it.value()->asInteger()->value() ); - InstSrcManager::ISrcId source_id( _y2pm.instSrcManager().getSourceByID( uId ) ); - if ( source_id ) { - if ( source_id->enabled() ) { - order.push_back( uId ); // finaly ;) - - } else { - y2error ("order map entry '%s:%s': source not enabled", - it.key()->toString().c_str(), - it.value()->toString().c_str() ); - error = true; - } - } else { - y2error ("order map entry '%s:%s': bad source id", - it.key()->toString().c_str(), - it.value()->toString().c_str() ); - error = true; - } - } else { - y2error ("order map entry '%s:%s': integer value expected", - it.key()->toString().c_str(), - it.value()->toString().c_str() ); - error = true; - } - } - if ( error ) { - return pkgError( Error::E_bad_args ); - } - - // store new instorder - _y2pm.instSrcManager().setInstOrder( order ); -*/ - + /* TODO FIXME */ #warning SourceInstallOrder is not implemented return YCPBoolean( true ); } - static std::string timestamp () { time_t t = time(NULL); @@ -1022,137 +1359,24 @@ } /** - * Take the ?alias=foo part of old_url, if any, and return it, - * putting the rest to new_url. - * \throws Exception on malformed URLs I guess - */ -static std::string removeAlias (const zypp::Url & old_url, - zypp::Url & new_url) -{ - std::string alias; - new_url = old_url; - zypp::url::ParamMap query = new_url.getQueryStringMap (); - zypp::url::ParamMap::iterator alias_it = query.find ("alias"); - if (alias_it != query.end ()) - { - alias = alias_it->second; - query.erase (alias_it); - new_url.setQueryStringMap (query); - } - return alias; -} - - -/** Create a Source and immediately put it into the SourceManager. - * \return the SourceId - * \throws Exception if Source creation fails -*/ -zypp::SourceManager::SourceId -createManagedSource( const zypp::Url & url_r, - const zypp::Pathname & path_r, - const bool base_source, - const std::string& type ) -{ - y2milestone ("Original URL: %s", url_r.asString().c_str()); - - // #158850#c17, if the URL contains an alias, we use that - zypp::Url new_url; - string alias = removeAlias (url_r, new_url); - - y2milestone("Using alias (from URL): '%s'", alias.c_str()); - - zypp::Source_Ref newsrc = - (type.empty()) ? - // autoprobe source type - zypp::SourceFactory().createFrom(new_url, path_r, alias, zypp::filesystem::Pathname(), base_source) : - // use required source type, autorefresh = true - zypp::SourceFactory().createFrom(type, new_url, path_r, alias, zypp::filesystem::Pathname(), base_source, true); - - y2milestone("Alias of the new source: %s", newsrc.alias().c_str()); - - bool alias_found = false; - std::list<zypp::SourceManager::SourceId> ids = zypp::SourceManager::sourceManager()->allSources(); - - // remember the existing aliases - std::list<std::string> aliases; - - for( std::list<zypp::SourceManager::SourceId>::iterator it = ids.begin(); it != ids.end(); ++it) - { - try - { - zypp::Source_Ref src = zypp::SourceManager::sourceManager()->findSource(*it); - aliases.push_back(src.alias()); - - if (src.alias() == newsrc.alias()) - { - alias_found = true; - break; - } - } - catch (const zypp::Exception& excpt) - { - // this should never happen - y2internal("Source ID %lu not found: %s", *it, excpt.msg().c_str()); - } - } - - if (alias_found) - { - y2milestone("Alias is already in use"); - } - - // if the source has empty alias use a time stamp - if (newsrc.alias().empty() || alias_found) - { - - // use product name+edition as the alias - // (URL is not enough for different sources in the same DVD drive) - // alias must be unique, add timestamp - zypp::ResStore products = newsrc.resolvables (zypp::Product::TraitsType::kind); - zypp::ResStore::iterator - b = products.begin (), - e = products.end (); - if (b != e) - { - zypp::ResObject::Ptr p = *b; - alias = p->name () + '-' + p->edition ().asString () + '-'; - } - - if (alias.empty()) - { - alias = newsrc.alias() + '-'; - } - - alias += timestamp (); - - // does the alias already exist? - if (std::find_if(aliases.begin(), aliases.end(), std::bind2nd(std::equal_to<std::string>(), alias)) != aliases.end()) - { - // yes, make the alias unique (see bnc #406720) - int uniq_suffix = 0; - std::string new_alias; - - do - { - std::ostringstream os; - os << alias << '_' << uniq_suffix; - new_alias = os.str(); - uniq_suffix++; - } - while (std::find_if(aliases.begin(), aliases.end(), std::bind2nd(std::equal_to<std::string>(), new_alias)) != aliases.end()); - - y2milestone("Make the new alias unique: '%s' -> '%s'", alias.c_str(), new_alias.c_str()); - alias = new_alias; - } - - newsrc.setAlias( alias ); - - y2milestone("Using time stamp '%s' as the alias", alias.c_str()); + * Take the ?alias=foo part of old_url, if any, and return it, + * putting the rest to new_url. + * \throws Exception on malformed URLs I guess + */ +static std::string removeAlias (const zypp::Url & old_url, + zypp::Url & new_url) +{ + std::string alias; + new_url = old_url; + zypp::url::ParamMap query = new_url.getQueryStringMap (); + zypp::url::ParamMap::iterator alias_it = query.find ("alias"); + if (alias_it != query.end ()) + { + alias = alias_it->second; + query.erase (alias_it); + new_url.setQueryStringMap (query); } - - zypp::SourceManager::SourceId id = zypp::SourceManager::sourceManager()->addSource( newsrc ); - y2milestone("Added source %lu: %s %s (alias %s)", id, new_url.asString().c_str(), path_r.asString().c_str(), alias.c_str() ); - return id; + return alias; } /**************************************************************************************** @@ -1194,10 +1418,18 @@ * @return list<integer> list of SrcIds (integer). **/ YCPValue -PkgModuleFunctions::SourceScan (const YCPString& media, const YCPString& pd) +PkgFunctions::SourceScan (const YCPString& media, const YCPString& pd) +{ + // not base product, autoprobe source type, scanning only + return SourceCreateEx(media, pd, false, YCPString(""), true); +} + +YCPValue +PkgFunctions::SourceCreateEx (const YCPString& media, const YCPString& pd, bool base, const YCPString& source_type, bool scan_only) { - zypp::SourceFactory factory; + y2debug("Creating source..."); + zypp::Pathname pn(pd->value ()); zypp::Url url; @@ -1207,72 +1439,184 @@ catch(const zypp::Exception & expt ) { y2error ("Invalid URL: %s", expt.asString().c_str()); - _last_error.setLastError(expt.asUserString()); - return YCPList(); + _last_error.setLastError(ExceptionAsString(expt)); + return YCPInteger (-1LL); } - zypp::Pathname pn(pd->value ()); + const std::string type = source_type->value(); + const bool scan = pd->value().empty(); - YCPList ids; - unsigned int id; + // steps: (scan), download, build cache, load resolvables + PkgProgress pkgprogress(_callbackHandler); + std::list<std::string> stages; - if ( pd->value().empty() ) { - // scan all sources + // display the scan stage only when needed + if (scan) + { + stages.push_back(_("Search Available Products")); + } + + if (source_type->value().empty()) + { + stages.push_back(_("Probe Source Type")); + } - zypp::SourceFactory::ProductSet products; + stages.push_back(_("Download Descriptions")); + stages.push_back(_("Rebuild Cache")); - try - { - factory.listProducts( url, products ); + if (!scan_only) + { + stages.push_back(_("Load Data")); + } + + pkgprogress.Start(_("Adding the Repository..."), stages, _(HelpTexts::create_help)); + + zypp::ProgressData prg(100); + prg.sendTo(pkgprogress.Receiver()); + prg.toMin(); + + // remember the new ids for loading the resolvables + std::list<RepoId> new_repos; + + if (scan) { + // scan all sources + zypp::MediaProductSet products; + + try { + ScanProductsWithCallBacks(url); + products = available_products; } catch ( const zypp::Exception& excpt) { - y2error("Scanning products for '%s' has failed" - , url.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); - return ids; + _last_error.setLastError(ExceptionAsString(excpt)); + y2error( "Cannot read the product list from the media" ); + return YCPInteger(-1LL); } - + if( products.empty() ) { // no products found, use the base URL instead - zypp::SourceFactory::ProductEntry entry ; + zypp::MediaProductEntry entry ; products.insert( entry ); } - - for( zypp::SourceFactory::ProductSet::const_iterator it = products.begin(); + + // scanning has been finished + prg.set(5); + pkgprogress.NextStage(); + + // register the repositories + for( zypp::MediaProductSet::const_iterator it = products.begin(); it != products.end() ; ++it ) { + y2milestone("Using product %s in directory %s", it->_name.c_str(), it->_dir.c_str()); + zypp::CombinedProgressData subprogrcv(prg, 85/products.size()); + try { - id = createManagedSource(url, it->_dir, false, ""); - ids->add( YCPInteger(id) ); + // don't use spaces in alias + std::string alias(it->_name); + zypp::str::replaceAll(alias, " ", "-"); + + RepoId id = createManagedSource(url, it->_dir, type, alias, pkgprogress, subprogrcv); + + new_repos.push_back(id); } catch ( const zypp::Exception& excpt) { - y2error("SourceScan for '%s' product '%s' has failed" + y2error("SourceCreate for '%s' product '%s' has failed" , url.asString().c_str(), pn.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); + _last_error.setLastError(ExceptionAsString(excpt)); + return YCPInteger(-1LL); + } + } + + if (!scan_only) + { + // load resolvables + for(std::list<RepoId>::const_iterator it = new_repos.begin(); + it != new_repos.end() ; ++it ) + { + zypp::CombinedProgressData subprogrcv2(prg, 10/products.size()); + + try + { + YRepo_Ptr repo = logFindRepository(*it); + + // no detailed progress needed, refresh has been done in createManagedSource() + LoadResolvablesFrom(repo, subprogrcv2); + + // search for a base product if it hasn't been set + if (base && !base_product) + { + y2milestone("Searching a base product..."); + base_product = FindBaseProduct(repo->repoInfo().alias()); + } + } + catch ( const zypp::Exception& excpt) + { + y2error("SourceCreate for '%s' product '%s' has failed" + , url.asString().c_str(), pn.asString().c_str()); + _last_error.setLastError(ExceptionAsString(excpt)); + return YCPInteger(-1LL); + } } } } else { y2debug("Creating source..."); + zypp::CombinedProgressData subprogrcv_create(prg, 80); + zypp::CombinedProgressData subprogrcv_load(prg, 20); + try { - id = createManagedSource(url, pn, false, ""); - ids->add( YCPInteger(id) ); + RepoId new_id = createManagedSource(url, pn, type, "", pkgprogress, subprogrcv_create); + new_repos.push_back(new_id); + + if (!scan_only) + { + pkgprogress.NextStage(); + + YRepo_Ptr repo = logFindRepository(new_id); + + // load the resolvables + LoadResolvablesFrom(repo, subprogrcv_load); + + if (base && !base_product) + { + y2milestone("Searching the base product..."); + base_product = FindBaseProduct(repo->repoInfo().alias()); + } + } } catch ( const zypp::Exception& excpt) { - y2error("SourceScan for '%s' product '%s' has failed" + y2error("SourceCreate for '%s' product '%s' has failed" , url.asString().c_str(), pn.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); + _last_error.setLastError(ExceptionAsString(excpt)); + return YCPInteger(-1LL); } } - y2milestone("Found sources: %s", ids->toString().c_str() ); - return ids; + prg.toMax(); + + if (!scan_only) + { + PkgFreshen(); + return YCPInteger(*new_repos.begin()); + } + else + { + YCPList ids; + + // load resolvables + for(std::list<RepoId>::const_iterator it = new_repos.begin(); + it != new_repos.end() ; ++it ) + { + ids->add(YCPInteger(*it)); + } + + return ids; + } } /**************************************************************************************** @@ -1323,113 +1667,6 @@ return SourceCreateEx (media, pd, false, type); } -YCPValue -PkgModuleFunctions::SourceCreateEx (const YCPString& media, const YCPString& pd, bool base, const YCPString& source_type) -{ - y2debug("Creating source..."); - - zypp::SourceFactory factory; - zypp::Pathname pn(pd->value ()); - - zypp::Url url; - - try { - url = zypp::Url(media->value ()); - } - catch(const zypp::Exception & expt ) - { - y2error ("Invalid URL: %s", expt.asString().c_str()); - _last_error.setLastError(expt.asUserString()); - return YCPInteger (-1LL); - } - - - YCPList ids; - int ret = -1; - - const std::string type = source_type->value(); - - if ( pd->value().empty() ) { - // scan all sources - - zypp::SourceFactory::ProductSet products; - - try { - factory.listProducts( url, products ); - } - catch ( const zypp::Exception& excpt) - { - _last_error.setLastError(excpt.asUserString()); - y2error( "Cannot read the product list from the media" ); - return YCPInteger(-1LL); - } - - if( products.empty() ) - { - // no products found, use the base URL instead - zypp::SourceFactory::ProductEntry entry ; - products.insert( entry ); - } - - for( zypp::SourceFactory::ProductSet::const_iterator it = products.begin(); - it != products.end() ; ++it ) - { - try - { - unsigned id = createManagedSource(url, it->_dir, base, type); - - zypp::Source_Ref src = zypp::SourceManager::sourceManager()->findSource(id); - - src.enable(); - - CallSourceReportInit(); - CallSourceReportStart(_("Parsing files...")); - zypp_ptr()->addResolvables (src.resolvables()); - CallSourceReportEnd(_("Parsing files...")); - CallSourceReportDestroy(); - - // return the id of the first product - if ( ret == -1 ) - ret = id; - - } - catch ( const zypp::Exception& excpt) - { - y2error("SourceCreate for '%s' product '%s' has failed" - , url.asString().c_str(), pn.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); - } - } - } else { - y2debug("Creating source..."); - - try - { - ret = createManagedSource(url, pn, base, type); - - zypp::Source_Ref src = zypp::SourceManager::sourceManager()->findSource(ret); - - src.enable(); - - CallSourceReportInit(); - CallSourceReportStart(_("Parsing files...")); - zypp_ptr()->addResolvables (src.resolvables()); - CallSourceReportEnd(_("Parsing files...")); - CallSourceReportDestroy(); - } - catch ( const zypp::Exception& excpt) - { - y2error("SourceCreate for '%s' product '%s' has failed" - , url.asString().c_str(), pn.asString().c_str()); - _last_error.setLastError(excpt.asUserString()); - } - } - - PkgFreshen(); - return YCPInteger(ret); -} - - /**************************************************************************************** * @builtin SourceSetEnabled * @@ -1440,48 +1677,60 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceSetEnabled (const YCPInteger& id, const YCPBoolean& e) +PkgFunctions::SourceSetEnabled (const YCPInteger& id, const YCPBoolean& e) { - zypp::Source_Ref src; - bool enabled = e->value(); - - try { - src = logFindSource(id->value()); - } - catch (const zypp::Exception& excpt) - { + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) return YCPBoolean(false); - } + + // no change required + bool enable = e->value(); + if ((enable && repo->repoInfo().enabled()) + || (!enable && !repo->repoInfo().enabled())) + return YCPBoolean(true); + + bool success = true; try { - if (enabled) + repo->repoInfo().setEnabled(enable); + + // add/remove resolvables + if (enable) { - src.enable(); - if (!src.resStoreInitialized ()) + // load resolvables only when they haven't been loaded yet + if (!repo->isLoaded()) { - zypp_ptr()->addResolvables (src.resolvables()); + std::list<std::string> stages; + stages.push_back(_("Load Data")); + + PkgProgress pkgprogress(_callbackHandler); + zypp::ProgressData prog_total(100); + prog_total.sendTo(pkgprogress.Receiver()); + zypp::CombinedProgressData load_subprogress(prog_total, 100); + + pkgprogress.Start(_("Loading the Package Manager..."), stages, _(HelpTexts::load_resolvables)); + + success = LoadResolvablesFrom(repo, load_subprogress); } } else { - src.disable(); - // remove the resolvables if they have been added - if (src.resStoreInitialized ()) - { - zypp_ptr()->removeResolvables(src.resolvables()); - } + // the source has been disabled, remove resolvables from the pool + RemoveResolvablesFrom(repo); } + PkgFreshen(); } catch (const zypp::Exception& excpt) { - std::string url = src.url().asString(); - y2error ("Error for %s: %s", url.c_str(), excpt.asString().c_str()); - _last_error.setLastError(url + ": " + excpt.asUserString()); + std::string alias = repo->repoInfo().alias(); + y2error ("Error for '%s': %s", alias.c_str(), excpt.asString().c_str()); + _last_error.setLastError(alias + ": " + ExceptionAsString(excpt)); + success = false; } - return YCPBoolean(src.enabled() == enabled); + return YCPBoolean(success); } /**************************************************************************************** @@ -1495,36 +1744,77 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceSetAutorefresh (const YCPInteger& id, const YCPBoolean& e) +PkgFunctions::SourceSetAutorefresh (const YCPInteger& id, const YCPBoolean& e) { - zypp::Source_Ref src; - - try - { - src = logFindSource(id->value()); - } - catch (const zypp::Exception& excpt) - { - return YCPVoid(); - } + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) + return YCPBoolean(false); - src.setAutorefresh(e->value()); + repo->repoInfo().setAutorefresh(e->value()); return YCPBoolean( true ); } /**************************************************************************************** * @builtin SourceFinish - * @short Disable an Installation Source + * @short Disable an Installation Source - obsoleted * @param integer SrcId Specifies the InstSrc. * @return boolean **/ YCPValue -PkgModuleFunctions::SourceFinish (const YCPInteger& id) +PkgFunctions::SourceFinish (const YCPInteger& id) { return SourceSetEnabled(id, false); } +YCPValue +PkgFunctions::SourceRefreshHelper (const YCPInteger& id, bool forced) +{ + y2milestone("Forced refresh : %s", forced ? "true" : "false"); + + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) + return YCPBoolean(false); + + PkgProgress pkgprogress(_callbackHandler); + std::list<std::string> stages; + + // stages: "download", "build cache" + stages.push_back(_("Refresh Metadata")); + stages.push_back(_("Rebuild Cache")); + + // two steps + zypp::ProgressData prog_total(2); + prog_total.sendTo(pkgprogress.Receiver()); + + // 3 steps per repository (download, cache rebuild, load resolvables) + pkgprogress.Start(_("Refreshing Repository..."), stages, _(HelpTexts::refresh_help)); + + try + { + zypp::RepoManager repomanager = CreateRepoManager(); + y2milestone("Refreshing metadata '%s'", repo->repoInfo().alias().c_str()); + RefreshWithCallbacks(repo->repoInfo(), zypp::ProgressData::ReceiverFnc(), forced ? zypp::RepoManager::RefreshForced : zypp::RepoManager::RefreshIfNeeded); + + // next stage, increase progress + prog_total.incr(); + pkgprogress.NextStage(); + + y2milestone("Caching source '%s'...", repo->repoInfo().alias().c_str()); + repomanager.buildCache(repo->repoInfo(), forced ? zypp::RepoManager::BuildForced : zypp::RepoManager::BuildIfNeeded); + } + catch ( const zypp::Exception & expt ) + { + y2error ("Error while refreshing the source: %s", expt.asString().c_str()); + _last_error.setLastError(repo->repoInfo().alias() + ": " + ExceptionAsString(expt)); + return YCPBoolean(false); + } + + pkgprogress.Done(); + + return YCPBoolean( true ); +} + /**************************************************************************************** * @builtin SourceRefreshNow * @short Attempt to immediately refresh a Source @@ -1537,25 +1827,10 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceRefreshNow (const YCPInteger& id) +PkgFunctions::SourceRefreshNow (const YCPInteger& id) { - zypp::Source_Ref src; - - try { - src = logFindSource(id->value()); - } - catch (const zypp::Exception& excpt) - { - return YCPBoolean(false); - } - - try { - src.refresh(); - } catch ( const zypp::Exception & expt ) { - y2error ("Error while refreshin the source: %s", expt.asString().c_str()); - return YCPBoolean(false); - } - return YCPBoolean( true ); + // refresh if needed + return SourceRefreshHelper(id); } /**************************************************************************************** @@ -1570,33 +1845,41 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceDelete (const YCPInteger& id) +PkgFunctions::SourceDelete (const YCPInteger& id) { - zypp::SourceManager::SourceId src_id = id->value(); + YRepo_Ptr repo = logFindRepository(id->value()); + if (!repo) + return YCPBoolean(false); + + bool success = true; + const std::string repo_alias(repo->repoInfo().alias()); + try { - zypp::Source_Ref src = zypp::SourceManager::sourceManager()-> - findSource(src_id); - // If the source cache is corrupt for any reason, inst_source - // would first try to access the resolvables only now, - // preventing the deletion of the broken source. But we do - // not need to remove resolvables that never got to the pool - // in the first place. #174840. - if (src.resStoreInitialized ()) + + // the resolvables cannot be used anymore, remove them + RemoveResolvablesFrom(repo); + + // update 'repos' + repo->setDeleted(); + + // removing the base product repository? + if (base_product && base_product->repoInfo().alias() == repo_alias) { - zypp_ptr()->removeResolvables(src.resolvables()); + y2warning("Resetting the base product, the base product repository has been removed"); + base_product = NULL; } - zypp::SourceManager::sourceManager()->removeSource(src_id); + PkgFreshen(); } catch (const zypp::Exception& excpt) { - y2error("Pkg::SourceDelete: Cannot remove source %lld", id->value()); - _last_error.setLastError(excpt.asUserString()); - return YCPBoolean(false); + y2error ("Error for '%s': %s", repo_alias.c_str(), excpt.asString().c_str()); + _last_error.setLastError(repo_alias + ": " + ExceptionAsString(excpt)); + success = false; } - return YCPBoolean(true); + return YCPBoolean(success); } /**************************************************************************************** @@ -1608,39 +1891,39 @@ * source priority (highest first). A source state is a map: * $[ * "SrcId" : YCPInteger, - * "enabled" : YCPBoolean - * "autorefresh": YCPBoolean + * "enabled" : YCPBoolean, + * "autorefresh": YCPBoolean, + * "name" : YCPString, + * "service" : YCPString, + * "keeppackages" : YCPBoolean, * ]; * * @return list<map> list of source states (map) **/ YCPValue -PkgModuleFunctions::SourceEditGet () +PkgFunctions::SourceEditGet () { YCPList ret; - std::list<zypp::SourceManager::SourceId> ids = zypp::SourceManager::sourceManager()->allSources(); - for( std::list<zypp::SourceManager::SourceId>::iterator it = ids.begin(); it != ids.end(); ++it) + unsigned long index = 0; + for( RepoCont::const_iterator it = repos.begin(); it != repos.end(); ++it, ++index) { - YCPMap src_map; - zypp::Source_Ref src; - - try - { - src = zypp::SourceManager::sourceManager()->findSource(*it); - } - catch (const zypp::Exception& excpt) + if (!(*it)->isDeleted()) { - // this should never happen - y2internal("Source ID %lu not found: %s", *it, excpt.msg().c_str()); - } + YCPMap src_map; - src_map->add(YCPString("SrcId"), YCPInteger(*it)); - src_map->add(YCPString("enabled"), YCPBoolean(src.enabled())); - src_map->add(YCPString("autorefresh"), YCPBoolean(src.autorefresh())); - src_map->add(YCPString("alias"), YCPString(src.alias())); + src_map->add(YCPString("SrcId"), YCPInteger(index)); + // Note: enabled() is tribool + src_map->add(YCPString("enabled"), YCPBoolean((*it)->repoInfo().enabled())); + // Note: autorefresh() is tribool + src_map->add(YCPString("autorefresh"), YCPBoolean((*it)->repoInfo().autorefresh())); + src_map->add(YCPString("name"), YCPString((*it)->repoInfo().name())); + src_map->add(YCPString("priority"), YCPInteger((*it)->repoInfo().priority())); + src_map->add(YCPString("service"), YCPString((*it)->repoInfo().service())); + src_map->add(YCPString("keeppackages"), YCPBoolean((*it)->repoInfo().keepPackages())); - ret->add(src_map); + ret->add(src_map); + } } return ret; @@ -1661,7 +1944,7 @@ * @return boolean **/ YCPValue -PkgModuleFunctions::SourceEditSet (const YCPList& states) +PkgFunctions::SourceEditSet (const YCPList& states) { bool error = false; @@ -1669,7 +1952,7 @@ { if( ! states->value(index)->isMap() ) { - ycperror( "Pkg::SourceEditSet, entry not a map at index %d", index); + y2error( "Pkg::SourceEditSet, entry not a map at index %d", index); error = true; continue; } @@ -1678,20 +1961,17 @@ if (descr->value( YCPString("SrcId") ).isNull() || !descr->value(YCPString("SrcId"))->isInteger()) { - ycperror( "Pkg::SourceEditSet, SrcId not defined for a source description at index %d", index); + y2error( "Pkg::SourceEditSet, SrcId not defined for a source description at index %d", index); error = true; continue; } - int id = descr->value( YCPString("SrcId") )->asInteger()->value(); - zypp::Source_Ref src; - try { - src = zypp::SourceManager::sourceManager()->findSource(id); - } - catch (const zypp::Exception& excpt) + RepoId id = descr->value( YCPString("SrcId") )->asInteger()->value(); + + YRepo_Ptr repo = logFindRepository(id); + if (!repo) { - ycperror( "Pkg::SourceEditSet, source %d not found", index); - _last_error.setLastError(excpt.asUserString()); + y2error( "Pkg::SourceEditSet, source %d not found", index); error = true; continue; } @@ -1701,33 +1981,48 @@ { bool enable = descr->value(YCPString("enabled"))->asBoolean ()->value(); - if (src.enabled() != enable) + if (repo->repoInfo().enabled() != enable) { - ycpwarning("Pkg::SourceEditSet() does not refresh the pool (src: %lu, state: %s)", src.numericId(), enable ? "disabled -> enabled" : "enabled -> disabled"); + y2warning("Pkg::SourceEditSet() does not refresh the pool (src: %zd, state: %s)", id, enable ? "disabled -> enabled" : "enabled -> disabled"); } - if( enable ) - src.enable(); - else - src.disable(); + y2debug("set enabled: %d", enable); + repo->repoInfo().setEnabled(enable); } if( !descr->value(YCPString("autorefresh")).isNull() && descr->value(YCPString("autorefresh"))->isBoolean ()) { - src.setAutorefresh( descr->value(YCPString("autorefresh"))->asBoolean ()->value() ); + bool autorefresh = descr->value(YCPString("autorefresh"))->asBoolean()->value(); + y2debug("set autorefresh: %d", autorefresh); + repo->repoInfo().setAutorefresh( autorefresh ); } - if( !descr->value(YCPString("alias")).isNull() && descr->value(YCPString("alias"))->isString()) + if( !descr->value(YCPString("name")).isNull() && descr->value(YCPString("name"))->isString()) { // rename the source - zypp::SourceManager::sourceManager()->renameSource(src.numericId(), descr->value(YCPString("alias"))->asString()->value() ); + y2debug("set name: %s", descr->value(YCPString("name"))->asString()->value().c_str()); + repo->repoInfo().setName(descr->value(YCPString("name"))->asString()->value()); + } + + if( !descr->value(YCPString("priority")).isNull() && descr->value(YCPString("priority"))->isInteger()) + { + unsigned int priority = descr->value(YCPString("priority"))->asInteger()->value(); + + // set the priority + repo->repoInfo().setPriority(priority); + y2debug("set priority: %d", priority); } -#warning SourceEditSet ordering not implemented yet + if(!descr->value(YCPString("keeppackages")).isNull() && descr->value(YCPString("keeppackages"))->isBoolean()) + { + bool keeppackages = descr->value(YCPString("keeppackages"))->asBoolean()->value(); + y2debug("set keeppackages: %d", keeppackages); + repo->repoInfo().setKeepPackages( keeppackages ); + } } PkgFreshen(); - return YCPBoolean( true ); + return YCPBoolean( !error ); } ///////////////////////////////////////////////////////////////////////////////////////// Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.loT URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.loT?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.loT (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Source.loT Tue May 10 20:10:47 2011 @@ -0,0 +1,7 @@ +# Source.lo - a libtool object file +# Generated by ltmain.sh - GNU libtool 1.5.22 (1.1220.2.365 2005/12/18 22:14:06) +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Target.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Target.cc?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Target.cc (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Target.cc Tue May 10 20:10:47 2011 @@ -38,43 +38,78 @@ #include <zypp/target/rpm/RpmDb.h> #include <zypp/Product.h> -#include <zypp/SourceManager.h> +#include <zypp/RepoManager.h> +#include <zypp/Locks.h> #include <zypp/DiskUsageCounter.h> -#include <zypp/target/store/PersistentStorage.h> + +#include <PkgProgress.h> using namespace zypp; /** ------------------------ * * @builtin TargetInit - * @deprecated * @short Initialize Target and load resolvables * @param string root Root Directory - * @param boolean new If true, initialize new rpm database + * @param boolean unused Dummy option, only for backward compatibility * @return boolean */ YCPValue PkgModuleFunctions::TargetInit (const YCPString& root, const YCPBoolean & /*unused_and_broken*/) { - std::string r = root->value(); + bool rebuild_rpmdb = false; + const std::string r(root->value()); + + // display the progress if the target is changed or if the resolvables haven't been loaded + // otherwise there will be a quick flashing progress with no real action + if (_target_root == r && _target_loaded) + { + y2milestone("Target %s is already initialized", r.c_str()); + return YCPBoolean(true); + } + + std::list<std::string> stages; + stages.push_back(_("Initialize the Target System")); + stages.push_back(_("Read Installed Packages")); + + PkgProgress pkgprogress(_callbackHandler); + pkgprogress.Start(_("Loading the Package Manager..."), stages, _("")); try { - zypp_ptr()->initTarget(r); - zypp_ptr()->addResolvables( zypp_ptr()->target()->resolvables(), true ); + if (rebuild_rpmdb) + { + y2milestone("Initializing the target with rebuild"); + } + + zypp_ptr()->initializeTarget(r, rebuild_rpmdb); + //pkgprogress.NextStage(); + zypp_ptr()->target()->load(); + _target_loaded = true; } catch (zypp::Exception & excpt) { - _last_error.setLastError(excpt.asUserString()); - ycperror("TargetInit has failed: %s", excpt.msg().c_str() ); + _last_error.setLastError(ExceptionAsString(excpt)); + y2error("TargetInit has failed: %s", excpt.msg().c_str() ); return YCPError(excpt.msg().c_str(), YCPBoolean(false)); } - - _target_root = zypp::Pathname(root->value()); - - // we have moved to a different target, the broken source information - // is no longer valid - _broken_sources.clear(); + + _target_root = zypp::Pathname(r); + + // locks are optional, might not be present on the target + zypp::Pathname lock_file(_target_root + zypp::ZConfig::instance().locksFile()); + try + { + // read and apply the persistent locks + y2milestone("Reading locks from %s", lock_file.asString().c_str()); + zypp::Locks::instance().readAndApply(lock_file); + } + catch (zypp::Exception & excpt) + { + y2warning("Error reading persistent locks from %s", lock_file.asString().c_str()); + } + + pkgprogress.Done(); return YCPBoolean(true); } @@ -97,16 +132,12 @@ } catch (zypp::Exception & excpt) { - _last_error.setLastError(excpt.asUserString()); - ycperror("TargetInit has failed: %s", excpt.msg().c_str() ); + _last_error.setLastError(ExceptionAsString(excpt)); + y2error("TargetInit has failed: %s", excpt.msg().c_str() ); return YCPError(excpt.msg().c_str(), YCPBoolean(false)); } - + _target_root = zypp::Pathname(root->value()); - - // we have moved to a different target, the broken source information - // is no longer valid - _broken_sources.clear(); return YCPBoolean(true); } @@ -120,17 +151,33 @@ YCPValue PkgModuleFunctions::TargetLoad () { + if (_target_loaded) + { + y2milestone("The target system is already loaded"); + return YCPBoolean(true); + } + + std::list<std::string> stages; + stages.push_back(_("Read Installed Packages")); + + PkgProgress pkgprogress(_callbackHandler); + + pkgprogress.Start(_("Loading the Package Manager..."), stages, _("")); + try { - zypp_ptr()->addResolvables( zypp_ptr()->target()->resolvables(), true ); + zypp_ptr()->target()->load(); + _target_loaded = true; } catch (zypp::Exception & excpt) { - _last_error.setLastError(excpt.asUserString()); - ycperror("TargetLoad has failed: %s", excpt.msg().c_str() ); + _last_error.setLastError(ExceptionAsString(excpt)); + y2error("TargetLoad has failed: %s", excpt.msg().c_str() ); return YCPError(excpt.msg().c_str(), YCPBoolean(false)); } - + + pkgprogress.Done(); + return YCPBoolean(true); } @@ -146,26 +193,23 @@ { try { - zypp::SourceManager::disableSourcesAt( _target_root ); +// FIXME: should it also remove from pool? - // disable source refresh - workaround for #220056 - zypp::storage::PersistentStorage store; - store.init( _target_root ); + zypp::RepoManager repomanager = CreateRepoManager(); + std::list<zypp::RepoInfo> all_sources = repomanager.knownRepositories(); - std::list<zypp::source::SourceInfo> new_sources = store.storedSources(); - y2milestone("Disabling refresh for sources at %s", _target_root.asString().c_str()); - - for ( std::list<zypp::source::SourceInfo>::iterator it = new_sources.begin(); it != new_sources.end(); ++it) + for (std::list<zypp::RepoInfo>::iterator it = all_sources.begin(); it != all_sources.end(); ++it) { - y2milestone("Disabling refresh: alias: %s", it->alias().c_str()); + y2milestone("Disabling source '%s'", it->alias().c_str()); it->setAutorefresh(false); - store.storeSource( *it ); + + repomanager.modifyRepository(it->alias(), *it); } } catch (zypp::Exception & excpt) { - _last_error.setLastError(excpt.asUserString()); - ycperror("TargetDisableSources has failed: %s", excpt.msg().c_str() ); + _last_error.setLastError(ExceptionAsString(excpt)); + y2error("TargetDisableSources has failed: %s", excpt.msg().c_str() ); return YCPBoolean(false); } @@ -185,14 +229,21 @@ try { zypp_ptr()->finishTarget(); + + zypp::Pathname lock_file(_target_root + zypp::ZConfig::instance().locksFile()); + zypp::Locks::instance().save(lock_file); } catch (zypp::Exception & excpt) { - _last_error.setLastError(excpt.asUserString()); - ycperror("TargetFinish has failed: %s", excpt.msg().c_str() ); + _last_error.setLastError(ExceptionAsString(excpt)); + y2error("TargetFinish has failed: %s", excpt.msg().c_str() ); return YCPBoolean(false); } + // reset the target + _target_root = zypp::Pathname(); + _target_loaded = false; + return YCPBoolean(true); } @@ -218,8 +269,8 @@ } catch (zypp::Exception & excpt) { - _last_error.setLastError(excpt.asUserString()); - ycperror("TargetInstall has failed: %s", excpt.asString().c_str()); + _last_error.setLastError(ExceptionAsString(excpt)); + y2error("TargetInstall has failed: %s", excpt.asString().c_str()); return YCPBoolean(false); } @@ -247,8 +298,8 @@ } catch (zypp::Exception & excpt) { - _last_error.setLastError(excpt.asUserString()); - ycperror("TargetRemove has failed: %s", excpt.asString().c_str()); + _last_error.setLastError(ExceptionAsString(excpt)); + y2error("TargetRemove has failed: %s", excpt.asString().c_str()); return YCPBoolean(false); } @@ -266,17 +317,8 @@ YCPBoolean PkgModuleFunctions::TargetLogfile (const YCPString& name) { - try - { - return YCPBoolean (zypp_ptr()->target()->setInstallationLogfile (name->value())); - } - catch (zypp::Exception & excpt) - { - _last_error.setLastError(excpt.asUserString()); - ycperror("TargetLogfile has failed: %s", excpt.asString().c_str()); - return YCPBoolean(false); - } - return YCPBoolean (true); // never reached + y2warning("Pkg::TargetLogfile() is obsoleted, the log file is now entirely handled by libzypp. See http://en.opensuse.org/Libzypp/Package_History"); + return YCPBoolean (true); } @@ -375,56 +417,65 @@ try { - for (ResStore::resfilter_const_iterator it = zypp_ptr()->target()->byKindBegin(ResTraits<Product>::kind); it != zypp_ptr()->target()->byKindEnd(ResTraits<Product>::kind); ++it) + zypp::ResPool pool( zypp::ResPool::instance() ); // ResPool is a global singleton + + for_( it, pool.byKindBegin<zypp::Product>(), pool.byKindEnd<zypp::Product>() ) { - zypp::Product::constPtr product = asKind<const zypp::Product>( *it ); -#warning TargetProducts does not return all keys + if ( ! it->status().isInstalled() ) + continue; + zypp::Product::constPtr product = asKind<zypp::Product>( it->resolvable() ); + + #warning TargetProducts does not return all keys YCPMap prod; - // see also PkgModuleFunctions::Descr2Map and Product.ycp::Product -// FIXME unify with code in Pkg::ResolvablePropertiesEx + // see also PkgFunctions::Descr2Map and Product.ycp::Product + // FIXME unify with code in Pkg::ResolvablePropertiesEx prod->add( YCPString("name"), YCPString( product->name() ) ); prod->add( YCPString("version"), YCPString( product->edition().version() ) ); - prod->add(YCPString("category"), YCPString(product->category())); - prod->add(YCPString("vendor"), YCPString(product->vendor())); - prod->add(YCPString("relnotes_url"), YCPString(product->releaseNotesUrl().asString())); - std::string product_summary = product->summary(); - if (product_summary.size() > 0) - { - prod->add(YCPString("display_name"), YCPString(product_summary)); - } - std::string product_shortname = product->shortName(); - if (product_shortname.size() > 0) - { - prod->add(YCPString("short_name"), YCPString(product_shortname)); - } - // use summary for the short name if it's defined - else if (product_summary.size() > 0) - { - prod->add(YCPString("short_name"), YCPString(product_summary)); - } - prod->add(YCPString("description"), YCPString((*it)->description())); - - std::string resolvable_summary = (*it)->summary(); - if (resolvable_summary.size() > 0) - { - prod->add(YCPString("summary"), YCPString((*it)->summary())); - } - YCPList updateUrls; - std::list<zypp::Url> pupdateUrls = product->updateUrls(); - for (std::list<zypp::Url>::const_iterator it = pupdateUrls.begin(); it != pupdateUrls.end(); ++it) - { - updateUrls->add(YCPString(it->asString())); - } - prod->add(YCPString("update_urls"), updateUrls); - - YCPList flags; - std::list<std::string> pflags = product->flags(); - for (std::list<std::string>::const_iterator flag_it = pflags.begin(); - flag_it != pflags.end(); ++flag_it) - { - flags->add(YCPString(*flag_it)); - } - prod->add(YCPString("flags"), flags); + + std::string category(product->isTargetDistribution() ? "base" : "addon"); + prod->add(YCPString("type"), YCPString(category)); + prod->add(YCPString("category"), YCPString(category)); + + prod->add(YCPString("vendor"), YCPString(product->vendor())); + prod->add(YCPString("relnotes_url"), YCPString(product->releaseNotesUrls().first().asString())); + std::string product_summary = product->summary(); + if (product_summary.size() > 0) + { + prod->add(YCPString("display_name"), YCPString(product_summary)); + } + std::string product_shortname = product->shortName(); + if (product_shortname.size() > 0) + { + prod->add(YCPString("short_name"), YCPString(product_shortname)); + } + // use summary for the short name if it's defined + else if (product_summary.size() > 0) + { + prod->add(YCPString("short_name"), YCPString(product_summary)); + } + prod->add(YCPString("description"), YCPString((*it)->description())); + + std::string resolvable_summary = (*it)->summary(); + if (resolvable_summary.size() > 0) + { + prod->add(YCPString("summary"), YCPString((*it)->summary())); + } + YCPList updateUrls; + zypp::Product::UrlList pupdateUrls = product->updateUrls(); + for_( it, pupdateUrls.begin(), pupdateUrls.end() ) + { + updateUrls->add(YCPString(it->asString())); + } + prod->add(YCPString("update_urls"), updateUrls); + + YCPList flags; + std::list<std::string> pflags = product->flags(); + for (std::list<std::string>::const_iterator flag_it = pflags.begin(); + flag_it != pflags.end(); ++flag_it) + { + flags->add(YCPString(*flag_it)); + } + prod->add(YCPString("flags"), flags); products->add(prod); } @@ -471,7 +522,7 @@ // set the mount points zypp_ptr()->setPartitions(system); } - + /** ------------------------ * @@ -687,7 +738,7 @@ { try { - return YCPBoolean (zypp_ptr()->target()->whoOwnsFile(filepath->value())); + return YCPBoolean (zypp_ptr()->target()->whoOwnsFile(filepath->value()).c_str()); } catch (...) { @@ -696,7 +747,6 @@ return YCPBoolean(false); } - /** @builtin TargetStoreRemove @@ -711,70 +761,5 @@ YCPBoolean PkgModuleFunctions::TargetStoreRemove(const YCPString& root, const YCPSymbol& kind_r) { - zypp::Resolvable::Kind kind; - std::string req_kind = kind_r->symbol(); - - if( req_kind == "product" ) { - kind = zypp::ResTraits<zypp::Product>::kind; - } - else if ( req_kind == "patch" ) { - kind = zypp::ResTraits<zypp::Patch>::kind; - } - else if ( req_kind == "package" ) { - kind = zypp::ResTraits<zypp::Package>::kind; - } - else if ( req_kind == "selection" ) { - kind = zypp::ResTraits<zypp::Selection>::kind; - } - else if ( req_kind == "pattern" ) { - kind = zypp::ResTraits<zypp::Pattern>::kind; - } - else if ( req_kind == "language" ) { - kind = zypp::ResTraits<zypp::Language>::kind; - } - else - { - y2error("Pkg::TargetStoreRemove: unknown symbol: %s", req_kind.c_str()); - return YCPBoolean(false); - } - - bool success = true; - - std::string target_root = root->value(); - if (target_root.empty()) - { - y2error("Pkg::TargetStoreRemove: parameter root is empty"); - return YCPBoolean(false); - } - - try - { - // create a storage - zypp::storage::PersistentStorage store; - store.init( target_root ); - - // get all resolvables of the required kind - std::list<ResObject::Ptr> objects = store.storedObjects(kind); - - y2warning("Removing %d objects of kind '%s' from %s", objects.size(), req_kind.c_str(), target_root.c_str()); - - // remove the resolvables - for( std::list<ResObject::Ptr>::const_iterator it = objects.begin(); it != objects.end(); ++it) - { - try { - store.deleteObject(*it); - } catch( const zypp::Exception& excpt ) - { - y2error("TargetStoreRemove has failed: %s", excpt.msg().c_str()); - success = false; - } - } - } - catch( const zypp::Exception& excpt ) - { - y2error("TargetStoreRemove has failed: %s", excpt.msg().c_str()); - success = false; - } - - return YCPBoolean(success); + return YCPBoolean(true); } Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.cc?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.cc (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.cc Tue May 10 20:10:47 2011 @@ -0,0 +1,17 @@ +#include <ycp/y2log.h> +#include "Utils.h" + +std::string ExceptionAsString(const zypp::Exception &e) +{ + std::string ret = e.asUserString(); + + if (e.historySize() > 0) + { + ret += "\n" + e.historyAsString(); + } + + y2debug("Error message: %s", ret.c_str()); + + return ret; +} + Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.h?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.h (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/Utils.h Tue May 10 20:10:47 2011 @@ -0,0 +1,10 @@ + +#ifndef PKGBINDINGS_UTILS_H +#define PKGBINSINGS_UTILS_H + +#include <zypp/base/Exception.h> + +// convert Exception object to string represenatation +std::string ExceptionAsString(const zypp::Exception &e); + +#endif Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.cc?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.cc (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.cc Tue May 10 20:10:47 2011 @@ -0,0 +1,63 @@ +/* ------------------------------------------------------------------------------ + * Copyright (c) 2007 Novell, Inc. All Rights Reserved. + * + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of version 2 of the GNU General Public License as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may find + * current contact information at www.novell.com. + * ------------------------------------------------------------------------------ + */ + +/* + File: $Id$ + Author: Ladislav Slezák <lslezak@novell.com> + Summary: YRepo class is a Yast representaion of a repository +*/ + +#include <YRepo.h> + +#define y2log_component "Pkg" +#include <ycp/y2log.h> + +IMPL_PTR_TYPE(YRepo); + +YRepo::YRepo(zypp::RepoInfo & repo) + : _repo(repo), _deleted(false), _loaded(false) +{} + +YRepo::~YRepo() +{ + if (_maccess) + { + try { _maccess->release(); } + catch (const zypp::media::MediaException & ex) + { + y2error("Error in ~Yrepo(): %s", ex.asString().c_str()); + } + } +} + +zypp::MediaSetAccess_Ptr & YRepo::mediaAccess() +{ + if (!_maccess) + { + y2milestone("Creating new MediaSetAccess for url %s", + (*_repo.baseUrlsBegin()).asString().c_str()); + _maccess = new zypp::MediaSetAccess(_repo.name(), *_repo.baseUrlsBegin()); // FIXME handle multiple baseUrls + } + + return _maccess; +} + +const YRepo YRepo::NOREPO; + Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.h?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.h (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/YRepo.h Tue May 10 20:10:47 2011 @@ -0,0 +1,65 @@ + +/* ------------------------------------------------------------------------------ + * Copyright (c) 2007 Novell, Inc. All Rights Reserved. + * + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of version 2 of the GNU General Public License as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may find + * current contact information at www.novell.com. + * ------------------------------------------------------------------------------ + */ + +/* + File: $Id$ + Author: Ladislav Slezák <lslezak@novell.com> + Summary: YRepo class is a Yast representaion of a repository +*/ + +#ifndef YRepo_h +#define YRepo_h + +#include <zypp/RepoInfo.h> +#include <zypp/MediaSetAccess.h> +#include <zypp/base/ReferenceCounted.h> + +DEFINE_PTR_TYPE(YRepo); +class YRepo : public zypp::base::ReferenceCounted +{ +private: + zypp::RepoInfo _repo; + zypp::MediaSetAccess_Ptr _maccess; + bool _deleted; + bool _loaded; + + YRepo() {} + +public: + YRepo(zypp::RepoInfo & repo); + ~YRepo(); + + const zypp::RepoInfo & repoInfo() const { return _repo; } + zypp::RepoInfo & repoInfo() { return _repo; } + zypp::MediaSetAccess_Ptr & mediaAccess(); + + bool isDeleted() {return _deleted;} + void setDeleted() {_deleted = true;} + + bool isLoaded() {return _loaded;} + void setLoaded() {_loaded = true;} + void resetLoaded() {_loaded = false;} + +public: + static const YRepo NOREPO; +}; + +#endif Added: branches/tmp/dmacvicar/zc10/pkg-bindings/src/log.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/log.h?rev=63940&view=auto ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/log.h (added) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/log.h Tue May 10 20:10:47 2011 @@ -0,0 +1,4 @@ + +#define y2log_component "Pkg" +#include <y2util/y2log.h> + Modified: branches/tmp/dmacvicar/zc10/pkg-bindings/src/ycpTools.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/zc10/pkg-bindings/src/ycpTools.h?rev=63940&r1=63939&r2=63940&view=diff ============================================================================== --- branches/tmp/dmacvicar/zc10/pkg-bindings/src/ycpTools.h (original) +++ branches/tmp/dmacvicar/zc10/pkg-bindings/src/ycpTools.h Tue May 10 20:10:47 2011 @@ -29,6 +29,7 @@ #include <YCP.h> #include <zypp/Pathname.h> +#include <zypp/Product.h> #include <zypp/Url.h> /////////////////////////////////////////////////////////////////// @@ -244,6 +245,16 @@ return ret; } +/** Trasform zypp::Product::UrlList into YCPList */ +inline YCPList asYCPList( const zypp::Product::UrlList & urls_r ) +{ + YCPList ret; + for_( it, urls_r.begin(), urls_r.end() ) + { + ret->add( YCPString(it->asCompleteString()) ); + } + return ret; +} /////////////////////////////////////////////////////////////////// -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org
participants (1)
-
dmacvicar@svn2.opensuse.org