Code

Beautified FAI templates
[gosa.git] / gosa-plugins / fai / admin / fai / class_faiPartition.inc
index 755158144e54cf254ef3b93dfb57250910a8f9db..ad553a2348acd2107c0841b3b4bd92271772a260 100644 (file)
@@ -15,7 +15,7 @@ class faiPartition extends plugin
   var $FAIfsType = "";
   var $FAImountOptions = "";
   var $FAImountPoint = "";
-  var $FAIpartitionNr = "";
+  var $FAIpartitionNr = "undefined"; // Initial value for new partitions
   var $FAIpartitionSize = "";
   var $FAIpartitionType = "";
   var $FAIstate = "";
@@ -23,55 +23,117 @@ class faiPartition extends plugin
   
   var $FAIdiskType = "disk";
 
+  // Size options.
   var $FAIpartitionSizeType = "fixed";
   var $sizeStart = 0;
   var $sizeStop  = 0;
   var $sizeStart_Type = "MB";
   var $sizeStop_Type  = "MB";
-   
+  
+  //  Flags 
   var $bootable = false; 
   var $resize = false;
+  var $encrypted = false;
   var $preserve = false;
   var $preserveType = "always";
-  var $encrypted = false;
 
-  function __construct($config, $object, $type)
+  var $raidDevices = array();
+
+  // Once we've exceeded the primary partition limit,
+  //  hide the the 'primary' option from the select box.
+  var $disablePrimary = FALSE; 
+
+  function __construct($config, $object, $parent,$type)
   {
-    foreach($this->attributes as $attr){
-      if(isset($object[$attr])){
-        $this->$attr = $object[$attr];
-      }
-    }
 
+    $this->parent = $parent;
     $this->FAIdiskType = $type;
 
-    /* Prepare size attribute 
-     * This attribute may represent a range, a fixed value 
-     *  or a percentage.
-     * fixed is just a number   * 500MB
-     * range                    * 500MB-1TB
-     * remaining                * -
-     */
-    
-    // Fixed
-    if(preg_match("/^[0-9]*(KB|MB|GB|TB|PB)$/",$this->FAIpartitionSize)){
-      $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB)$/","\\1",$this->FAIpartitionSize);
-      $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB)$/","\\2",$this->FAIpartitionSize);
-      $this->FAIpartitionSizeType = "fixed";
-    }else
+    // Check if we should be able to add primary partitions.
+    if(!$object || $object['FAIpartitionType'] == "logical"){
+      if($this->FAIdiskType == "disk"){
+        $types = array('logical' => array(), 'primary' => array());
+        foreach($this->parent->partitions as $key => $part){
+          $types[$part['FAIpartitionType']][$part['FAIpartitionNr']] = 1;
+        }
+        if(count($types['logical']) && count($types['primary']) >= 3){
+          $this->disablePrimary = TRUE;
+        }elseif(count($types['logical']) >= 4){
+          $this->disablePrimary = TRUE;
+        }
+      } 
+    } 
+
+    // Load attributes from existing partition 
+    if($object){
+      foreach($this->attributes as $attr){
+        if(isset($object[$attr])){
+          $this->$attr = $object[$attr];
+        }
+      }
+
+      if($type == "disk" || $type =="lvm"){
+
+        /* Prepare size attribute 
+         * This attribute may represent a range, a fixed value 
+         *  or a percentage.
+         * fixed is just a number   * 500MB
+         * range                    * 500MB-1TB
+         * remaining                * -
+         */
+        // Fixed
+        if(preg_match("/^[0-9]{1,}(KB|MB|GB|TB|PB|%|)$/",$this->FAIpartitionSize)){
+          $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\1",$this->FAIpartitionSize);
+          $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\2",$this->FAIpartitionSize);
+          $this->FAIpartitionSizeType = "fixed";
+        }else
+
+        // Dynamic range
+        if(preg_match("/^[0-9]{1,}(KB|MB|GB|TB|PB|%|)-[0-9]{1,}(KB|MB|GB|TB|PB|%|)$/",$this->FAIpartitionSize)){
+          $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%).*$/","\\1",$this->FAIpartitionSize);
+          $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%).*$/","\\2",$this->FAIpartitionSize);
+          $this->sizeStop = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\1",$this->FAIpartitionSize);
+          $this->sizeStop_Type = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\2",$this->FAIpartitionSize);
+          $this->FAIpartitionSizeType = "dynamic";
+        }else
+
+        // Dynamic range
+        if(preg_match("/^(0|)\-$/",$this->FAIpartitionSize)){
+          $this->FAIpartitionSizeType = "remaining";
+        }
+
+        // Ensure that we've a valid value type selected.
+        if(!preg_match("/(KB|MB|GB|TB|PB|%)/",$this->sizeStart_Type)){
+          $this->sizeStart_Type = "MB";
+        }
+        if(!preg_match("/(KB|MB|GB|TB|PB|%)/",$this->sizeStop_Type)){
+          $this->sizeStop_Type = "MB";
+        }
+
+        /* Check for encrypted partitions
+         */
+        if(preg_match("/:encrypt$/",$this->FAImountPoint)){
+          $this->FAImountPoint = preg_replace("/:encrypt/","",$this->FAImountPoint);
+          $this->encrypted = TRUE;
+        }
     
