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 / Update.ycp < prev    next >
Text File  |  2006-11-29  |  13KB  |  456 lines

  1. /**
  2.  * Module:        Update.ycp
  3.  *
  4.  * Authors:        Anas Nashif <nashif@suse.de>
  5.  *            Arvin Schnell <arvin@suse.de>
  6.  *
  7.  * Purpose:        Update module
  8.  *
  9.  * $Id: Update.ycp 34202 2006-11-09 12:31:44Z locilka $
  10.  */
  11. {
  12.     module "Update";
  13.  
  14.     import "Installation";
  15.     import "Packages";
  16.     import "ProductFeatures";
  17.     import "Stage";
  18.     import "SuSERelease";
  19.     import "Mode";
  20.  
  21.     // number of packages to install
  22.     global integer packages_to_install = 0;
  23.  
  24.     // number of packages to update
  25.     global integer packages_to_update = 0;
  26.  
  27.     // number of packages to remove
  28.     global integer packages_to_remove = 0;
  29.  
  30.     // number of packages unknown (problematic) by update
  31.     global integer unknown_packages = 0;
  32.  
  33.     // number of errors (packages?) returned by solver
  34.     global integer solve_errors = 0;
  35.  
  36.     // Flag is set true if the user decides to delete unmaintained packages
  37.     global boolean deleteOldPackages = ProductFeatures::GetBooleanFeature ("software", "delete_old_packages");
  38.  
  39.     // don't allow upgrade only update
  40.     global boolean disallow_upgrade = false;
  41.  
  42.     global boolean did_init1 = false;
  43.  
  44.     global boolean did_init2 = false;
  45.  
  46.  
  47.     global integer last_runlevel = -1;
  48.  
  49.  
  50.     global boolean backup_modified = true;
  51.     global boolean backup_sysconfig = true;
  52.     global boolean remove_old_backups = false;
  53.     global string backup_path = "/var/adm/backup";
  54.  
  55.  
  56.     // Only an update, NOT an upgrade
  57.     global boolean onlyUpdateInstalled = ProductFeatures::GetBooleanFeature ("software", "only_update_installed");
  58.  
  59.     global string selected_selection = "";
  60.  
  61.     global boolean products_incompatible = false;
  62.  
  63.  
  64.     /*
  65.      *  Information about old and new product.
  66.      *
  67.      *  They do contain:
  68.      *    name (string), e.g. "SuSE Linux"
  69.      *    version (string), e.g. "9.1"
  70.      *    nameandversion (string), e.g. "SuSE Linux 9.1"
  71.      *
  72.      *  They may contain:
  73.      *    major (integer), e.g. "9"
  74.      *    minor (integer), e.g. "1"
  75.      */
  76.  
  77.     // Version of the targetsystem
  78.     global map <string, any> installedVersion = $[];
  79.  
  80.     // Version of the source medium
  81.     global map <string, any> updateVersion = $[];
  82.  
  83.  
  84.     // Flag, if the basesystem have to be installed
  85.     global boolean updateBasePackages = false;
  86.  
  87.     // counter for installed packages
  88.     global integer packagesInstalled = 0;
  89.  
  90.  
  91.     // see bug #40358
  92.     global boolean manual_interaction = false;
  93.  
  94.     // are the products (installed and to update) compatible?
  95.     boolean _products_compatible = nil;
  96.  
  97.  
  98.  
  99.  
  100.     /*-----------------------------------------------------------------------
  101.      * GLOBAL FUNCTIONS
  102.      *-----------------------------------------------------------------------*/
  103.  
  104. global list<string> SelectedProducts () {
  105.     list<map<string,any> > selected
  106.     = Pkg::ResolvableProperties ("", `product, "");
  107.     selected = filter (map<string,any> p, selected, {
  108.     return p["status"]:nil == `selected;
  109.     });
  110.     return maplist (map<string,any> p, selected, {
  111.     return p["summary"]:"";
  112.     });
  113. }
  114.  
  115. /**
  116.  * Check if installed product and product to upgrade to are compatible
  117.  * @return boolean true if update is possible
  118.  */
  119. global boolean ProductsCompatible () {
  120.     if (_products_compatible == nil)
  121.     {
  122.     if (Stage::normal ())
  123.     {
  124.         // check if name of one of the products on the installation
  125.         // media is same as one of the installed products
  126.         // assuming that multiple products on installation media
  127.         // are compatible and compatibility is transitive
  128.         list<map<string,any> > inst =
  129.         Pkg::ResolvableProperties ("", `product, "");
  130.         inst = filter (map<string,any> p, inst, {
  131.         return p["status"]:nil == `installed;
  132.         });
  133.         list<string> inst_names = maplist (map<string,any> p, inst, {
  134.         return p["name"]:"";
  135.         });
  136.         list<string> to_install = maplist (integer src,
  137.         Pkg::SourceGetCurrent (true),
  138.         {
  139.         map<string,string> prod_info = Pkg::SourceProduct (src);
  140.         return prod_info["name"]:"";
  141.         });
  142.         // filter out empty products
  143.         to_install = filter (string o_p, to_install, { return o_p != ""; });
  144.  
  145.         y2milestone ("Installed products: %1", inst_names);
  146.         y2milestone ("Products on installation media: %1", to_install);
  147.  
  148.         // at least one product name found
  149.         if (size (to_install) > 0) {
  150.         string equal_product = find (string i, inst_names, {
  151.             string found = find (string u, to_install, {
  152.             return u == i;
  153.             });
  154.             return found != nil;
  155.         });
  156.         _products_compatible = equal_product != nil;
  157.         // no product name found
  158.         // bugzilla #218720, valid without testing according to comment #10
  159.         } else {
  160.         y2warning ("No products found, setting product-compatible to 'true'");
  161.         _products_compatible = true;
  162.         }
  163.     }
  164.     else
  165.     {
  166.         _products_compatible = true; // FIXME this is temporary
  167.     }
  168.     y2milestone ("Products found compatible: %1", _products_compatible);
  169.     }
  170.  
  171.     return _products_compatible;
  172. }
  173.  
  174. global void IgnoreProductCompatibility () {
  175.     _products_compatible = true;
  176.  
  177. }
  178.  
  179.     /**
  180.      *
  181.      */
  182.     global define void Reset ()
  183.     {
  184.     deleteOldPackages = ProductFeatures::GetBooleanFeature ("software", "delete_old_packages");
  185.     disallow_upgrade = false;
  186.  
  187.     manual_interaction = false;
  188.     products_incompatible = false;
  189.     _products_compatible = nil;
  190.  
  191.     backup_modified = true;
  192.     backup_sysconfig = true;
  193.     remove_old_backups = false;
  194.     backup_path = "/var/adm/backup";
  195.     }
  196.  
  197.  
  198.     /**
  199.      *
  200.      */
  201.     global define void fill_version_map (map <string, any>& data)
  202.     {
  203.     data["nameandversion"] = data["name"]:"?" + " " + data["version"]:"?";
  204.  
  205.     list <string> tmp0 = [];
  206.     if (regexpmatch (data["version"]:"", " -")) {
  207.         splitstring (data["version"]:"", " -");
  208.     }
  209.  
  210.     list <string> tmp1 = [];
  211.     if (regexpmatch (tmp0[0]:"", "\.")) {
  212.         splitstring (tmp0[0]:"", ".");
  213.     }
  214.  
  215.     integer tmp2 = tointeger (tmp1[0]:"-1");
  216.     if (tmp2 >= 0)
  217.         data["major"] = tmp2;
  218.  
  219.     integer tmp3 = tointeger (tmp1[1]:"-1");
  220.     if (tmp3 >= 0)
  221.         data["minor"] = tmp3;
  222.     }
  223.  
  224.  
  225.     /**
  226.      * Read product name and version for the old and new release.
  227.      * Fill installedVersion and updateVersion.
  228.      * @return success
  229.      */
  230.     global define boolean GetProductName ()
  231.     {
  232.     installedVersion = $[];
  233.     updateVersion = $[];
  234.  
  235.     // get old product name
  236.  
  237.     // cannot use product information from package manager
  238.     // for pre-zypp products
  239.     // #153576
  240.     string old_name = SuSERelease::ReleaseInformation
  241.         (Installation::destdir);
  242.     y2milestone("SuSERelease::ReleaseInformation: %1", old_name);
  243.  
  244.     // Remove 'Beta...' from product release
  245.     if (regexpmatch (old_name, "Beta")) {
  246.         old_name = regexpsub (old_name, "^(.*)[ \t]+Beta.*$", "\\1");
  247.     // Remove 'Alpha...' from product release
  248.     } else if (regexpmatch (old_name, "Alpha")) {
  249.         old_name = regexpsub (old_name, "^(.*)[ \t]+Alpha.*$", "\\1");
  250.     }
  251.  
  252.     integer p = findlastof (old_name, " ");
  253.     if (p == nil)
  254.     {
  255.         y2error ("release info <%1> is screwed", old_name);
  256.         installedVersion = $[];
  257.     }
  258.     else
  259.     {
  260.         installedVersion["name"] = substring (old_name, 0, p);
  261.         installedVersion["version"] = substring (old_name, p + 1);
  262.         fill_version_map (installedVersion);
  263.     }
  264.  
  265.     // "minor" and "major" version keys
  266.     // bug #153576, "version" == "9" or "10.1" or ...
  267.     string inst_ver = installedVersion["version"]:"";
  268.     if (inst_ver != "" && inst_ver != nil) {
  269.         // SLE, SLD, OES...
  270.         if (regexpmatch (inst_ver, "^[0123456789]+$")) {
  271.         installedVersion["major"] = tointeger (inst_ver);
  272.         // openSUSE
  273.         } else if (regexpmatch (inst_ver, "^[0123456789]+\.[0123456789]+$")) {
  274.         installedVersion["major"] = tointeger (regexpsub (inst_ver, "^([0123456789]+)\.[0123456789]+$", "\\1"));
  275.         installedVersion["minor"] = tointeger (regexpsub (inst_ver, "^[0123456789]+\.([0123456789]+)$", "\\1"));
  276.         } else {
  277.         y2error("Cannot find out major/minor from >%1<", inst_ver);
  278.         }
  279.     } else {
  280.         y2error("Cannot find out version: %1", installedVersion);
  281.     }
  282.     
  283.     if (Mode::test()) {
  284.         y2error ("Skipping detection of new system");
  285.         return true;
  286.     }
  287.  
  288.     // get new product name
  289.  
  290.     integer num = size (Packages::theSources);
  291.     if (num <= 0)
  292.     {
  293.         y2error ("No source");
  294.         updateVersion["name"] = "?";
  295.         updateVersion["version"] = "?";
  296.         fill_version_map (updateVersion);
  297.         return false;
  298.     }
  299.  
  300.     map new_product = Pkg::SourceProductData (Packages::theSources[num-1]:0);
  301.     y2milestone ("First source product %1", new_product);
  302.     if (new_product == nil)
  303.     {
  304.         updateVersion["name"] = "?";
  305.         updateVersion["version"] = "?";
  306.         y2error("Cannot find out source details: %1", updateVersion);
  307.         fill_version_map (updateVersion);
  308.         return false;
  309.     }
  310.  
  311.     updateVersion["name"] = new_product["productname"]:"?";
  312.     updateVersion["version"] = new_product["productversion"]:"?";
  313.     fill_version_map (updateVersion);
  314.  
  315.     string new_ver = updateVersion["version"]:"";
  316.     if (new_ver != "" && new_ver != nil) {
  317.         // SLE, SLD, OES...
  318.         if (regexpmatch (new_ver, "^[0123456789]+$")) {
  319.         updateVersion["major"] = tointeger (new_ver);
  320.         // openSUSE
  321.         } else if (regexpmatch (new_ver, "^[0123456789]+\.[0123456789]$")) {
  322.         updateVersion["major"] = tointeger (regexpsub (new_ver, "^([0123456789]+)\.[0123456789]$", "\\1"));
  323.         updateVersion["minor"] = tointeger (regexpsub (new_ver, "^[0123456789]+\.([0123456789])$", "\\1"));
  324.         } else {
  325.         y2error("Cannot find out major/minor from %1", new_ver);
  326.         }
  327.     } else {
  328.         y2error("Cannot find out version: %1", updateVersion);
  329.     }
  330.  
  331.     y2milestone ("update from %1 to %2", installedVersion, updateVersion);
  332.  
  333.     return true;
  334.     }
  335.  
  336.     global list<string> GetBasePatterns ()
  337.     {
  338.         // get available base patterns
  339.         list<map<string,any> > patterns = Pkg::ResolvableProperties ("", `pattern, "");
  340.         patterns = filter (map<string,any> p, patterns, {
  341.             if (p["status"]:nil != `selected && p["status"]:nil != `available)
  342.                 return false;
  343.             // if type != base
  344.             return true;
  345.         });
  346.     return maplist (map<string,any> p, patterns, {
  347.        return p["name"]:"";
  348.     });
  349.     }
  350.  
  351.  
  352.     /**
  353.      * Get all available base selections sorted in reverse order
  354.      * (highest ordered bases selection comes first).
  355.      */
  356.     global define list<string> GetBaseSelections ()
  357.     {
  358.     list<string> available_base_selections = sort (string x, string y, Pkg::GetSelections (`available, "base"), {
  359.         map xmap = Pkg::SelectionData(x);
  360.         map ymap = Pkg::SelectionData(y);
  361.         return (xmap["order"]:"" > ymap["order"]:"");
  362.     });
  363.     y2milestone ("available_base_selections %1", available_base_selections);
  364.     return available_base_selections;
  365.     }
  366.  
  367.     string ReadInstalledDesktop() {
  368.     SCR::Execute (.target.bash, "/bin/mv -f /etc/sysconfig/windowmanager /etc/sysconfig/windowmanager.old");
  369.     SCR::Execute (.target.bash, "/bin/ln -s /mnt/etc/sysconfig/windowmanager /etc/sysconfig/windowmanager");
  370.     string ret = (string)SCR::Read (.sysconfig.windowmanager.DEFAULT_WM);
  371.     SCR::Execute (.target.bash, "/bin/rm -f /etc/sysconfig/windowmanager");
  372.     SCR::Execute (.target.bash, "/bin/mv -f /etc/sysconfig/windowmanager.old /etc/sysconfig/windowmanager");
  373.     return ret;
  374.     }
  375.  
  376.     global void SetDesktopPattern() {
  377.     string desktop = ReadInstalledDesktop();
  378.     if (desktop == "kde" || desktop == "gnome")
  379.     {
  380.         y2milestone ("Selecting pattern to install: %1", desktop);
  381.         Pkg::ResolvableInstall (desktop, `pattern);
  382.     }
  383.     }
  384.  
  385.     /**
  386.      * Propose a selection for the update and save it's name in
  387.      * Update::selected_selection.
  388.      */
  389.     global define void ProposeSelection ()
  390.     {
  391.     selected_selection = "";
  392.  
  393.     list available_selections = GetBaseSelections ();
  394.  
  395.     // nulth try: teh default desktop
  396.  
  397.     string desktop = ReadInstalledDesktop();
  398.     map wm2sel = $[
  399.         "kde" : "default",
  400.         "gnome" : "default-Gnome",
  401.     ];
  402.     selected_selection = wm2sel[desktop]:"";
  403.  
  404.     if (!contains (available_selections, selected_selection))
  405.         selected_selection = "";
  406.  
  407.     if (selected_selection != "")
  408.     {
  409.         y2milestone ("using default desktop %1 to define selection: %2",
  410.         desktop, selected_selection);
  411.         return;
  412.     }
  413.  
  414.     // first try: installed one
  415.  
  416.     list tmp1 = Pkg::GetSelections (`installed, "base");
  417.     if (tmp1 != nil && tmp1 != [])
  418.         selected_selection = tmp1[0]:"";
  419.  
  420.     if (!contains (available_selections, selected_selection))
  421.         selected_selection = "";
  422.  
  423.     if (selected_selection != "") {
  424.         y2milestone ("using installed selection: %1", selected_selection);
  425.         return;
  426.     }
  427.  
  428.     // second try: available selection with highest order
  429.  
  430.     if (size (available_selections) > 0)
  431.         selected_selection = available_selections[0]:"";
  432.  
  433.     if (selected_selection != "") {
  434.         y2milestone ("using highest order selection: %1", selected_selection);
  435.         return;
  436.     }
  437.  
  438.     // error: no selection available
  439.  
  440.     y2error ("no selection available");
  441.  
  442.     }
  443.  
  444.  
  445.     /**
  446.      *
  447.      */
  448.     global define void Detach ()
  449.     {
  450.     Pkg::TargetFinish ();
  451.     did_init1 = false;
  452.     did_init2 = false;
  453.     }
  454.  
  455. }
  456.