2012-12-29 77 views
0

我對gradle比較陌生。 爲了在集羣上創建自動部署腳本,我創建了一組相互依賴的自定義任務。例如:如何在自定義任務中定義默認dependsOn

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。我錯過了什麼嗎?

回答

1

感謝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() 
    } 
} 

這就是它!

感謝您的指針彼得和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 
    } 
} 
+0

我不明白爲什麼要將這些知識編碼到任務類型中。連接任務應該由創建任務的相同實體完成 - 無論是構建腳本還是插件。 –

+0

好的彼得,所以也許你可以建議如何可以在插件內完成?爲什麼這些知識不在buid腳本中,是因爲我需要一個腳本,可以在其中聲明性地編碼羣集的拓撲結構。我不想因爲在部署戰爭之前感到困擾,所以我需要關閉我的Tomcat工作人員。這低於我的構建腳本的抽象級別。 – loteq

+0

我用配置示例和任務聲明更新了答案 – loteq

2

這是因爲您在@TaskAction方法中聲明瞭依賴關係。 @TaskAction只在依賴圖形成後運行。

您可能會在您的@TaskActions方法中濫用DoFirst()來調用您的所有依賴關係,但這不會在依賴關係圖上顯示。

3

任務依賴性必須聲明在配置時間,而不是在執行時間。理論上你可以在任務的構造函數中這樣做,但更好的方法是在構建腳本或插件中執行此操作。

+0

我有一個插件。我用它來創建我的擴展對象。我可以這樣做嗎?動態創建的任務是否已經存在? – loteq

+0

我想保留腳本的依賴關係聲明,因爲依賴項來自我的情況下的任務類型,所以它們靜態地知道。通過使用命名約定,您還可以聲明任務實例的依賴關係。 – loteq