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,105 @@
1
+ # Patch to add ability to clear sessions/connections.
2
+ module Capitate
3
+ module CapExt
4
+ module Connections
5
+
6
+ # Set the user to something new (but save the old user; reset_user will set it back).
7
+ # Takes care of invalidating current connections. Will force a re-login.
8
+ #
9
+ # ==== Options
10
+ # +new_user+:: User to become
11
+ #
12
+ # ==== Examples
13
+ # set_user("nginx")
14
+ # # Do something as user nginx
15
+ #
16
+ def set_user(new_user)
17
+ previous_user = fetch(:user)
18
+
19
+ return if previous_user == new_user
20
+ set :previous_user, previous_user
21
+
22
+ set :user, new_user
23
+ clear_sessions
24
+ end
25
+
26
+ # Reset to the old user.
27
+ # Takes care of invalidating current connections. Will force a re-login.
28
+ #
29
+ # ==== Examples
30
+ # # User is "root"
31
+ # set_user("nginx")
32
+ # # Do something as user nginx
33
+ # reset_user
34
+ # # User is now root
35
+ #
36
+ def reset_user
37
+ return unless exists?(:previous_user)
38
+ set :user, fetch(:previous_user)
39
+ unset :previous_user
40
+ clear_sessions
41
+ end
42
+
43
+ # Perform action as a different user. Yields the previous user to the block.
44
+ #
45
+ # ==== Options
46
+ # +new_user+:: User to become
47
+ #
48
+ # ==== Examples
49
+ # new_user("nginx") do |old_user|
50
+ # # Do something as user nginx
51
+ # end
52
+ # # Now as user old_user
53
+ #
54
+ def with_user(new_user, &block)
55
+ begin
56
+ set_user(new_user)
57
+ yield exists?(:previous_user) ? fetch(:previous_user) : nil
58
+ ensure
59
+ reset_user
60
+ end
61
+
62
+ clear_sessions
63
+ end
64
+
65
+ # Close all open sessions, and will force user to re-login.
66
+ def clear_sessions
67
+ sessions.each do |key, session|
68
+ logger.info "Closing: #{key}"
69
+ session.close
70
+ end
71
+ sessions.clear
72
+ reset_password
73
+ end
74
+
75
+ # Reset the password.
76
+ # Display the current user that is asking for the password.
77
+ def reset_password
78
+ set :password, Proc.new {
79
+ Capistrano::CLI.password_prompt("Password (for user: #{user}): ")
80
+ }
81
+ end
82
+
83
+ end
84
+ end
85
+ end
86
+
87
+ # Debug connections
88
+ class Capistrano::SSH
89
+
90
+ class << self
91
+
92
+ def connect_with_logging(server, options={}, &block)
93
+ @connect_mutex ||= Mutex.new
94
+
95
+ @connect_mutex.synchronize do
96
+ puts "--- Connecting to #{server} with user: #{server.user || options[:user]}"
97
+ end
98
+
99
+ connect_without_logging(server, options, &block)
100
+ end
101
+
102
+ alias_method_chain :connect, :logging
103
+
104
+ end
105
+ end
@@ -0,0 +1,26 @@
1
+ module Capitate
2
+
3
+ module CapExt
4
+
5
+ module Docs
6
+
7
+ # Get link to github source, so we can refer to recipe code.
8
+ #
9
+ # ==== Options
10
+ # +recipe+:: Recipe path, probably use __FILE__
11
+ #
12
+ # ==== Examples
13
+ # # In a lib/recipes/foo/foo.rb
14
+ # link_to_source(__FILE__) => "http://github.com/gabriel/capitate/tree/master/lib/recipes/foo/foo.rb"
15
+ #
16
+ def link_to_source(recipe_path)
17
+ full_path = File.expand_path(recipe_path)
18
+ project_path = File.expand_path(File.dirname(__FILE__) + "/../../../")
19
+ "http://github.com/gabriel/capitate/tree/master#{full_path.sub(project_path, "")}"
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,34 @@
1
+ module Capitate
2
+
3
+ module CapExt
4
+
5
+ module Namespace
6
+
7
+ def self.included(base) #:nodoc:
8
+ unless base.method_defined?(:task_without_capitate)
9
+ base.send :alias_method, :task_without_capitate, :task
10
+ base.send :alias_method, :task, :task_with_capitate
11
+ end
12
+ end
13
+
14
+ def task_arg(name, desc, options = {})
15
+ @next_task_arguments ||= []
16
+ @next_task_arguments << options.merge({ :name => name, :desc => desc })
17
+ end
18
+
19
+ def task_with_capitate(name, options={}, &block)
20
+ task_without_capitate(name, options) do
21
+ find_task(name).setup_defaults
22
+ block.call
23
+ end
24
+ task_def = find_task(name)
25
+ task_def.arguments = @next_task_arguments
26
+ @next_task_arguments = nil
27
+ task_def
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,16 @@
1
+ module Capitate::CapExt::RunVia
2
+
3
+ # Invoke command with current run_method setting.
4
+ #
5
+ # Chooses +sudo+ or +run+ based on <tt>:run_method</tt> setting.
6
+ #
7
+ # ==== Options
8
+ # +cmd+:: Command to run
9
+ # +options+:: Options (see invoke_command options)
10
+ #
11
+ def run_via(cmd, options = {}, &block)
12
+ options[:via] = fetch(:run_method, :sudo) unless options.has_key?(:via)
13
+ invoke_command(cmd, options, &block)
14
+ end
15
+
16
+ end
@@ -0,0 +1,22 @@
1
+ module Capitate
2
+
3
+ module CapExt
4
+
5
+ module TaskDefinition
6
+
7
+ attr_accessor :arguments
8
+
9
+ def setup_defaults
10
+ return if arguments.blank?
11
+
12
+ arguments.each do |arg|
13
+ namespace.fetch_or_default(arg[:name], arg[:default]) if arg.has_key?(:default)
14
+ namespace.fetch_or_set(arg[:name], arg[:set]) if arg.has_key?(:set)
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,132 @@
1
+ module Capitate
2
+ module CapExt
3
+ module Variables
4
+
5
+ def self.included(base) #:nodoc:
6
+ base.send :alias_method, :fetch_without_capitate, :fetch
7
+ base.send :alias_method, :fetch, :fetch_with_capitate
8
+ end
9
+
10
+ # Fetch.
11
+ # Displays usage message from recipe docs if variable not found.
12
+ #
13
+ # See capistrano fetch for usage info.
14
+ #
15
+ def fetch_with_capitate(variable, *args)
16
+ begin
17
+ fetch_without_capitate(variable, *args)
18
+ rescue IndexError
19
+ message = capitate.usage(variable)
20
+
21
+ if message.blank?
22
+ message = <<-EOS
23
+
24
+ Please set :#{variable} variable in your Capfile or deploy.rb
25
+
26
+ EOS
27
+ end
28
+
29
+ raise IndexError, "\n#{message}"
30
+ end
31
+ end
32
+
33
+ # Fetch or set and return default.
34
+ #
35
+ # ==== Options
36
+ # +variable+:: Variable to fetch
37
+ # +default+:: Default value if not set
38
+ # +args+:: ?
39
+ #
40
+ # ==== Examples
41
+ # fetch_or_default(:memcached_port, 11211) => 11211
42
+ # # Any calls to fetch(memcached_port) in the future will return this value 11211 (unless overriden)
43
+ #
44
+ def fetch_or_default(variable, default, *args)
45
+ if exists?(variable)
46
+ fetch(variable, *args)
47
+ else
48
+ set variable, default
49
+ default
50
+ end
51
+ end
52
+
53
+ # Fetch or set and fetch any default variable listed.
54
+ #
55
+ # ==== Options
56
+ # +variable+:: Variable to fetch
57
+ # +variables+:: List if variables to try in order
58
+ #
59
+ # ==== Examples
60
+ # fetch_or_set(:sphinx_db_host, :db_host)
61
+ #
62
+ def fetch_or_set(variable, *default_variables)
63
+ return fetch(variable) if exists?(variable)
64
+
65
+ default_variables.each do |default_variable|
66
+ if exists?(default_variable)
67
+ value = fetch(default_variable)
68
+ set variable, value
69
+ return value
70
+ end
71
+ end
72
+ nil
73
+ end
74
+
75
+ # Fetch roles with name and options.
76
+ # I don't actually use this.
77
+ #
78
+ # ==== Options
79
+ # +name+:: Role name to look for
80
+ # +options+:: Options to match on, e.g. :primary => true
81
+ #
82
+ # ==== Examples
83
+ # fetch_roles(:db) => [ "10.0.6.71", "10.0.6.72" ]
84
+ # fetch_roles(:db, :primary => true) => [ "10.0.6.71" ]
85
+ #
86
+ def fetch_roles(name, options = {})
87
+ matched_roles = Set.new
88
+
89
+ roles.each do |role_info|
90
+ role_name = role_info.first
91
+
92
+ next unless role_name == name
93
+
94
+ role = role_info.last
95
+ role.each do |server|
96
+
97
+ abort = false
98
+ options.each do |k, v|
99
+ unless server.options[k] == v
100
+ abort = true
101
+ break
102
+ end
103
+ end
104
+ next if abort
105
+
106
+ matched_roles << server
107
+ end
108
+ end
109
+ matched_roles.to_a
110
+ end
111
+
112
+ # Fetch first role with name and options.
113
+ #
114
+ # ==== Options
115
+ # +name+:: Role name to look for
116
+ # +options+:: Options to match on, e.g. :primary => true
117
+ #
118
+ # ==== Examples
119
+ # fetch_roles(:db) => [ "10.0.6.71", "10.0.6.72" ]
120
+ # fetch_roles(:db, :primary => true) => [ "10.0.6.71" ]
121
+ #
122
+ def fetch_role(name, options = {})
123
+ matched = fetch_roles(name, options)
124
+ return matched.first if matched
125
+ nil
126
+ end
127
+
128
+ end
129
+ end
130
+
131
+ end
132
+
@@ -0,0 +1,140 @@
1
+ require 'erb'
2
+ require 'yaml'
3
+
4
+ # Capitate base capistrano plugin
5
+ module Capitate::Plugins::Base
6
+
7
+ # Project root. Fetch from :project_root, or fall back to RAILS_ROOT.
8
+ def root
9
+ return fetch(:project_root) if exists?(:project_root)
10
+ RAILS_ROOT
11
+ end
12
+
13
+ # Path relative to project root.
14
+ #
15
+ # To set the project root:
16
+ #
17
+ # set :project_root, "path/to/project" in Capfile.
18
+ #
19
+ # ==== Options
20
+ # +path+:: Relative path
21
+ # +check_exist+:: Whether to check its existence and throw error if not found
22
+ #
23
+ # ==== Examples
24
+ # relative_to_root("config/foo.yml") => "path/to/project/config/foo.yml"
25
+ #
26
+ def relative_to_root(path = nil, check_exist = false)
27
+ if path
28
+ root_path = File.join(root, path)
29
+ else
30
+ root_path = root
31
+ end
32
+
33
+ # Check for file existance
34
+ if check_exist and !File.exist?(root_path)
35
+ raise <<-EOS
36
+
37
+ File not found: #{File.expand_path(root_path)}
38
+
39
+ This is loaded for the capitate plugin. View the README in:
40
+ #{File.expand_path(File.dirname(__FILE__) + "/../doc/README")}
41
+ EOS
42
+ end
43
+
44
+ root_path
45
+ end
46
+
47
+ # Usage for current task.
48
+ #
49
+ # ==== Options
50
+ # +variable+:: Missing variable setting (to display as not set)
51
+ #
52
+ # ==== Examples
53
+ # usage(:gem_list) => "Description from task definition."
54
+ #
55
+ def usage(variable = nil)
56
+ message = ""
57
+
58
+ if variable
59
+ message += <<-EOS
60
+
61
+ Error: :#{variable} not set.
62
+ EOS
63
+ end
64
+
65
+ if current_task
66
+ message += <<-EOS
67
+
68
+ Usage:
69
+
70
+ #{indent_doc(current_task.desc)}
71
+
72
+ EOS
73
+ end
74
+ message
75
+ end
76
+
77
+ # Indent string block.
78
+ #
79
+ # ==== Options
80
+ # +s+:: String block
81
+ # +amount+:: Amount to indent
82
+ #
83
+ def indent_doc(s, amount = 4)
84
+ return nil if s.blank?
85
+ indentation = (0..amount).collect { |n| " " }.join
86
+ s.split("\n").collect { |sp| "#{indentation}#{sp}"}.join("\n")
87
+ end
88
+
89
+ # Unindent.
90
+ #
91
+ # Lifted from capistrano bin/capify
92
+ #
93
+ # ==== Options
94
+ # +string+:: String to unindent
95
+ #
96
+ def unindent(string)
97
+ return "" if string.blank?
98
+ if string =~ /\A(\s*)/
99
+ amount = $1.length
100
+ return string.strip.gsub(/^#{$1}/, "")
101
+ end
102
+ string
103
+ end
104
+
105
+ # Load all tasks into an array.
106
+ def load_all_tasks
107
+ tasks = []
108
+ top.namespaces.each do |namespace|
109
+ load_tasks(namespace, tasks)
110
+ end
111
+ tasks
112
+ end
113
+
114
+ # Build a task tree, consisting of task nodes.
115
+ def task_tree
116
+ top_node = Capitate::TaskNode.new("top")
117
+
118
+ load_all_tasks.each do |task|
119
+ Capitate::TaskNode.populate_with_task(top_node, task)
120
+ end
121
+ top_node
122
+ end
123
+
124
+ protected
125
+
126
+ def load_tasks(namespace, tasks = [])
127
+ recipe = namespace.last
128
+
129
+ recipe.namespaces.each do |nested_namespace|
130
+ load_tasks(nested_namespace, tasks)
131
+ end
132
+
133
+ recipe.task_list.each do |task|
134
+ tasks << task
135
+ end
136
+ end
137
+
138
+ end
139
+
140
+ Capistrano.plugin :capitate, Capitate::Plugins::Base