calas-capitate 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Capfile +13 -0
- data/History.txt +167 -0
- data/License.txt +20 -0
- data/Manifest.txt +121 -0
- data/README.txt +8 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +72 -0
- data/config/requirements.rb +17 -0
- data/lib/capitate.rb +56 -0
- data/lib/capitate/cap_ext/connections.rb +105 -0
- data/lib/capitate/cap_ext/docs.rb +26 -0
- data/lib/capitate/cap_ext/namespace.rb +34 -0
- data/lib/capitate/cap_ext/run_via.rb +16 -0
- data/lib/capitate/cap_ext/task_definition.rb +22 -0
- data/lib/capitate/cap_ext/variables.rb +132 -0
- data/lib/capitate/plugins/base.rb +140 -0
- data/lib/capitate/plugins/build.rb +71 -0
- data/lib/capitate/plugins/gem.rb +24 -0
- data/lib/capitate/plugins/prompt.rb +109 -0
- data/lib/capitate/plugins/rake.rb +25 -0
- data/lib/capitate/plugins/script.rb +96 -0
- data/lib/capitate/plugins/templates.rb +113 -0
- data/lib/capitate/plugins/utils.rb +151 -0
- data/lib/capitate/plugins/yum.rb +76 -0
- data/lib/capitate/recipes.rb +5 -0
- data/lib/capitate/task_node.rb +262 -0
- data/lib/capitate/version.rb +9 -0
- data/lib/deployment/centos-5.1-64-web/install.rb +196 -0
- data/lib/recipes/active_record.rb +36 -0
- data/lib/recipes/apache.rb +47 -0
- data/lib/recipes/backgroundrb.rb +29 -0
- data/lib/recipes/centos/backgroundjob.rb +27 -0
- data/lib/recipes/centos/backgroundrb.rb +23 -0
- data/lib/recipes/centos/centos.rb +45 -0
- data/lib/recipes/centos/imagemagick.rb +29 -0
- data/lib/recipes/centos/memcached.rb +45 -0
- data/lib/recipes/centos/merb.rb +23 -0
- data/lib/recipes/centos/mongrel_cluster.rb +54 -0
- data/lib/recipes/centos/monit.rb +62 -0
- data/lib/recipes/centos/mysql.rb +25 -0
- data/lib/recipes/centos/nginx.rb +64 -0
- data/lib/recipes/centos/ruby.rb +40 -0
- data/lib/recipes/centos/sphinx.rb +59 -0
- data/lib/recipes/docs.rb +24 -0
- data/lib/recipes/logrotate/backgroundjob.rb +26 -0
- data/lib/recipes/logrotate/backgroundrb.rb +26 -0
- data/lib/recipes/logrotate/merb.rb +25 -0
- data/lib/recipes/logrotate/mongrel_cluster.rb +29 -0
- data/lib/recipes/logrotate/monit.rb +28 -0
- data/lib/recipes/logrotate/mysql.rb +26 -0
- data/lib/recipes/logrotate/nginx.rb +37 -0
- data/lib/recipes/logrotate/rails.rb +21 -0
- data/lib/recipes/logrotate/sphinx.rb +21 -0
- data/lib/recipes/logrotated.rb +61 -0
- data/lib/recipes/memcached.rb +26 -0
- data/lib/recipes/merb.rb +32 -0
- data/lib/recipes/monit.rb +35 -0
- data/lib/recipes/monit/backgroundjob.rb +38 -0
- data/lib/recipes/monit/backgroundrb.rb +38 -0
- data/lib/recipes/monit/database.rb +25 -0
- data/lib/recipes/monit/memcached.rb +22 -0
- data/lib/recipes/monit/merb.rb +58 -0
- data/lib/recipes/monit/mongrel_cluster.rb +85 -0
- data/lib/recipes/monit/mysql.rb +20 -0
- data/lib/recipes/monit/nginx.rb +37 -0
- data/lib/recipes/monit/sphinx.rb +38 -0
- data/lib/recipes/monit/sshd.rb +27 -0
- data/lib/recipes/mysql.rb +42 -0
- data/lib/recipes/nginx.rb +29 -0
- data/lib/recipes/rails.rb +71 -0
- data/lib/recipes/redmine.rb +38 -0
- data/lib/recipes/sphinx.rb +60 -0
- data/lib/recipes/sshd.rb +47 -0
- data/lib/recipes/syslogd.rb +21 -0
- data/lib/templates/apache/vhost.mongrel_cluster.conf.erb +46 -0
- data/lib/templates/backgroundjob/backgroundjob.initd.centos.erb +54 -0
- data/lib/templates/backgroundjob/backgroundjob.monitrc.erb +3 -0
- data/lib/templates/backgroundrb/backgroundrb.initd.centos.erb +58 -0
- data/lib/templates/backgroundrb/backgroundrb.monitrc.erb +3 -0
- data/lib/templates/backgroundrb/backgroundrb.yml.erb +14 -0
- data/lib/templates/capistrano/Capfile +22 -0
- data/lib/templates/logrotated/conf.erb +3 -0
- data/lib/templates/memcached/memcached.initd.centos.erb +58 -0
- data/lib/templates/memcached/memcached.monitrc.erb +4 -0
- data/lib/templates/memcached/memcached.yml.erb +14 -0
- data/lib/templates/merb/merb-no-http.monitrc.erb +13 -0
- data/lib/templates/merb/merb.initd.centos.erb +123 -0
- data/lib/templates/merb/merb.monitrc.erb +15 -0
- data/lib/templates/mongrel/mongrel_cluster.initd.centos.erb +94 -0
- data/lib/templates/mongrel/mongrel_cluster.monitrc.erb +15 -0
- data/lib/templates/mongrel/mongrel_cluster.yml.erb +11 -0
- data/lib/templates/monit/monit.cnf +34 -0
- data/lib/templates/monit/monit.initd.centos.erb +68 -0
- data/lib/templates/monit/monitrc.erb +18 -0
- data/lib/templates/mysql/install_db.sql.erb +6 -0
- data/lib/templates/mysql/my.cnf.innodb_1024.erb +122 -0
- data/lib/templates/mysql/my.cnf.innodb_512.erb +127 -0
- data/lib/templates/mysql/mysql.monitrc.erb +6 -0
- data/lib/templates/nginx/nginx.conf.erb +97 -0
- data/lib/templates/nginx/nginx.initd.centos.erb +69 -0
- data/lib/templates/nginx/nginx.monitrc.erb +4 -0
- data/lib/templates/nginx/nginx_vhost.conf.erb +101 -0
- data/lib/templates/nginx/nginx_vhost_generic.conf.erb +99 -0
- data/lib/templates/rails/database.yml.erb +7 -0
- data/lib/templates/redmine/email.yml.erb +10 -0
- data/lib/templates/ruby/fix_openssl.sh +12 -0
- data/lib/templates/sphinx/sphinx.conf.erb +157 -0
- data/lib/templates/sphinx/sphinx.monitrc.erb +4 -0
- data/lib/templates/sphinx/sphinx_app.initd.centos.erb +90 -0
- data/lib/templates/sshd/sshd.monitrc.erb +5 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +80 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +23 -0
- data/test/test_helper.rb +2 -0
- data/test/test_plugin_upload.rb +32 -0
- data/test/test_recipes.rb +37 -0
- data/test/test_templates.rb +29 -0
- metadata +198 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
module Capitate::Plugins::Build
|
2
|
+
|
3
|
+
# Configure, make, make install.
|
4
|
+
#
|
5
|
+
# ==== Options
|
6
|
+
# +name+:: Name for app
|
7
|
+
# +options+:: Options (See Make install options)
|
8
|
+
#
|
9
|
+
# ==== Make install options
|
10
|
+
# +build_dest+:: Place to build from, ex. /usr/src, defaults to /tmp/name
|
11
|
+
# +url+:: URL to download package from
|
12
|
+
# +configure_options+:: Options for ./configure
|
13
|
+
# +symlink+:: After install, list of source, dest pairs to symlink
|
14
|
+
# [ { "/usr/local/sphinx-0.9.8-rc1" => "/usr/local/sphinx" }, ... ]
|
15
|
+
# ln -s /usr/local/sphinx-0.9.8-rc1 /usr/local/sphinx
|
16
|
+
# +unpack_dir+:: Directory that is unpacked from tgz (if not matching the file name)
|
17
|
+
# +to_log+:: If specified, will redirect output to this path
|
18
|
+
#
|
19
|
+
# ==== Examples (in capistrano task)
|
20
|
+
# build.make_install("nginx", { :url => "http://sysoev.ru/nginx/nginx-0.5.35.tar.gz", ... })
|
21
|
+
#
|
22
|
+
def make_install(name, options)
|
23
|
+
install(name, options) do |dir|
|
24
|
+
configure_options = options[:configure_options] || ""
|
25
|
+
|
26
|
+
# Whether to capture build output
|
27
|
+
unless options.has_key?(:to_log)
|
28
|
+
to_log = ">> debug.log 2>&1"
|
29
|
+
else
|
30
|
+
to_log = ""
|
31
|
+
to_log = ">> #{options[:to_log]}" unless options[:to_log].blank?
|
32
|
+
end
|
33
|
+
|
34
|
+
script.run_all <<-CMDS
|
35
|
+
sh -c "cd #{dir} && ./configure #{configure_options} #{to_log}"
|
36
|
+
sh -c "cd #{dir} && make #{to_log}"
|
37
|
+
sh -c "cd #{dir} && make install #{to_log}"
|
38
|
+
CMDS
|
39
|
+
|
40
|
+
utils.ln(options[:symlink]) unless options[:symlink].blank?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Download, unpack and yield (unpacked source director).
|
45
|
+
#
|
46
|
+
# ==== Options
|
47
|
+
# +name+:: Name for app
|
48
|
+
# +options+:: Options (see Install options)
|
49
|
+
#
|
50
|
+
# ==== Install options
|
51
|
+
# +build_dest+:: Place to build from, ex. /usr/src, defaults to /tmp/name
|
52
|
+
# +url+:: URL to download package from
|
53
|
+
#
|
54
|
+
# ==== Examples (in capistrano task)
|
55
|
+
# script.make("rubygems", { :url => :url => "http://rubyforge.org/frs/download.php/29548/rubygems-1.0.1.tgz" }) do |dir|
|
56
|
+
# sudo "echo 'Running setup...' && cd #{dir} && ruby #{dir}/setup.rb"
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
def install(name, options, &block)
|
60
|
+
build_dest = options[:build_dest]
|
61
|
+
build_dest ||= "/tmp/#{name}"
|
62
|
+
url = options[:url]
|
63
|
+
|
64
|
+
script.unpack(url, build_dest, options) do |dir|
|
65
|
+
yield(dir) if block_given?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
Capistrano.plugin :build, Capitate::Plugins::Build
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Capitate::Plugins::Gem
|
2
|
+
|
3
|
+
# Install a gem.
|
4
|
+
#
|
5
|
+
# ==== Options
|
6
|
+
# +gems+:: List of gem names, or a single gem
|
7
|
+
#
|
8
|
+
# ==== Examples (in capistrano task)
|
9
|
+
# gems.install("raspell")
|
10
|
+
# gems.install([ "raspell", "foo" ])
|
11
|
+
#
|
12
|
+
def install(gems)
|
13
|
+
# If a single object, wrap in array
|
14
|
+
gems = [ gems ] unless gems.is_a?(Array)
|
15
|
+
|
16
|
+
# Install one at a time because we may need to pass install args (e.g. mysql)
|
17
|
+
gems.each do |gem|
|
18
|
+
run_via "gem install --no-rdoc --no-ri --no-verbose #{gem}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
Capistrano.plugin :gems, Capitate::Plugins::Gem
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'md5'
|
2
|
+
|
3
|
+
module Capitate::Plugins::Prompt
|
4
|
+
|
5
|
+
# Prompt.
|
6
|
+
#
|
7
|
+
# ==== Options
|
8
|
+
# :label<String>:: Label
|
9
|
+
# :options<Hash>:: An options hash (see below)
|
10
|
+
#
|
11
|
+
def ask(label, options = {}, &block)
|
12
|
+
Capistrano::CLI.ui.ask(label, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Prompt for password.
|
16
|
+
#
|
17
|
+
# ==== Options (options)
|
18
|
+
# :label<String>:: Label
|
19
|
+
# :options<Hash>:: An options hash (see below)
|
20
|
+
#
|
21
|
+
# ==== Password options
|
22
|
+
# :verify<bool>:: If true, prompt twice and verify
|
23
|
+
# :lazy<bool>:: If true, returns a Proc. _Defaults to true_
|
24
|
+
# :check_hash<String>:: If present, checks that md5 is same as password md5
|
25
|
+
# :max_attempts<Integer>:: Number of attempts to retry. _Defaults to 3_
|
26
|
+
#
|
27
|
+
def password(label, options = {})
|
28
|
+
|
29
|
+
verify = options[:verify]
|
30
|
+
lazy = options[:lazy].nil? ? true : options[:lazy]
|
31
|
+
check_hash = options[:check_hash]
|
32
|
+
max_attempts = options[:max_attempts] || 3
|
33
|
+
|
34
|
+
# Lazy
|
35
|
+
password_prompt = Proc.new {
|
36
|
+
|
37
|
+
attempts = 0
|
38
|
+
password = nil
|
39
|
+
success = true
|
40
|
+
|
41
|
+
loop do
|
42
|
+
password = Capistrano::CLI.password_prompt(label)
|
43
|
+
attempts += 1
|
44
|
+
|
45
|
+
if verify
|
46
|
+
password_verify = Capistrano::CLI.password_prompt("[VERIFY] #{label}")
|
47
|
+
if password != password_verify
|
48
|
+
logger.important "Passwords do not match"
|
49
|
+
success = false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if check_hash
|
54
|
+
if MD5.md5(password).hexdigest != check_hash
|
55
|
+
logger.important "Invalid password, try again."
|
56
|
+
success = false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
break if success
|
61
|
+
break if attempts >= max_attempts
|
62
|
+
|
63
|
+
# Reset success
|
64
|
+
success = true
|
65
|
+
end
|
66
|
+
|
67
|
+
raise "Invalid password, too many tries" unless success
|
68
|
+
|
69
|
+
password
|
70
|
+
}
|
71
|
+
|
72
|
+
return password_prompt if lazy
|
73
|
+
password_prompt.call
|
74
|
+
end
|
75
|
+
|
76
|
+
# Preview variables, and re-set them if asked to.
|
77
|
+
# Uses highline menus. Is not very intelligent.
|
78
|
+
#
|
79
|
+
# ==== Options
|
80
|
+
# :variables<Array>:: List of variables to show and verify
|
81
|
+
# :header<String>:: Menu header
|
82
|
+
# :prompt<String>:: Menu prompt
|
83
|
+
#
|
84
|
+
def preview_variables(variables, header = "Verify your settings", prompt = "Choose: ")
|
85
|
+
hl = Capistrano::CLI.ui
|
86
|
+
|
87
|
+
confirmed = false
|
88
|
+
while not confirmed do
|
89
|
+
hl.choose do |menu|
|
90
|
+
menu.header = header
|
91
|
+
menu.prompt = prompt
|
92
|
+
|
93
|
+
menu.choice("<Continue>") do
|
94
|
+
confirmed = true
|
95
|
+
end
|
96
|
+
|
97
|
+
variables.each do |variable|
|
98
|
+
menu.choice("#{variable}: #{fetch(variable)}") do
|
99
|
+
new_setting = ask("Set #{variable}: ") { |q| q.default = fetch(variable) }
|
100
|
+
set variable, new_setting
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
Capistrano.plugin :prompt, Capitate::Plugins::Prompt
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Capitate::Plugins::Rake
|
2
|
+
|
3
|
+
# Execute rake tasks.
|
4
|
+
#
|
5
|
+
# ==== Options
|
6
|
+
# +tasks+:: List of task names, or a single task
|
7
|
+
#
|
8
|
+
# ==== Examples (in capistrano task)
|
9
|
+
# rake.run("db:migrate")
|
10
|
+
# rake.run([ "db:create", "db:migrate" ])
|
11
|
+
# rake.run("db:bootstrap AUTO_ACCEPT=true")
|
12
|
+
#
|
13
|
+
def run(tasks)
|
14
|
+
# If a single object, wrap in array
|
15
|
+
tasks = [ tasks ] unless tasks.is_a?(Array)
|
16
|
+
|
17
|
+
# Install one at a time because we may need to pass install args (e.g. AUTO_ACCEPT=true)
|
18
|
+
tasks.each do |task|
|
19
|
+
run_via "/usr/bin/env rake RAILS_ENV=#{rails_env} #{task}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
Capistrano.plugin :rake, Capitate::Plugins::Rake
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Capitate::Plugins::Script
|
2
|
+
|
3
|
+
# Run (sh) script. If script has .erb extension it will evaluate it.
|
4
|
+
#
|
5
|
+
# ==== Options
|
6
|
+
# +script+:: Name of sh file (relative to templates dir)
|
7
|
+
# +override_binding++:: Binding to override, otherwise defaults to current (task) context
|
8
|
+
#
|
9
|
+
# ==== Examples
|
10
|
+
# script.sh("ruby/openssl_fix.sh")
|
11
|
+
#
|
12
|
+
def sh(script, override_binding = nil)
|
13
|
+
|
14
|
+
if File.extname(script) == ".erb"
|
15
|
+
name = script[0...script.length-4]
|
16
|
+
dest = "/tmp/cap/#{name}"
|
17
|
+
run_via "mkdir -p #{File.dirname(dest)}"
|
18
|
+
put template.load(script, override_binding || binding), dest
|
19
|
+
else
|
20
|
+
name = script
|
21
|
+
dest = "/tmp/cap/#{name}"
|
22
|
+
run_via "mkdir -p #{File.dirname(dest)}"
|
23
|
+
put template.load(script), dest
|
24
|
+
end
|
25
|
+
|
26
|
+
# If want verbose, -v
|
27
|
+
run_all <<-CMDS
|
28
|
+
sh -v #{dest}
|
29
|
+
rm -rf #{File.dirname(dest)}
|
30
|
+
CMDS
|
31
|
+
end
|
32
|
+
|
33
|
+
# Download and unpack URL.
|
34
|
+
# Yields path to unpacked source.
|
35
|
+
#
|
36
|
+
# ==== Options
|
37
|
+
# +url+:: URL to download
|
38
|
+
# +dest+:: Destination directory
|
39
|
+
# +options+:: Options (see Unpack options)
|
40
|
+
#
|
41
|
+
# ==== Unpack options
|
42
|
+
# +clean+:: If true will remove the unpacked directory. _Defaults to true_
|
43
|
+
# +unpack_dir+:: Directory that is unpacked from tgz (if not matching the file name)
|
44
|
+
#
|
45
|
+
# ==== Examples
|
46
|
+
# script.unpack("http://rubyforge.org/frs/download.php/29548/rubygems-1.0.1.tgz", "/tmp/rubygems") do
|
47
|
+
# sudo "ruby setup.rb"
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
def unpack(url, dest, options, &block)
|
51
|
+
file = url.split("/").last
|
52
|
+
|
53
|
+
# TODO: Support other types
|
54
|
+
if file !~ /\.tar\.gz\Z|\.tgz\Z/
|
55
|
+
raise "Can't unpack this file: #{file}; only support tar.gz and tgz formats"
|
56
|
+
end
|
57
|
+
|
58
|
+
options[:clean] = true if options[:clean].nil?
|
59
|
+
unpack_dir = options[:unpack_dir]
|
60
|
+
clean = options[:clean]
|
61
|
+
|
62
|
+
unpack_dir ||= file.gsub(/\.tar\.gz|\.tgz/, "")
|
63
|
+
|
64
|
+
http_get_method = fetch(:http_get_method, "wget -nv")
|
65
|
+
|
66
|
+
run_all <<-CMDS
|
67
|
+
sh -c "mkdir -p #{dest} && cd #{dest} && #{http_get_method} #{url}"
|
68
|
+
sh -c "cd #{dest} && tar zxf #{file}"
|
69
|
+
CMDS
|
70
|
+
|
71
|
+
if block_given?
|
72
|
+
yield("#{dest}/#{unpack_dir}")
|
73
|
+
run_via "rm -f #{dest}/#{file}"
|
74
|
+
run_via "rm -rf #{dest}" if clean
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Run all commands (separated by newlines).
|
79
|
+
#
|
80
|
+
# Uses run_via to execute, so will use <tt>run</tt> or <tt>sudo</tt>
|
81
|
+
# depending on the current <tt>:run_method</tt>
|
82
|
+
#
|
83
|
+
# ==== Options
|
84
|
+
# +cmds+:: Commands (separated by newlines)
|
85
|
+
# +options+:: See Capistrano invoke_command options
|
86
|
+
#
|
87
|
+
def run_all(cmds, options = {}, &block)
|
88
|
+
cmds.split("\n").each do |cmd|
|
89
|
+
cmd = cmd.gsub(/^\s+/, "")
|
90
|
+
run_via(cmd, options, &block)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
Capistrano.plugin :script, Capitate::Plugins::Script
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Capitate::Plugins::Templates
|
2
|
+
|
3
|
+
# Load template. If the extension is .erb will be evaluated with binding.
|
4
|
+
#
|
5
|
+
# You can add to the list of places we search for templates by setting:
|
6
|
+
#
|
7
|
+
# set :templates_dirs, [ "path/to/templates1", "/path/to/templates2" ]
|
8
|
+
#
|
9
|
+
# It looks for the template from:
|
10
|
+
# * the <tt>:templates_dirs</tt> setting (if set)
|
11
|
+
# * the current directory
|
12
|
+
# * the <tt>:project_root</tt> setting (if set)
|
13
|
+
# * the gem templates path
|
14
|
+
#
|
15
|
+
# ==== Options
|
16
|
+
# +path+:: If starts with '/', absolute path, otherwise relative path to templates dir
|
17
|
+
# +override_binding+:: Binding to override, otherwise uses current (task) binding
|
18
|
+
#
|
19
|
+
# ==== Examples
|
20
|
+
# template.load("memcached/memcached.monitrc.erb") => "This is the text of eval'ed template found at ..."
|
21
|
+
#
|
22
|
+
# put template.load("memcached/memcached.monitrc.erb"), "/tmp/memcached.monitrc" # Uploads eval'ed template to remote /tmp/ directory
|
23
|
+
#
|
24
|
+
def load(path, override_binding = nil)
|
25
|
+
template_dirs_found = template_dirs.select { |dir| File.exist?("#{dir}/#{path}") }
|
26
|
+
|
27
|
+
# Not found anywhere, throw error
|
28
|
+
if template_dirs_found.empty?
|
29
|
+
raise "\n\nTemplate not found: #{path}\n\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Use first
|
33
|
+
template_path = template_dirs_found.first + "/#{path}"
|
34
|
+
|
35
|
+
logger.info "reading #{template_path}"
|
36
|
+
template_data = IO.read(template_path)
|
37
|
+
|
38
|
+
if File.extname(template_path) == ".erb"
|
39
|
+
template = ERB.new(template_data)
|
40
|
+
logger.info "evaluating #{template_path}"
|
41
|
+
template_data = template.result(override_binding || binding)
|
42
|
+
end
|
43
|
+
template_data
|
44
|
+
end
|
45
|
+
|
46
|
+
# Write template at (relative path) with binding to LOCAL destination path.
|
47
|
+
#
|
48
|
+
# ==== Options
|
49
|
+
# +template_path+:: Path to template relative to templates path
|
50
|
+
# +dest_path+:: Local destination path to write to
|
51
|
+
# +overwrite_binding+:: Binding
|
52
|
+
# +overwrite+:: Force overwrite
|
53
|
+
# +verbose+:: Verbose output
|
54
|
+
#
|
55
|
+
# ==== Examples
|
56
|
+
# template.write("config/templates/sphinx.conf.erb", "config/sphinx.conf")
|
57
|
+
#
|
58
|
+
def write(template_path, dest_path, override_binding = nil, overwrite = false, verbose = true)
|
59
|
+
# This is gnarly!
|
60
|
+
relative_dest_path = Pathname.new(File.expand_path(dest_path)).relative_path_from(Pathname.new(File.expand_path(".")))
|
61
|
+
|
62
|
+
if !overwrite && File.exist?(dest_path)
|
63
|
+
puts "%10s %-40s (skipped)" % [ "create", relative_dest_path ] if verbose
|
64
|
+
return
|
65
|
+
end
|
66
|
+
|
67
|
+
puts "%10s %-40s" % [ "create", relative_dest_path ] if verbose
|
68
|
+
template_data = load(template_path, override_binding)
|
69
|
+
File.open(dest_path, "w") { |file| file.puts(load(template_path, override_binding)) }
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
protected
|
74
|
+
|
75
|
+
# Load all possible places for templates.
|
76
|
+
#
|
77
|
+
# Returns:
|
78
|
+
# * the <tt>:templates_dirs</tt> setting (if set)
|
79
|
+
# * the current directory
|
80
|
+
# * the <tt>:project_root</tt> setting (if set)
|
81
|
+
# * the gem templates path
|
82
|
+
#
|
83
|
+
def template_dirs
|
84
|
+
@template_dirs ||= begin
|
85
|
+
template_dirs = []
|
86
|
+
template_dirs += fetch(:templates_dirs) if exists?(:templates_dirs)
|
87
|
+
template_dirs << "."
|
88
|
+
template_dirs << project_root if exists?(:project_root)
|
89
|
+
template_dirs << gem_templates_root
|
90
|
+
template_dirs
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Get the absolute base templates path.
|
95
|
+
def gem_templates_root
|
96
|
+
File.expand_path(File.dirname(__FILE__) + "/../../templates")
|
97
|
+
end
|
98
|
+
|
99
|
+
# Get full template path from relative path.
|
100
|
+
#
|
101
|
+
# ==== Options
|
102
|
+
# +template_path+:: Relative path
|
103
|
+
#
|
104
|
+
# ==== Examples
|
105
|
+
# gem_template_path("monit/monit.cnf") => /usr/lib/..../capitate/lib/templates/monit/monit.cnf
|
106
|
+
#
|
107
|
+
def gem_template_path(template_path)
|
108
|
+
File.join(gem_templates_root, template_path)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
Capistrano.plugin :template, Capitate::Plugins::Templates
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module Capitate::Plugins::Utils
|
2
|
+
|
3
|
+
# Symlink source to dest
|
4
|
+
#
|
5
|
+
# ==== Options
|
6
|
+
# +args+:: Arguments. If argument is hash, then key is symlinked to value.
|
7
|
+
#
|
8
|
+
# ==== Examples
|
9
|
+
# utils.ln("src/foo" => "dest/foo") # Run: ln -nfs src/foo dest/foo
|
10
|
+
# utils.ln("src/foo" => "dest/foo", "src/bar" => "dest/bar") # Links both
|
11
|
+
#
|
12
|
+
def ln(*args)
|
13
|
+
args.each do |arg|
|
14
|
+
if arg.is_a?(Hash)
|
15
|
+
arg.each do |src, dest|
|
16
|
+
run_via "ln -nfs #{src} #{dest}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Delete file.
|
23
|
+
#
|
24
|
+
# ==== Options
|
25
|
+
# +path+:: Path to delete
|
26
|
+
#
|
27
|
+
def rm(path)
|
28
|
+
run_via "rm #{path}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Delete file (recursive/force)
|
32
|
+
#
|
33
|
+
# ==== Options
|
34
|
+
# +path+:: Path to delete
|
35
|
+
#
|
36
|
+
def rm_rf(path)
|
37
|
+
run_via "rm -rf #{path}"
|
38
|
+
end
|
39
|
+
|
40
|
+
# Load template and install it.
|
41
|
+
# Removes temporary files during transfer and ensures desination directory is created before install.
|
42
|
+
#
|
43
|
+
# See template plugin for where template paths are loaded from.
|
44
|
+
#
|
45
|
+
# ==== Options
|
46
|
+
# +template_path+:: Path to template
|
47
|
+
# +destination+:: Remote path to evaluated template
|
48
|
+
# +options+:: Options (see Install template options)
|
49
|
+
#
|
50
|
+
# ==== Install template options
|
51
|
+
# +user+:: User to install (-o). Defaults to *root*.
|
52
|
+
# +mode+:: Mode to install file (-m)
|
53
|
+
#
|
54
|
+
# ==== Example
|
55
|
+
# utils.install_template("monit/memcached.monitrc.erb", "/etc/monit/memcached.monitrc", :user => "root", :mode => "600")
|
56
|
+
#
|
57
|
+
def install_template(template_path, destination, options = {})
|
58
|
+
# Truncate extension
|
59
|
+
tmp_file_path = template_path.gsub("/", "_").gsub(/.erb$/, "")
|
60
|
+
tmp_path = "/tmp/#{tmp_file_path}"
|
61
|
+
|
62
|
+
options[:user] ||= "root"
|
63
|
+
|
64
|
+
install_options = []
|
65
|
+
install_options << "-o #{options[:user]}"
|
66
|
+
install_options << "-m #{options[:mode]}" if options.has_key?(:mode)
|
67
|
+
|
68
|
+
put template.load(template_path), tmp_path
|
69
|
+
# TOOD: Ensure directory exists? mkdir -p #{File.dirname(destination)}
|
70
|
+
run_via "install #{install_options.join(" ")} #{tmp_path} #{destination} && rm -f #{tmp_path}"
|
71
|
+
end
|
72
|
+
|
73
|
+
# Grep file for regex. Returns true if found, false otherwise.
|
74
|
+
#
|
75
|
+
# ==== Options
|
76
|
+
# +grep+:: Regular expression
|
77
|
+
# +path+:: Path to file
|
78
|
+
#
|
79
|
+
# ==== Example
|
80
|
+
# utils.egrep("^mail.\\*", "/etc/syslog.conf") => true
|
81
|
+
#
|
82
|
+
def egrep(grep, path)
|
83
|
+
found = true
|
84
|
+
run_via %{egrep '#{grep}' #{path} || echo $?} do |channel, stream, data|
|
85
|
+
if data =~ /^(\d+)/
|
86
|
+
if $1.to_i > 0
|
87
|
+
logger.trace "Not found"
|
88
|
+
found = false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
found
|
93
|
+
end
|
94
|
+
|
95
|
+
# Check if file exists.
|
96
|
+
#
|
97
|
+
# ==== Options
|
98
|
+
# +path+:: Path to file
|
99
|
+
#
|
100
|
+
def exist?(path)
|
101
|
+
found = true
|
102
|
+
run_via "head -1 #{path} >/dev/null 2>&1 || echo $?" do |channel, stream, data|
|
103
|
+
if data =~ /^(\d+)/
|
104
|
+
if $1.to_i > 0
|
105
|
+
logger.trace "Not found"
|
106
|
+
found = false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
found
|
111
|
+
end
|
112
|
+
|
113
|
+
# Get the hostname of the remote server
|
114
|
+
#
|
115
|
+
# ==== Example
|
116
|
+
# utils.hostname => "localhost.localdomain"
|
117
|
+
#
|
118
|
+
def hostname
|
119
|
+
hostname = nil
|
120
|
+
run "hostname" do |channel, stream, data|
|
121
|
+
hostname = data.chomp
|
122
|
+
end
|
123
|
+
hostname
|
124
|
+
end
|
125
|
+
|
126
|
+
# Append data to a file.
|
127
|
+
# Optionally check that it exists before adding.
|
128
|
+
#
|
129
|
+
# ==== Options
|
130
|
+
# +path+:: Path to file to append to
|
131
|
+
# +data+:: String data to append
|
132
|
+
# +check+:: If not nil, will check to see if egrep matches this regex and will not re-append
|
133
|
+
# +left_strip+:: If true (default), remove whitespace before lines
|
134
|
+
# +should_exist+:: If true (default), raise error if file does not exist
|
135
|
+
#
|
136
|
+
def append_to(path, data, check = nil, left_strip = true, should_exist = true)
|
137
|
+
# If checking and found expression then abort append
|
138
|
+
return if check and egrep(check, path)
|
139
|
+
|
140
|
+
# If should exist and doesn't then abort append
|
141
|
+
raise "Can't append to file. File should exist: #{path}" if should_exist and !exist?(path)
|
142
|
+
|
143
|
+
data.split("\n").each do |line|
|
144
|
+
line = line.gsub(/^\s+/, "") if left_strip
|
145
|
+
run_via "echo '#{line}' >> #{path}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
Capistrano.plugin :utils, Capitate::Plugins::Utils
|