1 <?php
3 class faiDiskEntry extends plugin
4 {
5 /* attribute list for save action */
6 var $ignore_account= TRUE;
7 var $attributes = array("DISKcn","DISKdescription");
8 var $objectclasses= array();
10 var $DISKcn = "";
11 var $DISKdescription = "";
12 var $DISKFAIdiskOptions = "";
14 var $partitions = array();
15 var $UsedAttrs = array();
16 var $is_edit = false;
17 var $old_cn = "";
18 var $status = "new";
19 var $deletePartitions = array();
20 var $fstabkey = "device";
21 var $disklabel = "msdos";
23 var $FAIstate = "";
24 var $FAIdiskType = "disk";
26 function faiDiskEntry (&$config, $dn= NULL,$usedDiskNames=array(),$disk=false)
27 {
28 plugin::plugin ($config, $dn);
29 $this->UsedAttrs = array("cn","description","FAIpartitionType",
30 "FAIpartitionNr","FAIfsType","FAImountPoint","FAIpartitionSize",
31 "FAImountOptions","FAIfsOptions","FAIpartitionFlags","FAIdiskOption");
33 /* Default status is new */
34 $this->status = "new";
36 /* We want to edit an entry */
37 if($disk){
39 /* Set disk status */
40 $this->status = $disk['status'];
42 /* Walk through partitions */
43 foreach($disk['partitions'] as $name => $values){
45 /* If a partition is already marked as delete, attach it to deletePartitions only. */
46 if($values['status'] == "delete"){
47 unset($disk['partitions'][$name]);
48 $this->deletePartitions[]=$values;
49 }else{
51 /* Set status, to know which partition must be deleted from ldap
52 new : Neu partition entry // save
53 edited : Update partition entry in ldap
54 deleted: Remove partition from ldap
55 */
57 /* If status is not new, set to edit mode.
58 * New means that this partition currently wasn't saved to ldap.
59 */
60 if($disk['partitions'][$name]['status']!="new"){
61 $disk['partitions'][$name]['status']="edited";
62 }
64 $disk['partitions'][$name]['old_cn']= $disk['partitions'][$name]['cn'];
66 /* Assign empty attributes, if attribute is missing */
67 foreach($this->UsedAttrs as $attr){
68 if(!isset($values[$attr])){
69 $disk['partitions'][$name][$attr]="";
70 }
71 }
73 if (preg_match('/^_/', $disk['partitions'][$name]['FAIfsType'])){
74 $disk['partitions'][$name]['FAIfsType']= preg_replace('/^_/', '', $disk['partitions'][$name]['FAIfsType']);
75 }
76 }
77 }
79 /* Set default attributes */
80 $this->DISKcn = $disk['cn'];
81 $this->DISKdescription = $disk['description'];
82 $this->partitions = $disk['partitions'];
83 $this->is_edit = true;
84 $this->old_cn = $disk['cn'];
86 /* Move faiDiskOption */
87 if (isset($disk['FAIdiskOption'])){
88 foreach($disk['FAIdiskOption'] as $option) {
89 if (preg_match("/fstabkey:(device|label|uuid)/", $option)){
90 $this->fstabkey= preg_replace("/^.*fstabkey:(device|label|uuid).*$/", "$1", $option);
91 continue;
92 }
93 if (preg_match("/disklabel:(msdos|gpt)/", $option)){
94 $this->disklabel= preg_replace("/^.*disklabel:(msdos|gpt).*$/", "$1", $option);
95 continue;
96 }
97 if (preg_match("/^bootable:/", $option)){
98 $bootable = split(",", trim(preg_replace("/^bootable:/","",$option),","));
99 foreach($bootable as $bootflag){
100 $this->partitions[$bootflag]['bootable'] = TRUE;
101 }
102 break;
103 }
104 }
105 } else {
106 $this->fstabkey= "device";
107 }
108 }
109 }
112 function execute()
113 {
114 /* Call parent execute */
115 plugin::execute();
117 /* Fill templating stuff */
118 $smarty = get_smarty();
119 $s_action = "";
120 $s_entry = "";
121 $display = "";
123 /* Load parameters */
124 if (isset($_POST['disklabel']) && preg_match("/^(msdos|gpt)$/", $_POST['disklabel'])){
125 $this->disklabel= $_POST['disklabel'];
126 }
127 if (isset($_POST['fstabkey']) && preg_match("/^(device|label|uuid)$/", $_POST['fstabkey'])){
128 $this->fstabkey= $_POST['fstabkey'];
129 }
131 /* Assign values
132 * And Checkbox selection
133 */
134 foreach($this->attributes as $attrs){
135 $smarty->assign($attrs,$this->$attrs);
136 if($this->$attrs){
137 $smarty->assign($attrs."CHK"," ");
138 }else{
139 $smarty->assign($attrs."CHK"," disabled ");
140 }
141 }
143 /* Check all Posts if there is something usefull for us,
144 * For example : Delete is posted as Delete_1
145 * The number specifies the index we want to delete
146 */
147 foreach($_POST as $name => $value){
148 if((preg_match("/Delete_.*/",$name)) &&
149 $this->acl_is_removeable() &&
150 !preg_match("/freeze/i",$this->FAIstate)){
151 $tmp = split("_",$name);
152 $s_action = "remove";
153 $s_entry = $tmp[1];
154 }
155 }
157 /* To remove a partition we unset the index posted.
158 * We must sort the index again, else we possibly got problems
159 * with partitions order.
160 */
161 if($s_action == "remove" && $this->acl_is_removeable() &&
162 !preg_match("/freeze/i",$this->FAIstate)){
163 if($this->partitions[$s_entry]['status'] == "edited"){
164 $this->deletePartitions[$s_entry]= $this->partitions[$s_entry];
165 $this->deletePartitions[$s_entry]['FAIpartitionNr']=$s_entry;
166 unset($this->partitions[$s_entry]);
167 }else{
168 unset($this->partitions[$s_entry]);
169 }
170 $tmp= array();
171 foreach($this->partitions as $part){
172 $tmp[count($tmp)+1]=$part;
173 }
174 $this->partitions = $tmp;
175 }
178 /* Add / Edit partitions here.
179 */
180 foreach($_POST as $name => $value){
181 if(preg_match("/^EditPartition_/",$name)){
182 $id = preg_replace("/^EditPartition_/","",$name);
183 $id = preg_replace("/_.*$/","",$id);
184 if(isset($this->partitions[$id])){
185 $this->dialog = new faiPartition($this->config,"disk",$this->partitions[$id]);
186 break;
187 }
188 }
189 }
190 if(isset($_POST['AddPartition']) && !preg_match("/freeze/i",$this->FAIstate)){
191 $this->dialog = new faiPartition($this->config,"disk");
192 }
193 if($this->dialog instanceOf plugin && isset($_POST['PartitionCancel'])){
194 $this->dialog = null;
195 }
196 if($this->dialog instanceOf plugin && isset($_POST['PartitionSave'])){
197 $this->dialog->save_object();
198 $attrs = $this->dialog->save();
199 if(isset($attrs['FAIpartitionNr'])){
200 $this->partitions[$attrs['FAIpartitionNr']] = $attrs;
201 }else{
202 $this->partitions[] = $attrs;
203 }
204 $this->dialog = null;
205 }
206 if($this->dialog instanceOf plugin){
207 $this->dialog->save_object();
208 return($this->dialog->execute());
209 }
212 /* $setup contains a table with the partitions.
213 */
214 $smarty->assign("setup", $this->generateParts());
215 foreach($this->attributes as $attr){
216 $smarty->assign($attr,$this->$attr);
217 }
219 $tmp = $this->plInfo();
220 $sacl = "";
221 foreach($tmp['plProvidedAcls'] as $name => $translated){
222 $acl = $this->getacl($name, preg_match("/freeze/i",$this->FAIstate));
223 $smarty->assign($name."ACL",$acl);
224 }
226 $smarty->assign("sub_object_is_createable",$this->acl_is_createable());
227 $smarty->assign("freeze",preg_match("/freeze/i",$this->FAIstate));
229 // Fill boxes
230 $smarty->assign("fstabkeys", array("device" => _("Device"), "label" => _("Label"), "uuid" => _("UUID")));
231 $smarty->assign("disklabels", array("msdos" => "MSDOS", "gpt" => "GPT"));
232 $smarty->assign("fstabkey", $this->fstabkey);
233 $smarty->assign("disklabel", $this->disklabel);
235 /* Fetch template and show the result
236 */
237 $display.= $smarty->fetch(get_template_path('faiDiskEntry.tpl', TRUE));
238 return($display);
239 }
241 function generateParts()
242 {
244 $divlist = new divSelectBox("DiskEntries");
245 foreach($this->partitions as $key => $part){
246 $number =array(
247 "string" => $part['FAIpartitionNr'],
248 "attach" => "style='width:20px;'");
249 $size =array(
250 "string" => $part['FAIpartitionSize'],
251 "attach" => "style='width:100px;'");
252 $fstype =array(
253 "string" => $part['FAIfsType'],
254 "attach" => "style='width:60px;'");
255 $type =array(
256 "string" => $part['FAIpartitionType'],
257 "attach" => "style='width:80px;'");
258 $opt =array(
259 "string" => $part['FAImountOptions'],
260 "attach" => "style='width:80px;'");
261 $fsopt =array(
262 "string" => $part['FAIfsOptions'],
263 "attach" => "style='width:80px;'");
264 $flags =array(
265 "string" => $part['FAIpartitionFlags'],
266 "attach" => "style='width:80px;'");
267 $mntp =array("string" => $part['FAImountPoint']);
270 $action =array(
271 "string" => "<input type='image' src='images/lists/edit.png' name='EditPartition_".$key."'>",
272 "attach" => "style='width:40px;'");
275 $fields = array($number,$type,$mntp,$size,$fstype, $opt,$fsopt,$flags,$action);
276 $divlist->AddEntry($fields);
277 }
278 return($divlist->DrawList());
279 }
281 function save()
282 {
283 $tmp = array();
284 $tmp['cn'] = $this->DISKcn;
286 /* Attach partitions */
287 foreach($this->partitions as $key=>$val) {
288 $this->partitions[$key]['FAIpartitionNr']=$key;
289 }
291 /* Attach deleted */
292 foreach($this->deletePartitions as $key=>$val) {
293 $this->partitions[$key."-delete"]=$val;
294 $this->partitions[$key."-delete"]['status']="delete";
295 }
297 $tmp['description'] = $this->DISKdescription;
298 $tmp['partitions'] = $this->partitions;
299 $tmp['status'] = $this->status;
300 $tmp['FAIdiskType'] = $this->FAIdiskType;
302 /* Assemble flags */
303 $tmp['FAIdiskOption'] = array("fstabkey:".$this->fstabkey, "disklabel:".$this->disklabel);
305 /* If hdd name has changed, tell partitionTable to rename it */
306 if(($this->is_edit)&&($this->old_cn != $this->DISKcn)){
307 $tmp['rename']['from'] = $this->old_cn;
308 $tmp['rename']['to'] = $this->DISKcn;
309 }
310 return($tmp);
311 }
314 /* Save data to object */
315 function save_object()
316 {
317 if((isset($_POST['TableEntryFrameSubmitted'])) && !preg_match("/freeze/", $this->FAIstate) ){
318 plugin::save_object();
319 }
320 }
323 /* Check supplied data */
324 function check()
325 {
326 /* Call common method to give check the hook */
327 $message= plugin::check();
329 /* Check for an empty disk name */
330 $d = trim($this->DISKcn);
331 if($d == "" ){
332 $message[] = msgPool::required(_("Name"));
333 }
334 if(preg_match("/[^a-z0-9_\-]/i",$d)){
335 $message[] = msgPool::invalid(_("Name"),$d,"/[a-z0-9_\-]/i");
336 }
338 /* check every partition.
339 * if there is an invalid value defined, append an errorstr to message
340 */
342 /* Array that contain every partitionname mountpoint etc already assigned */
343 $alreadyUsed = array();
344 foreach($this->UsedAttrs as $attrs){
345 $alreadyUsed[$attrs] = array();
346 }
348 foreach($this->partitions as $key => $part){
350 /* Skip all checks, if preserve is set */
351 if($part['FAIpartitionFlags'] == "preserve"){
352 $this->partitions[$key]['FAIfsType'] = "preserve";
353 $this->partitions[$key]['FAIpartitionSize'] = "preserve";
354 continue;
355 }
357 if($part['FAImountPoint'] != "-" && (in_array($part['FAImountPoint'],$alreadyUsed['FAImountPoint']))&&($part['FAIfsType']!="swap")){
358 $message[]=sprintf(_("Please enter a unique mount point for partition %s"),($key));
359 }
361 if($part['FAIfsType']!="swap" && $part['FAImountPoint'] != "-"){
362 if((empty($part['FAImountPoint']))||(!((preg_match("/^\/.*/",$part['FAImountPoint']))||(preg_match("/^swap$/",$part['FAImountPoint']))))){
363 $message[]= msgPool::invalid(sprintf(_("partition %s mount point"),$key));
364 }
365 }
366 if($part['FAIfsType'] == "swap"){
367 if(in_array($part['FAIfsType'],$alreadyUsed['FAIfsType'])){
368 $message[]=sprintf(_("File system type 'swap' is already used, change file system type for partition %s."),$key);
369 }
370 }
371 if(($part['FAIfsType'] == "swap")&&(!empty($part['FAImountPoint']))&&($part['FAImountPoint']!="swap")){
372 $message[]=_("Please use 'swap' as mount point, if 'swap' is used as fs-type.");
373 }
375 $tmp = split("-",$part['FAIpartitionSize']);
376 switch (count($tmp)){
377 case 0:
378 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
379 break;
380 case 1:
381 if (!tests::is_id($tmp[0]) &&(!empty($tmp[1]))){
382 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
383 }
384 break;
386 case 2:
387 if( !tests::is_id($tmp[0]) && !tests::is_id($tmp[1]) && !empty($tmp[1]) ){
388 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
389 }elseif(!empty($tmp[1]) && $tmp[0]>=$tmp[1]){
390 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
391 }
392 break;
394 default:
395 $message[]= msgPool::invalid(sprintf(_("partition %s size"),$key));
396 }
398 foreach($this->UsedAttrs as $attrs){
399 $alreadyUsed[$attrs][$key] = $part[$attrs];
400 }
401 }
403 $cnt = 0;
404 foreach($this->partitions as $key => $part){
405 if($part['FAIpartitionType'] == "primary"){
406 $cnt ++ ;
407 }
408 }
409 if($cnt > 3){
410 $message[] = _("You have more than 3 primary partition table entries in your configuration, please check your configuration twice.");
411 }
413 return ($message);
414 }
418 /* Return plugin informations for acl handling */
419 static function plInfo()
420 {
421 return (array(
422 "plShortName" => _("Partition table entry"),
423 "plDescription" => _("FAI partition table entry"),
424 "plSelfModify" => FALSE,
425 "plDepends" => array(),
426 "plPriority" => 27,
427 "plSection" => array("administration"),
428 "plCategory" => array("fai"),
429 "plProvidedAcls" => array(
430 "DISKcn" => _("Name"),
431 "DISKdescription" => _("Description"),
432 "DISKFAIdiskOption" => _("Disk options"),
433 "FAIpartitionType" => _("Partition type"),
434 "FAIpartitionNr" => _("Partition no."),
435 "FAIfsType" => _("File system type"),
436 "FAImountPoint" => _("Mount point"),
437 "FAIpartitionSize" => _("Partition size"),
438 "FAImountOptions" => _("Mount options"),
439 "FAIfsOptions" => _("File system options"),
440 "FAIpartitionFlags" => _("Partition flags"))
441 ));
442 }
445 }
447 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
448 ?>