-    // Dynamic range
-    if(preg_match("/^[0-9]*(KB|MB|GB|TB|PB)-[0-9]*(KB|MB|GB|TB|PB)$/",$this->FAIpartitionSize)){
-      $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB).*$/","\\1",$this->FAIpartitionSize);
-      $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB).*$/","\\2",$this->FAIpartitionSize);
-      $this->sizeStop = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB)$/","\\1",$this->FAIpartitionSize);
-      $this->sizeStop_Type = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB)$/","\\2",$this->FAIpartitionSize);
-      $this->FAIpartitionSizeType = "dynamic";
-    }else
-
-    // Dynamic range
-    if(preg_match("/^\-$/",$this->FAIpartitionSize)){
-      $this->FAIpartitionSizeType = "remaining";
+      }elseif($type == "raid"){
+   
+        // Extract raid devices out of the partition size attribute. 
+        $usedDisks = explode(",",$this->FAIpartitionSize);
+        foreach($usedDisks as $disk){
+          $name = preg_replace("/:.*$/","",$disk);
+          $spare = preg_match("/:spare/",$disk);
+          $missing = preg_match("/:missing/",$disk);
+          if(!empty($name)){
+            $this->raidDevices[$name] = 
+              array(
+                  "name" => $name, 
+                  "spare" => $spare, 
+                  "missing" => $missing);
+          }
+        }
+      }
     }
   }
 
@@ -80,27 +142,39 @@ class faiPartition extends plugin
     plugin::execute();
     $smarty = get_smarty();
 
+    // Remove partition
+    if(isset($_POST['addPhysicalPartition']) && isset($_POST['physicalPartitionAdd'])){
+      $name = $_POST['physicalPartitionAdd'];
+      $this->raidDevices[$name] = array("name" => $name,"spare"=>false,"missing"=>false);     
+    }
+
     // Create a list of selectable partition types
     if($this->FAIdiskType == "disk"){
-      $types  = array(
-          "primary" => _("Primary"),
-          "secondary" => _("Secondary"));
+
+      if($this->disablePrimary){
+        $types  = array(
+            "logical" => _("Logical"));
+      }else{
+        $types  = array(
+            "primary" => _("Primary"),
+            "logical" => _("Logical"));
+      }
+
     }elseif($this->FAIdiskType == "raid"){
       $types  = array(
-          "raid0" => _("Raid 0"),
-          "raid1" => _("Raid 1"),
-          "raid5" => _("Raid 5"),
-          "raid6" => _("Raid 6"));
+          "raid0" => _("RAID 0"),
+          "raid1" => _("RAID 1"),
+          "raid5" => _("RAID 5"),
+          "raid6" => _("RAID 6"));
     }else{
       $types = "";
     }
-
      
     // Create a list of all size options
     $partitionSizeTypes  = array(
-        "fixed"     => _("Fixed"),
-        "dynamic"     => _("Dynamic"),
-        "remaining" => _("Use remaining space")
+        "fixed"     => _("fixed"),
+        "dynamic"     => _("dynamic"),
+        "remaining" => _("remaining space")
         );
 
     // Create a list of all size options
@@ -110,23 +184,25 @@ class faiPartition extends plugin
         "GB"      => _("GB"),
         "TB"      => _("TB"),
         "PB"      => _("PB"),
-        "%"      => _("Percent")
+        "%"      => _("%")
         );
 
     // Preserve types 
     $preserveTypes = array(
-        "always" => _("Always"),
-        "reinstall" => _("Reinstall"));
-  
+        "always" => _("always"),
+        "reinstall" => _("reinstall"));
+
+    // File system types.  
     $FAIfsTypes = array(
-        "swap" => _("Swap"),
-        "ext2" => _("Ext 2"),
-        "ext3" => _("Ext 3"),
-        "ext4" => _("Ext 4"),
-        "reiserfs" => _("Reiser fs"),
-        "xfs" => _("Xfs"),
-        "btrfs" => _("Btrfs"));
+        "swap" => _("swap space"),
+        "ext2" => _("ext2"),
+        "ext3" => _("ext3"),
+        "ext4" => _("ext4"),
+        "reiserfs" => _("reiser fs"),
+        "xfs" => _("xfs"),
+        "btrfs" => _("btrfs"),
+        "-" => "-");
+
     $smarty->assign("partitionTypes", $types);
     $smarty->assign("partitionSizeTypes", $partitionSizeTypes);
     $smarty->assign("FAIpartitionSizeType", $this->FAIpartitionSizeType);
