calas-capitate 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
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