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 / OSR.ycp < prev    next >
Text File  |  2006-11-29  |  30KB  |  1,057 lines

  1. /**
  2.  *  File:
  3.  *    OSR.ycp
  4.  *
  5.  *  Module:
  6.  *
  7.  *
  8.  *  Summary:
  9.  *    Control of the automatic scan and repair sequence.
  10.  *
  11.  *  Author:
  12.  *    Johannes Buchhold <jbuch@suse.de>
  13.  *
  14.  * $Id: OSR.ycp 23769 2005-06-21 12:18:10Z jsuchome $
  15.  */
  16. {
  17.   module "OSR";
  18.  
  19.   import "Linuxrc";
  20.   import "Mode";
  21.   import "Stage";
  22.   import "Report";
  23.  
  24.   import "OSRCommon";
  25.   import "OSRMode";
  26.   import "OSRProgress";
  27.   import "OSRSummary";
  28.   import "OSRStatus";
  29.   import "OSRLogFile";
  30.   import "OSRDirect";
  31.  
  32.   textdomain "repair";
  33.  
  34.   // function prototypes (needed by includes)
  35.   global define void SetReboot();
  36.  
  37.   // we have to include this files, because using them as clients is not
  38.   // possible (because of passing function references)
  39.   include "repair/osr_module_init.ycp";
  40.   include "repair/osr_module_partition.ycp";
  41.   include "repair/osr_module_packages.ycp";
  42.   include "repair/osr_module_bootloader.ycp";
  43.   // ----------------------------
  44.  
  45.   /**
  46.    * Only for define ComputesDetectMethodSequence ! not global.
  47.    */
  48.   list<string> global_provides_list        = [];
  49.  
  50.   /**
  51.    * Only for define Detect. Contains the current module index.
  52.    * osrmodule_init       -> 0
  53.    * osr_module_partition -> 1
  54.    * osr_module_grub      -> 2
  55.    */
  56.   integer index_modules = 0;
  57.  
  58.   /**
  59.    * Only for define Detect. Contains the current detection method index of a module.
  60.    * OSRPartitionCheckMBR   ->0
  61.    * OSRPartitionCheckDisks -> 1
  62.    * ..
  63.    */
  64.   integer index_detect  = 0;
  65.  
  66.   /**
  67.    * Static global_provides entries for all detection methods.
  68.    * $["root_mountpoint":"/mnt"]
  69.    */
  70.   map static_provides            = $[];
  71.  
  72.   /**
  73.    * A map with all lists of detect-methods-entries. The function-names have to be enclosed in
  74.    * double-quoted braces!
  75.    $["osr_module_init":[
  76.                         $["group":"init",
  77.               "method": ``OSRInitInit(),
  78.               "progress":10,
  79.               "provides":["has_floppy"],
  80.               "requires":[],
  81.               "summary":"Probing floppy"],
  82.                 $["group":"init",
  83.               "method": ``OSRInitFloppy(),
  84.               "progress":10,
  85.               "provides":["repair_target"],
  86.               "requires":[],
  87.               "summary":"Init target system"]],
  88.      "osr_module_partition":[
  89.                         $["group":"mbr_check",
  90.               "method":``OSRPartitionMBR(),
  91.               "progress":10,
  92.               "provides":["valid_target"],
  93.               "requires":["repair_target"],
  94.               "summary":"Searching for harddisks"],
  95.               ]
  96.               ...   
  97.    */
  98.    map module_detection_methods = $[]; 
  99.  
  100.    /**
  101.     * Contains all reset method descriptions.
  102.     * Need to reset settings for a scan and repair sequence.
  103.     */
  104.    map module_reset_methods    = $[];
  105.  
  106.   /**
  107.    * Sequence of all rescue (detect and repair) modules
  108.    *
  109.    * ["osr_module_init", "osr_module_partition"]
  110.    */
  111.    list<string> module_sequence            = [];
  112.  
  113.   /**
  114.    * Date of all rescue modules
  115.    *
  116.    *  $["osr_module_init": $[
  117.                              "headline":"OSRInit",
  118.                              "name":"osr_module_init",
  119.                  "provides":["has_floppy", "repair_target"],
  120.                  "requires":[]],
  121.        "osr_module_partition":$[
  122.                               "headline":"Partitions and filesystems",
  123.                               "name":"osr_module_partition",
  124.                   "provides":["valid_target",
  125.                   "valid_target_list", "swap_partition_list", "valid_swap_partitions", "swapable_partitions", "fs_module_loaded", .......],
  126.                       "requires":["repair_target", "has_floppy", "valid_target", "valid_target_list", "swap_partition_list", .......]
  127.             ]]
  128.     ...
  129.    */
  130.    map module_maps            = $[];
  131.  
  132.  
  133.  
  134.   /**
  135.    * Allowed back jump in a scan and repair sequence error appear.
  136.    */
  137.   global string next_detect_method        = "";
  138.  
  139.   /**
  140.    * Maximal execution of a detect function.
  141.    * (The proper meaning is "do not run max_index_detect_loop-times", so
  142.    * the variable means "maximal execution + 1")
  143.    */
  144.   integer max_index_detect_loop     = 3;
  145.  
  146.   /**
  147.    * Reset all.
  148.    */
  149.   global define void Reset()``{
  150.       global_provides_list    = [];
  151.  
  152.       index_detect        = 0;
  153.       index_modules        = 0;
  154.  
  155.       module_detection_methods        = $[];
  156.       module_sequence            = [];
  157.  
  158.       module_maps            = $[];
  159.  
  160.       OSRCommon::Reset ();
  161.   }
  162.  
  163.   /**
  164.    * Reset detect settings.
  165.    */
  166.   global define void ResetDetect() ``{
  167.       index_detect        = 0;
  168.       index_modules        = 0;
  169.  
  170.       global_provides_list      = [];
  171.  
  172.       OSRCommon::SetGlobalProvides (static_provides);
  173.  
  174.       OSRCommon::current_detect_map    = $[];
  175.       OSRCommon::current_module_name    = "";
  176.   }
  177.  
  178.   /**
  179.    * set OSRCommon::detect_group_list to []
  180.    */
  181.   global define void ResetDetectGroupList() {
  182.       OSRCommon::detect_group_list = [];
  183.   }
  184.  
  185.   /**
  186.    * return size of OSRCommon::detect_group_list
  187.    */
  188.   global define integer SizeDetectGroupList () {
  189.       return size (OSRCommon::detect_group_list);
  190.   }
  191.  
  192.   /**
  193.    * set new value for OSRCommon::detect_group_list
  194.    */
  195.   global define void SetDetectGroupList (list<string> gl) {
  196.       OSRCommon::detect_group_list = gl;
  197.   }
  198.  
  199.   /**
  200.    * get value of OSRCommon::detect_group_list
  201.    */
  202.   global define list<string> DetectGroupList() {
  203.       return OSRCommon::detect_group_list;
  204.   }
  205.  
  206.   /**
  207.    * Computes the sequence of the detection methods of a module. 
  208.    */
  209.   define list<map> ComputesDetectMethodSequence(string module_name )``{
  210.  
  211.       y2milestone("Build method sequence for module %1", module_name );
  212.  
  213.       list<map> module_detect_methods    =
  214.     module_detection_methods[module_name]:[];
  215.       list<string> method_requires_list    = [];
  216.       integer index            = 0;
  217.       list<map> ret            = [];
  218.  
  219.       while((index >= 0) && index < size (module_detect_methods )) {
  220.  
  221.       map mm =  module_detect_methods[index]:$[];
  222.       method_requires_list = mm["requires"]:[];
  223.  
  224.       if ( OSRCommon::IsSubSet(method_requires_list, global_provides_list ))
  225.       {
  226.           // if true add this module as next module in the sequence list, remove it from the
  227.           // list of modules and decrease the size of the list
  228.           ret  = add(ret, mm );
  229.  
  230.           module_detect_methods = remove(module_detect_methods, index );
  231.           index                 = 0;
  232.  
  233.           // concatenate, sort and remove duplicates of the global_provides_list and the module_provides_list
  234.           global_provides_list = (list<string>)
  235.         union (global_provides_list, mm["provides"]:[]);
  236.       }
  237.       else
  238.       {
  239.           index = index + 1;
  240.       }
  241.       }
  242. //      y2debug ("Detection method sequence for module %1 : %2", module_name , ret);
  243.       return ret;
  244.   }
  245.  
  246.   /**
  247.    *  This method resolves the requirements and provides of the modules and computes
  248.    *  the correct sequence of detection modules.
  249.    *
  250.    *  @return boolean True if the module sequence was successfully created.
  251.    */
  252.   define boolean ComputeModuleSequence(list<string> module_name_list ) ``{
  253.  
  254.       integer index                = 0;
  255.       string  module_name            = "";
  256.       list<string>    module_provides_list    = [];
  257.       list<string>    module_requires_list    = [];
  258.       list<string>    global_provides_list      = [];
  259.  
  260.       while ((index >= 0) && (index < size(module_name_list )))
  261.       {
  262.       // get the module name and its requirements
  263.       module_name          = module_name_list[ index]:"";
  264.  
  265.       module_requires_list = module_maps [module_name,"requires"]:[];
  266.       module_provides_list = module_maps [module_name,"provides"]:[];
  267.  
  268.       // check if the requirements of the current module are resolved by the global provides
  269.       if (OSRCommon::IsSubSet (module_requires_list, (list<string>)
  270.           union (global_provides_list, module_provides_list)))
  271.       {
  272.           // if true add this module as next module in the sequence list, remove it from the
  273.           // list of modules and decrease the size of the list
  274.           module_sequence  = add(module_sequence, module_name);
  275.           module_name_list = remove(module_name_list, index);
  276.           index            = 0;
  277.  
  278.           // concatenate, sort and remove duplicates of the global_provides_list and the module_provides_list
  279.           global_provides_list = (list<string>) union (global_provides_list,
  280.         module_provides_list);
  281.       }
  282.       else
  283.       {
  284.           index = index + 1;
  285.       }
  286.       }
  287.       if (size(module_name_list) != 0 )
  288.       {
  289.       y2error("ComputeModuleSequence: module(s) not added to the sequence list: %1", module_name_list);
  290.       return false;
  291.       }
  292.       return true;
  293.   };
  294.  
  295.   /**
  296.    *  This method initializes the YaST OS Repair system. It is started at first and
  297.    *  builds the main window, initializes the global osr_map and a lot of other data.
  298.    *
  299.    *  For internal use only.
  300.    *
  301.    *  @return boolean True if the initialization progress succeeded.
  302.    */
  303.   global define boolean Init() ``{
  304.  
  305.     // set repair mode (used e.g. from Bootloader)
  306.     Mode::SetMode ("repair");
  307.  
  308.     list<string> module_function_list    = [
  309.     "osr_module_init",
  310.     "osr_module_partition",
  311.     "osr_module_packages",
  312.     "osr_module_bootloader",
  313.     ];
  314.     map init_functions            = $[
  315.     "osr_module_init"    : OSRInitInit,
  316.     "osr_module_partition"    : OSRPartitionInit,
  317.     "osr_module_packages"    : OSRPackagesInit,
  318.     "osr_module_bootloader" : OSRBootloaderInit
  319.     ];
  320.  
  321.     list<string> module_name_list    = [];
  322.     integer index            = 0;
  323.  
  324.     if (( module_function_list == nil) || (size( module_function_list) == 0))
  325.     {
  326.       y2error("Something's wrong with the
  327. file \"osr_module_list.ycp\".
  328. YaST system repair halts now!");
  329.  
  330.       // popup text: %1 is "System Repair" (translated)
  331.       Report::Error(sformat(_("
  332. Error during initialization.
  333. Halting %1.
  334. "), OSRCommon::tool_name ));
  335.       return false;
  336.     }
  337.  
  338.  
  339.     OSRLogFile::Add (sformat("List of modules:\n%1\n", module_function_list));
  340.  
  341.     // execute the init-functions of all modules in the module-list
  342.     while ((index >= 0) && (index < size( module_function_list)))
  343.     {
  344.     // result of this evaluation is the module_map of the specific module
  345.     map result_map = $[];
  346.     if (module_function_list [index]:"" != "")
  347.     {
  348.         // call Init functions from all includes...
  349.         map () f = init_functions [module_function_list[index]:""]:OSRCommon::EmptyMap;
  350.         result_map = f ();
  351.     }
  352.  
  353.       if ((result_map == nil) || (result_map == $[]))
  354.       {
  355.           Report::Error(sformat(
  356. // popup text: %1 is function name, %2 is "System Repair" (translated)
  357. _("An error occurred during execution
  358. of the init functions of module %1.
  359.  
  360. Halting %2.
  361. "), module_function_list[index]:"", OSRCommon::tool_name ));
  362.  
  363.           y2error("An error occurred during execution of the init-functions
  364. of module: %1. YaST system repair halts now!",
  365.               module_function_list[index]:"" );
  366.  
  367.           return false;
  368.       }
  369.  
  370.       // the name of the current module
  371.       string module_name = result_map["name"]:"";
  372.  
  373.       // add the detect-methods of the current module to the global detect-methods-map
  374.       module_detection_methods[module_name]=result_map["detect_methods"]:[];
  375.       module_reset_methods [module_name] =  result_map["reset_methods"]:[];
  376.  
  377.       list module_provides = [];
  378.       list module_requires = [];
  379.  
  380.       foreach (map mb, result_map["detect_methods"]:[], {
  381.           module_provides = union (module_provides, mb["provides"]:[]);
  382.           module_requires = union (module_requires, mb["requires"]:[]);
  383.       });
  384.  
  385.       result_map["provides"] = module_provides;
  386.       result_map["requires"] = module_requires;
  387.  
  388.  
  389.       // get the current module-name, put it to the module-list and store it in the global map
  390.       module_name_list = add(module_name_list, module_name );
  391.  
  392.       static_provides  = union (static_provides, result_map["static_provides"]:$[] );
  393.  
  394.  
  395.       OSRCommon::global_entries   = union( OSRCommon::global_entries,  result_map["global_entries"]:$[]);
  396.  
  397.       OSRDirect::AddEntries (result_map["direct_methods"]:[],
  398.         module_function_list[index]:"");
  399.  
  400.       // delete the detect_methods from the result_map (it should not appear in the osr_map)
  401.       result_map = filter (string k, any v, (map<string,any>) result_map, ``(
  402.         k != "detect_methods" &&
  403.         k != "static_provides" &&
  404.         k != "global_entries"  &&
  405.         k != "direct_methods" )
  406.       );
  407.  
  408.       // add the module_map to the global osr_map
  409.       module_maps[ module_name ] =  result_map;
  410.  
  411.       // increase the index counter
  412.       index = index + 1;
  413.     }
  414.  
  415.     // Create the sequence-list of the detection-modules.
  416.     // This is the provides- and requirement-resolver.
  417.     if (! ComputeModuleSequence( module_name_list ))
  418.     {
  419.     y2error("Not all dependencies between the
  420. modules successfully solved. YaST system repair halts now!");
  421.  
  422.     if (! OSRMode::automatic )
  423.     {
  424.         // show error message and close the main window
  425.         //%1 is translation of "System Repair"
  426.         Report::Error(sformat(_("
  427. Not all dependencies between the
  428. modules were successfully solved.
  429.  
  430. Halting %1."), OSRCommon::tool_name ));
  431.     }
  432.     return false;
  433.     }
  434.  
  435.     y2milestone("Module sequence : %1", module_sequence );
  436.     return true;
  437.   };
  438.  
  439.  
  440.   /**
  441.    * Empty term.
  442.    */
  443.   global define boolean osr_empty() ``{
  444.       y2error("No methods to detect ");
  445.       return false;
  446.   };
  447.  
  448.   /**
  449.    * Return a list of string with group names executed at the
  450.    * beginning of every Detect sequence.
  451.    */
  452.   define list<string> forall_groups_names()``{
  453.  
  454.     // Add init groups ("mode" == "forall" )  to OSRCommon::detect_group_list
  455.     return (list<string>) maplist (string m, map vv,
  456.     filter (string k, map v, (map<string,map>)OSRCommon::global_entries, ``(
  457.         v["mode"]:"" == "forall" )),
  458.     ``( m ));
  459.   }
  460.  
  461.   /**
  462.    * Returns if all detection groups are selected for detection.
  463.    */
  464.   define boolean all_groups_selected() {
  465.       return (SizeDetectGroupList () == (size(OSRCommon::global_entries) - size( forall_groups_names())));
  466.   }
  467.  
  468.  
  469.   /**
  470.    * Returns true if the specified requires argument
  471.    * is not provided (not in the map global_provides).
  472.    */
  473.   define boolean requires_not_provided (list<string> requires) {
  474.     return !OSRCommon::IsSubSet (
  475.     requires, maplist (string k, any v, OSRCommon::GlobalProvides () ,``(k)));
  476.   }
  477.  
  478.   /**
  479.    * Returns true if all specified requires are supported
  480.    * from the selected detection groups.
  481.    */
  482.   define boolean requires_in_detection_group(list<string> requires )``{
  483.  
  484.     boolean req_not_in_detection_group = false;
  485.     foreach (string module_name, list module_detect_list,
  486.         (map<string,list>) module_detection_methods,``{
  487.  
  488.     list<map> required_module_detection_methods = (list<map>)
  489.         filter (map detect_method, (list<map>) module_detect_list, ``(
  490.         size (union (detect_method["provides"]:[], requires)) <
  491.         size (merge (detect_method["provides"]:[], requires)))
  492.         );
  493.  
  494.     list<string> required_groups = (list<string>)
  495.         maplist (map detect_method, required_module_detection_methods, ``(
  496.         detect_method["group"]:""));
  497.  
  498.     y2debug("Required module groups %1", required_groups );
  499.     if (!OSRCommon::IsSubSet (required_groups, DetectGroupList ()))
  500.     {
  501.         req_not_in_detection_group = true;
  502.     }
  503.     });
  504.  
  505.     y2debug("Requires are not in detection group: %1",
  506.     req_not_in_detection_group );
  507.     return ! req_not_in_detection_group;
  508.   }
  509.  
  510.  
  511.   /**
  512.    * Returns true if a detect method is not a member of a slected
  513.    * detection group. Skip detection.
  514.    */
  515.   define boolean skip_detect_method(map method_map )``{
  516.  
  517.       // Check if only a few groups are selected -- ignore requires ( at the moment )
  518.       if ( !contains (DetectGroupList (), method_map["group"]:""))
  519.       {
  520.       y2milestone ("Detection method '%1' skipped (not in detection group)",
  521.         method_map["name"]:"");
  522.       return true;
  523.       }
  524.       else
  525.       {
  526.       // If not all entries are selected
  527.       if (all_groups_selected ()) {
  528.           // Check if the requires for the next detection method
  529.           if ( requires_not_provided (method_map["requires"]:[] )  &&
  530.            requires_in_detection_group (method_map["requires"]:[]))
  531.           {
  532.           // next step can not be executed - skip execution
  533.           OSRLogFile::Add(sformat("Detection method with the summary :%1 could not be executed.
  534. The conditions are not complied.",module_detection_methods["summary"]:""));
  535.  
  536.           y2error ("Skip detection method (requires not solved ) %1",
  537.             method_map["name"]:"");
  538.           return true;
  539.           }
  540.       }
  541.       }
  542.       return false;
  543.   }
  544.  
  545.   /**
  546.    * Reset the temporary changes.
  547.    * e.g.: Umount temporary mounted partitions ...
  548.    */
  549.   global define boolean ResetDetectionModules()``{
  550.  
  551.       // count of executed modules
  552.       integer reset_module_index = index_modules;
  553.  
  554.       // for every module
  555.       while( reset_module_index >= 0 ) {
  556.  
  557.       string reset_module_name = module_sequence[reset_module_index]:"";
  558.       list<map> reset_methods  = module_reset_methods[reset_module_name]:[];
  559.       integer index_reset       = 0;
  560.  
  561.       while( index_reset <= size( reset_methods )) {
  562.           map current_reset_map = reset_methods[index_reset]:$[];
  563.  
  564.           if( current_reset_map != $[] )
  565.           {
  566.           if (haskey (current_reset_map , "method"))
  567.           {
  568.             boolean () f = current_reset_map["method"]:OSRCommon::False;
  569.             if (f())
  570.             {
  571.             y2milestone("%1 : was successfull",
  572.                 current_reset_map["summary"]:"");
  573.             }
  574.             else
  575.             {
  576.             y2milestone("%1 : was not successfull",
  577.                 current_reset_map["summary"]:"");
  578.             }
  579.           }
  580.           }
  581.           index_reset = index_reset + 1;
  582.       }
  583.       reset_module_index = reset_module_index -1;
  584.       }
  585.       return true;
  586.   }
  587.  
  588.  
  589.   /**
  590.    * Go back to a previous detection method.
  591.    * e.g. if a error can not repaired.
  592.    */
  593.   define boolean back2status_detect_method_name()``{
  594.  
  595.       if( OSRStatus::next_detect_method_name == "")
  596.       return false;
  597.  
  598.       integer i_modules = 0;
  599.       integer i_detect  = 0;
  600.  
  601.       while (i_modules < size(module_sequence))
  602.       {
  603.       string c_module_name  = module_sequence[ i_modules ]:"";
  604.       list<map> d_methods    = ComputesDetectMethodSequence(c_module_name );
  605.  
  606.       while(( i_detect >= 0) && ( i_detect < size(d_methods)))
  607.       {
  608.           map c_detect_map =  d_methods [i_detect]:$[];
  609.           if (OSRStatus::next_detect_method_name == c_detect_map["name"]:"")
  610.           {
  611.           index_modules = i_modules;
  612.           index_detect  = i_detect;
  613.           return true;
  614.           }
  615.           i_detect = i_detect +1;
  616.       }
  617.       i_modules = i_modules +1 ;
  618.       }
  619.  
  620.       y2error("Next detection method name not found");
  621.       return false;
  622.   }
  623.  
  624.  
  625.   /**
  626.    * Count of all detection methods.
  627.    */
  628.   define integer DetectionMethodesCount()``{
  629.  
  630.     integer number_of_detection_methods = 0;
  631.     if (size( module_sequence ) > 0)
  632.     {
  633.     list<string> detect_list    = DetectGroupList ();
  634.     foreach (string mod, module_sequence, ``{
  635.  
  636.         // count the total number of detection methods
  637.         number_of_detection_methods = number_of_detection_methods + size (
  638.         filter (map v, module_detection_methods[mod]:[], ``(
  639.             contains (detect_list, v["group"]:"" ))
  640.         ));
  641.     });
  642.     }
  643.     else
  644.     {
  645.     y2error("The sequence of the modules is empty.");
  646.     }
  647.     return number_of_detection_methods;
  648.   }
  649.  
  650.  
  651.   /**
  652.    *  This is the main detection method. It looks for the module_sequence and
  653.    *  executes all detection methods from the forthcoming modules.
  654.    *
  655.    *  @return boolean True if the detection progress succeeded.
  656.    */
  657.   define symbol detect() ``{
  658.  
  659.       integer old_detect_size = 0;
  660.  
  661.       if (!OSRCommon::IsSubSet (forall_groups_names(), DetectGroupList ()))
  662.       {
  663.       SetDetectGroupList ((list<string>) merge (
  664.         forall_groups_names(), DetectGroupList ()));
  665.       }
  666.       if ( size( module_sequence ) <= 0 )
  667.       {
  668.       y2error("List module_sequence is empty: %1. YaST system repair halts now!", module_sequence);
  669.       return `error;
  670.       }
  671.  
  672.       // Set the global progressbar steps count
  673.       if ( index_modules == 0 )
  674.       OSRProgress::SetSteps(`global_progress_bar, DetectionMethodesCount());
  675.  
  676.       ////////////////////////////////////////////////////////////////////////
  677.       //
  678.       // For every repair module
  679.       //
  680.       ///////////////////////////////////////////////////////////////////////
  681.     while (index_modules < size(module_sequence))
  682.     {
  683.     OSRCommon::current_module_name = module_sequence [ index_modules ]:"";
  684.     OSRCommon::current_direct_name = "";
  685.  
  686.     y2milestone("The name of the current module is: %1",
  687.         OSRCommon::current_module_name );
  688.  
  689.     map module_map= module_maps [ OSRCommon::current_module_name ]:$[];
  690.  
  691.     // sort the detect method sequence
  692.     list<map> detect_methods = ComputesDetectMethodSequence (
  693.         OSRCommon::current_module_name);
  694.  
  695.     if (index_detect == old_detect_size)
  696.         index_detect = 0;
  697.  
  698.     old_detect_size = size(detect_methods);
  699.  
  700.     if (index_detect == 0)
  701.         OSRProgress::SetSteps (`module_progress_bar, size(detect_methods));
  702.  
  703.     ////////////////////////////////////////////////////////////////////////
  704.     //
  705.     // Execute all detect-functions of the specified module
  706.     //
  707.     //////////////////////////////////////////////////////////////////////
  708.     integer index_detect_loop_counter = 0;
  709.     integer last_index_detect        = index_detect;
  710.  
  711.     while (( index_detect >= 0) && ( index_detect < size(detect_methods)))
  712.     {
  713.         // Poll user input
  714.         if (!OSRMode::script)
  715.         {
  716.         symbol ret = (symbol) UI::PollInput();
  717.             if (ret == `pause || ret == `cancel || ret == `abort ||
  718.             ret == `details )
  719.             return ret;
  720.         }
  721.  
  722.         OSRCommon::current_detect_map =  detect_methods[index_detect]:$[];
  723.         y2milestone("The name of the current detect method is: %1",
  724.         OSRCommon::current_detect_map["name"]:"");
  725.         if (OSRCommon::current_detect_map["name"]:"" == "")
  726.         {
  727.         y2warning ("detect map: %1", OSRCommon::current_detect_map);
  728.         }
  729.  
  730.         // check call count - no endless loop
  731.         if (index_detect != last_index_detect )
  732.         {
  733.         last_index_detect = index_detect;
  734.         }
  735.         else
  736.         {
  737.         index_detect_loop_counter = index_detect_loop_counter +1;
  738.         }
  739.  
  740.         // check skip
  741.         if (skip_detect_method(OSRCommon::current_detect_map) ||
  742.             index_detect_loop_counter == max_index_detect_loop )
  743.         {
  744.             index_detect = index_detect + 1;
  745.             if ( index_detect == size( detect_methods ))
  746.         {
  747.                 index_modules = index_modules +1 ;
  748.                 index_detect  = 0;
  749.                 return `restart;
  750.             }
  751.             continue;
  752.         }
  753.  
  754.         // Init module progress bar (DownloadProgress widget)
  755.         OSRSummary::PrepareNewEntry(OSRCommon::current_detect_map );
  756.  
  757.         // evaluate the functions and get the result_map
  758.         // ret is boolean and not used at the moment
  759.         if (haskey (OSRCommon::current_detect_map, "method"))
  760.         {
  761.         boolean () f =
  762.             OSRCommon::current_detect_map["method"]:OSRCommon::False;
  763.         f ();
  764.         }
  765.  
  766.         ///////////////////////////////////////////////////////////////////
  767.         //
  768.         // Analyse the status set by one detection method
  769.         //
  770.         ///////////////////////////////////////////////////////////////////
  771.         if ((OSRStatus::IsStatusDetectError() &&
  772.          OSRStatus::IsErrorSeverityBlocking())  ||
  773.         (OSRStatus::IsStatusRepairError() &&
  774.          OSRStatus::IsErrorSeverityBlocking())    ||
  775.         (OSRStatus::IsStatusRepairOmit() &&
  776.          OSRStatus::IsErrorSeverityBlocking())    ||
  777.         OSRStatus::IsStatusExit()  ||
  778.         OSRStatus::IsCancel())
  779.         {
  780.         // RepairError & ErrorSeverityBlocking:
  781.         // if a blocking error was detected but the repair method failed
  782.         // halt the rescue system
  783.  
  784.         // DetectError & ErrorSeverityBlocking:
  785.         // if a blocking error was detected but no repair method started
  786.         // halt the rescue system
  787.  
  788.         // RepairOmit & ErrorSeverityBlocking:
  789.         // if a blocking error was detected but the user omitted repair
  790.         // halt the rescue system
  791.  
  792.         // Exit:
  793.         // if a blocking error was detected exit the rescue system,
  794.         // e.g. if no harddisks were detected
  795.  
  796.         y2milestone("A blocking error was detected. YaST system repair halts now!");
  797.         OSRProgress::Fill (`global_progress_bar);
  798.         if( back2status_detect_method_name())
  799.         {
  800.             return `restart;
  801.         }
  802.         return (OSRStatus::IsCancel()) ? `back :  `error;
  803.         }
  804.         else if ( ( OSRStatus::IsStatusDetectError() &&
  805.                 OSRStatus::IsErrorSeverityModuleBlocking()) ||
  806.             ( OSRStatus::IsStatusRepairError() &&
  807.                 OSRStatus::IsErrorSeverityModuleBlocking())    ||
  808.             ( OSRStatus::IsStatusRepairOmit() &&
  809.                 OSRStatus::IsErrorSeverityModuleBlocking()))
  810.         {
  811.         /*
  812.             - DetectError & SeverityModuleBlocking:
  813.             if a module-blocking error was detected but no repair
  814.             method started
  815.             - RepairError & SeverityModuleBlocking:
  816.             if a module-blocking error was detected but the repair
  817.             method failed
  818.             - RepairOmit & SeverityModuleBlocking:
  819.             if the user omitted repairing a module-blocking error
  820.  
  821.             -> execute no further detection methods from the current
  822.             module and jump to the next detection module
  823.         */
  824.  
  825.         // adjust the value of the global progress bar
  826.         while (index_detect < size(detect_methods))
  827.         {
  828.             OSRProgress::Increase(`global_progress_bar);
  829.             index_detect = index_detect + 1;
  830.         }
  831.         }
  832.         else if ( OSRStatus::IsStatusDetectOK ()        ||
  833.             OSRStatus::IsStatusDetectOmit()        ||
  834.             OSRStatus::IsStatusNotFound()        ||
  835.             OSRStatus::IsStatusDetectError()    ||
  836.             OSRStatus::IsStatusDetectProblem()    ||
  837.             OSRStatus::IsStatusRepairOmit())
  838.         {
  839.           /*
  840.             - DetectOK:
  841.             no error detected
  842.             - DetectProblem:
  843.             potential problem detected and no repair method started
  844.             - RepairOmit:
  845.             user omitted repairing a "normal" error
  846.  
  847.             -> go to the next detection method
  848.             */
  849.  
  850.         // TODO no restarting is done here, so why is DetectError here?
  851.         // DetectError:
  852.         // if a "normal" error was detected but no repair method started
  853.         // restart the current detection method
  854.         OSRProgress::Increase(`global_progress_bar);
  855.         index_detect = index_detect + 1;
  856.         }
  857.         else if (OSRStatus::IsStatusRepairOK() ||
  858.              OSRStatus::IsStatusRepairError() )
  859.         {
  860.         /*
  861.             - RepairError:
  862.             repair-method was not successfull
  863.             - RepairOK:
  864.             all detected errors were repaired
  865.             ->restart detect
  866.         */
  867.  
  868.         y2milestone ("restarting detection method after repair");
  869.         /*
  870.             NOTE: detection is restarted only once - see above check
  871.             "index_detect_loop_counter == max_index_detect_loop"
  872.         */
  873.         }
  874.         else if ( OSRStatus::IsOpen() )
  875.         {
  876.         y2milestone("no status set in detection method: %1 (group %2)",
  877.             OSRCommon::current_detect_map["name"]:"",
  878.             OSRCommon::current_detect_map["group"]:"");
  879.         OSRProgress::Increase(`global_progress_bar);
  880.         index_detect = index_detect + 1;
  881.         }
  882.         else
  883.         {
  884.         y2error("not a valid status: %1", OSRStatus::status );
  885.         }
  886.  
  887.         OSRSummary::FinishNewEntry();
  888.  
  889.         if (back2status_detect_method_name())
  890.         {
  891.           OSRStatus::Open();
  892.           OSRCommon::current_detect_map  = $[];
  893.           return `restart;
  894.         }
  895.         OSRStatus::Open();
  896.         OSRCommon::current_detect_map  = $[];
  897.     }
  898.     // fill the module-progress-bar to 100%, if not already done
  899.     OSRProgress::Fill(`module_progress_bar);
  900.  
  901.     y2milestone("Finished module with the name  %1",
  902.     OSRCommon::current_module_name);
  903.  
  904.     OSRCommon::current_module_name = "";
  905.  
  906.     // go to the next module
  907.     index_modules = index_modules + 1;
  908.     }
  909.  
  910.     // fill up the global-progress-bar to 100%, this can be necessary
  911.     // because of arithmetic rounding problems
  912.     OSRProgress::Fill(`global_progress_bar);
  913.     OSRSummary::Finish();
  914.  
  915.     return `detectok;
  916.   };
  917.  
  918.  
  919.   /**
  920.    * Start detection loop.
  921.    */
  922.   global define symbol Detect()``{
  923.       symbol ret = `restart;
  924.       while( ret == `restart ) {
  925.       ret = detect();
  926.       }
  927.       return ret;
  928.   }
  929.  
  930.   /**
  931.    * Sort the sequence of all detection methods of the
  932.    * specified group.
  933.    */
  934.   define list<map> SortGroupSequence (map groups) ``{
  935.  
  936.       list<map> ret        = [];
  937.       list<string> g_list    = [];
  938.       foreach (string module_name,  module_sequence, ``{
  939.  
  940.       list<map> detect_methods = ComputesDetectMethodSequence(module_name );
  941.       foreach(map method, detect_methods, ``{
  942.           if (!contains( g_list, method["group"]:"" ))
  943.           {
  944.           g_list = add (g_list , method["group"]:"");
  945.           }
  946.       });
  947.       });
  948.       foreach(string group, g_list, ``{
  949.       ret = add( ret, add( groups[group]:$[], "key", group ));
  950.       });
  951.       return ret;
  952.   }
  953.  
  954.   /**
  955.    * Count of all reset Methods.
  956.    */
  957.   define integer ResetMethodesCount()``{
  958.  
  959.       integer number_of_reset_methods = 0;
  960.  
  961.       foreach (string mod, module_sequence, ``{
  962.       number_of_reset_methods = number_of_reset_methods +
  963.           size(module_reset_methods[mod]:[] );
  964.       });
  965.       return number_of_reset_methods;
  966.   }
  967.  
  968.  
  969.   /**
  970.    * Build item list with all group items.
  971.    * @param mode if all entries should be checked ('Select all')
  972.    */
  973.   global define list<term> GroupItems(boolean mode)``{
  974.  
  975.     list<term> entries      = [];
  976.  
  977.     foreach (map d, SortGroupSequence( OSRCommon::global_entries ), ``{
  978.     if (SizeDetectGroupList () > 0)
  979.     {
  980.         mode = contains (DetectGroupList (), d["key"]:"");
  981.     }
  982.     if (d["mode"]:"" != "forall" && d["key"]:"" != "" && d["text"]:"" != "")
  983.     {
  984.         entries = add (entries, `item(`id(d["key"]:""), d["text"]:"",mode));
  985.     }
  986.     else if( d["mode"]:"" != "forall" )
  987.     {
  988.         y2error("Key not valid ('%1') or text entry ('%2') is empty",
  989.         d["key"]:"", d["text"]:"");
  990.     }
  991.     });
  992.     return entries;
  993.   }
  994.  
  995.  
  996.  
  997.  
  998.   global define void SelectDefaultDetectGroups()``{
  999.  
  1000.     SetDetectGroupList (maplist (map vv,
  1001.     filter (map v, SortGroupSequence (OSRCommon::global_entries), ``(
  1002.         v["selected"]:true == true)),
  1003.     ``(vv["key"]:""))
  1004.     );
  1005.   }
  1006.  
  1007.   /**
  1008.    * check the dependencies for seleced detect groups
  1009.    */
  1010.   global define list<string> CheckGroupRequires()``{
  1011.  
  1012.     list<string> ret =  [];
  1013.     boolean again = true;
  1014.     while ( again )
  1015.     {
  1016.     boolean found = false;
  1017.     foreach (string group, DetectGroupList (), {
  1018.  
  1019.         list<string> requires = (list<string>)
  1020.         OSRCommon::global_entries[group,"requires"]:[];
  1021.         foreach (string req, requires, {
  1022.         if (!contains (OSRCommon::detect_group_list, req))
  1023.         {
  1024.             if (!contains(ret, req))
  1025.             {
  1026.             ret = (list<string>) toset(add(ret, req));
  1027.             found = true;
  1028.             }
  1029.         }
  1030.         });
  1031.     });
  1032.     if (found)
  1033.     {
  1034.         SetDetectGroupList ((list<string>) union (DetectGroupList (), ret));
  1035.         again = true;
  1036.     }
  1037.     else
  1038.     {
  1039.         again = false;
  1040.     }
  1041.     }
  1042.     return ret;
  1043.   }
  1044.  
  1045.   /**
  1046.    * Prepare for reboot system
  1047.    */
  1048.   global define void SetReboot()``{
  1049.       if ( Stage::initial () )
  1050.       {
  1051.       Linuxrc::WriteYaSTInf($["Root" : "reboot", "RebootMsg" : "0"]);
  1052.       y2milestone ( "Make a hard reboot" );
  1053.       }
  1054.   }
  1055.  
  1056. }//EOF
  1057.