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
15 var $dialog = NULL; // a dialog, e.g. new disk dialog
17 var $FAIstate = "";
18 var $base = "";
19 var $release = "";
20 var $copy_paste_mode = false;
21 var $cut_paste_mode = false;
23 var $CopyPasteVars = array("disks");
25 function faiPartitionTable ($config, $dn= NULL)
26 {
27 /* Load Attributes */
28 plugin::plugin ($config, $dn);
30 $this->acl ="#all#";
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 * First read disks from ldap ... and then the partition definitions for the disks.
35 */
36 if($dn != "new"){
37 $this->dn =$dn;
39 /* Set acls
40 */
41 $ui = get_userinfo();
42 $acl = get_permissions ($this->dn, $ui->subtreeACL);
43 $acli = get_module_permission($acl, "FAIclass", $this->dn);
44 $this->acl=$acli;
46 /* Get FAIstate
47 */
48 if(isset($this->attrs['FAIstate'][0])){
49 $this->FAIstate = $this->attrs['FAIstate'][0];
50 }
52 /* Read all disks from ldap taht are defined fot this partition table
53 */
54 $ldap = $this->config->get_ldap_link();
55 $ldap->cd ($this->dn);
56 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
57 while($object = $ldap->fetch()){
58 $this->disks[$object['cn'][0]]['status'] = "edited";
59 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
60 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
61 if(isset($object['description'][0])){
62 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
63 }else{
64 $this->disks[$object['cn'][0]]['description'] = "";
65 }
66 $this->disks[$object['cn'][0]]['partitions'] = array();
67 }
69 /* read all partitions for each disk
70 */
71 foreach($this->disks as $name => $disk){
72 $ldap->cd ($disk['dn']);
73 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
74 while($partition = $ldap->fetch()){
76 /* remove count ... from ldap result
77 */
78 foreach($partition as $key=>$val){
79 if((is_numeric($key))||($key=="count")||($key=="dn")){
80 unset($partition[$key]);
81 }else{
82 $partition[$key] = $val[0];
83 }
84 }
86 /* Append fetched partitions
87 */
88 $partition['status']="edited";
89 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
90 }
91 }
92 }
93 ksort($this->disks);
94 }
96 function execute()
97 {
98 /* Call parent execute */
99 plugin::execute();
101 /* Fill templating stuff */
102 $smarty= get_smarty();
103 $display= "";
105 /* Add Disk to this Partitionset
106 * This code adds a new HDD to the disks
107 * A new Dialog will be opened
108 */
109 if(isset($_POST['AddDisk'])){
110 $usedDiskNames =array();
111 foreach($this->disks as $key=>$disk){
112 $usedDiskNames[]= $key;
113 }
114 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
115 $this->dialog->acl = $this->acl;
116 $this->dialog->FAIstate = $this->FAIstate;
117 $this->is_dialog = true;
118 }
120 /* Edit disk.
121 * Open dialog which allows us to edit the selected entry
122 */
124 if($this->dn != "new"){
125 $_SESSION['objectinfo']= $this->dn;
126 }
128 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
129 $usedDiskNames =array();
131 $Udisk = $_POST['disks'][0];
133 foreach($this->disks as $key=>$disk){
134 if($key != $Udisk){
135 $usedDiskNames[]= $key;
136 }
137 }
138 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
139 $this->dialog->acl = $this->acl;
140 $this->dialog->FAIstate = $this->FAIstate;
142 /* Set object info string, which will be displayed in plugin info line */
143 if(isset($this->disks[$Udisk]['dn'])){
144 $_SESSION['objectinfo'] = $this->disks[$Udisk]['dn'];
145 }else{
146 $_SESSION['objectinfo'] = "";
147 }
149 $this->is_dialog = true;
150 }
152 /* Edit aborted, close dialog, without saving anything
153 */
154 if(isset($_POST['CancelDisk'])){
155 unset($this->dialog);
156 $this->dialog = NULL;
157 $this->is_dialog=false;
158 }
160 /* Dialog saved
161 * Save given data from Dialog, if no error is occured
162 */
163 if(isset($_POST['SaveDisk'])){
165 if($this->FAIstate != "freeze"){
166 $this->dialog->save_object();
167 if(count($this->dialog->check())){
168 foreach($this->dialog->check() as $msg){
169 print_red($msg);
170 }
171 }else{
172 $disk = $this->dialog->save();
173 if(isset($disk['rename'])){
174 if($this->disks[$disk['rename']['from']]['status']=="edited"){
175 $this->disks[$disk['rename']['from']]['status']="delete";
176 }else{
177 unset($this->disks[$disk['rename']['from']]);
178 }
180 foreach($disk['partitions'] as $key => $val){
181 if($disk['partitions'][$key]['status']!="delete"){
182 $disk['partitions'][$key]['status']= "new";
183 }
184 }
186 $disk['status']="new";
187 $disk['cn']= $disk['rename']['to'];
188 }
190 $this->disks[$disk['cn']]=$disk;
191 unset($this->dialog);
192 $this->dialog = NULL;
193 $this->is_dialog=false;
194 ksort($this->disks);
195 }
196 }else{
197 $this->dialog = NULL;
198 $this->is_dialog=false;
199 }
200 }
202 /* Delete selected disk drive from list
203 * Assign delete status for all its partitions
204 */
205 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
206 if($this->FAIstate != "freeze"){
207 foreach($_POST['disks'] as $disk) {
208 if($this->disks[$disk]['status']=="edited"){
209 $this->disks[$disk."-delete"]=$this->disks[$disk];
210 unset($this->disks[$disk]);
211 $disk = $disk."-delete";
212 $this->disks[$disk]['status']="delete";
213 foreach($this->disks[$disk]['partitions'] as $name => $value ){
214 if($value['status']=="edited"){
215 $this->disks[$disk]['partitions'][$name]['status']="delete";
216 }else{
217 unset($this->disks[$disk]['partitions'][$name]);
218 }
219 }
220 }else{
221 unset($this->disks[$disk]);
222 }
223 }
224 }
225 }
227 /* Display dialog if one is defined
228 */
229 if(isset($this->dialog)){
230 $this->dialog->save_object();
231 return($this->dialog->execute());
232 }
234 /* Assign all attributes to smarty engine
235 */
236 foreach($this->attributes as $attrs){
237 $smarty->assign($attrs,$this->$attrs);
238 if($this->$attrs){
239 $smarty->assign($attrs."CHK"," ");
240 }else{
241 $smarty->assign($attrs."CHK"," disabled ");
242 }
243 }
245 foreach($this->attributes as $attr){
246 $smarty->assign($attr."ACL",chkacl($this->acl,$attr));
247 }
249 $disks = $this->getDisks();
250 $smarty->assign("disks" ,$disks);
251 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
252 return($display);
253 }
255 function getDisks(){
256 /* Return all available disks for this partition table
257 * Return in listBox friendly array
258 */
259 $a_return = array();
260 foreach($this->disks as $key => $disk){
261 if($disk['status'] != "delete"){
262 $cnt=0;
263 foreach($disk['partitions'] as $val){
264 if($val['status']!="delete"){
265 $cnt ++;
266 }
267 }
268 if(!empty($disk['description'])){
269 if($cnt == 1){
270 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
271 }else{
272 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
273 }
274 }else{
275 if($cnt == 1){
276 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
277 }else{
278 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
279 }
280 }
281 }
282 }
283 return($a_return);
284 }
287 /* Delete me, and all my subtrees
288 */
289 function remove_from_parent()
290 {
291 $ldap = $this->config->get_ldap_link();
292 $ldap->cd ($this->dn);
293 $ldap->rmdir_recursive($this->dn);
294 $this->handle_post_events("remove");
296 /* This cannot be removed... */
297 }
300 /* Save data to object
301 */
302 function save_object()
303 {
304 if($this->FAIstate == "freeze") return;
305 plugin::save_object();
306 foreach($this->attributes as $attrs){
307 if(isset($_POST[$attrs])){
308 $this->$attrs = $_POST[$attrs];
309 }
310 }
311 }
314 /* Check supplied data */
315 function check()
316 {
317 /* Call common method to give check the hook */
318 $message= plugin::check();
320 /* If this is a new script, check if a script with this name already exists */
321 if(!empty($this->release) && ($this->copy_paste_mode || $this->cut_paste_mode) ){
323 /* Check if current name is already used for fai scripts in selected release */
324 $dn = 'cn='.$this->cn.",ou=disk,".$this->release;
325 $ldap = $this->config->get_ldap_link();
326 $ldap->cat($dn);
327 if($ldap->count()){
329 $r =convert_department_dn($this->release);;
330 $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);
331 }
332 }
333 return ($message);
334 }
337 /* Save to LDAP */
338 function save()
339 {
341 plugin::save();
342 /* Save current settings.
343 * 1 : We must save the partition table, with its description and cn
344 * 2 : Append Disk with cn and description.
345 * 3 : Save partitions for each disk
346 */
348 /* Copy & Paste : Ensure that FAIstate is copied too */
349 if($this->copy_paste_mode && preg_match("/freeze/",$this->FAIstate)){
350 $this->attrs['FAIstate'] = $this->FAIstate;
351 }
353 $ldap = $this->config->get_ldap_link();
355 if($this->new){
356 $ldap->cd($this->config->current['BASE']);
357 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
358 $ldap->cd($this->dn);
359 $ldap->add($this->attrs);
360 }else{
361 /* Add partition table to ldap
362 */
363 $ldap->cd($this->dn);
364 $this->cleanup();
365 $ldap->modify ($this->attrs);
366 }
367 show_ldap_error($ldap->get_error(), _("Saving FAI partition table base failed"));
369 /* Do object tagging */
370 $this->handle_object_tagging();
372 /* Sort entries, because we must delete entries with status="delete" first */
373 $order = array();
374 foreach($this->disks as $key => $disk){
375 if($disk['status'] == "delete"){
376 $order[$key] = $disk;
377 }
378 }
379 foreach($this->disks as $key => $disk){
380 if($disk['status'] != "delete"){
381 $order[$key] = $disk;
382 }
383 }
385 /* Append all disks to ldap */
386 foreach($order as $cn=>$disk){
387 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
388 $disk_attrs['cn'] = $disk['cn'];
389 $disk_attrs['description'] = $disk['description'];
390 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
392 /* We currently use the copy & paste method */
393 if($this->copy_paste_mode){
394 $disk['status'] = "new";
395 }
397 if($disk['status']=="new"){
398 $ldap->cat($disk_dn,array("objectClass"));
399 if($ldap->count()){
400 $disk['status']="edited";
401 }
402 }
404 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for disks */
405 $ldap->cat($disk_dn,array("objectClass"));
406 $attrs = $ldap->fetch();
407 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
408 $disk_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
409 }
411 if($disk['status'] == "delete"){
412 $ldap->cd($disk_dn);
413 $ldap->rmdir_recursive($disk_dn);
414 show_ldap_error($ldap->get_error(), _("Removing FAI partition table failed"));
415 }elseif($disk['status']== "edited"){
416 if(empty($disk_attrs['description'])){
417 $disk_attrs['description']=array();
418 }
419 $ldap->cd($disk_dn);
420 $this->cleanup();
421 $ldap->modify ($disk_attrs);
422 show_ldap_error($ldap->get_error(), _("Saving FAI partition table failed"));
423 }elseif($disk['status']== "new"){
424 if(empty($disk_attrs['description'])){
425 unset($disk_attrs['description']);
426 }
427 $ldap->cd($this->config->current['BASE']);
428 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $disk_dn));
429 $ldap->cd($disk_dn);
430 $ldap->add($disk_attrs);
431 show_ldap_error($ldap->get_error(), _("Saving FAI partition table failed"));
432 }else{
433 print_red("unknown status while saving disks");
434 }
436 $this->handle_object_tagging($disk_dn, $this->gosaUnitTag);
438 /* Collect all opperations. Delete first than add new entries .*/
439 $Todo['delete'] = array();
440 $Todo['rest'] = array();
442 /* Skip partition handling if current disk is marked as deleted */
443 if($disk['status']!="delete"){
445 /* Add all partitions */
446 foreach($disk['partitions'] as $key => $partition){
448 /* Create attribute array */
449 $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 /* Create partition dn and add necessary attributes */
459 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
460 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
461 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
463 /* Unset status attributes */
464 unset($partition_attrs['status']);
465 unset($partition_attrs['old_cn']);
467 /* We currently use the copy & paste method */
468 if($this->copy_paste_mode){
469 $partition['status']="new";
470 }
472 /* Check if this partition is realy new .. */
473 if($partition['status']=="new"){
474 $ldap->cat($partition_dn,array("objectClass"));
475 if($ldap->count()){
476 $partition['status']="edited";
477 }
478 }
480 /* Set mount point top swap if it is emtpy */
481 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
482 $partition_attrs['FAImountPoint']="swap";
483 }
485 /* Collect all operations */
486 if(($partition['status'] == "delete")&&($disk['status']!="new")){
487 $Todo['delete'][$partition_dn] = $partition_attrs;
488 }elseif($partition['status'] == "new"){
489 $Todo['rest'][$partition_dn] = $partition_attrs;
490 }elseif($partition['status'] == "edited"){
491 $Todo['rest'][$partition_dn] = $partition_attrs;
492 }
493 }
494 }
496 /* First of all, delete old entries */
497 foreach($Todo['delete'] as $partition_dn => $attrs){
498 $ldap->cd($partition_dn);
499 $ldap->rmdir_recursive($partition_dn);
500 show_ldap_error($ldap->get_error(), _("Removing FAI partition table entry failed"));
501 }
503 /* Add/edit entries */
504 foreach($Todo['rest'] as $partition_dn => $partition_attrs){
506 /* Check if entry exists */
507 $ldap->cat($partition_dn);
508 if($ldap->count()){
510 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for partitions */
511 $attrs = $ldap->fetch();
512 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
513 $partition_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
514 }
515 if(empty($partition_attrs['description'])){
516 $partition_attrs['description']=array();
517 }
518 if(empty($partition_attrs['FAIfsOptions'])){
519 $partition_attrs['FAIfsOptions']=array();
520 }
521 if(empty($partition_attrs['FAImountOptions'])){
522 $partition_attrs['FAImountOptions']=array();
523 }
524 if(empty($partition_attrs['FAIpartitionFlags'])){
525 $partition_attrs['FAIpartitionFlags']=array();
526 }
527 $ldap->cd($partition_dn);
528 $this->cleanup();
529 $ldap->modify ($partition_attrs);
530 show_ldap_error($ldap->get_error(), _("Saving FAI partition table entry failed"));
531 }else{
533 if(empty($partition_attrs['description'])){
534 unset($partition_attrs['description']);
535 }
537 $ldap->cd($this->config->current['BASE']);
538 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $partition_dn));
539 $ldap->cd($partition_dn);
540 if (isset($partition_attrs['gosaUnitTag']) && !in_array_ics("gosaAdministrativeUnitTag",$partition_attrs['objectClass'])){
541 $partition_attrs['objectClass'][]= "gosaAdministrativeUnitTag";
542 }
543 $ldap->add($partition_attrs);
544 show_ldap_error($ldap->get_error(), _("Saving FAI partition table entry failed"));
545 }
546 $this->handle_object_tagging($partition_dn, $this->gosaUnitTag);
547 }
548 }
549 $this->handle_post_events("add");
550 }
553 /* return copy & paste dialog
554 */
555 function getCopyDialog()
556 {
557 /* Ask for cn */
558 $smarty = get_smarty();
559 $smarty->assign("cn" ,$this->cn);
560 $str = $smarty->fetch(get_template_path("paste_fai_object.tpl",TRUE));
561 $ret = array();
562 $ret['string'] = $str;
563 $ret['status'] = "";
564 return($ret);
565 }
567 /* Get posted cn */
568 function saveCopyDialog()
569 {
570 if(isset($_POST['cn'])){
571 $this->cn = $_POST['cn'];
572 }
573 }
574 }
576 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
577 ?>