capistrano-kitchen 0.0.0.pre

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 (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset.template +1 -0
  5. data/.ruby-version.template +1 -0
  6. data/.travis.yml +7 -0
  7. data/.yardopts +5 -0
  8. data/Gemfile +8 -0
  9. data/Guardfile +13 -0
  10. data/LICENSE.txt +46 -0
  11. data/Rakefile +14 -0
  12. data/capistrano-kitchen.gemspec +29 -0
  13. data/lib/capistrano-kitchen.rb +41 -0
  14. data/lib/capistrano_kitchen/dishes/aptitude/manage.rb +38 -0
  15. data/lib/capistrano_kitchen/dishes/bundler/hooks.rb +7 -0
  16. data/lib/capistrano_kitchen/dishes/bundler/install.rb +79 -0
  17. data/lib/capistrano_kitchen/dishes/git/hooks.rb +3 -0
  18. data/lib/capistrano_kitchen/dishes/git/install.rb +18 -0
  19. data/lib/capistrano_kitchen/dishes/java_7_oracle/hooks.rb +5 -0
  20. data/lib/capistrano_kitchen/dishes/java_7_oracle/install.rb +17 -0
  21. data/lib/capistrano_kitchen/dishes/nginx_unicorn/app.conf +66 -0
  22. data/lib/capistrano_kitchen/dishes/nginx_unicorn/hooks.rb +11 -0
  23. data/lib/capistrano_kitchen/dishes/nginx_unicorn/install.rb +176 -0
  24. data/lib/capistrano_kitchen/dishes/nginx_unicorn/manage.rb +1 -0
  25. data/lib/capistrano_kitchen/dishes/nginx_unicorn/mime.types.erb +79 -0
  26. data/lib/capistrano_kitchen/dishes/nginx_unicorn/nginx.conf +138 -0
  27. data/lib/capistrano_kitchen/dishes/nginx_unicorn/nginx_unicorn.god +47 -0
  28. data/lib/capistrano_kitchen/dishes/nginx_unicorn/nginx_unicorn.init +95 -0
  29. data/lib/capistrano_kitchen/dishes/nginx_unicorn/nginx_unicorn.logrotate +18 -0
  30. data/lib/capistrano_kitchen/dishes/nginx_unicorn/stub_status.conf +16 -0
  31. data/lib/capistrano_kitchen/dishes/nodejs/hooks.rb +4 -0
  32. data/lib/capistrano_kitchen/dishes/nodejs/install.rb +13 -0
  33. data/lib/capistrano_kitchen/dishes/provision/empty_roles.rb +60 -0
  34. data/lib/capistrano_kitchen/dishes/provision/manage.rb +49 -0
  35. data/lib/capistrano_kitchen/dishes/provision/task_once.rb +62 -0
  36. data/lib/capistrano_kitchen/dishes/ruby/hooks.rb +7 -0
  37. data/lib/capistrano_kitchen/dishes/ruby/install.rb +55 -0
  38. data/lib/capistrano_kitchen/dishes/teelogger/teelogger.rb +121 -0
  39. data/lib/capistrano_kitchen/dishes/unicorn/hooks.rb +9 -0
  40. data/lib/capistrano_kitchen/dishes/unicorn/install.rb +120 -0
  41. data/lib/capistrano_kitchen/dishes/unicorn/unicorn.god +71 -0
  42. data/lib/capistrano_kitchen/dishes/unicorn/unicorn.rb.erb +191 -0
  43. data/lib/capistrano_kitchen/recipes/aptitude.rb +1 -0
  44. data/lib/capistrano_kitchen/recipes/bundler.rb +1 -0
  45. data/lib/capistrano_kitchen/recipes/git.rb +1 -0
  46. data/lib/capistrano_kitchen/recipes/java_7_oracle.rb +1 -0
  47. data/lib/capistrano_kitchen/recipes/nginx_unicorn.rb +1 -0
  48. data/lib/capistrano_kitchen/recipes/nodejs.rb +1 -0
  49. data/lib/capistrano_kitchen/recipes/provision.rb +1 -0
  50. data/lib/capistrano_kitchen/recipes/ruby.rb +1 -0
  51. data/lib/capistrano_kitchen/recipes/teelogger.rb +1 -0
  52. data/lib/capistrano_kitchen/recipes/unicorn.rb +1 -0
  53. data/lib/capistrano_kitchen/recipes/utilities.rb +442 -0
  54. data/lib/capistrano_kitchen/version.rb +3 -0
  55. data/spec/capistrano_kitchen_spec.rb +5 -0
  56. data/spec/spec_helper.rb +21 -0
  57. metadata +200 -0
@@ -0,0 +1,95 @@
1
+ #! /bin/sh
2
+
3
+ ### BEGIN INIT INFO
4
+ # Provides: nginx
5
+ # Required-Start: $local_fs $remote_fs $network $syslog
6
+ # Required-Stop: $local_fs $remote_fs $network $syslog
7
+ # Default-Start: 2 3 4 5
8
+ # Default-Stop: 0 1 6
9
+ # Short-Description: starts the nginx web server
10
+ # Description: starts nginx using start-stop-daemon
11
+ ### END INIT INFO
12
+
13
+ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
14
+ DAEMON=<%=nginx_unicorn_sbin_file%>
15
+ DAEMON_OPTS="-c <%="#{nginx_unicorn_conf_dir}/nginx.conf"%>"
16
+ NAME=<%=nginx_unicorn_init_d%>
17
+ DESC=<%=nginx_unicorn_init_d%>
18
+ PID=<%=nginx_unicorn_pid_file%>
19
+
20
+ test -x $DAEMON || exit 0
21
+
22
+ # Include nginx defaults if available
23
+ if [ -f /etc/default/nginx ] ; then
24
+ . /etc/default/nginx
25
+ fi
26
+
27
+ set -e
28
+
29
+ . /lib/lsb/init-functions
30
+
31
+ test_nginx_config() {
32
+ if $DAEMON -t $DAEMON_OPTS >/dev/null 2>&1
33
+ then
34
+ return 0
35
+ else
36
+ $DAEMON -t $DAEMON_OPTS
37
+ return $?
38
+ fi
39
+ }
40
+
41
+ case "$1" in
42
+ start)
43
+ echo -n "Starting $DESC: "
44
+ test_nginx_config
45
+ start-stop-daemon --start --quiet --pidfile $PID \
46
+ --exec $DAEMON -- $DAEMON_OPTS || true
47
+ echo "$NAME."
48
+ ;;
49
+ stop)
50
+ echo -n "Stopping $DESC: "
51
+ start-stop-daemon --stop --quiet --pidfile $PID \
52
+ --exec $DAEMON || true
53
+ echo "$NAME."
54
+ ;;
55
+ restart|force-reload)
56
+ echo -n "Restarting $DESC: "
57
+ start-stop-daemon --stop --quiet --pidfile \
58
+ $PID --exec $DAEMON || true
59
+ sleep 1
60
+ test_nginx_config
61
+ start-stop-daemon --start --quiet --pidfile \
62
+ $PID --exec $DAEMON -- $DAEMON_OPTS || true
63
+ echo "$NAME."
64
+ ;;
65
+ reload)
66
+ echo -n "Reloading $DESC configuration: "
67
+ test_nginx_config
68
+ start-stop-daemon --stop --signal HUP --quiet --pidfile $PID \
69
+ --exec $DAEMON || true
70
+ echo "$NAME."
71
+ ;;
72
+ reopen)
73
+ echo -n "Reopening $DESC log files: "
74
+ $DAEMON -s reopen || true
75
+ echo "$NAME."
76
+ ;;
77
+ configtest)
78
+ echo -n "Testing $DESC configuration: "
79
+ if test_nginx_config
80
+ then
81
+ echo "$NAME."
82
+ else
83
+ exit $?
84
+ fi
85
+ ;;
86
+ status)
87
+ status_of_proc -p $PID "$DAEMON" nginx && exit 0 || exit $?
88
+ ;;
89
+ *)
90
+ echo "Usage: $NAME {start|stop|restart|reload|force-reload|reopen|status|configtest}" >&2
91
+ exit 1
92
+ ;;
93
+ esac
94
+
95
+ exit 0
@@ -0,0 +1,18 @@
1
+ <%=nginx_unicorn_log_dir%>/*.log {
2
+ daily
3
+ missingok
4
+ rotate 52
5
+ compress
6
+ delaycompress
7
+ notifempty
8
+ create 0640 www-data adm
9
+ sharedscripts
10
+ prerotate
11
+ if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
12
+ run-parts /etc/logrotate.d/httpd-prerotate; \
13
+ fi; \
14
+ endscript
15
+ postrotate
16
+ [ ! -f /var/run/<%=nginx_unicorn_init_d%>.pid ] || kill -USR1 `cat /var/run/<%=nginx_unicorn_init_d%>.pid`
17
+ endscript
18
+ }
@@ -0,0 +1,16 @@
1
+ server {
2
+ listen 127.0.0.1:80;
3
+ server_name localhost;
4
+
5
+ location /nginx_status {
6
+ # copied from http://blog.kovyrin.net/2006/04/29/monitoring-nginx-with-rrdtool/
7
+ # Generate stupid load to see the counters increase
8
+ # ab -n 1000 http://127.0.0.1/nginx_status
9
+ stub_status on;
10
+ access_log off;
11
+ allow 127.0.0.1;
12
+ deny all;
13
+ }
14
+
15
+ }
16
+
@@ -0,0 +1,4 @@
1
+ # @author Donovan Bray <donnoman@donovanbray.com>
2
+ Capistrano::Configuration.instance(true).load do
3
+ after "deploy:provision", "nodejs:install"
4
+ end
@@ -0,0 +1,13 @@
1
+ # @author Donovan Bray <donnoman@donovanbray.com>
2
+ Capistrano::Configuration.instance(true).load do
3
+
4
+ namespace :nodejs do
5
+
6
+ desc "Install nodejs"
7
+ task :install, :except => {:no_release => true} do
8
+ utilities.apt_install "nodejs"
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,60 @@
1
+ # Allows Tasks that have no servers to be skipped instead of raising a NoMatchingServersError
2
+
3
+ module Capistrano
4
+ class Configuration
5
+ module Connections
6
+ def execute_on_servers(options={})
7
+ raise ArgumentError, "expected a block" unless block_given?
8
+
9
+ if task = current_task
10
+ servers = find_servers_for_task(task, options)
11
+
12
+ if servers.empty?
13
+ #raise Capistrano::NoMatchingServersError, "`#{task.fully_qualified_name}' is only run for servers matching #{task.options.inspect}, but no servers matched"
14
+ logger.info "skipping `#{task.fully_qualified_name}' because no servers matched"
15
+ return
16
+ end
17
+
18
+ if task.continue_on_error?
19
+ servers.delete_if { |s| has_failed?(s) }
20
+ return if servers.empty?
21
+ end
22
+ else
23
+ servers = find_servers(options)
24
+ raise Capistrano::NoMatchingServersError, "no servers found to match #{options.inspect}" if servers.empty?
25
+ end
26
+
27
+ servers = [servers.first] if options[:once]
28
+ logger.trace "servers: #{servers.map { |s| s.host }.inspect}"
29
+
30
+ max_hosts = (options[:max_hosts] || (task && task.max_hosts) || servers.size).to_i
31
+ is_subset = max_hosts < servers.size
32
+
33
+ # establish connections to those servers in groups of max_hosts, as necessary
34
+ servers.each_slice(max_hosts) do |servers_slice|
35
+ begin
36
+ establish_connections_to(servers_slice)
37
+ rescue ConnectionError => error
38
+ raise error unless task && task.continue_on_error?
39
+ error.hosts.each do |h|
40
+ servers_slice.delete(h)
41
+ failed!(h)
42
+ end
43
+ end
44
+
45
+ begin
46
+ yield servers_slice
47
+ rescue RemoteError => error
48
+ raise error unless task && task.continue_on_error?
49
+ error.hosts.each { |h| failed!(h) }
50
+ end
51
+
52
+ # if dealing with a subset (e.g., :max_hosts is less than the
53
+ # number of servers available) teardown the subset of connections
54
+ # that were just made, so that we can make room for the next subset.
55
+ teardown_connections_to(servers_slice) if is_subset
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,49 @@
1
+ # @author Donovan Bray <donnoman@donovanbray.com>
2
+ require File.expand_path(File.dirname(__FILE__) + '/../utilities')
3
+
4
+ # Provisioning hooks into many of the scripts to give a single hook to install
5
+ # the requisite software.
6
+ #
7
+ # The provisioning process assumes capistrano has been overriden to support empty roles
8
+ #
9
+ # Supported tasks add a ' after "deploy:provision", "app:install" ' in their hooks.rb
10
+ # if you don't include ' require 'cap_recipes/tasks/provision' ' in your deploy.rb then the provision task
11
+ # is never fire, and all of the extra hooks are ignored.
12
+ #
13
+ # It's convenient to override the provision task in your deploy.rb to do something more meaningful as well.
14
+ #
15
+ # desc "Provision the servers"
16
+ # task :provision do
17
+ # utilities.apt_install "git-core telnet elinks netcat socat curl arping rsync nload wget locate strace"
18
+ # mysql.install_client_libs #needed to build mysql2 gem
19
+ # deploy.provision_bundler_dependencies
20
+ # end
21
+
22
+ Capistrano::Configuration.instance(true).load do
23
+
24
+ namespace :deploy do
25
+
26
+ # Init all base roles so they can be empty
27
+ roles[:web]
28
+ roles[:app]
29
+ roles[:db]
30
+
31
+ # This block allows us to add items to the very beginning of provisioning
32
+ # while allowing the consumer to freely override the deploy:provision task to add
33
+ # thier own non-framework items.
34
+ on :start, :only => "deploy:provision" do
35
+ deploy.provision_prerequisites
36
+ end
37
+
38
+ task :provision_prerequisites do
39
+ utilities.apt_update
40
+ utilities.apt_install_by_command('add-apt-repository')
41
+ end
42
+
43
+ task :provision do
44
+ logger.info "Provisioning Services"
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,62 @@
1
+ module Capistrano
2
+ class Configuration
3
+ module Servers
4
+ # Identifies all servers that the given task should be executed on.
5
+ # The options hash accepts the same arguments as #find_servers, and any
6
+ # preexisting options there will take precedence over the options in
7
+ # the task.
8
+ def find_servers_for_task(task, options={})
9
+ find_servers(task.options.merge(options))
10
+ end
11
+
12
+ # Attempts to find all defined servers that match the given criteria.
13
+ # The options hash may include a :hosts option (which should specify
14
+ # an array of host names or ServerDefinition instances), a :roles
15
+ # option (specifying an array of roles), an :only option (specifying
16
+ # a hash of key/value pairs that any matching server must match), and
17
+ # an :exception option (like :only, but the inverse).
18
+ #
19
+ # Additionally, if the HOSTS environment variable is set, it will take
20
+ # precedence over any other options. Similarly, the ROLES environment
21
+ # variable will take precedence over other options. If both HOSTS and
22
+ # ROLES are given, HOSTS wins.
23
+ #
24
+ # Yet additionally, if the HOSTFILTER environment variable is set, it
25
+ # will limit the result to hosts found in that (comma-separated) list.
26
+ #
27
+ # Usage:
28
+ #
29
+ # # return all known servers
30
+ # servers = find_servers
31
+ #
32
+ # # find all servers in the app role that are not exempted from
33
+ # # deployment
34
+ # servers = find_servers :roles => :app,
35
+ # :except => { :no_release => true }
36
+ #
37
+ # # returns the given hosts, translated to ServerDefinition objects
38
+ # servers = find_servers :hosts => "jamis@example.host.com"
39
+ def find_servers(options={})
40
+ hosts = server_list_from(ENV['HOSTS'] || options[:hosts])
41
+
42
+ if hosts.any?
43
+ filter_server_list(hosts.uniq)
44
+ else
45
+ roles = role_list_from(ENV['ROLES'] || options[:roles] || self.roles.keys)
46
+ only = options[:only] || {}
47
+ except = options[:except] || {}
48
+
49
+ servers = roles.inject([]) { |list, role| list.concat(self.roles[role]) }
50
+ servers = servers.select { |server| only.all? { |key,value| server.options[key] == value } }
51
+ servers = servers.reject { |server| except.any? { |key,value| server.options[key] == value } }
52
+
53
+ #allows you to add the option :once to a task ie: task :my_task, :roles => :app, :once => true do ...
54
+ servers = [servers.first] if options[:once] and servers.size > 1
55
+ logger.trace "servers: #{servers.map { |s| s.host }.inspect}"
56
+
57
+ filter_server_list(servers.uniq)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,7 @@
1
+ # @author Donovan Bray <donnoman@donovanbray.com>
2
+ Capistrano::Configuration.instance(true).load do
3
+ after "deploy:provision", "ruby:install"
4
+ after "ruby:install", "ruby:rubygems_source_fix"
5
+ after "ruby:install", "ruby:ruby_debugger"
6
+ after "deploy:setup", "ruby:ensure_trust_github"
7
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../utilities')
2
+
3
+ Capistrano::Configuration.instance(true).load do
4
+
5
+ namespace :ruby do
6
+
7
+ set :ruby_ver_latest_type, "stable" # can be major.minor numbers ie: 1.8, 2.1 etc. or 'stable'
8
+ set(:ruby_ver_latest) { open("http://ftp.ruby-lang.org/pub/ruby/#{ruby_ver_latest_type}").read.scan(/href="(ruby-\d.\d.\d(-p\d+)?).tar.bz2/).map{|r| r[0]}.sort.reverse.first }
9
+ set(:ruby_ver) { utilities.suggest_version(:ruby_ver,ruby_ver_latest) }
10
+
11
+ # Ruby Versioning: ruby-MAJOR.MINOR.TEENY-pPATCHLEVEL
12
+ set(:ruby_major_minor) { ruby_ver.match(/ruby-(\d\.\d)/)[1]}
13
+ set(:ruby_src) { "http://cache.ruby-lang.org/pub/ruby/#{ruby_major_minor}/#{ruby_ver}.tar.bz2"}
14
+
15
+ set :base_ruby_path, '/usr'
16
+ set :ruby_debugger_support, false
17
+ set :ruby_rubygems_source_fix_support, false
18
+ set :ruby_ensure_trust_github, true
19
+
20
+ # New Concept ':except => {:no_ruby => true}' to allow all systems by default
21
+ # to have ruby installed to allow use of ruby gems like god on all systems
22
+ # regardless of whether they have releases deployed to them, they may have other things
23
+ # that we want god to watch on them.
24
+
25
+ desc "install ruby"
26
+ task :install, :except => {:no_ruby => true} do
27
+ utilities.apt_install %w[build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool]
28
+ sudo "mkdir -p /usr/local/src/"
29
+ run "#{sudo} rm -rf /usr/local/src/#{ruby_ver}" #make clean is not allowing a re-install #http://www.ruby-forum.com/topic/4409005
30
+ run "cd /usr/local/src && #{sudo} wget --tries=2 -c --progress=bar:force #{ruby_src} && #{sudo} bunzip2 --keep --force #{ruby_ver}.tar.bz2 && #{sudo} tar xvf #{ruby_ver}.tar"
31
+ run "cd /usr/local/src/#{ruby_ver} && #{sudo} ./configure --prefix=#{base_ruby_path} --enable-shared && #{sudo} make install"
32
+ end
33
+
34
+ desc "add ruby debugger support"
35
+ task :ruby_debugger, :except => { :no_ruby => true } do
36
+ if ruby_debugger_support
37
+ utilities.gem_install("debugger-ruby_core_source -- --with-ruby-include=/usr/local/src/#{ruby_ver}")
38
+ utilities.gem_install("debugger-linecache -- --with-ruby-include=/usr/local/src/#{ruby_ver}")
39
+ end
40
+ end
41
+
42
+ desc "Remove legacy rubygems.org as gem source"
43
+ task :rubygems_source_fix, :except => { :no_ruby => true } do
44
+ if ruby_rubygems_source_fix_support
45
+ run "#{sudo} gem source -a http://production.s3.rubygems.org"
46
+ run "#{sudo} gem source -r http://rubygems.org/"
47
+ end
48
+ end
49
+
50
+ task :ensure_trust_github, :except => { :no_ruby => true } do
51
+ utilities.run_with_input("ssh -i ~/.ssh/id_rsa git@github.com;true", /\?/, "yes\n") if ruby_ensure_trust_github
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,121 @@
1
+ class TeeLogWriter
2
+ #use this to exit cap but still have a zero exit code
3
+ class NormalExit < Capistrano::Error; end
4
+ ##
5
+ # This passes through the value and adds it to the redaction list
6
+ #
7
+ # set(:mysql_client_user) { TeeLogWriter.redact(database_user) }
8
+ #
9
+ # So your capistrano variable has the correct value, but it will be redacted from TeeLogWriters output.
10
+ def self.redact(secure_message)
11
+ self.redactions = (self.redactions + [secure_message].flatten).uniq
12
+ secure_message
13
+ end
14
+
15
+ def self.redaction_replacement
16
+ @redaction_replacement ||= '######'
17
+ end
18
+
19
+ def self.redaction_replacement=(replacement)
20
+ @redaction_replacement = replacement
21
+ end
22
+
23
+ def self.redacted(message)
24
+ with_ensured_encoding(message) do |message|
25
+ redactions.inject(message) do |message,redaction|
26
+ message.gsub(redaction,redaction_replacement)
27
+ end
28
+ end
29
+ end
30
+
31
+ def with_redactions(message)
32
+ yield self.class.redacted(message)
33
+ end
34
+
35
+ def puts(message)
36
+ with_redactions(message) do |message|
37
+ STDOUT.puts message
38
+ file.puts "[#{log_timestamp}] #{message}"
39
+ end
40
+ end
41
+
42
+ def tty?
43
+ true
44
+ end
45
+
46
+ private
47
+
48
+
49
+ def self.redactions
50
+ @redactions ||= []
51
+ end
52
+
53
+ def self.redactions=(value)
54
+ @redactions = value
55
+ end
56
+
57
+ def self.with_ensured_encoding(message)
58
+ yield message.respond_to?(:force_encoding) ? message.force_encoding("UTF-8") : message
59
+ end
60
+
61
+ def file
62
+ @file ||= File.open(File.join(logdir,"deploy.#{file_timestamp}.log"), "w")
63
+ end
64
+
65
+ def log_timestamp
66
+ Time.now.strftime("%Y-%m-%d %H:%M:%S%z")
67
+ end
68
+
69
+ def file_timestamp
70
+ Time.now.strftime("%Y%m%d-%H%M%S%z")
71
+ end
72
+
73
+ def caproot
74
+ @caproot ||= File.dirname(capfile)
75
+ end
76
+
77
+ def logdir
78
+ FileUtils.mkdir_p(File.join(caproot,'log')).first
79
+ end
80
+
81
+ def capfile
82
+ previous = nil
83
+ current = File.expand_path(Dir.pwd)
84
+
85
+ until !File.directory?(current) || current == previous
86
+ filename = File.join(current, 'Capfile')
87
+ return filename if File.file?(filename)
88
+ current, previous = File.expand_path("..", current), current
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ require 'capistrano/configuration'
95
+
96
+ module Capistrano
97
+ class CLI
98
+ module Execute
99
+ def handle_error(error) #:nodoc:
100
+ case error
101
+ when TeeLogWriter::NormalExit #used to force capistrano to end but without an error code.
102
+ exit 0
103
+ when Net::SSH::AuthenticationFailed
104
+ abort "authentication failed for `#{TeeLogWriter.redacted(error.message)}'"
105
+ when Capistrano::Error
106
+ abort(TeeLogWriter.redacted(error.message))
107
+ else
108
+ puts TeeLogWriter.redacted(error.message)
109
+ puts error.backtrace
110
+ exit 1
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+
118
+ Capistrano::Configuration.instance(true).load do
119
+ #replace the running logger device with our own.
120
+ self.logger.instance_variable_set(:@device,TeeLogWriter.new)
121
+ end