BK-CI 流水线核心模型(Model)架构详解,涵盖 Pipeline/Stage/Container/Task 四层结构、模型序列化、版本管理、模型校验。当用户理解流水线数据结构、开发流水线功能、处理模型转换或进行模型扩展时使用。
Skill 名称: Pipeline Model Architecture
适用场景: 理解和操作 BK-CI 流水线的核心数据结构
重要性: ⭐⭐⭐⭐⭐ (最高优先级)
文档版本: 2.0
最后更新: 2024-12
Model 是整个 BK-CI 流水线系统的核心数据模型,定义了流水线在内部系统中的完整数据结构。所有流水线相关的业务逻辑(创建、编辑、执行、调度、监控)都围绕这个模型展开。
Model 采用的树状结构,完整描述了一个流水线的组织方式:
Model (流水线)
└── Stage[] (阶段集合)
└── Container[] (容器/Job集合)
└── Element[] (插件/任务集合)
数据文件位置:
// 核心模型定义
src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/Model.kt
src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Stage.kt
src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Container.kt
src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/Element.kt
@JsonTypeInfo 和 @JsonSubTypes 注解实现多态 JSON 序列化status、executeCount)标记为 readOnly = true,仅在构建运行时使用@Deprecated 字段和 transformCompatibility() 方法处理历史数据data class Model(
var name: String, // 流水线名称
var desc: String?, // 流水线描述
val stages: List<Stage>, // 阶段集合(核心)
var labels: List<String> = emptyList(), // 标签(已废弃)
// 模板相关
val instanceFromTemplate: Boolean? = null, // 是否从模板实例化
var srcTemplateId: String? = null, // 源模板ID
var templateId: String? = null, // 当前模板ID
var template: TemplateInstanceDescriptor?, // 模板实例描述符
var overrideTemplateField: TemplateInstanceField?, // 覆盖模板字段
// 元数据
var pipelineCreator: String? = null, // 创建人
var latestVersion: Int = 0, // 最新版本号
var tips: String? = null, // 提示信息
// 事件和视图
var events: Map<String, PipelineCallbackEvent>?, // 流水线回调事件
var staticViews: List<String> = emptyList(), // 静态流水线组
// 运行时数据
var timeCost: BuildRecordTimeCost? = null, // 各项耗时统计
val resources: Resources? = null // 模板资源
)
@JsonIgnore
fun getTriggerContainer() = stages[0].containers[0] as TriggerContainer
说明:
fun taskCount(skipTaskClassType: Set<String> = emptySet()): Int {
var count = 0
stages.forEach { s ->
s.containers.forEach { c ->
c.elements.forEach { e ->
if (!skipTaskClassType.contains(e.getClassType())) {
count++
}
}
}
}
return count
}
fun removeElements(elementClassTypes: Set<String>): Model {
// 遍历所有 Stage、Container、Element
// 过滤掉指定 classType 的 Element
// 返回新的 Model 实例
}
使用场景: 模板清理、插件卸载时移除特定类型的任务
companion object {
fun defaultModel(
pipelineName: String = "",
userId: String? = null
): Model {
return Model(
name = pipelineName,
desc = "",
stages = listOf(
Stage(
id = "stage-1",
containers = listOf(
TriggerContainer(
id = "0",
name = "trigger",
elements = listOf(
ManualTriggerElement(
id = "T-1-1-1",
name = I18nUtil.getCodeLanMessage(
CommonMessageCode.BK_MANUAL_TRIGGER
)
)
)
)
)
)
),
pipelineCreator = userId
)
}
}
说明: 创建一个最小化的流水线模型,只包含一个手动触发器
data class Stage(
val containers: List<Container> = listOf(), // 容器集合(核心)
var id: String?, // 系统生成的ID(不可编辑)
var name: String? = "", // 阶段名称
var stageIdForUser: String? = null, // 用户可编辑的ID
// 流程控制
var stageControlOption: StageControlOption?, // 流程控制选项
var checkIn: StagePauseCheck? = null, // Stage准入配置(人工审核)
var checkOut: StagePauseCheck? = null, // Stage准出配置(人工审核)
val finally: Boolean = false, // 是否为FinallyStage
val fastKill: Boolean? = false, // 失败快速终止
// 运行时数据
var status: String? = null, // 阶段状态
var executeCount: Int? = null, // 运行次数
var canRetry: Boolean? = null, // 是否可重试
var timeCost: BuildRecordTimeCost? = null, // 各项耗时
// 其他
val customBuildEnv: Map<String, String>?, // 自定义环境变量
var tag: List<String>? = null, // 阶段标签(显示用)
var template: TemplateDescriptor? = null // 模板信息
)
val finally: Boolean = false
特性:
canRetry = false)使用场景:
var checkIn: StagePauseCheck? = null // 阶段开始前人工审核
var checkOut: StagePauseCheck? = null // 阶段结束后人工审核
StagePauseCheck 包含:
reviewGroups: 审核人组timeout: 审核超时时间reviewParams: 审核时填写的参数status: 审核状态流程:
Stage 开始 → checkIn 审核 → 执行 Containers → checkOut 审核 → Stage 结束
fun resetBuildOption(init: Boolean? = false) {
if (init == true) {
status = null
startEpoch = null
elapsed = null
}
checkIn?.fixReviewGroups(init == true)
checkOut?.fixReviewGroups(init == true)
// 如果配置了手动触发但没有checkIn,自动创建
if (stageControlOption?.manualTrigger == true && checkIn == null) {
checkIn = StagePauseCheck.convertControlOption(stageControlOption!!)
}
if (finally) canRetry = false // FinallyStage禁止重试
}
fun getContainer(vmSeqId: String): Container? {
containers.forEach { container ->
return container.getContainerById(vmSeqId) ?: return@forEach
}
return null
}
fun stageEnabled(): Boolean {
return stageControlOption?.enable ?: true
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
@JsonSubTypes(
JsonSubTypes.Type(value = TriggerContainer::class, name = TriggerContainer.classType),
JsonSubTypes.Type(value = NormalContainer::class, name = NormalContainer.classType),
JsonSubTypes.Type(value = VMBuildContainer::class, name = VMBuildContainer.classType),
JsonSubTypes.Type(value = JobTemplateContainer::class, name = JobTemplateContainer.classType)
)
interface Container {
var id: String? // 序列ID
var name: String // 容器名称
var elements: List<Element> // 任务集合(核心)
// 运行时状态
var status: String?
var startVMStatus: String? // 构建环境启动状态
var executeCount: Int? // 运行次数
var canRetry: Boolean? // 是否可重试
// 唯一标识
var containerId: String? // 容器唯一ID(同id)
var containerHashId: String? // 容器全局唯一HashID
var jobId: String? // 用户自定义ID
// 耗时统计
var timeCost: BuildRecordTimeCost?
var startVMTaskSeq: Int? // 开机任务序号
// 标志位
var containPostTaskFlag: Boolean? // 是否包含post任务
val matrixGroupFlag: Boolean? // 是否为构建矩阵
// 抽象方法
fun getClassType(): String
fun getContainerById(vmSeqId: String): Container?
fun containerEnabled(): Boolean
fun setContainerEnable(enable: Boolean)
fun resetBuildOption(executeCount: Int)
fun transformCompatibility()
fun genTaskParams(): MutableMap<String, Any>
fun copyElements(elements: List<Element>): Container
// 矩阵相关
fun retryFreshMatrixOption()
fun fetchGroupContainers(): List<Container>?
fun fetchMatrixContext(): Map<String, String>?
}
data class TriggerContainer(
override var id: String? = null,
override var name: String = "",
override var elements: List<Element> = listOf(), // 触发器集合
var params: List<BuildFormProperty> = listOf(), // 流水线参数
var templateParams: List<BuildFormProperty>?, // 模板参数
var buildNo: BuildNo? = null, // 构建版本号规则
// ... 其他 Container 接口字段
) : Container {
companion object {
const val classType = "trigger"
}
}
特点:
stages[0].containers[0] 位置流水线参数 (BuildFormProperty):
data class BuildFormProperty(
var id: String, // 参数ID
var name: String?, // 参数名称
var required: Boolean, // 是否必填
var type: BuildFormPropertyType, // 参数类型 (STRING, BOOLEAN, ENUM, SVN_TAG等)
var defaultValue: Any, // 默认值
var value: Any? = null, // 上次构建取值
var options: List<BuildFormValue>?, // 下拉选项
var desc: String?, // 描述
// 特殊字段
var asInstanceInput: Boolean? = null // 控制实例化页面"实例入参"按钮
)
data class VMBuildContainer(
override var id: String? = null,
override var name: String = "构建环境",
override var elements: List<Element> = listOf(),
// 构建机配置
val baseOS: VMBaseOS, // 基础操作系统 (LINUX, WINDOWS, MACOS)
val vmNames: Set<String> = setOf(), // 预指定VM名称列表
val dispatchType: DispatchType? = null, // 构建机调度类型
// 环境变量
val buildEnv: Map<String, String>?, // 容器启动时环境变量
val customEnv: List<NameAndValue>?, // Agent启动时自定义环境变量
// 第三方构建机
val thirdPartyAgentId: String? = null,
val thirdPartyAgentEnvId: String? = null,
val thirdPartyWorkspace: String? = null,
// 流程控制
var jobControlOption: JobControlOption?, // Job控制选项
var mutexGroup: MutexGroup?, // 互斥组
// 构建矩阵
var matrixControlOption: MatrixControlOption?, // 矩阵配置
var groupContainers: MutableList<VMBuildContainer>?, // 分裂后的子容器
var matrixGroupId: String?, // 所属矩阵组ID
var matrixContext: Map<String, String>?, // 矩阵上下文
var showBuildResource: Boolean? = false,
var enableExternal: Boolean? = false, // 是否访问外网
var nfsSwitch: Boolean? = null // NFS挂载开关
) : Container
构建机调度类型 (DispatchType):
ThirdPartyAgentIDDispatchType: 第三方构建机ThirdPartyAgentEnvDispatchType: 第三方环境DockerDispatchType: Docker容器LocalDispatchType: 本地调度data class NormalContainer(
override var id: String? = null,
override var name: String = "",
override var elements: List<Element> = listOf(),
var jobControlOption: JobControlOption?,
var mutexGroup: MutexGroup?,
// 构建矩阵支持
var matrixControlOption: MatrixControlOption?,
var groupContainers: MutableList<NormalContainer>?,
var matrixGroupId: String?,
var matrixContext: Map<String, String>?,
// ... 其他 Container 接口字段
) : Container {
companion object {
const val classType = "normal"
}
}
特点:
data class JobControlOption(
val enable: Boolean = true, // 是否启用Job
val prepareTimeout: Int? = null, // 准备环境超时时间(分钟)
var timeout: Int? = 900, // 执行超时时间(分钟)
var timeoutVar: String? = null, // 超时时间变量(支持表达式)
// 运行条件
val runCondition: JobRunCondition = JobRunCondition.STAGE_RUNNING,
val customVariables: List<NameAndValue>?, // 自定义变量条件
val customCondition: String? = null, // 自定义条件表达式
// Job依赖
val dependOnType: DependOnType? = null, // 依赖类型
var dependOnId: List<String>? = null, // 依赖的JobID列表
val dependOnName: String? = null,
var dependOnContainerId2JobIds: Map<String, String>?, // containerId与jobId映射
val continueWhenFailed: Boolean? = false, // 失败继续
// 并发控制(第三方构建机)
val singleNodeConcurrency: Int? = null, // 单节点并发限制
val allNodeConcurrency: Int? = null // 所有节点并发限制
)
JobRunCondition 枚举:
STAGE_RUNNING: Stage运行中(默认)CUSTOM_VARIABLE_MATCH: 自定义变量匹配CUSTOM_CONDITION_MATCH: 自定义条件匹配构建矩阵允许一个 Job 根据参数组合分裂成多个并行执行的子 Job。
data class MatrixControlOption(
var strategyStr: String?, // 策略字符串
var includeCaseStr: String?, // 包含用例
var excludeCaseStr: String?, // 排除用例
var maxConcurrency: Int? = null, // 最大并发数
var totalCount: Int? = null, // 总任务数(运行时计算)
var finishCount: Int? = null // 已完成数(运行时计算)
)
矩阵字段:
matrixGroupFlag: 标识当前容器是否为矩阵父容器groupContainers: 分裂后的子容器集合(父容器特有)matrixGroupId: 所属矩阵组的 containerHashId(子容器特有)matrixContext: 当前子容器的参数组合(子容器特有)示例: