开发cloudify配方文件-自定义命令

摘要:为什么要使用自定义命令 在很多场景下,你想更好的控制你的应用服务而不仅仅局限在内置的生命周期事件中。例如,你想实现各种服务等级的问题,比如热升级(替换.war文件后刷新web容器)、数据库模式升级等等。 Cloudify使用groovy闭包、外置groovy脚本、外置shell/batch脚本来提供自定义命令机制。这些命令可以在cloudify shell下运行。 描述一个

为什么要使用自定义命令

在很多场景下,你想更好的控制你的应用服务而不仅仅局限在内置的生命周期事件中。例如,你想实现各种服务等级的问题,比如热升级(替换.war文件后刷新web容器)、数据库模式升级等等。

Cloudify使用groovy闭包、外置groovy脚本、外置shell/batch脚本来提供自定义命令机制。这些命令可以在cloudify shell下运行。

timg (51).jpg

描述一个自定义命令

自定义命令的描述在服务描述文件customCommands部分。每个customCommands 块使用数组来包含一个或多个命令。

下面是customCommands引用Groovy、shell、batch脚本的例子:

custom1.groovy

/* Run myFile.groovy whenever YOUR_COMMAND_NAME is invoked. */

customCommands ([

"YOUR_COMMAND_NAME" : "myFile.groovy"

])

 

/* Run myOtherFile.sh whenever YOUR_2ND_COMMAND_NAME is invoked. */

customCommands ([

"YOUR_2ND_COMMAND_NAME" : "myOtherFile.sh"

])

 

/* Run myBatchFile.bat whenever YOUR_3RD_COMMAND_NAME is invoked. */

customCommands ([

"YOUR_3RD_COMMAND_NAME" : "myBatchFile.bat"

])

下面是在customCommands块下使用Groovy闭包程序的例子:

customCommands2.groovy

customCommands ([

// A command with two parameters (firstName and lastName)

"YOUR_COMMAND_NAME" : {firstName, lastName ->

def lineSeparator = System.getProperty("line.separator");

def userFile = new File(context.serviceDirectory + lineSeparator + firstName+"_"+lastName+".txt";

System.out.println("User :"+firstName+ " " +lastName + " text is "+userFile.text)

 

return true

}

])

当需要在groovy闭包程序或脚本内使用用户定义的java库,可以使用import声明,并将jar文件放在这个服务的usmlib(比如:<cloudifyRoot>recipesservicesmongodbmongoConfigusmlib)文件夹中

任何外置脚本必须复制到服务文件夹中

customCommands部分必须写在相关服务描述文件的综述部分(<service name>-service.groovy),例:

tomcat.groovy

service {

name "tomcat"

icon "tomcat.gif"

type "WEB_SERVER"

numInstances 1

 

compute {

template "SMALL_LINUX_32"

}

 

lifecycle {

install "tomcat_install.groovy"

start "tomcat_start.groovy"

}

 

customCommands ([

"updateWar" : "update_war.groovy"

])

 

}

调用自定义命令

在部署应用时,你的自定义命令才被注册。一旦你的应用运行,在cloudify shell下可以随时使用自定义命令

在cloudify shell下调用自定义命令需要使用参数,如:invokeServiceName customCommandName

自定义命令有两个参数,则:invokeServiceName customCommandName x y

 

场景:

使用cloudify部署你的应用到云中,应用包含一个tomcat服务 安装完应用,你修复了一个web应用的bug
你想更新.war文件而不想挂掉tomcat服务器或虚拟主机,即重部署整个应用程序

为了实现更新需要做以下工作

在部署应用程序前,在tomcat服务描述文件的customCommands块下描述下列updateWar自定义命令

update_warcc.groovy

customCommands ([

"updateWar" : "update_war.groovy"

])

复制下列update_war.groovy脚本到tomcat服务文件夹

import groovy.util.ConfigSlurper

 

def config=new ConfigSlurper().parse(new File("tomcat.properties").toURL())

 

def ant = new AntBuilder();

 

ant.get(src:config.applicationWarUrl, dest:config.applicationWar, skipexisting:false)

ant.copy(todir: "${catalinaHome}/webapps", file:config.applicationWar, overwrite:true)

在Cloudify shell下调用updateWar命令: connectREST-ADMIN-SERVER-URL(连接cloudify管理的机器) use-applicationYOUR-APP-NAME(设置当前应用的上下文) invoketomcat updateWar