Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[dev_setup] refactor vcap components

Change-Id: Ia423958c2bf69f883c4107071193345c23c0b48d
  • Loading branch information...
commit 5f87720abc20f56973f9edf32b833afe847726cd 1 parent 13f9dbc
Frank Lu authored
4 dev_setup/README
View
@@ -129,8 +129,8 @@ o Excluded components:
environment variable as follows:
unset CLOUD_FOUNDRY_EXCLUDED_COMPONENT
- To modify the default exclusion list, add the component name in dev_setup/bin/vcap to:
- DEFAULT_CLOUD_FOUNDRY_EXCLUDED_sCOMPONENT
+ To modify the default exclusion list, add the component name in dev_setup/lib/vcap_components.rb to:
+ DEFAULT_CLOUD_FOUNDRY_EXCLUDED_COMPONENT
NOTE: To learn more about custom deployment config files and multi host setups
see the README file vcap/dev_setup/deployments/README.
307 dev_setup/bin/vcap
View
@@ -3,23 +3,6 @@
#
# Usage: bin/vcap_system [start|stop|restart|tail|status] [component ...]
#
-# Omit component name to apply the operation to these components:
-#
-# core
-# - router
-# - cloud_controller
-# - health_manager
-# - dea
-# - uaa
-# - acm
-#
-# services
-# - redis
-# - mysql
-# - mongo
-#
-# service_tools
-# - backup_manager
require 'yaml'
require 'fileutils'
@@ -29,206 +12,7 @@ require 'rubygems'
require 'eventmachine'
require 'nats/client'
-
-class Component
- attr :name
- attr :path
-
- def initialize(name, configuration_path = nil)
- @name = name
- @configuration_path = configuration_path
-
- if core?
- @path = File.join(DIR, name)
- # Sane default for location of configuration file
- if @configuration_path.nil?
- if $config_dir
- @configuration_path = File.join($config_dir, "#{name}.yml")
- else
- @configuration_path = File.join(DIR, "..", name, "config", "#{name}.yml")
- end
- end
- else
- if service_tool?
- @configuration_path = File.join($config_dir, "#{name}.yml") if @configuration_path.nil? && $config_dir
- if name =~ /backup_manager|snapshot_manager/
- @path = File.join(DIR, "../services", "tools", "backup", "manager", "bin", name)
- @configuration_path ||= File.join(DIR, "../services", "tools", "backup", "manager", "config", "#{name}.yml")
- else
- @path = File.join(DIR, "../services", "tools", name, "bin", name)
- @configuration_path ||= File.join(DIR, "../services", "tools", name, "config", "#{name}.yml")
- end
- else
- # Sane default for location of service configuration file
- pre = name.sub(/_node|_gateway/,'')
- # mapping 'rabbitmq' in dev_setup to 'rabbit' in services
- pre = 'rabbit' if pre == 'rabbitmq'
- bin_name = name.index('rabbitmq')? name.sub(/mq/, '') : name
- @path = File.join(DIR, "../services", pre, "bin", bin_name)
- # Sane default for location of configuration file
- if @configuration_path.nil?
- if $config_dir
- @configuration_path = File.join($config_dir, "#{name}.yml")
- else
- @configuration_path ||= File.join(DIR, "../services", pre, "config", "#{name}.yml")
- end
- end
- end
- end
- end
-
- def is_cloud_controller?
- @name =~ /cloud_controller/i
- end
-
- def is_router?
- @name =~ /router/i
- end
-
- def to_s
- name
- end
-
- def core?
- Run.core.include? name
- end
-
- def service?
- Run.services.include? name
- end
-
- def service_tool?
- Run.service_tools.include? name
- end
-
- DEFAULT_CLOUD_FOUNDRY_EXCLUDED_COMPONENT = 'neo4j|memcached|couchdb|service_broker|elasticsearch|backup_manager'
- def is_excluded?
- @excluded ||= ENV['CLOUD_FOUNDRY_EXCLUDED_COMPONENT']
- @excluded ||= DEFAULT_CLOUD_FOUNDRY_EXCLUDED_COMPONENT
- name.match(@excluded) if !@excluded.empty?
- end
-
- def exists?
- File.exists? @path
- end
-
- def configuration
- @configuration ||= YAML.load(File.read(@configuration_path))
- end
-
- def pid_file
- configuration["pid"] || raise("#{@configuration_path} does not specify location of pid file")
- end
-
- def log_file?
- !configuration["log_file"].nil?
- end
-
- def log_file
- log_file = configuration["log_file"]
- log_file || File.join($log_dir, "#{name}.log")
- end
-
- def pid
- if File.exists?(pid_file)
- body = File.read(pid_file)
- body.to_i if body
- end
- end
-
- def running?
- running = false
- # Only evaluate 'pid' once per call to 'running?'
- if procid = pid
- running = `ps -o rss= -p #{procid}`.length > 0
- end
- running
- end
-
- def component_start_path
- exec_path = path.dup
- if $config_dir
- config_file = File.join($config_dir, "#{name}.yml")
- if File.exists?(config_file)
- exec_path << " -c #{config_file}"
- end
- end
- if is_router? && $port
- exec_path << " -p #{$port}"
- end
- exec_path
- end
-
- def start
- if !running?
-
- pid = fork do
- # Capture STDOUT when no log file is configured
- if !log_file?
- stdout = File.open(log_file, 'a')
- stdout.truncate(0)
- STDOUT.reopen(stdout)
- stderr = File.open(log_file, 'a')
- STDERR.reopen(stderr)
- end
- # Make sure db is setup, this is slow and we should make it faster, but
- # should help for now.
- if is_cloud_controller?
- cc_dir = File.expand_path(File.join(DIR, '..', 'cloud_controller'))
- Dir.chdir(cc_dir) { `bundle exec rake db:migrate` }
- end
- exec("#{component_start_path}")
- end
-
- Process.detach(pid)
-
- start = Time.now
- while ((Time.now - start) < 20)
- break if running?
- sleep (0.25)
- end
- end
-
- status
-
- if !running?
- if File.exists?(log_file)
- log = File.read(log_file)
- STDERR.puts "LOG:\n #{log}" if !log.empty?
- end
- end
- end
-
- def stop
- return status unless running?
-
- kill = "kill -TERM #{pid}"
- `#{kill} 2> /dev/null`
-
- if $? != 0
- STDERR.puts "#{'Failed'.red} to stop #{name}, possible permission problem\?"
- return
- end
-
- # Return status if we succeeded in stopping
- return status unless running?
-
- if running?
- sleep(0.25)
- if running?
- kill = "kill -9 #{pid}"
- `#{kill} 2> /dev/null`
- end
- end
- status
- end
-
- def status
- status = running? ? 'RUNNING'.green : 'STOPPED'.red
- puts "#{name.ljust(20)}:\t #{status}"
- end
-
-end
+require File.expand_path(File.join("..", "lib", "vcap_components"), File.dirname(__FILE__))
# This is used to bring up and down the NATS messaging server.
class NatsServer
@@ -418,34 +202,33 @@ module Run
private
- def self.core
- %w(router cloud_controller dea health_manager uaa acm)
- end
-
- def self.services
- %w(redis mysql mongodb)
- end
-
- def self.service_tools
- %w(backup_manager)
+ # type: all, core, service, service_tool, service_auxilary, and name of registered components, e.g. router, mysql_node ...
+ def self.component_collection(type)
+ return Component.getNamedComponents().keys if type == "all"
+ return [type] if Component.getNamedComponents().include?(type)
+ collection = []
+ check_type_method_sym = "#{type}?".to_sym
+ Component.getNamedComponents().each do |k, v|
+ if v.method_defined?(check_type_method_sym) && v.new('foo').send(check_type_method_sym)
+ collection << k
+ end
+ end
+ collection
end
def self.alias_args(args)
aliased = []
args.each do |arg|
case arg
- when 'all'
- aliased.concat(Run.core + Run.services)
- when 'core'
- aliased.concat Run.core
- when 'services'
- aliased.concat Run.services
- when 'service_tools'
- aliased.concat Run.service_tools
when 'mongo'
aliased << 'mongodb'
else
- aliased << arg
+ collection = Run.component_collection(arg)
+ if collection.empty?
+ aliased << arg
+ else
+ aliased.concat collection
+ end
end
end
aliased
@@ -455,11 +238,7 @@ module Run
args = Run.alias_args(args)
new_args = []
args.each do |arg|
- if Run.core.include? arg
- new_args << arg
- elsif Run.service_tools.include? arg
- new_args << arg
- elsif arg =~ /_node|_gateway|_backup|_broker/
+ if Component.getNamedComponents().keys.include? arg
new_args << arg
else # This is a service, expand in place here..
new_args << "#{arg}_gateway"
@@ -470,12 +249,16 @@ module Run
end
def self.components(args)
- args = (Run.core + Run.services + Run.service_tools) if args.empty?
+ args = Component.getNamedComponents().keys if args.empty?
args = Run.expand_args(args)
components = args.map do |arg|
- component = Component.new(arg)
- STDOUT.puts "Skipping excluded component: #{component.name}" if component.is_excluded?
- component if (component.exists? && !component.is_excluded?)
+ component = Component.create(arg)
+ if component.nil?
+ STDOUT.puts "Skipping invalid component: #{arg}"
+ else
+ STDOUT.puts "Skipping excluded component: #{component.name}" if component.is_excluded?
+ end
+ component if (component && component.exists? && !component.is_excluded?)
end.compact
STDERR.puts "Don't know how to process '#{args.inspect}' \?\?" if components.empty?
components
@@ -545,37 +328,6 @@ module Run
end
-module VcapStringExtensions
-
- def red
- colorize("\e[0m\e[31m")
- end
-
- def green
- colorize("\e[0m\e[32m")
- end
-
- def yellow
- colorize("\e[0m\e[33m")
- end
-
- def bold
- colorize("\e[0m\e[1m")
- end
-
- def colorize(color_code)
- unless $nocolor
- "#{color_code}#{self}\e[0m"
- else
- self
- end
- end
-end
-
-class String
- include VcapStringExtensions
-end
-
$config_dir ||= ENV['CLOUD_FOUNDRY_CONFIG_PATH']
args = ARGV.dup
opts_parser = OptionParser.new do |opts|
@@ -588,8 +340,7 @@ opts_parser = OptionParser.new do |opts|
opts.on('--noprompt', '-n') { $noprompt = true }
end
-
-excluded ||= ENV['CLOUD_FOUNDRY_EXCLUDED_COMPONENT'] || Component::DEFAULT_CLOUD_FOUNDRY_EXCLUDED_COMPONENT
+excluded ||= ENV['CLOUD_FOUNDRY_EXCLUDED_COMPONENT'] || Component.getExcludedComponents().join('|')
puts "- Excluded components: #{excluded}.\n See dev_setup/README for details" if !excluded.empty?
args = opts_parser.parse!(args)
30 dev_setup/lib/vcap_common.rb
View
@@ -0,0 +1,30 @@
+module VcapStringExtensions
+
+ def red
+ colorize("\e[0m\e[31m")
+ end
+
+ def green
+ colorize("\e[0m\e[32m")
+ end
+
+ def yellow
+ colorize("\e[0m\e[33m")
+ end
+
+ def bold
+ colorize("\e[0m\e[1m")
+ end
+
+ def colorize(color_code)
+ unless $nocolor
+ "#{color_code}#{self}\e[0m"
+ else
+ self
+ end
+ end
+end
+
+class String
+ include VcapStringExtensions
+end
325 dev_setup/lib/vcap_components.rb
View
@@ -0,0 +1,325 @@
+# Copyright (c) 2009-2011 VMware, Inc.
+#
+
+require 'yaml'
+require 'fileutils'
+
+require File.expand_path("./vcap_common.rb", File.dirname(__FILE__))
+
+class Component
+ @@named_components = {}
+ @@excluded = []
+
+ DEFAULT_CLOUD_FOUNDRY_EXCLUDED_COMPONENT = 'neo4j|memcached|couchdb|service_broker|elasticsearch|backup_manager'
+
+ attr :name
+
+ def self.create(name, configuration_file=nil)
+ sub_class = @@named_components[name]
+ if sub_class
+ sub_class.new(name, configuration_file)
+ else
+ nil
+ end
+ end
+
+ def self.register(name, excluded=nil)
+ @@named_components[name] = self
+ default_excluded=/#{DEFAULT_CLOUD_FOUNDRY_EXCLUDED_COMPONENT}/
+ if excluded == true || (excluded.nil? && name =~ default_excluded)
+ @@excluded << name
+ end
+ end
+
+ def self.getNamedComponents()
+ @@named_components
+ end
+
+ def self.getExcludedComponents()
+ @@excluded
+ end
+
+ private
+ def initialize(name, configuration_file = nil)
+ @name = name
+ @configuration_path = configuration_file || get_configuration_path
+ end
+
+ public
+ def is_cloud_controller?
+ @name =~ /cloud_controller/i
+ end
+
+ def is_router?
+ @name =~ /router/i
+ end
+
+ def to_s
+ name
+ end
+
+ def is_excluded?
+ excluded_env = $excluded || ENV['CLOUD_FOUNDRY_EXCLUDED_COMPONENT']
+ unless excluded_env.nil?
+ if excluded_env.empty?
+ false
+ else
+ name.match(excluded_env)
+ end
+ else
+ @@excluded.include?(name)
+ end
+ end
+
+ def exists?
+ File.exists? get_path
+ end
+
+ def vcap_bin
+ DIR
+ end
+
+ def get_path
+ @path = File.join(vcap_bin, name)
+ end
+
+ def configuration_file_in
+ $config_dir ||= ENV['CLOUD_FOUNDRY_CONFIG_PATH']
+ $config_dir
+ end
+
+ def get_configuration_path
+ if @configuration_path.nil?
+ if configuration_file_in
+ @configuration_path = File.join(configuration_file_in, "#{name}.yml")
+ else
+ @configuration_path = File.join(vcap_bin, "..", name, "config", "#{name}.yml")
+ end
+ end
+ @configuration_path
+ end
+
+ def configuration
+ @configuration ||= YAML.load(File.read(get_configuration_path))
+ end
+
+ def pid_file
+ configuration["pid"] || raise("#{get_configuration_path} does not specify location of pid file")
+ end
+
+ def log_file?
+ !configuration["log_file"].nil?
+ end
+
+ def log_file
+ log_file = configuration["log_file"]
+ log_file || File.join($log_dir, "#{name}.log")
+ end
+
+ def pid
+ if File.exists?(pid_file)
+ body = File.read(pid_file)
+ body.to_i if body
+ end
+ end
+
+ def running?
+ running = false
+ # Only evaluate 'pid' once per call to 'running?'
+ if procid = pid
+ running = `ps -o rss= -p #{procid}`.length > 0
+ end
+ running
+ end
+
+ def component_start_path
+ exec_path = (get_path).dup
+ exec_path << " -c #{get_configuration_path}"
+ if is_router? && $port
+ exec_path << " -p #{$port}"
+ end
+ exec_path
+ end
+
+ def start
+ if !running?
+
+ pid = fork do
+ # Capture STDOUT when no log file is configured
+ if !log_file?
+ stdout = File.open(log_file, 'a')
+ stdout.truncate(0)
+ STDOUT.reopen(stdout)
+ stderr = File.open(log_file, 'a')
+ STDERR.reopen(stderr)
+ end
+ # Make sure db is setup, this is slow and we should make it faster, but
+ # should help for now.
+ if is_cloud_controller?
+ cc_dir = File.expand_path(File.join(vcap_bin, '..', 'cloud_controller'))
+ Dir.chdir(cc_dir) { `bundle exec rake db:migrate` }
+ end
+ exec("#{component_start_path}")
+ end
+
+ Process.detach(pid)
+
+ start = Time.now
+ while ((Time.now - start) < 20)
+ break if running?
+ sleep (0.25)
+ end
+ end
+
+ status
+
+ if !running?
+ if File.exists?(log_file)
+ log = File.read(log_file)
+ STDERR.puts "LOG:\n #{log}" if !log.empty?
+ end
+ end
+ end
+
+ def stop
+ return status unless running?
+
+ kill = "kill -TERM #{pid}"
+ `#{kill} 2> /dev/null`
+
+ if $? != 0
+ STDERR.puts "#{'Failed'.red} to stop #{name}, possible permission problem\?"
+ return
+ end
+
+ # Return status if we succeeded in stopping
+ return status unless running?
+
+ if running?
+ sleep(0.25)
+ if running?
+ kill = "kill -9 #{pid}"
+ `#{kill} 2> /dev/null`
+ end
+ end
+ status
+ end
+
+ def status
+ status = running? ? 'RUNNING'.green : 'STOPPED'.red
+ puts "#{name.ljust(20)}:\t #{status}"
+ end
+
+end
+
+class CoreComponent < Component
+ def core?
+ true
+ end
+end
+
+class ServiceComponent < Component
+ def service?
+ true
+ end
+
+ def node?
+ @name =~ /_node/i
+ end
+
+ def gateway?
+ @name =~ /_gateway/i
+ end
+
+ def get_path
+ return @path if @path
+ pre = name.sub(/_node|_gateway/,'')
+ # mapping 'rabbitmq' in dev_setup to 'rabbit' in services
+ pre = 'rabbit' if pre == 'rabbitmq'
+ bin_name = name.index('rabbitmq')? name.sub(/mq/, '') : name
+ @path = File.join(vcap_bin, "../services", pre, "bin", bin_name)
+ end
+
+ def get_configuration_path
+ @configuration_path ||= (File.join(configuration_file_in, "#{name}.yml") if configuration_file_in)
+ unless @configuration_path && File.exist?(@configuration_path)
+ pre = name.sub(/_node|_gateway/,'')
+ # mapping 'rabbitmq' in dev_setup to 'rabbit' in services
+ pre = 'rabbit' if pre == 'rabbitmq'
+ @configuration_path = File.join(vcap_bin, "../services", pre, "config", "#{name}.yml")
+ end
+ @configuration_path
+ end
+end
+
+class ServiceAuxiliaryComponent < Component
+ def service_auxiliary?
+ true
+ end
+
+ def get_path
+ @path ||= File.join(vcap_bin, "../services", name, "bin", name)
+ end
+
+ def get_configuration_path
+ @configuration_path ||= (File.join(configuration_file_in, "#{name}.yml") if configuration_file_in)
+ unless @configuration_path && File.exist?(@configuration_path)
+ @configuration_path = File.join(vcap_bin, "../services", name, "config", "#{name}.yml")
+ end
+ @configuration_path
+ end
+end
+
+class ServiceToolComponent < Component
+ def service_tool?
+ true
+ end
+
+ def get_path
+ return @path if @path
+ if name =~ /backup_manager|snapshot_manager/
+ @path = File.join(vcap_bin, "../services", "tools", "backup", "manager", "bin", name)
+ else
+ @path = File.join(vcap_bin, "../services", "tools", name, "bin", name)
+ end
+ @path
+ end
+
+ def get_configuration_path
+ @configuration_path ||= (File.join(configuration_file_in, "#{name}.yml") if configuration_file_in)
+ unless @configuration_path && File.exist?(@configuration_path)
+ if name =~ /backup_manager|snapshot_manager/
+ @configuration_path = File.join(vcap_bin, "../services", "tools", "backup", "manager", "config", "#{name}.yml")
+ else
+ @configuration_path = File.join(vcap_bin, "../services", "tools", name, "config", "#{name}.yml")
+ end
+ end
+ @configuration_path
+ end
+end
+
+# register valid named components
+
+## core
+%w(router cloud_controller dea health_manager uaa acm).each do |core|
+ CoreComponent.register(core)
+end
+
+## services: gateways & nodes
+%w(redis mysql mongodb rabbitmq postgresql vblob neo4j memcached couchdb elasticsearch filesystem).each do |service|
+ ServiceComponent.register("#{service}_gateway")
+end
+
+%w(redis mysql mongodb rabbitmq postgresql vblob neo4j memcached couchdb elasticsearch).each do |service|
+ ServiceComponent.register("#{service}_node")
+end
+
+## service auxiliary
+%w(service_broker).each do |auxiliary|
+ ServiceAuxiliaryComponent.register(auxiliary)
+end
+
+## service tools
+%w(backup_manager snapshot_manager).each do |tool|
+ ServiceToolComponent.register(tool)
+end
31 dev_setup/lib/vcap_defs.rb
View
@@ -1,36 +1,7 @@
require 'rubygems'
require 'json'
-module VcapStringExtensions
-
- def red
- colorize("\e[0m\e[31m")
- end
-
- def green
- colorize("\e[0m\e[32m")
- end
-
- def yellow
- colorize("\e[0m\e[33m")
- end
-
- def bold
- colorize("\e[0m\e[1m")
- end
-
- def colorize(color_code)
- unless $nocolor
- "#{color_code}#{self}\e[0m"
- else
- self
- end
- end
-end
-
-class String
- include VcapStringExtensions
-end
+require File.expand_path("./vcap_common.rb", File.dirname(__FILE__))
DEPLOYMENT_DEFAULT_SPEC = File.join("deployments", "devbox.yml")
DEPLOYMENT_DEFAULT_NAME = "devbox"
Please sign in to comment.
Something went wrong with that request. Please try again.