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 /* Specific attributes */
11 var $cn = ""; // The class name for this object
12 var $description = ""; // The description for this set of partitions
13 var $disks = array(); // All defined Disks
14 var $is_dialog = false; // specifies which buttons will be shown to save or abort
16 var $FAIstate = "";
17 var $ui;
19 var $view_logged = FALSE;
21 function faiPartitionTable (&$config, $dn= NULL)
22 {
23 /* Load Attributes */
24 plugin::plugin ($config, $dn);
26 $this->acl ="#all#";
28 $this->ui = get_userinfo();
30 /* If "dn==new" we try to create a new entry
31 * Else we must read all objects from ldap which belong to this entry.
32 * First read disks from ldap ... and then the partition definitions for the disks.
33 */
34 if($dn != "new"){
35 $this->dn =$dn;
37 /* Get FAIstate
38 */
39 if(isset($this->attrs['FAIstate'][0])){
40 $this->FAIstate = $this->attrs['FAIstate'][0];
41 }
43 /* Read all disks from ldap taht are defined fot this partition table
44 */
45 $ldap = $this->config->get_ldap_link();
46 $ldap->cd ($this->dn);
47 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
48 while($object = $ldap->fetch()){
50 /* Skip objects, that are tagged as removed */
51 if(isset($object['FAIstate'][0])){
52 if(preg_match("/removed$/",$object['FAIstate'][0])){
53 continue;
54 }
55 }
57 $this->disks[$object['cn'][0]]['status'] = "edited";
58 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
59 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
60 if(isset($object['description'][0])){
61 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
62 }else{
63 $this->disks[$object['cn'][0]]['description'] = "";
64 }
65 $this->disks[$object['cn'][0]]['partitions'] = array();
66 }
68 /* read all partitions for each disk
69 */
70 foreach($this->disks as $name => $disk){
71 $ldap->cd ($disk['dn']);
72 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
73 while($partition = $ldap->fetch()){
75 /* Skip objects, that are tagged as removed */
76 if(isset($partition['FAIstate'][0])){
77 if(preg_match("/removed$/",$partition['FAIstate'][0])){
78 continue;
79 }
80 }
82 /* remove count ... from ldap result
83 */
84 foreach($partition as $key=>$val){
85 if((is_numeric($key))||($key=="count")||($key=="dn")){
86 unset($partition[$key]);
87 }else{
88 $partition[$key] = $val[0];
89 }
90 }
92 /* Append fetched partitions
93 */
94 $partition['status']="edited";
95 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
96 }
97 }
98 }
99 ksort($this->disks);
100 }
103 function acl_base_for_current_object($dn)
104 {
105 if($dn == "new"){
106 if($this->dn == "new"){
107 $dn = session::get('CurrentMainBase');
108 }else{
109 $dn = $this->dn;
110 }
111 }
112 return($dn);
113 }
116 function execute()
117 {
118 /* Call parent execute */
119 plugin::execute();
121 if($this->is_account && !$this->view_logged){
122 $this->view_logged = TRUE;
123 new log("view","fai/".get_class($this),$this->dn);
124 }
126 /* Fill templating stuff */
127 $smarty= get_smarty();
128 $display= "";
130 /* Add Disk to this Partitionset
131 * This code adds a new HDD to the disks
132 * A new Dialog will be opened
133 */
134 if(isset($_POST['AddDisk'])){
135 $usedDiskNames =array();
136 foreach($this->disks as $key=>$disk){
137 $usedDiskNames[]= $key;
138 }
139 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
140 $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
141 $this->dialog->set_acl_category("fai");
142 $this->dialog->FAIstate = $this->FAIstate;
143 $this->is_dialog = true;
144 }
146 /* Edit disk.
147 * Open dialog which allows us to edit the selected entry
148 */
150 if($this->dn != "new"){
151 session::set('objectinfo',$this->dn);
152 }
154 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
155 $usedDiskNames =array();
156 $Udisk = $_POST['disks'][0];
157 if(isset($this->disks[$Udisk])){
159 foreach($this->disks as $key=>$disk){
160 if($key != $Udisk){
161 $usedDiskNames[]= $key;
162 }
163 }
165 /* Set object info string, which will be displayed in plugin info line */
166 if(isset($this->disks[$Udisk]['dn'])){
167 session::set('objectinfo',$this->disks[$Udisk]['dn']);
168 $dn = $this->disks[$Udisk]['dn'];
169 }else{
170 session::set('objectinfo',"");
171 $dn = "new";
172 }
174 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
175 $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
176 $this->dialog->set_acl_category("fai");
177 $this->dialog->FAIstate = $this->FAIstate;
179 $this->is_dialog = true;
180 }
181 }
183 /* Edit aborted, close dialog, without saving anything
184 */
185 if(isset($_POST['CancelDisk'])){
186 unset($this->dialog);
187 $this->dialog = FALSE;
188 $this->is_dialog=false;
189 }
191 /* Dialog saved
192 * Save given data from Dialog, if no error is occurred
193 */
194 if(isset($_POST['SaveDisk'])){
196 if($this->FAIstate != "freeze"){
197 $this->dialog->save_object();
198 if(count($this->dialog->check())){
199 foreach($this->dialog->check() as $msg){
200 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
201 }
202 }else{
203 $disk = $this->dialog->save();
204 if(isset($disk['rename'])){
205 if($this->disks[$disk['rename']['from']]['status']=="edited"){
206 $this->disks[$disk['rename']['from']]['status']="delete";
207 }else{
208 unset($this->disks[$disk['rename']['from']]);
209 }
211 foreach($disk['partitions'] as $key => $val){
212 if($disk['partitions'][$key]['status']!="delete"){
213 $disk['partitions'][$key]['status']= "new";
214 }
215 }
217 $disk['status']="new";
218 $disk['cn']= $disk['rename']['to'];
219 }
221 $this->disks[$disk['cn']]=$disk;
222 unset($this->dialog);
223 $this->dialog = FALSE;
224 $this->is_dialog=false;
225 ksort($this->disks);
226 }
227 }else{
228 $this->dialog = FALSE;
229 $this->is_dialog=false;
230 }
231 }
233 /* Delete selected disk drive from list
234 * Assign delete status for all its partitions
235 */
236 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
237 if($this->FAIstate != "freeze"){
238 foreach($_POST['disks'] as $disk) {
240 if(isset($this->disks[$disk])){
241 if($this->disks[$disk]['status']=="edited"){
242 $this->disks[$disk."-delete"]=$this->disks[$disk];
243 unset($this->disks[$disk]);
244 $disk = $disk."-delete";
245 $this->disks[$disk]['status']="delete";
246 foreach($this->disks[$disk]['partitions'] as $name => $value ){
247 if($value['status']=="edited"){
248 $this->disks[$disk]['partitions'][$name]['status']="delete";
249 }else{
250 unset($this->disks[$disk]['partitions'][$name]);
251 }
252 }
253 }else{
254 unset($this->disks[$disk]);
255 }
256 }
257 }
258 }
259 }
261 /* Display dialog if one is defined
262 */
263 if(is_object($this->dialog)){
264 $this->dialog->save_object();
265 return($this->dialog->execute());
266 }
268 /* Assign all attributes to smarty engine
269 */
270 foreach($this->attributes as $attrs){
271 $smarty->assign($attrs,$this->$attrs);
272 if($this->$attrs){
273 $smarty->assign($attrs."CHK"," ");
274 }else{
275 $smarty->assign($attrs."CHK"," disabled ");
276 }
277 }
279 $dn = $this->acl_base_for_current_object($this->dn);
280 $smarty->assign("sub_object_is_addable",
281 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
282 !preg_match("/freeze/",$this->FAIstate));
284 $tmp = $this->plInfo();
285 foreach($tmp['plProvidedAcls'] as $name => $translated){
286 $smarty->assign($name."ACL",$this->getacl($name));
287 }
288 $disks = $this->getDisks();
289 $smarty->assign("disks" ,$disks);
290 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
291 return($display);
292 }
294 function getDisks(){
295 /* Return all available disks for this partition table
296 * Return in listBox friendly array
297 */
298 $a_return = array();
299 foreach($this->disks as $key => $disk){
301 $dn = "new";
302 if(isset($obj['dn'])){
303 $dn = $obj['dn'];
304 }
305 $dn = $this->acl_base_for_current_object($dn);
306 $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
307 if(preg_match("/(r|w)/",$acl)) {
309 if($disk['status'] != "delete"){
310 $cnt=0;
311 foreach($disk['partitions'] as $val){
312 if($val['status']!="delete"){
313 $cnt ++;
314 }
315 }
316 if(!empty($disk['description'])){
317 if($cnt == 1){
318 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
319 }else{
320 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
321 }
322 }else{
323 if($cnt == 1){
324 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
325 }else{
326 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
327 }
328 }
329 }
330 }
331 }
332 return($a_return);
333 }
336 /* Delete me, and all my subtrees
337 */
338 function remove_from_parent()
339 {
340 $ldap = $this->config->get_ldap_link();
341 $ldap->cd ($this->dn);
343 $faifilter = session::get('faifilter');
344 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $faifilter['branch'], $this->dn);
345 if($faifilter['branch'] == "main"){
346 $use_dn = $this->dn;
347 }
349 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
351 new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
353 foreach($this->disks as $disk){
355 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
356 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $faifilter['branch'], $disk_dn);
357 if($faifilter['branch'] == "main"){
358 $use_dn = $disk_dn;
359 }
360 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
362 foreach($disk['partitions'] as $key => $partition){
364 $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;
365 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $faifilter['branch'], $partition_dn);
366 if($faifilter['branch'] == "main"){
367 $use_dn = $disk_dn;
368 }
369 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
370 }
371 }
372 }
375 /* Save data to object
376 */
377 function save_object()
378 {
379 if($this->FAIstate == "freeze") return;
380 plugin::save_object();
381 foreach($this->attributes as $attrs){
382 if(isset($_POST[$attrs])){
383 $this->$attrs = $_POST[$attrs];
384 }
385 }
386 }
389 /* Check supplied data */
390 function check()
391 {
392 /* Call common method to give check the hook */
393 $message= plugin::check();
395 return ($message);
396 }
399 /* Save to LDAP */
400 function save()
401 {
403 plugin::save();
404 /* Save current settings.
405 * 1 : We must save the partition table, with its description and cn
406 * 2 : Append Disk with cn and description.
407 * 3 : Save partitions for each disk
408 */
410 $ldap = $this->config->get_ldap_link();
412 FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
413 show_ldap_error($ldap->get_error(), sprintf(_("Saving of FAI/partition table with dn '%s' failed."),$this->dn));
415 if($this->initially_was_account){
416 new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
417 }else{
418 new log("create","fai/".get_class($this),$this->dn,$this->attributes);
419 }
421 /* Sort entries, because we must delete entries with status="delete" first */
422 $order = array();
423 foreach($this->disks as $key => $disk){
424 if($disk['status'] == "delete"){
425 $order[$key] = $disk;
426 }
427 }
428 foreach($this->disks as $key => $disk){
429 if($disk['status'] != "delete"){
430 $order[$key] = $disk;
431 }
432 }
434 /* Append all disks to ldap */
435 foreach($order as $cn=>$disk){
436 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
437 $disk_attrs['cn'] = $disk['cn'];
438 $disk_attrs['description'] = $disk['description'];
439 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
441 if($disk['status']=="new"){
442 $ldap->cat($disk_dn,array("objectClass"));
443 if($ldap->count()){
444 $disk['status']="edited";
445 }
446 }
448 /* Tag object */
449 $this->tag_attrs($disk_attrs, $disk_dn, $this->gosaUnitTag);
451 if($disk['status'] == "delete"){
452 FAI::prepare_to_save_FAI_object($disk_dn,array(),true);
453 $this->handle_post_events("remove");
454 }elseif($disk['status'] == "edited"){
455 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
456 $this->handle_post_events("modify");
457 }elseif($disk['status']=="new"){
458 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
459 $this->handle_post_events("add");
460 }
462 if($disk['status']!="delete")
463 /* Add all partitions */
464 foreach($disk['partitions'] as $key => $partition){
465 $partition_attrs = array();
467 foreach($partition as $key => $value){
468 if(!empty($value)){
469 $partition_attrs[$key]=$value;
470 }else{
471 unset($partition_attrs[$key]);
472 }
473 }
475 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
476 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
477 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
479 unset($partition_attrs['status']);
480 unset($partition_attrs['old_cn']);
482 if($partition['status']=="new"){
483 $ldap->cat($partition_dn,array("objectClass"));
484 if($ldap->count()){
485 $partition['status']="edited";
486 }
487 }
489 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
490 $partition_attrs['FAImountPoint']="swap";
491 }
493 /* Tag object */
494 $this->tag_attrs($partition_attrs, $partition_dn, $this->gosaUnitTag);
496 if($partition['status'] == "delete"){
497 FAI::prepare_to_save_FAI_object($partition_dn,array(),true);
498 $this->handle_post_events("remove");
499 }elseif($partition['status'] == "edited"){
500 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
501 $this->handle_post_events("modify");
502 }elseif($partition['status']=="new"){
503 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
504 $this->handle_post_events("add");
505 }
506 }
507 }
508 $this->handle_post_events("add");
509 }
512 function PrepareForCopyPaste($source)
513 {
514 plugin::PrepareForCopyPaste($source);
515 /* Get FAIstate
516 */
517 if(isset($source['FAIstate'][0])){
518 $this->FAIstate = $source['FAIstate'][0];
519 }
521 /* Read all disks from ldap taht are defined fot this partition table
522 */
523 $ldap = $this->config->get_ldap_link();
524 $ldap->cd ($source['dn']);
525 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
526 while($object = $ldap->fetch()){
528 /* Skip objects, that are tagged as removed */
529 if(isset($object['FAIstate'][0])){
530 if(preg_match("/removed$/",$object['FAIstate'][0])){
531 continue;
532 }
533 }
535 $this->disks[$object['cn'][0]]['status'] = "edited";
536 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
537 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
538 if(isset($object['description'][0])){
539 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
540 }else{
541 $this->disks[$object['cn'][0]]['description'] = "";
542 }
543 $this->disks[$object['cn'][0]]['partitions'] = array();
544 }
546 /* read all partitions for each disk
547 */
548 foreach($this->disks as $name => $disk){
549 $ldap->cd ($disk['dn']);
550 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
551 while($partition = $ldap->fetch()){
553 /* Skip objects, that are tagged as removed */
554 if(isset($partition['FAIstate'][0])){
555 if(preg_match("/removed$/",$partition['FAIstate'][0])){
556 continue;
557 }
558 }
560 /* remove count ... from ldap result
561 */
562 foreach($partition as $key=>$val){
563 if((is_numeric($key))||($key=="count")||($key=="dn")){
564 unset($partition[$key]);
565 }else{
566 $partition[$key] = $val[0];
567 }
568 }
570 /* Append fetched partitions
571 */
572 $partition['status']="edited";
573 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
574 }
575 }
576 ksort($this->disks);
577 }
580 /* Return plugin informations for acl handling */
581 static function plInfo()
582 {
583 return (array(
584 "plShortName" => _("Partition table"),
585 "plDescription" => _("FAI partition table"),
586 "plSelfModify" => FALSE,
587 "plDepends" => array(),
588 "plPriority" => 26,
589 "plSection" => array("administration"),
590 "plCategory" => array("fai"),
591 "plProvidedAcls" => array(
592 "cn" => _("Name")." ("._("Read only").")",
593 "description" => _("Description"))
594 ));
595 }
596 }
598 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
599 ?>