已开启
fix: 支持SSU定位灯控制(Redfish/Web) #1505
huangminghao创建于 8 天前
fix: 支持SSU定位灯控制(Redfish/Web) #1505
已开启
共 5 个文件变更+419-1
| @@ -1389,6 +1389,179 @@ | |||
| 1389 | } | 1389 | } |
| 1390 | ] | 1390 | ] |
| 1391 | }, | 1391 | }, |
| 1392 | + { | ||
W | |||
| 1393 | + "Uri": "/redfish/v1/Chassis/SSU:id", | ||
| 1394 | + "Interfaces": [ | ||
| 1395 | + { | ||
| 1396 | + "Type": "GET", | ||
| 1397 | + "ResourceExist": { | ||
| 1398 | + "${Statements/IsValidSSUId()}": true | ||
| 1399 | + }, | ||
| 1400 | + "RspBody": { | ||
| 1401 | + "@odata.context": "/redfish/v1/$metadata#Chassis.Chassis", | ||
| 1402 | + "@odata.id": "/redfish/v1/Chassis/SSU${Uri/id}", | ||
| 1403 | + "@odata.type": "#Chassis.v1_26_0.Chassis", | ||
| 1404 | + "Id": "${ProcessingFlow[1]/Destination/Id}", | ||
| 1405 | + "Name": "${ProcessingFlow[2]/Destination/Name}", | ||
| 1406 | + "ChassisType": "Module", | ||
| 1407 | + "LocationIndicatorActive": "${Statements/GetLocationIndicatorActive()}" | ||
| 1408 | + }, | ||
| 1409 | + "Statements": { | ||
| 1410 | + "GetSSUPath": { | ||
| 1411 | + "Steps": [ | ||
| 1412 | + { | ||
| 1413 | + "Type": "Plugin", | ||
| 1414 | + "Formula": "orchestrator.chassis.get_ssu_path(Uri.id)" | ||
| 1415 | + } | ||
| 1416 | + ] | ||
| 1417 | + }, | ||
| 1418 | + "GetSSULedPath": { | ||
| 1419 | + "Steps": [ | ||
| 1420 | + { | ||
| 1421 | + "Type": "Plugin", | ||
| 1422 | + "Formula": "orchestrator.chassis.get_ssu_led_path(Uri.id)" | ||
| 1423 | + } | ||
| 1424 | + ] | ||
| 1425 | + }, | ||
| 1426 | + "IsValidSSUId": { | ||
| 1427 | + "Input": "${Statements/GetSSUPath()}", | ||
| 1428 | + "Steps": [ | ||
| 1429 | + { | ||
| 1430 | + "Type": "Switch", | ||
| 1431 | + "Formula": [ | ||
| 1432 | + { | ||
| 1433 | + "Case": "", | ||
| 1434 | + "To": false | ||
| 1435 | + }, | ||
| 1436 | + { | ||
| 1437 | + "To": true | ||
| 1438 | + } | ||
| 1439 | + ] | ||
| 1440 | + } | ||
| 1441 | + ] | ||
| 1442 | + }, | ||
| 1443 | + "GetLocationIndicatorActive": { | ||
| 1444 | + "Input": "${ProcessingFlow[3]/Destination/State}", | ||
| 1445 | + "Steps": [ | ||
| 1446 | + { | ||
| 1447 | + "Type": "Switch", | ||
| 1448 | + "Formula": [ | ||
| 1449 | + { "Case": 0, "To": false }, | ||
| 1450 | + { "Case": 5, "To": true }, | ||
| 1451 | + { "Case": 255, "To": true }, | ||
| 1452 | + { "To": null } | ||
| 1453 | + ] | ||
| 1454 | + } | ||
| 1455 | + ] | ||
| 1456 | + } | ||
| 1457 | + }, | ||
| 1458 | + "ProcessingFlow": [ | ||
| 1459 | + { | ||
| 1460 | + "Type": "Property", | ||
| 1461 | + "Path": "${Statements/GetSSUPath()}", | ||
| 1462 | + "Interface": "bmc.dev.Chassis", | ||
| 1463 | + "Destination": { | ||
| 1464 | + "Id": "Id" | ||
| 1465 | + } | ||
| 1466 | + }, | ||
| 1467 | + { | ||
| 1468 | + "Type": "Property", | ||
| 1469 | + "Path": "${Statements/GetSSUPath()}", | ||
| 1470 | + "Interface": "bmc.dev.Board", | ||
| 1471 | + "Destination": { | ||
| 1472 | + "Name": "Name" | ||
| 1473 | + } | ||
| 1474 | + }, | ||
| 1475 | + { | ||
| 1476 | + "Type": "Property", | ||
| 1477 | + "Path": "${Statements/GetSSULedPath()}", | ||
| 1478 | + "Interface": "bmc.kepler.Systems.Led", | ||
| 1479 | + "Destination": { | ||
| 1480 | + "State": "State" | ||
| 1481 | + } | ||
| 1482 | + } | ||
| 1483 | + ] | ||
| 1484 | + }, | ||
| 1485 | + { | ||
| 1486 | + "Type": "PATCH", | ||
| 1487 | + "ResourceExist": { | ||
| 1488 | + "${Statements/IsValidSSUId()}": true | ||
| 1489 | + }, | ||
| 1490 | + "LockdownAllow": true, | ||
| 1491 | + "ReqBody": { | ||
| 1492 | + "Type": "object", | ||
| 1493 | + "Required": true, | ||
| 1494 | + "Properties": { | ||
| 1495 | + "LocationIndicatorActive": { | ||
| 1496 | + "Type": "boolean" | ||
| 1497 | + } | ||
| 1498 | + } | ||
| 1499 | + }, | ||
| 1500 | + "Statements": { | ||
| 1501 | + "GetSSUPath": { | ||
| 1502 | + "Steps": [ | ||
| 1503 | + { | ||
| 1504 | + "Type": "Plugin", | ||
| 1505 | + "Formula": "orchestrator.chassis.get_ssu_path(Uri.id)" | ||
| 1506 | + } | ||
| 1507 | + ] | ||
| 1508 | + }, | ||
| 1509 | + "GetSSULedPath": { | ||
| 1510 | + "Steps": [ | ||
| 1511 | + { | ||
| 1512 | + "Type": "Plugin", | ||
| 1513 | + "Formula": "orchestrator.chassis.get_ssu_led_path(Uri.id)" | ||
| 1514 | + } | ||
| 1515 | + ] | ||
| 1516 | + }, | ||
| 1517 | + "IsValidSSUId": { | ||
| 1518 | + "Input": "${Statements/GetSSUPath()}", | ||
| 1519 | + "Steps": [ | ||
| 1520 | + { | ||
| 1521 | + "Type": "Switch", | ||
| 1522 | + "Formula": [ | ||
| 1523 | + { | ||
| 1524 | + "Case": "", | ||
| 1525 | + "To": false | ||
| 1526 | + }, | ||
| 1527 | + { | ||
| 1528 | + "To": true | ||
| 1529 | + } | ||
| 1530 | + ] | ||
| 1531 | + } | ||
| 1532 | + ] | ||
| 1533 | + }, | ||
| 1534 | + "SetLocationIndicatorActiveState": { | ||
| 1535 | + "Input": "${ReqBody/LocationIndicatorActive}", | ||
| 1536 | + "Steps": [ | ||
| 1537 | + { | ||
| 1538 | + "Type": "Switch", | ||
| 1539 | + "Formula": [ | ||
| 1540 | + { "Case": true, "To": 5 }, | ||
| 1541 | + { "Case": false, "To": 0 } | ||
| 1542 | + ] | ||
| 1543 | + } | ||
| 1544 | + ] | ||
| 1545 | + } | ||
| 1546 | + }, | ||
| 1547 | + "ProcessingFlow": [ | ||
| 1548 | + { | ||
| 1549 | + "Type": "Method", | ||
| 1550 | + "Path": "${Statements/GetSSULedPath()}", | ||
| 1551 | + "Interface": "bmc.kepler.Systems.Led", | ||
| 1552 | + "Name": "SetState", | ||
| 1553 | + "Params": [ | ||
| 1554 | + "${Statements/SetLocationIndicatorActiveState()}", | ||
| 1555 | + 255 | ||
| 1556 | + ], | ||
| 1557 | + "CallIf": { | ||
| 1558 | + "${ReqBody/LocationIndicatorActive}": "#WITH" | ||
| 1559 | + } | ||
| 1560 | + } | ||
| 1561 | + ] | ||
| 1562 | + } | ||
| 1563 | + ] | ||
| 1564 | + }, | ||
| 1392 | { | 1565 | { |
| 1393 | "Uri": "/Expand/Chassis/bmc/kepler/Systems/:systemid/Processors/CPU/:id", | 1566 | "Uri": "/Expand/Chassis/bmc/kepler/Systems/:systemid/Processors/CPU/:id", |
| 1394 | "Interfaces": [ | 1567 | "Interfaces": [ |
| @@ -250,6 +250,40 @@ function m.get_expansion_path(expansionid) | |||
| 250 | return path | 250 | return path |
| 251 | end | 251 | end |
| 252 | 252 | ||
| 253 | +-- 获取SSU模组Chassis对象路径 | ||
| 254 | +function m.get_ssu_path(ssuid) | ||
| 255 | + local id = 'SSU' .. ssuid | ||
| 256 | + local path = bus:call( | ||
| 257 | + 'bmc.kepler.maca', | ||
| 258 | + '/bmc/kepler/MdbService', | ||
| 259 | + 'bmc.kepler.Mdb', | ||
| 260 | + 'GetPath', | ||
| 261 | + 'a{ss}ssb', | ||
| 262 | + context.new(), | ||
| 263 | + 'bmc.dev.Chassis', | ||
| 264 | + cjson.encode({ Id = id }), | ||
| 265 | + false | ||
| 266 | + ) | ||
| 267 | + return path | ||
| 268 | +end | ||
| 269 | + | ||
| 270 | +-- 获取SSU模组定位灯对象路径 | ||
| 271 | +function m.get_ssu_led_path(ssuid) | ||
| 272 | + local name = 'SSU' .. ssuid .. '_UID' | ||
| 273 | + local path = bus:call( | ||
| 274 | + 'bmc.kepler.maca', | ||
| 275 | + '/bmc/kepler/MdbService', | ||
| 276 | + 'bmc.kepler.Mdb', | ||
| 277 | + 'GetPath', | ||
| 278 | + 'a{ss}ssb', | ||
| 279 | + context.new(), | ||
| 280 | + 'bmc.kepler.Systems.Led', | ||
| 281 | + cjson.encode({ Name = name }), | ||
| 282 | + false | ||
| 283 | + ) | ||
| 284 | + return path | ||
| 285 | +end | ||
| 286 | + | ||
| 253 | function m.get_manager_path(managers) | 287 | function m.get_manager_path(managers) |
| 254 | local num = string.match(managers[1] or '', 'Manager(%d+)') | 288 | local num = string.match(managers[1] or '', 'Manager(%d+)') |
| 255 | local id = num and ('Expansion' .. num) or nil | 289 | local id = num and ('Expansion' .. num) or nil |
Minterface_config/redfish/static_resource/redfish/v1/schemastore/en/dmtf/json_schema/chassis.json+2-1
| @@ -50,7 +50,8 @@ | |||
| 50 | "deletable": false, | 50 | "deletable": false, |
| 51 | "uris": [ | 51 | "uris": [ |
| 52 | "/redfish/v1/Chassis/:chassisid", | 52 | "/redfish/v1/Chassis/:chassisid", |
| 53 | - "/redfish/v1/Chassis/Expansion:id" | 53 | + "/redfish/v1/Chassis/Expansion:id", |
| 54 | + "/redfish/v1/Chassis/SSU:id" | ||
| 54 | ] | 55 | ] |
| 55 | } | 56 | } |
| 56 | }, | 57 | }, |
| @@ -0,0 +1,168 @@ | |||
| 1 | +{ | ||
| 2 | + "Resources": [ | ||
| 3 | + { | ||
| 4 | + "Uri": "/UI/Rest/System/SSUs", | ||
| 5 | + "Interfaces": [ | ||
| 6 | + { | ||
| 7 | + "Type": "GET", | ||
| 8 | + "RspBody": { | ||
| 9 | + "List": "${Statements/GetSSUList()}" | ||
| 10 | + }, | ||
| 11 | + "Statements": { | ||
| 12 | + "GetSSUList": { | ||
| 13 | + "Steps": [ | ||
| 14 | + { | ||
| 15 | + "Type": "Plugin", | ||
| 16 | + "Formula": "orchestrator.chassis.get_ssu_list()" | ||
| 17 | + } | ||
| 18 | + ] | ||
| 19 | + } | ||
| 20 | + } | ||
| 21 | + } | ||
| 22 | + ] | ||
| 23 | + }, | ||
| 24 | + { | ||
| 25 | + "Uri": "/UI/Rest/System/SSUs/:id", | ||
| 26 | + "Interfaces": [ | ||
| 27 | + { | ||
| 28 | + "Type": "GET", | ||
| 29 | + "ResourceExist": { | ||
| 30 | + "${Statements/IsValidSSUId()}": true | ||
| 31 | + }, | ||
| 32 | + "RspBody": { | ||
| 33 | + "Id": "${Uri/id}", | ||
| 34 | + "LocationIndicatorActive": "${Statements/GetLocationIndicatorActive()}", | ||
| 35 | + "SystemId": 1 | ||
| 36 | + }, | ||
| 37 | + "Statements": { | ||
| 38 | + "GetSSUPath": { | ||
| 39 | + "Steps": [ | ||
| 40 | + { | ||
| 41 | + "Type": "Plugin", | ||
| 42 | + "Formula": "orchestrator.chassis.get_ssu_path(Uri.id)" | ||
| 43 | + } | ||
| 44 | + ] | ||
| 45 | + }, | ||
| 46 | + "GetSSULedPath": { | ||
| 47 | + "Steps": [ | ||
| 48 | + { | ||
| 49 | + "Type": "Plugin", | ||
| 50 | + "Formula": "orchestrator.chassis.get_ssu_led_path(Uri.id)" | ||
| 51 | + } | ||
| 52 | + ] | ||
| 53 | + }, | ||
| 54 | + "IsValidSSUId": { | ||
| 55 | + "Input": "${Statements/GetSSUPath()}", | ||
| 56 | + "Steps": [ | ||
| 57 | + { | ||
| 58 | + "Type": "Switch", | ||
| 59 | + "Formula": [ | ||
| 60 | + { "Case": "", "To": false }, | ||
| 61 | + { "To": true } | ||
| 62 | + ] | ||
| 63 | + } | ||
| 64 | + ] | ||
| 65 | + }, | ||
| 66 | + "GetLocationIndicatorActive": { | ||
| 67 | + "Input": "${ProcessingFlow[1]/Destination/State}", | ||
| 68 | + "Steps": [ | ||
| 69 | + { | ||
| 70 | + "Type": "Switch", | ||
| 71 | + "Formula": [ | ||
| 72 | + { "Case": 0, "To": false }, | ||
| 73 | + { "Case": 5, "To": true }, | ||
| 74 | + { "Case": 255, "To": true }, | ||
| 75 | + { "To": null } | ||
| 76 | + ] | ||
| 77 | + } | ||
| 78 | + ] | ||
| 79 | + } | ||
| 80 | + }, | ||
| 81 | + "ProcessingFlow": [ | ||
| 82 | + { | ||
| 83 | + "Type": "Property", | ||
| 84 | + "Path": "${Statements/GetSSULedPath()}", | ||
| 85 | + "Interface": "bmc.kepler.Systems.Led", | ||
| 86 | + "Destination": { | ||
| 87 | + "State": "State" | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + ] | ||
| 91 | + }, | ||
| 92 | + { | ||
| 93 | + "Type": "PATCH", | ||
| 94 | + "ResourceExist": { | ||
| 95 | + "${Statements/IsValidSSUId()}": true | ||
| 96 | + }, | ||
| 97 | + "LockdownAllow": true, | ||
| 98 | + "ReqBody": { | ||
| 99 | + "Type": "object", | ||
| 100 | + "Required": true, | ||
| 101 | + "Properties": { | ||
| 102 | + "LocationIndicatorActive": { | ||
| 103 | + "Type": "boolean" | ||
| 104 | + } | ||
| 105 | + } | ||
| 106 | + }, | ||
| 107 | + "Statements": { | ||
| 108 | + "GetSSUPath": { | ||
| 109 | + "Steps": [ | ||
| 110 | + { | ||
| 111 | + "Type": "Plugin", | ||
| 112 | + "Formula": "orchestrator.chassis.get_ssu_path(Uri.id)" | ||
| 113 | + } | ||
| 114 | + ] | ||
| 115 | + }, | ||
| 116 | + "GetSSULedPath": { | ||
| 117 | + "Steps": [ | ||
| 118 | + { | ||
| 119 | + "Type": "Plugin", | ||
| 120 | + "Formula": "orchestrator.chassis.get_ssu_led_path(Uri.id)" | ||
| 121 | + } | ||
| 122 | + ] | ||
| 123 | + }, | ||
| 124 | + "IsValidSSUId": { | ||
| 125 | + "Input": "${Statements/GetSSUPath()}", | ||
| 126 | + "Steps": [ | ||
| 127 | + { | ||
| 128 | + "Type": "Switch", | ||
| 129 | + "Formula": [ | ||
| 130 | + { "Case": "", "To": false }, | ||
| 131 | + { "To": true } | ||
| 132 | + ] | ||
| 133 | + } | ||
| 134 | + ] | ||
| 135 | + }, | ||
| 136 | + "SetLocationIndicatorActiveState": { | ||
| 137 | + "Input": "${ReqBody/LocationIndicatorActive}", | ||
| 138 | + "Steps": [ | ||
| 139 | + { | ||
| 140 | + "Type": "Switch", | ||
| 141 | + "Formula": [ | ||
| 142 | + { "Case": true, "To": 5 }, | ||
| 143 | + { "Case": false, "To": 0 } | ||
| 144 | + ] | ||
| 145 | + } | ||
| 146 | + ] | ||
| 147 | + } | ||
| 148 | + }, | ||
| 149 | + "ProcessingFlow": [ | ||
| 150 | + { | ||
| 151 | + "Type": "Method", | ||
| 152 | + "Path": "${Statements/GetSSULedPath()}", | ||
| 153 | + "Interface": "bmc.kepler.Systems.Led", | ||
| 154 | + "Name": "SetState", | ||
| 155 | + "Params": [ | ||
| 156 | + "${Statements/SetLocationIndicatorActiveState()}", | ||
| 157 | + 255 | ||
| 158 | + ], | ||
| 159 | + "CallIf": { | ||
| 160 | + "${ReqBody/LocationIndicatorActive}": "#WITH" | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | + ] | ||
| 164 | + } | ||
| 165 | + ] | ||
| 166 | + } | ||
| 167 | + ] | ||
| 168 | +} | ||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | local cjson = require('cjson') | 11 | local cjson = require('cjson') |
| 12 | local log = require('mc.logging') | 12 | local log = require('mc.logging') |
| 13 | +local mdb_service = require('mc.mdb.mdb_service') | ||
| 13 | local detection_path = '/bmc/kepler/Chassis/1/ThermalSubsystem/LeakDetection' | 14 | local detection_path = '/bmc/kepler/Chassis/1/ThermalSubsystem/LeakDetection' |
| 14 | local detection_interface = 'bmc.kepler.Chassis.LeakDetection' | 15 | local detection_interface = 'bmc.kepler.Chassis.LeakDetection' |
| 15 | 16 | ||
| @@ -94,4 +95,45 @@ function m.getpowerstate() | |||
| 94 | end | 95 | end |
| 95 | end | 96 | end |
| 96 | 97 | ||
| 98 | +-- 获取SSU模组Chassis对象路径 | ||
| 99 | +function m.get_ssu_path(ssu_id) | ||
| 100 | + local filter = cjson.encode({ Id = ssu_id }) | ||
| 101 | + local ok, rsp = pcall(mdb_service.get_path, bus, 'bmc.dev.Chassis', filter, false) | ||
| 102 | + if not ok or not rsp or rsp.Path == '' then | ||
| 103 | + return '' | ||
| 104 | + end | ||
| 105 | + return rsp.Path | ||
| 106 | +end | ||
| 107 | + | ||
| 108 | +-- 获取SSU模组定位灯对象路径 | ||
| 109 | +function m.get_ssu_led_path(ssu_id) | ||
| 110 | + local filter = cjson.encode({ Name = ssu_id .. '_UID' }) | ||
| 111 | + local ok, rsp = pcall(mdb_service.get_path, bus, 'bmc.kepler.Systems.Led', filter, false) | ||
| 112 | + if not ok or not rsp or rsp.Path == '' then | ||
| 113 | + return '' | ||
| 114 | + end | ||
| 115 | + return rsp.Path | ||
| 116 | +end | ||
| 117 | + | ||
| 118 | +-- 获取所有SSU模组的Id列表 | ||
| 119 | +function m.get_ssu_list() | ||
| 120 | + local ok, res = pcall(mdb_service.get_sub_objects, bus, '/bmc/dev', 4, { 'bmc.dev.Chassis' }) | ||
| 121 | + if not ok or not res or not res.SubObjects then | ||
| 122 | + return {} | ||
| 123 | + end | ||
| 124 | + local list = {} | ||
| 125 | + for path, _ in pairs(res.SubObjects) do | ||
| 126 | + local obj_ok, obj = pcall(mdb.get_object, bus, path, 'bmc.dev.Chassis') | ||
| 127 | + if obj_ok and obj and obj.Id and string.match(obj.Id, '^SSU') then | ||
| 128 | + table.insert(list, '/UI/Rest/System/SSUs/' .. obj.Id) | ||
| 129 | + end | ||
| 130 | + end | ||
| 131 | + table.sort(list, function(a, b) | ||
| 132 | + local na = tonumber(string.match(a, 'SSU(%d+)')) | ||
| 133 | + local nb = tonumber(string.match(b, 'SSU(%d+)')) | ||
| 134 | + return na < nb | ||
| 135 | + end) | ||
| 136 | + return list | ||
| 137 | +end | ||
| 138 | + | ||
| 97 | return m | 139 | return m |


PATCH 的 SetState 调用中,Params 为 ["${Statements/SetLocationIndicatorActiveState()}", 255],即 Interval 固定为 255。但 PR 描述中明确说明'PATCH true→SetState(5, 255)(闪烁255秒自动灭)',且 chassis 仓的 identify 倒计时为 interval10 秒。25510=2550 秒(42.5分钟),与 PR 描述中'闪烁255秒自动灭'不符。PR 描述声称 255 秒,但实际实现为 2550 秒,存在明显的时间语义偏差。