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 / include / partitioning / lvm_ui_dialogs.ycp < prev    next >
Text File  |  2006-11-29  |  15KB  |  597 lines

  1. /**
  2.  * File:
  3.  *   lvm_ui_dialogs.ycp
  4.  *
  5.  * Module: 
  6.  *    configuration of lvm: lib for the user interface
  7.  *    - contains only dialogs    
  8.  *
  9.  * Summary:
  10.  *
  11.  * Authors:
  12.  *   mike <mike@suse.de>
  13.  *
  14.  *
  15.  * $Id: lvm_ui_dialogs.ycp 32189 2006-08-07 11:21:35Z fehr $
  16.  *
  17.  */
  18.  
  19.  
  20. {
  21.  
  22. textdomain "storage";
  23.  
  24. import "Mode";
  25. import "Partitions";
  26. import "FileSystems";
  27. import "Storage";
  28.  
  29. import "Label";
  30. import "Popup";
  31.  
  32. include "partitioning/custom_part_dialogs.ycp";
  33. include "partitioning/custom_part_lib.ycp";
  34. include "partitioning/lvm_lv_lib.ycp";
  35. include "partitioning/lvm_ui_lib.ycp";
  36.  
  37. define void handle_max( integer stripe, string max_text )
  38.     ``{
  39.     y2milestone( "stripe %1", stripe );
  40.     UI::ChangeWidget(`id("max_size"), `Enabled, stripe==1 );
  41.     UI::ChangeWidget(`id("max_text"), `Value, stripe==1?max_text:"" );
  42.     }
  43.     
  44. define map DlgCreateEditLogicaVolume( symbol create_or_edit, map<string,any> Lv,
  45.                       integer max_size, string vgname,
  46.                       list lvs, map<symbol,map> file_systems,
  47.                       string dev, integer pesize )
  48.  
  49.     ``{
  50.     y2milestone( "DlgCreateEditLogicaVolume %4 dev=%1 pesize=%2 max_size=%3", 
  51.                  dev, pesize, max_size, create_or_edit );
  52.     y2milestone( "DlgCreateEditLogicaVolume lvs %1", lvs );
  53.  
  54.     integer new_size     = Lv["size_k"]:0 * 1024;
  55.     integer old_size     = new_size;
  56.     string  curr_size    = ByteToHumanStringWithZero(new_size);
  57.     old_size = kmgt_str_to_byte(curr_size);
  58.     string  volume_name  = Lv["name"]:"";
  59.     integer stripes      = Lv["stripes"]:1;
  60.     integer stripesize   = Lv["stripesize"]:64;
  61.  
  62.     list stripes_poss = [
  63.               `item(`id(1), "1",  stripes == 1 ),
  64.               `item(`id(2), "2",  stripes == 2 ),
  65.               `item(`id(3), "3",  stripes == 3 ),
  66.               `item(`id(4), "4",  stripes == 4 ),
  67.               `item(`id(5), "5",  stripes == 5 ),
  68.               `item(`id(6), "6",  stripes == 6 ),
  69.               `item(`id(7), "7",  stripes == 7 ),
  70.               `item(`id(8), "8",  stripes == 8 )
  71.             ];
  72.  
  73.     list stripe_size = [
  74.               `item(`id(4),   "4",    stripesize == 4 ),
  75.               `item(`id(8),   "8",    stripesize == 8 ),
  76.               `item(`id(16),  "16",   stripesize == 16 ),
  77.               `item(`id(32),  "32",   stripesize == 32 ),
  78.               `item(`id(64),  "64",   stripesize == 64 ),
  79.               `item(`id(128), "128",  stripesize == 128 ),
  80.               `item(`id(256), "256",  stripesize == 256 ),
  81.               `item(`id(512), "512",  stripesize == 512 ),
  82.                        ];
  83.     
  84.     string lv_size      = "";   
  85.      
  86.     string  heading        = "";
  87.     boolean is_create_mode = false;
  88.     boolean is_resize_mode = false;
  89.     term    ui_volume_name = `Dummy();
  90.     any     c_ret          = `cancel;
  91.      
  92.     // header for input field size of Logical volume 
  93.     string size_txt = sformat(_("&Size: (e.g., %1 %2)"), 
  94.                   ByteToHumanStringWithZero(4196*1024*1024),
  95.                   ByteToHumanStringWithZero(210*1024*1024));
  96.     if( create_or_edit != `create )
  97.     {
  98.     max_size = max_size+new_size;
  99.     y2milestone( "new max_size=%1", max_size );
  100.     }
  101.     y2milestone( "new_size %1", new_size );
  102.     // header for input field maximum allowd size
  103.     string max_text = sformat(_("max = %1 "), 
  104.                   ByteToHumanStringWithZero(max_size));
  105.  
  106.  
  107.     if( create_or_edit == `create )
  108.         {
  109.     // popup heading 
  110.     heading        = _("Create Logical Volume");
  111.     is_create_mode = true; 
  112.     ui_volume_name = `VBox( `TextEntry(`id("volume_name"),
  113.                        // label text
  114.                        _("Logical volume &name "),
  115.                        volume_name),
  116.                  // label text
  117.                 `Left(`Label(_("(e.g. var, opt)")))
  118.                   );
  119.     }
  120.     else if( create_or_edit == `edit )
  121.         {
  122.     // popup heading 
  123.     heading = _("Edit Logical Volume");
  124.     is_create_mode = false;
  125.                // display name of current volume group
  126.     // display name of current volume group
  127.     ui_volume_name = `VBox( `Label(""),
  128.                 // label text
  129.                 `HBox(`Label( _("Logical volume name: ")),
  130.                       `Heading(`opt(`outputField), volume_name ),
  131.                       `HStretch()
  132.                      ));
  133.     }
  134.     else if( create_or_edit == `resize )
  135.     {
  136.     // popup heading 
  137.     heading = _("Edit Logical Volume");
  138.     is_create_mode = false;
  139.     is_resize_mode = true;
  140.     // display name of current volume group
  141.     ui_volume_name = `VBox( `Label(""),
  142.                 // label text
  143.                 `HBox(`Label( _("Logical volume name: ")),
  144.                       `Heading(`opt(`outputField), volume_name ),
  145.                       `HStretch()
  146.                      )
  147.                   );
  148.     }
  149.     else
  150.     {
  151.     // internal error message 
  152.     heading = _("INTERNAL ERROR");
  153.     }
  154.  
  155.     y2milestone( "is_create_mode %1 is_resize_mode %2", is_create_mode,
  156.                  is_resize_mode );
  157.  
  158.     UI::OpenDialog(
  159.     `opt(`decorated ),
  160.     `HBox(`HWeight(30, 
  161.               `HBox(
  162.                 `HSpacing(1),
  163.                 `HStretch(),
  164.             `VBox(
  165.                   `Heading(heading),
  166.                   `VStretch(),
  167.                   `VSpacing(1),
  168.                   `HBox(
  169.                     FormatDlg( Lv, file_systems ),
  170.                     `HStretch(),
  171.                     `HSpacing(2),
  172.                     `VBox(
  173.                       `Top(`Left(ui_volume_name)),
  174.                       `Top(`VBox( `TextEntry(`id("size"), size_txt, curr_size),
  175.                               `HBox(
  176.                                 // set size to maxsize
  177.                                 `Left(`Label( `id("max_text"), max_text )),
  178.                                 // button text
  179.                                 `PushButton( `id("max_size"), _("ma&x")))
  180.                               
  181.                           )),
  182.                       `VStretch(),
  183.                       `Left(`ComboBox( `id("stripes"), `opt(`hstretch,`notify),
  184.                                // button text
  185.                                _("Stri&pes"), stripes_poss )),
  186.                       `VStretch(),
  187.                       `Left(`ComboBox( `id("stripesize"), `opt(`hstretch,`notify),
  188.                                // button text
  189.                                _("Stripe &Size"), stripe_size )),
  190.                       `VStretch(),
  191.                       `VSpacing(1),
  192.                       `ReplacePoint( `id(`mount_dlg_rp), 
  193.                                      MountDlg(Lv, []))
  194.                       )
  195.                     ),
  196.                   `VStretch(),  
  197.                   `VSpacing(1),
  198.                   `HBox(
  199.                     // Ok button
  200.                     `PushButton(`id(`ok), `opt(`default), Label::OKButton()  ),
  201.                     // Cancel button
  202.                     `PushButton(`id(`cancel), Label::CancelButton() )
  203.                    )
  204.                   ),
  205.             `HStretch(),
  206.             `HSpacing(1)
  207.             )
  208.            )));
  209.  
  210.  
  211.     // configure main dialog for the first call
  212.  
  213.     if( is_create_mode )
  214.     {
  215.     UI::ChangeWidget( `id("volume_name"), `ValidChars, 
  216.               FileSystems::nchars + "-._:" );
  217.     }
  218.     UI::ChangeWidget( `id("stripes"), `Enabled, !is_resize_mode );
  219.     UI::ChangeWidget( `id("stripesize"), `Enabled, 
  220.               !is_resize_mode && stripes>1 );
  221.     handle_max( stripes, max_text );
  222.   
  223.     ////////////////////////////////////////////////////////////////////
  224.     // User mainloop for dialog
  225.     ////////////////////////////////////////////////////////////////////
  226.       
  227.     boolean input_is_ok = true;
  228.     map<string,any> retval = eval(Lv);
  229.  
  230.     retval = HandlePartWidgetChanges( true, `ok, file_systems, Lv, retval );
  231.  
  232.     repeat
  233.     {
  234.     input_is_ok  = true;
  235.       
  236.     c_ret = UI::UserInput();
  237.  
  238.     /////////////////////////////////////////////////////////
  239.     if( c_ret == "stripes")
  240.         {
  241.         stripes = (integer)UI::QueryWidget(`id("stripes"), `Value);
  242.         UI::ChangeWidget( `id("stripesize"), `Enabled, 
  243.                   !is_resize_mode && stripes>1 );
  244.         handle_max( stripes, max_text );
  245.         c_ret = `again;
  246.         continue;
  247.         }
  248.  
  249.     /////////////////////////////////////////////////////////
  250.     // stripes
  251.     if( c_ret == "max_size")
  252.         {
  253.         UI::ChangeWidget(`id("size"), `Value, ByteToHumanStringWithZero(max_size));
  254.         c_ret = `again;
  255.         continue;
  256.         }
  257.  
  258.     if( c_ret != `cancel )
  259.         {
  260.         retval = HandlePartWidgetChanges( false, c_ret, file_systems,
  261.                           Lv, retval );
  262.         }
  263.       
  264.     if( is_create_mode ) 
  265.         {
  266.         volume_name = (string)UI::QueryWidget( `id("volume_name"), 
  267.                            `Value );
  268.         volume_name = deletechars( volume_name, " \t" );
  269.         }
  270.  
  271.     stripes = (integer)UI::QueryWidget(`id("stripes"), `Value);
  272.     stripesize = (integer)UI::QueryWidget(`id("stripesize"), `Value);
  273.     lv_size = (string)UI::QueryWidget(`id("size"), `Value);
  274.      
  275.     y2debug("STRI ---- i%1i", stripes);
  276.     if( c_ret==`ok )
  277.         {
  278.         new_size = kmgt_str_to_byte(lv_size);
  279.         
  280.         if( !check_max_size(new_size, max_size) )
  281.         {
  282.         input_is_ok = false;
  283.         c_ret = `again;
  284.         continue;
  285.         }
  286.         y2milestone( "new_size %1 old_size %2", new_size, old_size );
  287.  
  288.         if( !check_ok_fssize(new_size, retval) )
  289.         {
  290.         input_is_ok = false;
  291.         c_ret = `again;
  292.         continue;
  293.         }
  294.  
  295.         if( is_resize_mode && !retval["format"]:false && 
  296.         new_size!=old_size )
  297.         {
  298.         string mp = retval["inactive"]:false ? "" : retval["mount"]:"";
  299.         if( !CheckResizePossible( true, true, new_size-old_size,
  300.                       retval["used_fs"]:`unknown, mp ))
  301.             {
  302.             UI::ChangeWidget(`id("size"), `Value, curr_size );
  303.             c_ret = `again;
  304.             continue;
  305.             }
  306.         }
  307.  
  308.         if( is_create_mode )
  309.         {
  310.         if( !icheck_volume_name(volume_name) )
  311.             {
  312.             input_is_ok = false;
  313.             // error popup text
  314.             // xgettext:no-c-format
  315.             Popup::Error(_("Check your volume name. 
  316. Use names like \"opt\" or \"var\" ...
  317. Do not use ;/\`',!\"%#"));
  318.             UI::SetFocus(`id("volume_name"));
  319.             c_ret = `again;
  320.             continue;
  321.             }
  322.         else 
  323.             {
  324.             if( contains( lvs, volume_name ) )
  325.             {
  326.             input_is_ok = false;
  327.             // error popup text
  328.             Popup::Error(sformat(_("A logical volume named \"%1\" already exists
  329. in volume group \"%2\". Choose another name
  330. or cancel this dialog.
  331. "), volume_name, vgname ));
  332.             UI::SetFocus(`id("volume_name"));
  333.             c_ret = `again;
  334.             continue;
  335.             }
  336.             }   
  337.         }
  338.  
  339.         map ret_mp = CheckOkMount( dev, Lv, retval );
  340.         retval = ret_mp["map"]:$[];
  341.         if( !ret_mp["ok"]:false )
  342.         {
  343.         if( ret_mp["field"]:`none != `none )
  344.             UI::SetFocus(`id( ret_mp["field"]:`none ));
  345.         input_is_ok = false;
  346.         c_ret = `again;
  347.         continue;
  348.         }
  349.  
  350.         retval["device"] = "/dev/"+vgname+"/"+volume_name;
  351.         ret_mp = CheckDeviceFinalOk( retval );
  352.         if( !ret_mp["ok"]:false )
  353.         input_is_ok = false;
  354.         else
  355.         retval = ret_mp["map"]:$[];
  356.         }
  357.  
  358.     /////////////////////////////////////////////////////////
  359.     retval["stripes"] = stripes;
  360.     if( stripes>1 )
  361.         {
  362.         retval["stripesize"] = stripesize;
  363.         }
  364.     retval["name"] = volume_name;
  365.     if( new_size!=old_size )
  366.         {
  367.         retval["size_k"] = (new_size+1023)/1024;
  368.         }
  369.     } until ( (c_ret==`ok&&input_is_ok) || c_ret == `cancel );
  370.  
  371.     UI::CloseDialog();
  372.       
  373.     y2milestone( "retval=%1", retval );
  374.       
  375.     if( c_ret != `cancel && input_is_ok )
  376.     {
  377.     return( retval );
  378.     }
  379.     else
  380.     {
  381.     return( nil );
  382.     }
  383.     };
  384.     
  385.  
  386.  
  387.  //////////////////////////////////////////////////////////////////////////////
  388.  // Dialog "Create a Volume Group
  389.  //////////////////////////////////////////////////////////////////////////////
  390.      
  391. define boolean HandleEditLv( map<string,map> targetMap, string device )
  392.     ``{
  393.     boolean ret = false;
  394.     map disk = Storage::GetDisk( targetMap, device );
  395.     integer pesize = disk["cyl_size"]:(4*1024*1024);
  396.  
  397.     map<symbol,map> fs = FileSystems::GetAllFileSystems(true, true);
  398.     map<string,any> Lv = Storage::GetPartition( targetMap, device );
  399.  
  400.     // if Lv is a lvm partition
  401.     if( size(Lv)>0 && Lv["type"]:`primary==`lvm )
  402.     {
  403.     string tmp_vg = disk["name"]:"";
  404.     list size_list = get_lv_size_info( targetMap, tmp_vg );
  405.     integer max_size    = size_list[1]:0;
  406.     symbol what = (Lv["create"]:false)?`edit:`resize;
  407.     map createLv = DlgCreateEditLogicaVolume( what, Lv, max_size, tmp_vg,
  408.                                               [], fs, device, pesize );
  409.     // has an error occured
  410.     if( size(createLv)>0 )
  411.         {
  412.         ret = editLogicalVolume( createLv, tmp_vg );
  413.         }
  414.     }
  415.     else
  416.     {
  417.     // Popup text
  418.     Popup::Error(_("You can only edit logical volumes."));
  419.     }
  420.     y2milestone( "ret %1", ret );
  421.     return( ret );
  422.     }
  423.  
  424. define boolean HandleRemoveLv( map<string,map> targetMap, string id )
  425.     ``{
  426.     boolean ret = false;
  427.     map disk = Storage::GetDisk( targetMap, id );
  428.     map Lv = Storage::GetPartition( targetMap, id );
  429.     if( size(Lv)==0 || Lv==nil || Lv["type"]:`primary!=`lvm )
  430.     {
  431.     // Popup text
  432.     Popup::Error(_("You can only remove logical volumes."));
  433.     }
  434.     else
  435.     {
  436.     // Popup text
  437.     string message = sformat( _("Remove the logical volume %1?"), id );
  438.  
  439.     if( Popup::YesNo( message ))
  440.         {
  441.         ret = removeLogicalVolume( disk["device"]:"", id );
  442.         }
  443.     }
  444.     y2milestone( "HandleRemoveLv ret:%1", ret );
  445.     return( ret );
  446.     }
  447.  
  448.  
  449. define boolean HandleRemoveVg( map<string,map> targetMap, string current_vg )
  450.     ``{
  451.     boolean ret = false;
  452.     integer count = size(get_lv_names(targetMap, current_vg));
  453.     if( count > 0 )
  454.     {
  455.     // Message popup
  456.     Popup::Message(sformat(
  457. _("The volume group \"%1\" contains at least one logical 
  458. volume.  It cannot be removed. Remove all logical volumes then
  459. remove the volume group.
  460. "), current_vg));
  461.     }
  462.     else
  463.     {  
  464.     // popup text
  465.     if( Popup::ContinueCancel( sformat( _("Really remove the volume group \"%1\"?"), current_vg)))
  466.         {
  467.         ret = removeVolumeGroup( current_vg );
  468.         }
  469.     }
  470.     return( ret );
  471.     }
  472.  
  473. define map DlgCreateVolumeGroup( list vgm_list )
  474.     ``{
  475.     string vgname = "";
  476.     string pesize = "";
  477.     boolean old_metadata = false;
  478.     boolean lvm2 = true;
  479.  
  480.     y2milestone( "lvm2 %1", lvm2 );
  481.  
  482.     term Lvm2Type = `Empty();
  483.  
  484.     if( lvm2 )
  485.     {
  486.     Lvm2Type = `CheckBox( `id("lvm1"), 
  487.                           _("Use &Old LVM1 Compatible Metadata Format"), 
  488.                   false );
  489.     }
  490.    
  491.     UI::OpenDialog(
  492.     `opt(`decorated ),
  493.     `HBox(
  494.         `HSpacing(2),
  495.         `VBox(
  496.           // popup header
  497.           `Heading(_("Create a Volume Group")),
  498.           // popup description
  499.           `Label( _("Now we have to create a volume group.
  500. Typically you don't have to change anything,
  501. but if you are an expert, feel free to change
  502. our defaults:")),
  503.           // label text
  504.           `TextEntry( `id("vgname"), _("Volume Group &Name:"), 
  505.                       size(vgm_list)==0?"system":""),
  506.           // label text
  507.           `TextEntry(`id("pesize"), _("&Physical Extent Size"), "4M"),
  508.           Lvm2Type,
  509.           `VSpacing(1),
  510.           `HBox(
  511.             // Ok button
  512.             `PushButton(`id(`ok), `opt(`default), 
  513.                          Label::OKButton()  ),
  514.             // Cancel button
  515.             `PushButton(`id(`cancel), Label::CancelButton() )
  516.                ),
  517.           `VSpacing(0.5)
  518.          ),
  519.         `HSpacing(2)
  520.         )
  521.     );
  522.  
  523.     any     ret         = nil;
  524.     boolean input_is_ok = false;
  525.       
  526.     repeat
  527.     {
  528.     ret = UI::UserInput();
  529.  
  530.     vgname = (string)UI::QueryWidget(`id("vgname"),  `Value);
  531.     vgname = deletechars( vgname, " \t" );
  532.     pesize = (string)UI::QueryWidget(`id("pesize"),  `Value);
  533.     if( UI::WidgetExists( `id("lvm1") ))
  534.         {
  535.         old_metadata = (boolean)UI::QueryWidget( `id("lvm1"), `Value );
  536.         }
  537.  
  538.     if( ret != `cancel )
  539.         {
  540.         input_is_ok = true;
  541.          
  542.         if( !icheck_pesize(pesize) )
  543.             {
  544.         // error popup text
  545.         Popup::Error(_("The data entered is invalid.
  546. Insert a physical extent size from
  547. 8KB to 512MB in powers of 2, for example, \"4M\" or \"512K\"
  548. "));
  549.         input_is_ok = false;
  550.         }
  551.  
  552.         if( !icheck_vgname(vgname) )
  553.         {
  554.         // error popup text
  555.         Popup::Error(_("The data entered is invalid.
  556. Insert a group name like \"system\" or \"test\".
  557. Do not use ;/`, in your group name.
  558. "));
  559.         input_is_ok = false;
  560.         }
  561.       
  562.         if( contains( vgm_list, vgname ) )
  563.         {
  564.         // error popup text
  565.         Popup::Error(sformat(_("The volume group \"%1\" already exists.
  566. Choose a different name
  567. or cancel this dialog.
  568. "), vgname ));
  569.         input_is_ok = false;
  570.         }
  571.         if( !check_vgname_dev( vgname ) )
  572.         {
  573.         // error popup text
  574.         Popup::Error(sformat(_("The volume group name \"%1\" conflicts
  575. with another entry in the /dev directory.\n"), vgname ));
  576.         input_is_ok = false;
  577.         }
  578.         }
  579.       
  580.     } until( input_is_ok || ret == `cancel );
  581.  
  582.     UI::CloseDialog();
  583.          
  584.     if (ret == `ok )
  585.     {
  586.     map ret = $[ "vgname" : vgname, "pesize" : pesize_str_to_byte (pesize) ];
  587.     ret["lvm2"] = !old_metadata;
  588.     return( ret );
  589.     }
  590.     else
  591.     {
  592.     return( $[] );
  593.     }
  594.     };
  595.  
  596. }
  597.