cap-runit 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c3e6b7e1396dc85e4f664fac65423f7b17eb80e5
4
+ data.tar.gz: e68549492f3f0e5cf8301dd473b15ea4fe778347
5
+ SHA512:
6
+ metadata.gz: 0fd9c847ffb4cb4fffd273b5cd754b66f1a985427ca1e4c9fb303e7dff41ae4ff69a7d2577374836a0fa9bf2aa03cd50f0eca5bc771db15ace1f68d8d07e73af
7
+ data.tar.gz: d84be89f74bb843f7f3a676962463e1b6c68c31f8879eac2c0d84fdd670f89d7f2bab9547dd936ecd187e169513895b703685ac2e03678600b710cec392c11d2
@@ -0,0 +1,136 @@
1
+ # Capistrano 3 Runit Support
2
+
3
+ cap-runit provides a helper for building runit services. It lets you easily
4
+ deploy services using capistrano 3 and run them with runit.
5
+
6
+ ## Installation
7
+
8
+ Using bundler: Add `gem 'cap-runit'` to your `Gemfile` and `require 'bundler';
9
+ Bundler.require` to your `Capfile`.
10
+
11
+ Not using bundler: `gem install cap-runit` and add `require 'capistrano/runit'`
12
+ to your `Capfile`.
13
+
14
+ ## Usage
15
+
16
+ cap-runit provides a helper method `runit_service` to Capistrano. As the
17
+ philosophy of runit is that everything is just a shell script, `cap-runit`
18
+ requires you to write a shell script.
19
+
20
+ For example, to run sidekiq, you might do something like this:
21
+
22
+
23
+ ```ruby
24
+ runit_service 'sidekiq' do
25
+
26
+ run <<-EOF
27
+ #!/bin/bash
28
+ cd /var/www/app/current
29
+ exec bundle exec sidekiq -e production -C ./config/sidekiq.yml 2>&1
30
+ EOF
31
+
32
+ end
33
+ ```
34
+
35
+ This creates three capistrano tasks:
36
+
37
+ ```
38
+ cap sidekiq:restart # Restart bugsnag-event-server
39
+ cap sidekiq:start # Start bugsnag-event-server
40
+ cap sidekiq:stop # Stop bugsnag-event-server
41
+ ```
42
+
43
+ If you'd like to restart sidekiq when your app restarts, you also need to
44
+ specify:
45
+
46
+ ```ruby
47
+ namespace :deploy do
48
+ after :publishing, 'sidekiq:restart'
49
+ end
50
+ ```
51
+
52
+ ### Logging
53
+
54
+ Runit sends the STDOUT of your `run` script to the `log` script. To get these
55
+ logs somewhere useful, you can use any program that reads from STDIN. But
56
+ `svlogd` is recommended as it works well with runit and handles log rotation
57
+ automatically.
58
+
59
+ ```ruby
60
+ runit_service 'sidekiq' do
61
+
62
+ run <<-EOF
63
+ #!/bin/bash -l
64
+ cd /var/www/app/current
65
+ exec bundle exec sidekiq -e production -C ./config/sidekiq.yml 2>&1
66
+ EOF
67
+
68
+ log <<-EOF
69
+ #!/bin/sh
70
+ mkdir -p /var/log/sidekiq
71
+ exec svlogd -tt /var/log/sidekiq
72
+ EOF
73
+ end
74
+ ```
75
+
76
+ ### Crash notifications
77
+
78
+ If you need to be notified of when a crash happens in your app, you can also
79
+ configure a `finish` script. This is run whenever the `run` script exits.
80
+
81
+ ```ruby
82
+ runit_service 'sidekiq' do
83
+
84
+ run <<-EOF
85
+ #!/bin/bash -l
86
+ cd /var/www/app/current
87
+ exec bundle exec sidekiq -e production -C ./config/sidekiq.yml 2>&1
88
+ EOF
89
+
90
+ log <<-EOF
91
+ #!/bin/sh
92
+ mkdir -p /var/log/sidekiq
93
+ exec svlogd -tt /var/log/sidekiq
94
+ EOF
95
+
96
+ finish <<-EOF
97
+ #!/bin/sh
98
+ export BUGSNAG_API_KEY=bf04f47b034e8df9d22ee75f30fdae6a
99
+ [ "$1" = 0 ] || exec bugsnag-runit "$0"
100
+ EOF
101
+ end
102
+
103
+ ```
104
+
105
+ ## Configuration
106
+
107
+ The only configuration variable you need to pass is `runit_service_directory`
108
+
109
+ ```ruby
110
+ set :runit_service_directory, "/apps/service"
111
+ ```
112
+
113
+ The service directory needs to be run with `runsvdir` and owned by the
114
+ capistrano user. To configure `runsvdir` you can create the following files:
115
+
116
+
117
+ ```bash
118
+ #/etc/service/cap-runit/run
119
+
120
+ #!/bin/bash
121
+ exec chpst -udeploy -- runsvdir /apps/service 2>&1
122
+ ```
123
+
124
+ And
125
+
126
+ ```bash
127
+ #/etc/service/cap-runit/log/run
128
+
129
+ #!/bin/sh
130
+ exec svlogd -tt /var/log/cap-runit
131
+ ```
132
+
133
+ These files should both be owned by root and `chmod +x`. This way the deploy
134
+ user does not need root permissions to reboot a service on deploy.
135
+
136
+
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = 'cap-runit'
3
+ gem.version = '0.1'
4
+
5
+ gem.summary = 'Capistrano 3 Runit integration'
6
+ gem.description = "Template for managing runit directories with capistrano 3"
7
+
8
+ gem.authors = ['Conrad Irwin']
9
+ gem.email = %w(conrad@bugsnag.com)
10
+ gem.homepage = 'http://github.com/ConradIrwin/cap-runit'
11
+
12
+ gem.license = 'MIT'
13
+
14
+ gem.add_dependency 'capistrano', '>= 3.0'
15
+
16
+ gem.files = `git ls-files`.split("\n")
17
+ end
@@ -0,0 +1,134 @@
1
+ # TODO:CI make this into a gem.
2
+
3
+ set :runit_service_dir, "/apps/service"
4
+
5
+ class RunitServiceBuilder
6
+
7
+ def initialize(&block)
8
+ instance_eval(&block)
9
+ unless @roles
10
+ raise ArgumentError, "No role configured for runit service"
11
+ end
12
+ unless @run
13
+ raise ArgumentError, "No run script configured for runit service"
14
+ end
15
+ end
16
+
17
+ def roles(*roles)
18
+ @roles = roles unless roles == []
19
+ @roles
20
+ end
21
+
22
+ def run(str=nil)
23
+ @run = str unless str.nil?
24
+ @run
25
+ end
26
+
27
+ def log(str=nil)
28
+ @log = str unless str.nil?
29
+ @log
30
+ end
31
+
32
+ def finish(str=nil)
33
+ @finish = str unless str.nil?
34
+ @finish
35
+ end
36
+
37
+ end
38
+
39
+ # Defines a runit service.
40
+ #
41
+ # @example
42
+ #
43
+ # # A runit directory that your deploy user can write to.
44
+ # # You can set one of these up using runsvdir.
45
+ #
46
+ # set :runit_service_dir, '/etc/service'
47
+ #
48
+ # # The first argument is the name of the service.
49
+ # # The remainder are passed to "on" to decide
50
+ # # which servers to use
51
+ # runit_service 'sidekiq', roles(:sidekiq) do
52
+ #
53
+ # # required, a bash script that execs your app
54
+ # run <<-EOF
55
+ # #!/bin/bash
56
+ # cd /var/www/app
57
+ # exec bundle exec sidekiq 2>&1
58
+ # EOF
59
+ #
60
+ # # optional, a log script that reads stdin/stdout
61
+ # log <<-EOF
62
+ # #!/bin/bash
63
+ # mkdir -p /var/log/app/sidekiq
64
+ # exec syslogd -tt /var/log/app/sidekiq
65
+ # EOF
66
+ #
67
+ # # optional, a finish script that runs when your app quits
68
+ # finish <<-EOF
69
+ # #!/bin/bash
70
+ # echo 'QUIT' >> /var/log/app/sidekiq/current
71
+ # EOF
72
+ #
73
+ # end
74
+ #
75
+ def runit_service(name, &block)
76
+ runit_service_dir = fetch(:runit_service_dir)
77
+
78
+ service = RunitServiceBuilder.new(&block)
79
+
80
+ namespace name do
81
+ desc "Configure #{name} runit"
82
+ task :configure do
83
+ on roles(service.roles) do
84
+ unless test("[ -e #{runit_service_dir}/#{name}/run ]")
85
+ execute <<-EOF
86
+ rm -rf #{runit_service_dir}/#{name}
87
+ mkdir -p #{runit_service_dir}/#{name}/log
88
+ EOF
89
+
90
+ upload! StringIO.new(service.run), "#{runit_service_dir}/#{name}/run"
91
+
92
+ if service.log
93
+ upload! StringIO.new(service.log), "#{runit_service_dir}/#{name}/log/run"
94
+ end
95
+
96
+ if service.finish
97
+ upload! StringIO.new(service.finish), "#{runit_service_dir}/#{name}/finish"
98
+ end
99
+
100
+ execute "chmod +x #{runit_service_dir}/#{name}/run #{runit_service_dir}/#{name}/log/run"
101
+ end
102
+ end
103
+ end
104
+
105
+ desc "Start #{name}"
106
+ task start: :configure do
107
+ on roles(*service.roles) do
108
+ execute "sv start #{runit_service_dir}/#{name}"
109
+ end
110
+ end
111
+
112
+ desc "Stop #{name}"
113
+ task :stop do
114
+ on roles(*service.roles) do
115
+ execute "sv stop #{runit_service_dir}/#{name}"
116
+ end
117
+ end
118
+
119
+ desc "Restart #{name}"
120
+ task restart: :configure do
121
+ on roles(*service.roles) do
122
+ execute "sv restart #{runit_service_dir}/#{name}"
123
+ end
124
+ end
125
+
126
+ desc "Disable #{name}"
127
+ task :disable do
128
+ on roles(*service.roles) do
129
+ execute "rm -rf #{runit_service_dir}/#{name}"
130
+ end
131
+ end
132
+ end
133
+ end
134
+
@@ -0,0 +1 @@
1
+ require 'cap-runit'
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cap-runit
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Conrad Irwin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ description: Template for managing runit directories with capistrano 3
28
+ email:
29
+ - conrad@bugsnag.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - cap-runit.gemspec
36
+ - lib/cap-runit.rb
37
+ - lib/capistrano/runit.rb
38
+ homepage: http://github.com/ConradIrwin/cap-runit
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.0.3
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: Capistrano 3 Runit integration
62
+ test_files: []
63
+ has_rdoc: