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 = "";
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";
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 }
124 }elseif($type == "raid"){
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 }
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 }
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 }
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 }
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").": ";
308 $str .= $objs[$device['name']]['FAIpartitionSize'];
309 }
310 $str = str_pad($str,60," ");
311 $opt = "";
312 if($device['spare']){
313 $opt.= " "._("spare")." ";
314 }
315 if($device['missing']){
316 $opt.= " "._("missing")." ";
317 }
318 if($opt){
319 $str .= " "._("Options").": ".$opt;
320 }
321 $str = str_pad($str,80," ");
322 $list[$name] = preg_replace("/ /"," ",$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();
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 }
475 return($ret);
476 }
477 }
478 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
479 ?>