View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
745 | RackTables | VMs/containers | public | 2013-02-13 10:41 | 2013-05-18 23:23 |
Reporter | MWilkinson | Assigned To | adoom42 | ||
Priority | normal | Severity | tweak | Reproducibility | N/A |
Status | closed | Resolution | fixed | ||
Product Version | 0.20.3 | ||||
Target Version | 0.20.5 | Fixed in Version | 0.20.5 | ||
Summary | 745: Display Blade servers in Chassis | ||||
Description | This patch alters the way the RackTables rendering of racks is performed to show blades mounted in chassis within the rack. | ||||
Steps To Reproduce | Apply the included Patch. Note : There are 2 versions of this patch, 1 against the Base install of RackTables-0.20.3, the other against RackTables-0.20.3 with my other portlets patch already applied (see http://bugs.racktables.org/view.php?id=691) | ||||
Additional Information | Currently it is hard coded for Servers and Server Chassis's only. 2 New attributes need defining for the Chasses, 'Num Rows' and 'Num Cols' which define how many rows and cols of blades a chassis can hold - this may be better implemented in a dictionary of standard Chassis Configurations (ie, 1 x 10, 2 x 8, etc) | ||||
Tags | No tags attached. | ||||
It should be noted that for the Server to appear in the Chassis, the slot number on the server should be set to a value between 1 and (Num Rows * Num Cols) | |
Aaron, could you please review this patch? I don't have containers in my environment and so it's hard to decide if it's useful. |
|
I really like this patch. May I suggest that it is incorporated into racktables? Additionally I'd like to propose a small modification: Please accept your own changes from mailinglist post on Feb. 13th 2013: http://www.freelists.org/post/racktables-users/Antwort-Re-Antwort-Patch-to-display-Blades-in-Chassis-in-Rack,1 With all patches applied, rows and columns work like a charm for us. Thanks for the great work! |
|
New versions of the patch - again against stock RackTables 0.20.4 and one with my other patch for the portlets. Things to note - the 2 extra attributes are no longer needed - it seem daft to have to enter this information in to every chassis when it should only need to be entered once. To this end, this patch adds a '%L' marker which is similar to the '%G' markers already used in the Hardware description. The %L marker is constructed as follows :- '%L<rows>,<cols>[<layout>]%' where <rows> is the number of rows in the chassis, <cols> is the number of columns in the chassis and <layout> is an optional Layout hint, either H for horizonal, or V for vertical. If the layout hint is not supplied, chassis with less than 6 slots will be laid out with horizontal slot names, otherwise vertical slot names will be used. |
|
chassis-0.20.4-base.patch (7,354 bytes)
diff -urN RackTables-0.20.4-orig/wwwroot/inc/dictionary.php base/wwwroot/inc/dictionary.php --- RackTables-0.20.4-orig/wwwroot/inc/dictionary.php 2013-04-14 21:27:19.000000000 +0100 +++ base/wwwroot/inc/dictionary.php 2013-05-16 12:49:23.681661125 +0100 @@ -1081,7 +1081,7 @@ 991 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R710'), 992 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R805'), 993 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R905'), - 994 => array ('chapter_id' => 31, 'dict_value' => 'Dell PowerEdge%GPASS%M1000e'), + 994 => array ('chapter_id' => 31, 'dict_value' => 'Dell PowerEdge%GPASS%M1000e%L2,8V%'), 995 => array ('chapter_id' => 18, 'dict_value' => 'Dell PowerVault%GPASS%MD1000'), 996 => array ('chapter_id' => 18, 'dict_value' => 'Dell PowerVault%GPASS%MD1120'), 997 => array ('chapter_id' => 18, 'dict_value' => 'Dell EqualLogic PS5000'), @@ -1601,7 +1601,7 @@ 1514 => array ('chapter_id' => 13, 'dict_value' => 'Xen Hypervisor%GSKIP%XenServer 4.0'), 1515 => array ('chapter_id' => 13, 'dict_value' => 'Xen Hypervisor%GSKIP%XenServer 5.0'), 1516 => array ('chapter_id' => 13, 'dict_value' => 'Xen Hypervisor%GSKIP%XenServer 5.5'), - 1517 => array ('chapter_id' => 31, 'dict_value' => 'Dell PowerEdge%GPASS%1855'), + 1517 => array ('chapter_id' => 31, 'dict_value' => 'Dell PowerEdge%GPASS%1855%L1,10V%'), 1518 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge (blade)%GPASS%1955'), 1519 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge (blade)%GPASS%M605'), 1520 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge (blade)%GPASS%M610'), diff -urN RackTables-0.20.4-orig/wwwroot/inc/functions.php base/wwwroot/inc/functions.php --- RackTables-0.20.4-orig/wwwroot/inc/functions.php 2013-04-14 21:27:19.000000000 +0100 +++ base/wwwroot/inc/functions.php 2013-05-16 12:49:23.681661125 +0100 @@ -1055,7 +1055,27 @@ // FIXME: should this be saved as "P-data"? function execGMarker ($line) { - return preg_replace ('/^.+%GSKIP%/', '', preg_replace ('/^(.+)%GPASS%/', '\\1 ', $line)); + return preg_replace ('/^.+%GSKIP%/', '', + preg_replace ('/^(.+)%GPASS%/', '\\1 ', + preg_replace ('/%L\d+,\d+(H|V|)%/', '', $line))); +} + +// extract the layout information from the %L...% marker in the dictionary info +// This is somewhat similar to the %GPASS %GSKIP +// +function extractLayout (&$record) +{ + if ( preg_match ('/%L(\d+),(\d+)(H|V|)%/', $record['value'], $matches) ) + { + $record['rows'] = $matches[1]; + $record['cols'] = $matches[2]; + $record['layout'] = $matches[3]; + if (! strlen($record['layout']) ) + if ( $record['cols'] >= 4 ) + $record['layout'] = 'V'; + else + $record['layout'] = 'H'; + } } // rackspace usage for a single rack @@ -3327,7 +3347,7 @@ $ifname = preg_replace ('@^BE(\d+)$@', 'bundle-ether\\1', $ifname); // IOS XR4 $ifname = strtolower ($ifname); $ifname = preg_replace ('/^(e|fa|gi|te|po|xg|lo|ma)\s+(\d.*)/', '$1$2', $ifname); - return $ifname; + return ucfirst($ifname); } # Produce a list of integers from a string in the following format: diff -urN RackTables-0.20.4-orig/wwwroot/inc/interface.php base/wwwroot/inc/interface.php --- RackTables-0.20.4-orig/wwwroot/inc/interface.php 2013-04-14 21:27:19.000000000 +0100 +++ base/wwwroot/inc/interface.php 2013-05-16 12:54:16.711661568 +0100 @@ -594,7 +594,7 @@ } // Used by renderRack() -function printObjectDetailsForRenderRack ($object_id) +function printObjectDetailsForRenderRack ($object_id, $hl_obj_id = 0) { $objectData = spotEntity ('object', $object_id); if (strlen ($objectData['asset_no'])) @@ -607,16 +607,80 @@ $body = ", visible label is \"${objectData['label']}\""; // Display list of child objects, if any $objectChildren = getEntityRelatives ('children', 'object', $objectData['id']); + $slotInfo = Array(); + $slotData = Array(); + $slotTitle = Array(); if (count($objectChildren) > 0) { foreach ($objectChildren as $child) + { $childNames[] = $child['name']; + $childData = spotEntity ('object', $child['entity_id']); + $attrData = getAttrValues ($child['entity_id']); + if ( $attrData['28'] ) + { + $slot = $attrData['28']['value']; + $slotInfo[$slot] = $child['name']; + $slotData[$slot] = $child['entity_id']; + if ( strlen ($childData['asset_no']) ) + $slotTitle[$slot] = "<div title='${childData['asset_no']}"; + else + $slotTitle[$slot] = "<div title='no asset tag"; + if ( $child['name'] != $child['label'] and strlen ($child['label']) ) + $slotTitle[$slot] .= ", visible label is \"${child['label']}\""; + $slotTitle[$slot] .= "'>"; + } + } natsort($childNames); $suffix = sprintf(", contains %s'>", implode(', ', $childNames)); } else $suffix = "'>"; echo "${prefix}${body}${suffix}" . mkA ($objectData['dname'], 'object', $objectData['id']) . '</div>'; + if ( in_array ($objectData['objtype_id'], array(1502,1503) ) ) + { + $objAttr = getAttrValues ($objectData['id']); + if ( isset ($objAttr[2]) ) + { + extractLayout($objAttr[2]); + if ( isset ($objAttr[2]['rows'] ) ) + { + echo "<table width='100%' border='1'>"; + for ($r=0; $r<$objAttr[2]['rows']; $r++) + { + echo "<tr>"; + for ( $c=0; $c<$objAttr[2]['cols']; $c++) + { + $s = ($r * $objAttr[2]['cols']) + $c + 1; + if ( $slotData[$s] ) + { + echo "<td class='state_T"; + if ( $slotData[$s] == $hl_obj_id ) + echo "h"; + echo "'>"; + echo $slotTitle[$s]; + if ( $objAttr[2]['layout'] == "V" ) + { + $tmp = substr ($slotInfo[$s], 0, 1); + foreach ( str_split (substr ($slotInfo[$s],1) ) as $letter ) + $tmp .= "<br>" . $letter; + $slotInfo[$s] = $tmp; + } + echo mkA ($slotInfo[$s], 'object', $slotData[$s]); + echo "</div></td>"; + } + else + echo "<td class='state_F'><div title=\"Free slot\"> </div></td>"; + } + echo "</tr>"; + } + echo "</table>"; + } + $fh = fopen("/tmp/rackData.lis","w"); + fwrite($fh, print_r($objAttr, true)); + fclose($fh); + } + } } // This function renders rack as HTML table. @@ -661,7 +725,7 @@ switch ($state) { case 'T': - printObjectDetailsForRenderRack($rackData[$i][$locidx]['object_id']); + printObjectDetailsForRenderRack($rackData[$i][$locidx]['object_id'], $hl_obj_id); break; case 'A': echo '<div title="This rackspace does not exist"> </div>'; @@ -1310,8 +1374,22 @@ { // rackspace portlet startPortlet ('rackspace allocation'); - foreach (getResidentRacksData ($object_id, FALSE) as $rack_id) - renderRack ($rack_id, $object_id); + if ( in_array( $info['objtype_id'], array(4,8) ) ) { + $parents = getEntityRelatives ('parents', 'object', $info['id']); + if (count ($parents)) + { + foreach ($parents as $parent) + foreach (getResidentRacksData($parent['entity_id'], FALSE) as $rack_id) + renderRack( $rack_id, $object_id ); + } + else + foreach (getResidentRacksData ($object_id, FALSE) as $rack_id) + renderRack ($rack_id, $object_id); + } + else + foreach (getResidentRacksData ($object_id, FALSE) as $rack_id) + renderRack ($rack_id, $object_id); + echo '<br>'; finishPortlet(); } |
|
chassis-0.20.4-enhanced.patch (7,759 bytes)
diff -urN base/wwwroot/inc/dictionary.php RackTables-0.20.4-dev/wwwroot/inc/dictionary.php --- base/wwwroot/inc/dictionary.php 2013-05-16 12:37:41.095622580 +0100 +++ RackTables-0.20.4-dev/wwwroot/inc/dictionary.php 2013-05-16 10:30:19.304190879 +0100 @@ -1081,7 +1081,7 @@ 991 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R710'), 992 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R805'), 993 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R905'), - 994 => array ('chapter_id' => 31, 'dict_value' => 'Dell PowerEdge%GPASS%M1000e'), + 994 => array ('chapter_id' => 31, 'dict_value' => 'Dell PowerEdge%GPASS%M1000e%L2,8V%'), 995 => array ('chapter_id' => 18, 'dict_value' => 'Dell PowerVault%GPASS%MD1000'), 996 => array ('chapter_id' => 18, 'dict_value' => 'Dell PowerVault%GPASS%MD1120'), 997 => array ('chapter_id' => 18, 'dict_value' => 'Dell EqualLogic PS5000'), @@ -1601,7 +1601,7 @@ 1514 => array ('chapter_id' => 13, 'dict_value' => 'Xen Hypervisor%GSKIP%XenServer 4.0'), 1515 => array ('chapter_id' => 13, 'dict_value' => 'Xen Hypervisor%GSKIP%XenServer 5.0'), 1516 => array ('chapter_id' => 13, 'dict_value' => 'Xen Hypervisor%GSKIP%XenServer 5.5'), - 1517 => array ('chapter_id' => 31, 'dict_value' => 'Dell PowerEdge%GPASS%1855'), + 1517 => array ('chapter_id' => 31, 'dict_value' => 'Dell PowerEdge%GPASS%1855%L1,10V%'), 1518 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge (blade)%GPASS%1955'), 1519 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge (blade)%GPASS%M605'), 1520 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge (blade)%GPASS%M610'), diff -urN base/wwwroot/inc/functions.php RackTables-0.20.4-dev/wwwroot/inc/functions.php --- base/wwwroot/inc/functions.php 2013-05-16 12:37:51.378492571 +0100 +++ RackTables-0.20.4-dev/wwwroot/inc/functions.php 2013-05-16 11:22:10.801660737 +0100 @@ -1055,7 +1055,27 @@ // FIXME: should this be saved as "P-data"? function execGMarker ($line) { - return preg_replace ('/^.+%GSKIP%/', '', preg_replace ('/^(.+)%GPASS%/', '\\1 ', $line)); + return preg_replace ('/^.+%GSKIP%/', '', + preg_replace ('/^(.+)%GPASS%/', '\\1 ', + preg_replace ('/%L\d+,\d+(H|V|)%/', '', $line))); +} + +// extract the layout information from the %L...% marker in the dictionary info +// This is somewhat similar to the %GPASS %GSKIP +// +function extractLayout (&$record) +{ + if ( preg_match ('/%L(\d+),(\d+)(H|V|)%/', $record['value'], $matches) ) + { + $record['rows'] = $matches[1]; + $record['cols'] = $matches[2]; + $record['layout'] = $matches[3]; + if (! strlen($record['layout']) ) + if ( $record['cols'] >= 4 ) + $record['layout'] = 'V'; + else + $record['layout'] = 'H'; + } } // rackspace usage for a single rack @@ -3327,7 +3347,7 @@ $ifname = preg_replace ('@^BE(\d+)$@', 'bundle-ether\\1', $ifname); // IOS XR4 $ifname = strtolower ($ifname); $ifname = preg_replace ('/^(e|fa|gi|te|po|xg|lo|ma)\s+(\d.*)/', '$1$2', $ifname); - return $ifname; + return ucfirst($ifname); } # Produce a list of integers from a string in the following format: diff -urN base/wwwroot/inc/interface.php RackTables-0.20.4-dev/wwwroot/inc/interface.php --- base/wwwroot/inc/interface.php 2013-05-16 12:37:51.401570636 +0100 +++ RackTables-0.20.4-dev/wwwroot/inc/interface.php 2013-05-16 12:32:23.081661201 +0100 @@ -595,7 +595,7 @@ } // Used by renderRack() -function printObjectDetailsForRenderRack ($object_id) +function printObjectDetailsForRenderRack ($object_id, $hl_obj_id = 0) { $objectData = spotEntity ('object', $object_id); if (strlen ($objectData['asset_no'])) @@ -608,16 +608,80 @@ $body = ", visible label is \"${objectData['label']}\""; // Display list of child objects, if any $objectChildren = getEntityRelatives ('children', 'object', $objectData['id']); + $slotInfo = Array(); + $slotData = Array(); + $slotTitle = Array(); if (count($objectChildren) > 0) { foreach ($objectChildren as $child) + { $childNames[] = $child['name']; + $childData = spotEntity ('object', $child['entity_id']); + $attrData = getAttrValues ($child['entity_id']); + if ( $attrData['28'] ) + { + $slot = $attrData['28']['value']; + $slotInfo[$slot] = $child['name']; + $slotData[$slot] = $child['entity_id']; + if ( strlen ($childData['asset_no']) ) + $slotTitle[$slot] = "<div title='${childData['asset_no']}"; + else + $slotTitle[$slot] = "<div title='no asset tag"; + if ( $child['name'] != $child['label'] and strlen ($child['label']) ) + $slotTitle[$slot] .= ", visible label is \"${child['label']}\""; + $slotTitle[$slot] .= "'>"; + } + } natsort($childNames); $suffix = sprintf(", contains %s'>", implode(', ', $childNames)); } else $suffix = "'>"; echo "${prefix}${body}${suffix}" . mkA ($objectData['dname'], 'object', $objectData['id']) . '</div>'; + if ( in_array ($objectData['objtype_id'], array(1502,1503) ) ) + { + $objAttr = getAttrValues ($objectData['id']); + if ( isset ($objAttr[2]) ) + { + extractLayout($objAttr[2]); + if ( isset ($objAttr[2]['rows'] ) ) + { + echo "<table width='100%' border='1'>"; + for ($r=0; $r<$objAttr[2]['rows']; $r++) + { + echo "<tr>"; + for ( $c=0; $c<$objAttr[2]['cols']; $c++) + { + $s = ($r * $objAttr[2]['cols']) + $c + 1; + if ( $slotData[$s] ) + { + echo "<td class='state_T"; + if ( $slotData[$s] == $hl_obj_id ) + echo "h"; + echo "'>"; + echo $slotTitle[$s]; + if ( $objAttr[2]['layout'] == "V" ) + { + $tmp = substr ($slotInfo[$s], 0, 1); + foreach ( str_split (substr ($slotInfo[$s],1) ) as $letter ) + $tmp .= "<br>" . $letter; + $slotInfo[$s] = $tmp; + } + echo mkA ($slotInfo[$s], 'object', $slotData[$s]); + echo "</div></td>"; + } + else + echo "<td class='state_F'><div title=\"Free slot\"> </div></td>"; + } + echo "</tr>"; + } + echo "</table>"; + } + $fh = fopen("/tmp/rackData.lis","w"); + fwrite($fh, print_r($objAttr, true)); + fclose($fh); + } + } } // This function renders rack as HTML table. @@ -662,7 +726,7 @@ switch ($state) { case 'T': - printObjectDetailsForRenderRack($rackData[$i][$locidx]['object_id']); + printObjectDetailsForRenderRack($rackData[$i][$locidx]['object_id'], $hl_obj_id); break; case 'A': echo '<div title="This rackspace does not exist"> </div>'; diff -urN base/wwwroot/inc/portlets.php RackTables-0.20.4-dev/wwwroot/inc/portlets.php --- base/wwwroot/inc/portlets.php 2013-05-16 12:37:51.407668381 +0100 +++ RackTables-0.20.4-dev/wwwroot/inc/portlets.php 2013-05-16 12:02:27.441666890 +0100 @@ -253,14 +264,30 @@ function renderObPortletRackspace( $info ) { + global $virtual_obj_types; + $object_id = $info['id']; if (!in_array($info['objtype_id'], $virtual_obj_types)) { // rackspace portlet startPortlet ('rackspace allocation'); - foreach (getResidentRacksData ($object_id, FALSE) as $rack_id) - renderRack ($rack_id, $object_id); + if ( in_array( $info['objtype_id'], array(4,8) ) ) { + $parents = getEntityRelatives ('parents', 'object', $info['id']); + if (count ($parents)) + { + foreach ($parents as $parent) + foreach (getResidentRacksData($parent['entity_id'], FALSE) as $rack_id) + renderRack( $rack_id, $object_id ); + } + else + foreach (getResidentRacksData ($object_id, FALSE) as $rack_id) + renderRack ($rack_id, $object_id); + } + else + foreach (getResidentRacksData ($object_id, FALSE) as $rack_id) + renderRack ($rack_id, $object_id); + echo '<br>'; finishPortlet(); } |
|
This approach doesn't support all use cases. For example, Dell's M1000e chassis accepts both full-height and half-height blades. But it is definitely an improvement, so it will appear in 0.20.5. Thanks. |
|
Date Modified | Username | Field | Change |
---|---|---|---|
2013-02-13 10:41 | MWilkinson | New Issue | |
2013-02-13 10:41 | MWilkinson | File Added: racktables-0-20-3.patch-base | |
2013-02-13 10:41 | MWilkinson | File Added: racktables-0-20-3.patch-enhanced | |
2013-02-13 11:29 | MWilkinson | File Deleted: racktables-0-20-3.patch-enhanced | |
2013-02-13 11:29 | MWilkinson | File Deleted: racktables-0-20-3.patch-base | |
2013-02-13 11:29 | MWilkinson | File Added: racktables-0-20-3.patch-base | |
2013-02-13 11:29 | MWilkinson | File Added: racktables-0-20-3.patch-enhanced | |
2013-02-13 14:10 | MWilkinson | Note Added: 0001129 | |
2013-02-22 12:17 | andriyanov | Note Added: 0001153 | |
2013-02-22 12:17 | andriyanov | Assigned To | => adoom42 |
2013-02-22 12:17 | andriyanov | Status | new => assigned |
2013-05-10 10:27 | mejo | Note Added: 0001389 | |
2013-05-13 01:09 | adoom42 | Category | default => VMs/containers |
2013-05-16 14:00 | MWilkinson | File Added: chassis-0.20.4-base.patch | |
2013-05-16 14:00 | MWilkinson | File Added: chassis-0.20.4-enhanced.patch | |
2013-05-16 14:05 | MWilkinson | Note Added: 0001419 | |
2013-05-16 14:14 | MWilkinson | File Deleted: chassis-0.20.4-enhanced.patch | |
2013-05-16 14:14 | MWilkinson | File Deleted: chassis-0.20.4-base.patch | |
2013-05-16 14:14 | MWilkinson | File Added: chassis-0.20.4-base.patch | |
2013-05-16 14:14 | MWilkinson | File Added: chassis-0.20.4-enhanced.patch | |
2013-05-18 23:23 | adoom42 | Note Added: 0001421 | |
2013-05-18 23:23 | adoom42 | Status | assigned => closed |
2013-05-18 23:23 | adoom42 | Resolution | open => fixed |
2013-05-18 23:23 | adoom42 | Fixed in Version | => 0.20.5 |
2013-05-18 23:23 | adoom42 | Target Version | => 0.20.5 |