Using vagrant and git set your dev environment up

To setup development environment is not easy.  Especially for server side, lots of dependency, same library in different version often act different. If you are just join into a new team and you have to use lots of libraries, frameworks, means you have to use lots of time to deal with them in detail stuffs. Using google, mail list, forum, ask others (and maybe them don’t know), cost you lots of time and make yourself upset, unhappy, angry.

I use vagrant to deal with this case.

What’s vagrant? OK, FINE, http://www.iwgtfy.com/?q=vagrant

Technically, vagrant is a virtual machine management tool, means vagrant can help you to build a environment from scratch, package and ship.

I will brief explain how I am using vagrant from scratch, cause it’s document is so nice.

  1. Install a clean OS. Download a new vagrant clean box file from http://www.vagrantbox.es, using vagrant init to install. I choose Ubuntu Server 12.04 (LTS)
  2. Log into vagrant to install basic libraries, for me install MySQL, Apache2, Django, django-plugins and so on
  3. Prepare your code base
  4. Logout vagrant, using vagrant package command to build your own library installed box file
  5. Ship this file to new guys, let him use vagrant init and setup the new box in 10 minutes
  6. Done, he’s already have the whole tool chain to hacking

In here, on step 3, I am not put code into vagrant managed virtual machine. I am using vagrant sync directory to make code base both available in virtual machine and local computer. The reason is VirtualBox’s IO performance is not good, hacking code (via git or some other tools) on local machine is easy and quick. Beside, I can make my vagrant box file holding on a public place (such as s3 or dropbox), and pull my private code into local machine, safe, security, fast, works well.

Till now, it works find. But still some issues. How to make every existing on vagrant environment upgrade libraries and dependencies?

I am not done with this, but I find the answer, using Puppet.

Making the whole thing together, I use git. Make a project, every configuration file, setup script all put here, then holding by Github. Every time upgrade for dev environment, just using git pull and vagrant provision is enough.

Things I can improve,

  • Using Puppet to manage every libraries and configuration file, both using on vagrant and production server
  • Using Fabric writing remote control script send command to vagrant and production server
  • Using virtualenv to manage python code
  • Improve vagrant automatic setup script, avoid wget command, cause Mac OS X doesn’t install this by default

 

It works so well, and I running this for a new guy, using 17 minutes, wonderful.

 

 

Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone

在构建中学习

先给大家说一个真实的故事: 有一个少年(也许是中年吧)在10年就购置了全套的水果设备,信誓旦旦的说要进行爱疯开发。他也尝试着喊出了『你好世界』,也真的把这个口号部署在了机器上。
然后,然后就没有然后了。
虽然我们知道有很多的因素造成了到现在世界都没末日的时候他还没能拿出一款应用,但是其中一个不可忽略的因素就是对未知的知识领域的恐惧,这种恐惧让他始终也没能认真的跨出有效的第一步。

嗯,对,那个骚年就是我。我就是学习了三年的iOS开发,也没学会的那个白痴。
与其说没学会[1],倒不如说从来没真正的踏出那一步。我们知道,想跨进一个成体系的知识领域是比较困难的,尤其是第一步。如果我们无法保持对这个知识的足够频繁的接触,则知识无法沉积,不但不会学到新的内容,而且还容易把已经学过的很多内容遗忘。在接触中,也不能是眉毛胡子一把抓,否则涉猎的知识点太广切分散则毫无关联可言,也是意义不大的。我们要的是找到河对岸的一条路,而不是踩过岸边的所有碎石。

一般要跨入一个全新的领域,我觉得有两个方法。一个是找到足够多的时间,全面的去学习这个领域的点滴;另一个方法是使用这个领域的知识去完成某一个目标,在达成目标的同时学习领域知识。 第一种方法学的更加的扎实,而且在实践中会给出『对的』解决方案,坏处是时间长,而且在学习的过程中没有足够的阶段性的产出作为对自己的刺激,更适合在学校、实验室等地方进行。 第二种方式会不断的有阶段性产出,不断的刺激学习者让学习者能够持续的保持对领域的渴望。当然坏处也是很明显的,就是由于一路突进式的学习,导致很多的实现方式往往是『凑合』出来的一些解决方法,而且容易留下各种隐患(这种隐患完全因为对系统的『无知』而无法避免)。

