Code

Updated FAI object detection.
[gosa.git] / gosa-plugins / fai / admin / fai / class_faiPartitionTable.inc
1 <?php
3 class faiPartitionTable extends plugin
4 {
5   /* attribute list for save action */
6   var $ignore_account   = TRUE;
7   var $attributes       = array("cn","description");
8   var $objectclasses    = array("top","FAIclass","FAIpartitionTable");
10   var $subAttributes      = array("cn","description");
11   var $subPartAttributes  = array("cn","FAIpartitionNr","FAIpartitionSize","FAImountPoint","FAIfsType","FAIpartitionType","FAImountOptions","FAIfsOptions","FAIpartitionFlags","description");
13   var $sub64coded = array();
14   var $subBinary = array();
16   /* Specific attributes */
17   var $cn               = "";       // The class name for this object
18   var $description      = "";       // The description for this set of partitions
19   var $disks            = array();  // All defined Disks 
20   var $is_dialog        = false;    // specifies which buttons will be shown to save or abort
22   var $FAIstate         = "";
23   var $ui;
25   var $view_logged      = FALSE;
27   function faiPartitionTable (&$config, $dn= NULL)
28   {
29     /* Load Attributes */
30     plugin::plugin ($config, $dn);
32     /* If "dn==new" we try to create a new entry
33      * Else we must read all objects from ldap which belong to this entry.
34      */
35     $this->ui = get_userinfo();
36     if($dn != "new"){
37       $this->dn =$dn;
39       /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
40        */
41       $res = FAI::get_all_objects_for_given_base($this->dn,"(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))");
42       foreach($res as $obj){
44         /* Skip not relevant objects */
45         if(!preg_match("/".normalizePreg($this->dn)."$/i",$obj['dn'])) continue;
47         $objects = array();
48         $objects['description']  = "";
49         $objects['status']      = "edited";
50         $objects['dn']          = $obj['dn'];
51         $objects                = $this->get_object_attributes($objects,$this->subAttributes);
52         $this->disks[$objects['cn']] = $objects;
53         $this->disks[$objects['cn']]['partitions'] = array();
54       }
56       /* read all partitions for each disk 
57        */
58       foreach($this->disks as $name => $disk){
59         $res = FAI::get_all_objects_for_given_base($disk['dn'],"(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))");
60         foreach($res as $obj){
62           /* Skip not relevant objects */
63           if(!preg_match("/".normalizePreg($disk['dn'])."$/i",$obj['dn'])) continue;
65           $objects = array();
66           $objects['status']      = "edited";
67           $objects['dn']          = $obj['dn'];
68           $objects                = $this->get_object_attributes($objects,$this->subPartAttributes);
69           unset($objects['dn']);;
70           $this->disks[$name]['partitions'][$objects['FAIpartitionNr']] = $objects;
71         }
72       }
73     }
75     $this->is_new = FALSE;
76     if($this->dn == "new"){
77       $this->is_new =TRUE;
78     }
79     ksort($this->disks);
80   }
83   function acl_base_for_current_object($dn)
84   {
85     if($dn == "new"){
86       if($this->dn == "new"){
87         $dn = session::get('CurrentMainBase');
88       }else{
89         $dn = $this->dn;
90       }
91     }
92     return($dn);
93   }
96   function execute()
97   {
98     /* Call parent execute */
99     plugin::execute();
101     if($this->is_account && !$this->view_logged){
102       $this->view_logged = TRUE;
103       new log("view","fai/".get_class($this),$this->dn);
104     }
106     /* Fill templating stuff */
107     $smarty= get_smarty();
108     $display= "";
109  
110     /* Add Disk to this Partitionset
111      * This code adds a new HDD to the disks 
112      * A new Dialog will be opened 
113      */
114     if(isset($_POST['AddDisk']) && !preg_match("/freeze/i",$this->FAIstate)){
115       $usedDiskNames =array();
116       foreach($this->disks as $key=>$disk){
117         $usedDiskNames[]= $key;
118       }
119       $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames); 
120       $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
121       $this->dialog->set_acl_category("fai");
122       $this->dialog->FAIstate = $this->FAIstate;
123       $this->is_dialog = true;
124     }
126     /* Edit disk.
127      * Open dialog which allows us to edit the selected entry 
128      */    
130     if($this->dn != "new"){
131       session::set('objectinfo',$this->dn);
132     }
134     if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
135       $usedDiskNames =array();
136       $Udisk = $_POST['disks'][0];
137       if(isset($this->disks[$Udisk])){
139         foreach($this->disks  as $key=>$disk){
140           if($key != $Udisk){
141             $usedDiskNames[]= $key;
142           }
143         }
145         /* Set object info string, which will be displayed in plugin info line */ 
146         if(isset($this->disks[$Udisk]['dn'])){
147           session::set('objectinfo',$this->disks[$Udisk]['dn']);
148           $dn = $this->disks[$Udisk]['dn'];
149         }else{
150           session::set('objectinfo',"");
151           $dn = "new";
152         }
154         $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]); 
155         $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
156         $this->dialog->set_acl_category("fai");
157         $this->dialog->FAIstate = $this->FAIstate;
159         $this->is_dialog = true;
160       }
161     }
163     /* Edit aborted, close dialog, without saving anything
164      */
165     if(isset($_POST['CancelDisk'])){
166       unset($this->dialog);
167       $this->dialog = FALSE;
168       $this->is_dialog=false;
169     }
171     /* Dialog saved
172      * Save given data from Dialog, if no error is occurred
173      */
174     if(isset($_POST['SaveDisk'])){
176       if (!preg_match("/freeze/i", $this->FAIstate)){
177         $this->dialog->save_object();
178         if(count($this->dialog->check())){
179           foreach($this->dialog->check() as $msg){
180             msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
181           }
182         }else{
183           $disk = $this->dialog->save();
184           if(isset($disk['rename'])){
185             if($this->disks[$disk['rename']['from']]['status']=="edited"){
186               $this->disks[$disk['rename']['from']]['status']="delete";
187             }else{
188               unset($this->disks[$disk['rename']['from']]);
189             }
191             foreach($disk['partitions'] as $key => $val){
192               if($disk['partitions'][$key]['status']!="delete"){
193                 $disk['partitions'][$key]['status']= "new";
194               }
195             }
197             $disk['status']="new";
198             $disk['cn']= $disk['rename']['to'];
199           }
201           $this->disks[$disk['cn']]=$disk; 
202           unset($this->dialog);
203           $this->dialog = FALSE;
204           $this->is_dialog=false;
205           ksort($this->disks);
206         }
207       }else{
208         $this->dialog = FALSE;
209         $this->is_dialog=false;
210       }
211     }
213     /* Delete selected disk drive from list
214      * Assign delete status for all its partitions      
215      */
216     if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
217       if (!preg_match("/freeze/i", $this->FAIstate)){
218         foreach($_POST['disks'] as $disk) {
220           if(isset($this->disks[$disk])){
221             if($this->disks[$disk]['status']=="edited"){
222               $this->disks[$disk."-delete"]=$this->disks[$disk];
223               unset($this->disks[$disk]);
224               $disk = $disk."-delete";        
225               $this->disks[$disk]['status']="delete";
226               foreach($this->disks[$disk]['partitions'] as $name => $value ){
227                 if($value['status']=="edited"){
228                   $this->disks[$disk]['partitions'][$name]['status']="delete"; 
229                 }else{
230                   unset($this->disks[$disk]['partitions'][$name]);
231                 }
232               }
233             }else{
234               unset($this->disks[$disk]);
235             }
236           }
237         }
238       }
239     }
241     /* Display dialog if one is defined
242      */
243     if(is_object($this->dialog)){
244       $this->dialog->save_object();
245       return($this->dialog->execute());
246     }
248     /* Assign all attributes to smarty engine
249      */
250     foreach($this->attributes as $attrs){
251       $smarty->assign($attrs,$this->$attrs);
252       if($this->$attrs){
253         $smarty->assign($attrs."CHK"," ");
254       }else{
255         $smarty->assign($attrs."CHK"," disabled ");
256       }
257     }
258    
259     $dn = $this->acl_base_for_current_object($this->dn);
260     $smarty->assign("sub_object_is_addable",
261         preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
262         !preg_match("/freeze/",$this->FAIstate));
263     $smarty->assign("sub_object_is_removeable",
264         preg_match("/d/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
265         !preg_match("/freeze/",$this->FAIstate));
267     $tmp = $this->plInfo();
268     foreach($tmp['plProvidedAcls'] as $name => $translated){
269       $smarty->assign($name."ACL",$this->getacl($name,preg_match("/freeze/i",$this->FAIstate)));
270     }
271     $disks = $this->getDisks();
272     $smarty->assign("disks"   ,$disks);
273     $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
274     return($display);
275   }
277   function getDisks(){
278     /* Return all available disks for this partition table
279      * Return in listBox friendly array
280      */
281     $a_return = array();
282     foreach($this->disks as $key => $disk){
284       $dn = "new";
285       if(isset($obj['dn'])){
286         $dn = $obj['dn'];
287       }
288       $dn = $this->acl_base_for_current_object($dn);
289       $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
290       if(preg_match("/(r|w)/",$acl)) {
292         if($disk['status'] != "delete"){
293           $cnt=0;
294           foreach($disk['partitions'] as $val){
295             if($val['status']!="delete"){
296               $cnt ++;
297             }
298           }
299           if(!empty($disk['description'])){
300             if($cnt == 1){
301               $a_return[$key]=  $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
302             }else{
303               $a_return[$key]=  $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
304             }
305           }else{
306             if($cnt == 1){
307               $a_return[$key]=  $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
308             }else{
309               $a_return[$key]=  $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
310             }
311           }
312         }
313       }
314     }
315     return($a_return);
316   }
319   /* Delete me, and all my subtrees
320    */
321   function remove_from_parent()
322   {
323     $ldap = $this->config->get_ldap_link();
324     $ldap->cd ($this->dn);
326     $release = $this->parent->parent->fai_release;
327     $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $release, $this->dn);
329     FAI::prepare_to_save_FAI_object($use_dn,array(),true);
330     new log("remove","fai/".get_class($this),$use_dn,$this->attributes);   
331     foreach($this->disks as $disk){
332       $disk_dn = "cn=".$disk['cn'].",".$this->dn;
333       $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i",$release, $disk_dn);
334       FAI::prepare_to_save_FAI_object($use_dn,array(),true);
335       foreach($disk['partitions'] as $key => $partition){    
336         $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;      
337         $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $release, $partition_dn);
338         FAI::prepare_to_save_FAI_object($use_dn,array(),true);
339       }
340     }
341   }
344   /* Save data to object 
345    */
346   function save_object()
347   {
348     if (preg_match("/freeze/", $this->FAIstate)) return;
349     plugin::save_object();
350     foreach($this->attributes as $attrs){
351       if(isset($_POST[$attrs])){
352         $this->$attrs = $_POST[$attrs];
353       }
354     }
355   }
358   /* Check supplied data */
359   function check()
360   {
361     /* Call common method to give check the hook */
362     $message= plugin::check();
364     /* Ensure that we do not overwrite an allready existing entry 
365      */
366     if($this->is_new){
367       $release = $this->parent->parent->fai_release;
368       $new_dn= 'cn='.$this->cn.",".get_ou('faipartitionou').get_ou('faiou').$release;
369       $res = faiManagement::check_class_name("FAIpartitionTable",$this->cn,$new_dn);
370       if(isset($res[$this->cn])){
371         $message[] = msgPool::duplicated(_("Name"));
372       }
373     }
374     return ($message);
375   }
378   /* Save to LDAP */
379   function save()
380   {
382     plugin::save();
383     /* Save current settings.
384      * 1 : We must save the partition table, with its description and cn 
385      * 2 : Append Disk with cn and  description.
386      * 3 : Save partitions for each disk
387      */  
389     $ldap = $this->config->get_ldap_link();
391     FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
393     if($this->initially_was_account){
394       new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
395     }else{
396       new log("create","fai/".get_class($this),$this->dn,$this->attributes);
397     }
398  
399     /* Sort entries, because we must delete entries with status="delete" first */
400     $order = array();
401     foreach($this->disks as $key => $disk){
402       if($disk['status'] == "delete"){
403         $order[$key] = $disk;
404       }
405     }
406     foreach($this->disks as $key => $disk){
407       if($disk['status'] != "delete"){
408         $order[$key] = $disk;
409       }
410     }
412     /* Append all disks to ldap */
413     foreach($order as $cn=>$disk){
414       $disk_dn                    = "cn=".$disk['cn'].",".$this->dn;
415       $disk_attrs['cn']           =  $disk['cn'];
416       $disk_attrs['description']  =  $disk['description']; 
418       if(empty($disk_attrs['description']) && $disk['status'] == "edited"){
419         $disk_attrs['description'] = array();
420       }
422       $disk_attrs['objectClass']  =  array("top","FAIclass","FAIpartitionDisk");
424       if($disk['status']=="new"){
425         $ldap->cat($disk_dn,array("objectClass"));
426         if($ldap->count()){
427           $disk['status']="edited";
428         }
429       }
431       /* Tag object */
432       $this->tag_attrs($disk_attrs, $disk_dn, $this->gosaUnitTag);
434       if($disk['status'] == "delete"){
435         FAI::prepare_to_save_FAI_object($disk_dn,array(),true);
436         $this->handle_post_events("remove");
437       }elseif($disk['status'] == "edited"){
438         FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
439         $this->handle_post_events("modify");
440       }elseif($disk['status']=="new"){
441         FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
442         $this->handle_post_events("add");
443       }
445       if($disk['status']!="delete")
446       /* Add all partitions */
447       foreach($disk['partitions'] as $key => $partition){
448         $partition_attrs = array();
450         foreach($partition as $key => $value){
451           if(!empty($value)){
452             $partition_attrs[$key]=$value;        
453           }else{
454             unset($partition_attrs[$key]);        
455           }
456         }
458         $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;      
459         $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
460         $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
461         
462         unset($partition_attrs['status']);
463         unset($partition_attrs['old_cn']);
465         if($partition['status']=="new"){
466           $ldap->cat($partition_dn,array("objectClass"));
467           if($ldap->count()){
468             $partition['status']="edited";
469           }
470         }
472         if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
473           $partition_attrs['FAImountPoint']="swap";
474         }
476         /* Tag object */
477         $this->tag_attrs($partition_attrs, $partition_dn, $this->gosaUnitTag);
479         if($partition['status'] == "delete"){
480           FAI::prepare_to_save_FAI_object($partition_dn,array(),true);
481           $this->handle_post_events("remove");
482         }elseif($partition['status'] == "edited"){
483           FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
484           $this->handle_post_events("modify");
485         }elseif($partition['status']=="new"){
486           FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
487           $this->handle_post_events("add");
488         }
489       }
490     }
491     $this->handle_post_events("add");
492   }
495   function PrepareForCopyPaste($source)
496   {
497     plugin::PrepareForCopyPaste($source);
498     /* Get FAIstate
499      */
500     if(isset($source['FAIstate'][0])){
501       $this->FAIstate = $source['FAIstate'][0];
502     }
504     /* Read all disks from ldap taht are defined fot this partition table 
505      */
506     $ldap = $this->config->get_ldap_link();
507     $ldap->cd ($source['dn']);
508     $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
509     while($object = $ldap->fetch()){
511       /* Skip objects, that are tagged as removed */
512       if(isset($object['FAIstate'][0])){
513         if(preg_match("/removed$/",$object['FAIstate'][0])){
514           continue;
515         }
516       }
518       $this->disks[$object['cn'][0]]['status']      = "edited";
519       $this->disks[$object['cn'][0]]['dn']          = $object['dn'];
520       $this->disks[$object['cn'][0]]['cn']          = $object['cn'][0];
521       if(isset($object['description'][0])){
522         $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
523       }else{
524         $this->disks[$object['cn'][0]]['description'] = "";
525       }
526       $this->disks[$object['cn'][0]]['partitions']   = array();
527     }
529     /* read all partitions for each disk 
530      */
531     foreach($this->disks as $name => $disk){
532       $ldap->cd ($disk['dn']);
533       $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
534       while($partition = $ldap->fetch()){
536         /* Skip objects, that are tagged as removed */
537         if(isset($partition['FAIstate'][0])){
538           if(preg_match("/removed$/",$partition['FAIstate'][0])){
539             continue;
540           }
541         }
543         /* remove count ... from ldap result 
544          */
545         foreach($partition as $key=>$val){
546           if((is_numeric($key))||($key=="count")||($key=="dn")){
547             unset($partition[$key]);
548           }else{
549             $partition[$key] = $val[0];
550           }
551         }
553         /* Append fetched partitions
554          */
555         $partition['status']="edited";
556         $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition; 
557       }  
558     }
559     ksort($this->disks);
560   }
563   /* Return plugin informations for acl handling */ 
564   static function plInfo()
565   {
566     return (array( 
567           "plShortName" => _("Partition table"),
568           "plDescription" => _("FAI partition table"),
569           "plSelfModify"  => FALSE,
570           "plDepends"     => array(),
571           "plPriority"    => 26,
572           "plSection"     => array("administration"),
573           "plCategory"    => array("fai"),
574           "plProvidedAcls" => array(
575             "cn"                => _("Name")."&nbsp;("._("Read only").")",
576             "description"       => _("Description"))
577           ));
578   }
581   /*! \brief  Used for copy & paste.
582     Returns a HTML input mask, which allows to change the cn of this entry.
583     @param  Array   Array containing current status && a HTML template.
584    */
585   function getCopyDialog()
586   {
587     $vars = array("cn");
588     $smarty = get_smarty();
589     $smarty->assign("cn", htmlentities($this->cn));
590     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
591     $ret = array();
592     $ret['string'] = $str;
593     $ret['status'] = "";
594     return($ret);
595   }
598   /*! \brief  Used for copy & paste.
599     Some entries must be renamed to avaoid duplicate entries.
600    */
601   function saveCopyDialog()
602   {
603     if(isset($_POST['cn'])){
604       $this->cn = get_post('cn');
605     }
606   }
608   /* Reload some attributes */
609   function get_object_attributes($object,$attributes)
610   {
611     $ldap = $this->config->get_ldap_link();
612     $ldap->cd($this->config->current['BASE']);
613     $ldap->cat($object['dn'],$attributes);
614     $tmp  = $ldap->fetch();
616     foreach($attributes as $attrs){
617       if(isset($tmp[$attrs][0])){
618         $var = $tmp[$attrs][0];
620         /* Check if we must decode some attributes */
621         if(in_array_ics($attrs,$this->sub64coded)){
622           $var = base64_decode($var);
623         }
625         /*  check if this is a binary entry */
626         if(in_array_ics($attrs,$this->subBinary)){
627           $var = $ldap->get_attribute($object['dn'], $attrs,$r_array=0);
628         }
630         /* Fix slashes */
631         $var = addslashes($var);
632         $object[$attrs] = $var;
633       }
634     }
635     return($object);
636   }
640 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
641 ?>