Code

Updated FAI partition handling.
[gosa.git] / gosa-plugins / fai / admin / fai / class_faiPartition.inc
1 <?php
3 class faiPartition extends plugin
4 {
5   var $attributes = array("cn","description","FAIfsCreateOptions","FAIfsOptions","FAIfsTuneOptions",
6       "FAIfsType","FAImountOptions","FAImountPoint","FAIpartitionNr","FAIpartitionFlags","FAIdiskType",
7       "FAIpartitionSize","FAIpartitionType","FAIstate", "bootable","resize", "preserve", "preserveType",
8       "encrypted");
10   var $cn  = "";
11   var $description  = "";
12   var $FAIfsCreateOptions = "";
13   var $FAIfsOptions = "";
14   var $FAIfsTuneOptions = "";
15   var $FAIfsType = "";
16   var $FAImountOptions = "";
17   var $FAImountPoint = "";
18   var $FAIpartitionNr = "undefined"; // Initial value for new partitions
19   var $FAIpartitionSize = "";
20   var $FAIpartitionType = "";
21   var $FAIstate = "";
22   var $FAIpartitionFlags = "";
23   
24   var $FAIdiskType = "disk";
26   // Size options.
27   var $FAIpartitionSizeType = "fixed";
28   var $sizeStart = 0;
29   var $sizeStop  = 0;
30   var $sizeStart_Type = "MB";
31   var $sizeStop_Type  = "MB";
32   
33   //  Flags 
34   var $bootable = false; 
35   var $resize = false;
36   var $encrypted = false;
37   var $preserve = false;
38   var $preserveType = "always";
40   var $status = "";
41   var $raidDevices = array();
43   // Once we've exceeded the primary partition limit,
44   //  hide the the 'primary' option from the select box.
45   var $disablePrimary = FALSE; 
47   function __construct($config, $object, $parent,$type)
48   {
50     $this->parent = $parent;
51     $this->status = "new";
52     $this->FAIdiskType = $type;
54     // Check if we should be able to add primary partitions.
55     if(!$object || $object['FAIpartitionType'] == "logical"){
56       if($this->FAIdiskType == "disk"){
57         $types = array('logical' => array(), 'primary' => array());
58         foreach($this->parent->partitions as $key => $part){
59           $types[$part['FAIpartitionType']][$part['FAIpartitionNr']] = 1;
60         }
61         if(count($types['logical']) && count($types['primary']) >= 3){
62           $this->disablePrimary = TRUE;
63         }elseif(count($types['logical']) >= 4){
64           $this->disablePrimary = TRUE;
65         }
66       } 
67     } 
69     // Load attributes from existing partition 
70     if($object){
71       foreach($this->attributes as $attr){
72         if(isset($object[$attr])){
73           $this->$attr = $object[$attr];
74         }
75       }
77       $this->status = $object['status'];
79       if($type == "disk" || $type =="lvm"){
81         /* Prepare size attribute 
82          * This attribute may represent a range, a fixed value 
83          *  or a percentage.
84          * fixed is just a number   * 500MB
85          * range                    * 500MB-1TB
86          * remaining                * -
87          */
88         // Fixed
89         if(preg_match("/^[0-9]{1,}(KB|MB|GB|TB|PB|%|)$/",$this->FAIpartitionSize)){
90           $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\1",$this->FAIpartitionSize);
91           $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\2",$this->FAIpartitionSize);
92           $this->FAIpartitionSizeType = "fixed";
93         }else
95         // Dynamic range
96         if(preg_match("/^[0-9]{1,}(KB|MB|GB|TB|PB|%|)-[0-9]{1,}(KB|MB|GB|TB|PB|%|)$/",$this->FAIpartitionSize)){
97           $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%).*$/","\\1",$this->FAIpartitionSize);
98           $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%).*$/","\\2",$this->FAIpartitionSize);
99           $this->sizeStop = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\1",$this->FAIpartitionSize);
100           $this->sizeStop_Type = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\2",$this->FAIpartitionSize);
101           $this->FAIpartitionSizeType = "dynamic";
102         }else
104         // Dynamic range
105         if(preg_match("/^(0|)\-$/",$this->FAIpartitionSize)){
106           $this->FAIpartitionSizeType = "remaining";
107         }
109         // Ensure that we've a valid value type selected.
110         if(!preg_match("/(KB|MB|GB|TB|PB|%)/",$this->sizeStart_Type)){
111           $this->sizeStart_Type = "MB";
112         }
113         if(!preg_match("/(KB|MB|GB|TB|PB|%)/",$this->sizeStop_Type)){
114           $this->sizeStop_Type = "MB";
115         }
117         /* Check for encrypted partitions
118          */
119         if(preg_match("/:encrypt$/",$this->FAImountPoint)){
120           $this->FAImountPoint = preg_replace("/:encrypt/","",$this->FAImountPoint);
121           $this->encrypted = TRUE;
122         }
123     
124       }elseif($type == "raid"){
125    
126         // Extract raid devices out of the partition size attribute. 
127         $usedDisks = split(",",$this->FAIpartitionSize);
128         foreach($usedDisks as $disk){
129           $name = preg_replace("/:.*$/","",$disk);
130           $spare = preg_match("/:spare/",$disk);
131           $missing = preg_match("/:missing/",$disk);
132           if(!empty($name)){
133             $this->raidDevices[$name] = 
134               array(
135                   "name" => $name, 
136                   "spare" => $spare, 
137                   "missing" => $missing);
138           }
139         }
140       }
141     }
142   }
144   function execute()
145   {
146     plugin::execute();
147     $smarty = get_smarty();
149     // Remove partition
150     if(isset($_POST['addPhysicalPartition']) && isset($_POST['physicalPartitionAdd'])){
151       $name = $_POST['physicalPartitionAdd'];
152       $this->raidDevices[$name] = array("name" => $name,"spare"=>false,"missing"=>false);     
153     }
155     // Create a list of selectable partition types
156     if($this->FAIdiskType == "disk"){
158       if($this->disablePrimary){
159         $types  = array(
160             "logical" => _("Logical"));
161       }else{
162         $types  = array(
163             "primary" => _("Primary"),
164             "logical" => _("Logical"));
165       }
167     }elseif($this->FAIdiskType == "raid"){
168       $types  = array(
169           "raid0" => _("RAID 0"),
170           "raid1" => _("RAID 1"),
171           "raid5" => _("RAID 5"),
172           "raid6" => _("RAID 6"));
173     }else{
174       $types = "";
175     }
176      
177     // Create a list of all size options
178     $partitionSizeTypes  = array(
179         "fixed"     => _("fixed"),
180         "dynamic"     => _("dynamic"),
181         "remaining" => _("remaining space")
182         );
184     // Create a list of all size options
185     $sizeTypes  = array(
186         "KB"      => _("KB"),
187         "MB"      => _("MB"),
188         "GB"      => _("GB"),
189         "TB"      => _("TB"),
190         "PB"      => _("PB"),
191         "%"      => _("%")
192         );
194     // Preserve types 
195     $preserveTypes = array(
196         "always" => _("always"),
197         "reinstall" => _("reinstall"));
199     // File system types.  
200     $FAIfsTypes = array(
201         "swap" => _("swap space"),
202         "ext2" => _("ext2"),
203         "ext3" => _("ext3"),
204         "ext4" => _("ext4"),
205         "reiserfs" => _("reiser fs"),
206         "xfs" => _("xfs"),
207         "btrfs" => _("btrfs"));
209     $smarty->assign("partitionTypes", $types);
210     $smarty->assign("partitionSizeTypes", $partitionSizeTypes);
211     $smarty->assign("FAIpartitionSizeType", $this->FAIpartitionSizeType);
212     $smarty->assign("sizeTypes", $sizeTypes);
214     $smarty->assign("sizeStart_Type", $this->sizeStart_Type);
215     $smarty->assign("sizeStop_Type", $this->sizeStop_Type);
216     $smarty->assign("sizeStart", $this->sizeStart);
217     $smarty->assign("sizeStop", $this->sizeStop);
219     $smarty->assign("preserveTypes", $preserveTypes);
220     $smarty->assign("preserveType", $this->preserveType);
222     $smarty->assign("FAIfsTypes", $FAIfsTypes);
223     $smarty->assign("cn", $this->cn);
224     $smarty->assign("freeze", preg_match("/freeze/i",$this->parent->FAIstate));
226     $smarty->assign("plist",$this->getRaidlist());
227     $smarty->assign("physicalPartitionList",$this->getPartitionlist());
228     $smarty->assign("disablePrimary", $this->disablePrimary);
230     foreach($this->attributes as $attr){
231       $smarty->assign($attr,$this->$attr);
232     }
233     return($smarty->fetch(get_template_path("faiPartition.tpl", TRUE, dirname(__FILE__))));
234   }
236   
237   /* Returns a list of all partitions that are useable 
238    *  for raid arrays.
239    */
240   function getPartitionList()
241   {
242     $may = $used = array();  
243     foreach($this->parent->parent->disks as $disk){
245       // Skip ourselves 
246       if($disk['cn'] == $this->parent->DISKcn) continue;
247       if($disk['status'] == "delete") continue;
249       // Add partition from lvm combinations 
250       if($disk['FAIdiskType'] == "lvm"){
251         $used = array_merge($used,$disk['FAIlvmDevice']);
252       }
254       foreach($disk['partitions'] as $key => $part){
256         if($part['status'] == "delete") continue;
258         // Add disks of raid arrays, to the used list.
259         if($disk['FAIdiskType'] == "raid"){
260           foreach(split(",",$part['FAIpartitionSize']) as $rDevice){
261             $used[] = preg_replace("/:.*$/i","",$rDevice);
262           }
263         }
265         // Collect all available disks 
266         if($disk['FAIdiskType'] == "disk"){
267           $name = $part['cn'];
268           if(!isset($this->raidDevices[$name])){
269             $may[] = $name;
270           }
271         }
272       }
273     }
274  
275     // Check which of the available disks are unused. 
276     $ret = array();
277     foreach($may as $val){
278       if(!in_array($val,$used)){
279         $ret[$val] = $val;
280       }
281     }
282     return($ret);
283   }
286   /* Creates a human readable list of all used partitions 
287    *  of a raid device.
288    */
289   function getRaidList()
290   {
291     $divlist = new divSelectBox("RaidList");
292     $disks = $this->parent->parent->disks;
293     $objs = array();
294     foreach($disks as $disk){
295       if($disk['FAIdiskType'] != "raid"){
296         foreach($disk['partitions'] as $id => $part){
297           $objs[$part['cn']] = $part;
298         }
299       }
300     }
301   
302     $list = array();
303     foreach($this->raidDevices as $device){
304       $str = $name = $device['name'];
305       $str = str_pad($str,25," ");
306       if(isset($objs[$device['name']]['FAIpartitionSize'])){
307         $str .= _("Size").":&nbsp;";
308         $str .= $objs[$device['name']]['FAIpartitionSize'];
309       }
310       $str = str_pad($str,60," ");
311       $opt = "";
312       if($device['spare']){
313         $opt.= "&nbsp;"._("spare")."&nbsp;";
314       }
315       if($device['missing']){
316         $opt.= "&nbsp;"._("missing")."&nbsp;";
317       }
318       if($opt){
319         $str .= " &nbsp; "._("Options").": ".$opt;
320       }
321       $str = str_pad($str,80," ");
322       $list[$name] = preg_replace("/ /","&nbsp;",$str);
323     }
324     return($list);
325   }
327   function save_object()
328   {
329     if(isset($_POST['faiPartition'])){
330       foreach($this->attributes as $attr){
331         if(isset($_POST[$attr])){
332           $this->$attr = get_post($attr);
333         }
334       }
335       foreach(array("FAIpartitionSizeType","sizeStart","sizeStop","sizeStart_Type","sizeStop_Type") as $attr){
336         if(isset($_POST[$attr])){
337           $this->$attr = get_post($attr);
338         }
339       }
340       foreach(array("bootable","preserve","resize","encrypted") as $attr){
341         if(isset($_POST[$attr])){
342           $this->$attr = TRUE;
343         }else{
344           $this->$attr = FALSE;
345         }
346       }
348       // Allow user defined partition names for lvm disks.
349       if($this->FAIdiskType == "lvm" && isset($_POST['cn'])){
350         $this->cn = get_post('cn');
351       }
353       // Remove partition
354       if(isset($_POST['delPhysicalPartition']) && isset($_POST['physicalPartition'])){
355         foreach($_POST['physicalPartition'] as $key){
356           if(isset($this->raidDevices[$key])){
357             unset($this->raidDevices[$key]);
358           }
359         }
360       }
362       // Toggle spare flag for partition entries
363       if(isset($_POST['toggleSpare']) && isset($_POST['physicalPartition'])){
364         $this->raidDevices[$_POST['physicalPartition']]['spare'] = 
365             !$this->raidDevices[$_POST['physicalPartition']]['spare'];
366       }
368       // Toggle missing flag for partition entries
369       if(isset($_POST['toggleMissing']) && isset($_POST['physicalPartition'])){
370         $this->raidDevices[$_POST['physicalPartition']]['missing'] = 
371             !$this->raidDevices[$_POST['physicalPartition']]['missing'];
372       }
373     } 
374   }
377   function check()
378   {
379     $msgs = plugin::check();
380     
381     // Check the given partition size.
382     if($this->FAIdiskType == "disk" || $this->FAIdiskType == "lvm"){
383       if($this->FAIpartitionSizeType == "fixed" || $this->FAIpartitionSizeType == "dynamic"){ 
384         if(!is_numeric($this->sizeStart)){
385           $msgs[] = msgPool::invalid(_("Partition size"),$this->sizeStart,"/[0-9]/i");
386         }
387       }
388       if($this->FAIpartitionSizeType == "dynamic"){ 
389         if(!is_numeric($this->sizeStop)){
390           $msgs[] = msgPool::invalid(_("Partition size"),$this->sizeStop,"/[0-9]/i");
391         }
393         $mp = array(
394                     "%"  => 1,
395                     "KB" => pow(1024,0),
396                     "MB" => pow(1024,1),
397                     "GB" => pow(1024,2),
398                     "TB" => pow(1024,3),
399                     "PB" => pow(1024,4));
400         $res1 = $this->sizeStart * $mp[$this->sizeStart_Type];
401         $res2 = $this->sizeStop * $mp[$this->sizeStop_Type];
402         if($res1 > $res2){
403           $msgs[] = msgPool::toobig(_("Minimum partition size"), "'"._("Maximum partition size")."'");
404         }
405       }
406     }
408     // Add raid checks
409     if($this->FAIdiskType == "raid"){
410       if(count($this->raidDevices) < 2){
411         $msgs[] = _("Raid arrays must contain at least two partitions!");
412       }else if($this->FAIpartitionType == "raid0" && count($this->raidDevices) != 2){
413         $msgs[] = _("Raid 0 arrays can only be realized with a combination of two partitions!");
414       }
415     }
417     // check mount point 
418     if($this->FAIfsType != "swap"){
419       if(!preg_match("#^/#",$this->FAImountPoint)){
420         $msgs[] = msgPool::invalid(_("Mount point"));
421       }
422     }
424     return($msgs);
425   }
428   function save()
429   {
430     $ret = array();
431     foreach($this->attributes as $attr){
432       $ret[$attr] = $this->$attr;
433     }
435     // Save partition size
436     if($this->FAIdiskType == "disk" || $this->FAIdiskType == "lvm"){ 
437       switch($this->FAIpartitionSizeType){
438         case 'fixed' : 
439           $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type;break; 
440         case 'dynamic' : 
441           $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type."-".  
442             $this->sizeStop.$this->sizeStop_Type;break; 
443         case 'remaining' : 
444           $ret['FAIpartitionSize'] = "0-";break; 
445         default: trigger_error("Unknown partition size!");
446       }
448       // Add encryption flag to partition mount point
449       if($this->encrypted){
450         $ret['FAImountPoint'] .= ":encrypt";
451       }
453     }elseif($this->FAIdiskType == "raid"){
455       // Save selected raid partitions in FAIpartitionSize
456       $ret['FAIpartitionSize'] = "";
457       foreach($this->raidDevices as $device){
458         $ret['FAIpartitionSize'] .= $device['name'];
459         if($device['spare']){
460           $ret['FAIpartitionSize'] .= ":spare";
461         }
462         if($device['missing']){
463           $ret['FAIpartitionSize'] .= ":missing";
464         }
465         $ret['FAIpartitionSize'] .= ",";
466       }
467       $ret['FAIpartitionSize'] = trim($ret['FAIpartitionSize'],",");
468     }
469     $ret['status'] = $this->status;
471     if($this->FAIfsType == "swap"){
472       $ret['FAImountPoint'] = "swap";
473     }
474  
475     return($ret);
476   }
478 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
479 ?>