其实我们几乎每次在这种时候都是按照第二种方式去进入一个全新的知识领域的,不管是学习一个新的技术,还是新加入一个公司/项目。我们都或主动或被动的要求在一个给定的时间点去完成什么目标,也就是我想说的『在构建中学习』。

我们应该如何跨出第一步,并且在构建中学习呢?

  1. 给定一个目标,让自己去完成一个达到足够好(Good Enough)质量的任务。
    很多时候并没有走出第一步是因为我们还没有一个明确的目标,这个目标不用很大,但是要明确、可达、有监督。
    明确:意味着这个目标是没有歧义的去完成一个明确的任务,而且是可以度量的
    可达:意味着这个目标不能是高不可攀的,一定要在一个段时间内可以完成
    有监督:这个至少对我很重要,我经常是下定决心然后不了了之,其实就是找某种方法监督自己一定把这个任务完成比如我一直想要开始 Mac/iOS 的开发,但是一直没能展开下去。直到我参与了我的一个小兄弟 @lovekonakona 发起了一个Mac下番茄工作法的应用 TomaTodo 。在这期间,我们对目标进行了上述的分析
    明确:只做一个可以计时的功能,工作25分钟,休息5分钟,到时间给提醒,工作中可以选择是否有滴答声。
    可达:这个任务是可以实现的,因为总的工作量就三个大点,计时、Notification、播放声音
    有监督:我俩相互推荐开发,互为监督。
  2. 利用已有的知识去推测可能隐藏的细节。
    虽然是进入一个新的知识体系,但是也会有一些方面和我们已经掌握的知识能够相互映射。我们可以利用自己的知识储备去快速的理解新的知识。在这过程中应该不断的去仔细体会一些细节的地方,去想为什么这些地方要这样设计,因为往往细节都是全局的延伸,而且是初期最容易接触到的。
    在这里要求我们就是敏感一些,多问一个为什么。在 TomaTodo 的开发过程中,遇到了 NSRunLoop、NSTimer、Notification Center 等 OS X SDK 的概念,也遇到了比如什么叫做 Target,怎么做一个应用的发布等基础概念。
    每个点想要『凑合』的完成并不难,但是明白了一些变化,为什么这样设计等问题工作量就会大好几倍甚至一个数量级。往往我们是被这些庞杂的概念吓倒或者干脆跳过去,但是想深入的研究 Mac OS X 开发,这些就必须下功夫仔细的研读相关文档。
  3. 寻找最佳实践,并给定一个新目标,重复1
    在经过一些思考和熟悉之后,我们往往会发现之前的实现方式其实是比较麻烦、性价比低甚至是南辕北辙的一种方式。那么就去优化这个方案,让她更加的『合理』。同时一定会有新的需求等出现,让我们再重复1。这期间,我们对代码进行了多次小规模重构,其实都是因为之前对一些概念的理解偏差或者是实现的并不合理,当然就更别提什么『优雅』了。然后我们定了新的功能点,继续回到第一步开始边构建边学习。

如此往复,我们会在一段时间内推开新知识的一个门缝。不断的修炼自己,就能达到一个『术』的层面,可以开始利用新知识工作了。但是想要达到『道』的层面,还需要大量的实践和经验了。而且根据自己的情况,也可以给自己一些稍微挑战的任务,这样进步的也会快一些。

 

注: [1],学会是指能够掌握这个领域的知识,并做到对一些问题的举一反三。而不仅仅是能够理解和看明白一些专业内的东西。

Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone

2013

  • 体重增加20斤,10斤为及格
  • 在豆瓣做成一件事儿
  • 在豆瓣外做成一件事儿
  • 给自己买一辆车,至少是能跑高速的
  • 运营好《背包电台》,目标是2013年度新播客
  • 看25本书,平均每两周一本
    • 经济类
    • 历史类
    • 新闻传播类
  • 看50部电影,平均每周一部
  • 去一个以前没去过的地方
  • 每周至少1小时德州
    • 目标从新浪打到PS
  • 坚持体育锻炼,每周至少一次足球或者游泳
  • 每两周坚持写一篇文章
  • 生活有规律,让家里不像一个垃圾宿舍
Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone

使用git的一些问题的补充

昨天写了多半年的第一篇Blog,为什么选择git作为版本管理工具 。从微博和blog上收到很多反馈,我在这里做一个统一的补充。以Q&A的形式出现。

Q:SVN为什么对并行开发支持不好?
A:因为下面这几个点导致的

  • 不支持离线版本提交(最新版我不知道)
    • 每次提交都需要和服务器进行交互,只要有代码交换就有冲突的风险。这时候一旦出现冲突则必须解决,但是这个是被动的,不自愿的,他会使你从当前的任务中抽离出来去解决冲突。
    • 如果当前我没有可以联通服务器的网络环境,那么我就无法提交代码。这样对于一个稍大一些的功能,就必须一次性的开发完成才能提交,而无法在中途有几个关键节点的提交作为管理、存档。
  • 不支持轻量级分支
    这就决定了创建、销毁分支的代价比较大。不是不可以,而是不如git那么自然。
  • 分支合并的问题
    见下一个问题

Q:SVN的分支合并有问题?
A:有问题,而且问题很大。

SVN的分支模型是比较奇怪的一种方式。SVN的分支、Tag都是采用拷贝模式,也就是把现在的代码拷贝到一个叫做branches的目录(这是SVN推荐的目录模型)。而基于这种分支模型,他的合并模型自然选用了 diff-patch 模式,也就是从开出分支的分叉点作为基础,使用源分支的最新代码和基础点做diff生成patch文件,然后把patch文件作用在目标分支上。这样说起来可能有点乱,我们看下面的图。

这里是一条提交的记录,其中的数字是版本号。我们在版本1开出一条分支,现在绿色和红色两条分支一同并行开发。
在版本6的地方,需要从绿色分支到红色分支有一个合并,SVN是如何做的呢?

  1. 找到两个分支上一个diff的点,这里是共同的祖先版本1
  2. 对当前绿色分支的最新的版本4和版本1进行diff,生成patch
  3. patch作用在版本5上,生成版本6
这个过程看上去是没问题的,而且工作良好,但是问题马上来了,如果再来一次合并呢?这个“上一次”是哪个版本?还是版本1么?还是其他版本?因为版本6是从版本4和版本1 diff来的,所以如果还要从绿色的分支想红色分支进行合并那么就需要对版本4进行diff。老的SVN(1.4、1.5?)之前是没有办法知道这个新的基础点的,所以才有了svn-merge这样的工具出现。
苇叶同学说,svn在新版本中已经天然支持了这个基础点的记录,所以合并的体验会好很多。所以我今天特意的使用svn1.6版本做尝试,但是在准备之后,merge的这一步我犹豫了。svn的merge还是老掉牙的模式,这让用习惯了git/hg的我怎么也没胆量尝试。
 
Morpheus:svn-repo yinwm$ svn merge --help
merge: Apply the differences between two sources to a working copy path.
usage: 1. merge sourceURL1[@N] sourceURL2[@M] [WCPATH]
       2. merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]
       3. merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [WCPATH]

  1. In the first form, the source URLs are specified at revisions
     N and M.  These are the two sources to be compared.  The revisions
     default to HEAD if omitted.

  2. In the second form, the URLs corresponding to the source working
     copy paths define the sources to be compared.  The revisions must
     be specified.

  3. In the third form, SOURCE can be either a URL or a working copy
     path (in which case its corresponding URL is used).  SOURCE (in
     revision REV) is compared as it existed between revisions N and M
     for each revision range provided.  If REV is not specified, HEAD
     is assumed.  '-c M' is equivalent to '-r :M', and '-c -M'
     does the reverse: '-r M:'.  If no revision ranges are
     specified, the default range of 0:REV is used.  Multiple '-c'
     and/or '-r' options may be specified, and mixing of forward
     and reverse ranges is allowed.

