labs-vcap/dev_setup/lib/chefsolo_launch.rb

152 строки
5.5 KiB
Ruby
Executable File

#!/usr/bin/env ruby
require 'rubygems'
require 'json'
require 'tempfile'
require 'uri'
require 'fileutils'
require 'optparse'
require 'yaml'
require 'pp'
$LOAD_PATH.unshift(File.dirname(__FILE__))
require File.expand_path('vcap_defs', File.dirname(__FILE__))
require File.expand_path('job_manager', File.dirname(__FILE__))
script_dir = File.expand_path(File.dirname(__FILE__))
cloudfoundry_home = Deployment.get_cloudfoundry_home
cloudfoundry_domain = Deployment.get_cloudfoundry_domain
deployment_spec = File.expand_path(File.join(script_dir, "..", DEPLOYMENT_DEFAULT_SPEC))
chef_log_level = 'info'
args = ARGV.dup
opts_parser = OptionParser.new do |opts|
opts.on('--config CONFIG_FILE', '-c CONFIG_FILE') { |file| deployment_spec = File.expand_path(file.to_s) }
opts.on('--dir CLOUDFOUNDRY_HOME', '-d CLOUDFOUNDRY_HOME') { |dir| cloudfoundry_home = File.expand_path(dir.to_s) }
opts.on('--domain CLOUDFOUNDRY_DOMAIN', '-D CLOUDFOUNDRY_DOMAIN') { |domain| cloudfoundry_domain = domain }
opts.on('--log_level LEVEL', '-l LEVEL') { |level| chef_log_level = level }
end
args = opts_parser.parse!(args)
unless File.exists?(deployment_spec)
puts "Cannot find config file #{deployment_spec}"
puts "Usage: #{$0} -c config_file -d cloud_foundry_home"
exit 1
end
spec = YAML.load_file(deployment_spec)
# Fill in default config attributes
spec["deployment"] ||= {}
spec["deployment"]["name"] ||= DEPLOYMENT_DEFAULT_NAME
spec["deployment"]["user"] ||= ENV["USER"]
spec["deployment"]["group"] ||= `id -g`.strip
spec["deployment"]["domain"] ||= cloudfoundry_domain
spec["cloudfoundry"] ||= {}
spec["cloudfoundry"]["home"] ||= cloudfoundry_home
spec["cloudfoundry"]["home"] = File.expand_path(spec["cloudfoundry"]["home"])
if cloudfoundry_home != Deployment.get_cloudfoundry_home && cloudfoundry_home != spec["cloudfoundry"]["home"]
puts "Conflicting values for cloudfoundry home directory, command line argument says #{cloudfoundry_home} but config file says #{spec["cloudfoundry"]["home"]}"
exit 1
end
# convenience variables
cloudfoundry_home = spec["cloudfoundry"]["home"]
deployment_name = spec["deployment"]["name"]
deployment_config_path = Deployment.get_config_path(deployment_name, cloudfoundry_home)
puts "Installing deployment #{deployment_name}, cloudfoundry home dir is #{cloudfoundry_home}"
# Resolve all job dependencies
vcap_run_list = {}
job_specs, job_roles, vcap_run_list["components"] = JobManager.go(spec)
if job_roles.nil?
puts "You haven't specified any install jobs"
exit 0
end
# Prepare the chef run list
run_list = []
job_roles.each do |role|
run_list << "role[#{role}]"
end
spec["run_list"] = run_list
# Merge the job specs
spec.merge!(job_specs)
# Deploy
Dir.mktmpdir do |tmpdir|
# Create chef-solo config file
File.open(File.join(tmpdir, "solo.rb"), "w") do |f|
f.puts("cookbook_path \"#{File.expand_path(File.join("..", "cookbooks"), script_dir)}\"")
f.puts("role_path \"#{File.expand_path(File.join("..", "roles"), script_dir)}\"")
%w[ http_proxy https_proxy].each do |proxy|
if ENV[proxy]
uri = URI.parse(ENV[proxy])
f.puts("#{proxy} \"#{uri.scheme}://#{uri.host}:#{uri.port}\"")
if uri.userinfo
f.puts("http_proxy_user \"#{uri.userinfo.split(":")[0]}\"")
f.puts("http_proxy_pass \"#{uri.userinfo.split(":")[1]}\"")
end
end
end
if ENV["no_proxy"]
f.puts("no_proxy \"#{ENV["no_proxy"]}\"")
end
end
# Create chef-solo attributes file
json_attribs = File.join(tmpdir, "solo.json")
File.open(json_attribs, "w") { |f| f.puts(spec.to_json) }
# Save the chef-solo attributes to a file in /tmp, useful for debugging
File.open(File.join("", "tmp", "solo.json"), "w") { |f| f.puts(spec.to_json) }
id = fork do
proxy_env = []
# Setup proxy
%w(http_proxy https_proxy no_proxy).each do |env_var|
if ENV[env_var] || ENV[env_var.upcase]
[env_var, env_var.upcase].each do |v|
proxy = "#{v}=#{ENV[v.downcase] || ENV[v.upcase]}"
proxy_env << proxy
end
end
end
exec("sudo env #{proxy_env.join(" ")} chef-solo -c #{File.join(tmpdir, "solo.rb")} -j #{json_attribs} -l #{chef_log_level}")
end
pid, status = Process.waitpid2(id)
if status.exitstatus != 0
exit status.exitstatus
end
# save the config of this deployment
File.open(Deployment.get_config_file(deployment_config_path), "w") { |f| f.puts(spec.to_json) }
# save the list of components that should be started for this deployment
File.open(Deployment.get_vcap_config_file(deployment_config_path), "w") { |f| f.puts(vcap_run_list.to_json) }
# save the deployment target for later use
Deployment.save_deployment_target(deployment_name, cloudfoundry_home)
puts "\nDeployment Info".green
puts "***************".green
puts "* Status:" + " Success".green
vcap_dev_path = File.expand_path(File.join(script_dir, "..", "bin", "vcap_dev"))
puts "* Config files:" + " #{deployment_config_path}"
puts "* Deployment name:" + " #{deployment_name}"
puts "*" + " Note:".red
puts " * If you want to run ruby/vmc please source the profile #{Deployment.get_deployment_profile_file}"
puts " * If you want to run cloudfoundry components by hand please source the profile #{Deployment.get_local_deployment_run_profile}"
args = ""
args << (deployment_name != DEPLOYMENT_DEFAULT_NAME ? " -n #{deployment_name}" : "")
args << (cloudfoundry_home != Deployment.get_cloudfoundry_home ? " -d #{cloudfoundry_home}" : "")
args << " start"
puts "* Command to run cloudfoundry:" + " #{vcap_dev_path} #{args.strip}".green
end