@@ -141,6 +217,12 @@ class faiPartition extends plugin
     $smarty->assign("preserveType", $this->preserveType);
 
     $smarty->assign("FAIfsTypes", $FAIfsTypes);
+    $smarty->assign("cn", $this->cn);
+    $smarty->assign("freeze", preg_match("/freeze/i",$this->parent->FAIstate));
+
+    $smarty->assign("plist",$this->getRaidlist());
+    $smarty->assign("physicalPartitionList",$this->getPartitionlist());
+    $smarty->assign("disablePrimary", $this->disablePrimary);
 
     foreach($this->attributes as $attr){
       $smarty->assign($attr,$this->$attr);
@@ -148,6 +230,94 @@ class faiPartition extends plugin
     return($smarty->fetch(get_template_path("faiPartition.tpl", TRUE, dirname(__FILE__))));
   }
 
+  
+  /* Returns a list of all partitions that are useable 
+   *  for raid arrays.
+   */
+  function getPartitionList()
+  {
+    $may = $used = array();  
+    foreach($this->parent->parent->disks as $disk){
+
+      // Skip ourselves 
+      if($disk['cn'] == $this->parent->DISKcn) continue;
+
+      // Add partition from lvm combinations 
+      if($disk['FAIdiskType'] == "lvm"){
+        $used = array_merge($used,$disk['FAIlvmDevice']);
+      }
+
+      foreach($disk['partitions'] as $key => $part){
+
+        // Add disks of raid arrays, to the used list.
+        if($disk['FAIdiskType'] == "raid"){
+          foreach(explode(",",$part['FAIpartitionSize']) as $rDevice){
+            $used[] = preg_replace("/:.*$/i","",$rDevice);
+          }
+        }
+
+        // Collect all available disks 
+        if($disk['FAIdiskType'] == "disk"){
+          $name = $part['cn'];
+          if(!isset($this->raidDevices[$name])){
+            $may[] = $name;
+          }
+        }
+      }
+    }
+    // Check which of the available disks are unused. 
+    $ret = array();
+    foreach($may as $val){
+      if(!in_array($val,$used)){
+        $ret[$val] = $val;
+      }
+    }
+    return($ret);
+  }
+
+
+  /* Creates a human readable list of all used partitions 
+   *  of a raid device.
+   */
+  function getRaidList()
+  {
+    $divlist = new divSelectBox("RaidList");
+    $disks = $this->parent->parent->disks;
+    $objs = array();
+    foreach($disks as $disk){
+      if($disk['FAIdiskType'] != "raid"){
+        foreach($disk['partitions'] as $id => $part){
+          $objs[$part['cn']] = $part;
+        }
+      }
+    }
+  
+    $list = array();
+    foreach($this->raidDevices as $device){
+      $str = $name = $device['name'];
+      $str = str_pad($str,25," ");
+      if(isset($objs[$device['name']]['FAIpartitionSize'])){
+        $str .= _("Size").": ";
+        $str .= $objs[$device['name']]['FAIpartitionSize'];
+      }
+      $str = str_pad($str,60," ");
+      $opt = "";
+      if($device['spare']){
+        $opt.= " "._("spare")." ";
+      }
+      if($device['missing']){
+        $opt.= " "._("missing")." ";
+      }
+      if($opt){
+        $str .= "   "._("Options").": ".$opt;
+      }
+      $str = str_pad($str,80," ");
+      $list[$name] = preg_replace("/ /"," ",$str);
+    }
+    return($list);
+  }
+
   function save_object()
   {
     if(isset($_POST['faiPartition'])){
@@ -168,9 +338,87 @@ class faiPartition extends plugin
           $this->$attr = FALSE;
         }
       }
+
+      // Allow user defined partition names for lvm disks.
+      if($this->FAIdiskType == "lvm" && isset($_POST['cn'])){
+        $this->cn = get_post('cn');
+      }
+
+      // Remove partition
+      if(isset($_POST['delPhysicalPartition']) && isset($_POST['physicalPartition'])){
+        foreach($_POST['physicalPartition'] as $key){
+          if(isset($this->raidDevices[$key])){
+            unset($this->raidDevices[$key]);
+          }
+        }
+      }
+
+      // Toggle spare flag for partition entries
+      if(isset($_POST['toggleSpare']) && isset($_POST['physicalPartition'])){
+        $this->raidDevices[$_POST['physicalPartition']]['spare'] = 
+            !$this->raidDevices[$_POST['physicalPartition']]['spare'];
+      }
+
+      // Toggle missing flag for partition entries
+      if(isset($_POST['toggleMissing']) && isset($_POST['physicalPartition'])){
+        $this->raidDevices[$_POST['physicalPartition']]['missing'] = 
+            !$this->raidDevices[$_POST['physicalPartition']]['missing'];
+      }
     } 
   }
 
