分享

Cloud Foundry vcap_dev start过程分析

本帖最后由 pig2 于 2014-7-30 19:58 编辑
问题导读

1、什么是options参数?
2、使用什么命令来启动所有的cf组件?




我们会通过bin/vcap_dev start命令来启动所有的cf组件,当然,也可以指定某些组件,比如bin/vcap_dev start health_manager。
下面大致研究下流程。

1. vcap_dev文件
首先是vcap_dev文件,前面主要处理了命令参数以及路径等问题。最后可以看到
  1. exec_cmd("#{ruby_binary} #{vcap_launch} #{command} #{vcap_components["components"].join(" ")} -c #{deployment_config_path} -v #{vcap_path} -l #{deployment_info["deployment_log_path"]}")  
复制代码


exec_cmd意思就是执行cmd,而ruby_binary是ruby,vcap_launch就是和vcap_dev同位置的vcap文件,后面的command就是我们的启动指令start,当然可能是stop,restart之类的。

2. vcap文件
所以我们就可以跑去vcap文件看个究竟了。
因为本文研究start,所以直接看vcap文件的start函数:
  1. def start  
  2.   if !running?  
  3.   
  4.     pid = fork do  
  5.       # Capture STDOUT when no log file is configured  
  6.       if !log_file?  
  7.         stdout = File.open(log_file, 'a')  
  8.         stdout.truncate(0)  
  9.         STDOUT.reopen(stdout)  
  10.         stderr = File.open(log_file, 'a')  
  11.         STDERR.reopen(stderr)  
  12.       end  
  13.       # Make sure db is setup, this is slow and we should make it faster, but  
  14.       # should help for now.  
  15.       if is_cloud_controller?  
  16.         cc_dir = File.expand_path(File.join(DIR, '..', 'cloud_controller'))  
  17.         Dir.chdir(cc_dir) { `bundle exec rake db:migrate` }  
  18.       end  
  19.       exec("#{component_start_path}")  
  20.     end  
  21.   
  22.     Process.detach(pid)  
  23.   
  24.     start = Time.now  
  25.     while ((Time.now - start) < 20)  
  26.       break if running?  
  27.       sleep (0.25)  
  28.     end  
  29.   end  
  30.   
  31.   status  
  32.   
  33.   if !running?  
  34.     if File.exists?(log_file)  
  35.       log = File.read(log_file)  
  36.       STDERR.puts "LOG:\n #{log}" if !log.empty?  
  37.     end  
  38.   end  
  39. end  
复制代码


其他的不理会,重点语句是exec("#{component_start_path}"),当然cc还需要做一个db migrate。那么我们看component_start_path,这也是个函数。这个函数所做的事情就是跑去vcap的相应目录下面,然后执行bin目录下的同名文件。以health manager为例,它执行vcap/bin/health_manager文件,同时以-c传入.deployment/devbox/config下面的health_manager.yml文件。那么vcap_dev start任务就交接完成了,接下来由bin下面的脚本执行了。
这里的vcap路径下有bin目录,而vcap/health manager下面也有bin,vcap脚本调用的是vcap下的bin。之前搞错了。那么看health manager的bin脚本:
  1. exec(File.expand_path("../../health_manager/bin/health_manager", __FILE__), *ARGV)  
复制代码


他就直接调用vcap/health_manager/bin/health_manager脚本了

3. bin脚本
然后我们看看bin下面的脚本都在做什么:
  1. home = File.join(File.dirname(__FILE__), '/..')  
  2. ENV['BUNDLE_GEMFILE'] = "#{home}/Gemfile"  
  3. require File.join(home, 'lib/health_manager')
复制代码

很简单,就是设置了bundle gemfile的环境变量,然后指向lib下的health_manager文件。Lib下的health_manager.rb主要有三个部分,第一个部分是module CloudController,用来添加非常多的依赖(require),目前不清楚这么做的意义。第二部分是HealthManager类,那就不提了。重要的是第三部分,也就是文档末尾的一些代码:
  1. if $0 == __FILE__ || File.expand_path($0) == File.expand_path(File.join(File.dirname(__FILE__), '../bin/health_manager'))  
  2.   
  3.   config_path = ENV["CLOUD_FOUNDRY_CONFIG_PATH"] || File.join(File.dirname(__FILE__), '../config')  
  4.   config_file = File.join(config_path, "health_manager.yml")  
  5.   options = OptionParser.new do |opts|  
  6.     opts.banner = 'Usage: healthmanager [OPTIONS]'  
  7.     opts.on("-c", "--config [ARG]", "Configuration File") do |opt|  
  8.       config_file = opt  
  9.     end  
  10.     opts.on("-h", "--help", "Help") do  
  11.       puts opts  
  12.       exit  
  13.     end  
  14.   end  
  15.   options.parse!(ARGV.dup)  
  16.   
  17.   begin  
  18.     config = YAML.load_file(config_file)  
  19.   rescue => e  
  20.     $stderr.puts "Could not read configuration file:  #{e}"  
  21.     exit 1  
  22.   end  
  23.   
  24.   EM.epoll  
  25.   
  26.   EM.run { HealthManager.start(config) }  
  27. end  
复制代码


首先去读config file,然后解析了options参数,我们知道bin脚本已经传入了-c参数,所以在options解析中,config会覆盖掉。在读取config之后,就使用Event Machine启动HealthManager了。EM.epoll是一个linux下的调用命令,对我们没有意义。EM.run就是我们要看的,可以看到这里只调用了HealthManager.start函数。后面就不再深入了,大致的流程就是完成配置,然后开启NATS,订阅NATS事件,然后发送NATS消息。

总结一下:vcap_dev和vcap脚本都用来处理安装之后的启动停止等任务,他们会调用vcap/bin目录下对应的脚本,而这些脚本又会去相应组件的目录下执行更为详细的任务


已有(1)人评论

跳转到指定楼层
qinjun_angel 发表于 2014-7-30 20:46:37
关注一下,学习了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条