e306340590ebaf6c99cb13896888ae8eb40287a1
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;
27 var $CopyPasteVars = array("disks","FAIstate");
29 function faiPartitionTable ($config, $dn= NULL)
30 {
31 /* Load Attributes */
32 plugin::plugin ($config, $dn);
34 $this->acl ="#all#";
36 /* If "dn==new" we try to create a new entry
37 * Else we must read all objects from ldap which belong to this entry.
38 * First read disks from ldap ... and then the partition definitions for the disks.
39 */
40 if($dn != "new"){
41 $this->dn =$dn;
43 /* Set acls
44 */
45 $ui = get_userinfo();
46 $acl = get_permissions ($this->dn, $ui->subtreeACL);
47 $acli = get_module_permission($acl, "FAIclass", $this->dn);
48 $this->acl=$acli;
50 /* Get FAIstate
51 */
52 if(isset($this->attrs['FAIstate'][0])){
53 $this->FAIstate = $this->attrs['FAIstate'][0];
54 }
56 /* Read all disks from ldap taht are defined fot this partition table
57 */
58 $ldap = $this->config->get_ldap_link();
59 $ldap->cd ($this->dn);
60 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
61 while($object = $ldap->fetch()){
62 $this->disks[$object['cn'][0]]['status'] = "edited";
63 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
64 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
65 if(isset($object['description'][0])){
66 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
67 }else{
68 $this->disks[$object['cn'][0]]['description'] = "";
69 }
70 $this->disks[$object['cn'][0]]['partitions'] = array();
71 }
73 /* read all partitions for each disk
74 */
75 foreach($this->disks as $name => $disk){
76 $ldap->cd ($disk['dn']);
77 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
78 while($partition = $ldap->fetch()){
80 /* remove count ... from ldap result
81 */
82 foreach($partition as $key=>$val){
83 if((is_numeric($key))||($key=="count")||($key=="dn")){
84 unset($partition[$key]);
85 }else{
86 $partition[$key] = $val[0];
87 }
88 }
90 /* Append fetched partitions
91 */
92 $partition['status']="edited";
93 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
94 }
95 }
96 }
97 ksort($this->disks);
98 }
100 function execute()
101 {
102 /* Call parent execute */
103 plugin::execute();
105 /* Fill templating stuff */
106 $smarty= get_smarty();
107 $display= "";
109 /* Add Disk to this Partitionset
110 * This code adds a new HDD to the disks
111 * A new Dialog will be opened
112 */
113 if(isset($_POST['AddDisk'])){
114 $usedDiskNames =array();
115 foreach($this->disks as $key=>$disk){
116 $usedDiskNames[]= $key;
117 }
118 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
119 $this->dialog->acl = $this->acl;
120 $this->dialog->FAIstate = $this->FAIstate;
121 $this->is_dialog = true;
122 }
124 /* Edit disk.
125 * Open dialog which allows us to edit the selected entry
126 */
128 if($this->dn != "new"){
129 $_SESSION['objectinfo']= $this->dn;
130 }
132 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
133 $usedDiskNames =array();
135 $Udisk = $_POST['disks'][0];
137 foreach($this->disks as $key=>$disk){
138 if($key != $Udisk){
139 $usedDiskNames[]= $key;
140 }
141 }
142 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
143 $this->dialog->acl = $this->acl;
144 $this->dialog->FAIstate = $this->FAIstate;
146 /* Set object info string, which will be displayed in plugin info line */
147 if(isset($this->disks[$Udisk]['dn'])){
148 $_SESSION['objectinfo'] = $this->disks[$Udisk]['dn'];
149 }else{
150 $_SESSION['objectinfo'] = "";
151 }
153 $this->is_dialog = true;
154 }
156 /* Edit aborted, close dialog, without saving anything
157 */
158 if(isset($_POST['CancelDisk'])){
159 unset($this->dialog);
160 $this->dialog = NULL;
161 $this->is_dialog=false;
162 }
164 /* Dialog saved
165 * Save given data from Dialog, if no error is occured
166 */
167 if(isset($_POST['SaveDisk'])){
169 if($this->FAIstate != "freeze"){
170 $this->dialog->save_object();
171 if(count($this->dialog->check())){
172 foreach($this->dialog->check() as $msg){
173 print_red($msg);
174 }
175 }else{
176 $disk = $this->dialog->save();
177 if(isset($disk['rename'])){
178 if($this->disks[$disk['rename']['from']]['status']=="edited"){
179 $this->disks[$disk['rename']['from']]['status']="delete";
180 }else{
181 unset($this->disks[$disk['rename']['from']]);
182 }
184 foreach($disk['partitions'] as $key => $val){
185 if($disk['partitions'][$key]['status']!="delete"){
186 $disk['partitions'][$key]['status']= "new";
187 }
188 }
190 $disk['status']="new";
191 $disk['cn']= $disk['rename']['to'];
192 }
194 $this->disks[$disk['cn']]=$disk;
195 unset($this->dialog);
196 $this->dialog = NULL;
197 $this->is_dialog=false;
198 ksort($this->disks);
199 }
200 }else{
201 $this->dialog = NULL;
202 $this->is_dialog=false;
203 }
204 }
206 /* Delete selected disk drive from list
207 * Assign delete status for all its partitions
208 */
209 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
210 if($this->FAIstate != "freeze"){
211 foreach($_POST['disks'] as $disk) {
212 if($this->disks[$disk]['status']=="edited"){
213 $this->disks[$disk."-delete"]=$this->disks[$disk];
214 unset($this->disks[$disk]);
215 $disk = $disk."-delete";
216 $this->disks[$disk]['status']="delete";
217 foreach($this->disks[$disk]['partitions'] as $name => $value ){
218 if($value['status']=="edited"){
219 $this->disks[$disk]['partitions'][$name]['status']="delete";
220 }else{
221 unset($this->disks[$disk]['partitions'][$name]);
222 }
223 }
224 }else{
225 unset($this->disks[$disk]);
226 }
227 }
228 }
229 }
231 /* Display dialog if one is defined
232 */
233 if(isset($this->dialog)){
234 $this->dialog->save_object();
235 return($this->dialog->execute());
236 }
238 /* Assign all attributes to smarty engine
239 */
240 foreach($this->attributes as $attrs){
241 $smarty->assign($attrs,$this->$attrs);
242 if($this->$attrs){
243 $smarty->assign($attrs."CHK"," ");
244 }else{
245 $smarty->assign($attrs."CHK"," disabled ");
246 }
247 }
249 foreach($this->attributes as $attr){
250 $smarty->assign($attr."ACL",chkacl($this->acl,$attr));
251 }
253 $disks = $this->getDisks();
254 $smarty->assign("disks" ,$disks);
255 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
256 return($display);
257 }
259 function getDisks(){
260 /* Return all available disks for this partition table
261 * Return in listBox friendly array
262 */
263 $a_return = array();
264 foreach($this->disks as $key => $disk){
265 if($disk['status'] != "delete"){
266 $cnt=0;
267 foreach($disk['partitions'] as $val){
268 if($val['status']!="delete"){
269 $cnt ++;
270 }
271 }
272 if(!empty($disk['description'])){
273 if($cnt == 1){
274 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
275 }else{
276 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
277 }
278 }else{
279 if($cnt == 1){
280 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
281 }else{
282 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
283 }
284 }
285 }
286 }
287 return($a_return);
288 }
291 /* Delete me, and all my subtrees
292 */
293 function remove_from_parent()
294 {
295 $ldap = $this->config->get_ldap_link();
296 $ldap->cd ($this->dn);
297 $ldap->rmdir_recursive($this->dn);
298 $this->handle_post_events("remove");
300 /* This cannot be removed... */
301 }
304 /* Save data to object
305 */
306 function save_object()
307 {
308 if($this->FAIstate == "freeze") return;
309 plugin::save_object();
310 foreach($this->attributes as $attrs){
311 if(isset($_POST[$attrs])){
312 $this->$attrs = $_POST[$attrs];
313 }
314 }
315 }
318 /* Check supplied data */
319 function check()
320 {
321 /* Call common method to give check the hook */
322 $message= plugin::check();
324 /* If this is a new script, check if a script with this name already exists */
325 if(!empty($this->release) && $this->copy_paste_mode){
327 /* Check if current name is already used for fai scripts in selected release */
328 $dn = 'cn='.$this->cn.",ou=disk,".$this->release;
329 $ldap = $this->config->get_ldap_link();
330 $ldap->cat($dn);
331 if($ldap->count()){
333 $r =convert_department_dn($this->release);;
334 $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);
335 }
336 }
337 return ($message);
338 }
341 /* Save to LDAP */
342 function save()
343 {
345 plugin::save();
346 /* Save current settings.
347 * 1 : We must save the partition table, with its description and cn
348 * 2 : Append Disk with cn and description.
349 * 3 : Save partitions for each disk
350 */
352 /* Copy & Paste : Ensure that FAIstate is copied too */
353 if($this->copy_paste_mode && preg_match("/freeze/",$this->FAIstate)){
354 $this->attrs['FAIstate'] = $this->FAIstate;
355 }
357 $ldap = $this->config->get_ldap_link();
359 if($this->new){
360 $ldap->cd($this->config->current['BASE']);
361 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
362 $ldap->cd($this->dn);
363 $ldap->add($this->attrs);
364 }else{
365 /* Add partition table to ldap
366 */
367 $ldap->cd($this->dn);
368 $this->cleanup();
369 $ldap->modify ($this->attrs);
370 }
371 show_ldap_error($ldap->get_error(), _("Saving FAI partition table base failed"));
373 /* Do object tagging */
374 $this->handle_object_tagging();
376 /* Sort entries, because we must delete entries with status="delete" first */
377 $order = array();
378 foreach($this->disks as $key => $disk){
379 if($disk['status'] == "delete"){
380 $order[$key] = $disk;
381 }
382 }
383 foreach($this->disks as $key => $disk){
384 if($disk['status'] != "delete"){
385 $order[$key] = $disk;
386 }
387 }
389 /* Append all disks to ldap */
390 foreach($order as $cn=>$disk){
391 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
392 $disk_attrs['cn'] = $disk['cn'];
393 $disk_attrs['description'] = $disk['description'];
394 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
396 /* We currently use the copy & paste method */
397 if($this->copy_paste_mode){
398 $disk['status'] = "new";
399 }
401 if($disk['status']=="new"){
402 $ldap->cat($disk_dn,array("objectClass"));
403 if($ldap->count()){
404 $disk['status']="edited";
405 }
406 }
408 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for disks */
409 $ldap->cat($disk_dn,array("objectClass"));
410 $attrs = $ldap->fetch();
411 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
412 $disk_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
413 }
415 if($disk['status'] == "delete"){
416 $ldap->cd($disk_dn);
417 $ldap->rmdir_recursive($disk_dn);
418 show_ldap_error($ldap->get_error(), _("Removing FAI partition table failed"));
419 }elseif($disk['status']== "edited"){
420 if(empty($disk_attrs['description'])){
421 $disk_attrs['description']=array();
422 }
423 $ldap->cd($disk_dn);
424 $this->cleanup();
425 $ldap->modify ($disk_attrs);
426 show_ldap_error($ldap->get_error(), _("Saving FAI partition table failed"));
427 }elseif($disk['status']== "new"){
428 if(empty($disk_attrs['description'])){
429 unset($disk_attrs['description']);
430 }
431 $ldap->cd($this->config->current['BASE']);
432 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $disk_dn));
433 $ldap->cd($disk_dn);
434 $ldap->add($disk_attrs);
435 show_ldap_error($ldap->get_error(), _("Saving FAI partition table failed"));
436 }else{
437 print_red("unknown status while saving disks");
438 }
440 $this->handle_object_tagging($disk_dn, $this->gosaUnitTag);
442 /* Collect all opperations. Delete first than add new entries .*/
443 $Todo['delete'] = array();
444 $Todo['rest'] = array();
446 /* Skip partition handling if current disk is marked as deleted */
447 if($disk['status']!="delete"){
449 /* Add all partitions */
450 foreach($disk['partitions'] as $key => $partition){
452 /* Create attribute array */
453 $partition_attrs = array();
454 foreach($partition as $key => $value){
455 if(!empty($value)){
456 $partition_attrs[$key]=$value;
457 }else{
458 unset($partition_attrs[$key]);
459 }
460 }
462 /* Create partition dn and add necessary attributes */
463 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
464 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
465 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
467 /* Unset status attributes */
468 unset($partition_attrs['status']);
469 unset($partition_attrs['old_cn']);
471 /* We currently use the copy & paste method */
472 if($this->copy_paste_mode){
473 $partition['status']="new";
474 }
476 /* Check if this partition is realy new .. */
477 if($partition['status']=="new"){
478 $ldap->cat($partition_dn,array("objectClass"));
479 if($ldap->count()){
480 $partition['status']="edited";
481 }
482 }
484 /* Set mount point top swap if it is emtpy */
485 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
486 $partition_attrs['FAImountPoint']="swap";
487 }
489 /* Collect all operations */
490 if(($partition['status'] == "delete")&&($disk['status']!="new")){
491 $Todo['delete'][$partition_dn] = $partition_attrs;
492 }elseif($partition['status'] == "new"){
493 $Todo['rest'][$partition_dn] = $partition_attrs;
494 }elseif($partition['status'] == "edited"){
495 $Todo['rest'][$partition_dn] = $partition_attrs;
496 }
497 }
498 }
500 /* First of all, delete old entries */
501 foreach($Todo['delete'] as $partition_dn => $attrs){
502 $ldap->cd($partition_dn);
503 $ldap->rmdir_recursive($partition_dn);
504 show_ldap_error($ldap->get_error(), _("Removing FAI partition table entry failed"));
505 }
507 /* Add/edit entries */
508 foreach($Todo['rest'] as $partition_dn => $partition_attrs){
510 /* Check if entry exists */
511 $ldap->cat($partition_dn);
512 if($ldap->count()){
514 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for partitions */
515 $attrs = $ldap->fetch();
516 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
517 $partition_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
518 }
519 if(empty($partition_attrs['description'])){
520 $partition_attrs['description']=array();
521 }
522 $ldap->cd($partition_dn);
523 $this->cleanup();
524 $ldap->modify ($partition_attrs);
525 show_ldap_error($ldap->get_error(), _("Saving FAI partition table entry failed"));
526 }else{
528 if(empty($partition_attrs['description'])){
529 unset($partition_attrs['description']);
530 }
532 $ldap->cd($this->config->current['BASE']);
533 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $partition_dn));
534 $ldap->cd($partition_dn);
535 $ldap->add($partition_attrs);
536 show_ldap_error($ldap->get_error(), _("Saving FAI partition table entry failed"));
537 }
538 }
539 $this->handle_object_tagging($partition_dn, $this->gosaUnitTag);
540 }
541 $this->handle_post_events("add");
542 }
543 }
545 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
546 ?>