ACC SHELL
/**
* File:
* PartitionDialog.ycp
*
* Module:
* Partitioning
*
* Summary:
* Display and handle partition dialog.
*
* Authors:
* Sven Schober (sschober@suse.de)
*
* $Id: PartitionDialog.ycp 2812 2008-06-05 12:49:30Z sschober $
*/
{
textdomain "autoinst";
include "autoinstall/common.ycp";
include "autoinstall/AdvancedPartitionDialog.ycp";
import "AutoinstPartPlan";
import "AutoinstDrive";
import "AutoinstPartition";
define PartitionT currentPartition = $[];
define DriveT parentDrive = $[];
define integer driveId = 0;
define integer partitionIdx = 0;
define boolean dirty = false;
define list<string>
getAvailableMountPoints(){
/**
* TODO: implement filtering out already used mp's
*/
return AutoinstPartPlan::getAvailableMountPoints();
}
define list<term>
getValidUnitsForMountPoint( string mountPoint ){
list<string> unit = AutoinstPartition::getAllUnits();
/* filter out "auto" */
if( "/boot" == mountPoint ||
"swap" == mountPoint ){
/* 'auto' is only available for '/boot' and 'swap' */
unit = add( unit, "auto" );
}
return toItemList( unit );
}
define list<term>
getFileSystemTypes(){
//return toItemList( AutoinstPartition::getAllFileSystemTypes() );
map<symbol,map> allFs = AutoinstPartition::getAllFileSystemTypes();
list<term> result = [];
foreach( symbol fsType, map fsMap, allFs ,{
result = add(result, `item(`id(fsType), fsMap[`name]:"no-text" ));
});
return add(result, `item(`id(`keep), "<keep>"));
}
define boolean
getFormatStatus(){
return AutoinstPartition::getFormat(currentPartition);
}
define integer
getMaxPartitionNumber(){
return AutoinstPartition::getMaxPartitionNumber();
}
/**
* determines if this partition is a PV feeding VG
*/
define boolean
isPartOfVolgroup(){
return AutoinstPartition::isPartOfVolgroup( currentPartition );
}
/**
* determines if this partition is to be created on a VG
*/
define boolean
isOnVolgroup(){
return `CT_DISK != parentDrive["type"]:`Empty;
}
define list<term>
getVolgroups(){
return add( toItemList( AutoinstPartPlan::getAvailableVolgroups() ), `item(`id(`none),_("<none>")) );
}
define void enableMount(){
UI::ChangeWidget(`id(`cbMountPoint), `Enabled, true );
UI::ChangeWidget(`id(`cbFileSystem), `Enabled, true );
UI::ChangeWidget(`id(`cbVolgroup), `Value, `none );
}
define void disableMount(){
UI::ChangeWidget(`id(`cbMountPoint), `Enabled, false );
UI::ChangeWidget(`id(`cbFileSystem), `Value, `keep );
UI::ChangeWidget(`id(`cbFileSystem), `Enabled, false );
}
/**
* SYNCING UI <-> DATA
*/
/**
* Sync. UI Settings to currentPartition map.
*/
define PartitionT
updatePartitionDialogData( PartitionT part ){
string mpString = "";
string lvName = "";
string lvmGroup = "";
integer stripes = 1;
integer stripesize = 0;
integer partId = 131;
any mpAny = UI::QueryWidget(`id(`cbMountPoint),`Value);
if( is(mpAny, symbol) ){
mpString = symbol2string( (symbol) mpAny );
}
else if( is(mpAny, string) ){
mpString = (string) mpAny;
}
if( isOnVolgroup() ){
/* LV */
lvName = (string) UI::QueryWidget( `id(`lvName), `Value );
stripes = (integer) UI::QueryWidget( `id(`numberStripes), `Value );
stripesize = (integer) UI::QueryWidget( `id(`stripesize), `Value );
if( "" == lvName ) {
Popup::Warning( _("Please provide a logical volume name.") );
}
} else {
UI::ChangeWidget( `id(`striping), `Enabled, false );
if( (symbol) UI::QueryWidget(`id(`cbVolgroup), `Value) != `none ){
/* PV */
/* `/dev/system1 -> "system1" */
lvmGroup = removePrefix(symbol2string( (symbol) UI::QueryWidget(`id(`cbVolgroup), `Value ) ), "/dev/");
partId = 142;
/* a PV needs no mount point */
mpString = "";
}
}
if( mpString == "swap" ){
partId = 130;
}
part = AutoinstPartition::set( part, "partition_id", partId );
part = AutoinstPartition::set( part, "mount",mpString);
part = AutoinstPartition::set( part, "lvm_group",lvmGroup);
part = AutoinstPartition::set( part, "lv_name",lvName);
if( stripes > 1 && stripesize > 0 && (boolean)UI::QueryWidget(`id(`striping), `Value) ) {
part = AutoinstPartition::set( part, "stripes", stripes );
part = AutoinstPartition::set( part, "stripesize", stripesize );
} else {
part = remove( part, "stripes" );
part = remove( part, "stripesize" );
}
string unit = symbol2string((symbol)UI::QueryWidget(`id(`unit), `Value));
string sizeVal = "";
if( unit != "max" && unit != "auto" ){
sizeVal = (string) UI::QueryWidget(`id(`size), `Value);
if( unit != "%" ){
if( unit == "Byte" ){
/* don't save any unit for byte sizes */
unit = "";
}
else{
/* MB, GB -> M, B */
unit = regexpsub(unit, "(.*)B", "\\1");
}
}
}
string encodedSize = sizeVal + unit;
part = AutoinstPartition::set( part, "size",
encodedSize);
part = AutoinstPartition::set( part, "partition_nr",
tointeger(UI::QueryWidget(`id(`partitionNumber),`Value)));
boolean reUse = (boolean) UI::QueryWidget(`id(`reusePartition),`Value);
part = AutoinstPartition::set( part, "create", ! reUse );
part = AutoinstPartition::set( part, "resize",
(boolean) UI::QueryWidget(`id(`resizePartition),`Value));
if( `keep == (symbol) UI::QueryWidget(`id(`cbFileSystem), `Value ) ){
if( ! reUse && lvmGroup == "" ){ /* for PV's its ok to have no fs */
Popup::Warning( _("You selected to create the partition but you did not select a valid file system.\nPlease select a valid filesystem to continue.") );
}
part = AutoinstPartition::set( part, "format", false);
part = AutoinstPartition::set( part, "filesystem",`Empty);
}
else{
part = AutoinstPartition::set( part, "format", true);
part = AutoinstPartition::set( part, "filesystem",
(symbol)UI::QueryWidget(`id(`cbFileSystem),`Value));
}
return part;
}
/**
* Sync. currentPartition map to UI.
*/
define void
updatePartitionDialogGUI(){
if( isPartOfVolgroup() ){
/* this is a PV feeding a VG */
disableMount();
string volgroupName = addPrefix(currentPartition["lvm_group"]:"not-set", "/dev/");
UI::ChangeWidget(`id(`cbVolgroup),`Value, string2symbol( volgroupName ));
}
else{
enableMount();
string mountPoint = currentPartition["mount"]:"";
if( isOnVolgroup() ){
/* this is a partition on a VG */
string lvName = currentPartition["lv_name"]:"";
if( "" == lvName ){
lvName = AutoinstPartition::getLVNameFor( mountPoint );
}
UI::ChangeWidget(`id(`lvName), `Value, lvName);
UI::ChangeWidget(`id(`stripesize), `Value, currentPartition["stripesize"]:0 );
UI::ChangeWidget(`id(`numberStripes), `Value, currentPartition["stripes"]:1 );
if( currentPartition["stripes"]:1 > 1 ) {
UI::ChangeWidget(`id(`striping), `Enabled, true );
UI::ChangeWidget(`id(`striping), `Value, true );
UI::ChangeWidget(`id(`numberStripes), `Enabled, true );
UI::ChangeWidget(`id(`stripesize), `Enabled, true );
} else {
UI::ChangeWidget(`id(`striping), `Enabled, true );
UI::ChangeWidget(`id(`striping), `Value, false );
UI::ChangeWidget(`id(`numberStripes), `Enabled, false );
UI::ChangeWidget(`id(`stripesize), `Enabled, false );
}
} else {
UI::ChangeWidget(`id(`striping), `Value, false );
UI::ChangeWidget(`id(`striping), `Enabled, false );
UI::ChangeWidget(`id(`numberStripes), `Enabled, false );
UI::ChangeWidget(`id(`stripesize), `Enabled, false );
}
UI::ChangeWidget(`id(`cbMountPoint), `Value, mountPoint );
}
if( 0 == size( getVolgroups() ) ){
UI::ChangeWidget(`id(`rbLVM), `Enabled, false );
}
/* The size string can be either an absolute numerical like
* 500M or 10G, the string 'max' or a relative percentage
* like '10%'.
*/
string unit = AutoinstPartition::getUnit( currentPartition );
if( "max" == unit || "auto" == unit ){
UI::ChangeWidget(`id(`size), `Enabled, false );
}
else{
integer partSize = AutoinstPartition::getSize(currentPartition);
UI::ChangeWidget(`id(`size), `Value, tostring(partSize) );
if( unit != "%" ){
if( unit == "" ){
/* size strings with no unit are bytes */
unit = "Byte";
}
else{
/* M, G -> MB, GB */
unit = unit + "B";
}
}
}
symbol sUnit = string2symbol( unit );
UI::ChangeWidget(`id(`unit), `Value, sUnit );
UI::ChangeWidget(`id(`partitionNumber), `Value, currentPartition["partition_nr"]:0 );
if( parentDrive["initialize"]:false ){
UI::ChangeWidget(`id(`reusePartition), `Enabled, false );
UI::ChangeWidget(`id(`resizePartition), `Enabled, false );
}
else{
if( ! currentPartition["create"]:true ){
/* reuse */
UI::ChangeWidget(`id(`reusePartition), `Value, true );
UI::ChangeWidget(`id(`size), `Enabled, false );
UI::ChangeWidget(`id(`unit), `Enabled, false );
}
else{
/* create */
UI::ChangeWidget(`id(`resizePartition), `Enabled, false );
}
if( currentPartition["resize"]:false ){
UI::ChangeWidget(`id(`resizePartition), `Enabled, true );
UI::ChangeWidget(`id(`resizePartition), `Value, true );
if( `max != sUnit ){
/* only enable size text entry, if unit is not max */
UI::ChangeWidget(`id(`size), `Enabled, true );
}
/* if resize is enabled, definitly enable units combobox,
* so user can change units */
UI::ChangeWidget(`id(`unit), `Enabled, true );
}
}
if( getFormatStatus() ){
symbol filesystem = AutoinstPartition::getFileSystem( currentPartition );
UI::ChangeWidget(`id(`cbFileSystem), `Value, filesystem );
}
else{
UI::ChangeWidget(`id(`cbFileSystem), `Value, `keep );
}
}
define boolean PartitionCheckSanity( PartitionT partition ){
boolean result = false;
string errMsg = AutoinstPartition::checkSanity( partition );
if( "" != errMsg ){
Popup::Error( errMsg );
}
else{
/* if errMsg was empty no error was detected. */
result = true;
}
return result;
}
/**
* GENERAL DIALOG IFACE
*/
define PartitionT PartitionLoad( integer dIdx, integer pIdx ){
PartitionT p = AutoinstPartPlan::getPartition( dIdx, pIdx );
y2milestone("Loaded partition '%1' on drive '%2': \n%3", pIdx, dIdx, p );
return p;
}
define void PartitionStore(){
currentPartition = updatePartitionDialogData( currentPartition );
y2milestone("PartitionStore():\ncurrent partiton: '%1'\n(driveId:partitionIdx): ('%2':'%3')",
currentPartition, driveId,partitionIdx);
/* We don't use the return value of the check, because we
* currently can't stop the dialog switch from happening, so we
* issue possible errors as warnings, and store anyway... should
* be fixed.
*/
PartitionCheckSanity( currentPartition );
AutoinstPartPlan::updatePartition(driveId, partitionIdx, currentPartition );
}
define void PartitionCheck(){
currentPartition = updatePartitionDialogData( currentPartition );
y2milestone("PartitionCheck():\ncurrent partiton: '%1'\n(driveId:partitionIdx): ('%2':'%3')",
currentPartition, driveId,partitionIdx);
PartitionT storedPartition = PartitionLoad( driveId, partitionIdx );
if( ! AutoinstPartition::areEqual( currentPartition, storedPartition ) || dirty ){
if( Popup::YesNo( _("Store unsaved changes to partition?") ) ){
dirty = false;
if( PartitionCheckSanity( currentPartition ) ){
AutoinstPartPlan::updatePartition(driveId, partitionIdx, currentPartition );
}
}
}
}
define void PartitionDisplay(){
string reference = stack[`which]:"";
y2milestone( "PartitionDisplay('%1')", reference );
list<string> splice = splitstring( reference, "_" );
driveId = tointeger( splice[0]:"999" );
partitionIdx = tointeger( splice[1]:"999" );
currentPartition = PartitionLoad( driveId, partitionIdx );
parentDrive = AutoinstPartPlan::getDrive( driveId );
term lvmSettings = `ComboBox(`id(`cbVolgroup),`opt(`notify), _("Volgroup"), getVolgroups());
if( isOnVolgroup() ){
lvmSettings = `InputField(`id(`lvName), _("Logical volume name"));
}
term contents =
`VBox(
`Heading( _("Edit partition") ),
`VSpacing(1),
`HVCenter(`HVSquash(
`VBox(
`HBox(
`Left(`ComboBox(`id(`cbMountPoint),`opt(`editable,`notify),
_("&Mount point"),getAvailableMountPoints())),
`HSpacing(1),
lvmSettings,
`HSpacing(2),
`Right(`ComboBox(`id(`cbFileSystem),_("File sys&tem"), getFileSystemTypes()))
),
`VSpacing(1),
`HBox(
`Left(`InputField(`id(`size), _("&Size"))),
//`TextEntry(`id(`size), _("&Size")),
`Left(`ComboBox(`id(`unit),`opt(`notify), " ",
getValidUnitsForMountPoint(currentPartition["mount"]:""))),
`HStretch()
), /* HBox */
`VSpacing(1),
`HBox(
`IntField(`id(`partitionNumber),_("Partiti&on number"),0,getMaxPartitionNumber(),
currentPartition["partition_nr"]:0),
`HStretch(),
`VBox(
`Left(`CheckBox(`id(`reusePartition),`opt(`notify),_("Reuse e&xisting partition"))),
`Left(`CheckBox(`id(`resizePartition),`opt(`notify),_("Res&ize existing partition")))
) /* VBox */
),/* HBox */
`VSpacing(1),
`HBox( `CheckBox(`id(`striping), `opt(`notify), _("Activate Striping") ),
`IntField(`id(`numberStripes),`opt(`notify),_("Number of Stripes"),1,9,1),
`IntField(`id(`stripesize), `opt(`notify),_("Stripe size"),1,32,1),
`HStretch()
), /* HBox */
`VSpacing(1),
`PushButton(`id(`advanced), _("Advan&ced")),
`VSpacing(2),
`PushButton( `id(`apply),_("Apply"))
) /* VBox */
) /* HVCenter */
)); /* VBox */
UI::ReplaceWidget(`id(replacement_point), contents );
/* only numbers are allowed in size */
UI::ChangeWidget(`id(`size), `ValidChars, "0123456789" );
UI::ChangeWidget(`id(`striping), `Enabled, isOnVolgroup() );
UI::ChangeWidget(`id(`numberStripes), `Enabled, (boolean)UI::QueryWidget( `id(`striping), `Value) );
UI::ChangeWidget(`id(`stripesize), `Enabled, (boolean)UI::QueryWidget( `id(`striping), `Value) );
updatePartitionDialogGUI();
}
define void PartitionNew(){
integer parentDriveId = tointeger( stack[`which]:"0" );
integer newPartitionNumber = AutoinstPartPlan::newPartition( parentDriveId );
if( newPartitionNumber != 999 ){
DriveT parentDrive = AutoinstPartPlan::getDrive( parentDriveId );
string parentRef = AutoinstDrive::getNodeReference( parentDrive );
string newPartitionId = AutoinstPartition::getNodeReference( parentRef, newPartitionNumber );
stack[`which] = stripTypePrefix( newPartitionId );
PartitionDisplay();
selectTreeItem( newPartitionId );
}
else{
y2error( "Cannot create new partition an invalid drive with index '%1'.", parentDriveId );
}
}
define void PartitionEventHandler(){
y2milestone( "PartitionEventHandler():");
if( is( currentEvent, map ) ){
symbol event = currentEvent["WidgetID"]:`Empty;
if( `cbVolgroup == event){
if( `none == (symbol)UI::QueryWidget( `id(`cbVolgroup), `Value )){
/* user selected this partition _not_ to be part of volgroup */
enableMount();
}
else{
/* user selected this partition to be part of volgroup */
disableMount();
}
eventHandled();
}
else if( `unit == event ){
symbol which = (symbol) UI::QueryWidget( `id(`unit), `Value );
if( `max == which ){
UI::ChangeWidget(`id(`size), `Enabled, false);
}
else if( `auto == which ){
if( (boolean) UI::QueryWidget(`id(`cbMountPoint), `Enabled) ){
string mp = (string) UI::QueryWidget(`id(`cbMountPoint), `Value );
if( "/boot" == mp || "swap" == mp ){
UI::ChangeWidget(`id(`size), `Enabled, false);
}
else{
Popup::Error(_("Size \"auto\" is only valid if mount point \"/boot\" or \"swap\" is selected"));
UI::ChangeWidget(`id(`size), `Enabled, true);
UI::ChangeWidget(`id(`unit), `Value, `GB );
}
}
else{
Popup::Error(_("Size \"auto\" is invalid for physical volumes."));
UI::ChangeWidget(`id(`size), `Enabled, true);
UI::ChangeWidget(`id(`unit), `Value, `GB );
}
}
else{
UI::ChangeWidget(`id(`size), `Enabled, true);
}
eventHandled();
}
else if( `advanced == event ){
/* if this partition is part of a volume group,
* we call it a PV (physical volume).
*/
boolean isPV = false;
isPV = ( UI::WidgetExists(`id(`cbVolgroup) ) &&
( `none != (symbol) UI::QueryWidget(`id(`cbVolgroup), `Value )));
currentPartition = AdvancedPartitionDisplay( currentPartition, isPV );
y2milestone("got partition '%1'", currentPartition );
}
else if( `reusePartition == event ){
boolean reuseEnabled = (boolean) UI::QueryWidget( `id(`reusePartition), `Value );
if( reuseEnabled ){
UI::ChangeWidget( `id(`size), `Enabled, false );
UI::ChangeWidget(`id(`unit), `Enabled, false);
UI::ChangeWidget( `id(`resizePartition), `Enabled, true );
}
else{
/* reuse has been disabled */
UI::ChangeWidget(`id(`unit), `Enabled, true);
if( `max != (symbol) UI::QueryWidget(`id(`unit), `Value) ){
UI::ChangeWidget( `id(`size), `Enabled, true );
}
UI::ChangeWidget( `id(`resizePartition), `Value, false );
UI::ChangeWidget( `id(`resizePartition), `Enabled, false );
}
}
else if( `resizePartition == event ){
boolean resizeEnabled = (boolean) UI::QueryWidget( `id(`resizePartition), `Value );
if( resizeEnabled ){
/* resize has been enabled */
if( `max != (symbol) UI::QueryWidget(`id(`unit), `Value) ){
UI::ChangeWidget( `id(`size), `Enabled, true );
}
UI::ChangeWidget(`id(`unit), `Enabled, true);
}
else{
/* resize has been disabled */
UI::ChangeWidget( `id(`size), `Enabled, false );
UI::ChangeWidget(`id(`unit), `Enabled, false);
}
}
else if( `cbMountPoint == event ){
any mp = UI::QueryWidget(`id(`cbMountPoint), `Value );
string mountPoint = "";
if( is( mountPoint, symbol )){
mountPoint = symbol2string( (symbol) mp );
}
else{
mountPoint = (string) mp;
}
symbol prevUnit = (symbol) UI::QueryWidget( `id(`unit), `Value);
/* rebuild unit list */
UI::ChangeWidget(`id(`unit), `Items, getValidUnitsForMountPoint(mountPoint));
if( `auto == prevUnit &&
"/boot" != mountPoint &&
"swap" != mountPoint ){
UI::ChangeWidget(`id(`size), `Enabled, true);
/* as 'auto' is no longer available select GB as default */
prevUnit = `GB;
}
/* reselect previous unit */
UI::ChangeWidget(`id(`unit), `Value, prevUnit );
if( mountPoint == "swap" ){
UI::ChangeWidget(`id(`cbFileSystem), `Value, `swap );
UI::ChangeWidget(`id(`cbFileSystem), `Enabled, false );
}
}
else if( event == `striping ) {
UI::ChangeWidget(`id(`numberStripes), `Value, 1 );
UI::ChangeWidget(`id(`numberStripes), `Enabled, (boolean)UI::QueryWidget( `id(`striping), `Value) );
UI::ChangeWidget(`id(`stripesize), `Enabled, (boolean)UI::QueryWidget( `id(`striping), `Value) );
dirty = true;
}
}
}
define void PartitionDelete(){
string reference = stack[`which]:"";
y2milestone("PartitionDelete('%1')", reference );
/* PartitionDelete is only called when a partition is selected,
* so driveId and partitionIdx should have valid values.
*/
AutoinstPartPlan::deletePartition( driveId, partitionIdx );
}
string partitionType = "part";
map<symbol,any> partitionDialog = $[
`type : partitionType,
`display : ``(PartitionDisplay()),
`eventHandler : ``(PartitionEventHandler()),
`store : ``(PartitionStore()),
`new : ``(PartitionNew()),
`delete : ``(PartitionDelete()),
`check : ``(PartitionCheck())
];
y2milestone("adding partition dialog to dialog list.");
dialogs = add(dialogs,partitionType,partitionDialog);
}
ACC SHELL 2018