Skip to content

Commit

Permalink
Merge pull request #4632 from fitzcao/issues_4132
Browse files Browse the repository at this point in the history
feat: 对于流水线TASK执行前支持自动暂停,希望能开放应用态接口,使插件继续执行或者中止 #4132
  • Loading branch information
irwinsun authored Jul 12, 2021
2 parents e052a9f + ceb4e33 commit 30bbea0
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_APP_CODE
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_APP_CODE_DEFAULT_VALUE
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_USER_ID
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_USER_ID_DEFAULT_VALUE
import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID
import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE
import com.tencent.devops.common.api.pojo.BuildHistoryPage
import com.tencent.devops.common.api.pojo.Result
import com.tencent.devops.common.pipeline.pojo.StageReviewRequest
import com.tencent.devops.process.pojo.BuildHistory
import com.tencent.devops.process.pojo.BuildHistoryWithVars
import com.tencent.devops.process.pojo.BuildId
import com.tencent.devops.process.pojo.BuildManualStartupInfo
import com.tencent.devops.process.pojo.BuildTaskPauseInfo
import com.tencent.devops.process.pojo.pipeline.ModelDetail
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
Expand Down Expand Up @@ -294,4 +297,23 @@ interface ApigwBuildResourceV3 {
@ApiParam("变量名列表", required = true)
variableNames: List<String>
): Result<Map<String, String>>

@ApiOperation("操作暂停插件")
@POST
@Path("/{buildId}/execute/pause")
fun executionPauseAtom(
@ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE)
@HeaderParam(AUTH_HEADER_USER_ID)
userId: String,
@ApiParam("项目ID", required = true)
@PathParam("projectId")
projectId: String,
@ApiParam("流水线ID", required = true)
@PathParam("pipelineId")
pipelineId: String,
@ApiParam("构建ID", required = true)
@PathParam("buildId")
buildId: String,
taskPauseExecute: BuildTaskPauseInfo
): Result<Boolean>
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.tencent.devops.process.pojo.BuildHistory
import com.tencent.devops.process.pojo.BuildHistoryWithVars
import com.tencent.devops.process.pojo.BuildId
import com.tencent.devops.process.pojo.BuildManualStartupInfo
import com.tencent.devops.process.pojo.BuildTaskPauseInfo
import com.tencent.devops.process.pojo.pipeline.ModelDetail
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
Expand Down Expand Up @@ -222,6 +223,23 @@ class ApigwBuildResourceV3Impl @Autowired constructor(
)
}

override fun executionPauseAtom(
userId: String,
projectId: String,
pipelineId: String,
buildId: String,
taskPauseExecute: BuildTaskPauseInfo
): Result<Boolean> {
logger.info("$pipelineId| $buildId| $userId |executionPauseAtom $taskPauseExecute")
return client.get(ServiceBuildResource::class).executionPauseAtom(
userId = userId,
projectId = projectId,
pipelineId = pipelineId,
buildId = buildId,
taskPauseExecute = taskPauseExecute
)
}

