deploify 0.2.5

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 (35) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +36 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +2 -0
  6. data/Rakefile +1 -0
  7. data/deploify.gemspec +29 -0
  8. data/lib/deploify/capistrano_extensions.rb +189 -0
  9. data/lib/deploify/recipes/deploify.rb +171 -0
  10. data/lib/deploify/recipes/mongodb.rb +15 -0
  11. data/lib/deploify/recipes/monit.rb +84 -0
  12. data/lib/deploify/recipes/mysql.rb +85 -0
  13. data/lib/deploify/recipes/nginx.rb +122 -0
  14. data/lib/deploify/recipes/passenger.rb +130 -0
  15. data/lib/deploify/recipes/puma.rb +15 -0
  16. data/lib/deploify/recipes/rails.rb +221 -0
  17. data/lib/deploify/recipes/thin.rb +104 -0
  18. data/lib/deploify/recipes.rb +13 -0
  19. data/lib/deploify/templates/monit/monit.conf.erb +5 -0
  20. data/lib/deploify/templates/nginx/logrotate.conf.erb +12 -0
  21. data/lib/deploify/templates/nginx/vhost_http_force_ssl.conf.erb +79 -0
  22. data/lib/deploify/templates/nginx/vhost_http_only.conf.erb +66 -0
  23. data/lib/deploify/templates/nginx/vhost_http_with_ssl.conf.erb +131 -0
  24. data/lib/deploify/templates/passenger/logrotate.conf.erb +12 -0
  25. data/lib/deploify/templates/passenger/passengerctl-lib.erb +68 -0
  26. data/lib/deploify/templates/passenger/passengerctl.erb +10 -0
  27. data/lib/deploify/templates/thin/logrotate.conf.erb +0 -0
  28. data/lib/deploify/templates/thin/thinctl-lib.erb +84 -0
  29. data/lib/deploify/templates/thin/thinctl.erb +9 -0
  30. data/lib/deploify/version.rb +12 -0
  31. data/lib/deploify.rb +7 -0
  32. data/lib/plugins/all.rb +20 -0
  33. data/lib/plugins/apt.rb +94 -0
  34. data/lib/plugins/std.rb +203 -0
  35. metadata +196 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in deploify.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ deploify (0.2.0)
