006bc35ee2d126de3a23236f26dde1ddbff0a949
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->initTime = microtime(TRUE);
50 $this->parent = $parent;
51 $this->FAIdiskType = $type;
53 // Check if we should be able to add primary partitions.
54 if(!$object || $object['FAIpartitionType'] == "logical"){
55 if($this->FAIdiskType == "disk"){
56 $types = array('logical' => array(), 'primary' => array());
57 foreach($this->parent->partitions as $key => $part){
58 $types[$part['FAIpartitionType']][$part['FAIpartitionNr']] = 1;
59 }
60 if(count($types['logical']) && count($types['primary']) >= 3){
61 $this->disablePrimary = TRUE;
62 }elseif(count($types['logical']) >= 4){
63 $this->disablePrimary = TRUE;
64 }
65 }
66 }
68 // Load attributes from existing partition
69 if($object){
70 foreach($this->attributes as $attr){
71 if(isset($object[$attr])){
72 $this->$attr = $object[$attr];
73 }
74 }
76 if($type == "disk" || $type =="lvm"){
78 /* Prepare size attribute
79 * This attribute may represent a range, a fixed value
80 * or a percentage.
81 * fixed is just a number * 500MB
82 * range * 500MB-1TB
83 * remaining * -
84 */
85 // Fixed
86 if(preg_match("/^[0-9]{1,}(KB|MB|GB|TB|PB|%|)$/",$this->FAIpartitionSize)){
87 $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\1",$this->FAIpartitionSize);
88 $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\2",$this->FAIpartitionSize);
89 $this->FAIpartitionSizeType = "fixed";
90 }else
92 // Dynamic range
93 if(preg_match("/^[0-9]{1,}(KB|MB|GB|TB|PB|%|)-[0-9]{1,}(KB|MB|GB|TB|PB|%|)$/",$this->FAIpartitionSize)){
94 $this->sizeStart = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%).*$/","\\1",$this->FAIpartitionSize);
95 $this->sizeStart_Type = preg_replace("/^([0-9]*)(KB|MB|GB|TB|PB|%).*$/","\\2",$this->FAIpartitionSize);
96 $this->sizeStop = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\1",$this->FAIpartitionSize);
97 $this->sizeStop_Type = preg_replace("/^[^\-]*\-([0-9]*)(KB|MB|GB|TB|PB|%)$/","\\2",$this->FAIpartitionSize);
98 $this->FAIpartitionSizeType = "dynamic";
99 }else
101 // Dynamic range
102 if(preg_match("/^(0|)\-$/",$this->FAIpartitionSize)){
103 $this->FAIpartitionSizeType = "remaining";
104 }
106 // Ensure that we've a valid value type selected.
107 if(!preg_match("/(KB|MB|GB|TB|PB|%)/",$this->sizeStart_Type)){
108 $this->sizeStart_Type = "MB";
109 }
110 if(!preg_match("/(KB|MB|GB|TB|PB|%)/",$this->sizeStop_Type)){
111 $this->sizeStop_Type = "MB";
112 }
114 /* Check for encrypted partitions
115 */
116 if(preg_match("/:encrypt$/",$this->FAImountPoint)){
117 $this->FAImountPoint = preg_replace("/:encrypt/","",$this->FAImountPoint);
118 $this->encrypted = TRUE;
119 }
121 }elseif($type == "raid"){
123 // Extract raid devices out of the partition size attribute.
124 $usedDisks = explode(",",$this->FAIpartitionSize);
125 foreach($usedDisks as $disk){
126 $name = preg_replace("/:.*$/","",$disk);
127 $spare = preg_match("/:spare/",$disk);
128 $missing = preg_match("/:missing/",$disk);
129 if(!empty($name)){
130 $this->raidDevices[$name] =
131 array(
132 "name" => $name,
133 "spare" => $spare,
134 "missing" => $missing);
135 }
136 }
137 }
138 }
140 // Create statistic table entry
141 stats::log('plugin', $class = get_class($this), $category = array($this->acl_category), $action = 'open',
142 $amount = 1, $duration = (microtime(TRUE) - $this->initTime));
144 }
146 function execute()
147 {
148 plugin::execute();
149 $smarty = get_smarty();
151 // Remove partition
152 if(isset($_POST['addPhysicalPartition']) && isset($_POST['physicalPartitionAdd'])){
153 $name =get_post('physicalPartitionAdd');
154 $this->raidDevices[$name] = array("name" => $name,"spare"=>false,"missing"=>false);
155 }
157 // Create a list of selectable partition types
158 if($this->FAIdiskType == "disk"){
160 if($this->disablePrimary){
161 $types = array(
162 "logical" => _("Logical"));
163 }else{
164 $types = array(
165 "primary" => _("Primary"),
166 "logical" => _("Logical"));
167 }
169 }elseif($this->FAIdiskType == "raid"){
170 $types = array(
171 "raid0" => _("RAID 0"),
172 "raid1" => _("RAID 1"),
173 "raid5" => _("RAID 5"),
174 "raid6" => _("RAID 6"));
175 }else{
176 $types = "";
177 }
179 // Create a list of all size options
180 $partitionSizeTypes = array(
181 "fixed" => _("fixed"),
182 "dynamic" => _("dynamic"),
183 "remaining" => _("remaining space")
184 );
186 // Create a list of all size options
187 $sizeTypes = array(
188 "KB" => _("KB"),
189 "MB" => _("MB"),
190 "GB" => _("GB"),
191 "TB" => _("TB"),
192 "PB" => _("PB"),
193 "%" => _("%")
194 );
196 // Preserve types
197 $preserveTypes = array(
198 "always" => _("always"),
199 "reinstall" => _("reinstall"));
201 // File system types.
202 $FAIfsTypes = array(
203 "swap" => _("swap space"),
204 "ext2" => "ext2",
205 "ext3" => "ext3",
206 "ext4" => "ext4",
207 "reiserfs" => "reiser fs",
208 "xfs" => "xfs",
209 "btrfs" => "btrfs",
210 "-" => "-");
212 $smarty->assign("partitionTypes", $types);
213 $smarty->assign("partitionSizeTypes", $partitionSizeTypes);
214 $smarty->assign("FAIpartitionSizeType", $this->FAIpartitionSizeType);
215 $smarty->assign("sizeTypes", $sizeTypes);
217 $smarty->assign("sizeStart_Type", $this->sizeStart_Type);
218 $smarty->assign("sizeStop_Type", $this->sizeStop_Type);
219 $smarty->assign("sizeStart", set_post($this->sizeStart));
220 $smarty->assign("sizeStop", set_post($this->sizeStop));
222 $smarty->assign("preserveTypes", $preserveTypes);
223 $smarty->assign("preserveType", set_post($this->preserveType));
225 $smarty->assign("FAIfsTypes", $FAIfsTypes);
226 $smarty->assign("cn", $this->cn);
227 $smarty->assign("freeze", preg_match("/freeze/i",$this->parent->FAIstate));
229 $smarty->assign("plist",$this->getRaidlist());
230 $smarty->assign("physicalPartitionList",$this->getPartitionlist());
231 $smarty->assign("disablePrimary", $this->disablePrimary);
233 foreach($this->attributes as $attr){
234 $smarty->assign($attr,set_post($this->$attr));
235 }
236 return($smarty->fetch(get_template_path("faiPartition.tpl", TRUE, dirname(__FILE__))));
237 }
240 /* Returns a list of all partitions that are useable
241 * for raid arrays.
242 */
243 function getPartitionList()
244 {
245 $may = $used = array();
246 foreach($this->parent->parent->disks as $disk){
248 // Skip ourselves
249 if($disk['cn'] == $this->parent->DISKcn) continue;
251 // Add partition from lvm combinations
252 if($disk['FAIdiskType'] == "lvm"){
253 $used = array_merge($used,$disk['FAIlvmDevice']);
254 }
256 foreach($disk['partitions'] as $key => $part){
258 // Add disks of raid arrays, to the used list.
259 if($disk['FAIdiskType'] == "raid"){
260 foreach(explode(",",$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 $disks = $this->parent->parent->disks;
292 $objs = array();
293 foreach($disks as $disk){
294 if($disk['FAIdiskType'] != "raid"){
295 foreach($disk['partitions'] as $id => $part){
296 $objs[$part['cn']] = $part;
297 }
298 }
299 }
301 $list = array();
302 foreach($this->raidDevices as $device){
303 $str = $name = $device['name'];
304 $str = str_pad($str,25," ");
305 if(isset($objs[$device['name']]['FAIpartitionSize'])){
306 $str .= _("Size").": ";
307 $str .= $objs[$device['name']]['FAIpartitionSize'];
308 }
309 $str = str_pad($str,60," ");
310 $opt = "";
311 if($device['spare']){
312 $opt.= " "._("spare")." ";
313 }
314 if($device['missing']){
315 $opt.= " "._("missing")." ";
316 }
317 if($opt){
318 $str .= " "._("Options").": ".$opt;
319 }
320 $str = str_pad($str,80," ");
321 $list[$name] = preg_replace("/ /"," ",$str);
322 }
323 return($list);
324 }
326 function save_object()
327 {
328 if(isset($_POST['faiPartition'])){
329 foreach($this->attributes as $attr){
330 if(isset($_POST[$attr])){
331 $this->$attr = get_post($attr);
332 }
333 }
334 foreach(array("FAIpartitionSizeType","sizeStart","sizeStop","sizeStart_Type","sizeStop_Type") as $attr){
335 if(isset($_POST[$attr])){
336 $this->$attr = get_post($attr);
337 }
338 }
339 foreach(array("bootable","preserve","resize","encrypted") as $attr){
340 if(isset($_POST[$attr])){
341 $this->$attr = TRUE;
342 }else{
343 $this->$attr = FALSE;
344 }
345 }
347 // Allow user defined partition names for lvm disks.
348 if($this->FAIdiskType == "lvm" && isset($_POST['cn'])){
349 $this->cn = get_post('cn');
350 }
352 // Remove partition
353 if(isset($_POST['delPhysicalPartition']) && isset($_POST['physicalPartition'])){
354 foreach($_POST['physicalPartition'] as $key){
355 if(isset($this->raidDevices[$key])){
356 unset($this->raidDevices[$key]);
357 }
358 }
359 }
361 // Toggle spare flag for partition entries
362 if(isset($_POST['toggleSpare']) && isset($_POST['physicalPartition'])){
363 $this->raidDevices[$_POST['physicalPartition'][0]]['spare'] =
364 !$this->raidDevices[$_POST['physicalPartition'][0]]['spare'];
365 }
367 // Toggle missing flag for partition entries
368 if(isset($_POST['toggleMissing']) && isset($_POST['physicalPartition'])){
369 $this->raidDevices[$_POST['physicalPartition'][0]]['missing'] =
370 !$this->raidDevices[$_POST['physicalPartition'][0]]['missing'];
371 }
372 }
373 }
376 function check()
377 {
378 $msgs = plugin::check();
380 // Check the given partition size.
381 if($this->FAIdiskType == "disk" || $this->FAIdiskType == "lvm"){
382 if($this->FAIpartitionSizeType == "fixed" || $this->FAIpartitionSizeType == "dynamic"){
383 if(!is_numeric($this->sizeStart)){
384 $msgs[] = msgPool::invalid(_("Partition size"),$this->sizeStart,"/[0-9]/i");
385 }
386 }
387 if($this->FAIpartitionSizeType == "dynamic"){
388 if(!is_numeric($this->sizeStop)){
389 $msgs[] = msgPool::invalid(_("Partition size"),$this->sizeStop,"/[0-9]/i");
390 }
392 $mp = array(
393 "%" => 1,
394 "KB" => pow(1024,0),
395 "MB" => pow(1024,1),
396 "GB" => pow(1024,2),
397 "TB" => pow(1024,3),
398 "PB" => pow(1024,4));
399 $res1 = $this->sizeStart * $mp[$this->sizeStart_Type];
400 $res2 = $this->sizeStop * $mp[$this->sizeStop_Type];
401 if($res1 > $res2){
402 $msgs[] = msgPool::toobig(_("Minimum partition size"), "'"._("Maximum partition size")."'");
403 }
404 }
405 }
407 // Add raid checks
408 if($this->FAIdiskType == "raid"){
409 if(count($this->raidDevices) < 2){
410 $msgs[] = _("Raid arrays must contain at least two partitions!");
411 }else if($this->FAIpartitionType == "raid0" && count($this->raidDevices) != 2){
412 $msgs[] = _("Raid 0 arrays can only be realized with a combination of two partitions!");
413 }
414 }
416 // check mount point
417 if($this->FAIfsType != "swap" && $this->FAIfsType != "-"){
418 if(!preg_match("#^/#",$this->FAImountPoint)){
419 $msgs[] = msgPool::invalid(_("Mount point"));
420 }
421 }
423 return($msgs);
424 }
427 function save()
428 {
429 $ret = array();
430 foreach($this->attributes as $attr){
431 $ret[$attr] = $this->$attr;
432 }
434 // Save partition size
435 if($this->FAIdiskType == "disk" || $this->FAIdiskType == "lvm"){
436 switch($this->FAIpartitionSizeType){
437 case 'fixed' :
438 $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type;break;
439 case 'dynamic' :
440 $ret['FAIpartitionSize'] = $this->sizeStart.$this->sizeStart_Type."-".
441 $this->sizeStop.$this->sizeStop_Type;break;
442 case 'remaining' :
443 $ret['FAIpartitionSize'] = "0-";break;
444 default: trigger_error("Unknown partition size!");
445 }
447 // Add encryption flag to partition mount point
448 if($this->encrypted){
449 $ret['FAImountPoint'] .= ":encrypt";
450 }
452 }elseif($this->FAIdiskType == "raid"){
454 // Save selected raid partitions in FAIpartitionSize
455 $ret['FAIpartitionSize'] = "";
456 foreach($this->raidDevices as $device){
457 $ret['FAIpartitionSize'] .= $device['name'];
458 if($device['spare']){
459 $ret['FAIpartitionSize'] .= ":spare";
460 }
461 if($device['missing']){
462 $ret['FAIpartitionSize'] .= ":missing";
463 }
464 $ret['FAIpartitionSize'] .= ",";
465 }
466 $ret['FAIpartitionSize'] = trim($ret['FAIpartitionSize'],",");
467 }
469 if($this->FAIfsType == "swap"){
470 $ret['FAImountPoint'] = "swap";
471 }
473 return($ret);
474 }
475 }
476 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
477 ?>