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. | ||||
| Attached Files | 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();
}
| ||||
| 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. |
|
|
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 |