1 <?php
3 class DevicePartition
4 {
5 public $object =NULL;
6 public $partitionString =NULL;
8 public $addDialog = NULL;
9 public $initialized = FALSE;
11 function __construct($config, $partitionString)
12 {
13 $this->config = &$config;
14 $this->partitionString = $partitionString;
16 #$this->partitionString = "disk sda --initlabel --none;
17 # part /boot --size 1000 --format --fstype ext3 --ondisk sda;
18 # part /test --size 1000 --fstype ext3 --ondisk sda;
19 # part pv.00 --size 10 --bootable --ondisk sda;
20 # part raid.00 --size 5000 --bootable --ondisk sda;
21 # part pv.01 --size 10009 --ondisk sda;
22 # part raid.01 --size 1000 --bootable --ondisk sda;
23 # part pv.03 --size 1000 --bootable --ondisk sda;
24 # part raid.02 --size 981 --bootable --ondisk sda;
25 # raid pv.02 --level 0 --name md0 --format raid.01 raid.00;
26 # volgroup garnele --format pv.01 pv.00 pv.02;
27 # logvol /homejj --size 8978 --format --fstype ext3 --name garnele_home --vgname garnele;
28 # logvol /opt --size 7041 --format --fstype ext3 --name garnele_opt --vgname garnele;";
30 // Prepare lists
31 $this->entryList = new sortableListing();
32 $this->entryList->setDeleteable(false);
33 $this->entryList->setEditable(false);
34 $this->entryList->setWidth("100%");
35 $this->entryList->setHeight("400px");
36 $this->entryList->setHeader(array(_("Type"),_("Target"),_("Size"),_("Uses device")." / "._("Used by"),
37 _("Filesystem"), _("Options"), _("Details"), "-"));
38 $this->entryList->setColspecs(array('*','*','*', '*'));
39 $this->entryList->setAcl('rwcdm');
40 $this->entryList->setReorderable(FALSE);
41 $this->entryList->sortingEnabled(FALSE);
42 }
44 function execute()
45 {
46 /*****
47 * Handle add-partition dialog
48 *****/
50 // Create button was pressed, show dialog to add new partitions
51 if(isset($_POST['create_partition'])){
52 $this->addDialog = new AddPartitionDialog($this->config, $this->object);
53 }
55 // Abort partition add
56 if(isset($_POST['cancel_partition_add'])){
57 $this->addDialog = NULL;
58 }
60 // Save created partitions
61 if(isset($_POST['save_partition_add'])){
62 $this->addDialog->save_object();
63 if($this->addDialog->save()){
64 $this->addDialog = NULL;
65 }
66 }
68 // Show partition dialog
69 if($this->addDialog){
70 $this->addDialog->save_object();
71 return($this->addDialog->execute());
72 }
75 /*****
76 * Open partition object on demand
77 *****/
79 // Open remote parition object
80 if(!$this->initialized){
81 $rpc = $this->config->getRpcHandle();
82 $this->object = $rpc->openObject('libinst.preseed.diskdefinition', $this->partitionString);
83 if(!$rpc->success()){
84 $message = _("An error occured while loading partition information.");
85 $message = sprintf(_("An error occured while loading partition information, error was: '%s'."), $rpc->get_error());
86 $smarty = get_smarty();
87 $smarty->assign('error', TRUE);
88 $smarty->assign('errorMsg', $message);
89 return($smarty->fetch(get_template_path('goto/Device/DevicePartition.tpl', TRUE)));
90 }else{
91 $this->initialized = TRUE;
92 }
93 }
96 /*****
97 * Fill listing
98 *****/
100 // Receive list informations
101 $map = array();
102 $map['disks'] = 'getDisks';
103 $map['partitions'] = 'getPartitions';
104 $map['raids'] = 'getRaidDevices';
105 $map['volumeGroups'] = 'getVolumeGroups';
106 $map['volumes'] = 'getVolumes';
107 $map['deviceUsage'] = 'getDeviceUsage';
108 foreach($map as $target => $func){
109 $$target = @$this->object->$func();
110 if(!$this->object->success()){
111 $message = sprintf(_("An error occured while loading partition information, error was: '%s'."), $this->object->getError());
112 $smarty = get_smarty();
113 $smarty->assign('error', TRUE);
114 $smarty->assign('errorMsg', $message);
115 return($smarty->fetch(get_template_path('goto/Device/DevicePartition.tpl', TRUE)));
116 }
117 }
119 // Create a mapping that show which partitions was used for which raid.
120 $map_partToRaid = array();
121 $raidTargets = array();
122 foreach($raids as $raid){
123 $raidTargets[] = $raid['target'];
124 foreach($raid['devices'] as $devName){
125 $map_partToRaid[$devName] = $raid['name'];
126 }
127 }
129 // Create a mapping that shows which partition was used in which volumeGroup.
130 $map_partToVolumeGroup = array();
131 foreach($volumeGroups as $vol){
132 foreach($vol['partitions'] as $part){
133 $map_partToVolumeGroup[$part] = $vol['name'];
134 }
135 }
137 // Create partition name map
138 $partNames = array();
140 // Create separators to create a visible indentation
141 $seps = array();
142 $seps[0] = "";
143 $seps[1] = str_pad("", 18, " ");
144 $seps[2] = str_pad("", 36, " ");
146 // Prepare images
147 $partitionImg = image('plugins/goto/images/partition.png','',_("Partition"));
148 $diskImg = image('plugins/goto/images/disk.png','',_("Disk"));
149 $raidImg = image('plugins/goto/images/raid.png', '', _('Raid'));
150 $volumeGroupImg = image('plugins/goto/images/volumeGroups.png', '', _('Volume group'));
151 $volumeImg = image('plugins/goto/images/volume.png','',_('Volume'));
153 // Add raid devices
154 $lData = array();
155 if(count($raids)){
157 // Add raid header
158 $lData[] = array("data" => array("<b>"._("Raid devices")."</b>"));
160 // Add raids
161 foreach($raids as $id => $raid){
162 $str = "{$seps[1]}{$raidImg} {$raid['name']} ("._("Raid")."{$raid['level']})";
163 $delImg = image('images/lists/trash.png', "delete_raid_{$id}", _("Remove raid device"));
165 $devsStr = "";
166 foreach($raid['devices'] as $devName){
167 $devsStr .= $partitionImg." ".$devName.", ";
168 }
169 $devsStr = rtrim($devsStr, ', ');
171 $target = $raid['target'];
172 if(isset($map_partToVolumeGroup[$target])){
173 $target = $volumeGroupImg." ".$target;
174 }
176 $fsType = (isset($raid['fsType'])) ? $raid['fsType'] :"";
177 $fsOptions = (isset($raid['fsOptions'])) ? $raid['fsOptions'] :"";
179 $size = "";
180 if(isset($deviceUsage['raid'][$raid['target']])){
181 $size = "<i>".$this->__convertPartSize($deviceUsage['raid'][$raid['target']]['size'])."</i>";
182 }
184 $lData[] = array("data" => array($str,
185 $target,
186 $size,
187 $devsStr,
188 $fsType,
189 $fsOptions,
190 '',
191 $delImg
192 ));
193 }
194 }
196 // Add volume groups
197 if(count($volumeGroups)){
199 // Add LVM volume groups header
200 $lData[] = array("data" => array("<b>"._("LVM Volume Groups")."</b>"));
202 // Add volume groups
203 foreach($volumeGroups as $id => $vg){
204 $str = "{$seps[1]}{$volumeGroupImg} {$vg['name']}";
205 $delImg = image('images/lists/trash.png', "delete_vg_{$id}", _("Remove volume group"));
207 // Build up a list of all used partitions
208 $partStr = "";
209 foreach($vg['partitions'] as $partName){
210 if(in_array_strict($partName, $raidTargets)){
211 $img = $raidImg;
212 }else{
213 $img = $partitionImg;
214 }
215 $partStr .= "{$img} {$partName}, ";
216 }
217 $partStr = rtrim($partStr, ", ");
219 $size = "";
220 if(isset($deviceUsage['vg'][$vg['name']])){
221 $size = "<b>".$this->__convertPartSize($deviceUsage['vg'][$vg['name']]['size'])."</b>";
222 }
224 // Add entry to the list.
225 $lData[] = array("data" => array($str, '', $size, $partStr, '', '','',$delImg));
227 // Add volumes
228 foreach($volumes as $vid => $volume){
229 $delImg = image('images/lists/trash.png', "delete_v_{$vid}", _("Remove volume"));
230 if($volume['volGroup'] == $vg['name']){
231 $str = "{$seps[2]}{$volumeImg} {$volume['name']}";
232 $lData[] = array("data" => array(
233 $str,
234 $volume['target'],
235 $this->__convertPartSize($volume['size']),
236 '',
237 $volume['fsType'],
238 $volume['fsOptions'],
239 '',
240 $delImg
241 ));
245 }
246 }
247 }
248 }
250 // Collect all disk devices names
251 $diskNames = array();
252 foreach($disks as $disk){
253 $diskNames[] = $disk['device'];
254 }
256 // Add physical disks to the listing.
257 if(count($disks)){
259 // Add disks
260 $lData[] = array("data" => array("<b>"._("Disks")."</b>"));
261 foreach($disks as $id => $disk){
262 $str = "{$seps[1]}{$diskImg} {$disk['device']}";
264 $size = "";
265 if(isset($deviceUsage['disk'][$disk['device']])){
266 $size = "<b>".$this->__convertPartSize($deviceUsage['disk'][$disk['device']]['size'])."</b>";
267 }
269 // Create remove icon
270 $delImg = image('images/lists/trash.png', "delete_disk_{$id}", _("Remove disk"));
271 $lData[] = array("data" => array($str,"",$size,"","","","", $delImg));
273 // Add partitions
274 foreach($partitions as $pid => $part){
276 if(!in_array_strict($part['onDisk'], $diskNames)){
278 echo "Cannot display '{$part['target']}' the given disk '{$part['onDisk']}' does not exists!<br>";
279 continue;
280 }
282 if($part['onDisk'] == $disk['device']){
284 // Prepare columns
285 $str = "{$seps[2]}{$partitionImg} {$part['target']}";
286 $device = "";
287 $fsType = $part['fsType'];
288 $target = "";
289 if(preg_match("/^(swap|\/)/", $part['target'])){
290 $target = $part['target'];
291 }
293 // Do we have a raid here? Then update the device column
294 // to point to the raid name
295 if(isset($map_partToRaid[$part['target']])){
296 $device = sprintf(_("Used by: %s"), $raidImg." ".$map_partToRaid[$part['target']]);
297 $fsType.= " "._("Software raid");
298 $fsType = trim($fsType);
299 }elseif(isset($map_partToVolumeGroup[$part['target']])){
300 $device = sprintf(_("Used by: %s"), $volumeGroupImg." ".$map_partToVolumeGroup[$part['target']]);
301 $fsType.= " "._("Physical volume LVM");
302 $fsType = trim($fsType);
303 }
305 // Create property icons
306 $emptyImage = image("images/empty.png");
307 $formatImg = ($part['format']) ? image('plugins/goto/images/formatDisk.png','',_("Format partition")) : $emptyImage;
308 $primaryImg = ($part['primary']) ? image('plugins/goto/images/primary.png','',_("Primary partition")) : $emptyImage;
309 $bootImg = ($part['bootable']) ? image('images/true.png','',_("Bootable")) : $emptyImage;
310 $encryptImg = ($part['encrypted']) ? image('images/lists/locked.png','',_("Encrypted")) : $emptyImage;
312 // Create remove icon
313 $delImg = image('images/lists/trash.png', "delete_part_{$pid}", _("Remove partition"));
315 // Add entry to the listing
316 $lData[] = array("data" => array(
317 $str,
318 $target,
319 $this->__convertPartSize($part['size'], $part['grow'], $part['maxSize']),
320 $device,
321 $fsType,
322 $part['fsOptions'],
323 "{$primaryImg} {$formatImg} {$bootImg} {$encryptImg}",
324 $delImg));
325 }
326 }
327 }
328 }
330 // Updated columns length for all entries to avoid render errors.
331 $length = 8;
332 foreach($lData as $id => $entry){
333 while(count($lData[$id]['data']) < $length){
334 $lData[$id]['data'][] = '';
335 }
336 }
337 $this->entryList->setListData($lData, $lData);
338 $this->entryList->update();
340 $smarty = get_smarty();
341 $smarty->assign('error', FALSE);
342 $smarty->assign('list', $this->entryList->render());
343 return($smarty->fetch(get_template_path('goto/Device/DevicePartition.tpl', TRUE)));
344 }
347 /*! \brief Keep posted HTML values and acts on remove requests.
348 */
349 function save_object()
350 {
351 // Create a map whcih points to the correct remove method for each device.
352 $map = array();
353 $map['part'] = array('func' => 'delPartition', 'name' => _("Partition"));
354 $map['raid'] = array('func' => 'delRaidDevice', 'name' => _("Raid device"));
355 $map['disk'] = array('func' => 'delDisk', 'name' => _("Disk"));
356 $map['vg'] = array('func' => 'delVolumeGroup', 'name' => _("Volume group"));
357 $map['v'] = array('func' => 'delVolume', 'name' => _("Volume"));
359 // Walk through posts and search for remove requests.
360 foreach($_POST as $name => $value){
361 foreach($map as $type => $data){
363 // Remove paritions
364 if(preg_match("/^delete_{$type}_[0-9]*$/", $name)){
365 $id = preg_replace("/^delete_{$type}_/i", "", $name) + 0;
366 $func = $data['func'];
367 @$this->object->$func($id);
368 if(!$this->object->success()){
369 $msg = sprintf(_("Failed to remove '%s': %s"), $data['name'], $this->object->getError());
370 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
371 }
372 }
373 }
374 }
375 }
378 /*! \brief Returns to created partition table string, which can then be
379 * saved back to the server.
380 */
381 function save()
382 {
383 return($this->object->dump());
384 }
387 /*! \brief Convert a given size value to a human readable format.
388 */
389 function __convertPartSize($size, $grow = False, $maxSize = NULL)
390 {
391 $str = $size." "._("MB");
393 if($maxSize != NULL){
394 $str .= " - ".$this->__convertPartSize($maxSize);
395 }elseif($grow){
396 $str .= " - ... <i>("._("growing").")</i>";
397 }
398 return($str);
399 }
400 }
402 ?>