home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / root / usr / share / YaST2 / modules / PackageSystem.ycp < prev    next >
Text File  |  2006-11-29  |  8KB  |  334 lines

  1. /**
  2.  * File:    modules/PackageSystem.ycp
  3.  * Package:    yast2
  4.  * Summary:    Packages manipulation (system)
  5.  * Authors:    Martin Vidner <mvidner@suse.cz>
  6.  *        Michal Svec <msvec@suse.cz>
  7.  * Flags:    Stable
  8.  *
  9.  * $Id: PackageSystem.ycp 33164 2006-09-27 08:42:24Z jsrain $
  10.  *
  11.  * The documentation is maintained at
  12.  * <a href="../index.html">.../docs/index.html</a>.
  13.  */
  14.  
  15. {
  16.  
  17. module "PackageSystem";
  18. textdomain "base";
  19.  
  20. import "Mode";
  21. import "PackageCallbacksInit";
  22. import "PackageLock";
  23. import "Report";
  24. import "Stage";
  25. import "CommandLine";
  26.  
  27. /**
  28.  * Was last operation canceled?
  29.  *
  30.  * Used to enhance the exit status to distinguish between package
  31.  * installation fail and installation canceled by user, as in the second
  32.  * case doesn't make much sense to display any error
  33.  * Is set to true when user canceled package installation, from
  34.  * PackageSystem::* functions
  35.  */
  36. boolean last_op_canceled = false;
  37.  
  38. /**
  39.  * Has Pkg::TargetInit run?
  40.  */
  41. boolean target_initialized = false;
  42.  
  43. /**
  44.  * Has Pkg::SourceStartCache run?
  45.  */
  46. boolean source_initialized = false;
  47.  
  48.  
  49. include "packages/common.ycp";
  50.  
  51.  
  52. /**
  53.  * Ensure that Pkg:: calls work.
  54.  * This may become superfluous.
  55.  */
  56. global void EnsureTargetInit() {
  57.     PackageLock::Check ();
  58.     PackageCallbacksInit::InitPackageCallbacks ();
  59.     //    target_initialized = target_initialized || Pkg::TargetInit ("/", false);
  60.     // always initizalize target, it should be cheap according to #45356
  61.     Pkg::TargetInit ("/", false);
  62. }
  63.  
  64. /**
  65.  * Ensure that Pkg:: calls working with the installation sources work
  66.  */
  67. global void EnsureSourceInit() {
  68.     PackageLock::Check ();
  69.  
  70.     if(source_initialized) 
  71.     {
  72.     // this way, if somebody closed the cache outside of Package
  73.     // (typically in installation), we will reinitialize
  74.     // it's cheap if cache is already initialized
  75.     Pkg::SourceStartCache (true);
  76.     return;
  77.     }
  78.  
  79.     PackageCallbacksInit::InitPackageCallbacks ();
  80.  
  81.     if(! target_initialized)
  82.     {
  83.     // make sure we have the RPM keys imported
  84.         EnsureTargetInit();
  85.     }
  86.  
  87.     list sources = Pkg::SourceStartCache (true);
  88.  
  89.     if (size (sources) > 0)
  90.     {
  91.     source_initialized = true;
  92.     }
  93.     else
  94.     {
  95.     /* Error message, no packages sources found */
  96.     Report::Error(_("No package source defined."));
  97.     }
  98. }
  99.  
  100. global boolean DoInstall(list<string> packages) {
  101.     return DoInstallAndRemove(packages, []);
  102. }
  103.  
  104. global boolean DoRemove(list<string> packages) {
  105.     return DoInstallAndRemove([], packages);
  106. }
  107.  
  108. global boolean DoInstallAndRemove(list<string> toinstall, list<string> toremove) {
  109.     y2debug ("toinstall: %1, toremove: %2", toinstall, toremove);
  110.     if (!PackageLock::Check ())
  111.     {
  112.     return false;
  113.     }
  114.  
  115.     EnsureSourceInit ();
  116.     EnsureTargetInit ();
  117.     boolean ok = true;
  118.  
  119.     import "Label";
  120.     import "Popup";
  121.     // licenses: #35250
  122.     map<string, string> licenses = Pkg::PkgGetLicensesToConfirm (toinstall);
  123.     if (size (licenses) > 0)
  124.     {
  125.     list<string> rt_licenses_l = maplist ( string p, string l, licenses, {
  126.         return sformat ("<p><b>%1</b></p>\n%2", p, l);
  127.     });
  128.     if (! Popup::AnyQuestionRichText (
  129.         // popup heading, with rich text widget and Yes/No buttons
  130.         _("Do you accept this license agreement?",
  131.           "Do you accept these license agreements?",
  132.           size (licenses)),
  133.         mergestring (rt_licenses_l, "\n"),
  134.         70, 20,
  135.         Label::YesButton (), Label::NoButton (),
  136.         `focus_none))
  137.     {
  138.         y2milestone("License not accepted: %1", toinstall);
  139.         last_op_canceled = true;
  140.         return false;
  141.     }
  142.     foreach (string p, string l, licenses, {
  143.         Pkg::PkgMarkLicenseConfirmed (p);
  144.     });
  145.     last_op_canceled = false;
  146.     }
  147.  
  148.     // check if the database os consistent before packages were added
  149.     boolean packages_consistent = Pkg::PkgSolveCheckTargetOnly();
  150.  
  151.     foreach (string p, toinstall, {
  152.     if(ok == true)
  153.         if(Pkg::PkgInstall(p) != true) {
  154.         y2error("Package %1 install failed: %2", p, Pkg::LastError());
  155.         ok = false;
  156.         }
  157.     });
  158.     if(ok != true) return false;
  159.  
  160.     foreach (string p, toremove, {
  161.     if(ok == true)
  162.         if(Pkg::PkgDelete(p) != true) {
  163.         y2error("Package %1 delete failed: %2", p, Pkg::LastError());
  164.         ok = false;
  165.         }
  166.     });
  167.     if(ok != true) return false;
  168.  
  169.     if(Pkg::PkgSolve (false) != true) {
  170.     y2error("Package solve failed: %1", Pkg::LastError());
  171.     if (packages_consistent)
  172.     {
  173.         return false;
  174.     }
  175.     }
  176.  
  177.     //[int successful, list failed, list remaining, list srcremaining]
  178.     list result = Pkg::PkgCommit (0);
  179.     y2debug ("PkgCommit: %1", result);
  180.     if(result[1]:[] != []) {
  181.     y2error("Package commit failed: %1", result[1]:[]);
  182.     return false;
  183.     }
  184.  
  185.     foreach (string remaining, (list<string>) (result[2]:[]), {
  186.     if(ok == true)
  187.         if(contains(toinstall, remaining)) {
  188.         y2error("Package remain: %1", remaining);
  189.         ok = false;
  190.         }
  191.     });
  192.     if(ok != true) return false;
  193.  
  194.     // Only run SUSEconfig if any packages were installed?
  195.     // No, deleted packages are not covered by this.
  196.     // if (true || result[0]:-1 > 0)
  197.  
  198.     // But omit it during installation, one is run at its end.
  199.     // #25071
  200.     if (!Stage::initial () && !Stage::cont ())
  201.     {
  202.     RunSUSEconfig ();
  203.     }
  204.  
  205.     return true;
  206. }
  207.  
  208. /**
  209.  * Is a package available?
  210.  * @return true if yes
  211.  */
  212. global boolean Available(string package) {
  213.     EnsureSourceInit();
  214.     return Pkg::IsAvailable(package);
  215. }
  216.  
  217. /**
  218.  * Is a package installed?
  219.  * @return true if yes
  220.  */
  221. global boolean Installed(string package) {
  222.     // This is a most commonly called function and so it's
  223.     // important that it's fast, especially in the common
  224.     // case, where all dependencies are satisfied.
  225.     // Unfortunately, initializing Pkg reads the RPM database...
  226.     // so we must avoid it.
  227.     return 0 == (integer) SCR::Execute(.target.bash, "rpm -q " + package);
  228.     // return Pkg::IsProvided (package);
  229. }
  230.  
  231. /**
  232.  * @short Check if packages are installed
  233.  * @descr Install them if they are not and user approves installation
  234.  *
  235.  * @param a list of packages to check (and install)
  236.  * @return boolean true if installation succeeded or packages were installed,
  237.  * false otherwise
  238.  */
  239. global boolean CheckAndInstallPackages (list<string> packages) {
  240.     if (Mode::config ())
  241.     return true;
  242.     if (InstalledAll (packages))
  243.     return true;
  244.     return InstallAll (packages);
  245. }
  246.  
  247. /**
  248.  * @short Check if packages are installed
  249.  *
  250.  * @descr Install them if they are not and user approves installation
  251.  * If installation fails (or wasn't allowed), ask user if he wants to continue
  252.  *
  253.  * @param packages a list of packages to check (and install)
  254.  * @return boolean true if installation succeeded, packages were installed
  255.  * before or user decided to continue, false otherwise
  256.  */
  257. global boolean CheckAndInstallPackagesInteractive (list<string> packages) {
  258.     boolean success = CheckAndInstallPackages (packages);
  259.     if (! success)
  260.     {
  261.     if (! LastOperationCanceled ())
  262.     {
  263.         if (Mode::commandline ())
  264.         {
  265.         // error report
  266.         Report::Error (_("Installing required packages failed."));
  267.         }
  268.         else
  269.         {
  270.         success = Popup::ContinueCancel (
  271.             // continue/cancel popup
  272.             _("Installing required packages failed. If you continue
  273. without installing required packages,
  274. YaST may not work properly.
  275. "));
  276.         }
  277.     }
  278.     else
  279.     {
  280.         if (Mode::commandline ())
  281.         {
  282.         Report::Error (
  283.             // error report
  284.             _("Cannot continue without installing required packages."));
  285.         }
  286.         else
  287.         {
  288.         success = Popup::ContinueCancel (
  289.             // continue/cancel popup
  290.             _("If you continue without installing required 
  291. packages, YaST may not work properly.
  292. "));
  293.         }
  294.     }
  295.     }
  296.     return success;
  297. }
  298.  
  299. global boolean InstallKernel (list<string> kernel_modules) {
  300.     // this function may be responsible for the horrible startup time
  301.     y2milestone ("want: %1", kernel_modules);
  302.     if (kernel_modules == [])
  303.     {
  304.     return true;        // nothing to do
  305.     }
  306.  
  307.     EnsureTargetInit ();
  308.  
  309.     list <list> provides = Pkg::PkgQueryProvides ("kernel");
  310.     y2milestone ("provides: %1", provides);
  311.  
  312.     list <list> kernels = filter (list l, provides, {
  313.         return l[1]:`NONE == `BOTH || l[1]:`NONE == l[2]:`NONE;
  314.     });
  315.  
  316.     if (size (kernels) != 1)
  317.         y2error ("not exactly one package provides tag kernel");
  318.  
  319.     string kernel = kernels[0,0]:"none";
  320.     list<string> packs = [kernel];
  321.  
  322.     if (! Pkg::IsProvided(kernel))
  323.     {
  324.     EnsureSourceInit ();
  325.     }
  326.  
  327.     // TODO: for 9.2, we always install all packages, but
  328.     // we could only install those really needed (#44394)
  329.     return InstallAll ( packs );
  330. }
  331.  
  332. /* EOF */
  333. }
  334.