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 = "";
24 function faiPartitionTable ($config, $dn= NULL)
25 {
26 /* Load Attributes */
27 plugin::plugin ($config, $dn);
29 $this->acl ="#all#";
31 /* If "dn==new" we try to create a new entry
32 * Else we must read all objects from ldap which belong to this entry.
33 * First read disks from ldap ... and then the partition definitions for the disks.
34 */
35 if($dn != "new"){
36 $this->dn =$dn;
38 /* Set acls
39 */
40 $ui = get_userinfo();
41 $acl = get_permissions ($this->dn, $ui->subtreeACL);
42 $acli = get_module_permission($acl, "FAIclass", $this->dn);
43 $this->acl=$acli;
45 /* Get FAIstate
46 */
47 if(isset($this->attrs['FAIstate'][0])){
48 $this->FAIstate = $this->attrs['FAIstate'][0];
49 }
51 /* Read all disks from ldap taht are defined fot this partition table
52 */
53 $ldap = $this->config->get_ldap_link();
54 $ldap->cd ($this->dn);
55 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
56 while($object = $ldap->fetch()){
57 $this->disks[$object['cn'][0]]['status'] = "edited";
58 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
59 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
60 if(isset($object['description'][0])){
61 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
62 }else{
63 $this->disks[$object['cn'][0]]['description'] = "";
64 }
65 $this->disks[$object['cn'][0]]['partitions'] = array();
66 }
68 /* read all partitions for each disk
69 */
70 foreach($this->disks as $name => $disk){
71 $ldap->cd ($disk['dn']);
72 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
73 while($partition = $ldap->fetch()){
75 /* remove count ... from ldap result
76 */
77 foreach($partition as $key=>$val){
78 if((is_numeric($key))||($key=="count")||($key=="dn")){
79 unset($partition[$key]);
80 }else{
81 $partition[$key] = $val[0];
82 }
83 }
85 /* Append fetched partitions
86 */
87 $partition['status']="edited";
88 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
89 }
90 }
91 }
92 ksort($this->disks);
93 }
95 function execute()
96 {
97 /* Call parent execute */
98 plugin::execute();
100 /* Fill templating stuff */
101 $smarty= get_smarty();
102 $display= "";
104 /* Add Disk to this Partitionset
105 * This code adds a new HDD to the disks
106 * A new Dialog will be opened
107 */
108 if(isset($_POST['AddDisk'])){
109 $usedDiskNames =array();
110 foreach($this->disks as $key=>$disk){
111 $usedDiskNames[]= $key;
112 }
113 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
114 $this->dialog->acl = $this->acl;
115 $this->dialog->FAIstate = $this->FAIstate;
116 $this->is_dialog = true;
117 }
119 /* Edit disk.
120 * Open dialog which allows us to edit the selected entry
121 */
123 if($this->dn != "new"){
124 $_SESSION['objectinfo']= $this->dn;
125 }
127 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
128 $usedDiskNames =array();
130 $Udisk = $_POST['disks'][0];
132 foreach($this->disks as $key=>$disk){
133 if($key != $Udisk){
134 $usedDiskNames[]= $key;
135 }
136 }
137 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
138 $this->dialog->acl = $this->acl;
139 $this->dialog->FAIstate = $this->FAIstate;
141 /* Set object info string, which will be displayed in plugin info line */
142 if(isset($this->disks[$Udisk]['dn'])){
143 $_SESSION['objectinfo'] = $this->disks[$Udisk]['dn'];
144 }else{
145 $_SESSION['objectinfo'] = "";
146 }
148 $this->is_dialog = true;
149 }
151 /* Edit aborted, close dialog, without saving anything
152 */
153 if(isset($_POST['CancelDisk'])){
154 unset($this->dialog);
155 $this->dialog = NULL;
156 $this->is_dialog=false;
157 }
159 /* Dialog saved
160 * Save given data from Dialog, if no error is occured
161 */
162 if(isset($_POST['SaveDisk'])){
164 if($this->FAIstate != "freeze"){
165 $this->dialog->save_object();
166 if(count($this->dialog->check())){
167 foreach($this->dialog->check() as $msg){
168 print_red($msg);
169 }
170 }else{
171 $disk = $this->dialog->save();
172 if(isset($disk['rename'])){
173 if($this->disks[$disk['rename']['from']]['status']=="edited"){
174 $this->disks[$disk['rename']['from']]['status']="delete";
175 }else{
176 unset($this->disks[$disk['rename']['from']]);
177 }
179 foreach($disk['partitions'] as $key => $val){
180 if($disk['partitions'][$key]['status']!="delete"){
181 $disk['partitions'][$key]['status']= "new";
182 }
183 }
185 $disk['status']="new";
186 $disk['cn']= $disk['rename']['to'];
187 }
189 $this->disks[$disk['cn']]=$disk;
190 unset($this->dialog);
191 $this->dialog = NULL;
192 $this->is_dialog=false;
193 ksort($this->disks);
194 }
195 }else{
196 $this->dialog = NULL;
197 $this->is_dialog=false;
198 }
199 }
201 /* Delete selected disk drive from list
202 * Assign delete status for all its partitions
203 */
204 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
205 if($this->FAIstate != "freeze"){
206 foreach($_POST['disks'] as $disk) {
207 if($this->disks[$disk]['status']=="edited"){
208 $this->disks[$disk."-delete"]=$this->disks[$disk];
209 unset($this->disks[$disk]);
210 $disk = $disk."-delete";
211 $this->disks[$disk]['status']="delete";
212 foreach($this->disks[$disk]['partitions'] as $name => $value ){
213 if($value['status']=="edited"){
214 $this->disks[$disk]['partitions'][$name]['status']="delete";
215 }else{
216 unset($this->disks[$disk]['partitions'][$name]);
217 }
218 }
219 }else{
220 unset($this->disks[$disk]);
221 }
222 }
223 }
224 }
226 /* Display dialog if one is defined
227 */
228 if(isset($this->dialog)){
229 $this->dialog->save_object();
230 return($this->dialog->execute());
231 }
233 /* Assign all attributes to smarty engine
234 */
235 foreach($this->attributes as $attrs){
236 $smarty->assign($attrs,$this->$attrs);
237 if($this->$attrs){
238 $smarty->assign($attrs."CHK"," ");
239 }else{
240 $smarty->assign($attrs."CHK"," disabled ");
241 }
242 }
244 foreach($this->attributes as $attr){
245 $smarty->assign($attr."ACL",chkacl($this->acl,$attr));
246 }
248 $disks = $this->getDisks();
249 $smarty->assign("disks" ,$disks);
250 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
251 return($display);
252 }
254 function getDisks(){
255 /* Return all available disks for this partition table
256 * Return in listBox friendly array
257 */
258 $a_return = array();
259 foreach($this->disks as $key => $disk){
260 if($disk['status'] != "delete"){
261 $cnt=0;
262 foreach($disk['partitions'] as $val){
263 if($val['status']!="delete"){
264 $cnt ++;
265 }
266 }
267 if(!empty($disk['description'])){
268 if($cnt == 1){
269 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
270 }else{
271 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
272 }
273 }else{
274 if($cnt == 1){
275 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
276 }else{
277 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
278 }
279 }
280 }
281 }
282 return($a_return);
283 }
286 /* Delete me, and all my subtrees
287 */
288 function remove_from_parent()
289 {
290 $ldap = $this->config->get_ldap_link();
291 $ldap->cd ($this->dn);
292 $ldap->rmdir_recursive($this->dn);
293 $this->handle_post_events("remove");
295 /* This cannot be removed... */
296 }
299 /* Save data to object
300 */
301 function save_object()
302 {
303 if($this->FAIstate == "freeze") return;
304 plugin::save_object();
305 foreach($this->attributes as $attrs){
306 if(isset($_POST[$attrs])){
307 $this->$attrs = $_POST[$attrs];
308 }
309 }
310 }
313 /* Check supplied data */
314 function check()
315 {
316 /* Call common method to give check the hook */
317 $message= plugin::check();
319 return ($message);
320 }
323 /* Save to LDAP */
324 function save()
325 {
327 plugin::save();
328 /* Save current settings.
329 * 1 : We must save the partition table, with its description and cn
330 * 2 : Append Disk with cn and description.
331 * 3 : Save partitions for each disk
332 */
334 $ldap = $this->config->get_ldap_link();
336 if($this->new){
337 $ldap->cd($this->config->current['BASE']);
338 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
339 $ldap->cd($this->dn);
340 $ldap->add($this->attrs);
341 }else{
342 /* Add partition table to ldap
343 */
344 $ldap->cd($this->dn);
345 $this->cleanup();
346 $ldap->modify ($this->attrs);
347 }
348 show_ldap_error($ldap->get_error(), _("Saving FAI partition table base failed"));
350 /* Do object tagging */
351 $this->handle_object_tagging();
353 /* Sort entries, because we must delete entries with status="delete" first */
354 $order = array();
355 foreach($this->disks as $key => $disk){
356 if($disk['status'] == "delete"){
357 $order[$key] = $disk;
358 }
359 }
360 foreach($this->disks as $key => $disk){
361 if($disk['status'] != "delete"){
362 $order[$key] = $disk;
363 }
364 }
366 /* Append all disks to ldap */
367 foreach($order as $cn=>$disk){
368 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
369 $disk_attrs['cn'] = $disk['cn'];
370 $disk_attrs['description'] = $disk['description'];
371 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
373 if($disk['status']=="new"){
374 $ldap->cat($disk_dn,array("objectClass"));
375 if($ldap->count()){
376 $disk['status']="edited";
377 }
378 }
380 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for disks */
381 $ldap->cat($disk_dn,array("objectClass"));
382 $attrs = $ldap->fetch();
383 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
384 $disk_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
385 }
387 if($disk['status'] == "delete"){
388 $ldap->cd($disk_dn);
389 $ldap->rmdir_recursive($disk_dn);
390 show_ldap_error($ldap->get_error(), _("Removing FAI partition table failed"));
391 }elseif($disk['status']== "edited"){
392 if(empty($disk_attrs['description'])){
393 $disk_attrs['description']=array();
394 }
395 $ldap->cd($disk_dn);
396 $this->cleanup();
397 $ldap->modify ($disk_attrs);
398 show_ldap_error($ldap->get_error(), _("Saving FAI partition table failed"));
399 }elseif($disk['status']== "new"){
400 if(empty($disk_attrs['description'])){
401 unset($disk_attrs['description']);
402 }
403 $ldap->cd($this->config->current['BASE']);
404 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $disk_dn));
405 $ldap->cd($disk_dn);
406 $ldap->add($disk_attrs);
407 show_ldap_error($ldap->get_error(), _("Saving FAI partition table failed"));
408 }else{
409 print_red("unknown status while saving disks");
410 }
412 $this->handle_object_tagging($disk_dn, $this->gosaUnitTag);
414 if($disk['status']!="delete")
415 /* Add all partitions */
416 foreach($disk['partitions'] as $key => $partition){
417 $partition_attrs = array();
419 foreach($partition as $key => $value){
420 if(!empty($value)){
421 $partition_attrs[$key]=$value;
422 }else{
423 unset($partition_attrs[$key]);
424 }
425 }
427 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
428 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
429 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
431 unset($partition_attrs['status']);
432 unset($partition_attrs['old_cn']);
434 if($partition['status']=="new"){
435 $ldap->cat($partition_dn,array("objectClass"));
436 if($ldap->count()){
437 $partition['status']="edited";
438 }
439 }
441 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
442 $partition_attrs['FAImountPoint']="swap";
443 }
445 /* Fix problem with missing objectClass "gosaAdministrativeUnitTag" for partitions */
446 $ldap->cat($partition_dn,array("objectClass"));
447 $attrs = $ldap->fetch();
448 if(isset($attrs['objectClass']) && in_array_ics("gosaAdministrativeUnitTag",$attrs['objectClass'])){
449 $partition_attrs['objectClass'][] = "gosaAdministrativeUnitTag";
450 }
452 if(($partition['status'] == "delete")&&($disk['status']!="new")){
453 $ldap->cd($partition_dn);
454 $ldap->rmdir_recursive($partition_dn);
455 show_ldap_error($ldap->get_error(), _("Removing FAI partition table entry failed"));
456 }elseif($partition['status'] == "new"){
457 if(empty($partition_attrs['description'])){
458 unset($partition_attrs['description']);
459 }
460 $ldap->cd($this->config->current['BASE']);
461 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $partition_dn));
462 $ldap->cd($partition_dn);
463 $ldap->add($partition_attrs);
464 show_ldap_error($ldap->get_error(), _("Saving FAI partition table entry failed"));
465 }elseif($partition['status'] == "edited"){
466 if(empty($partition_attrs['description'])){
467 $partition_attrs['description']=array();
468 }
469 $ldap->cd($partition_dn);
470 $this->cleanup();
471 $ldap->modify ($partition_attrs);
472 show_ldap_error($ldap->get_error(), _("Saving FAI partition table entry failed"));
473 }
475 $this->handle_object_tagging($partition_dn, $this->gosaUnitTag);
476 }
477 }
478 $this->handle_post_events("add");
479 }
480 }
482 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
483 ?>