看,上面是svn merge的帮助,当我看到还需要指定版本号的时候,我就退却了。

Q:那么git没有这些问题么?
A:没有

git的初衷是为了管理Linux内核,要知道那可是全世界维护的一个项目,所以对分支的创建、销毁、合并的支持是非常良好的。他可以创建轻量级分支,这样在本地临时切换到某个分支进行一些feature的开发是非常方便的。当开发完成后直接合并即可,而如果失败就直接废弃这个分支,没什么成本和污染的。

git的每次提交是把整个的项目做一个镜像存储的,这样任何两个版本的区别只要简单的diff出来就可以,而分支合并也归并为简单的两个版本的diff,然后根据diff合并。这样你可以打着滚儿的合并,而不怕沾一身屎。

具体的git存储可以看这里,Git 内部原理 – Git 对象(翻墙越翻越健康)

Q:git没有良好的权限管理
A:被你戳中了

git本身有一些权限的管理,但是基本上他的粒度是对整个的项目。你可以通过ssh、apache等方式进行读、写的控制。但是能否更加细粒度的控制,我个人就不知道了。

这点上SVN绝对是领先git的。SVN也更适合大团队,因为大团队会有代码的安全性的考虑,分层、分段的控制是非常必须的。但是我们的团队很小,而且我的团队哲学是任何人可以看到、修改任何东西,包括代码和文档(我们的文档用trac的wiki和GDocs管理)。

在这点上我没过多的考虑,但是有需求的童鞋们,你们要想清楚哦。

Q:git-flow 真的很好么
A:git-flow 真的很好,像 hg-flow 一样的好

XD

最后

给大家看点我们代码库的截图,看到这些你就能明白为什么我说git/git-flow对我们的并行开发有很大的帮助了。图中每条颜色的线都是一条分支。

使用git-flow前

使用git-flow后

             

Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone

为什么选择git作为版本管理工具

团队组建已经半年有余,也该写一些东西了。

团队最初搭建的时候,有很多的东西是必须确定的,比如版本管理工具等。这些东西一旦定下来,要么以后就完全改不了,要么就是变更的代价非常大,所以必须慎重。这里就说一下为什么我们选择git。

选择一个好的版本管理工具是可以达到事半功倍的作用的。因为自信团队成员的能力不弱,所以在学习门槛的高度上就没有做太多的思考,不会自学好了。结合团队情况,考虑的角度有

  • 熟悉程度
  • 操作系统支持程度
  • 客户端支持程度
  • 离线操作能力
  • 并行开发能力
  • 对运维的支持能力
  • 扩展能力
备选的工具有

  • svn
  • mercurial (hg)
  • git
请注意:这里结合我团队的情况,例如我们的主力开发机全部是Mac,辅助的测试机器为WinXP,Win7,我们的Server是Linux(Ubuntu/CentOS);我们的生产环境需要一个跳板机器才能登陆上去,我们的开发、测试环境无法直接联通;我们的开发能力也一般。

SVN

  • 熟悉程度:★★★★☆
    SVN在IT界至少有将近十年的历史了吧,所以大家都比较熟悉
  • 操作系统支持程度:★★★★★
    老牌劲旅,各个系统的支持程度非常没问题
  • 客户端支持程度:★★★
    在Mac上没有看到非常好用的,Versions 貌似很好用,但是收费,所以也没用。至于乌龟SVN,那就更别说了。
  • 离线操作能力:☆
    鉴于我对SVN的理解,这就别提了,一个矬字了得。
  • 并行开发能力: ★★★
    团队上八成的功能都是可以分开进行的,所以相互之间干扰不会太大。但是SVN的合并功能啊,能让武大郎蹦起来打飞机。
  • 对运维的支持能力:★
    因为团队中是通过跳板机到生产环节,所以SVN是无法直接把代码输送到线上的,只能通过打包等方式。
  • 扩展能力:☆
    我完全不会嘛
  • 综合评分:★★★
    从这分数也就意味着基本上跟SVN拜拜了

