ChatOps 的一次简单实践
回顾一下自己部署服务的变化:
最初学习的时候,部署 ASP, PHP 是通过 FTP(甚至 Web)将 ASP/PHP 文件上传到服务器上。
后来知道有版本控制器之后,将代码托管到版本库,手动通过 ssh 登录服务器更新代码来部署服务,
再后来,知道利用 fabfile.py 等来自动化 ssh 到更新,到部署的过程了。
再后来,学会使用 CI,通过 travis / Jenkins 来自动部署服务。
一直到 ChatOps 实践之前,最便捷的方式是登录 Jenkins,输入 commit sha
来指定构建的版本,进行服务部署。
虽然如此,还是避免不了比较繁琐的人工操作。
Slack / BearyChat / 微信等 IM 发展,已经开始提供 hook 或类似的功能,可以很方便地将聊天跟机器人集成起来, 那么通过 IM 上的聊天来指挥机器人协助我们完成工作也不是难事,自然也可以通过这个方式进行服务部署。
在 vanke 的时候噢,也考虑过通过 BearyChat 的 outgoing
机器人完成服务部署的工作,但疲于业务开发,一直没有实践机会。最近再空闲时间进行了一次简单的 ChatOps 实践:
这次实践使用 BearyChat + GitHub + Hubot + Jenkins 完成部署。
由于 BearyChat 和 Hubot 之间已经由 BearyChat 完成,所以整个过程主要在于编写 Hubot。定义 Hubot 命令,然后请求 Jenkins 进行构建。
先在 BearyChat 上创建 hubot 机器人,获得 hubot token,并填入 hubot URL.
根据 https://hubot.github.com 搭建 Hubot 框架
$ npm install yo hubot generator-hubot hubot-bearychat
$ yo hubot
这时候已经可以启动 hubot:
启动之前需要配置环境变量:
- HUBOT_BEARYCHAT_TOKENS: BearyChat hubot 机器人提供的 tokens
HUBOT_BEARYCHAT_TOKENS=TOKEN ./bin/hubot -a bearychat
hubot 默认监听 8080 端口,可以配置 nginx 做一次反向代理。
启动之后,可以回到 BearyChat,测试 hubot 机器人是否配置成功。
hubot 默认实现了 time
命令,在 BearyChat 私聊 hubot 机器人 time
。若返回 Server time is: Wed Nov 09 2016 17:04:15 GMT+0800 (CST)
的消息,表示 hubot 配置成功,接着开始编写命令。
命令处理逻辑都放在 scripts/ 中。
Hubot 默认支持 coffee,但不支持 ES6。
如需要支持 ES6,这里可以在 scripts/
下新建 000-es6-support.coffee
'use strict'
require 'babel-register'
module.exports = (robot) => {}
同时也需要安装相应的库,babel-register
, babel-preset-es2015
, babel-plugin-add-module-exports
等。
准备好 Hubot 框架,就可以开始配置 Jenkins 编写相应脚本了。
完整安装了 Jenkins 之后会安装上 GitHub 的 plugins,新建一个 Job 并配置 GitHub 仓库,勾选 Build Triggers 下的 Trigger builds remotely (e.g., from scripts)
,并填入 Authentication Token
。
这里还利用了 https://wiki.jenkins-ci.org/display/JENKINS/Build+Token+Root+Plugin 这个插件,支持通过 POST URL 来触发 Build Job
在 scripts/
下新建 jenkins.js
'use strict';
require('babel-register');
const JENKINS_URL = process.env.JENKINS_URL;
const JENKINS_JOB_NAME = process.env.JENKINS_JOB_NAME;
const JENKINS_JOB_TOKEN = process.env.JENKINS_JOB_TOKEN;
module.exports = (robot) => {
robot.respond(/jenkins:build/i, (res) => {
const url = JENKINS_URL + "/buildByToken/build?job=" + JENKINS_JOB_NAME + "&token=" + JENKINS_JOB_TOKEN;
robot.http(url).post()((_err, _res, _body) => {
robot.logger.debug(_body);
res.reply("Building");
});
});
};
执行程序之前,需要设置 4 个环境变量:
- HUBOT_BEARYCHAT_TOKENS: BearyChat hubot 机器人提供的 tokens
- JENKINS_URL: Jenkins 的地址
- JENKINS_JOB_NAME: 想要构建的 Job 名
- JENKINS_JOB_TOKEN: Job 对应的 Token
$ source $(cat .env | xargs) && ./bin/hubot -a bearychat
回到 BearyChat 私聊 hubot: jenkins:build
,如果 jenkins 开始构建,说明 hubot 配置已经成功。
让 hubot 加入到 讨论组后,也可以在讨论组中 @hubot jenkin:build
触发构建。
上例子中的 jenkins.js 只支持一个 job ,命令也只支持 jenkins:build
。当然可以修改成支持不同 job。例如 jenkins build fooJob
, jenkins build barJob
分别构建 fooJob 和 barJob.