[yast-commit] r60179 - in /trunk/storage: package/yast2-storage.changes storage/src/include/ep-hd-lib.ycp storage/src/include/ep-hd.ycp storage/src/include/ep-main.ycp storage/src/modules/Storage.ycp

Author: aschnell Date: Tue Dec 22 15:29:58 2009 New Revision: 60179 URL: http://svn.opensuse.org/viewcvs/yast?rev=60179&view=rev Log: - support for cloning disk partition layout (fate #303809) (port from SLE11 SP1) Modified: trunk/storage/package/yast2-storage.changes trunk/storage/storage/src/include/ep-hd-lib.ycp trunk/storage/storage/src/include/ep-hd.ycp trunk/storage/storage/src/include/ep-main.ycp trunk/storage/storage/src/modules/Storage.ycp Modified: trunk/storage/package/yast2-storage.changes URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/package/yast2-storage.cha... ============================================================================== --- trunk/storage/package/yast2-storage.changes (original) +++ trunk/storage/package/yast2-storage.changes Tue Dec 22 15:29:58 2009 @@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Tue Dec 22 14:23:40 CET 2009 - aschnell@suse.de + +- support for cloning disk partition layout (fate #303809) + +------------------------------------------------------------------- Mon Dec 21 14:17:30 CET 2009 - aschnell@suse.de - added testsuite for partitioning proposal Modified: trunk/storage/storage/src/include/ep-hd-lib.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/include/ep-hd... ============================================================================== --- trunk/storage/storage/src/include/ep-hd-lib.ycp (original) +++ trunk/storage/storage/src/include/ep-hd-lib.ycp Tue Dec 22 15:29:58 2009 @@ -357,6 +357,206 @@ } + void EpCloneDisk(string device) + { + map<string, map> target_map = Storage::GetTargetMap(); + + integer mysize = target_map[ device, "size_k"]:0; + integer mycyl_size = target_map[ device, "cyl_size"]:0; + list <map> myparts = target_map[ device, "partitions"]:[]; + string mypart_table_type = target_map[ device, "label" ]:Storage::DefaultDiskLabel( mysize ); + + string helptext = _("<p>Select one or more (if available) hard disks +that will have the same partition layout as +this disk.</p> +<p>Disks marked with '*' sign contain one or +more partitions. After cloning, these +partitions will be deleted.</p>"); + + void HelpDialog() { + UI::OpenDialog( `MinSize( 40,10,`VBox( + `RichText(helptext), + `VSpacing(1), + `PushButton(`id(`ok), Label::CloseButton()) + ) + )); + + UI::UserInput(); + UI::CloseDialog(); + } + + list <string> AvailableTargetDisks() { + list <string> items = []; + + map <string, map> filtered_target_map = + filter( string dev, map props, target_map, { + return ( dev != device && + Storage::IsDiskType( props["type"]:`CT_UNKNOWN ) && + props["used_by_device"]:"" == "" && + props["cyl_size"]:0 == mycyl_size ); + }); + + y2milestone("Available, suitable and unused disks (other than %1): %2", device, Map::Keys(filtered_target_map)); + + foreach( string dev, map props, filtered_target_map,{ + if( props["size_k"]:0 >= mysize ) + items = add(items, dev); + else + y2milestone("%1 is smaller than needed, skipping it", device); + }); + + return items; + } + + boolean ConfirmDeletePartitions( list <string> to_delete) { + + UI::OpenDialog( `opt(`warncolor), `VBox( + `Left(`Label(_("The following partitions will be deleted\nand all data on them will be lost:"))), + `VSpacing(1), + `RichText(HTML::List( to_delete)), + `Left(`Label(_("Really delete these partitions?"))), + `VSpacing(1), + `ButtonBox( + `PushButton(`id(`ok), `opt(`default), Label::DeleteButton()), + `PushButton(`id(`cancel), Label::CancelButton()) + ) + ) + ); + symbol ret = (symbol) UI::UserInput(); + UI::CloseDialog(); + + return (ret == `ok); + } + + if (isempty(myparts)) { + Popup::Error(_("There are no partitions on this disk (a clonable +disk must have at least one partition). +Create some partitions before cloning the disk.")); + return; + } + + list <string> mydisks = AvailableTargetDisks(); + + if (isempty(mydisks)) { + Popup::Error("This disk cannot be cloned. There are no suitable +disks that could have the same partitioning layout."); + return; + } + + list<term> ui_items = maplist( string one_disk, mydisks, { + boolean any_partitions = !isempty(target_map[ one_disk, "partitions" ]:[]); + + return `item(`id(one_disk), sformat("%1%2 (%3)",one_disk, + any_partitions ? "*" : "", + Storage::KByteToHumanString( target_map[one_disk, "size_k"]:42))); + }); + + UI::OpenDialog (`MinSize( 60, 20, `VBox( + `Heading(sformat(_("Clone partition layout of %1"), device)), + `VSpacing(1), + `MultiSelectionBox(`id(`tdisk), _("Available target disks:"), ui_items ), + `VSpacing(1), + `ButtonBox( + `PushButton(`id(`help), Label::HelpButton()), + `PushButton(`id(`ok), `opt(`default), Label::OKButton()), + `PushButton(`id(`cancel), Label::CancelButton()) + ) + ) + )); + + any ret = nil; + boolean run_raid_setup = false; + + while(ret != `ok && ret != `cancel) + { + ret = UI::UserInput(); + + if( ret == `ok) { + list <string> selected_disks = (list <string>) UI::QueryWidget(`id(`tdisk), `SelectedItems); + boolean any_disk_selected = !isempty(selected_disks); + + if (!any_disk_selected) { + Popup::Error(_("Select some target disk for creating a clone")); + UI::SetFocus(`id(`tdisk)); + ret = nil; + continue; + } + + list <string> partitions_to_delete = []; + + //collect partitions to delete + foreach (string this_disk, selected_disks, { + list <map> partitions = target_map[ this_disk, "partitions" ]:[]; + + if (!isempty(partitions)) { + list <string> tmp = maplist( map one_part, partitions, { + return one_part["device"]:""; + }); + partitions_to_delete = (list <string>) union( partitions_to_delete, tmp); + } + }); + + //if there is anything to delete, ask user if s/he really wants to delete + if ( !isempty(partitions_to_delete) && + !ConfirmDeletePartitions( partitions_to_delete )) { + ret = nil; + continue; + } + + //We'll be deleting recursively, so that no longer valid + //LVMs and RAIDs are not left behind + boolean recursive = Storage::GetRecursiveRemoval(); + Storage::SetRecursiveRemoval(true); + + foreach (string this_disk, selected_disks, { + map <string,any> disk_info = Storage::GetDisk( target_map, this_disk ); + list <map> partitions = target_map[ this_disk, "partitions" ]:[]; + list<string> pnames = maplist(map part, partitions, { return part["device"]:""; }); + string part_table_type = disk_info["label"]:Storage::DefaultDiskLabel(disk_info["size_k"]:0); + + y2milestone("Deleting these partitions: %1", pnames); + + if (!isempty(partitions)) { + foreach( string one_partition, pnames,{ + Storage::DeleteDevice( disk_info["device"]:"", one_partition ); + }); + } + + if( mypart_table_type != part_table_type ) { + y2milestone("%1 has different type of partition table: %2, will create a new one", + this_disk, part_table_type); + Storage::CreatePartitionTable( disk_info["device"]:"", mypart_table_type ); + } + + foreach( map one_partition, myparts, { + map next = Storage::NextPartition( this_disk, one_partition["type"]:`none); + Storage::CreatePartition( this_disk, next["device"]:"error", + one_partition["type"]:`primary, + one_partition["fsid"]: Partitions::fsid_native, + one_partition["region",0]:0, one_partition["region",1]:0, + one_partition["mountby"]:Storage::GetMountBy(device) ); + //FIXME: ChangeVolumeProperties too? + }); + }); + + Storage::SetRecursiveRemoval( recursive ); + } + else if (ret == `help) { + HelpDialog(); + continue; + } + } + + UI::CloseDialog(); + + if( ret == `ok ) { + UpdateMainStatus(); + UpdateNavigationTree(nil); + TreePanel::Create(); + } + } + + void EpDasdfmtDisk(string device) { map<string, map> target_map = Storage::GetTargetMap(); Modified: trunk/storage/storage/src/include/ep-hd.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/include/ep-hd... ============================================================================== --- trunk/storage/storage/src/include/ep-hd.ycp (original) +++ trunk/storage/storage/src/include/ep-hd.ycp Tue Dec 22 15:29:58 2009 @@ -259,7 +259,10 @@ list<term> expert_cmds = [ `item(`id(`create_partition_table), // menu entry text - _("Create New Partition Table")) + _("Create New Partition Table")), + `item(`id(`clone_disk), + // menu entry text + _("Clone This Disk")) ]; if (Arch::s390() && search(device, "/dev/dasd") == 0) @@ -308,6 +311,10 @@ EpCreatePartitionTable(disk_device); break; + case `clone_disk: + EpCloneDisk(disk_device); + break; + case `dasdfmt: EpDasdfmtDisk(disk_device); break; Modified: trunk/storage/storage/src/include/ep-main.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/include/ep-ma... ============================================================================== --- trunk/storage/storage/src/include/ep-main.ycp (original) +++ trunk/storage/storage/src/include/ep-main.ycp Tue Dec 22 15:29:58 2009 @@ -33,6 +33,7 @@ import "ProductFeatures"; import "Directory"; import "HTML"; + import "Map"; include "partitioning/lvm_ui_dialogs.ycp"; include "partitioning/raid_lib.ycp"; Modified: trunk/storage/storage/src/modules/Storage.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/modules/Stora... ============================================================================== --- trunk/storage/storage/src/modules/Storage.ycp (original) +++ trunk/storage/storage/src/modules/Storage.ycp Tue Dec 22 15:29:58 2009 @@ -1570,7 +1570,7 @@ integer count=0; -boolean IsDiskType(symbol t) +global boolean IsDiskType(symbol t) { return contains([ `CT_DISK, `CT_DMRAID, `CT_DMMULTIPATH ], t); } -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org
participants (1)
-
aschnell@svn.opensuse.org