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 $raidDevices = array();
42 // Once we've exceeded the primary partition limit,
43 // hide the the 'primary' option from the select box.
44 var $disablePrimary = FALSE;
46 function __construct($config, $object, $parent,$type)
47 {
49 $this->parent = $parent;
50 $this->FAIdiskType = $type;
52 // Check if we should be able to add primary partitions.
53 if(!$object || $object['FAIpartitionType'] == "logical"){
54 if($this->FAIdiskType == "disk"){
55 $types = array('logical' => array(), 'primary' => array());
56 foreach($this->parent->partitions as $key => $part){
57 $types[$part['FAIpartitionType']][$part['FAIpartitionNr']] = 1;
58 }
59 if(count($types['logical']) && count($types['primary']) >= 3){
60 $this->disablePrimary = TRUE;
61 }elseif(count($types['logical']) >= 4){
62 $this->disablePrimary = TRUE;
63 }
64 }
65 }
67 // Load attributes from existing partition
68 if($object){
69 foreach($this->attributes as $attr){
70 if(isset($object[$attr])){
71 $this->$attr = $object[$attr];
72 }
73 }
75 if($type == "disk" || $type =="lvm"){
77 /* Prepare size attribute
78 * This attribute may represent a range, a fixed value
79 * or a percentage.
80 * fixed is just a number * 500MB
81 * range * 500MB-1TB
82 * remaining * -
83 */
84 // Fixed
85 if(preg_match("/^[0-9]{1,}(KB|MB|GB|TB|PB|%|)$/",$this->FAIpartitionSize)){
86 $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\1",$this->FAIpartitionSize);
87 $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\2",$this->FAIpartitionSize);
88 $this->FAIpartitionSizeType = "fixed";
89 }else
91 // Dynamic range
92 if(preg_match("/^[0-9]{1,}(KB|MB|GB|TB|PB|%|)-[0-9]{1,}(KB|MB|GB|TB|PB|%|)$/",$this->FAIpartitionSize)){
93 $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%).*$/","\\1",$this->FAIpartitionSize);
94 $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%).*$/","\\2",$this->FAIpartitionSize);
95 $this->sizeStop = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\1",$this->FAIpartitionSize);
96 $this->sizeStop_Type = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\2",$this->FAIpartitionSize);
97 $this->FAIpartitionSizeType = "dynamic";
98 }else
100 // Dynamic range
101 if(preg_match("/^(0|)\-$/",$this->FAIpartitionSize)){
102 $this->FAIpartitionSizeType = "remaining";
103 }
105 // Ensure that we've a valid value type selected.
106 if(!preg_match("/(KB|MB|GB|TB|PB|%)/",$this->sizeStart_Type)){
107 $this->sizeStart_Type = "MB";
108 }
109 if(!preg_match("/(KB|MB|GB|TB|PB|%)/",$this->sizeStop_Type)){
110 $this->sizeStop_Type = "MB";
111 }
113 /* Check for encrypted partitions
114 */
115 if(preg_match("/:encrypt$/",$this->FAImountPoint)){
116 $this->FAImountPoint = preg_replace("/:encrypt/","",$this->FAImountPoint);
117 $this->encrypted = TRUE;
118 }
120 }elseif($type == "raid"){
122 // Extract raid devices out of the partition size attribute.
123 $usedDisks = explode(",",$this->FAIpartitionSize);
124 foreach($usedDisks as $disk){
125 $name = preg_replace("/:.*$/","",$disk);
126 $spare = preg_match("/:spare/",$disk);
127 $missing = preg_match("/:missing/",$disk);
128 if(!empty($name)){
129 $this->raidDevices[$name] =
130 array(
131 "name" => $name,
132 "spare" => $spare,
133 "missing" => $missing);
134 }
135 }
136 }
137 }
138 }
140 function execute()
141 {
142 plugin::execute();
143 $smarty = get_smarty();
145 // Remove partition
146 if(isset($_POST['addPhysicalPartition']) && isset($_POST['physicalPartitionAdd'])){
147 $name = $_POST['physicalPartitionAdd'];
148 $this->raidDevices[$name] = array("name" => $name,"spare"=>false,"missing"=>false);
149 }
151 // Create a list of selectable partition types
152 if($this->FAIdiskType == "disk"){
154 if($this->disablePrimary){
155 $types = array(
156 "logical" => _("Logical"));
157 }else{
158 $types = array(
159 "primary" => _("Primary"),
160 "logical" => _("Logical"));
161 }
163 }elseif($this->FAIdiskType == "raid"){
164 $types = array(
165 "raid0" => _("RAID 0"),
166 "raid1" => _("RAID 1"),
167 "raid5" => _("RAID 5"),
168 "raid6" => _("RAID 6"));
169 }else{
170 $types = "";
171 }
173 // Create a list of all size options
174 $partitionSizeTypes = array(
175 "fixed" => _("fixed"),
176 "dynamic" => _("dynamic"),
177 "remaining" => _("remaining space")
178 );
180 // Create a list of all size options
181 $sizeTypes = array(
182 "KB" => _("KB"),
183 "MB" => _("MB"),
184 "GB" => _("GB"),
185 "TB" => _("TB"),
186 "PB" => _("PB"),
187 "%" => _("%")
188 );
190 // Preserve types
191 $preserveTypes = array(
192 "always" => _("always"),
193 "reinstall" => _("reinstall"));
195 // File system types.
196 $FAIfsTypes = array(
197 "swap" => _("swap space"),
198 "ext2" => _("ext2"),
199 "ext3" => _("ext3"),
200 "ext4" => _("ext4"),
201 "reiserfs" => _("reiser fs"),
202 "xfs" => _("xfs"),
203 "btrfs" => _("btrfs"),
204 "-" => "-");
206 $smarty->assign("partitionTypes", $types);
207 $smarty->assign("partitionSizeTypes", $partitionSizeTypes);
208 $smarty->assign("FAIpartitionSizeType", $this->FAIpartitionSizeType);
209 $smarty->assign("sizeTypes", $sizeTypes);
211 $smarty->assign("sizeStart_Type", $this->sizeStart_Type);
212 $smarty->assign("sizeStop_Type", $this->sizeStop_Type);
213 $smarty->assign("sizeStart", $this->sizeStart);
214 $smarty->assign("sizeStop", $this->sizeStop);
216 $smarty->assign("preserveTypes", $preserveTypes);
217 $smarty->assign("preserveType", $this->preserveType);
219 $smarty->assign("FAIfsTypes", $FAIfsTypes);
220 $smarty->assign("cn", $this->cn);
221 $smarty->assign("freeze", preg_match("/freeze/i",$this->parent->FAIstate));
223 $smarty->assign("plist",$this->getRaidlist());
224 $smarty->assign("physicalPartitionList",$this->getPartitionlist());
225 $smarty->assign("disablePrimary", $this->disablePrimary);
227 foreach($this->attributes as $attr){
228 $smarty->assign($attr,$this->$attr);
229 }
230 return($smarty->fetch(get_template_path("faiPartition.tpl", TRUE, dirname(__FILE__))));
231 }
234 /* Returns a list of all partitions that are useable
235 * for raid arrays.
236 */
237 function getPartitionList()
238 {
239 $may = $used = array();
240 foreach($this->parent->parent->disks as $disk){
242 // Skip ourselves
243 if($disk['cn'] == $this->parent->DISKcn) continue;
245 // Add partition from lvm combinations
246 if($disk['FAIdiskType'] == "lvm"){
247 $used = array_merge($used,$disk['FAIlvmDevice']);
248 }
250 foreach($disk['partitions'] as $key => $part){
252 // Add disks of raid arrays, to the used list.
253 if($disk['FAIdiskType'] == "raid"){
254 foreach(explode(",",$part['FAIpartitionSize']) as $rDevice){
255 $used[] = preg_replace("/:.*$/i","",$rDevice);
256 }
257 }
259 // Collect all available disks
260 if($disk['FAIdiskType'] == "disk"){
261 $name = $part['cn'];
262 if(!isset($this->raidDevices[$name])){
263 $may[] = $name;
264 }
265 }
266 }
267 }
269 // Check which of the available disks are unused.
270 $ret = array();
271 foreach($may as $val){
272 if(!in_array($val,$used)){
273 $ret[$val] = $val;
274 }
275 }
276 return($ret);
277 }
280 /* Creates a human readable list of all used partitions
281 * of a raid device.
282 */
283 function getRaidList()
284 {
285 $divlist = new divSelectBox("RaidList");
286 $disks = $this->parent->parent->disks;
287 $objs = array();
288 foreach($disks as $disk){
289 if($disk['FAIdiskType'] != "raid"){
290 foreach($disk['partitions'] as $id => $part){
291 $objs[$part['cn']] = $part;
292 }
293 }
294 }
296 $list = array();
297 foreach($this->raidDevices as $device){
298 $str = $name = $device['name'];
299 $str = str_pad($str,25," ");
300 if(isset($objs[$device['name']]['FAIpartitionSize'])){
301 $str .= _("Size").": ";
302 $str .= $objs[$device['name']]['FAIpartitionSize'];
303 }
304 $str = str_pad($str,60," ");
305 $opt = "";
306 if($device['spare']){
307 $opt.= " "._("spare")." ";
308 }
309 if($device['missing']){
310 $opt.= " "._("missing")." ";
311 }
312 if($opt){
313 $str .= " "._("Options").": ".$opt;
314 }
315 $str = str_pad($str,80," ");
316 $list[$name] = preg_replace("/ /"," ",$str);
317 }
318 return($list);
319 }
321 function save_object()
322 {
323 if(isset($_POST['faiPartition'])){
324 foreach($this->attributes as $attr){
325 if(isset($_POST[$attr])){
326 $this->$attr = get_post($attr);
327 }
328 }
329 foreach(array("FAIpartitionSizeType","sizeStart","sizeStop","sizeStart_Type","sizeStop_Type") as $attr){
330 if(isset($_POST[$attr])){
331 $this->$attr = get_post($attr);
332 }
333 }
334 foreach(array("bootable","preserve","resize","encrypted") as $attr){
335 if(isset($_POST[$attr])){
336 $this->$attr = TRUE;
337 }else{
338 $this->$attr = FALSE;
339 }
340 }
342 // Allow user defined partition names for lvm disks.
343 if($this->FAIdiskType == "lvm" && isset($_POST['cn'])){
344 $this->cn = get_post('cn');
345 }
347 // Remove partition
348 if(isset($_POST['delPhysicalPartition']) && isset($_POST['physicalPartition'])){
349 foreach($_POST['physicalPartition'] as $key){
350 if(isset($this->raidDevices[$key])){
351 unset($this->raidDevices[$key]);
352 }
353 }
354 }
356 // Toggle spare flag for partition entries
357 if(isset($_POST['toggleSpare']) && isset($_POST['physicalPartition'])){
358 $this->raidDevices[$_POST['physicalPartition'][0]]['spare'] =
359 !$this->raidDevices[$_POST['physicalPartition'][0]]['spare'];
360 }
362 // Toggle missing flag for partition entries
363 if(isset($_POST['toggleMissing']) && isset($_POST['physicalPartition'])){
364 $this->raidDevices[$_POST['physicalPartition'][0]]['missing'] =
365 !$this->raidDevices[$_POST['physicalPartition'][0]]['missing'];
366 }
367 }
368 }
371 function check()
372 {
373 $msgs = plugin::check();
375 // Check the given partition size.
376 if($this->FAIdiskType == "disk" || $this->FAIdiskType == "lvm"){
377 if($this->FAIpartitionSizeType == "fixed" || $this->FAIpartitionSizeType == "dynamic"){
378 if(!is_numeric($this->sizeStart)){
379 $msgs[] = msgPool::invalid(_("Partition size"),$this->sizeStart,"/[0-9]/i");
380 }
381 }
382 if($this->FAIpartitionSizeType == "dynamic"){
383 if(!is_numeric($this->sizeStop)){
384 $msgs[] = msgPool::invalid(_("Partition size"),$this->sizeStop,"/[0-9]/i");
385 }
387 $mp = array(
388 "%" => 1,
389 "KB" => pow(1024,0),
390 "MB" => pow(1024,1),
391 "GB" => pow(1024,2),
392 "TB" => pow(1024,3),
393 "PB" => pow(1024,4));
394 $res1 = $this->sizeStart * $mp[$this->sizeStart_Type];
395 $res2 = $this->sizeStop * $mp[$this->sizeStop_Type];
396 if($res1 > $res2){
397 $msgs[] = msgPool::toobig(_("Minimum partition size"), "'"._("Maximum partition size")."'");
398 }
399 }
400 }
402 // Add raid checks
403 if($this->FAIdiskType == "raid"){
404 if(count($this->raidDevices) < 2){
405 $msgs[] = _("Raid arrays must contain at least two partitions!");
406 }else if($this->FAIpartitionType == "raid0" && count($this->raidDevices) != 2){
407 $msgs[] = _("Raid 0 arrays can only be realized with a combination of two partitions!");
408 }
409 }
411 // check mount point
412 if($this->FAIfsType != "swap" && $this->FAIfsType != "-"){
413 if(!preg_match("#^/#",$this->FAImountPoint)){
414 $msgs[] = msgPool::invalid(_("Mount point"));
415 }
416 }
418 return($msgs);
419 }
422 function save()
423 {
424 $ret = array();
425 foreach($this->attributes as $attr){
426 $ret[$attr] = $this->$attr;
427 }
429 // Save partition size
430 if($this->FAIdiskType == "disk" || $this->FAIdiskType == "lvm"){
431 switch($this->FAIpartitionSizeType){
432 case 'fixed' :
433 $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type;break;
434 case 'dynamic' :
435 $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type."-".
436 $this->sizeStop.$this->sizeStop_Type;break;
437 case 'remaining' :
438 $ret['FAIpartitionSize'] = "0-";break;
439 default: trigger_error("Unknown partition size!");
440 }
442 // Add encryption flag to partition mount point
443 if($this->encrypted){
444 $ret['FAImountPoint'] .= ":encrypt";
445 }
447 }elseif($this->FAIdiskType == "raid"){
449 // Save selected raid partitions in FAIpartitionSize
450 $ret['FAIpartitionSize'] = "";
451 foreach($this->raidDevices as $device){
452 $ret['FAIpartitionSize'] .= $device['name'];
453 if($device['spare']){
454 $ret['FAIpartitionSize'] .= ":spare";
455 }
456 if($device['missing']){
457 $ret['FAIpartitionSize'] .= ":missing";
458 }
459 $ret['FAIpartitionSize'] .= ",";
460 }
461 $ret['FAIpartitionSize'] = trim($ret['FAIpartitionSize'],",");
462 }
464 if($this->FAIfsType == "swap"){
465 $ret['FAImountPoint'] = "swap";
466 }
468 return($ret);
469 }
470 }
471 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
472 ?>