ACC SHELL

Path : /usr/share/YaST2/include/autoinstall/
File Upload :
Current File : //usr/share/YaST2/include/autoinstall/PartitionDialog.ycp

/**
 * 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