如果列举开发人员在工作中最讨厌的部分,估计搭建开发环境得票率肯定可以排进前三。年初 Github 开源了自己内部的 Privision 框架Boxen,趁着新笔记本需要起轿,尝试了一把。
Boxen框架简介
Boxen 基于大红大紫的Puppet,但和后者目前主要侧重于服务器的 Privision 不同,Boxen 更主要是用于组织内工作人员使用的机器的配置和管理流程标准化。
配置流程标准化比较好理解:拿到一台机器,敲一个命令就把所有需要的软件装上并且把环境配置好。按 Boxen 主页上的说法,Github 新员工入职后领到电脑后,用 Boxen 配置环境到开始写代码只需要 30 分钟。
管理流程标准化听起来比较抽象,你可以想象这么一个场景:如果公司里面所有的机器都是是用 Boxen 来配置的。当发现 Chrome 浏览器的 Java 插件会导致安全问题的时候,IT 部门可以 push 一个禁用 Chrome 里 Java 插件的 change 到 boxen repo。所有的员工只需要和 repo 做一次 sync,自己的 Chrome 里的 Java 插件就被禁用了。这显然比传统的发邮件要求大家去禁用 Chrome 浏览器 Java 插件简单有效。
简单地概括 Boxen 的思路,就是像对待产品一样对待开发环境。使用包括版本控制,持续集成这些手段,在团队中维护一个开发环境的仓库。如果你想更深入地了解 Boxen 的设计哲学,可以看看这个 slide:BOXEN by Will Farrington。
使用Boxen
首先确保你的初始环境是干净的:
- 如果你手上是台新机器,它是干净的
-
如果不是一台新机器,请先备份,然后:
接下来就是安装一些必须的软件,比如 Git 和 Xcode 的 Command Line Tools
。
###Xcode CLT###
- 升级 Xcode
- 启动 Xcode,在 Preferences 里面选择下载
- 安装”Command Line Tools”
###打开 FireVault2###
Boxen 默认会希望硬盘信息是被加密的:
###Fork our-boxen###
our-boxen是 Boxen 提供的基线 repo,也是整个 Boxen 框架里面文档最全的一个 repo。
首先按照 repo 说明中的方式来 clone 和配置本地 repo:
sudo mkdir -p /opt/boxen
sudo chown ${USER}:admin /opt/boxen
git clone https://github.com/boxen/our-boxen /opt/boxen/repo
cd /opt/boxen/repo
git remote rm origin
git remote add origin
git push -u origin master
这种 clone 下来再配置 origin 的方式类似于 fork,区别是 fork 下来的 repo 一定是 public 的,而这样得到的 repo 可以是 private 的。可以想象如果你使用 boxen 来完成对公司电脑的配置,多少都会有一些敏感信息在 repo 里面,所以 private 的 repo 是非常必要的。
接下来在 /opt/boxen/repo
路径下运行 script/boxen
即可完成 boxen 默认的模块的安装。默认的模块定义在 /opt/boxen/repo/Puppetfile
中:
github "dnsmasq", "1.0.0"
github "gcc", "1.0.0"
github "git", "1.0.0"
github "homebrew", "1.0.0"
github "hub", "1.0.0"
github "inifile", "0.9.0", :repo => "cprice-puppet/puppetlabs-inifile"
github "nginx", "1.0.0"
github "nodejs", "1.0.0"
github "nvm", "1.0.0"
github "ruby", "1.0.0"
github "stdlib", "3.0.0", :repo => "puppetlabs/puppetlabs-stdlib"
github "sudo", "1.0.0"
可以看到 Github 大量用到 ruby
和 nodejs
。在运行 boxen 的时候,可能会看到大量的警告信息:
Warning: Could not retrieve fact fqdn
Warning: Host is missing hostname and/or domain: suttlemac
然后伴随着 https://rubygems.org
失败。这些主要是因为 GFW,你可以使用镜像,比如淘宝的。具体方式可以查看这里。
注意你还应该把下面的脚本加到 ~/.bashrc
或者 ~/.zshrc
:
[ -f /opt/boxen/env.sh ] && source /opt/boxen/env.sh
然后新开一个 shell 运行 boxen --env
,结果一切正常你的 box 就配置完毕了。
自定义你的box
默认安装的内容当然不一定对你的口味,如果你用过 Puppet 那么自定义 Boxen 的 box 是非常简单的。不过埋头开干之前还是可以 check 一下是不是已经有人做好了。这些做好的 repo 可以直接通过修改配置文件是用,因为 Boxen 对 librarian-puppet 做了 wrapper,对 fetch 各种 module 也做了 wrapper。
比如我们要安装 Chrome 和 Skype,打开 /opt/boxen/repo/Puppetfile
并添加两行:
...
github "sudo", "1.0.0"
# Add new modules
github "skype", "1.0.2"
github "chrome", "1.1.0"
这里安装的 module 的声明规则是 github "{name}", "{version}"
。 其中 name
的取法是在 Puppetfile
里面定义的:
def github(name, version, options = nil)
options ||= {}
options[:repo] ||= "boxen/puppet-#{name}"
mod name, version, :github_tarball => options[:repo]
end
因此puppet-skype对应的就是 skype
。
而 version
则是对应具体 repo 的 tag,比如puppet-skype对应的tag有:
如果你的 repo 不是在 github 也很简单,只需要指定 repo 的位置即可。比如如果你自己的 Skype 是放在 Bitbucket 上的:
mod "skype", :git => "git@bitbucket.org:yourusername/puppet-skype.git"
在 Puppetfile
里面完成的声明主要是让 Boxen(实际上是 Puppet)知道去哪里找安装和配置文件。要告诉 Boxen 安装 Skype 还需要在 manifests/site.pp
里面 include
需要安装的 module:
...
node default {
include dnsmasq
include ruby
include git
include hub
include homebrew
include skype
}
...
接下来只需要运行 boxen
(如果你运行了 boxen --env
命令会在可执行路径里)或者是 boxen --debug
(如果你需要更多的 verbose 信息),指定的软件就安装上了。
What’s Next
目前为止主要是解释了如何使用 Boxen 来安装一些基本软件。目前本座机器上使用 Boxen 安装的软件包括:
github "ccleaner", "1.0.1"
github "iterm2", "1.0.2"
github "skype", "1.0.2"
github "chrome", "1.1.0"
github "sublime_text_2", "1.1.0"
github "jumpcut", "1.0.0"
接下来的计划就是建立项目组自己的 repo,把诸如输入法、dotfiles、Java 开发环境和 Django 开发环境这些东西的安装和配置都自动化了。