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 $ui;
25 function faiPartitionTable ($config, $dn= NULL)
26 {
27 /* Load Attributes */
28 plugin::plugin ($config, $dn);
30 $this->acl ="#all#";
32 $this->ui = get_userinfo();
34 /* If "dn==new" we try to create a new entry
35 * Else we must read all objects from ldap which belong to this entry.
36 * First read disks from ldap ... and then the partition definitions for the disks.
37 */
38 if($dn != "new"){
39 $this->dn =$dn;
41 /* Get FAIstate
42 */
43 if(isset($this->attrs['FAIstate'][0])){
44 $this->FAIstate = $this->attrs['FAIstate'][0];
45 }
47 /* Read all disks from ldap taht are defined fot this partition table
48 */
49 $ldap = $this->config->get_ldap_link();
50 $ldap->cd ($this->dn);
51 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
52 while($object = $ldap->fetch()){
54 /* Skip objects, that are tagged as removed */
55 if(isset($object['FAIstate'][0])){
56 if(preg_match("/removed$/",$object['FAIstate'][0])){
57 continue;
58 }
59 }
61 $this->disks[$object['cn'][0]]['status'] = "edited";
62 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
63 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
64 if(isset($object['description'][0])){
65 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
66 }else{
67 $this->disks[$object['cn'][0]]['description'] = "";
68 }
69 $this->disks[$object['cn'][0]]['partitions'] = array();
70 }
72 /* read all partitions for each disk
73 */
74 foreach($this->disks as $name => $disk){
75 $ldap->cd ($disk['dn']);
76 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
77 while($partition = $ldap->fetch()){
79 /* Skip objects, that are tagged as removed */
80 if(isset($partition['FAIstate'][0])){
81 if(preg_match("/removed$/",$partition['FAIstate'][0])){
82 continue;
83 }
84 }
86 /* remove count ... from ldap result
87 */
88 foreach($partition as $key=>$val){
89 if((is_numeric($key))||($key=="count")||($key=="dn")){
90 unset($partition[$key]);
91 }else{
92 $partition[$key] = $val[0];
93 }
94 }
96 /* Append fetched partitions
97 */
98 $partition['status']="edited";
99 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
100 }
101 }
102 }
103 ksort($this->disks);
104 }
107 function acl_base_for_current_object($dn)
108 {
109 if($dn == "new"){
110 if($this->dn == "new"){
111 $dn= $_SESSION['CurrentMainBase'];
112 }else{
113 $dn = $this->dn;
114 }
115 }
116 return($dn);
117 }
120 function execute()
121 {
122 /* Call parent execute */
123 plugin::execute();
125 /* Fill templating stuff */
126 $smarty= get_smarty();
127 $display= "";
129 /* Add Disk to this Partitionset
130 * This code adds a new HDD to the disks
131 * A new Dialog will be opened
132 */
133 if(isset($_POST['AddDisk'])){
134 $usedDiskNames =array();
135 foreach($this->disks as $key=>$disk){
136 $usedDiskNames[]= $key;
137 }
138 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
139 $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
140 $this->dialog->set_acl_category("fai");
141 $this->dialog->FAIstate = $this->FAIstate;
142 $this->is_dialog = true;
143 }
145 /* Edit disk.
146 * Open dialog which allows us to edit the selected entry
147 */
149 if($this->dn != "new"){
150 $_SESSION['objectinfo']= $this->dn;
151 }
153 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
154 $usedDiskNames =array();
156 $Udisk = $_POST['disks'][0];
158 foreach($this->disks as $key=>$disk){
159 if($key != $Udisk){
160 $usedDiskNames[]= $key;
161 }
162 }
164 /* Set object info string, which will be displayed in plugin info line */
165 if(isset($this->disks[$Udisk]['dn'])){
166 $_SESSION['objectinfo'] = $this->disks[$Udisk]['dn'];
167 $dn = $this->disks[$Udisk]['dn'];
168 }else{
169 $_SESSION['objectinfo'] = "";
170 $dn = "new";
171 }
173 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
174 $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
175 $this->dialog->set_acl_category("fai");
176 $this->dialog->FAIstate = $this->FAIstate;
178 $this->is_dialog = true;
179 }
181 /* Edit aborted, close dialog, without saving anything
182 */
183 if(isset($_POST['CancelDisk'])){
184 unset($this->dialog);
185 $this->dialog = NULL;
186 $this->is_dialog=false;
187 }
189 /* Dialog saved
190 * Save given data from Dialog, if no error is occured
191 */
192 if(isset($_POST['SaveDisk'])){
194 if($this->FAIstate != "freeze"){
195 $this->dialog->save_object();
196 if(count($this->dialog->check())){
197 foreach($this->dialog->check() as $msg){
198 print_red($msg);
199 }
200 }else{
201 $disk = $this->dialog->save();
202 if(isset($disk['rename'])){
203 if($this->disks[$disk['rename']['from']]['status']=="edited"){
204 $this->disks[$disk['rename']['from']]['status']="delete";
205 }else{
206 unset($this->disks[$disk['rename']['from']]);
207 }
209 foreach($disk['partitions'] as $key => $val){
210 if($disk['partitions'][$key]['status']!="delete"){
211 $disk['partitions'][$key]['status']= "new";
212 }
213 }
215 $disk['status']="new";
216 $disk['cn']= $disk['rename']['to'];
217 }
219 $this->disks[$disk['cn']]=$disk;
220 unset($this->dialog);
221 $this->dialog = NULL;
222 $this->is_dialog=false;
223 ksort($this->disks);
224 }
225 }else{
226 $this->dialog = NULL;
227 $this->is_dialog=false;
228 }
229 }
231 /* Delete selected disk drive from list
232 * Assign delete status for all its partitions
233 */
234 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
235 if($this->FAIstate != "freeze"){
236 foreach($_POST['disks'] as $disk) {
237 if($this->disks[$disk]['status']=="edited"){
238 $this->disks[$disk."-delete"]=$this->disks[$disk];
239 unset($this->disks[$disk]);
240 $disk = $disk."-delete";
241 $this->disks[$disk]['status']="delete";
242 foreach($this->disks[$disk]['partitions'] as $name => $value ){
243 if($value['status']=="edited"){
244 $this->disks[$disk]['partitions'][$name]['status']="delete";
245 }else{
246 unset($this->disks[$disk]['partitions'][$name]);
247 }
248 }
249 }else{
250 unset($this->disks[$disk]);
251 }
252 }
253 }
254 }
256 /* Display dialog if one is defined
257 */
258 if(isset($this->dialog)){
259 $this->dialog->save_object();
260 return($this->dialog->execute());
261 }
263 /* Assign all attributes to smarty engine
264 */
265 foreach($this->attributes as $attrs){
266 $smarty->assign($attrs,$this->$attrs);
267 if($this->$attrs){
268 $smarty->assign($attrs."CHK"," ");
269 }else{
270 $smarty->assign($attrs."CHK"," disabled ");
271 }
272 }
274 $dn = $this->acl_base_for_current_object($this->dn);
275 $smarty->assign("sub_object_is_addable",
276 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
277 !preg_match("/freeze/",$this->FAIstate));
279 $tmp = $this->plInfo();
280 foreach($tmp['plProvidedAcls'] as $name => $translated){
281 $smarty->assign($name."ACL",$this->getacl($name));
282 }
283 $disks = $this->getDisks();
284 $smarty->assign("disks" ,$disks);
285 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
286 return($display);
287 }
289 function getDisks(){
290 /* Return all available disks for this partition table
291 * Return in listBox friendly array
292 */
293 $a_return = array();
294 foreach($this->disks as $key => $disk){
296 $dn = "new";
297 if(isset($obj['dn'])){
298 $dn = $obj['dn'];
299 }
300 $dn = $this->acl_base_for_current_object($dn);
301 $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
302 if(preg_match("/(r|w)/",$acl)) {
304 if($disk['status'] != "delete"){
305 $cnt=0;
306 foreach($disk['partitions'] as $val){
307 if($val['status']!="delete"){
308 $cnt ++;
309 }
310 }
311 if(!empty($disk['description'])){
312 if($cnt == 1){
313 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
314 }else{
315 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
316 }
317 }else{
318 if($cnt == 1){
319 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
320 }else{
321 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
322 }
323 }
324 }
325 }
326 }
327 return($a_return);
328 }
331 /* Delete me, and all my subtrees
332 */
333 function remove_from_parent()
334 {
335 $ldap = $this->config->get_ldap_link();
336 $ldap->cd ($this->dn);
338 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $this->dn);
339 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $this->dn);
340 if($_SESSION['faifilter']['branch'] == "main"){
341 $use_dn = $this->dn;
342 }
344 prepare_to_save_FAI_object($use_dn,array(),true);
346 foreach($this->disks as $disk){
348 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
349 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $disk_dn);
350 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $disk_dn);
351 if($_SESSION['faifilter']['branch'] == "main"){
352 $use_dn = $disk_dn;
353 }
354 prepare_to_save_FAI_object($use_dn,array(),true);
356 foreach($disk['partitions'] as $key => $partition){
358 $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;
359 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $partition_dn);
360 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $partition_dn);
361 if($_SESSION['faifilter']['branch'] == "main"){
362 $use_dn = $disk_dn;
363 }
364 prepare_to_save_FAI_object($use_dn,array(),true);
365 }
366 }
367 }
370 /* Save data to object
371 */
372 function save_object()
373 {
374 if($this->FAIstate == "freeze") return;
375 plugin::save_object();
376 foreach($this->attributes as $attrs){
377 if(isset($_POST[$attrs])){
378 $this->$attrs = $_POST[$attrs];
379 }
380 }
381 }
384 /* Check supplied data */
385 function check()
386 {
387 /* Call common method to give check the hook */
388 $message= plugin::check();
390 return ($message);
391 }
394 /* Save to LDAP */
395 function save()
396 {
398 plugin::save();
399 /* Save current settings.
400 * 1 : We must save the partition table, with its description and cn
401 * 2 : Append Disk with cn and description.
402 * 3 : Save partitions for each disk
403 */
405 $ldap = $this->config->get_ldap_link();
407 prepare_to_save_FAI_object($this->dn,$this->attrs);
408 show_ldap_error($ldap->get_error(), sprintf(_("Saving of FAI/partition table with dn '%s' failed."),$this->dn));
410 /* Do object tagging */
411 $this->handle_object_tagging();
413 /* Sort entries, because we must delete entries with status="delete" first */
414 $order = array();
415 foreach($this->disks as $key => $disk){
416 if($disk['status'] == "delete"){
417 $order[$key] = $disk;
418 }
419 }
420 foreach($this->disks as $key => $disk){
421 if($disk['status'] != "delete"){
422 $order[$key] = $disk;
423 }
424 }
426 /* Append all disks to ldap */
427 foreach($order as $cn=>$disk){
428 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
429 $disk_attrs['cn'] = $disk['cn'];
430 $disk_attrs['description'] = $disk['description'];
431 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
433 if($disk['status']=="new"){
434 $ldap->cat($disk_dn,array("objectClass"));
435 if($ldap->count()){
436 $disk['status']="edited";
437 }
438 }
440 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for disks */
441 $ldap->cat($disk_dn,array("objectClass"));
442 $attrs = $ldap->fetch();
443 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
444 $disk_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
445 }
447 if($disk['status'] == "delete"){
448 prepare_to_save_FAI_object($disk_dn,array(),true);
449 $this->handle_post_events("remove");
450 }elseif($disk['status'] == "edited"){
451 prepare_to_save_FAI_object($disk_dn,$disk_attrs);
452 $this->handle_post_events("modify");
453 }elseif($disk['status']=="new"){
454 prepare_to_save_FAI_object($disk_dn,$disk_attrs);
455 $this->handle_post_events("add");
456 }
458 $this->handle_object_tagging($disk_dn, $this->gosaUnitTag);
460 if($disk['status']!="delete")
461 /* Add all partitions */
462 foreach($disk['partitions'] as $key => $partition){
463 $partition_attrs = array();
465 foreach($partition as $key => $value){
466 if(!empty($value)){
467 $partition_attrs[$key]=$value;
468 }else{
469 unset($partition_attrs[$key]);
470 }
471 }
473 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
474 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
475 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
477 unset($partition_attrs['status']);
478 unset($partition_attrs['old_cn']);
480 if($partition['status']=="new"){
481 $ldap->cat($partition_dn,array("objectClass"));
482 if($ldap->count()){
483 $partition['status']="edited";
484 }
485 }
487 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
488 $partition_attrs['FAImountPoint']="swap";
489 }
491 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for partitions */
492 $ldap->cat($partition_dn,array("objectClass"));
493 $attrs = $ldap->fetch();
494 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
495 $partition_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
496 }
498 if($partition['status'] == "delete"){
499 prepare_to_save_FAI_object($partition_dn,array(),true);
500 $this->handle_post_events("remove");
501 }elseif($partition['status'] == "edited"){
502 prepare_to_save_FAI_object($partition_dn,$partition_attrs);
503 $this->handle_post_events("modify");
504 }elseif($partition['status']=="new"){
505 prepare_to_save_FAI_object($partition_dn,$partition_attrs);
506 $this->handle_post_events("add");
507 }
509 $this->handle_object_tagging($partition_dn, $this->gosaUnitTag);
510 }
511 }
512 $this->handle_post_events("add");
513 }
516 /* Return plugin informations for acl handling */
517 function plInfo()
518 {
519 return (array(
520 "plShortName" => _("Partition table"),
521 "plDescription" => _("FAI partition table"),
522 "plSelfModify" => FALSE,
523 "plDepends" => array(),
524 "plPriority" => 26,
525 "plSection" => array("administration"),
526 "plCategory" => array("fai"),
527 "plProvidedAcls" => array(
528 "cn" => _("Name")." ("._("Read only").")",
529 "description" => _("Description"))
530 ));
531 }
532 }
534 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
535 ?>