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 }
103 @log::log("view","fai/".get_class($this),$this->dn);
104 }
105 ksort($this->disks);
106 }
109 function acl_base_for_current_object($dn)
110 {
111 if($dn == "new"){
112 if($this->dn == "new"){
113 $dn= $_SESSION['CurrentMainBase'];
114 }else{
115 $dn = $this->dn;
116 }
117 }
118 return($dn);
119 }
122 function execute()
123 {
124 /* Call parent execute */
125 plugin::execute();
127 /* Fill templating stuff */
128 $smarty= get_smarty();
129 $display= "";
131 /* Add Disk to this Partitionset
132 * This code adds a new HDD to the disks
133 * A new Dialog will be opened
134 */
135 if(isset($_POST['AddDisk'])){
136 $usedDiskNames =array();
137 foreach($this->disks as $key=>$disk){
138 $usedDiskNames[]= $key;
139 }
140 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
141 $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
142 $this->dialog->set_acl_category("fai");
143 $this->dialog->FAIstate = $this->FAIstate;
144 $this->is_dialog = true;
145 }
147 /* Edit disk.
148 * Open dialog which allows us to edit the selected entry
149 */
151 if($this->dn != "new"){
152 $_SESSION['objectinfo']= $this->dn;
153 }
155 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
156 $usedDiskNames =array();
158 $Udisk = $_POST['disks'][0];
160 foreach($this->disks as $key=>$disk){
161 if($key != $Udisk){
162 $usedDiskNames[]= $key;
163 }
164 }
166 /* Set object info string, which will be displayed in plugin info line */
167 if(isset($this->disks[$Udisk]['dn'])){
168 $_SESSION['objectinfo'] = $this->disks[$Udisk]['dn'];
169 $dn = $this->disks[$Udisk]['dn'];
170 }else{
171 $_SESSION['objectinfo'] = "";
172 $dn = "new";
173 }
175 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
176 $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
177 $this->dialog->set_acl_category("fai");
178 $this->dialog->FAIstate = $this->FAIstate;
180 $this->is_dialog = true;
181 }
183 /* Edit aborted, close dialog, without saving anything
184 */
185 if(isset($_POST['CancelDisk'])){
186 unset($this->dialog);
187 $this->dialog = NULL;
188 $this->is_dialog=false;
189 }
191 /* Dialog saved
192 * Save given data from Dialog, if no error is occured
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 print_red($msg);
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 = NULL;
224 $this->is_dialog=false;
225 ksort($this->disks);
226 }
227 }else{
228 $this->dialog = NULL;
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) {
239 if($this->disks[$disk]['status']=="edited"){
240 $this->disks[$disk."-delete"]=$this->disks[$disk];
241 unset($this->disks[$disk]);
242 $disk = $disk."-delete";
243 $this->disks[$disk]['status']="delete";
244 foreach($this->disks[$disk]['partitions'] as $name => $value ){
245 if($value['status']=="edited"){
246 $this->disks[$disk]['partitions'][$name]['status']="delete";
247 }else{
248 unset($this->disks[$disk]['partitions'][$name]);
249 }
250 }
251 }else{
252 unset($this->disks[$disk]);
253 }
254 }
255 }
256 }
258 /* Display dialog if one is defined
259 */
260 if(isset($this->dialog)){
261 $this->dialog->save_object();
262 return($this->dialog->execute());
263 }
265 /* Assign all attributes to smarty engine
266 */
267 foreach($this->attributes as $attrs){
268 $smarty->assign($attrs,$this->$attrs);
269 if($this->$attrs){
270 $smarty->assign($attrs."CHK"," ");
271 }else{
272 $smarty->assign($attrs."CHK"," disabled ");
273 }
274 }
276 $dn = $this->acl_base_for_current_object($this->dn);
277 $smarty->assign("sub_object_is_addable",
278 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
279 !preg_match("/freeze/",$this->FAIstate));
281 $tmp = $this->plInfo();
282 foreach($tmp['plProvidedAcls'] as $name => $translated){
283 $smarty->assign($name."ACL",$this->getacl($name));
284 }
285 $disks = $this->getDisks();
286 $smarty->assign("disks" ,$disks);
287 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
288 return($display);
289 }
291 function getDisks(){
292 /* Return all available disks for this partition table
293 * Return in listBox friendly array
294 */
295 $a_return = array();
296 foreach($this->disks as $key => $disk){
298 $dn = "new";
299 if(isset($obj['dn'])){
300 $dn = $obj['dn'];
301 }
302 $dn = $this->acl_base_for_current_object($dn);
303 $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
304 if(preg_match("/(r|w)/",$acl)) {
306 if($disk['status'] != "delete"){
307 $cnt=0;
308 foreach($disk['partitions'] as $val){
309 if($val['status']!="delete"){
310 $cnt ++;
311 }
312 }
313 if(!empty($disk['description'])){
314 if($cnt == 1){
315 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
316 }else{
317 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
318 }
319 }else{
320 if($cnt == 1){
321 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
322 }else{
323 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
324 }
325 }
326 }
327 }
328 }
329 return($a_return);
330 }
333 /* Delete me, and all my subtrees
334 */
335 function remove_from_parent()
336 {
337 $ldap = $this->config->get_ldap_link();
338 $ldap->cd ($this->dn);
340 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $this->dn);
341 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $this->dn);
342 if($_SESSION['faifilter']['branch'] == "main"){
343 $use_dn = $this->dn;
344 }
346 prepare_to_save_FAI_object($use_dn,array(),true);
348 @log::log("remove","fai/".get_class($this),$use_dn,$this->attributes);
350 foreach($this->disks as $disk){
352 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
353 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $disk_dn);
354 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $disk_dn);
355 if($_SESSION['faifilter']['branch'] == "main"){
356 $use_dn = $disk_dn;
357 }
358 prepare_to_save_FAI_object($use_dn,array(),true);
360 foreach($disk['partitions'] as $key => $partition){
362 $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;
363 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $partition_dn);
364 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $partition_dn);
365 if($_SESSION['faifilter']['branch'] == "main"){
366 $use_dn = $disk_dn;
367 }
368 prepare_to_save_FAI_object($use_dn,array(),true);
369 }
370 }
371 }
374 /* Save data to object
375 */
376 function save_object()
377 {
378 if($this->FAIstate == "freeze") return;
379 plugin::save_object();
380 foreach($this->attributes as $attrs){
381 if(isset($_POST[$attrs])){
382 $this->$attrs = $_POST[$attrs];
383 }
384 }
385 }
388 /* Check supplied data */
389 function check()
390 {
391 /* Call common method to give check the hook */
392 $message= plugin::check();
394 return ($message);
395 }
398 /* Save to LDAP */
399 function save()
400 {
402 plugin::save();
403 /* Save current settings.
404 * 1 : We must save the partition table, with its description and cn
405 * 2 : Append Disk with cn and description.
406 * 3 : Save partitions for each disk
407 */
409 $ldap = $this->config->get_ldap_link();
411 prepare_to_save_FAI_object($this->dn,$this->attrs);
412 show_ldap_error($ldap->get_error(), sprintf(_("Saving of FAI/partition table with dn '%s' failed."),$this->dn));
414 if($this->initially_was_account){
415 @log::log("modify","fai/".get_class($this),$this->dn,$this->attributes);
416 }else{
417 @log::log("create","fai/".get_class($this),$this->dn,$this->attributes);
418 }
420 /* Do object tagging */
421 $this->handle_object_tagging();
423 /* Sort entries, because we must delete entries with status="delete" first */
424 $order = array();
425 foreach($this->disks as $key => $disk){
426 if($disk['status'] == "delete"){
427 $order[$key] = $disk;
428 }
429 }
430 foreach($this->disks as $key => $disk){
431 if($disk['status'] != "delete"){
432 $order[$key] = $disk;
433 }
434 }
436 /* Append all disks to ldap */
437 foreach($order as $cn=>$disk){
438 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
439 $disk_attrs['cn'] = $disk['cn'];
440 $disk_attrs['description'] = $disk['description'];
441 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
443 if($disk['status']=="new"){
444 $ldap->cat($disk_dn,array("objectClass"));
445 if($ldap->count()){
446 $disk['status']="edited";
447 }
448 }
450 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for disks */
451 $ldap->cat($disk_dn,array("objectClass"));
452 $attrs = $ldap->fetch();
453 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
454 $disk_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
455 }
457 if($disk['status'] == "delete"){
458 prepare_to_save_FAI_object($disk_dn,array(),true);
459 $this->handle_post_events("remove");
460 }elseif($disk['status'] == "edited"){
461 prepare_to_save_FAI_object($disk_dn,$disk_attrs);
462 $this->handle_post_events("modify");
463 }elseif($disk['status']=="new"){
464 prepare_to_save_FAI_object($disk_dn,$disk_attrs);
465 $this->handle_post_events("add");
466 }
468 $this->handle_object_tagging($disk_dn, $this->gosaUnitTag);
470 if($disk['status']!="delete")
471 /* Add all partitions */
472 foreach($disk['partitions'] as $key => $partition){
473 $partition_attrs = array();
475 foreach($partition as $key => $value){
476 if(!empty($value)){
477 $partition_attrs[$key]=$value;
478 }else{
479 unset($partition_attrs[$key]);
480 }
481 }
483 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
484 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
485 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
487 unset($partition_attrs['status']);
488 unset($partition_attrs['old_cn']);
490 if($partition['status']=="new"){
491 $ldap->cat($partition_dn,array("objectClass"));
492 if($ldap->count()){
493 $partition['status']="edited";
494 }
495 }
497 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
498 $partition_attrs['FAImountPoint']="swap";
499 }
501 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for partitions */
502 $ldap->cat($partition_dn,array("objectClass"));
503 $attrs = $ldap->fetch();
504 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
505 $partition_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
506 }
508 if($partition['status'] == "delete"){
509 prepare_to_save_FAI_object($partition_dn,array(),true);
510 $this->handle_post_events("remove");
511 }elseif($partition['status'] == "edited"){
512 prepare_to_save_FAI_object($partition_dn,$partition_attrs);
513 $this->handle_post_events("modify");
514 }elseif($partition['status']=="new"){
515 prepare_to_save_FAI_object($partition_dn,$partition_attrs);
516 $this->handle_post_events("add");
517 }
519 $this->handle_object_tagging($partition_dn, $this->gosaUnitTag);
520 }
521 }
522 $this->handle_post_events("add");
523 }
526 /* Return plugin informations for acl handling */
527 function plInfo()
528 {
529 return (array(
530 "plShortName" => _("Partition table"),
531 "plDescription" => _("FAI partition table"),
532 "plSelfModify" => FALSE,
533 "plDepends" => array(),
534 "plPriority" => 26,
535 "plSection" => array("administration"),
536 "plCategory" => array("fai"),
537 "plProvidedAcls" => array(
538 "cn" => _("Name")." ("._("Read only").")",
539 "description" => _("Description"))
540 ));
541 }
542 }
544 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
545 ?>