calas-capitate 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. data/Capfile +13 -0
  2. data/History.txt +167 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +121 -0
  5. data/README.txt +8 -0
  6. data/Rakefile +4 -0
  7. data/config/hoe.rb +72 -0
  8. data/config/requirements.rb +17 -0
  9. data/lib/capitate.rb +56 -0
  10. data/lib/capitate/cap_ext/connections.rb +105 -0
  11. data/lib/capitate/cap_ext/docs.rb +26 -0
  12. data/lib/capitate/cap_ext/namespace.rb +34 -0
  13. data/lib/capitate/cap_ext/run_via.rb +16 -0
  14. data/lib/capitate/cap_ext/task_definition.rb +22 -0
  15. data/lib/capitate/cap_ext/variables.rb +132 -0
  16. data/lib/capitate/plugins/base.rb +140 -0
  17. data/lib/capitate/plugins/build.rb +71 -0
  18. data/lib/capitate/plugins/gem.rb +24 -0
  19. data/lib/capitate/plugins/prompt.rb +109 -0
  20. data/lib/capitate/plugins/rake.rb +25 -0
  21. data/lib/capitate/plugins/script.rb +96 -0
  22. data/lib/capitate/plugins/templates.rb +113 -0
  23. data/lib/capitate/plugins/utils.rb +151 -0
  24. data/lib/capitate/plugins/yum.rb +76 -0
  25. data/lib/capitate/recipes.rb +5 -0
  26. data/lib/capitate/task_node.rb +262 -0
  27. data/lib/capitate/version.rb +9 -0
  28. data/lib/deployment/centos-5.1-64-web/install.rb +196 -0
  29. data/lib/recipes/active_record.rb +36 -0
  30. data/lib/recipes/apache.rb +47 -0
  31. data/lib/recipes/backgroundrb.rb +29 -0
  32. data/lib/recipes/centos/backgroundjob.rb +27 -0
  33. data/lib/recipes/centos/backgroundrb.rb +23 -0
  34. data/lib/recipes/centos/centos.rb +45 -0
  35. data/lib/recipes/centos/imagemagick.rb +29 -0
  36. data/lib/recipes/centos/memcached.rb +45 -0
  37. data/lib/recipes/centos/merb.rb +23 -0
  38. data/lib/recipes/centos/mongrel_cluster.rb +54 -0
  39. data/lib/recipes/centos/monit.rb +62 -0
  40. data/lib/recipes/centos/mysql.rb +25 -0
  41. data/lib/recipes/centos/nginx.rb +64 -0
  42. data/lib/recipes/centos/ruby.rb +40 -0
  43. data/lib/recipes/centos/sphinx.rb +59 -0
  44. data/lib/recipes/docs.rb +24 -0
  45. data/lib/recipes/logrotate/backgroundjob.rb +26 -0
  46. data/lib/recipes/logrotate/backgroundrb.rb +26 -0
  47. data/lib/recipes/logrotate/merb.rb +25 -0
  48. data/lib/recipes/logrotate/mongrel_cluster.rb +29 -0
  49. data/lib/recipes/logrotate/monit.rb +28 -0
  50. data/lib/recipes/logrotate/mysql.rb +26 -0
  51. data/lib/recipes/logrotate/nginx.rb +37 -0
  52. data/lib/recipes/logrotate/rails.rb +21 -0
  53. data/lib/recipes/logrotate/sphinx.rb +21 -0
  54. data/lib/recipes/logrotated.rb +61 -0
  55. data/lib/recipes/memcached.rb +26 -0
  56. data/lib/recipes/merb.rb +32 -0
  57. data/lib/recipes/monit.rb +35 -0
  58. data/lib/recipes/monit/backgroundjob.rb +38 -0
  59. data/lib/recipes/monit/backgroundrb.rb +38 -0
  60. data/lib/recipes/monit/database.rb +25 -0
  61. data/lib/recipes/monit/memcached.rb +22 -0
  62. data/lib/recipes/monit/merb.rb +58 -0
  63. data/lib/recipes/monit/mongrel_cluster.rb +85 -0
  64. data/lib/recipes/monit/mysql.rb +20 -0
  65. data/lib/recipes/monit/nginx.rb +37 -0
  66. data/lib/recipes/monit/sphinx.rb +38 -0
  67. data/lib/recipes/monit/sshd.rb +27 -0
  68. data/lib/recipes/mysql.rb +42 -0
  69. data/lib/recipes/nginx.rb +29 -0
  70. data/lib/recipes/rails.rb +71 -0
  71. data/lib/recipes/redmine.rb +38 -0
  72. data/lib/recipes/sphinx.rb +60 -0
  73. data/lib/recipes/sshd.rb +47 -0
  74. data/lib/recipes/syslogd.rb +21 -0
  75. data/lib/templates/apache/vhost.mongrel_cluster.conf.erb +46 -0
  76. data/lib/templates/backgroundjob/backgroundjob.initd.centos.erb +54 -0
  77. data/lib/templates/backgroundjob/backgroundjob.monitrc.erb +3 -0
  78. data/lib/templates/backgroundrb/backgroundrb.initd.centos.erb +58 -0
  79. data/lib/templates/backgroundrb/backgroundrb.monitrc.erb +3 -0
  80. data/lib/templates/backgroundrb/backgroundrb.yml.erb +14 -0
  81. data/lib/templates/capistrano/Capfile +22 -0
  82. data/lib/templates/logrotated/conf.erb +3 -0
  83. data/lib/templates/memcached/memcached.initd.centos.erb +58 -0
  84. data/lib/templates/memcached/memcached.monitrc.erb +4 -0
  85. data/lib/templates/memcached/memcached.yml.erb +14 -0
  86. data/lib/templates/merb/merb-no-http.monitrc.erb +13 -0
  87. data/lib/templates/merb/merb.initd.centos.erb +123 -0
  88. data/lib/templates/merb/merb.monitrc.erb +15 -0
  89. data/lib/templates/mongrel/mongrel_cluster.initd.centos.erb +94 -0
  90. data/lib/templates/mongrel/mongrel_cluster.monitrc.erb +15 -0
  91. data/lib/templates/mongrel/mongrel_cluster.yml.erb +11 -0
  92. data/lib/templates/monit/monit.cnf +34 -0
  93. data/lib/templates/monit/monit.initd.centos.erb +68 -0
  94. data/lib/templates/monit/monitrc.erb +18 -0
  95. data/lib/templates/mysql/install_db.sql.erb +6 -0
  96. data/lib/templates/mysql/my.cnf.innodb_1024.erb +122 -0
  97. data/lib/templates/mysql/my.cnf.innodb_512.erb +127 -0
  98. data/lib/templates/mysql/mysql.monitrc.erb +6 -0
  99. data/lib/templates/nginx/nginx.conf.erb +97 -0
  100. data/lib/templates/nginx/nginx.initd.centos.erb +69 -0
  101. data/lib/templates/nginx/nginx.monitrc.erb +4 -0
  102. data/lib/templates/nginx/nginx_vhost.conf.erb +101 -0
  103. data/lib/templates/nginx/nginx_vhost_generic.conf.erb +99 -0
  104. data/lib/templates/rails/database.yml.erb +7 -0
  105. data/lib/templates/redmine/email.yml.erb +10 -0
  106. data/lib/templates/ruby/fix_openssl.sh +12 -0
  107. data/lib/templates/sphinx/sphinx.conf.erb +157 -0
  108. data/lib/templates/sphinx/sphinx.monitrc.erb +4 -0
  109. data/lib/templates/sphinx/sphinx_app.initd.centos.erb +90 -0
  110. data/lib/templates/sshd/sshd.monitrc.erb +5 -0
  111. data/script/destroy +14 -0
  112. data/script/generate +14 -0
  113. data/script/txt2html +80 -0
  114. data/setup.rb +1585 -0
  115. data/tasks/deployment.rake +34 -0
  116. data/tasks/environment.rake +7 -0
  117. data/tasks/website.rake +23 -0
  118. data/test/test_helper.rb +2 -0
  119. data/test/test_plugin_upload.rb +32 -0
  120. data/test/test_recipes.rb +37 -0
  121. data/test/test_templates.rb +29 -0
  122. 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