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

  1. /**
  2.  * File:    modules/SystemFilesCopy.ycp
  3.  * Package:    Installation
  4.  * Summary:    Functionality for copying files from another systems
  5.  * Authors:    Lukas Ocilka <locilka@suse.cz>
  6.  *
  7.  * $Id:$
  8.  *
  9.  * Functionality for copying files from any not-mounted systems
  10.  * to inst-sys and from inst-sys to just-installed system.
  11.  */
  12.  
  13. {
  14.  
  15.     textdomain "installation";
  16.     module "SystemFilesCopy";
  17.  
  18.     import "Directory";
  19.     import "FileUtils";
  20.     import "String";
  21.     import "Installation";
  22.  
  23.  
  24.  
  25.     // --> Variables
  26.     
  27.     /**
  28.      * @struct [
  29.      *     [ archive_name, copy_to ],
  30.      *     [ "/tmp/archive_001.tgz", "/etc" ],
  31.      * ]
  32.      */
  33.     list <list <string> > copy_files_to_installed_system = [];
  34.  
  35.     boolean already_initialized = false;
  36.     
  37.     string inst_sys_tmp_directory = nil;
  38.     
  39.     string tmp_mount_directory = nil;
  40.     
  41.     // max tries when creating a temporary mount-directory
  42.     integer counter_max = 10;
  43.     
  44.     integer tmp_archive_counter = 0;
  45.     
  46.  
  47.  
  48.     // --> Functions
  49.  
  50.     global define string CreateDirectoryIfMissing (string mnt_tmpdir);
  51.  
  52.     /**
  53.      * Checks whether the directory exists and creates it if it is missing
  54.      * If the path exists but it is not a directory, it tries to create another
  55.      * directory and returns its name. 'nil' is returned when everythig fails.
  56.      *
  57.      * @param string mnt_tmpdir
  58.      * #return string mnt_tmpdir (maybe changed)
  59.      */
  60.     global define string CreateDirectoryIfMissing (string create_directory) {
  61.     // path already exists
  62.     if (FileUtils::Exists(create_directory)) {
  63.         // exists as a directory
  64.         if (FileUtils::IsDirectory(create_directory)) {
  65.         y2milestone("Directory %1 already exists", create_directory);
  66.         return create_directory;
  67.         // exists but it's not a directory
  68.         } else {
  69.         y2warning("Path %1 is not a directory", create_directory);
  70.         string new_dir = nil;
  71.  
  72.         while (new_dir == nil && counter_max > 0) {
  73.             counter_max = counter_max - 1;
  74.             create_directory = create_directory + "x";
  75.             new_dir = CreateDirectoryIfMissing (create_directory);
  76.         }
  77.         
  78.         return new_dir;
  79.         }
  80.  
  81.     // path doesn't exist
  82.     } else {
  83.         SCR::Execute(.target.mkdir, create_directory);
  84.         // created successfully
  85.         if (FileUtils::Exists (create_directory)) {
  86.         y2milestone("Directory %1 created", create_directory);
  87.         return create_directory;
  88.         // cannot create
  89.         } else {
  90.         y2error("Cannot create path %1", create_directory);
  91.         return nil;
  92.         }
  93.     }
  94.     }
  95.     
  96.     /**
  97.      * Sets and creates a temporary directory for files to lay
  98.      * in inst-sys until they're copied to the installed system.
  99.      * Sets and creates a temporary directory that is used for
  100.      * mounting partitions when copying files from them.
  101.      */
  102.     boolean Initialize () {
  103.     if (already_initialized) return true;
  104.  
  105.     inst_sys_tmp_directory = CreateDirectoryIfMissing("/tmp/tmp_dir_for_SystemFilesCopy_files");
  106.     tmp_mount_directory    = CreateDirectoryIfMissing("/tmp/tmp_dir_for_SystemFilesCopy_mount");
  107.  
  108.     if (inst_sys_tmp_directory == nil || tmp_mount_directory == nil) {
  109.         y2error("Cannot create one of needed directories");
  110.         return false;
  111.     }
  112.  
  113.     // everything is fine
  114.     already_initialized = true;
  115.     return true;
  116.     }
  117.  
  118.     /**
  119.      * Mounts the partition and proceeds the copying files from that partition
  120.      * to the inst-sys.
  121.      *
  122.      * @struct partiton  == "/dev/sdb4"
  123.      * @struct filenames == [ "/etc/123", "/etc/456" ]
  124.      * @struct copy_to   == "/root/" (where to copy it to the installed system)
  125.      */
  126.     global boolean CopyFilesToTemp (string partition, list <string> filenames, string copy_to) {
  127.     if (! Initialize ()) {
  128.         y2error("Cannot initialize!");
  129.         return false;
  130.     }
  131.     
  132.     // creating full archive name (path)
  133.     tmp_archive_counter = tmp_archive_counter + 1;
  134.     string archive_name = sformat("%1/_inst_archive_%2.tgz", inst_sys_tmp_directory, tmp_archive_counter);
  135.  
  136.     y2milestone("Copying from '%1' files %2 to '%3'. Files will appear in '%4'",
  137.         partition, filenames, archive_name, copy_to
  138.     );
  139.  
  140.     y2milestone("Mounting %1 to %2", partition, tmp_mount_directory);
  141.     if (! (boolean) SCR::Execute(.target.mount, [partition, tmp_mount_directory], "-o ro")) {
  142.         y2error("Mounting failed!");
  143.         return false;
  144.     }
  145.  
  146.     boolean ret = true;
  147.     string archive_files = "";
  148.     foreach (string filename, filenames, {
  149.         // removing the leading slash
  150.         if (substring(filename, 0, 1) == "/") filename = substring(filename, 1);
  151.         archive_files = archive_files + " '" + String::Quote (filename) + "'";
  152.     });
  153.  
  154.     // archive files were already quoted
  155.     string command = sformat (
  156.         "cd '%1'; tar -zcvf '%2' %3",
  157.         tmp_mount_directory, String::Quote(archive_name), archive_files
  158.     );
  159.     map cmd_run = (map) SCR::Execute(.target.bash_output, command);
  160.     if ((integer) cmd_run["exit"]:nil != 0) {
  161.         y2error(
  162.         "Problem during archivation: %1, command >%2<",
  163.         cmd_run, command
  164.         );
  165.         ret = false;
  166.     } else {
  167.         y2milestone("Archived: %1", cmd_run);
  168.     }
  169.  
  170.     y2milestone("Umounting %1", partition);
  171.     if (! (boolean) SCR::Execute(.target.umount, tmp_mount_directory)) {
  172.         y2warning("Umounting failed!");
  173.     }
  174.     
  175.     // add a new entry into the list of archives
  176.     copy_files_to_installed_system = add (copy_files_to_installed_system, [archive_name, copy_to]);
  177.  
  178.     return ret;
  179.     }
  180.  
  181.     /**
  182.      * Proceeds the copying of all files in inst-sys (that were copied from
  183.      * another partition before) to the directory.
  184.      */
  185.     global boolean CopyFilesToSystem () {
  186.     if (! already_initialized) {
  187.         y2error("CopyFilesToTemp() needs to be called first...");
  188.         return false;
  189.     }
  190.     
  191.     boolean ret = true;
  192.  
  193.     // this should run before the SCR root is changed
  194.     foreach (list <string> archive_to_extract, copy_files_to_installed_system, {
  195.         string archive_name     = archive_to_extract[0]:nil;
  196.         string where_to_extract = archive_to_extract[1]:nil;
  197.  
  198.         if (archive_name == nil || where_to_extract == nil) {
  199.         y2error("Something is wrong with the archive: %1", archive_to_extract);
  200.         ret = false;
  201.         }
  202.  
  203.         where_to_extract = sformat("%1%2", Installation::destdir, where_to_extract);
  204.  
  205.         string command = sformat (
  206.         "mkdir -p '%1'; cd '%1'; tar --preserve -xvzf '%2'",
  207.         String::Quote (where_to_extract),
  208.         String::Quote (archive_name)
  209.         );
  210.  
  211.         map cmd_run = (map) SCR::Execute(.target.bash_output, command);
  212.         if ((integer) cmd_run["exit"]:nil != 0) {
  213.         y2error(
  214.             "Problem during extracting an archive: %1, command >%2<",
  215.             cmd_run, command
  216.         );
  217.         ret = false;
  218.         } else {
  219.         y2milestone("Extracted: %1 into %2", cmd_run, where_to_extract);
  220.         }
  221.     });
  222.  
  223.     return true;
  224.     }
  225.  
  226. /* EOF */
  227. }
  228.