1 <?php
3 class faiPartitionTable extends plugin
4 {
5 /* CLI vars */
6 var $cli_summary= "Manage server basic objects";
7 var $cli_description= "Some longer text\nfor help";
8 var $cli_parameters= array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
10 /* attribute list for save action */
11 var $ignore_account = TRUE;
12 var $attributes = array("cn","description");
13 var $objectclasses = array("top","FAIclass","FAIpartitionTable");
15 /* Specific attributes */
16 var $cn = ""; // The class name for this object
17 var $description = ""; // The description for this set of partitions
18 var $disks = array(); // All defined Disks
19 var $is_dialog = false; // specifies which buttons will be shown to save or abort
20 var $dialog = NULL; // a dialog, e.g. new disk dialog
22 var $FAIstate = "";
23 var $base = "";
24 var $release = "";
25 var $copy_paste_mode = false;
26 var $cut_paste_mode = false;
28 var $CopyPasteVars = array("disks");
30 function faiPartitionTable ($config, $dn= NULL)
31 {
32 /* Load Attributes */
33 plugin::plugin ($config, $dn);
35 $this->acl ="#all#";
37 /* If "dn==new" we try to create a new entry
38 * Else we must read all objects from ldap which belong to this entry.
39 * First read disks from ldap ... and then the partition definitions for the disks.
40 */
41 if($dn != "new"){
42 $this->dn =$dn;
44 /* Set acls
45 */
46 $ui = get_userinfo();
47 $acl = get_permissions ($this->dn, $ui->subtreeACL);
48 $acli = get_module_permission($acl, "FAIclass", $this->dn);
49 $this->acl=$acli;
51 /* Get FAIstate
52 */
53 if(isset($this->attrs['FAIstate'][0])){
54 $this->FAIstate = $this->attrs['FAIstate'][0];
55 }
57 /* Read all disks from ldap taht are defined fot this partition table
58 */
59 $ldap = $this->config->get_ldap_link();
60 $ldap->cd ($this->dn);
61 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
62 while($object = $ldap->fetch()){
63 $this->disks[$object['cn'][0]]['status'] = "edited";
64 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
65 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
66 if(isset($object['description'][0])){
67 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
68 }else{
69 $this->disks[$object['cn'][0]]['description'] = "";
70 }
71 $this->disks[$object['cn'][0]]['partitions'] = array();
72 }
74 /* read all partitions for each disk
75 */
76 foreach($this->disks as $name => $disk){
77 $ldap->cd ($disk['dn']);
78 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
79 while($partition = $ldap->fetch()){
81 /* remove count ... from ldap result
82 */
83 foreach($partition as $key=>$val){
84 if((is_numeric($key))||($key=="count")||($key=="dn")){
85 unset($partition[$key]);
86 }else{
87 $partition[$key] = $val[0];
88 }
89 }
91 /* Append fetched partitions
92 */
93 $partition['status']="edited";
94 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
95 }
96 }
97 }
98 ksort($this->disks);
99 }
101 function execute()
102 {
103 /* Call parent execute */
104 plugin::execute();
106 /* Fill templating stuff */
107 $smarty= get_smarty();
108 $display= "";
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'])){
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->acl = $this->acl;
121 $this->dialog->FAIstate = $this->FAIstate;
122 $this->is_dialog = true;
123 }
125 /* Edit disk.
126 * Open dialog which allows us to edit the selected entry
127 */
129 if($this->dn != "new"){
130 $_SESSION['objectinfo']= $this->dn;
131 }
133 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
134 $usedDiskNames =array();
136 $Udisk = $_POST['disks'][0];
138 foreach($this->disks as $key=>$disk){
139 if($key != $Udisk){
140 $usedDiskNames[]= $key;
141 }
142 }
143 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
144 $this->dialog->acl = $this->acl;
145 $this->dialog->FAIstate = $this->FAIstate;
147 /* Set object info string, which will be displayed in plugin info line */
148 if(isset($this->disks[$Udisk]['dn'])){
149 $_SESSION['objectinfo'] = $this->disks[$Udisk]['dn'];
150 }else{
151 $_SESSION['objectinfo'] = "";
152 }
154 $this->is_dialog = true;
155 }
157 /* Edit aborted, close dialog, without saving anything
158 */
159 if(isset($_POST['CancelDisk'])){
160 unset($this->dialog);
161 $this->dialog = NULL;
162 $this->is_dialog=false;
163 }
165 /* Dialog saved
166 * Save given data from Dialog, if no error is occured
167 */
168 if(isset($_POST['SaveDisk'])){
170 if($this->FAIstate != "freeze"){
171 $this->dialog->save_object();
172 if(count($this->dialog->check())){
173 foreach($this->dialog->check() as $msg){
174 print_red($msg);
175 }
176 }else{
177 $disk = $this->dialog->save();
178 if(isset($disk['rename'])){
179 if($this->disks[$disk['rename']['from']]['status']=="edited"){
180 $this->disks[$disk['rename']['from']]['status']="delete";
181 }else{
182 unset($this->disks[$disk['rename']['from']]);
183 }
185 foreach($disk['partitions'] as $key => $val){
186 if($disk['partitions'][$key]['status']!="delete"){
187 $disk['partitions'][$key]['status']= "new";
188 }
189 }
191 $disk['status']="new";
192 $disk['cn']= $disk['rename']['to'];
193 }
195 $this->disks[$disk['cn']]=$disk;
196 unset($this->dialog);
197 $this->dialog = NULL;
198 $this->is_dialog=false;
199 ksort($this->disks);
200 }
201 }else{
202 $this->dialog = NULL;
203 $this->is_dialog=false;
204 }
205 }
207 /* Delete selected disk drive from list
208 * Assign delete status for all its partitions
209 */
210 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
211 if($this->FAIstate != "freeze"){
212 foreach($_POST['disks'] as $disk) {
213 if($this->disks[$disk]['status']=="edited"){
214 $this->disks[$disk."-delete"]=$this->disks[$disk];
215 unset($this->disks[$disk]);
216 $disk = $disk."-delete";
217 $this->disks[$disk]['status']="delete";
218 foreach($this->disks[$disk]['partitions'] as $name => $value ){
219 if($value['status']=="edited"){
220 $this->disks[$disk]['partitions'][$name]['status']="delete";
221 }else{
222 unset($this->disks[$disk]['partitions'][$name]);
223 }
224 }
225 }else{
226 unset($this->disks[$disk]);
227 }
228 }
229 }
230 }
232 /* Display dialog if one is defined
233 */
234 if(isset($this->dialog)){
235 $this->dialog->save_object();
236 return($this->dialog->execute());
237 }
239 /* Assign all attributes to smarty engine
240 */
241 foreach($this->attributes as $attrs){
242 $smarty->assign($attrs,$this->$attrs);
243 if($this->$attrs){
244 $smarty->assign($attrs."CHK"," ");
245 }else{
246 $smarty->assign($attrs."CHK"," disabled ");
247 }
248 }
250 foreach($this->attributes as $attr){
251 $smarty->assign($attr."ACL",chkacl($this->acl,$attr));
252 }
254 $disks = $this->getDisks();
255 $smarty->assign("disks" ,$disks);
256 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
257 return($display);
258 }
260 function getDisks(){
261 /* Return all available disks for this partition table
262 * Return in listBox friendly array
263 */
264 $a_return = array();
265 foreach($this->disks as $key => $disk){
266 if($disk['status'] != "delete"){
267 $cnt=0;
268 foreach($disk['partitions'] as $val){
269 if($val['status']!="delete"){
270 $cnt ++;
271 }
272 }
273 if(!empty($disk['description'])){
274 if($cnt == 1){
275 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
276 }else{
277 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
278 }
279 }else{
280 if($cnt == 1){
281 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
282 }else{
283 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
284 }
285 }
286 }
287 }
288 return($a_return);
289 }
292 /* Delete me, and all my subtrees
293 */
294 function remove_from_parent()
295 {
296 $ldap = $this->config->get_ldap_link();
297 $ldap->cd ($this->dn);
298 $ldap->rmdir_recursive($this->dn);
299 $this->handle_post_events("remove");
301 /* This cannot be removed... */
302 }
305 /* Save data to object
306 */
307 function save_object()
308 {
309 if($this->FAIstate == "freeze") return;
310 plugin::save_object();
311 foreach($this->attributes as $attrs){
312 if(isset($_POST[$attrs])){
313 $this->$attrs = $_POST[$attrs];
314 }
315 }
316 }
319 /* Check supplied data */
320 function check()
321 {
322 /* Call common method to give check the hook */
323 $message= plugin::check();
325 /* If this is a new script, check if a script with this name already exists */
326 if(!empty($this->release) && ($this->copy_paste_mode || $this->cut_paste_mode) ){
328 /* Check if current name is already used for fai scripts in selected release */
329 $dn = 'cn='.$this->cn.",ou=disk,".$this->release;
330 $ldap = $this->config->get_ldap_link();
331 $ldap->cat($dn);
332 if($ldap->count()){
334 $r =convert_department_dn($this->release);;
335 $message[] = sprintf(_("Can't insert a new fai partition table named '%s' in '%s' there is already one defined with the given name."),$this->cn,$r);
336 }
337 }
338 return ($message);
339 }
342 /* Save to LDAP */
343 function save()
344 {
346 plugin::save();
347 /* Save current settings.
348 * 1 : We must save the partition table, with its description and cn
349 * 2 : Append Disk with cn and description.
350 * 3 : Save partitions for each disk
351 */
353 /* Copy & Paste : Ensure that FAIstate is copied too */
354 if($this->copy_paste_mode && preg_match("/freeze/",$this->FAIstate)){
355 $this->attrs['FAIstate'] = $this->FAIstate;
356 }
358 $ldap = $this->config->get_ldap_link();
360 if($this->new){
361 $ldap->cd($this->config->current['BASE']);
362 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
363 $ldap->cd($this->dn);
364 $ldap->add($this->attrs);
365 }else{
366 /* Add partition table to ldap
367 */
368 $ldap->cd($this->dn);
369 $this->cleanup();
370 $ldap->modify ($this->attrs);
371 }
372 show_ldap_error($ldap->get_error(), _("Saving FAI partition table base failed"));
374 /* Do object tagging */
375 $this->handle_object_tagging();
377 /* Sort entries, because we must delete entries with status="delete" first */
378 $order = array();
379 foreach($this->disks as $key => $disk){
380 if($disk['status'] == "delete"){
381 $order[$key] = $disk;
382 }
383 }
384 foreach($this->disks as $key => $disk){
385 if($disk['status'] != "delete"){
386 $order[$key] = $disk;
387 }
388 }
390 /* Append all disks to ldap */
391 foreach($order as $cn=>$disk){
392 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
393 $disk_attrs['cn'] = $disk['cn'];
394 $disk_attrs['description'] = $disk['description'];
395 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
397 /* We currently use the copy & paste method */
398 if($this->copy_paste_mode){
399 $disk['status'] = "new";
400 }
402 if($disk['status']=="new"){
403 $ldap->cat($disk_dn,array("objectClass"));
404 if($ldap->count()){
405 $disk['status']="edited";
406 }
407 }
409 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for disks */
410 $ldap->cat($disk_dn,array("objectClass"));
411 $attrs = $ldap->fetch();
412 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
413 $disk_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
414 }
416 if($disk['status'] == "delete"){
417 $ldap->cd($disk_dn);
418 $ldap->rmdir_recursive($disk_dn);
419 show_ldap_error($ldap->get_error(), _("Removing FAI partition table failed"));
420 }elseif($disk['status']== "edited"){
421 if(empty($disk_attrs['description'])){
422 $disk_attrs['description']=array();
423 }
424 $ldap->cd($disk_dn);
425 $this->cleanup();
426 $ldap->modify ($disk_attrs);
427 show_ldap_error($ldap->get_error(), _("Saving FAI partition table failed"));
428 }elseif($disk['status']== "new"){
429 if(empty($disk_attrs['description'])){
430 unset($disk_attrs['description']);
431 }
432 $ldap->cd($this->config->current['BASE']);
433 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $disk_dn));
434 $ldap->cd($disk_dn);
435 $ldap->add($disk_attrs);
436 show_ldap_error($ldap->get_error(), _("Saving FAI partition table failed"));
437 }else{
438 print_red("unknown status while saving disks");
439 }
441 $this->handle_object_tagging($disk_dn, $this->gosaUnitTag);
443 /* Collect all opperations. Delete first than add new entries .*/
444 $Todo['delete'] = array();
445 $Todo['rest'] = array();
447 /* Skip partition handling if current disk is marked as deleted */
448 if($disk['status']!="delete"){
450 /* Add all partitions */
451 foreach($disk['partitions'] as $key => $partition){
453 /* Create attribute array */
454 $partition_attrs = array();
455 foreach($partition as $key => $value){
456 if(!empty($value)){
457 $partition_attrs[$key]=$value;
458 }else{
459 unset($partition_attrs[$key]);
460 }
461 }
463 /* Create partition dn and add necessary attributes */
464 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
465 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
466 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
468 /* Unset status attributes */
469 unset($partition_attrs['status']);
470 unset($partition_attrs['old_cn']);
472 /* We currently use the copy & paste method */
473 if($this->copy_paste_mode){
474 $partition['status']="new";
475 }
477 /* Check if this partition is realy new .. */
478 if($partition['status']=="new"){
479 $ldap->cat($partition_dn,array("objectClass"));
480 if($ldap->count()){
481 $partition['status']="edited";
482 }
483 }
485 /* Set mount point top swap if it is emtpy */
486 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
487 $partition_attrs['FAImountPoint']="swap";
488 }
490 /* Collect all operations */
491 if(($partition['status'] == "delete")&&($disk['status']!="new")){
492 $Todo['delete'][$partition_dn] = $partition_attrs;
493 }elseif($partition['status'] == "new"){
494 $Todo['rest'][$partition_dn] = $partition_attrs;
495 }elseif($partition['status'] == "edited"){
496 $Todo['rest'][$partition_dn] = $partition_attrs;
497 }
498 }
499 }
501 /* First of all, delete old entries */
502 foreach($Todo['delete'] as $partition_dn => $attrs){
503 $ldap->cd($partition_dn);
504 $ldap->rmdir_recursive($partition_dn);
505 show_ldap_error($ldap->get_error(), _("Removing FAI partition table entry failed"));
506 }
508 /* Add/edit entries */
509 foreach($Todo['rest'] as $partition_dn => $partition_attrs){
511 /* Check if entry exists */
512 $ldap->cat($partition_dn);
513 if($ldap->count()){
515 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for partitions */
516 $attrs = $ldap->fetch();
517 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
518 $partition_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
519 }
520 if(empty($partition_attrs['description'])){
521 $partition_attrs['description']=array();
522 }
523 $ldap->cd($partition_dn);
524 $this->cleanup();
525 $ldap->modify ($partition_attrs);
526 show_ldap_error($ldap->get_error(), _("Saving FAI partition table entry failed"));
527 }else{
529 if(empty($partition_attrs['description'])){
530 unset($partition_attrs['description']);
531 }
533 $ldap->cd($this->config->current['BASE']);
534 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $partition_dn));
535 $ldap->cd($partition_dn);
536 $ldap->add($partition_attrs);
537 show_ldap_error($ldap->get_error(), _("Saving FAI partition table entry failed"));
538 }
539 }
540 $this->handle_object_tagging($partition_dn, $this->gosaUnitTag);
541 }
542 $this->handle_post_events("add");
543 }
546 /* return copy & paste dialog
547 */
548 function getCopyDialog()
549 {
550 /* Ask for cn */
551 $smarty = get_smarty();
552 $smarty->assign("cn" ,$this->cn);
553 $str = $smarty->fetch(get_template_path("paste_fai_object.tpl",TRUE));
554 $ret = array();
555 $ret['string'] = $str;
556 $ret['status'] = "";
557 return($ret);
558 }
560 /* Get posted cn */
561 function saveCopyDialog()
562 {
563 if(isset($_POST['cn'])){
564 $this->cn = $_POST['cn'];
565 }
566 }
567 }
569 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
570 ?>