我比较陌生。 为了在集群上创建自动部署脚本,我创建了一堆彼此依赖的自定义任务。例如:
class StartSchedulerTask extends SchedulerTask {
@TaskAction
void start() {
dependsOn env.nodes.name.collect {"startTomcat_$it"}
println "Starting quartz on node: ${node}"
}
}
在build.gradle中,我已经动态创建了任务:
project.extensions.environment.nodes.each { TomcatNode n ->
String name = n.name
task "nodeInit_$name"(type: DeployToNodeInitTask) {
node(n)
}
task "stopWorker_$name"(type: StopWorkerTask) {
node(n)
}
task "stopTomcat_$name"(type: StopTomcatTask){
node(n)
}
task "updateAppConfigs_$name"(type: UpdateAppConfigsTask){
node(n)
apps(V3Application.ALL_APPS)
buildName('develop')
}
task "deployWars_$name"(type: DeployWarsTask){
node(n)
apps(V3Application.ALL_APPS)
buildName('develop')
}
task "startTomcat_$name"(type: StartTomcatTask){
node(n)
}
task "startWorker_$name"(type: StartWorkerTask){
node(n)
}
task "terminateNode_$name"(type: DeployToNodeTerminationTask){
node(n)
}
}
task stopScheduler(type: StopSchedulerTask) {
environment(environment)
}
task startScheduler(type: StartSchedulerTask) {
environment(environment)
}
默认任务配置为startScheduler,这是部署过程的最后一步,其构思是任务图一旦构建,将处理我的任务的正确执行顺序。
但是,当我打印出任务图时,列出的唯一任务是startScheduler。我错过了什么吗?
答案 0 :(得分:3)
任务依赖性必须在配置时声明,而不是在执行时声明。从理论上讲,您可以在任务的构造函数中执行此操作,但更好的方法是在构建脚本或插件中执行此操作。
答案 1 :(得分:2)
这是因为你在@TaskAction方法中声明了依赖关系。 @TaskAction仅在形成依赖图时运行。
您可以滥用@TaskActions方法中的DoFirst()
来调用所有依赖项,但这不会出现在依赖关系图上。
答案 2 :(得分:2)
感谢Peter Niederwieser和Jeffrey的评论,我能够提出我想要的完整解决方案。我没有将彼得的标记作为答案,因为完整的答案如下,但这是对正确解决方案的必要暗示:
我创建了一个接口DependencyAware:
public interface DependencyAware {
void declareDependencies()
}
每个知道如何声明其依赖关系的任务都会实现此接口。例如:
class StartSchedulerTask extends SchedulerTask {
@TaskAction
void start() {
println "Starting quartz on node: ${node}"
}
void declareDependencies() {
dependsOn env.nodes.name.collect {"startTomcat_$it"}
}
}
在我的构建脚本中:
tasks.each { Task t ->
if (t instanceof DependencyAware) {
t.declareDependencies()
}
}
就是这样!
感谢指点Peter和Jeffrey
更新1
task deploy(dependsOn: ['backupWars', 'startScheduler'])
task stopScheduler(type: StopSchedulerTask)
task backupWars(type: BackupWarsTask)
project.extensions.targetEnvironment.nodes.each { TomcatNode n ->
String name = n.name
[
("nodeInit_$name"): DeployToNodeInitTask,
("stopWorker_$name"): StopWorkerTask,
("stopTomcat_$name"): StopTomcatTask,
("updateAppConfigs_$name"): UpdateAppConfigsTask,
("deployWars_$name"): DeployWarsTask,
("startTomcat_$name"): StartTomcatTask,
("startWorker_$name"): StartWorkerTask,
("terminateNode_$name"): DeployToNodeTerminationTask,
].each { String taskName, Class taskType ->
task "$taskName"(type: taskType) {
node(n)
}
}
}
task startScheduler(type: StartSchedulerTask) {
dryRun(testMode)
}
不同部署步骤之间的内部依赖关系位于任务本身,例如:
class StartWorkerTask extends WorkerTask {
@TaskAction
void start() {
println "Starting worker ${node}"
}
void declareDependencies() {
dependsOn tomcatOnThisNodeHasBeenStarted()
}
String tomcatOnThisNodeHasBeenStarted() {
"startTomcat_${node.name}"
}
}
拓扑的声明如下:
environments {
prod {
nodes {
(1..2).each { int i ->
"w${i}_prod" {
host = "prod-n$i"
userName = "xxxxx"
password = "xxxxx"
loadBalancer = 'lb_prod'
frontendJkManagerUrl = 'http://web01/jkmanager'
}
}
scheduler {
name = "w1_prod"
}
}
}
rc {
//rc topology here
}
}