+
+  function check()
+  {
+    $msgs = plugin::check();
+    
+    // Check the given partition size.
+    if($this->FAIdiskType == "disk" || $this->FAIdiskType == "lvm"){
+      if($this->FAIpartitionSizeType == "fixed" || $this->FAIpartitionSizeType == "dynamic"){ 
+        if(!is_numeric($this->sizeStart)){
+          $msgs[] = msgPool::invalid(_("Partition size"),$this->sizeStart,"/[0-9]/i");
+        }
+      }
+      if($this->FAIpartitionSizeType == "dynamic"){ 
+        if(!is_numeric($this->sizeStop)){
+          $msgs[] = msgPool::invalid(_("Partition size"),$this->sizeStop,"/[0-9]/i");
+        }
+
+        $mp = array(
+                    "%"  => 1,
+                    "KB" => pow(1024,0),
+                    "MB" => pow(1024,1),
+                    "GB" => pow(1024,2),
+                    "TB" => pow(1024,3),
+                    "PB" => pow(1024,4));
+        $res1 = $this->sizeStart * $mp[$this->sizeStart_Type];
+        $res2 = $this->sizeStop * $mp[$this->sizeStop_Type];
+        if($res1 > $res2){
+          $msgs[] = msgPool::toobig(_("Minimum partition size"), "'"._("Maximum partition size")."'");
+        }
+      }
+    }
+
+    // Add raid checks
+    if($this->FAIdiskType == "raid"){
+      if(count($this->raidDevices) < 2){
+        $msgs[] = _("Raid arrays must contain at least two partitions!");
+      }else if($this->FAIpartitionType == "raid0" && count($this->raidDevices) != 2){
+        $msgs[] = _("Raid 0 arrays can only be realized with a combination of two partitions!");
+      }
+    }
+
+    // check mount point 
+    if($this->FAIfsType != "swap" && $this->FAIfsType != "-"){
+      if(!preg_match("#^/#",$this->FAImountPoint)){
+        $msgs[] = msgPool::invalid(_("Mount point"));
+      }
+    }
+
+    return($msgs);
+  }
+
+
   function save()
   {
     $ret = array();
@@ -178,18 +426,45 @@ class faiPartition extends plugin
       $ret[$attr] = $this->$attr;
     }
 
-    // Save partition size 
-    switch($this->FAIpartitionSizeType){
-      case 'fixed' : 
-        $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type;break; 
-      case 'dynamic' : 
-        $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type."-".  
-          $this->sizeStop.$this->sizeStop_Type;break; 
-      case 'remaining' : 
-        $ret['FAIpartitionSize'] = "-";break; 
-      default: trigger_error("Unknown partition size!");
+    // Save partition size
+    if($this->FAIdiskType == "disk" || $this->FAIdiskType == "lvm"){ 
+      switch($this->FAIpartitionSizeType){
+        case 'fixed' : 
+          $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type;break; 
+        case 'dynamic' : 
+          $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type."-".  
+            $this->sizeStop.$this->sizeStop_Type;break; 
+        case 'remaining' : 
+          $ret['FAIpartitionSize'] = "0-";break; 
+        default: trigger_error("Unknown partition size!");
+      }
+
+      // Add encryption flag to partition mount point
+      if($this->encrypted){
+        $ret['FAImountPoint'] .= ":encrypt";
+      }
+
+    }elseif($this->FAIdiskType == "raid"){
+
+      // Save selected raid partitions in FAIpartitionSize
+      $ret['FAIpartitionSize'] = "";
+      foreach($this->raidDevices as $device){
+        $ret['FAIpartitionSize'] .= $device['name'];
+        if($device['spare']){
+          $ret['FAIpartitionSize'] .= ":spare";
+        }
+        if($device['missing']){
+          $ret['FAIpartitionSize'] .= ":missing";
+        }
+        $ret['FAIpartitionSize'] .= ",";
+      }
+      $ret['FAIpartitionSize'] = trim($ret['FAIpartitionSize'],",");
     }
 
+    if($this->FAIfsType == "swap"){
+      $ret['FAImountPoint'] = "swap";
+    }
     return($ret);
   }
 }