Mercurial(hg)

  • 熟悉程度:★★★★☆
    从上一个团队开始,我们就深度使用hg,所以对hg是非常的熟悉,而且我个人非常认同hg保留一切历史的哲学。
  • 操作系统支持程度:★★★★★
    Python作品,对各个系统的支持均非常赞
  • 客户端支持程度:★★★★
    在之前,Mac上有MacHG,这是一个非常好用的客户端。而且在合并的时候可以使用P4Merge,这也是非常赞的。
  • 离线操作能力:★★★★★
    hg作为一个分布式版本管理系统,离线能力必然不在话下。
  • 并行开发能力: ★★★★
    结合我写的hgflow,hg的并行开发能力是没有问题的。但是由于hg哲学的问题他会保留一切历史,比如我本地的feature也会保留,但是这些都是没用的,而且会随着历史的演进不断的积累,会成为项目的垃圾累赘。
  • 对运维的支持能力:★★★★
    可以在跳板机上增加一个临时的repo,实现代码对生产环节的推送。
  • 扩展能力:★★★★★
    直接用Python扩展,我的hgflow就是一个标准的扩展程序。而且我熟悉嘛。
  • 综合评分:★★★★
    主要还是不断增加的历史垃圾给hg减了一星

git

  • 熟悉程度:★★★☆
    因为有hg的经验,所以git也会熟悉的比较快,但是一些高级的命令还不是很熟悉。
  • 操作系统支持程度:★★★☆
    win总是git的一个痛,不过我们不在win上开发,所以这个并不是大问题
  • 客户端支持程度:★★★★☆
    其实一直没找到一个非常好用的客户端,但好在git的命令行非常方便,而且团队觉得这无所谓。而后来发现了 SourceTree 这个应用,这是我见过的最完美的git/hg客户端,而且1.5版之后还支持git-flow/hg-flow
  • 离线操作能力:★★★★★
    这就别说了嘛
  • 并行开发能力: ★★★★★
    git的哲学对并行开发支持非常赞,而且这是他出现的主要目的。
  • 对运维的支持能力:★★★★
    和hg处理方式几乎一样。
  • 扩展能力:☆
    这个我也完全不会,但是git的扩展现在非常完备,所以也应该不用自己开发。
  • 综合评分:★★★★☆
    git看来是最好的选择,尤其是 SourceTree 的出现。

总所上述,我们决定选择git作为我们的版本控制软件,不会的大家多学学即可。

另,再次推荐 SourceTree ,天然的支持 git-flow/hg-flow,社区支持 github/bitbucket,所以用起来非常的爽。而且结合P4Merge,基本上解决了我遇到的所有问题。而且 SourceTree 是免费的,只要申请一个免费的 License 即可。

Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone

2011最后一天

今天是2011的最后一天,今年要总结的很多,稍后给出吧。只想说一句,今年结婚是我人生到现在最大的事情,宝宝我爱你。

Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone

从哪个谣言看出来我是移动的人了?

今天在一个QQ群中说了几句话,又被莫名的捧杀。之所以叫做捧杀,就是让你感觉到我现在高高的捧起你,是为了更狠的摔你。我十分不明白为什么在这个群我一直会受到这样待遇,今天终于明白了。
今天听到这么一句话,说我是移动的帮凶,我是助纣为虐。开始我很不明白,后来我想我可能猜到了,他们把我当作移动的人了。可是我什么时候、从什么地方表示过我是移动的人呢?

我在139干过一段时间,那时候的139还是卓望控股的下属公司,和移动就算有关系也是外包的关系。你总不能说ARM就是苹果吧。

