解决-增加系统支持范围(一)
OSCheck专题
本章节的修改位置如下:
ambari-common/src/main/python/ambari_commons/os_check.py
# 一、背景与问题定位

Ambari 在执行安装任务前,会首先通过 OSCheck 模块 识别当前操作系统类型、家族与版本号。 然而,当部署目标是 Kylin V10(麒麟高级服务器版)时,会报出如下错误:
OS type detection failed: Unsupported OS
排查发现,问题出在系统识别逻辑上:
@staticmethod
def is_redhat_family():
return OSCheck.is_in_family(OSCheck.get_os_family(), OSConst.REDHAT_FAMILY)
2
3
进一步跟踪调用链:
OSCheck.is_redhat_family()
└── is_in_family()
└── get_os_family()
└── get_os_type()
└── _get_os_type()
2
3
4
5
Ambari 通过 _get_os_type() 从 /etc/*-release 文件读取系统名,并比对预定义的系统集合。
但默认情况下,并没有包含 Kylin 系统,因此被判定为“不支持的操作系统”。
# 二、逻辑链路分析
整个调用流程如下:
oscheck.is_redhat_family ➜ is_in_family ➜ get_os_family_parent ➜ OS_FAMILY_COLLECTION ➜ json_mapping_data (os_family.json)
也就是说,Ambari 会先通过 os_check.py 的逻辑识别系统,再通过 os_family.json 查找该系统归属的家族。
这两部分共同决定系统是否被支持。

而对于 Kylin 系统 来说,若 _get_os_type() 返回为空或无法在 JSON 中找到对应关系,
Ambari 初始化阶段(包括 agent 与 server 启动)就会直接中断。
# 三、源码修改位置与原理
文件路径如下:
ambari-common/src/main/python/ambari_commons/os_check.py
# 1、核心模块 _get_os_type

在原始 Ambari 代码中,操作系统的识别逻辑如下:
if _is_oracle_linux():
operatingSystem = "oraclelinux"
elif operatingSystem.startswith("suse linux enterprise server"):
operatingSystem = "sles"
elif operatingSystem.startswith("red hat enterprise linux"):
operatingSystem = "redhat"
elif operatingSystem.startswith("rocky"):
operatingSystem = "redhat"
2
3
4
5
6
7
8
可见,它支持 RedHat、SUSE、Rocky 等,但没有针对 Kylin 的分支。
因此我们在其中增加对 kylin 的识别逻辑。
# 修改后代码
@staticmethod
def _get_os_type():
dist = OSCheck.os_distribution()
operatingSystem = dist[0].lower()
if _is_oracle_linux():
operatingSystem = "oraclelinux"
elif operatingSystem.startswith("suse linux enterprise server"):
operatingSystem = "sles"
elif operatingSystem.startswith("red hat enterprise linux"):
operatingSystem = "redhat"
elif operatingSystem.startswith("rocky"):
operatingSystem = "redhat"
elif operatingSystem.startswith("kylin"):
operatingSystem = "kylin"
elif operatingSystem.startswith("darwin"):
operatingSystem = "mac"
if operatingSystem == "":
raise Exception("Cannot detect os type. Exiting...")
return operatingSystem
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
修改说明
- 新增
elif operatingSystem.startswith("kylin")分支,以正确识别 Kylin 系统; - 保持识别结果为小写
kylin,与os_family.json匹配; - 逻辑位置放在 “rocky” 之后,保持代码结构一致。
# 2、版本识别 _get_os_version

默认 Ambari 会直接取 /etc/os-release 的 VERSION_ID 字段,但部分国产系统的版本号格式如 "V10",
这会导致后续版本比较时报错。
因此需增加逻辑:去除前缀 “V” 或 “v”。
@staticmethod
def _get_os_version():
dist = OSCheck.os_distribution()
version = dist[1]
if version:
# 去掉前缀的 V 或 v,只保留数字部分
if version.lower().startswith("v") and version[1:].isdigit():
return version[1:]
return version
else:
raise Exception("Cannot detect os version. Exiting...")
2
3
4
5
6
7
8
9
10
11
12
设计动机
大多数 Linux 发行版的版本号均为纯数字(如 8.10、7.9),
保留英文字母可能在版本比对(>、<)时产生异常。
因此统一转换为数字格式,确保与 RedHat 系列兼容。
# 四、行为验证(实机测试)
完成修改后,我们在一台 Kylin V10 Server 上进行验证。
# 测试命令:
export PYTHONPATH=/usr/lib/ambari-server/lib:$PYTHONPATH
python3 - <<'PY'
from ambari_commons.os_check import OSCheck
print("dist =", OSCheck.os_distribution())
print("os_type =", OSCheck.get_os_type())
print("os_family =", OSCheck.get_os_family())
print("is_redhat_family =", OSCheck.is_redhat_family())
print("has_yum =", __import__('shutil').which('yum') is not None)
print("redhat-release exists =", __import__('os').path.exists('/etc/redhat-release'))
PY
2
3
4
5
6
7
8
9
10
11
# 预期输出结果:

dist = ('kylin', 'V10', 'Halberd')
os_type = kylin
os_family = kylin
is_redhat_family = True
has_yum = True
redhat-release exists = False
2
3
4
5
6
结果分析
- Ambari 成功识别到 Kylin V10;
is_redhat_family=True说明其家族映射已生效;yum检测正常,后续安装任务可继续进行。
下一节预告
虽然我们已经修改了 Python 逻辑,但 Ambari 的系统继承关系 仍然定义在
ambari-common/resources/os_family.json 中。
若不在此文件中补充 kylin 的继承映射,后续脚本模板(如 yum.repo、install.sh)仍可能报错。
下一篇,我们将继续讲解: 如何在 os_family.json 中新增 kylin → redhat 的映射关系,让整个系统家族检测链完整闭环。
- 01
- Ambari开启Kerberos认证加密类型错误 Kylin V1011-05
- 02
- KERBEROS SERVICE CHECK 报错11-04