On Thursday 18 July 2013 10:23:34 Chen, Gui wrote:
I tried the two ways here: 1. steps: 'select pattern base' 'deselect package A' 'resolve pool' Result: A, B, C, D ... I attached my source code, which was adapted to use the first way. And I have tested in openSUSE 12.2, it runs successfully, my chroot includes A, B, C, D however, instead of printing resolve problems.
I modified your code to print out the return values of the status changes you apply in mark_poolitem. (restore the location of your repo) === U_Tu_(6)pattern:base-.noarch(tmp) applied setToBeInstalled This is currently selected: U_Tu_(6)pattern:base-.noarch(tmp) === U__s_(5)A-0.1-1.x86_64(tmp) applied resetTransact === U__s_(5)A-0.1-1.x86_64(tmp) FAILED TO APPLY setToBeUninstalled This is currently selected: U_Tu_(6)pattern:base-.noarch(tmp) This would have been commited: U_Ts_(2)D-1.0-1.x86_64(tmp) U_Ts_(3)C-0.1-1.x86_64(tmp) U_Ts_(4)B-1.0-1.x86_64(tmp) U_Ts_(5)A-0.1-1.x86_64(tmp) USTu_(6)pattern:base-.noarch(tmp) Actually you did not deselect A. Only pattern:base is selected and resolved. That's why A,B,C,D are installed. Why? A PoolItem combines the basic data of a single package(pattern/patch/..) instance with a simple status. Package instances are found in the rpm database (@System) as well as in repositories. On a typical system you will have multiple instances of a package called e.g. "kernel": installed: kernel-1.0 (@System) kernel-1.1 (@System) available: kernel-1.0 (repo: foo) kernel-1.1 (repo: foo-updates) kernel-1.2 (repo: foo-updates) kernel-2.0 (repo: experimental) So you have 6 PoolItems named "kernel". The status of each PoolItem describes this instances fate: - unchanged: nothing happens - transacts: for an installed item it means it gets deleted; for an available item it means it gets installed; - locked: not allowed to change the status; raises a resolver conflict if a change would be necessary. In your case you requested setToBeUninstalled for an available PoolItem. As the item is not installed, the request can't be fulfilled. What you wanted is to lock A, in fact all available instances of A if there were multiple, so the solver will not be allowed to select any of them and raise a conflict instead. Obviously by looking at a single PoolItem you do not get the whole picture. You always need to consider all PoolItems for of given name in order to see what is, and what will happen. A 'normal' package update for example will cause the installed as well as one available PoolItem to 'transact'. Only in case multiple versions of a package can be installed in parallel (e.g. kernel), each PoolItem can be treated (more or less) independently. The above collection of all PoolItems of the same name is available as ui::Selectable. This class also allows to get/set an overall status for this 'name' (translating this into solver requests and adjusting the individual PoolItems): ui::Selectable::Ptr sel = ui::Selectable::get( "A" ); // (package) A if ( ! sel ) std::cout << "No package:A in the pool" << endl; else if ( ! sel->setStatus( ui::S_Taboo, ResStatus::USER ) ) std::cout << "FAILED to set S_Taboo on " << sel << endl; // ui::Selectable::get( ResKind::package, "A" ); // ui::Selectable::get( ResKind::pattern, "base" ); // ui::Selectable::get( IdString( "pattern:base" ) ); // also get from Solvable or PoolItem With the above fix, you get the desired resolver conflict. Choosing to ignore it. you get D,C installed: Problem: ============================== pattern:base-.noarch requires A, but this requirement cannot be provided uninstallable providers: A-0.1-1.x86_64[tmp] ------------------------------ Solution: do not forbid installation of A-0.1-1.x86_64[tmp] TransactionSolutionAction: Unlock U_Lu_(5)A-0.1-1.x86_64(tmp) Solution: do not install pattern:base-.noarch TransactionSolutionAction: Keep UBTu_(6)pattern:base-.noarch(tmp) Solution: break pattern:base-.noarch by ignoring some of its dependencies InjectSolutionAction: Weak UBTu_(6)pattern:base-.noarch(tmp) ============================== PICK LAST SOLUTION SOLVE AGAIN This would have been commited: U_Ts_(2)D-1.0-1.x86_64(tmp) U_Ts_(3)C-0.1-1.x86_64(tmp) UBTu_(6)pattern:base-.noarch(tmp) JFYI: There is also a way to directly file solver requests. It is currently a bit limited, as it just supports Capabilities (you 'd not be be asking for 'package A' but for 'something providing A', which is close, but not exactly the same). This API will be enhanced as it's probably nice to usee for simple tasks. ResPool pool( ResPool::instance() ); pool.resolver().addRequire( Capability("pattern:base") ); pool.resolver().addConflict( Capability("A") ); pool.resolver().resolvePool(); -- cu, Michael Andres +------------------------------------------------------------------+ Key fingerprint = 2DFA 5D73 18B1 E7EF A862 27AC 3FB8 9E3A 27C6 B0E4 +------------------------------------------------------------------+ Michael Andres SUSE LINUX Products GmbH, Development, ma@suse.de GF:Jeff Hawn,Jennifer Guild,Felix Imendörffer, HRB16746(AG Nürnberg) Maxfeldstrasse 5, D-90409 Nuernberg, Germany, ++49 (0)911 - 740 53-0 +------------------------------------------------------------------+