关于cloud_foundry自己的ruby, gem, bundle

很早就大致了解cloud_foundry有自己的ruby,而不是使用系统提供的ruby。并且还有两个版本的ruby,今天终于遇到了,大致搞清楚了。

他们在哪里

首先我们要知道cloud_foundry把自己的ruby,gem装到哪里去了,这个可以去看config目录下面的deployment_info.conf文件。里面包含了一个ruby_bin_dir变量。这个路径就是ruby所在,在本机上面是:/root/cloudfoundry/.deployments/devbox/deploy/rubies/ruby-1.9.2-p180/bin。

ruby下面有什么

在bin目录下面可以看到许多已近安装的软件,包括gem、rails、rack、bundle等。
关于cloud_foundry自己的ruby, gem, bundle_第1张图片
这里的软件才是cf真正使用到的。
有个办法可以验证,我们在终端中直接输入:gem list --local查看安装的gem包,会发现gem非常少,bundle之类的根本没有。如果使用这个gem,那么vcap::common之类的模块也无法使用。
而如果跑到这个路径下面执行这里的gem,那么就可以看到所需要的结果了。

cf是怎么使用这里的软件的

既然知道了cf确实是使用这个位置下面的ruby的,那么到底在哪里做了这个相应的操作呢?
我们来看vcap_dev文件,在dev_setup/bin目录里面的。我在 http://blog.csdn.net/cherry_sun/article/details/7730008里面分析过,我们start的时候是通过
exec_cmd("#{ruby_binary} #{vcap_launch} #{command} #{vcap_components["components"].join(" ")} -c #{deployment_config_path} -v #{vcap_path} -l #{deployment_info["deployment_log_path"]}")
这句话来执行start的,那么这里的ruby_binary其实就是我们上面提到的ruby的绝对路径。有兴趣可以去看下代码。归根到底,这个ruby的路径还是从前面提到的deployment_info.conf文件中取得的。而这个文件其实是vcap_dev_setup在安装的时候写入的。

cf的gem和bundle如何发生作用的

我们知道要让ruby项目取得依赖,我们可以利用gem和bundle来实现。使用bundle install来安装相应的gem包,然后在项目当中写下:
require "rubygems"
require "bundler/setup"
两行代码(可以看bundler官网: http://gembundler.com/)

第一步

在cf当中,第一步bundle install是在安装时完成的,现在采用chef了,就是在chef的cookbook中定义的。我在 http://blog.csdn.net/cherry_sun/article/details/7730008中已经有提到了,可以参看最后一部分,cloud controller的recipe分析,其中的 cf_bundle_install就是在做bundle install。当然,这个bundle也是使用了cf自己的bunlder:File.join(node[:ruby][:path], "bin", "bundle")

第二步

然后就是两个require了,这里有两个实现方式。
首先是最简单的,看dea/lib/dea/dea.rb最开头,就有两句:
require 'rubygems'
require 'bundler/setup'

第二种要看vcap/cloud_controller/config/boot.rb文件了,这个文件的最前面有:
require 'rubygems'
require 'erb'
begin
  require 'fiber'
rescue LoadError
  $stderr.puts "CloudController requires a Ruby implementation that supports Fibers"
  exit 1
end

# Set up gems listed in the Gemfile.
gemfile = File.expand_path('../../Gemfile', __FILE__)
begin
  ENV['BUNDLE_GEMFILE'] = gemfile
  require 'bundler'
  Bundler.setup
rescue Bundler::GemNotFound => e
  STDERR.puts e.message
  STDERR.puts "Try running `bundle install`."
  exit!
end if File.exist?(gemfile)

想必应该可以看懂了,就是在把bundle和gem加载进来。这个boot.rb被health manager调用到了,我们可以看health_manager.rb文件最前面的部分:
  def self.setup
    $:.unshift(lib_dir.to_s) unless $:.include?(lib_dir.to_s)
    require root.join('config', 'boot')
    require 'active_record'
    require 'active_support/core_ext'
    require 'yajl'
    require 'eventmachine'
    require 'nats/client'
    require 'vcap/common'
    require 'vcap/component'
    require 'vcap/logging'
    require 'vcap/rolling_metric'
    require 'vcap/priority_queue'
也是一目了然,把上面提到的boot.rb require进去了。

你可能感兴趣的:(manager,Ruby,Path,rubygems,Deployment,Components)