companion object {
private val logger = LoggerFactory.getLogger(ApigwBuildResourceV3Impl::class.java)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.tencent.devops.process.pojo.BuildHistoryVariables
import com.tencent.devops.process.pojo.BuildHistoryWithVars
import com.tencent.devops.process.pojo.BuildId
import com.tencent.devops.process.pojo.BuildManualStartupInfo
import com.tencent.devops.process.pojo.BuildTaskPauseInfo
import com.tencent.devops.process.pojo.ReviewParam
import com.tencent.devops.process.pojo.VmInfo
import com.tencent.devops.process.pojo.pipeline.ModelDetail
Expand Down Expand Up @@ -550,4 +551,23 @@ interface ServiceBuildResource {
@ApiParam("审核请求体", required = false)
reviewRequest: StageReviewRequest? = null
): Result<Boolean>

@ApiOperation("操作暂停插件")
@POST
@Path("/projects/{projectId}/pipelines/{pipelineId}/builds/{buildId}/execution/pause")
fun executionPauseAtom(
@ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE)
@HeaderParam(AUTH_HEADER_USER_ID)
userId: String,
@ApiParam("项目ID", required = true)
@PathParam("projectId")
projectId: String,
@ApiParam("流水线ID", required = true)
@PathParam("pipelineId")
pipelineId: String,
@ApiParam("构建ID", required = true)
@PathParam("buildId")
buildId: String,
taskPauseExecute: BuildTaskPauseInfo
): Result<Boolean>
}
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,8 @@ interface UserBuildResource {
@ApiParam("任务ID", required = true)
@PathParam("taskId")
taskId: String,
@ApiParam("待执行插件元素", required = true)
element: Element,
@ApiParam("待执行插件元素", required = false)
element: Element?,
@ApiParam("执行类型, true 继续, false 停止", required = true)
@QueryParam("isContinue")
isContinue: Boolean,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
*
* * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
* *
* * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* *
* * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
* *
* * A copy of the MIT License is included in this file.
* *
* *
* * Terms of the MIT License:
* * ---------------------------------------------------
* * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* * permit persons to whom the Software is furnished to do so, subject to the following conditions:
* *
* * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
* * the Software.
* *
* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

package com.tencent.devops.process.pojo

import com.tencent.devops.common.pipeline.pojo.element.Element
import io.swagger.annotations.ApiModel
import io.swagger.annotations.ApiModelProperty

@ApiModel("流水线暂停操作实体类")
data class BuildTaskPauseInfo(
@ApiModelProperty("任务ID")
val taskId: String,
@ApiModelProperty("element信息,若插件内有变量变更需给出变更后的element")
val element: Element?,
@ApiModelProperty("是否继续 true:继续构建 false:停止构建")
val isContinue: Boolean,
@ApiModelProperty("当前stageId")
val stageId: String,
@ApiModelProperty("当前containerId")
val containerId: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,21 @@ import com.tencent.devops.process.pojo.BuildHistoryVariables
import com.tencent.devops.process.pojo.BuildHistoryWithVars
import com.tencent.devops.process.pojo.BuildId
import com.tencent.devops.process.pojo.BuildManualStartupInfo
import com.tencent.devops.process.pojo.BuildTaskPauseInfo
import com.tencent.devops.process.pojo.ReviewParam
import com.tencent.devops.process.pojo.VmInfo
import com.tencent.devops.process.pojo.pipeline.ModelDetail
import com.tencent.devops.process.pojo.pipeline.PipelineLatestBuild
import com.tencent.devops.process.service.builds.PipelinePauseBuildFacadeService
import org.springframework.beans.factory.annotation.Autowired

@Suppress("ALL")
@RestResource
class ServiceBuildResourceImpl @Autowired constructor(
private val pipelineBuildFacadeService: PipelineBuildFacadeService,
private val engineVMBuildService: EngineVMBuildService,
private val vmBuildService: PipelineVMBuildService
private val vmBuildService: PipelineVMBuildService,
private val pipelinePauseBuildFacadeService: PipelinePauseBuildFacadeService
) : ServiceBuildResource {

override fun setVMStatus(
Expand Down Expand Up @@ -510,6 +513,30 @@ class ServiceBuildResourceImpl @Autowired constructor(
return Result(true)
}

override fun executionPauseAtom(
userId: String,
projectId: String,
pipelineId: String,
buildId: String,
taskPauseExecute: BuildTaskPauseInfo
): Result<Boolean> {
checkParam(projectId, pipelineId)
checkUserId(userId)
return Result(
pipelinePauseBuildFacadeService.executePauseAtom(
userId = userId,
projectId = projectId,
pipelineId = pipelineId,
buildId = buildId,
isContinue = taskPauseExecute.isContinue,
taskId = taskPauseExecute.taskId,
element = taskPauseExecute.element,
stageId = taskPauseExecute.stageId,
containerId = taskPauseExecute.containerId
)
)
}

private fun checkParam(projectId: String, pipelineId: String) {
if (pipelineId.isBlank()) {
throw ParamBlankException("Invalid pipelineId")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ class UserBuildResourceImpl @Autowired constructor(
pipelineId: String,
buildId: String,
taskId: String,
element: Element,
element: Element?,
isContinue: Boolean,
stageId: String,
containerId: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class PipelinePauseBuildFacadeService(
stageId: String,
containerId: String,
isContinue: Boolean,
element: Element,
element: Element?,
checkPermission: Boolean? = true
): Boolean {
logger.info("executePauseAtom| $userId| $pipelineId|$buildId| $stageId| $containerId| $taskId| $isContinue")
Expand All @@ -89,17 +89,6 @@ class PipelinePauseBuildFacadeService(
)
}

val newElementStr = ParameterUtils.element2Str(element, objectMapper)
if (newElementStr.isNullOrEmpty()) {
logger.warn("executePauseAtom element is too long")
throw ErrorCodeException(
statusCode = Response.Status.INTERNAL_SERVER_ERROR.statusCode,
errorCode = ProcessMessageCode.ERROR_ELEMENT_TOO_LONG,
defaultMessage = "${buildId}element大小越界",
params = arrayOf(buildId)
)
}

val buildInfo = pipelineRuntimeService.getBuildInfo(buildId)
?: throw ErrorCodeException(
statusCode = Response.Status.NOT_FOUND.statusCode,
Expand Down Expand Up @@ -128,21 +117,14 @@ class PipelinePauseBuildFacadeService(
actionType = ActionType.END // END才会对应成取消状态
}

val isDiff = findDiffValue(
buildId = buildId,
taskId = taskId,
userId = userId,
newElement = element,
oldTask = taskRecord
)

if (isDiff) {
pipelineTaskPauseService.savePauseValue(PipelinePauseValue(
if (element != null) {
findAndSaveDiff(
element = element,
buildId = buildId,
taskId = taskId,
newValue = newElementStr!!,
defaultValue = objectMapper.writeValueAsString(taskRecord.taskParams)
))
userId = userId,
taskRecord = taskRecord
)
}

pipelineEventDispatcher.dispatch(
Expand All @@ -161,14 +143,17 @@ class PipelinePauseBuildFacadeService(
return true
}

fun findDiffValue(
newElement: Element,
private fun findDiffValue(
newElement: Element?,
buildId: String,
taskId: String,
userId: String,
oldTask: PipelineBuildTask
): Boolean {
var isDiff = false
if (newElement == null) {
return isDiff
}
val newInputData = ParameterUtils.getElementInput(newElement)

val oldInputData = ParameterUtils.getParamInputs(oldTask.taskParams) ?: return isDiff
Expand Down Expand Up @@ -203,4 +188,39 @@ class PipelinePauseBuildFacadeService(
}
return isDiff
}

private fun findAndSaveDiff(
element: Element,
buildId: String,
taskId: String,
userId: String,
taskRecord: PipelineBuildTask
) {
val newElementStr = ParameterUtils.element2Str(element, objectMapper)
if (newElementStr.isNullOrEmpty()) {
logger.warn("executePauseAtom element is too long")
throw ErrorCodeException(
statusCode = Response.Status.INTERNAL_SERVER_ERROR.statusCode,
errorCode = ProcessMessageCode.ERROR_ELEMENT_TOO_LONG,
defaultMessage = "${buildId}element大小越界",
params = arrayOf(buildId)
)
}
val isDiff = findDiffValue(
buildId = buildId,
taskId = taskId,
userId = userId,
newElement = element,
oldTask = taskRecord
)

if (isDiff) {
pipelineTaskPauseService.savePauseValue(PipelinePauseValue(
buildId = buildId,
taskId = taskId,
newValue = newElementStr!!,
defaultValue = objectMapper.writeValueAsString(taskRecord.taskParams)
))
}
}
}

0 comments on commit 30bbea0

Please sign in to comment.