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
21 var $FAIstate = "";
22 var $ui;
24 var $view_logged = FALSE;
26 function faiPartitionTable (&$config, $dn= NULL)
27 {
28 /* Load Attributes */
29 plugin::plugin ($config, $dn);
31 $this->acl ="#all#";
33 $this->ui = get_userinfo();
35 /* If "dn==new" we try to create a new entry
36 * Else we must read all objects from ldap which belong to this entry.
37 * First read disks from ldap ... and then the partition definitions for the disks.
38 */
39 if($dn != "new"){
40 $this->dn =$dn;
42 /* Get FAIstate
43 */
44 if(isset($this->attrs['FAIstate'][0])){
45 $this->FAIstate = $this->attrs['FAIstate'][0];
46 }
48 /* Read all disks from ldap taht are defined fot this partition table
49 */
50 $ldap = $this->config->get_ldap_link();
51 $ldap->cd ($this->dn);
52 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
53 while($object = $ldap->fetch()){
55 /* Skip objects, that are tagged as removed */
56 if(isset($object['FAIstate'][0])){
57 if(preg_match("/removed$/",$object['FAIstate'][0])){
58 continue;
59 }
60 }
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 /* Skip objects, that are tagged as removed */
81 if(isset($partition['FAIstate'][0])){
82 if(preg_match("/removed$/",$partition['FAIstate'][0])){
83 continue;
84 }
85 }
87 /* remove count ... from ldap result
88 */
89 foreach($partition as $key=>$val){
90 if((is_numeric($key))||($key=="count")||($key=="dn")){
91 unset($partition[$key]);
92 }else{
93 $partition[$key] = $val[0];
94 }
95 }
97 /* Append fetched partitions
98 */
99 $partition['status']="edited";
100 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
101 }
102 }
103 }
104 ksort($this->disks);
105 }
108 function acl_base_for_current_object($dn)
109 {
110 if($dn == "new"){
111 if($this->dn == "new"){
112 $dn= $_SESSION['CurrentMainBase'];
113 }else{
114 $dn = $this->dn;
115 }
116 }
117 return($dn);
118 }
121 function execute()
122 {
123 /* Call parent execute */
124 plugin::execute();
126 if($this->is_account && !$this->view_logged){
127 $this->view_logged = TRUE;
128 new log("view","fai/".get_class($this),$this->dn);
129 }
131 /* Fill templating stuff */
132 $smarty= get_smarty();
133 $display= "";
135 /* Add Disk to this Partitionset
136 * This code adds a new HDD to the disks
137 * A new Dialog will be opened
138 */
139 if(isset($_POST['AddDisk'])){
140 $usedDiskNames =array();
141 foreach($this->disks as $key=>$disk){
142 $usedDiskNames[]= $key;
143 }
144 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
145 $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
146 $this->dialog->set_acl_category("fai");
147 $this->dialog->FAIstate = $this->FAIstate;
148 $this->is_dialog = true;
149 }
151 /* Edit disk.
152 * Open dialog which allows us to edit the selected entry
153 */
155 if($this->dn != "new"){
156 $_SESSION['objectinfo']= $this->dn;
157 }
159 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
160 $usedDiskNames =array();
162 $Udisk = $_POST['disks'][0];
164 foreach($this->disks as $key=>$disk){
165 if($key != $Udisk){
166 $usedDiskNames[]= $key;
167 }
168 }
170 /* Set object info string, which will be displayed in plugin info line */
171 if(isset($this->disks[$Udisk]['dn'])){
172 $_SESSION['objectinfo'] = $this->disks[$Udisk]['dn'];
173 $dn = $this->disks[$Udisk]['dn'];
174 }else{
175 $_SESSION['objectinfo'] = "";
176 $dn = "new";
177 }
179 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
180 $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
181 $this->dialog->set_acl_category("fai");
182 $this->dialog->FAIstate = $this->FAIstate;
184 $this->is_dialog = true;
185 }
187 /* Edit aborted, close dialog, without saving anything
188 */
189 if(isset($_POST['CancelDisk'])){
190 unset($this->dialog);
191 $this->dialog = FALSE;
192 $this->is_dialog=false;
193 }
195 /* Dialog saved
196 * Save given data from Dialog, if no error is occurred
197 */
198 if(isset($_POST['SaveDisk'])){
200 if($this->FAIstate != "freeze"){
201 $this->dialog->save_object();
202 if(count($this->dialog->check())){
203 foreach($this->dialog->check() as $msg){
204 print_red($msg);
205 }
206 }else{
207 $disk = $this->dialog->save();
208 if(isset($disk['rename'])){
209 if($this->disks[$disk['rename']['from']]['status']=="edited"){
210 $this->disks[$disk['rename']['from']]['status']="delete";
211 }else{
212 unset($this->disks[$disk['rename']['from']]);
213 }
215 foreach($disk['partitions'] as $key => $val){
216 if($disk['partitions'][$key]['status']!="delete"){
217 $disk['partitions'][$key]['status']= "new";
218 }
219 }
221 $disk['status']="new";
222 $disk['cn']= $disk['rename']['to'];
223 }
225 $this->disks[$disk['cn']]=$disk;
226 unset($this->dialog);
227 $this->dialog = FALSE;
228 $this->is_dialog=false;
229 ksort($this->disks);
230 }
231 }else{
232 $this->dialog = FALSE;
233 $this->is_dialog=false;
234 }
235 }
237 /* Delete selected disk drive from list
238 * Assign delete status for all its partitions
239 */
240 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
241 if($this->FAIstate != "freeze"){
242 foreach($_POST['disks'] as $disk) {
243 if($this->disks[$disk]['status']=="edited"){
244 $this->disks[$disk."-delete"]=$this->disks[$disk];
245 unset($this->disks[$disk]);
246 $disk = $disk."-delete";
247 $this->disks[$disk]['status']="delete";
248 foreach($this->disks[$disk]['partitions'] as $name => $value ){
249 if($value['status']=="edited"){
250 $this->disks[$disk]['partitions'][$name]['status']="delete";
251 }else{
252 unset($this->disks[$disk]['partitions'][$name]);
253 }
254 }
255 }else{
256 unset($this->disks[$disk]);
257 }
258 }
259 }
260 }
262 /* Display dialog if one is defined
263 */
264 if(is_object($this->dialog)){
265 $this->dialog->save_object();
266 return($this->dialog->execute());
267 }
269 /* Assign all attributes to smarty engine
270 */
271 foreach($this->attributes as $attrs){
272 $smarty->assign($attrs,$this->$attrs);
273 if($this->$attrs){
274 $smarty->assign($attrs."CHK"," ");
275 }else{
276 $smarty->assign($attrs."CHK"," disabled ");
277 }
278 }
280 $dn = $this->acl_base_for_current_object($this->dn);
281 $smarty->assign("sub_object_is_addable",
282 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
283 !preg_match("/freeze/",$this->FAIstate));
285 $tmp = $this->plInfo();
286 foreach($tmp['plProvidedAcls'] as $name => $translated){
287 $smarty->assign($name."ACL",$this->getacl($name));
288 }
289 $disks = $this->getDisks();
290 $smarty->assign("disks" ,$disks);
291 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
292 return($display);
293 }
295 function getDisks(){
296 /* Return all available disks for this partition table
297 * Return in listBox friendly array
298 */
299 $a_return = array();
300 foreach($this->disks as $key => $disk){
302 $dn = "new";
303 if(isset($obj['dn'])){
304 $dn = $obj['dn'];
305 }
306 $dn = $this->acl_base_for_current_object($dn);
307 $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
308 if(preg_match("/(r|w)/",$acl)) {
310 if($disk['status'] != "delete"){
311 $cnt=0;
312 foreach($disk['partitions'] as $val){
313 if($val['status']!="delete"){
314 $cnt ++;
315 }
316 }
317 if(!empty($disk['description'])){
318 if($cnt == 1){
319 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
320 }else{
321 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
322 }
323 }else{
324 if($cnt == 1){
325 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
326 }else{
327 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
328 }
329 }
330 }
331 }
332 }
333 return($a_return);
334 }
337 /* Delete me, and all my subtrees
338 */
339 function remove_from_parent()
340 {
341 $ldap = $this->config->get_ldap_link();
342 $ldap->cd ($this->dn);
344 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $this->dn);
345 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $this->dn);
346 if($_SESSION['faifilter']['branch'] == "main"){
347 $use_dn = $this->dn;
348 }
350 prepare_to_save_FAI_object($use_dn,array(),true);
352 new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
354 foreach($this->disks as $disk){
356 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
357 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $disk_dn);
358 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $disk_dn);
359 if($_SESSION['faifilter']['branch'] == "main"){
360 $use_dn = $disk_dn;
361 }
362 prepare_to_save_FAI_object($use_dn,array(),true);
364 foreach($disk['partitions'] as $key => $partition){
366 $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;
367 # $use_dn = str_ireplace( get_release_dn($this->dn), $_SESSION['faifilter']['branch'], $partition_dn);
368 $use_dn = preg_replace("/".normalizePreg(get_release_dn($this->dn))."/i", $_SESSION['faifilter']['branch'], $partition_dn);
369 if($_SESSION['faifilter']['branch'] == "main"){
370 $use_dn = $disk_dn;
371 }
372 prepare_to_save_FAI_object($use_dn,array(),true);
373 }
374 }
375 }
378 /* Save data to object
379 */
380 function save_object()
381 {
382 if($this->FAIstate == "freeze") return;
383 plugin::save_object();
384 foreach($this->attributes as $attrs){
385 if(isset($_POST[$attrs])){
386 $this->$attrs = $_POST[$attrs];
387 }
388 }
389 }
392 /* Check supplied data */
393 function check()
394 {
395 /* Call common method to give check the hook */
396 $message= plugin::check();
398 return ($message);
399 }
402 /* Save to LDAP */
403 function save()
404 {
406 plugin::save();
407 /* Save current settings.
408 * 1 : We must save the partition table, with its description and cn
409 * 2 : Append Disk with cn and description.
410 * 3 : Save partitions for each disk
411 */
413 $ldap = $this->config->get_ldap_link();
415 prepare_to_save_FAI_object($this->dn,$this->attrs);
416 show_ldap_error($ldap->get_error(), sprintf(_("Saving of FAI/partition table with dn '%s' failed."),$this->dn));
418 if($this->initially_was_account){
419 new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
420 }else{
421 new log("create","fai/".get_class($this),$this->dn,$this->attributes);
422 }
424 /* Do object tagging */
425 $this->handle_object_tagging();
427 /* Sort entries, because we must delete entries with status="delete" first */
428 $order = array();
429 foreach($this->disks as $key => $disk){
430 if($disk['status'] == "delete"){
431 $order[$key] = $disk;
432 }
433 }
434 foreach($this->disks as $key => $disk){
435 if($disk['status'] != "delete"){
436 $order[$key] = $disk;
437 }
438 }
440 /* Append all disks to ldap */
441 foreach($order as $cn=>$disk){
442 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
443 $disk_attrs['cn'] = $disk['cn'];
444 $disk_attrs['description'] = $disk['description'];
445 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
447 if($disk['status']=="new"){
448 $ldap->cat($disk_dn,array("objectClass"));
449 if($ldap->count()){
450 $disk['status']="edited";
451 }
452 }
454 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for disks */
455 $ldap->cat($disk_dn,array("objectClass"));
456 $attrs = $ldap->fetch();
457 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
458 $disk_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
459 }
461 if($disk['status'] == "delete"){
462 prepare_to_save_FAI_object($disk_dn,array(),true);
463 $this->handle_post_events("remove");
464 }elseif($disk['status'] == "edited"){
465 prepare_to_save_FAI_object($disk_dn,$disk_attrs);
466 $this->handle_post_events("modify");
467 }elseif($disk['status']=="new"){
468 prepare_to_save_FAI_object($disk_dn,$disk_attrs);
469 $this->handle_post_events("add");
470 }
472 $this->handle_object_tagging($disk_dn, $this->gosaUnitTag);
474 if($disk['status']!="delete")
475 /* Add all partitions */
476 foreach($disk['partitions'] as $key => $partition){
477 $partition_attrs = array();
479 foreach($partition as $key => $value){
480 if(!empty($value)){
481 $partition_attrs[$key]=$value;
482 }else{
483 unset($partition_attrs[$key]);
484 }
485 }
487 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
488 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
489 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
491 unset($partition_attrs['status']);
492 unset($partition_attrs['old_cn']);
494 if($partition['status']=="new"){
495 $ldap->cat($partition_dn,array("objectClass"));
496 if($ldap->count()){
497 $partition['status']="edited";
498 }
499 }
501 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
502 $partition_attrs['FAImountPoint']="swap";
503 }
505 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for partitions */
506 $ldap->cat($partition_dn,array("objectClass"));
507 $attrs = $ldap->fetch();
508 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
509 $partition_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
510 }
512 if($partition['status'] == "delete"){
513 prepare_to_save_FAI_object($partition_dn,array(),true);
514 $this->handle_post_events("remove");
515 }elseif($partition['status'] == "edited"){
516 prepare_to_save_FAI_object($partition_dn,$partition_attrs);
517 $this->handle_post_events("modify");
518 }elseif($partition['status']=="new"){
519 prepare_to_save_FAI_object($partition_dn,$partition_attrs);
520 $this->handle_post_events("add");
521 }
523 $this->handle_object_tagging($partition_dn, $this->gosaUnitTag);
524 }
525 }
526 $this->handle_post_events("add");
527 }
530 /* Return plugin informations for acl handling */
531 function plInfo()
532 {
533 return (array(
534 "plShortName" => _("Partition table"),
535 "plDescription" => _("FAI partition table"),
536 "plSelfModify" => FALSE,
537 "plDepends" => array(),
538 "plPriority" => 26,
539 "plSection" => array("administration"),
540 "plCategory" => array("fai"),
541 "plProvidedAcls" => array(
542 "cn" => _("Name")." ("._("Read only").")",
543 "description" => _("Description"))
544 ));
545 }
546 }
548 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
549 ?>