开发指南 ###开发 本指南将会按照如下流程,教你如何运用 Flynn 开发: - Flynn 源码修改 - Flynn 构建和执行 - Flynn 调试 - 新建 Flynn 发布版本 ####开发环境 开发任务通常在 [Vagrant](https://www.vagrantup.com/) 管理的 [VirtualBox](https://www.virtualbox.org/) 虚拟机内完成的,Flynn 使用 Vagrantfile 自动创建虚拟机。 #####运行开发虚拟机 如果你还没安装 VirtualBox 和 Vagrant,请按照官网安装文档,自主安装。 把 Flynn 的源码复制到本地: ``` $ git clone https://github.com/flynn/flynn.git ``` 接着在 ```flynn``` 目录下,启动虚拟机: ``` $ vagrant up ``` 若你是第一次创建虚拟机,Vagrant 会下载 VirtualBox 下的文件,大约 1G 大小,会占用你部分时间,时间长短,由网络带宽决定。 一旦 vagrant up 命令执行成功,你就可通过 SSH 方式连接虚拟机: ``` $ vagrant ssh ``` 从现在开始,若无特别说明,接下来所有命令都会在虚拟机中运行。 ####修改代码 开发虚拟环境通过挂载物理机```/vagrant```目录实现 Flynn 源码共享。这意味着你可以在本地物理机修改文件,并且这些变化在虚拟机内也能看见。 因为 Flynn 主要由 Go 写成,源代码需要一个可用的 Go 工作空间。开发虚拟机有一个```$HOME/go```的```GOPATH```,Flynn 的源代码是从 ```/vagrant``` 到 ```$GOPATH/src/github.com/flynn/flynn``` 的一个软链。 如果你没有特殊的问题需要修复,但又对贡献这个社区很感兴趣,你可以先看一下 GitHub 被标记为 [easy](https://github.com/flynn/flynn/labels/easy) 的问题。 ####Flynn 搭建 我们在 [tup](http://gittup.org/tup/) 构建系统里执行命令即可完成 Flynn 多组件安装。 搭建 Flynn 只需运行```make```: ``` $ make ``` 该命令会构建 GO 二进制文件,创建个Docker镜像等工作。若你对某个环节感兴趣,可查看子目录下的```Tupfiles```。 若构建失败,```tup``` 将会输出错误并退出。修复后,重新运行```make```即可。 如果你想重新编译 Go 二进制文件,运行```make clean```。 一旦 tup 成功运行,你会有许许多多的 Go 二进制文件和 Docker 镜像,这些对运行 Flynn 都是有用的。 ####Flynn 运行 一旦 Flynn 系统依赖组件搭建完成,执行如下脚本即可创建Flynn 集群节点: ``` $ script/bootstrap-flynn ``` 这个命令将会做如下几件事: - 停止```flynn-host```守护进程,以及所有正在运行的 Flynn 服务 - 开启```flynn-host```守护进程 - 运行 Flynn 加载程序,该程序会开启所有 Flynn 服务 本脚本还提供了其他选项,供用户使用他方式开启 Flynn 后台服务,比如使用其他外部IP的```eth0```设备。请通过```script/bootstrap-flynn -h```查看所有功能选项。 一旦 Flynn 提供服务,使用bootstrap 输出添加集群```flynn``` CLI工具,请尝试修改(比如遵循[指南](https://github.com/flynn/flynn#trying-it-out))。 ####调试 如果没有按预期运行,使用如下命令工具进行调试: #####查看 flynn-host 守护进程日志 ``` $ less /tmp/flynn-host.log ``` #####查看运行任务列表 ``` $ flynn-host ps ID STATE STARTED CONTROLLER APP CONTROLLER TYPE flynn-66f3ca0c60374a1abb172e3a73b50e21 running About a minute ago example web flynn-9d716860f69f4f63bfb4074bcc7f4419 running 4 minutes ago gitreceive app flynn-7eff6d37af3c4d909565ca0ab3b077ad running 4 minutes ago router app flynn-b8f3ecd48bb343dab96744a17c96b95d running 4 minutes ago blobstore web ... ``` #####查看所有的任务(运行中+停止) ``` $ flynn-host ps -a ID STATE STARTED CONTROLLER APP CONTROLLER TYPE flynn-7fd8c48542e442349c0217e7cb52dec9 running 15 seconds ago example web flynn-66f3ca0c60374a1abb172e3a73b50e21 running About a minute ago example web flynn-9868a539703145a1886bc2557f6f6441 done 2 minutes ago example web flynn-100f36e9d18849658e11188a8b85e79f done 3 minutes ago example web flynn-f737b5ece2694f81b3d5efdc2cb8dc56 done 4 minutes ago flynn-9d716860f69f4f63bfb4074bcc7f4419 running 5 minutes ago gitreceive app flynn-7eff6d37af3c4d909565ca0ab3b077ad running 5 minutes ago router app flynn-b8f3ecd48bb343dab96744a17c96b95d running 5 minutes ago blobstore web ... ``` #####查看任务输出 ``` $ flynn-host log $JOBID Listening on 55006 ``` #####检查任务详情 ``` $ flynn-host inspect $JOBID ID flynn-075c21e8b79a41d89713352f04f94a71 Status running StartedAt 2014-10-14 14:34:11.726864147 +0000 UTC EndedAt 0001-01-01 00:00:00 +0000 UTC ExitStatus 0 IP Address 192.168.200.24 flynn-controller.release 954b7ee40ef24a1798807499d5eb8297 flynn-controller.type web flynn-controller.app e568286366d443c49dc18e7a99f40fc1 flynn-controller.app_name ``` #####停止任务 ``` $ flynn-host stop $JOBID ``` #####停止所有任务 ``` $ flynn-host ps -a | xargs flynn-host stop ``` #####停止某个APP所有任务 假设APP名字叫 example: ``` $ flynn-host ps | awk -F " {2,}" '$4=="example" {print $1}' | xargs flynn-host stop ``` ####向 GitHub 的 gist 上传日志和系统信息 如果你想帮助诊断你系统上的问题,运行下面命令来上传一些有用的信息到一个匿名的 GitHub gist ```: $ flynn-host collect-debug-info INFO[03-11|19:25:29] uploading logs and debug information to a private, anonymous gist INFO[03-11|19:25:29] this may take a while depending on the size of your logs INFO[03-11|19:25:29] getting flynn-host logs INFO[03-11|19:25:29] getting job logs INFO[03-11|19:25:29] getting system information INFO[03-11|19:25:30] creating anonymous gist 789.50 KB / 789.50 KB [=======================================================] 100.00 % 93.39 KB/s 8s INFO[03-11|19:25:38] debug information uploaded to: https://gist.github.com/47379bd4604442cac820 ``` 接着你可以在```#flynn``` IRC 聊天室内附上 gist 信息 ,便于得到聊天室内其他人帮助。 如果你不想用 GitHub gist 服务,或者你的 log 文件太大不能放在一个单独的 gist 中,你可以通过 ```--tarball``` 选项创建信息的 tar 包: ``` $ flynn-host collect-debug-info --tarball INFO[03-11|19:28:58] creating a tarball containing logs and debug information INFO[03-11|19:28:58] this may take a while depending on the size of your logs INFO[03-11|19:28:58] getting flynn-host logs INFO[03-11|19:28:58] getting job logs INFO[03-11|19:28:58] getting system information INFO[03-11|19:28:59] created tarball containing debug information at /tmp/flynn-host-debug407848418/flynn-host-debug.tar.gz ``` 同 IRC 内交谈的时候,可以附上这些信息。 ####运行测试 Flynn 有两种测试方式 - "单元"测试,运行```go test``` - "集成"测试,运行在启动了的 Flynn 集群上 #####运行单元测试 运行所有单元测试 ``` $ go test ./... ``` 给一个单独的组建运行单元测试(例如:router) ``` $ go test ./router ``` 给一个组建以及它的子组建运行单元测试(例如:controller) ``` $ go test ./controller/... ``` #####运行集成测试 集成测试在```tests```目录中,在测试可以运行前,需要一个正在运行的 Flynn 集群 运行所有的集成测试 ``` $ script/run-integration-tests ``` 它会做下列的事情: - 运行```make```建立 Flynn - 通过```script/bootstrap-flynn```来启动 Flynn 集群节点 - 运行集成测试(```bin/flynn-test```) 运行一个单独的集成测试(例如:```TestEnvDir```) ``` $ script/run-integration-tests -f TestEnvDir ``` ####Pull request 一旦你修改了 Flynn 的源代码,并且测试了你的新特性,你可以在 GitHub 上开一个 pull request,这样我们就可以审查你的新特性,并将它们合并到 Flynn 中。 请看 [贡献指南](https://flynn.io/docs/contributing) ####Flynn 发布 一旦 Flynn 在你的开发虚拟机内搭建并测试通过,你就能创建一个发行版本并且在其他主机上安装这些组件。 一个 Flynn 发行版本是一系列组件的集合,包括二进制文件、配置文件、文件系统镜像,这些必须按顺序安装,才能保证 Flynn 正常运行。 ####更新框架 (TUF) Flynn 使用[更新框架](http://theupdateframework.com/)(即TUF) 安全分发所有 Flynn 组件。 Flynn 新版本发布,使用 [go-tuf](https://github.com/flynn/go-tuf) 库自动生成一个 TUP 仓库 参考[安装指引](https://github.com/flynn/go-tuf#install)内的[“Create signed root manifest“](https://github.com/flynn/go-tuf#examples)例子。保证代码目录结构如下所示: ``` . ├── keys │ ├── snapshot.json │ ├── targets.json │ └── timestamp.json ├── repository └── staged ├── root.json └── targets ``` TUF 根密钥需要编译进 Flynn 的发布版本中,镜像 URL 必须和 TUF 仓库将上传的文件服务器相关。可以通过在```tup.config```中设置参数```CONFIG_TUF_ROOT_KEYS```和```CONFIG_IMAGE_REPOSITORY```并再次运行```make```来完成。例如: ``` CONFIG_IMAGE_REPOSITORY=https://s3.amazonaws.com/my-flynn-repo/tuf CONFIG_TUF_ROOT_KEYS=[{"keytype":"ed25519","keyval":{"public":"31351ecc833417968faabf98e004d1ef48ecfd996f971aeed399a7dc735d2c8c"}}] ``` ####导出组件 将 Flynn 组件导出到 TUF 仓库(这需要提示输入 TUF 密钥的 passphrase) ``` $ script/export-components /path/to/tuf-repo ``` ####上传组件 上传 TUF 仓库的```repository```目录到```CONFIG_IMAGE_REPOSITORY```指示的文件服务器。 例如,如果使用 S3,并且```CONFIG_IMAGE_REPOSITORY```设置为```https://s3.amazonaws.com/my-flynn-repo/tuf```,使用```s3cmd```来同步文件: ``` $ s3cmd sync --acl-public /path/to/tuf-repo/repository s3://my-flynn-repo/tuf ``` 现在你可以分发```script/install-flynn```,并且用一个明确的仓库 URL 来安装用户建立的 Flynn 组件: ``` install-flynn -r https://s3.amazonaws.com/my-flynn-repo ```