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 / clients / inst_pre_install.ycp < prev    next >
Text File  |  2006-11-29  |  7KB  |  223 lines

  1. {
  2.     import "Storage";
  3.     import "FileUtils";
  4.     import "Directory";
  5.     import "SystemFilesCopy";
  6.  
  7.     // --> Functions
  8.  
  9.     define void Initialize ();
  10.     
  11.     define map <string, map <string, integer> > FindTheBestFiles (map <string, map <string, integer> > files_found);
  12.     
  13.     define void FindAndCopyNewestFiles (string copy_to, list <string> wanted_files);
  14.  
  15.     // --> Variables
  16.  
  17.     // all partitions that can be used as a 
  18.     list <map <string, any> > useful_partitions = [];
  19.  
  20.     list <symbol> possible_root_fs = [ `ext2, `ext3, `reiser, `xfs, `jfs ];
  21.  
  22.     /* ******************************************************************************* */
  23.     // --> main()
  24.  
  25.     Initialize();
  26.  
  27.     // FATE #300421: Import ssh keys from previous installations
  28.     FindAndCopyNewestFiles("/", ["/etc/ssh/ssh_host_key", "/etc/ssh/ssh_host_key.pub"]);
  29.     
  30.     // FATE #120103: Import Users From Existing Partition
  31.     FindAndCopyNewestFiles(
  32.     sformat ("%1/imported/userdata", Directory::vardir),
  33.     ["/etc/shadow", "/etc/passwd", "/etc/login.defs", "/etc/group"]
  34.     );
  35.  
  36.     // free the memory
  37.     useful_partitions = nil;
  38.     
  39.     // at least some return
  40.     return `a_glass_of_milk_please;
  41.  
  42.     // <-- main()
  43.     /* ******************************************************************************* */
  44.  
  45.     // --> Functions
  46.  
  47.     /**
  48.      * Finds the newest files in the map
  49.      *
  50.      * @struct [
  51.      *     "/dev/hda3" : $[
  52.      *         "/etc/xyz" : 8445577887,
  53.      *         "/etc/xzz" : 8445577888,
  54.      *     ]
  55.      * ]
  56.      */
  57.     define map <string, map <string, integer> > FindTheBestFiles (map <string, map <string, integer> > files_found) {
  58.     map <string, map <string, integer> > ret = $[];
  59.     integer max = 0;
  60.     
  61.     // going through all partitions
  62.     foreach (string partition_name, map <string, integer> files_on_it, files_found, {
  63.         integer counter = 0;
  64.         integer filetimes = 0;
  65.         foreach (string filename, integer filetime, files_on_it, {
  66.         filetimes = filetimes + filetime;
  67.         counter = counter + 1;
  68.         });
  69.  
  70.         // if there were some files on in
  71.         if (counter > 0) {
  72.         // average filetime (if more files were there)
  73.         filetimes = filetimes / counter;
  74.         
  75.         // the current time is bigger (newer file) then the maximum found
  76.         if (filetimes > max) {
  77.             max = filetimes;
  78.             ret = $[];
  79.             ret[partition_name] = files_on_it;
  80.         }
  81.         }
  82.     });
  83.     
  84.     return ret;
  85.     }
  86.  
  87.     define void FindAndCopyNewestFiles (string copy_to, list <string> wanted_files) {
  88.     y2milestone("Searching for files: %1", wanted_files);
  89.     string mnt_tmpdir = Directory::tmpdir + "/tmp_mnt_for_check";
  90.  
  91.     mnt_tmpdir = SystemFilesCopy::CreateDirectoryIfMissing (mnt_tmpdir);
  92.  
  93.     // CreateDirectory failed
  94.     if (mnt_tmpdir == nil) {
  95.         return nil;
  96.     }
  97.  
  98.     map <string, map <string, integer> > files_found_on_partitions = $[];
  99.  
  100.     foreach (map <string, any> partition, useful_partitions, {
  101.         string partition_device = (string) partition["device"]:"";
  102.         y2milestone("Mounting %1 to %2", partition_device, mnt_tmpdir);
  103.  
  104.         // mounting read-only
  105.         if (! (boolean) SCR::Execute(.target.mount, [partition_device, mnt_tmpdir], "-o ro")) {
  106.         y2error("Mounting falied!");
  107.         return;
  108.         }
  109.  
  110.         boolean files_found = true;
  111.         map <string, integer> one_partition_files_found = $[];
  112.  
  113.         foreach (string wanted_file, wanted_files, {
  114.         string filename_to_seek = mnt_tmpdir + wanted_file;
  115.  
  116.         if (! FileUtils::Exists (filename_to_seek)) {
  117.             files_found = false;
  118.             return;
  119.         }
  120.         if (FileUtils::IsLink (filename_to_seek)) {
  121.             files_found = false;
  122.             return;
  123.         }
  124.         map file_attribs = (map) SCR::Read (.target.lstat, filename_to_seek);
  125.         if (file_attribs == nil || file_attribs == $[]) {
  126.             files_found = false;
  127.             return;
  128.         }
  129.         // checking for the acces-time
  130.         integer file_time = (integer) file_attribs["atime"]:nil;
  131.         if (file_time == nil || file_time == 0) {
  132.             files_found = false;
  133.             return;
  134.         }
  135.         // doesn't make sense to copy files with zero size
  136.         integer file_size = (integer) file_attribs["atime"]:nil;
  137.         if (file_size == nil || file_size == 0) {
  138.             files_found = false;
  139.             return;
  140.         }
  141.         
  142.         one_partition_files_found[wanted_file] = file_time;
  143.         });
  144.         
  145.         if (files_found) {
  146.         files_found_on_partitions[partition_device] = one_partition_files_found;
  147.         }
  148.  
  149.         // umounting
  150.         y2milestone("Umounting %1", partition_device);
  151.         if (! (boolean) SCR::Execute(.target.umount, mnt_tmpdir)) {
  152.         y2error("Umount failed!");
  153.         }
  154.     });
  155.  
  156.     y2milestone("Files found: %1", files_found_on_partitions);
  157.  
  158.     map <string, map <string, integer> > ic_winner = $[];
  159.  
  160.     // nothing found
  161.     if (size(files_found_on_partitions) == 0) {
  162.         y2milestone("No such files found");
  163.     // only one (easy)
  164.     } else if (size(files_found_on_partitions) == 1) {
  165.         ic_winner = files_found_on_partitions;
  166.     // more than one (getting the best ones)
  167.     } else {
  168.         ic_winner = FindTheBestFiles (files_found_on_partitions);
  169.     }
  170.     files_found_on_partitions = nil;
  171.     
  172.     y2milestone("Selected files: %1", ic_winner);
  173.     
  174.     // should be only one entry
  175.     foreach (string partition, map <string, integer> files, ic_winner, {
  176.         SystemFilesCopy::CopyFilesToTemp (
  177.         partition,
  178.         maplist (string filename, integer filetime, files, { return filename; }),
  179.         copy_to
  180.         );
  181.     });
  182.     }
  183.     
  184.     /**
  185.      * Goes through disks and searches for usable partitions.
  186.      * Sets them to the 'useful_partitions' variable
  187.      */
  188.     define void Initialize () {
  189.     y2milestone("Evaluating all current partitions");
  190.     map <string, map> target_map = (map <string, map>) Storage::GetTargetMap();
  191.     integer counter = -1;
  192.     foreach (string device_name, map device_descr, target_map, {
  193.         list <map <string, any> > partitons = (list <map <string, any> >) device_descr["partitions"]:[];
  194.         symbol filesystem = nil;
  195.         string devicename = nil;
  196.  
  197.         foreach (map <string, any> partition, partitons, {
  198.         filesystem = (symbol) partition["used_fs"]:partition["detected_fs"]:nil;
  199.         devicename = (string) partition["device"]:nil;
  200.  
  201.         if (filesystem == nil) {
  202.             y2milestone("Skipping partition %1, no FS detected", devicename);
  203.             return;
  204.         }
  205.  
  206.         if (! contains(possible_root_fs, filesystem)) {
  207.             y2milestone("Skipping partition %1, %2 is not a root filesystem", devicename, filesystem);
  208.             return;
  209.         }
  210.  
  211.         // adding the partition into the list of possible ones
  212.         counter = counter + 1;
  213.         useful_partitions[counter] = $[
  214.             "device" : partition["device"]:nil,
  215.             "fs"     : filesystem,
  216.         ];
  217.         });
  218.     });
  219.  
  220.     y2milestone("Possible partitons: %1", useful_partitions);
  221.     }
  222. }
  223.