让我十分不解的地方就是为什么他们对我的火气这么大。OK,就算是因为移动,那跟我有半毛钱关系么?作为IT人,难道就不能自己去查查么?难道一边愤青着,一边盲从着么?
退一万步说,就算我是移动的员工,你用得着跟我急么?你觉得移动不好你投诉啊,你找移动打架啊。看见流氓不吱声,见了老实人上来踹一脚还真是英雄啊。

这就是国内的IT从业者,哎,洗洗睡吧。

Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone

周末在家当了两天好男人

周末老婆来北京找我,但是来之前就感冒了,来了还有发烧的症状。

本来周末还是想跑一下婚礼的事情,结果也不去了。让老婆在家躺了两天,我则全职主夫两天。

好久没跑菜市场了,现在东西太贵了,西红柿最便宜的竟然三块一斤。烧饼都7毛了,而且还小了一圈。物价真是高了。买了一些退烧的药,三天的剂量竟然¥180多,比我们出去吃顿好的都贵。

在家给老婆煎鸡蛋,做面汤,熬梨水。居家男人的感觉也挺不错的喔。

宝宝快快好起来吧。

Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone

每个人都应该经历一次创业,趁早

过年,虽然胡乱的在家度日,但是也还惦记着自己做点小东西,从网上看点文章什么的。这几天,越发的让我有了一个想法:每个人都应该经历一次创业,趁早。

看了 @laoxiong 的《工程师导向与产品经理导向》,也看了很多人的回复和解说。我没有那么深刻的认识,只是从这几天做点小东西中想来的一点东西。因为是我自己的小东西,那么就一个人,所以肯定的是“我”导向。但是这个“我”到底是什么身份呢?
我肯定是工程师,而且我也肯定是产品经理,虽然肯定是一个二调子的PM。作为一个死程序员,工程师部分不说,说说产品经理这部分。整个的过程中,我也会设计产品,从用户的角度去思考产品场景、使用过程等。以往工作中不同部门之间的妥协随处发生,我会因为产品原因让技术妥协,也会因为技术原因让产品妥协。而这个看似冲突、挣扎、分裂的过程中,有一点是不变的,就是我要给这个小东西的用户一个好的东西,一个好的产品。一切的冲突、挣扎、分裂都是以此作为基础的。如果真说是什么导向,我认为是 Owner、拥有者

还看了 @zhengjun 的《一个想法从构思到实现只需7天》。不同的人从文章中肯定可以看到很多的哈姆雷特,但是我体会到最重要的就是要保持激情。是激情让我们总是感到活力无限,总是不会让自己沉沉的死去。
春节偶获 Amazon Kindle 3 一枚,也在摸索中不断的学会使用。随着越会用,就越想用的爽,则很自然的有了一些想法。仿照激情的做法,设计产品、开发功能、买域名、配置等,只花去了一天的功夫。虽然最后由于 Kindle 的一些服务追查的问题没能够成功。但是在双手离开键盘的那一刻,还是觉得这是非常澎湃的一天。而且这也是对自己的又一次挑战,要知道前一天冒出这个想法的时候,我已经钻被窝了,根本没有细想工作量有多大就给自己规定了一天的时间。挑战虽然没有完全成功,也不算失败。
我想就是这样的自我挑战,期待突破就是让我一直能保持激情和年轻的办法把。

今天,看到了《台湾大众银行电视广告-梦骑士篇-TC Bank Dream Ranger》。五个老人平均年龄81,一个患有癌症,一个重听,三个心脏病,13天,不分白天黑夜,骑摩托环台湾。人为什么要活着?最后一个大大的“梦”字,也激动了我。

胡乱的说了一通。想起这个题目的时候,我都没有整理好自己的思路。我只是想,是不是我们的人生,应该让自己去激动的做些什么,而这个也应该是自己对自己完全负责,去实现自己的一个“梦”的事情。让自己沉浸在其中,以我为导向,全情的投入。

人为什么要活着?

Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Email this to someone