libirc库对openUBMC社区提供KVM客户端开发套件,赋能用户在工具和系统集成KVM功能,调用libirc库提供的接口使用、操作KVM客户端。
编译环境搭建方法可见libirc库README文件。
功能介绍
通过集成libirc库,可以向BMC(作为服务端)发送封装好的WebSocket请求,将建立连接、执行操作、关闭连接以调用接口的方式便捷地集成至用户的系统中。
当前libirc库支持以下功能:
认证
- 基于boost开源软件和openssl, 发送https POST请求到
/UI/Rest/KvmHandler
, 用于创建KVM会话并获取token
和KVM端口号。
- 基于boost开源软件和openssl, 发送https POST请求到
建立WebSocket连接
- 基于boost开源软件和openssl, 与KVM服务端建立WebSocket连接;
- 使用认证阶段得到的
token
, 封装KVM认证报文,发送至服务端认证KVM会话; - 认证后启动心跳检测机制,定时发送封装的KVM心跳报文;
- 接收服务发送的KVM协议报文,解析并分发给其它业务处理;
- 关闭连接时发送封装的KVM断开连接报文;
BIOS启动项控制
- 连接KVM后会主动获取一次BIOS启动项当前配置;
- 接收到BIOS启动项配置响应报文后更新BIOS启动项当前配置;
- 根据用户输入封装BIOS启动项报文发送至KVM服务端;
电源控制
- 根据用户输入封装电源控制报文发送至KVM服务端;
虚拟光驱控制
- 根据用户输入封装虚拟光驱控制报文发送至KVM服务端,操作类型包括弹出和挂载虚拟媒体;
客户端调用接口后,根据接口返回码执行自定义后续操作。
关键接口
libirc库对外提供了以下关键接口,通过这些接口,可以实现开启、关闭KVM会话、进行光驱操作等。
关键接口功能
void SetErrorHandler(std::function<void(const std::exception&)> handler)
设置错误处理函数,入参为处理函数,而处理函数的入参为
exception
异常,用于自定义运行时错误异常的处理;void SetCloseHandler(std::function<void(const uint16_t&)> handler)
设置关闭处理函数,入参为处理函数,而处理函数的入参为KVM会话关闭状态码,定义参考WebSocket协议关闭状态码,用于自定义对KVM会话关闭的处理;
void SetLogHandler(std::function<void(const std::string&)> handler)
设置日志处理函数,入参为处理函数,而处理函数的入参为日志字符串,用于自定义运行时产生的日志处理;
int OpenKvm(const char* host, const char* port, const char* userName, const char* password, const char* kvmMode)
打开KVM会话函数,入参为主机IP、https端口号、用户名、密码、KVM连接模式(
0
:共享/1
:独占),出参为错误码响应,错误码定义参考响应码;int CloseKvm()
关闭KVM会话函数,出参为错误码响应,错误码定义参考响应码;
int GetBootOption(BootOption& option)
获取当前系统启动项函数,获取成功会将结果设置到传入的引用中,
BootOption
枚举类型定义参考系统启动项定义,出参为错误码响应;int SetBootOption(BootOption option)
设置系统启动项函数,入参为
BootOption
枚举类型的系统启动项,出参为错误码响应,错误码定义参考响应码;int PowerControl(PowerControlOption option)
电源控制函数,入参为
PowerControlOption
枚举类型的电源控制项,PowerControlOption
枚举类型定义参考电源控制项定义,出参为错误码响应,错误码定义参考响应码;int OpenVmm(const std::string& filePath, MountType type)
VMM虚拟媒体挂载函数,入参为本地镜像文件路径、挂载类型,当前仅支持挂载镜像文件,出参为错误码响应,错误码定义参考响应码;
int CloseVmm()
VMM虚拟媒体卸载函数,出参为错误码响应,错误码定义参考响应码;
响应码
libirc库定义了13种返回码,返回码对应表如下:
宏定义 | 常量值 | 说明 |
---|---|---|
E_OK | 0 | 执行成功 |
E_ERR | 1 | 发生错误 |
E_AUTHORIZATION_FAILED | 2 | 鉴权失败 |
E_NO_ACCESS | 3 | 无法获取 |
E_INSUFFICIENT_PRIVILEGE | 4 | 权限不足 |
E_SESSION_LIMIT_EXCEEDED | 5 | 会话超限 |
E_SESSION_MODE_IS_EXCLUSIVE | 6 | 当前KVM会话模式为独占模式 |
E_INVALID_PARAM | 7 | 非法入参 |
E_ALREADY_CONNECTED | 8 | 重复连接 |
E_NOT_CONNECTED | 9 | 未连接 |
E_TIMEOUT | 10 | 超时 |
E_VMM_DISABLED | 11 | VMM使能关闭 |
E_INVALID_FILE_PATH | 12 | 非法文件路径 |
E_VMM_BUSY | 13 | VMM被占用 |
NOTE
客户端获取到响应后,需要根据返回码自定义客户端对应操作。
WebSocket协议关闭状态码
WebSocket断开连接时,会返回一个关闭状态码,并根据SetCloseHandler
注册的对不同关闭状态码的处理函数进行自定义处理。关闭状态码对应表如下:
宏定义 | 常量值 | 说明 |
---|---|---|
NORMAL_CLOSURE | 1000 | 正常断开连接 |
GOING_AWAY | 1001 | 服务不存在或服务器断开连接 |
PROTOCOL_ERROR | 1002 | WebSocket协议错误 |
UNSUPPORTED_CLOSURE | 1003 | 客户端接收到不允许的数据类型(如接收到二进制数据而不是文本数据) |
ABNORMAL_CLOSURE | 1006 | 用于期望收到状态码时连接非正常关闭(即没有发送关闭帧) |
UNSUPPORTED_DATA | 1007 | 客户端接收到格式不符的无效数据而关闭连接(如文本数据中包含了非UTF-8字符) |
TIMEOUT | 1008 | 客户端接收到不符合约定的数据而断开连接,通用状态码 |
MESSAGE_TOO_BIG | 1009 | 传输数据量过大 |
MANDATORY_EXT | 1010 | 客户端终止连接 |
INTERNAL_ERROR | 1011 | 服务端终止连接 |
SERVICE_RESTART | 1012 | 服务端正在重新启动 |
TRY_AGAIN_LATER | 1013 | 服务端临时终止 |
BAD_GATEWAY | 1014 | 通过网关或代理请求服务端,服务端无法及时响应 |
TOO_MANY_CONNECTIONS | 4000 | WebSocket连接过多 |
FORCE_TO_KICK_SESSION | 4001 | 强制踢出会话 |
NOTE
4xxx
格式的关闭状态码为业务自定义状态码。
通过调用SetHandler
注册以上关闭状态码的处理函数,可以实现断开WebSocket连接时的自定义处理。如正常断开连接(关闭状态码1000
)时退出KVM客户端,服务端重新启动(关闭状态码1012
)时等待一段时间,WebSocket连接过多(关闭状态码4000
)时弹出提示等。
系统启动项定义
libirc库定义了6种系统启动项,系统启动项对应表如下:
宏定义 | 常量值 | 说明 |
---|---|---|
None | 0x00 | 无启动介质 |
Hdd | 0x01 | 硬盘启动 |
Cd | 0x02 | 光驱启动 |
Floppy | 0x03 | 软驱启动 |
Pxe | 0x04 | PXE启动 |
BiosSetup | 0x05 | BIOS设置启动 |
获取系统启动项成功时,枚举类型BootOption
的入参会被置为以上启动项中的一项;设置系统启动项时,则需要把预期设置的启动项作为入参传入。
电源控制项定义
libirc库定义了6种电源控制项,电源控制项对应表如下:
宏定义 | 常量值 | 说明 |
---|---|---|
On | 0x00 | 上电 |
ForceOff | 0x01 | 强制下电 |
GracefulShutdown | 0x02 | 下电 |
ForceRestart | 0x03 | 强制重启 |
ForcePowerCycle | 0x04 | 强制下电再上电 |
GracefulPowerCycle | 0x05 | 安全下电再上电 |
控制电源时,则需要把预期进行的电源控制项作为入参传入。
简单示例
libirc代码仓提供了简单demo示例,运行demo可以按照回显执行libirc库提供的所有对外接口。
调用方式以GetBootOption
为例:
void handleGetBootOption(KvmClient& kvmClient) {
BootOption option; // 初始化BootOption枚举类型
int result = kvmClient.GetBootOption(option); // 以入参传入GetBootOption,结果存储在option,返回码用result接收
// 处理未成功执行的场景
if (result != 0) {
std::cerr << "Failed to get boot option, errorCode: " << result << "\n";
return;
}
std::cout << "Current boot option: ";
// 将BootOption枚举类型取值转换为对应含义输出
switch (option) {
case BootOption::None: std::cout << "None\n"; break;
case BootOption::Hdd: std::cout << "Hdd\n"; break;
case BootOption::Cd: std::cout << "Cd\n"; break;
case BootOption::Floppy: std::cout << "Floppy\n"; break;
case BootOption::Pxe: std::cout << "Pxe\n"; break;
case BootOption::BiosSetup: std::cout << "BiosSetup\n"; break;
default: std::cout << "Unknown\n"; break;
}
}