1 <?php
3 class faiDiskEntry extends plugin
4 {
5 /* attribute list for save action */
6 var $ignore_account= TRUE;
7 var $attributes = array("DISKcn","DISKdescription");
8 var $objectclasses= array();
10 var $DISKcn = "";
11 var $DISKdescription = "";
12 var $DISKFAIdiskOptions = "";
14 var $partitions = array();
15 var $UsedAttrs = array();
16 var $is_edit = false;
17 var $old_cn = "";
18 var $status = "new";
19 var $deletePartitions = array();
20 var $fstabkey = "device";
21 var $disklabel = "msdos";
23 var $FAIstate = "";
24 var $FAIdiskType = "disk";
26 function faiDiskEntry (&$config, $dn= NULL,$parent,$disk,$type)
27 {
28 plugin::plugin ($config, $dn);
30 $this->parent = $parent;
32 $this->UsedAttrs = array("cn","description","FAIpartitionType",
33 "FAIpartitionNr","FAIfsType","FAImountPoint","FAIpartitionSize","FAIfsTuneOptions",
34 "FAIfsCreateOptions",
35 "FAImountOptions","FAIfsOptions","FAIpartitionFlags","FAIdiskOption");
37 /* Set disk type */
38 $this->FAIdiskType = $type;
40 /* Default status is new */
41 $this->status = "new";
43 /* We want to edit an entry */
44 if($disk){
46 /* Set disk status */
47 $this->status = $disk['status'];
49 /* Walk through partitions */
50 foreach($disk['partitions'] as $name => $values){
52 /* If a partition is already marked as delete, attach it to deletePartitions only. */
53 if($values['status'] == "delete"){
54 unset($disk['partitions'][$name]);
55 $this->deletePartitions[]=$values;
56 }else{
58 /* Set status, to know which partition must be deleted from ldap
59 new : Neu partition entry // save
60 edited : Update partition entry in ldap
61 deleted: Remove partition from ldap
62 */
64 /* If status is not new, set to edit mode.
65 * New means that this partition currently wasn't saved to ldap.
66 */
67 if($disk['partitions'][$name]['status']!="new"){
68 $disk['partitions'][$name]['status']="edited";
69 }
71 $disk['partitions'][$name]['old_cn']= $disk['partitions'][$name]['cn'];
72 $disk['partitions'][$name]['FAIdiskType']= $this->FAIdiskType;
74 /* Assign empty attributes, if attribute is missing */
75 foreach($this->UsedAttrs as $attr){
76 if(!isset($values[$attr])){
77 $disk['partitions'][$name][$attr]="";
78 }
79 }
81 if (preg_match('/^_/', $disk['partitions'][$name]['FAIfsType'])){
82 $disk['partitions'][$name]['FAIfsType']= preg_replace('/^_/', '', $disk['partitions'][$name]['FAIfsType']);
83 }
84 }
85 }
87 /* Set default attributes */
88 $this->DISKcn = $disk['cn'];
89 $this->DISKdescription = $disk['description'];
90 $this->partitions = $disk['partitions'];
91 $this->is_edit = true;
92 $this->old_cn = $disk['cn'];
94 /* Move faiDiskOption */
95 if (isset($disk['FAIdiskOption'])){
96 foreach($disk['FAIdiskOption'] as $option) {
97 if (preg_match("/fstabkey:(device|label|uuid)/", $option)){
98 $this->fstabkey= preg_replace("/^.*fstabkey:(device|label|uuid).*$/", "$1", $option);
99 continue;
100 }
101 if (preg_match("/disklabel:(msdos|gpt)/", $option)){
102 $this->disklabel= preg_replace("/^.*disklabel:(msdos|gpt).*$/", "$1", $option);
103 continue;
104 }
105 if (preg_match("/^bootable:/", $option)){
106 $bootable = split(",", trim(preg_replace("/^bootable:/","",$option),","));
107 foreach($bootable as $bootflag){
108 $this->partitions[$bootflag]['bootable'] = TRUE;
109 }
110 continue;
111 }
112 if (preg_match("/^resize:/", $option)){
113 $resize = split(",", trim(preg_replace("/^resize:/","",$option),","));
114 foreach($resize as $id){
115 $this->partitions[$id]['resize'] = TRUE;
116 }
117 continue;
118 }
119 if (preg_match("/^preserve_always:/", $option)){
120 $preserve = split(",", trim(preg_replace("/^preserve_always:/","",$option),","));
121 foreach($preserve as $presflag){
122 $this->partitions[$presflag]['preserve'] = TRUE;
123 $this->partitions[$presflag]['preserveType'] = 'always';
124 }
125 continue;
126 }
127 if (preg_match("/^preserve_reinstall:/", $option)){
128 $preserve = split(",", trim(preg_replace("/^preserve_reinstall:/","",$option),","));
129 foreach($preserve as $presflag){
130 $this->partitions[$presflag]['preserve'] = TRUE;
131 $this->partitions[$presflag]['preserveType'] = 'reinstall';
132 }
133 continue;
134 }
135 }
136 } else {
137 $this->fstabkey= "device";
138 }
139 }
140 }
143 function execute()
144 {
145 /* Call parent execute */
146 plugin::execute();
148 /* Fill templating stuff */
149 $smarty = get_smarty();
150 $s_action = "";
151 $s_entry = "";
152 $display = "";
154 /* Load parameters */
155 if (isset($_POST['disklabel']) && preg_match("/^(msdos|gpt)$/", $_POST['disklabel'])){
156 $this->disklabel= $_POST['disklabel'];
157 }
158 if (isset($_POST['fstabkey']) && preg_match("/^(device|label|uuid)$/", $_POST['fstabkey'])){
159 $this->fstabkey= $_POST['fstabkey'];
160 }
162 /* Assign values
163 * And Checkbox selection
164 */
165 foreach($this->attributes as $attrs){
166 $smarty->assign($attrs,$this->$attrs);
167 if($this->$attrs){
168 $smarty->assign($attrs."CHK"," ");
169 }else{
170 $smarty->assign($attrs."CHK"," disabled ");
171 }
172 }
174 /* Check all Posts if there is something usefull for us,
175 * For example : Delete is posted as Delete_1
176 * The number specifies the index we want to delete
177 */
178 foreach($_POST as $name => $value){
179 if((preg_match("/Delete_.*/",$name)) &&
180 $this->acl_is_removeable() &&
181 !preg_match("/freeze/i",$this->FAIstate)){
182 $tmp = split("_",$name);
183 $s_action = "remove";
184 $s_entry = $tmp[1];
185 }
186 }
188 /* To remove a partition we unset the index posted.
189 * We must sort the index again, else we possibly got problems
190 * with partitions order.
191 */
192 if($s_action == "remove" && $this->acl_is_removeable() &&
193 !preg_match("/freeze/i",$this->FAIstate)){
194 if($this->partitions[$s_entry]['status'] == "edited"){
195 $this->deletePartitions[$s_entry]= $this->partitions[$s_entry];
196 $this->deletePartitions[$s_entry]['FAIpartitionNr']=$s_entry;
197 unset($this->partitions[$s_entry]);
198 }else{
199 unset($this->partitions[$s_entry]);
200 }
201 $tmp= array();
202 foreach($this->partitions as $part){
203 $tmp[count($tmp)+1]=$part;
204 }
205 $this->partitions = $tmp;
206 }
209 /* Add / Edit partitions here.
210 */
211 foreach($_POST as $name => $value){
212 if(preg_match("/^EditPartition_/",$name)){
213 $id = preg_replace("/^EditPartition_/","",$name);
214 $id = preg_replace("/_.*$/","",$id);
215 if(isset($this->partitions[$id])){
216 $this->dialog = new faiPartition($this->config,$this->partitions[$id], $this,$this->FAIdiskType);
217 break;
218 }
219 }
220 }
221 if(isset($_POST['AddPartition']) && !preg_match("/freeze/i",$this->FAIstate)){
222 $this->dialog = new faiPartition($this->config, array(), $this,$this->FAIdiskType);
223 }
224 if($this->dialog instanceOf plugin && isset($_POST['PartitionCancel'])){
225 $this->dialog = null;
226 }
227 if($this->dialog instanceOf plugin && isset($_POST['PartitionSave'])){
228 $this->dialog->save_object();
229 $attrs = $this->dialog->save();
230 if(isset($attrs['FAIpartitionNr'])){
231 $this->partitions[$attrs['FAIpartitionNr']] = $attrs;
232 }else{
233 $this->partitions[] = $attrs;
234 }
235 $this->dialog = null;
236 }
237 if($this->dialog instanceOf plugin){
238 $this->dialog->save_object();
239 return($this->dialog->execute());
240 }
243 /* $setup contains a table with the partitions.
244 */
245 $smarty->assign("setup", $this->generateParts());
246 foreach($this->attributes as $attr){
247 $smarty->assign($attr,$this->$attr);
248 }
250 $tmp = $this->plInfo();
251 $sacl = "";
252 foreach($tmp['plProvidedAcls'] as $name => $translated){
253 $acl = $this->getacl($name, preg_match("/freeze/i",$this->FAIstate));
254 $smarty->assign($name."ACL",$acl);
255 }
257 $smarty->assign("sub_object_is_createable",$this->acl_is_createable());
258 $smarty->assign("freeze",preg_match("/freeze/i",$this->FAIstate));
260 // Fill boxes
261 $smarty->assign("fstabkeys", array("device" => _("Device"), "label" => _("Label"), "uuid" => _("UUID")));
262 $smarty->assign("disklabels", array("msdos" => "MSDOS", "gpt" => "GPT"));
263 $smarty->assign("fstabkey", $this->fstabkey);
264 $smarty->assign("disklabel", $this->disklabel);
266 /* Fetch template and show the result
267 */
268 $display.= $smarty->fetch(get_template_path('faiDiskEntry.tpl', TRUE));
269 return($display);
270 }
272 function generateParts()
273 {
275 $divlist = new divSelectBox("DiskEntries");
276 foreach($this->partitions as $key => $part){
277 $number =array(
278 "string" => $part['FAIpartitionNr'],
279 "attach" => "style='width:20px;'");
280 $size =array(
281 "string" => $part['FAIpartitionSize'],
282 "attach" => "style='width:100px;'");
283 $fstype =array(
284 "string" => $part['FAIfsType'],
285 "attach" => "style='width:60px;'");
286 $type =array(
287 "string" => $part['FAIpartitionType'],
288 "attach" => "style='width:80px;'");
289 $opt =array(
290 "string" => $part['FAImountOptions'],
291 "attach" => "style='width:80px;'");
292 $fsopt =array(
293 "string" => $part['FAIfsOptions'],
294 "attach" => "style='width:80px;'");
295 $flags =array(
296 "string" => $part['FAIpartitionFlags'],
297 "attach" => "style='width:80px;'");
298 $mntp =array("string" => $part['FAImountPoint']);
301 $action =array(
302 "string" => "<input type='image' src='images/lists/edit.png' name='EditPartition_".$key."'>",
303 "attach" => "style='width:40px;'");
306 $fields = array($number,$type,$mntp,$size,$fstype, $opt,$fsopt,$flags,$action);
307 $divlist->AddEntry($fields);
308 }
309 return($divlist->DrawList());
310 }
312 function save()
313 {
314 $tmp = array();
315 $tmp['cn'] = $this->DISKcn;
317 /* Attach partitions */
318 foreach($this->partitions as $key=>$val) {
319 $this->partitions[$key]['FAIpartitionNr']=$key;
320 }
322 /* Attach deleted */
323 foreach($this->deletePartitions as $key=>$val) {
324 $this->partitions[$key."-delete"]=$val;
325 $this->partitions[$key."-delete"]['status']="delete";
326 }
328 $tmp['description'] = $this->DISKdescription;
329 $tmp['partitions'] = $this->partitions;
330 $tmp['status'] = $this->status;
331 $tmp['FAIdiskType'] = $this->FAIdiskType;
333 /* Assemble flags */
334 $tmp['FAIdiskOption'] = array("fstabkey:".$this->fstabkey, "disklabel:".$this->disklabel);
336 /* If hdd name has changed, tell partitionTable to rename it */
337 if(($this->is_edit)&&($this->old_cn != $this->DISKcn)){
338 $tmp['rename']['from'] = $this->old_cn;
339 $tmp['rename']['to'] = $this->DISKcn;
340 }
342 // Build up disk options
343 $bootable = "";
344 $resize = "";
345 $preserve_always = "";
346 $preserve_reinstall = "";
348 foreach($tmp['partitions'] as $id => $part){
349 if(isset($part['bootable']) && $part['bootable']){
350 $bootable .= $id.",";
351 }
352 if(isset($part['resize']) && $part['resize']){
353 $resize .= $id.",";
354 }
355 if(isset($part['preserve']) && $part['preserve']){
356 if($part['preserveType'] == "always"){
357 $preserve_always .= $id.",";
358 }else{
359 $preserve_reinstall .= $id.",";
360 }
361 }
362 $tmp['partitions'][$id]['status'] = $part['status'];
364 // Unset non valid attributes
365 foreach(array("bootable","encrypted","preserve","preserveType","resize","FAIdiskType") as $attr){
366 if(isset($tmp['partitions'][$id][$attr])){
367 unset($tmp['partitions'][$id][$attr]);
368 }
369 }
370 }
372 if(!empty($bootable)){
373 $tmp['FAIdiskOption'][] = "bootable:".trim($bootable,",");
374 }
375 if(!empty($resize)){
376 $tmp['FAIdiskOption'][] = "resize:".trim($resize,",");
377 }
378 if(!empty($preserve_always)){
379 $tmp['FAIdiskOption'][] = "preserve_always:".trim($preserve_always,",");
380 }
381 if(!empty($preserve_reinstall)){
382 $tmp['FAIdiskOption'][] = "preserve_reinstall:".trim($preserve_reinstall,",");
383 }
385 $tmp['status'] = $this->status;
386 return($tmp);
387 }
390 /* Save data to object */
391 function save_object()
392 {
393 if((isset($_POST['TableEntryFrameSubmitted'])) && !preg_match("/freeze/", $this->FAIstate) ){
394 plugin::save_object();
395 }
396 }
399 /* Check supplied data */
400 function check()
401 {
402 /* Call common method to give check the hook */
403 $message= plugin::check();
405 /* Check for an empty disk name */
406 $d = trim($this->DISKcn);
407 if($d == "" ){
408 $message[] = msgPool::required(_("Name"));
409 }
410 if(preg_match("/[^a-z0-9_\-]/i",$d)){
411 $message[] = msgPool::invalid(_("Name"),$d,"/[a-z0-9_\-]/i");
412 }
414 /* check every partition.
415 * if there is an invalid value defined, append an errorstr to message
416 */
418 /* Array that contain every partitionname mountpoint etc already assigned */
419 $alreadyUsed = array();
420 foreach($this->UsedAttrs as $attrs){
421 $alreadyUsed[$attrs] = array();
422 }
424 foreach($this->partitions as $key => $part){
426 /* Skip all checks, if preserve is set */
427 if($part['FAIpartitionFlags'] == "preserve"){
428 $this->partitions[$key]['FAIfsType'] = "preserve";
429 $this->partitions[$key]['FAIpartitionSize'] = "preserve";
430 continue;
431 }
433 if($part['FAImountPoint'] != "-" && (in_array($part['FAImountPoint'],$alreadyUsed['FAImountPoint']))&&($part['FAIfsType']!="swap")){
434 $message[]=sprintf(_("Please enter a unique mount point for partition %s"),($key));
435 }
437 if($part['FAIfsType']!="swap" && $part['FAImountPoint'] != "-"){
438 if((empty($part['FAImountPoint']))||(!((preg_match("/^\/.*/",$part['FAImountPoint']))||(preg_match("/^swap$/",$part['FAImountPoint']))))){
439 $message[]= msgPool::invalid(sprintf(_("partition %s mount point"),$key));
440 }
441 }
442 if($part['FAIfsType'] == "swap"){
443 if(in_array($part['FAIfsType'],$alreadyUsed['FAIfsType'])){
444 $message[]=sprintf(_("File system type 'swap' is already used, change file system type for partition %s."),$key);
445 }
446 }
447 if(($part['FAIfsType'] == "swap")&&(!empty($part['FAImountPoint']))&&($part['FAImountPoint']!="swap")){
448 $message[]=_("Please use 'swap' as mount point, if 'swap' is used as fs-type.");
449 }
451 $tmp = split("-",$part['FAIpartitionSize']);
452 switch (count($tmp)){
453 case 0:
454 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
455 break;
456 case 1:
457 if (!tests::is_id($tmp[0]) &&(!empty($tmp[1]))){
458 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
459 }
460 break;
462 case 2:
463 if( !tests::is_id($tmp[0]) && !tests::is_id($tmp[1]) && !empty($tmp[1]) ){
464 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
465 }elseif(!empty($tmp[1]) && $tmp[0]>=$tmp[1]){
466 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
467 }
468 break;
470 default:
471 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
472 }
474 foreach($this->UsedAttrs as $attrs){
475 if(isset($part[$attrs])){
476 $alreadyUsed[$attrs][$key] = $part[$attrs];
477 }
478 }
479 }
481 $cnt = 0;
482 foreach($this->partitions as $key => $part){
483 if($part['FAIpartitionType'] == "primary"){
484 $cnt ++ ;
485 }
486 }
487 if($cnt > 3){
488 $message[] = _("You have more than 3 primary partition table entries in your configuration, please check your configuration twice.");
489 }
491 return ($message);
492 }
496 /* Return plugin informations for acl handling */
497 static function plInfo()
498 {
499 return (array(
500 "plShortName" => _("Partition table entry"),
501 "plDescription" => _("FAI partition table entry"),
502 "plSelfModify" => FALSE,
503 "plDepends" => array(),
504 "plPriority" => 27,
505 "plSection" => array("administration"),
506 "plCategory" => array("fai"),
507 "plProvidedAcls" => array(
508 "DISKcn" => _("Name"),
509 "DISKdescription" => _("Description"),
510 "DISKFAIdiskOption" => _("Disk options"),
511 "FAIpartitionType" => _("Partition type"),
512 "FAIpartitionNr" => _("Partition no."),
513 "FAIfsType" => _("File system type"),
514 "FAImountPoint" => _("Mount point"),
515 "FAIpartitionSize" => _("Partition size"),
516 "FAImountOptions" => _("Mount options"),
517 "FAIfsOptions" => _("File system options"),
518 "FAIpartitionFlags" => _("Partition flags"))
519 ));
520 }
523 }
525 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
526 ?>