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

  1. /**
  2.  * File:    OSRPkgVerify.ycp
  3.  * Module:    repair
  4.  * Summary:    Packages check
  5.  * Authors:    Johannes Buchhold <jbuch@suse.de>
  6.  *
  7.  * $Id: OSRPkgVerify.ycp 20504 2004-12-06 14:55:51Z jsuchome $
  8.  *
  9.  * Provide osr mode information.
  10.  */
  11.  
  12. {
  13.     module "OSRPkgVerify";
  14.  
  15.     textdomain "repair";
  16.  
  17.     import "Kernel";
  18.     import "OSRExecute";
  19.     import "OSRLogFile";
  20.     import "OSRMode";
  21.  
  22.     /**
  23.      * Missing key. For parsing rpm output.
  24.      */
  25.     global string missing         = "missing";
  26.  
  27.     /**
  28.      * Unsatisfied key. For parsing rpm output.
  29.      */
  30.     global string unsatisfied         = "Unsatisfied dependencies for";
  31.  
  32.     /**
  33.      * Rpm symbol for all tests.
  34.      */
  35.     string all_tests            = "SM5DLUGT";
  36.  
  37.     /**
  38.      * All allowed rpm test options.
  39.      */
  40.     string possible            = "5SLTDUGM?.";
  41.  
  42.     /**
  43.      * Key seperate packagename with not valid file count.
  44.      */
  45.     global string separator             = "____KEY____";
  46.  
  47.     map unimportant_file_problems = $[
  48.     "file_type" : $[
  49.         ".log"        : [ all_tests ],
  50.         ".html"        : [ all_tests, missing ],
  51.         ".png"        : [ all_tests ],
  52.         ".protocol"        : [ all_tests ]
  53.     ],
  54.     "directory" : $[
  55.         "/usr/share/doc"    : [ all_tests, missing ],
  56.         "/var/log"        : [ all_tests ],
  57.         "/var/cache"    : [ all_tests ],
  58.         "/usr/share/man"    : [ all_tests, missing ],
  59.         "/usr/X11R6/man"    : [ all_tests, missing ],
  60.         "/usr/share/man"    : [ all_tests, missing ],
  61.         "/usr/share/info"    : [ all_tests, missing ],
  62.         "/var/spool"    : [ all_tests ],
  63.         "/dev"        : [ "MUG..." ]
  64.     ],
  65.     "config_file" : $[
  66.         "all"        : [ "SM5....T" ]
  67.     ],
  68.     "you-installed" : $[
  69.         "/var/lib/YaST2/you/installed"    : [ all_tests ]
  70.     ],
  71.     "build_problems": $[
  72.         "all"        : []
  73.     ]
  74.     ];
  75.  
  76.     global map unimportant2help = $[
  77.     // helptext: why the error is not so important
  78.     "file_type"    : _("The file is a noncritical type."),
  79.     // helptext: why the error is not so important
  80.     "directory"    : _("The file is located in a noncritical directory."),
  81.     // helptext: why the error is not so important
  82.     "config_file"    : _("The file is a configuration file."),
  83.     "you-installed" :
  84.     // helptext: why the error is not so important
  85. _("The package has been updated with the online update."),
  86.     "build_problems":
  87.     // helptext: why the error is not so important
  88. _("The test failure seems to be caused by an incorrectly built package.")
  89.     ];
  90.  
  91.     /**
  92.      * index of all currently verified packages
  93.      */
  94.     map verified_packages            = $[];
  95.  
  96.     // number of packages verified so far
  97.     integer verified_counter            = 0;
  98.  
  99.     // data of package currently verified
  100.     global list<map> verify_data        = [];
  101.  
  102.     global list<string> not_successful_verified    = [];
  103.  
  104.     /**
  105.      * maximum of file entries shown in detailed pkg verification summary
  106.      * (necessary because of potential large memory requirements)
  107.      */
  108.     global integer max_files        = 10;
  109.  
  110.     // mount point to root fs
  111.     global string root_for_verification    = "";
  112.  
  113.     /**
  114.      * Verified packages after a new installation.
  115.      */
  116.     global map initial_verified_packages    = $[];
  117.  
  118.     map update_problems_map        = $[];
  119.  
  120.  
  121.     /**
  122.      *
  123.      */
  124.     global define void Reset()``{
  125.     verified_packages    = $[];
  126.     verify_data        = [];
  127.     verified_counter    = 0;
  128.     not_successful_verified = [];
  129.     }
  130.  
  131.     /**
  132.      * module constructor: read packages with build problems
  133.      */
  134.     global define void OSRPkgVerify()``{
  135.  
  136.     initial_verified_packages = (map)
  137.         WFM::CallFunction ("osr_verified_packages");
  138.     Reset();
  139.     }
  140.  
  141.     // has the package been verified?
  142.     global define boolean PackageVerified (string pkg_name) {
  143.  
  144.     return verified_packages[pkg_name]:false;
  145.     }
  146.  
  147.     // return number of packages verified so far
  148.     global define integer VerifiedSize () {
  149.  
  150.     return verified_counter;
  151.     }
  152.  
  153.     define void    build_update_problems_map()``{
  154.  
  155.     if( update_problems_map == $[] || update_problems_map == nil )
  156.     {
  157.         foreach (string dir, list<string> allowed_erros,
  158.           unimportant_file_problems["you-installed" ]:$[], ``{
  159.  
  160.         list<string> you_installed_pkgs =
  161.             (list<string>) SCR::Read (.target.dir, dir);
  162.  
  163.         if( you_installed_pkgs == nil || you_installed_pkgs == [] )
  164.         {
  165.             return;
  166.         }
  167.         foreach (string patch_file, you_installed_pkgs, ``{
  168.  
  169.             string file  = (string)
  170.             SCR::Read(.target.string , dir + "/" + patch_file);
  171.             list<string> lines = filter (string line,
  172.             splitstring (file, "\n"), ``(
  173.                 substring (line, 0,size("Filename:")) == "Filename:"
  174.             ));
  175.  
  176.             foreach (string line, lines, ``{
  177.             line = substring (line, size("Filename:"));
  178.             line = mergestring (splitstring (line, " "), "");
  179.             if (issubstring (line, ".rpm") ||
  180.                 issubstring (line, ".RPM"))
  181.             {
  182.                 line = substring (line,0,size(line) - size(".rpm"));
  183.             }
  184.             if( line != nil && line != "" )
  185.             {
  186.                 update_problems_map[ line ] = allowed_erros;
  187.             }
  188.             });
  189.         });
  190.         });
  191.         y2milestone(" update_problems packages %1", update_problems_map );
  192.     }
  193.     }
  194.  
  195.     define boolean check_allowed (list<string> allowed_erros, string status)``{
  196.  
  197.     boolean found = false;
  198.     foreach (string allowed, allowed_erros, ``{
  199.  
  200.         if ((allowed == missing && status == missing) ||
  201.         (allowed != missing &&
  202.         size (deletechars (status, allowed + "." )) == 0))
  203.         {
  204.         found = true;
  205.         return;
  206.         }
  207.     });
  208.     y2debug ("all allowed: %1; current status %2; found: %3",
  209.         allowed_erros, status, found);
  210.  
  211.     return found;
  212.     }
  213.  
  214.     /**
  215.      *
  216.      */
  217.     define string unimportant_file_type (string file, string status)``{
  218.  
  219.     boolean found = false;
  220.     foreach (string type, list<string> allowed_erros,
  221.       unimportant_file_problems["file_type"]:$[], ``{
  222.  
  223.         if (size (file) > size (type) &&
  224.         substring (file, size (file) - size (type)) == type)
  225.         {
  226.         if (check_allowed( allowed_erros, status ))
  227.         {
  228.             found = true;
  229.             return;
  230.         }
  231.         }
  232.     });
  233.     return ( found ) ? "file_type" : "";
  234.     }
  235.  
  236.     /*
  237.      *
  238.      */
  239.     define string unimportant_directory( string file, string status )``{
  240.  
  241.     boolean found = false;
  242.     foreach (string dir, list<string> allowed_erros,
  243.       unimportant_file_problems["directory"]:$[] , ``{
  244.  
  245.         if (substring( file, 0, size(dir)) == dir)
  246.         {
  247.         if ( check_allowed( allowed_erros, status ))
  248.         {
  249.             found = true;
  250.             return;
  251.         }
  252.         }
  253.     });
  254.     return ( found ) ? "directory" : "";
  255.     }
  256.  
  257.     /**
  258.      *
  259.      */
  260.     define string config_file_allowed( map pkg_data ) ``{
  261.  
  262.     if (!pkg_data["config_file"]:false)
  263.         return "";
  264.  
  265.     return check_allowed (
  266.         unimportant_file_problems ["config_file","all"]:[],
  267.         pkg_data ["status"]:"")
  268.     ? "config_file" : "";
  269.     }
  270.  
  271.     /**
  272.      *
  273.      */
  274.     define string update_problems (string pkg_name, string file, string status)``{
  275.     boolean found = false;
  276.  
  277.     map you_installed = filter (string you_installed_pkg,
  278.       list<string> allowed_erros, (map<string,list<string> >)update_problems_map,
  279.         ``(substring (you_installed_pkg,0, size( pkg_name)) == pkg_name));
  280.  
  281.     foreach (string you_installed_pkg, list<string> allowed_erros,
  282.       (map<string,list<string> >) you_installed, ``{
  283.  
  284.         if( check_allowed( allowed_erros, status ))
  285.         {
  286.         found = true;
  287.         return;
  288.         }
  289.     });
  290.     return ( found ) ? "you-installed" : "";
  291.     }
  292.  
  293.     /**
  294.      *
  295.      */
  296.     define string build_problems( string pkg_name, map pkg_data )``{
  297.  
  298.     map org_data = initial_verified_packages[pkg_name]:$[];
  299.     if (size (filter(string key, map d, (map<string,map<any,any> >)org_data,``( d == pkg_data ))) > 0)
  300.     {
  301.         return "build_problems";
  302.     }
  303.     return "";
  304.     }
  305.  
  306.  
  307.     /**
  308.      * Return if a package was not build correctly.
  309.      */
  310.     global define string GreenPackageProblems(string pkg_name, map pkg_data )``{
  311.  
  312.     if (haskey (pkg_data , "green_status" ))
  313.         return pkg_data["green_status"]:"";
  314.  
  315.     string green_status =  "";
  316.  
  317.     // set config files to green status
  318.     if ( green_status == "" )
  319.         green_status = config_file_allowed( pkg_data  );
  320.  
  321.     if ( green_status == "" )
  322.         green_status = update_problems (
  323.         pkg_name, pkg_data["file"]:"", pkg_data["status"]:"" );
  324.  
  325.     if ( green_status == "" )
  326.         green_status = unimportant_file_type (
  327.         pkg_data["file"]:"" , pkg_data["status"]:"" );
  328.  
  329.     if ( green_status == "" )
  330.         green_status = unimportant_directory (
  331.         pkg_data["file"]:"" , pkg_data["status"]:"" );
  332.  
  333.     if ( green_status == "" )
  334.         green_status = build_problems( pkg_name,  pkg_data );
  335.  
  336.     if ( green_status != "" )
  337.     {
  338.         y2milestone("Found green package problems. Name of package: %1 Type: %2 File: %3 ",
  339.         pkg_name, green_status , pkg_data["file"]:"");
  340.     }
  341.  
  342.     return green_status;
  343.     }
  344.  
  345.     /**
  346.      * Convert rpm output to a map.
  347.      * @param pkg_name The package name e.g.: filesystem
  348.      * @param verify_output_string The rpm output: .....UG.   /etc/cups
  349.      *                                             .M......   /proc
  350.      *
  351.      * @return  e.g.: $["filesystem____KEY____1":
  352.      *                                      $["config_file":false,
  353.      *                          "file":"/etc/cups",
  354.      *                          "status":".....UG."
  355.      *                          ],
  356.      *                  "filesystem____KEY____2"   :$["config_file":false, "
  357.      *                                       file":"/proc",
  358.      *                           "status":".M......"]]
  359.      *
  360.      *
  361.      */
  362. //    define boolean convert_verify_output ( string pkg_name, string verify_output_string)
  363.     global define map convert_verify_output (
  364.     string pkg_name, string verify_output_string, boolean full_list)
  365.     {
  366.  
  367.     list pkg_data            = [];
  368.     integer build_problem_counter   = 0;
  369.     integer verify_output_counter   = 0;
  370.     list<string> verify_output_list =
  371.         splitstring (verify_output_string , "\n");
  372.  
  373.     foreach (string verify_output, verify_output_list, {
  374.  
  375.         if (size (verify_output) > 1)
  376.         {
  377.         verify_output_counter = verify_output_counter  +1 ;
  378.         string pkg_key =
  379.             sformat("%1%2%3",pkg_name, separator,verify_output_counter);
  380.         map file_data    = $[];
  381.         if (substring (verify_output, 0, size(missing) )  == missing )
  382.         {
  383.             file_data = $[
  384.             "config_file"    : issubstring (
  385.                 substring (verify_output, size (missing),
  386.                 findfirstof(verify_output, "/")- size(missing)),
  387.                 "c"),
  388.             "file"        : substring (
  389.                 verify_output, findfirstof(verify_output, "/")),
  390.             "status"    : missing
  391.             ];
  392.         }
  393.         else if (substring(verify_output, 0, size(unsatisfied ))
  394.              == unsatisfied )
  395.         {
  396.             file_data = $[
  397.             "config_file"    : false,
  398.             "file"    : substring(verify_output, size(unsatisfied)),
  399.             "status"    : unsatisfied
  400.             ];
  401.         }
  402.         else if (findfirstnotof(substring(verify_output,0,8), possible)
  403.              == nil )
  404.         {
  405.             file_data = $[
  406.             "config_file"    : issubstring (
  407.                 substring (verify_output, 8,
  408.                     findfirstof(verify_output, "/") - 8 ),
  409.                 "c" ),
  410.             "file"        : substring (verify_output,
  411.                 findfirstof (verify_output, "/")),
  412.             "status"    : substring (verify_output, 0,8)
  413.             ];
  414.         }
  415.         else
  416.         {
  417.             y2error ("unknown output");
  418.             file_data    =  $[ "status" : "unknown" ];
  419.         }
  420.  
  421.         file_data ["green_status"] =
  422.             GreenPackageProblems (pkg_name, file_data);
  423.  
  424.         if (file_data["green_status"]:"" != "")
  425.         {
  426.             build_problem_counter = build_problem_counter +1;
  427.         }
  428.  
  429.         if (full_list || verify_output_counter <= max_files)
  430.         {
  431.             pkg_data = add (pkg_data, file_data);
  432.         }
  433.         else if (verify_output_counter == max_files + 1)
  434.         {
  435.             pkg_data = add (pkg_data, $["more": true]);
  436.         }
  437.         }
  438.     });
  439.  
  440.  
  441.     return $[
  442.         // false if the package was not verified successfully.
  443.         "ok"        :
  444.         (build_problem_counter == verify_output_counter ||
  445.         (build_problem_counter == 0 && size(verify_output_string)<= 1)),
  446.         "verify_data"    : pkg_data
  447.     ];
  448.     }
  449.  
  450.     /**
  451.      *
  452.      */
  453.     global define boolean Verify (string p, string root_mountpoint) ``{
  454.  
  455.     root_for_verification    = root_mountpoint;
  456.     build_update_problems_map();
  457.  
  458.     y2milestone("-----------verifying package %1", p );
  459.  
  460.     OSRExecute::CommandOutput (.local.bash,
  461.         sformat("LANG=ENG /bin/rpm --root %2 -V %1", p, root_mountpoint));
  462.  
  463.     y2milestone("-----------package %1 verified", p);
  464.  
  465.     map converted    = convert_verify_output (p, OSRExecute::stdout, false);
  466.     boolean ok    = converted["ok"]:false;
  467.     verify_data    = converted["verify_data"]:[];
  468.  
  469.     verified_packages [p]    = true;
  470.     verified_counter    = verified_counter + 1;
  471.  
  472.     if (!ok)
  473.         not_successful_verified = add (not_successful_verified, p);
  474.     return ok;
  475.     }
  476.  
  477.  
  478.  
  479.     /**
  480.      * Debug the verified packages informations.
  481.      */
  482.     global define boolean WriteVerifiedPackages( list installed, boolean debug )``{
  483.     string ypath  = OSRLogFile::GetTmpDir()+ "/initial_verified_packages";
  484.     string spath  = OSRLogFile::GetTmpDir()+ "/initial_verified_packages_text";
  485.  
  486.     if ( OSRMode::save )
  487.     {
  488.         y2milestone("Try to save data of all verified packages");
  489.         // not ok packages
  490.         map t_verified_packages = filter(string pkg_name, map data,
  491.         (map<string,map<any,any> >)verified_packages, ``( data != $[] ));
  492.  
  493.         // write as text file!!
  494.         foreach (string pkg_name, map<string,map<string,any> > pkg_data, (map<string, map<string,map<string,any> > >) t_verified_packages, ``{
  495.  
  496.         WFM::Execute(.local.bash,
  497.             sformat("/bin/echo %1 >> %2", pkg_name, spath));
  498.         foreach (string key, map file_data,  pkg_data, ``{
  499.  
  500.             WFM::Execute (.local.bash,
  501.             sformat("/bin/echo \"  %1  %2  %3\" >> %4",
  502.                 file_data["status"]:"",
  503.                 ( file_data["config_file"]:false) ? "c" : " ",
  504.                 file_data["file"]:"" , spath ));
  505.         });
  506.         });
  507.         // write as ycp-file
  508.         return WFM::Write(.local.ycp, ypath, t_verified_packages);
  509.     }
  510.  
  511.     if (debug)
  512.         return WFM::Write(.local.ycp , ypath , verified_packages);
  513.  
  514.     return true;
  515.     }
  516. }//EOF
  517.