5
+ bundler (>= 1.0.21)
6
+ capistrano (~> 2.13.5)
7
+ rvm-capistrano (~> 1.2.7)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ capistrano (2.13.5)
13
+ highline
14
+ net-scp (>= 1.0.0)
15
+ net-sftp (>= 2.0.0)
16
+ net-ssh (>= 2.0.14)
17
+ net-ssh-gateway (>= 1.1.0)
18
+ highline (1.6.15)
19
+ net-scp (1.0.4)
20
+ net-ssh (>= 1.99.1)
21
+ net-sftp (2.0.5)
22
+ net-ssh (>= 2.0.9)
23
+ net-ssh (2.6.2)
24
+ net-ssh-gateway (1.1.0)
25
+ net-ssh (>= 1.99.1)
26
+ rvm-capistrano (1.2.7)
27
+ capistrano (>= 2.0.0)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ bundler (>= 1.0.21)
34
+ capistrano (~> 2.13.5)
35
+ deploify!
36
+ rvm-capistrano (~> 1.2.7)
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Richard Říman
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ deploify - capistrano based and deprec inspired deploy gem
2
+ ================================================================================
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/deploify.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'deploify/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "deploify"
8
+ gem.version = Deploify::VERSION
9
+ gem.authors = ["Richard R\314\214i\314\201man"]
10
+ gem.email = ["riman.richard@gmail.com"]
11
+ gem.description = "deploify - capistrano based and deprec inspired deploy solution served as a gem"
12
+ gem.summary = "capistrano based and deprec inspired deploy gem"
13
+ gem.homepage = "https://github.com/richardriman/deploify"
14
+
15
+ gem.required_ruby_version = ">= 1.8.7"
16
+
17
+ gem.add_development_dependency "bundler", ">= 1.0.21"
18
+ gem.add_development_dependency "capistrano", "~> 2.13.5"
19
+ gem.add_development_dependency "rvm-capistrano", "~> 1.2.7"
20
+
21
+ gem.add_dependency "bundler", ">= 1.0.21"
22
+ gem.add_dependency "capistrano", "~> 2.13.5"
23
+ gem.add_dependency "rvm-capistrano", "~> 1.2.7"
24
+
25
+ gem.files = `git ls-files`.split($/)
26
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
27
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
28
+ gem.require_paths = ["lib"]
29
+ end
@@ -0,0 +1,189 @@
1
+ require "capistrano"
2
+
3
+ module Deploify
4
+
5
+ DEPLOIFY_TEMPLATES_BASE = File.join(File.dirname(__FILE__), "templates")
6
+
7
+ # Render template (usually a config file)
8
+ #
9
+ # Usually we render it to a file on the local filesystem.
10
+ # This way, we keep a copy of the config file under source control.
11
+ # We can make manual changes if required and push to new hosts.
12
+ #
13
+ # If the options hash contains :path then it's written to that path.
14
+ # If it contains :remote => true, the file will instead be written to remote targets
15
+ # If options[:path] and options[:remote] are missing, it just returns the rendered
16
+ # template as a string (good for debugging).
17
+ #
18
+ # XXX I would like to get rid of :render_template_to_file
19
+ # XXX Perhaps pass an option to this function to write to remote
20
+ #
21
+ def render_template(app, options={})
22
+ template = options[:template]
23
+ path = options[:path] || nil
24
+ remote = options[:remote] || false
25
+ mode = options[:mode] || 0755
26
+ owner = options[:owner] || nil
27
+ stage = exists?(:stage) ? fetch(:stage).to_s : ''
28
+ # replace this with a check for the file
29
+ unless template
30
+ puts "render_template() requires a value for the template!"
31
+ return false
32
+ end
33
+
34
+ # If local copies of deploifyy templates exist they will be used
35
+ # If you don't specify the location with the local_template_dir option
36
+ # it defaults to config/templates.
37
+ # e.g. config/templates/nginx/nginx.conf.erb
38
+ local_template = File.join(local_template_dir, app.to_s, template)
39
+ if File.exists?(local_template)
40
+ puts
41
+ puts "Using local template (#{local_template})"
42
+ template = ERB.new(IO.read(local_template), nil, '-')
43
+ else
44
+ template = ERB.new(IO.read(File.join(DEPLOIFY_TEMPLATES_BASE, app.to_s, template)), nil, '-')
45
+ end
46
+ rendered_template = template.result(binding)
47
+
48
+ if remote
49
+ # render to remote machine
50
+ puts 'You need to specify a path to render the template to!' unless path
51
+ exit unless path
52
+ sudo "test -d #{File.dirname(path)} || #{sudo} mkdir -p #{File.dirname(path)}"
53
+ std.su_put rendered_template, path, '/tmp/', :mode => mode
54
+ sudo "chown #{owner} #{path}" if defined?(owner)
55
+ elsif path
56
+ # render to local file
57
+ full_path = File.join('config', stage, app.to_s, path)
58
+ path_dir = File.dirname(File.expand_path(full_path))
59
+ if File.exists?(full_path)
60
+ if IO.read(full_path) == rendered_template
61
+ puts "[skip] Identical file exists (#{full_path})."
62
+ return false
63
+ elsif overwrite?(full_path, rendered_template)
64
+ File.delete(full_path)
65
+ else
66
+ puts "[skip] Not overwriting #{full_path}"
67
+ return false
68
+ end
69
+ end
70
+ FileUtils.mkdir_p "#{path_dir}" unless File.directory?(path_dir)
71
+ # added line above to make windows compatible
72
+ # system "mkdir -p #{path_dir}" if ! File.directory?(path_dir)
73
+ File.open(File.expand_path(full_path), 'w') { |f| f.write rendered_template }
74
+ puts "[done] #{full_path} written"
75
+ else
76
+ # render to string
77
+ return rendered_template
78
+ end
79
+ end
80
+
81
+ # Copy configs to server(s). Note there is no :pull task. No changes should
82
+ # be made to configs on the servers so why would you need to pull them back?
83
+ def push_configs(app, files)
84
+ app = app.to_s
85
+ stage = exists?(:stage) ? fetch(:stage).to_s : ''
86
+
87
+ files.each do |file|
88
+ full_local_path = File.join('config', stage, app, file[:path])
89
+ if File.exists?(full_local_path)
90
+ # If the file path is relative we will prepend a path to this projects
91
+ # own config directory for this service.
92
+ if file[:path][0, 1] != '/'
93
+ full_remote_path = File.join(deploy_to, app, file[:path])
94
+ else
95
+ full_remote_path = file[:path]
96
+ end
97
+ sudo "test -d #{File.dirname(full_remote_path)} || #{sudo} mkdir -p #{File.dirname(full_remote_path)}"
98
+ std.su_put File.read(full_local_path), full_remote_path, '/tmp/', :mode => file[:mode]
99
+ sudo "chown #{file[:owner]} #{full_remote_path}"
100
+ else
101
+ # Render directly to remote host.
102
+ render_template(app, file.merge(:remote => true))
103
+ end
104
+ end
105
+ end
106
+
107
+ def overwrite?(full_path, rendered_template)
108
+ if defined?(overwrite_all)
109
+ return overwrite_all ? true : false
110
+ end
111
+
112
+ puts
113
+ response = Capistrano::CLI.ui.ask "File exists (#{full_path}).
114
+ Overwrite? ([y]es, [n]o, [d]iff)" do |q|
115
+ q.default = 'n'
116
+ end
117
+
118
+ case response
119
+ when 'y'
120
+ return true
121
+ when 'n'
122
+ return false
123
+ when 'd'
124
+ require 'tempfile'
125
+ tf = Tempfile.new("deprec_diff")
126
+ tf.puts(rendered_template)
127
+ tf.close
128
+ puts
129
+ puts "Running diff -u current_file new_file_if_you_overwrite"
130
+ puts
131
+ system "diff -u #{full_path} #{tf.path} | less"
132
+ puts
133
+ overwrite?(full_path, rendered_template)
134
+ end
135
+ end
136
+
137
+ # create new user account on target system
138
+ def useradd(user, options={})
139
+ options[:shell] ||= "/bin/bash" # new accounts on ubuntu have been getting /bin/sh
140
+ switches = ''
141
+ switches += " --shell=#{options[:shell]} " if options[:shell]
142
+ unless options[:homedir] == false
143
+ switches += " --create-home "
144
+ switches += " --home #{options[:homedir]} " if options[:homedir]
145
+ end
146
+ switches += " --gid #{options[:group]} " unless options[:group].nil?
147
+ invoke_command "#{sudo} mkdir -p #{File.dirname(options[:homedir])}" if options[:homedir]
148
+ invoke_command "grep '^#{user}:' /etc/passwd || #{sudo} /usr/sbin/useradd #{switches} #{user}", :via => run_method
149
+ end
150
+
151
+ # create a new group on target system
152
+ def groupadd(group, options={})
153
+ via = options.delete(:via) || run_method
154
+ invoke_command "grep '#{group}:' /etc/group || #{sudo} /usr/sbin/groupadd #{group}", :via => via
155
+ end
156
+
157
+ # add group to the list of groups this user belongs to
158
+ def add_user_to_group(user, group)
159
+ invoke_command "groups #{user} | grep ' #{group} ' || #{sudo} /usr/sbin/usermod -G #{group} -a #{user}", :via => run_method
160
+ end
161
+
162
+ # create directory if it doesn't already exist
163
+ # set permissions and ownership
164
+ # XXX move mode, path and
165
+ def mkdir(path, options={})
166
+ via = options.delete(:via) || :run
167
+ # XXX need to make sudo commands wrap the whole command (sh -c ?)
168
+ # XXX removed the extra 'sudo' from after the '||' - need something else
169
+ invoke_command "test -d #{path} || #{sudo if via == :sudo} mkdir -p #{path}"
170
+ invoke_command "chmod #{sprintf("%3o",options[:mode] || 0755)} #{path}", :via => via if options[:mode]
171
+ invoke_command "chown -R #{options[:owner]} #{path}", :via => via if options[:owner]
172
+ groupadd(options[:group], :via => via) if options[:group]
173
+ invoke_command "chgrp -R #{options[:group]} #{path}", :via => via if options[:group]
174
+ end
175
+
176
+ def install_deps(packages=[])
177
+ apt.install({:base => Array(packages)}, :stable)
178
+ end
179
+
180
+ def teardown_connections
181
+ sessions.keys.each do |server|
182
+ sessions[server].close
183
+ sessions.delete(server)
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+ Capistrano.plugin :_deploify, Deploify
@@ -0,0 +1,171 @@
1
+ # Copyright 2012 by Richard Riman. All rights reserved.
2
+
3
+ require "bundler/capistrano"
4
+ require "rvm/capistrano"
5
+
6
+ Capistrano::Configuration.instance(:must_exist).load do
7
+
8
+ # Set the value if not already set
9
+ # This method is accessible to all recipe files
10
+ # Defined and used by capistrano/deploy tasks
11
+ def _cset(name, *args, &block)
12
+ unless exists?(name)
13
+ set(name, *args, &block)
14
+ end
15
+ end
16
+
17
+ alias :default :_cset
18
+
19
+ # we allways use bundler, so change rake call
20
+ _cset :rake, lambda { "#{fetch(:bundle_cmd, "bundle")} exec rake" }
21
+
22
+ default_run_options[:pty] = true
23
+
24
+ set :local_template_dir, File.join("config", "templates")
25
+
26
+ # The following two Constants contain details of the configuration
27
+ # files used by each service. They're used when generating config
28
+ # files from templates and when configs files are pushed out to servers.
29
+ #
30
+ # They are populated by the recipe file for each service
31
+ #
32
+ SYSTEM_CONFIG_FILES = {} # e.g. httpd.conf
33
+ PROJECT_CONFIG_FILES = {} # e.g. projectname-httpd-vhost.conf
34
+
35
+ # deploify defines some generic recipes for common services
36
+ # including web, app and database servers
37
+ #
38
+ # They default to my current favourites which you can override
39
+ #
40
+ # Service options
41
+ CHOICES_WEBSERVER = [:nginx]
42
+ CHOICES_APPSERVER = [:passenger, :thin] # :puma, :unicorn
43
+ CHOICES_DATABASE = [:mysql] # :mongodb
44
+ #
45
+ # Service defaults
46
+ set :web_server_type, :nginx
47
+ set :app_server_type, :passenger
48
+ set :db_server_type, :mysql
49
+
50
+ # we always use RMV, but we must set :system, because RVM default is :user
51
+ set :rvm_type, :system
52
+ set(:rvm_ruby_string) do
53
+ Capistrano::CLI.ui.choose do |menu|
54
+ menu.prompt = "Please choose RVM Ruby version for this application"
55
+ menu.choices("1.8.6", "1.8.7", "ree", "1.9.2", "1.9.3")
56
+ end
57
+ end
58
+
59
+ set :use_monit, true
60
+
61
+ # Prompt user for missing values if not supplied
62
+ set(:application) do
63
+ Capistrano::CLI.ui.ask "Enter name of project (no spaces)" do |q|
64
+ q.validate = /^[0-9a-z_]*$/
65
+ end
66
+ end
67
+
68
+ set(:domain) do
69
+ Capistrano::CLI.ui.ask "Enter domain name for project" do |q|
70
+ q.validate = /^[0-9a-z_\-\.]*$/
71
+ end
72
+ end
73
+
74
+ # some tasks run commands requiring special user privileges on remote servers
75
+ # these tasks will run the commands with:
76
+ # :invoke_command "command", :via => run_method
77
+ # override this value if sudo is not an option
78
+ # in that case, your use will need the correct privileges
79
+ set :run_method, :sudo
80
+
81
+ # deploy from TAG stuff
82
+
83
+ set :deployable_without_tag, false # only used WITHOUT multi-staging
84
+ set :stages, %w(production staging) # default stages (only used WITH multi-staging)
85
+ set :stages_deployable_without_tag, %w(staging) # only used WITH multi-staging
86
+
87
+ set(:branch) do
88
+ unless exists?(:stage)
89
+ # single stage configuration
90
+ if deployable_without_tag
91
+ tag = `git branch | grep '*' | awk '{ print $2 }'`.split[0]
92
+ else
93
+ tag = Capistrano::CLI.ui.ask("TAG to deploy (make sure to push the tag first): ")
94
+ end
95
+ else
96
+ # multi-staging configuration
97
+ if stages_deployable_without_tag.include?(fetch(:stage).to_s)
98
+ tag = `git branch | grep '*' | awk '{ print $2 }'`.split[0]
99
+ else
100
+ tag = Capistrano::CLI.ui.ask("TAG from which we deploy on stage '#{fetch(:stage)}' (make sure to push the tag first): ")
101
+ end
102
+ end
103
+ end
104
+
105
+ # rails deploy stuff
106
+ set :apps_root, "/var/www" # parent dir for apps
107
+ set(:deploy_to) { File.join(apps_root, application) } # dir for current app
108
+ set(:current_path) { File.join(deploy_to, "current") }
109
+ set(:shared_path) { File.join(deploy_to, "shared") }
110
+
111
+ # more rails deploy stuff
112
+ set :user, "deploy" # user who is deploying
113
+ set :group, "deploy" # deployment group
114
+ set(:web_server_aliases) { domain.match(/^www/) ? [] : ["www.#{domain}"] }
115
+
116
+ # rails deploy GIT stuff
117
+ set :scm, :git
118
+ set :deploy_via, :remote_cache
119
+ set :copy_exclude, ['.git', '.rvmrc']
120
+ set(:repository) do
121
+ Capistrano::CLI.ui.ask "Enter repository URL for project"
122
+ end
123
+
124
+ # webserver stuff
125
+ set :force_domain_with_www, false
126
+
127
+ on :load, "deploify:connect_canonical_tasks"
128
+
129
+ namespace :deploify do
130
+
131
+ task :connect_canonical_tasks do
132
+ # link application specific recipes into canonical task names
133
+ # e.g. deprec:web:restart => deprec:nginx:restart
134
+ namespaces_to_connect = {
135
+ :web => :web_server_type,
136
+ :app => :app_server_type,
137
+ :db => :db_server_type
138
+ }
139
+ metaclass = class << self; self; end
140
+ namespaces_to_connect.each do |server, choice|
141
+ server_type = send(choice).to_sym
142
+ if server_type != :none
143
+ metaclass.send(:define_method, server) { namespaces[server] }
144
+ namespaces[server] = deploify.send(server_type)
145
+ end
146
+ end
147
+ end
148
+
149
+ end # namespace :deploify
150
+
151
+ namespace :deploy do
152
+
153
+ task :start, :roles => :app, :except => { :no_release => true } do
154
+ run "#{sudo} service #{app_server_type}-#{application} start"
155
+ end
156
+
157
+ task :stop, :roles => :app, :except => { :no_release => true } do
158
+ run "#{sudo} service #{app_server_type}-#{application} stop"
159
+ end
160
+
161
+ task :restart, :roles => :app, :except => { :no_release => true } do
162
+ run "#{sudo} service #{app_server_type}-#{application} graceful"
163
+ end
164
+
165
+ task :force_restart, :roles => :app, :except => { :no_release => true } do
166
+ run "#{sudo} service #{app_server_type}-#{application} restart"
167
+ end
168
+
169
+ end # namespace :deploy
170
+
171
+ end
@@ -0,0 +1,15 @@
1
+ # Copyright 2012 by Richard Riman. All rights reserved.
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+
5
+ namespace :deploify do
6
+
7
+ namespace :mongodb do
8
+
9
+
10
+
11
+ end # namespace :mongodb
12
+
13
+ end # namespace :deploify
14
+
15
+ end
@@ -0,0 +1,84 @@
1
+ # Copyright 2012 by Richard Riman. All rights reserved.
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+
5
+ # we use monit primary to control passenger processes so the tasks
6
+ # are restricted to :app. You may use it for other processes.
7
+ # In this case, specify HOSTS=hostname on the command line or use:
8
+ # for_roles(:role_name) { top.deploify.monit.task_name }
9
+ # in your recipes.
10
+
11
+ set :monit_timeout_interval, 120
12
+ set :monit_conf_dir, "/etc/monit/conf.d"
13
+ # TODO
14
+ # set :monit_alert_recipients, %w(monitoring@example.com)
15
+ # set :monit_timeout_recipients, %w(monitoring@example.com)
16
+
17
+ namespace :deploify do
18
+
19
+ namespace :monit do
20
+
21
+ PROJECT_CONFIG_FILES[:monit] = [
22
+ { :template => "monit.conf.erb",
23
+ :path => "monit.conf",
24
+ :mode => 0644,
25
+ :owner => "root:root" }
26
+ ]
27
+
28
+ desc <<-DESC
29
+ Generate monit application config from template. Note that this does not
30
+ push the config to the server, it merely generates required
31
+ configuration files. These should be kept under source control.
32
+ DESC
33
+ task :config_gen_project do
34
+ PROJECT_CONFIG_FILES[:monit].each do |file|
35
+ _deploify.render_template(:monit, file)
36
+ end
37
+ end
38
+
39
+ desc "Push application monit config files to server"
40
+ task :config_project, :roles => :app do
41
+ _deploify.push_configs(:monit, PROJECT_CONFIG_FILES[:monit])
42
+ end
43
+
44
+ desc "Start Monit"
45
+ task :start, :roles => :app do
46
+ send(run_method, "service monit start")
47
+ end
48
+
49
+ task :activate do
50
+ top.deploify.monit.activate_project
51
+ end
52
+
53
+ desc "Activate application monit config and reload monit"
54
+ task :activate_project, :roles => :app do
55
+ run "#{sudo} ln -sf #{deploy_to}/monit/monit.conf #{monit_conf_dir}/#{application}"
56
+ top.deploify.monit.reload
57
+ end
58
+
59
+ desc "Dectivate application monit config and reload monit"
60
+ task :deactivate_project, :roles => :app do
61
+ run "#{sudo} rm -f #{monit_conf_dir}/#{application}; exit 0"
62
+ top.deploify.monit.reload
63
+ end
64
+
65
+ desc "Stop Monit"
66
+ task :stop, :roles => :app do
67
+ send(run_method, "service monit stop")
68
+ end
69
+
70
+ desc "Restart Monit"
71
+ task :restart, :roles => :app do
72
+ send(run_method, "service monit restart")
73
+ end
74
+
75
+ desc "Reload Monit"
76
+ task :reload, :roles => :app do
77
+ send(run_method, "service monit restart")
78
+ end
79
+
80
+ end # namespace :monit
81
+
82
+ end # namespace :deploify
83
+
84
+ end
@@ -0,0 +1,85 @@
1
+ # Copyright 2006-2008 by Mike Bailey. All rights reserved.
2
+ # Copyright 2012 by Richard Riman. All rights reserved.
3
+
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+
6
+ set :mysql_admin_user, "deploy"
7
+ set(:mysql_admin_pass) { Capistrano::CLI.password_prompt "Enter database password for '#{mysql_admin_user}':" }
8
+
9
+ namespace :deploify do
10
+
11
+ namespace :mysql do
12
+
13
+ desc "Start Mysql"
14
+ task :start, :roles => :db do
15
+ send(run_method, "service mysql start")
16
+ end
17
+
18
+ desc "Stop Mysql"
19
+ task :stop, :roles => :db do
20
+ send(run_method, "service mysql stop")
21
+ end
22
+
23
+ desc "Restart Mysql"
24
+ task :restart, :roles => :db do
25
+ send(run_method, "service mysql restart")
26
+ end
27
+
28
+ desc "Reload Mysql"
29
+ task :reload, :roles => :db do
30
+ send(run_method, "service mysql reload")
31
+ end
32
+
33
+ desc "Create a database"
34
+ task :create_database, :roles => :db do
35
+ cmd = "CREATE DATABASE IF NOT EXISTS #{db_name}"
36
+ run "mysql -u #{mysql_admin_user} -p -e '#{cmd}'" do |channel, stream, data|
37
+ if data =~ /^Enter password:/
38
+ channel.send_data "#{mysql_admin_pass}\n"
39
+ end
40
+ end
41
+ end
42
+
43
+ desc "Grant user access to database"
44
+ task :grant_user_access_to_database, :roles => :db do
45
+ cmd = "GRANT ALL PRIVILEGES ON #{db_name}.* TO '#{db_user}'@localhost IDENTIFIED BY '#{db_password}';"
46
+ run "mysql -u #{mysql_admin_user} -p #{db_name} -e \"#{cmd}\"" do |channel, stream, data|
47
+ if data =~ /^Enter password:/
48
+ channel.send_data "#{mysql_admin_pass}\n"
49
+ end
50
+ end
51
+ end
52
+
53
+ end # namespace :mysql
54
+
55
+ end # namespace :deploify
56
+
57
+ end
58
+
59
+ #
60
+ # Setup replication
61
+ #
62
+
63
+ # setup user for repl
64
+ # GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.yourdomain.com' IDENTIFIED BY 'slavepass';
65
+
66
+ # get current position of binlog
67
+ # mysql> FLUSH TABLES WITH READ LOCK;
68
+ # Query OK, 0 rows affected (0.00 sec)
69
+ #
70
+ # mysql> SHOW MASTER STATUS;
71
+ # +------------------+----------+--------------+------------------+
72
+ # | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
73
+ # +------------------+----------+--------------+------------------+
74
+ # | mysql-bin.000012 | 296 | | |
75
+ # +------------------+----------+--------------+------------------+
76
+ # 1 row in set (0.00 sec)
77
+ #
78
+ # # get current data
79
+ # mysqldump --all-databases --master-data >dbdump.db
80
+ #
81
+ # UNLOCK TABLES;
82
+
83
+
84
+ # Replication Features and Issues
85
+ # http://dev.mysql.com/doc/refman/5.0/en/replication-features.html