puma 3.0.0.rc1 → 5.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puma might be problematic. Click here for more details.

Files changed (91) hide show
  1. checksums.yaml +5 -5
  2. data/{History.txt → History.md} +703 -70
  3. data/LICENSE +23 -20
  4. data/README.md +173 -163
  5. data/docs/architecture.md +37 -0
  6. data/{DEPLOYMENT.md → docs/deployment.md} +28 -6
  7. data/docs/fork_worker.md +31 -0
  8. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  9. data/docs/images/puma-connection-flow.png +0 -0
  10. data/docs/images/puma-general-arch.png +0 -0
  11. data/docs/jungle/README.md +13 -0
  12. data/docs/jungle/rc.d/README.md +74 -0
  13. data/docs/jungle/rc.d/puma +61 -0
  14. data/docs/jungle/rc.d/puma.conf +10 -0
  15. data/{tools → docs}/jungle/upstart/README.md +0 -0
  16. data/{tools → docs}/jungle/upstart/puma-manager.conf +0 -0
  17. data/{tools → docs}/jungle/upstart/puma.conf +1 -1
  18. data/docs/nginx.md +2 -2
  19. data/docs/plugins.md +38 -0
  20. data/docs/restart.md +41 -0
  21. data/docs/signals.md +57 -3
  22. data/docs/systemd.md +228 -0
  23. data/ext/puma_http11/PumaHttp11Service.java +2 -2
  24. data/ext/puma_http11/extconf.rb +16 -0
  25. data/ext/puma_http11/http11_parser.c +287 -468
  26. data/ext/puma_http11/http11_parser.h +1 -0
  27. data/ext/puma_http11/http11_parser.java.rl +21 -37
  28. data/ext/puma_http11/http11_parser.rl +10 -9
  29. data/ext/puma_http11/http11_parser_common.rl +4 -4
  30. data/ext/puma_http11/mini_ssl.c +159 -10
  31. data/ext/puma_http11/org/jruby/puma/Http11.java +108 -116
  32. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +99 -132
  33. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +30 -6
  34. data/ext/puma_http11/puma_http11.c +6 -38
  35. data/lib/puma.rb +25 -5
  36. data/lib/puma/accept_nonblock.rb +7 -1
  37. data/lib/puma/app/status.rb +53 -26
  38. data/lib/puma/binder.rb +150 -119
  39. data/lib/puma/cli.rb +56 -38
  40. data/lib/puma/client.rb +277 -80
  41. data/lib/puma/cluster.rb +326 -130
  42. data/lib/puma/commonlogger.rb +21 -20
  43. data/lib/puma/configuration.rb +160 -161
  44. data/lib/puma/const.rb +50 -47
  45. data/lib/puma/control_cli.rb +104 -63
  46. data/lib/puma/detect.rb +13 -1
  47. data/lib/puma/dsl.rb +463 -114
  48. data/lib/puma/events.rb +22 -13
  49. data/lib/puma/io_buffer.rb +9 -5
  50. data/lib/puma/jruby_restart.rb +2 -59
  51. data/lib/puma/launcher.rb +195 -105
  52. data/lib/puma/minissl.rb +110 -4
  53. data/lib/puma/minissl/context_builder.rb +76 -0
  54. data/lib/puma/null_io.rb +9 -14
  55. data/lib/puma/plugin.rb +32 -12
  56. data/lib/puma/plugin/tmp_restart.rb +19 -6
  57. data/lib/puma/rack/builder.rb +7 -5
  58. data/lib/puma/rack/urlmap.rb +11 -8
  59. data/lib/puma/rack_default.rb +2 -0
  60. data/lib/puma/reactor.rb +242 -32
  61. data/lib/puma/runner.rb +41 -30
  62. data/lib/puma/server.rb +265 -183
  63. data/lib/puma/single.rb +22 -63
  64. data/lib/puma/state_file.rb +9 -2
  65. data/lib/puma/thread_pool.rb +179 -68
  66. data/lib/puma/util.rb +3 -11
  67. data/lib/rack/handler/puma.rb +60 -11
  68. data/tools/Dockerfile +16 -0
  69. data/tools/trickletest.rb +1 -2
  70. metadata +35 -99
  71. data/COPYING +0 -55
  72. data/Gemfile +0 -13
  73. data/Manifest.txt +0 -79
  74. data/Rakefile +0 -158
  75. data/docs/config.md +0 -0
  76. data/ext/puma_http11/io_buffer.c +0 -155
  77. data/lib/puma/capistrano.rb +0 -94
  78. data/lib/puma/compat.rb +0 -18
  79. data/lib/puma/convenient.rb +0 -23
  80. data/lib/puma/daemon_ext.rb +0 -31
  81. data/lib/puma/delegation.rb +0 -11
  82. data/lib/puma/java_io_buffer.rb +0 -45
  83. data/lib/puma/rack/backports/uri/common_18.rb +0 -56
  84. data/lib/puma/rack/backports/uri/common_192.rb +0 -52
  85. data/lib/puma/rack/backports/uri/common_193.rb +0 -29
  86. data/lib/puma/tcp_logger.rb +0 -32
  87. data/puma.gemspec +0 -52
  88. data/tools/jungle/README.md +0 -9
  89. data/tools/jungle/init.d/README.md +0 -54
  90. data/tools/jungle/init.d/puma +0 -394
  91. data/tools/jungle/init.d/run-puma +0 -3
@@ -1,18 +0,0 @@
1
- # Provides code to work properly on 1.8 and 1.9
2
-
3
- class String
4
- unless method_defined? :bytesize
5
- alias_method :bytesize, :size
6
- end
7
-
8
- unless method_defined? :byteslice
9
- if RUBY_VERSION < '1.9'
10
- alias_method :byteslice, :[]
11
- else
12
- def byteslice(*arg)
13
- enc = self.encoding
14
- self.dup.force_encoding(Encoding::ASCII_8BIT).slice(*arg).force_encoding(enc)
15
- end
16
- end
17
- end
18
- end
@@ -1,23 +0,0 @@
1
- require 'puma/launcher'
2
- require 'puma/configuration'
3
-
4
- module Puma
5
- def self.run(opts={})
6
- cfg = Puma::Configuration.new do |c|
7
- if port = opts[:port]
8
- c.port port
9
- end
10
-
11
- c.quiet
12
-
13
- yield c
14
- end
15
-
16
- cfg.clamp
17
-
18
- events = Puma::Events.null
19
-
20
- launcher = Puma::Launcher.new cfg, :events => events
21
- launcher.run
22
- end
23
- end
@@ -1,31 +0,0 @@
1
- module Process
2
-
3
- # This overrides the default version because it is broken if it
4
- # exists.
5
-
6
- if respond_to? :daemon
7
- class << self
8
- remove_method :daemon
9
- end
10
- end
11
-
12
- def self.daemon(nochdir=false, noclose=false)
13
- exit if fork # Parent exits, child continues.
14
-
15
- Process.setsid # Become session leader.
16
-
17
- exit if fork # Zap session leader. See [1].
18
-
19
- Dir.chdir "/" unless nochdir # Release old working directory.
20
-
21
- if !noclose
22
- STDIN.reopen File.open("/dev/null", "r")
23
-
24
- null_out = File.open "/dev/null", "w"
25
- STDOUT.reopen null_out
26
- STDERR.reopen null_out
27
- end
28
-
29
- 0
30
- end
31
- end
@@ -1,11 +0,0 @@
1
- module Puma
2
- module Delegation
3
- def forward(what, who)
4
- module_eval <<-CODE
5
- def #{what}(*args, &block)
6
- #{who}.#{what}(*args, &block)
7
- end
8
- CODE
9
- end
10
- end
11
- end
@@ -1,45 +0,0 @@
1
- require 'java'
2
-
3
- # Conservative native JRuby/Java implementation of IOBuffer
4
- # backed by a ByteArrayOutputStream and conversion between
5
- # Ruby String and Java bytes
6
- module Puma
7
- class JavaIOBuffer < java.io.ByteArrayOutputStream
8
- field_reader :buf
9
- end
10
-
11
- class IOBuffer
12
- BUF_DEFAULT_SIZE = 4096
13
-
14
- def initialize
15
- @buf = JavaIOBuffer.new(BUF_DEFAULT_SIZE)
16
- end
17
-
18
- def reset
19
- @buf.reset
20
- end
21
-
22
- def <<(str)
23
- bytes = str.to_java_bytes
24
- @buf.write(bytes, 0, bytes.length)
25
- end
26
-
27
- def append(*strs)
28
- strs.each { |s| self << s; }
29
- end
30
-
31
- def to_s
32
- String.from_java_bytes @buf.to_byte_array
33
- end
34
-
35
- alias_method :to_str, :to_s
36
-
37
- def used
38
- @buf.size
39
- end
40
-
41
- def capacity
42
- @buf.buf.length
43
- end
44
- end
45
- end
@@ -1,56 +0,0 @@
1
- # :stopdoc:
2
-
3
- # Stolen from ruby core's uri/common.rb, with modifications to support 1.8.x
4
- #
5
- # https://github.com/ruby/ruby/blob/trunk/lib/uri/common.rb
6
- #
7
- #
8
-
9
- module URI
10
- TBLENCWWWCOMP_ = {} # :nodoc:
11
- 256.times do |i|
12
- TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
13
- end
14
- TBLENCWWWCOMP_[' '] = '+'
15
- TBLENCWWWCOMP_.freeze
16
- TBLDECWWWCOMP_ = {} # :nodoc:
17
- 256.times do |i|
18
- h, l = i>>4, i&15
19
- TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
20
- TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
21
- TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
22
- TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
23
- end
24
- TBLDECWWWCOMP_['+'] = ' '
25
- TBLDECWWWCOMP_.freeze
26
-
27
- # Encode given +s+ to URL-encoded form data.
28
- #
29
- # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
30
- # (ASCII space) to + and converts others to %XX.
31
- #
32
- # This is an implementation of
33
- # http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
34
- #
35
- # See URI.decode_www_form_component, URI.encode_www_form
36
- def self.encode_www_form_component(s)
37
- str = s.to_s
38
- if RUBY_VERSION < "1.9" && $KCODE =~ /u/i
39
- str.gsub(/([^ a-zA-Z0-9_.-]+)/) do
40
- '%' + $1.unpack('H2' * Rack::Utils.bytesize($1)).join('%').upcase
41
- end.tr(' ', '+')
42
- else
43
- str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]}
44
- end
45
- end
46
-
47
- # Decode given +str+ of URL-encoded form data.
48
- #
49
- # This decodes + to SP.
50
- #
51
- # See URI.encode_www_form_component, URI.decode_www_form
52
- def self.decode_www_form_component(str, enc=nil)
53
- raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%])*\z/ =~ str
54
- str.gsub(/\+|%[0-9a-fA-F]{2}/) {|m| TBLDECWWWCOMP_[m]}
55
- end
56
- end
@@ -1,52 +0,0 @@
1
- # :stopdoc:
2
-
3
- # Stolen from ruby core's uri/common.rb @32618ba to fix DoS issues in 1.9.2
4
- #
5
- # https://github.com/ruby/ruby/blob/32618ba7438a2247042bba9b5d85b5d49070f5e5/lib/uri/common.rb
6
- #
7
- # Issue:
8
- # http://redmine.ruby-lang.org/issues/5149
9
- #
10
- # Relevant Fixes:
11
- # https://github.com/ruby/ruby/commit/b5f91deee04aa6ccbe07c23c8222b937c22a799b
12
- # https://github.com/ruby/ruby/commit/93177c1e5c3906abf14472ae0b905d8b5c72ce1b
13
- #
14
- # This should probably be removed once there is a Ruby 1.9.2 patch level that
15
- # includes this fix.
16
-
17
- require 'uri/common'
18
-
19
- module URI
20
- TBLDECWWWCOMP_ = {} unless const_defined?(:TBLDECWWWCOMP_) #:nodoc:
21
- if TBLDECWWWCOMP_.empty?
22
- 256.times do |i|
23
- h, l = i>>4, i&15
24
- TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
25
- TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
26
- TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
27
- TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
28
- end
29
- TBLDECWWWCOMP_['+'] = ' '
30
- TBLDECWWWCOMP_.freeze
31
- end
32
-
33
- def self.decode_www_form(str, enc=Encoding::UTF_8)
34
- return [] if str.empty?
35
- unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/o =~ str
36
- raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})"
37
- end
38
- ary = []
39
- $&.scan(/([^=;&]+)=([^;&]*)/) do
40
- ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)]
41
- end
42
- ary
43
- end
44
-
45
- def self.decode_www_form_component(str, enc=Encoding::UTF_8)
46
- raise ArgumentError, "invalid %-encoding (#{str})" unless /\A[^%]*(?:%\h\h[^%]*)*\z/ =~ str
47
- str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc)
48
- end
49
-
50
- remove_const :WFKV_ if const_defined?(:WFKV_)
51
- WFKV_ = '(?:[^%#=;&]*(?:%\h\h[^%#=;&]*)*)' # :nodoc:
52
- end
@@ -1,29 +0,0 @@
1
- # :stopdoc:
2
-
3
- require 'uri/common'
4
-
5
- # Issue:
6
- # http://bugs.ruby-lang.org/issues/5925
7
- #
8
- # Relevant commit:
9
- # https://github.com/ruby/ruby/commit/edb7cdf1eabaff78dfa5ffedfbc2e91b29fa9ca1
10
-
11
- module URI
12
- 256.times do |i|
13
- TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
14
- end
15
- TBLENCWWWCOMP_[' '] = '+'
16
- TBLENCWWWCOMP_.freeze
17
-
18
- 256.times do |i|
19
- h, l = i>>4, i&15
20
- TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
21
- TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
22
- TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
23
- TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
24
- end
25
- TBLDECWWWCOMP_['+'] = ' '
26
- TBLDECWWWCOMP_.freeze
27
- end
28
-
29
- # :startdoc:
@@ -1,32 +0,0 @@
1
- module Puma
2
- class TCPLogger
3
- def initialize(logger, app, quiet=false)
4
- @logger = logger
5
- @app = app
6
- @quiet = quiet
7
- end
8
-
9
- FORMAT = "%s - %s"
10
-
11
- def log(who, str)
12
- now = Time.now.strftime("%d/%b/%Y %H:%M:%S")
13
-
14
- @logger.puts "#{now} - #{who} - #{str}"
15
- end
16
-
17
- def call(env, socket)
18
- who = env[Const::REMOTE_ADDR]
19
- log who, "connected" unless @quiet
20
-
21
- env['log'] = lambda { |str| log(who, str) }
22
-
23
- begin
24
- @app.call env, socket
25
- rescue Object => e
26
- log who, "exception: #{e.message} (#{e.class})"
27
- else
28
- log who, "disconnected" unless @quiet
29
- end
30
- end
31
- end
32
- end
@@ -1,52 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- # This is only used when puma is a git dep from Bundler, so it's a little
4
- # weird.
5
-
6
- d = File.read(File.expand_path("../lib/puma/const.rb", __FILE__))
7
- if d =~ /VERSION = "(\d+\.\d+\.\d+)"/
8
- version = $1
9
- else
10
- version = "0.0.1"
11
- end
12
-
13
- Gem::Specification.new do |s|
14
- s.name = "puma"
15
- s.version = version
16
-
17
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
18
- s.authors = ["Evan Phoenix"]
19
- s.date = `git log --pretty="%ai" -n 1`.split(" ").first
20
- s.description = "Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications. Puma is intended for use in both development and production environments. In order to get the best throughput, it is highly recommended that you use a Ruby implementation with real threads like Rubinius or JRuby."
21
- s.email = ["evan@phx.io"]
22
- s.executables = ["puma", "pumactl"]
23
- s.extensions = ["ext/puma_http11/extconf.rb"]
24
- s.files = `git ls-files`.split($/)
25
- s.homepage = "http://puma.io"
26
- s.license = "BSD-3-Clause"
27
- s.rdoc_options = ["--main", "README.md"]
28
- s.require_paths = ["lib"]
29
- s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
30
- s.rubyforge_project = "puma"
31
- s.rubygems_version = "1.8.25"
32
- s.summary = "Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications"
33
- s.test_files = s.files.grep(/^test/)
34
-
35
- if s.respond_to? :specification_version then
36
- s.specification_version = 3
37
-
38
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
39
- s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
40
- s.add_development_dependency(%q<rake-compiler>, ["~> 0.8.0"])
41
- s.add_development_dependency(%q<hoe>, ["~> 3.6"])
42
- else
43
- s.add_dependency(%q<rdoc>, ["~> 4.0"])
44
- s.add_dependency(%q<rake-compiler>, ["~> 0.8.0"])
45
- s.add_dependency(%q<hoe>, ["~> 3.6"])
46
- end
47
- else
48
- s.add_dependency(%q<rdoc>, ["~> 4.0"])
49
- s.add_dependency(%q<rake-compiler>, ["~> 0.8.0"])
50
- s.add_dependency(%q<hoe>, ["~> 3.6"])
51
- end
52
- end
@@ -1,9 +0,0 @@
1
- # Puma as a service
2
-
3
- ## Init.d
4
-
5
- See `/tools/jungle/init.d` for tools to use with init.d and start-stop-daemon.
6
-
7
- ## Upstart
8
-
9
- See `/tools/jungle/upstart` for Ubuntu's upstart scripts.
@@ -1,54 +0,0 @@
1
- # Puma daemon service
2
-
3
- Init script to manage multiple Puma servers on the same box using start-stop-daemon.
4
-
5
- ## Installation
6
-
7
- # Copy the init script to services directory
8
- sudo cp puma /etc/init.d
9
- sudo chmod +x /etc/init.d/puma
10
-
11
- # Make it start at boot time.
12
- sudo update-rc.d -f puma defaults
13
-
14
- # Copy the Puma runner to an accessible location
15
- sudo cp run-puma /usr/local/bin
16
- sudo chmod +x /usr/local/bin/run-puma
17
-
18
- # Create an empty configuration file
19
- sudo touch /etc/puma.conf
20
-
21
- ## Managing the jungle
22
-
23
- Puma apps are held in /etc/puma.conf by default. It's mainly a CSV file and every line represents one app. Here's the syntax:
24
-
25
- app-path,user,config-file-path,log-file-path
26
-
27
- You can add an instance by editing the file or running the following command:
28
-
29
- sudo /etc/init.d/puma add /path/to/app user /path/to/app/config/puma.rb /path/to/app/log/puma.log
30
-
31
- The config and log paths are optional parameters and default to:
32
-
33
- * config: /path/to/app/*config/puma.rb*
34
- * log: /path/to/app/*log/puma.log*
35
-
36
- To remove an app, simply delete the line from the config file or run:
37
-
38
- sudo /etc/init.d/puma remove /path/to/app
39
-
40
- The command will make sure the Puma instance stops before removing it from the jungle.
41
-
42
- ## Assumptions
43
-
44
- * The script expects a temporary folder named /path/to/app/*tmp/puma* to exist. Create it if it's not there by default.
45
- The pid and state files should live there and must be called: *tmp/puma/pid* and *tmp/puma/state*.
46
- You can change those if you want but you'll have to adapt the script for it to work.
47
-
48
- * Here's what a minimal app's config file should have:
49
-
50
- ```
51
- pidfile "/path/to/app/tmp/puma/pid"
52
- state_path "/path/to/app/tmp/puma/state"
53
- activate_control_app
54
- ```
@@ -1,394 +0,0 @@
1
- #! /bin/sh
2
- ### BEGIN INIT INFO
3
- # Provides: puma
4
- # Required-Start: $remote_fs $syslog
5
- # Required-Stop: $remote_fs $syslog
6
- # Default-Start: 2 3 4 5
7
- # Default-Stop: 0 1 6
8
- # Short-Description: Example initscript
9
- # Description: This file should be used to construct scripts to be
10
- # placed in /etc/init.d.
11
- ### END INIT INFO
12
-
13
- # Author: Darío Javier Cravero <dario@exordo.com>
14
- #
15
- # Do NOT "set -e"
16
-
17
- # PATH should only include /usr/* if it runs after the mountnfs.sh script
18
- PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin
19
- DESC="Puma rack web server"
20
- NAME=puma
21
- DAEMON=$NAME
22
- SCRIPTNAME=/etc/init.d/$NAME
23
- CONFIG=/etc/puma.conf
24
- JUNGLE=`cat $CONFIG`
25
- RUNPUMA=/usr/local/bin/run-puma
26
- USE_LOCAL_BUNDLE=0
27
-
28
- # Load the VERBOSE setting and other rcS variables
29
- . /lib/init/vars.sh
30
-
31
- # Define LSB log_* functions.
32
- # Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
33
- . /lib/lsb/init-functions
34
-
35
- #
36
- # Function that starts the jungle
37
- #
38
- do_start() {
39
- log_daemon_msg "=> Running the jungle..."
40
- for i in $JUNGLE; do
41
- dir=`echo $i | cut -d , -f 1`
42
- user=`echo $i | cut -d , -f 2`
43
- config_file=`echo $i | cut -d , -f 3`
44
- if [ "$config_file" = "" ]; then
45
- config_file="$dir/config/puma.rb"
46
- fi
47
- log_file=`echo $i | cut -d , -f 4`
48
- if [ "$log_file" = "" ]; then
49
- log_file="$dir/log/puma.log"
50
- fi
51
- environment=`echo $i | cut -d , -f 5`
52
- do_start_one $dir $user $config_file $log_file $environment
53
- done
54
- }
55
-
56
- do_start_one() {
57
- PIDFILE=$1/tmp/puma/pid
58
- if [ -e $PIDFILE ]; then
59
- PID=`cat $PIDFILE`
60
- # If the puma isn't running, run it, otherwise restart it.
61
- if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
62
- do_start_one_do $1 $2 $3 $4 $5
63
- else
64
- do_restart_one $1
65
- fi
66
- else
67
- do_start_one_do $1 $2 $3 $4 $5
68
- fi
69
- }
70
-
71
- do_start_one_do() {
72
- log_daemon_msg "--> Woke up puma $1"
73
- log_daemon_msg "user $2"
74
- log_daemon_msg "log to $4"
75
-
76
- if [ ! -z "$5" ]; then
77
- for e in $(echo "$5" | tr ';' '\n'); do
78
- log_daemon_msg "environment $e"
79
- v=${e%%\=*} ; eval "$e" ; export $v
80
- done
81
- fi
82
-
83
- start-stop-daemon --verbose --start --chdir $1 --chuid $2 --background --exec $RUNPUMA -- $1 $3 $4
84
- }
85
-
86
- #
87
- # Function that stops the jungle
88
- #
89
- do_stop() {
90
- log_daemon_msg "=> Putting all the beasts to bed..."
91
- for i in $JUNGLE; do
92
- dir=`echo $i | cut -d , -f 1`
93
- do_stop_one $dir
94
- done
95
- }
96
- #
97
- # Function that stops the daemon/service
98
- #
99
- do_stop_one() {
100
- log_daemon_msg "--> Stopping $1"
101
- PIDFILE=$1/tmp/puma/pid
102
- STATEFILE=$1/tmp/puma/state
103
- if [ -e $PIDFILE ]; then
104
- PID=`cat $PIDFILE`
105
- if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
106
- log_daemon_msg "---> Puma $1 isn't running."
107
- else
108
- log_daemon_msg "---> About to kill PID `cat $PIDFILE`"
109
- if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
110
- cd $1 && bundle exec pumactl --state $STATEFILE stop
111
- else
112
- pumactl --state $STATEFILE stop
113
- fi
114
- # Many daemons don't delete their pidfiles when they exit.
115
- rm -f $PIDFILE $STATEFILE
116
- fi
117
- else
118
- log_daemon_msg "---> No puma here..."
119
- fi
120
- return 0
121
- }
122
-
123
- #
124
- # Function that restarts the jungle
125
- #
126
- do_restart() {
127
- for i in $JUNGLE; do
128
- dir=`echo $i | cut -d , -f 1`
129
- do_restart_one $dir
130
- done
131
- }
132
-
133
- #
134
- # Function that sends a SIGUSR2 to the daemon/service
135
- #
136
- do_restart_one() {
137
- PIDFILE=$1/tmp/puma/pid
138
- i=`grep $1 $CONFIG`
139
- dir=`echo $i | cut -d , -f 1`
140
-
141
- if [ -e $PIDFILE ]; then
142
- log_daemon_msg "--> About to restart puma $1"
143
- if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
144
- cd $1 && bundle exec pumactl --state $dir/tmp/puma/state restart
145
- else
146
- pumactl --state $dir/tmp/puma/state restart
147
- fi
148
- # kill -s USR2 `cat $PIDFILE`
149
- # TODO Check if process exist
150
- else
151
- log_daemon_msg "--> Your puma was never playing... Let's get it out there first"
152
- user=`echo $i | cut -d , -f 2`
153
- config_file=`echo $i | cut -d , -f 3`
154
- if [ "$config_file" = "" ]; then
155
- config_file="$dir/config/puma.rb"
156
- fi
157
- log_file=`echo $i | cut -d , -f 4`
158
- if [ "$log_file" = "" ]; then
159
- log_file="$dir/log/puma.log"
160
- fi
161
- environment=`echo $i | cut -d , -f 5`
162
- do_start_one $dir $user $config_file $log_file $environment
163
- fi
164
- return 0
165
- }
166
-
167
- #
168
- # Function that statuss the jungle
169
- #
170
- do_status() {
171
- for i in $JUNGLE; do
172
- dir=`echo $i | cut -d , -f 1`
173
- do_status_one $dir
174
- done
175
- }
176
-
177
- #
178
- # Function that sends a SIGUSR2 to the daemon/service
179
- #
180
- do_status_one() {
181
- PIDFILE=$1/tmp/puma/pid
182
- i=`grep $1 $CONFIG`
183
- dir=`echo $i | cut -d , -f 1`
184
-
185
- if [ -e $PIDFILE ]; then
186
- log_daemon_msg "--> About to status puma $1"
187
- if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
188
- cd $1 && bundle exec pumactl --state $dir/tmp/puma/state stats
189
- else
190
- pumactl --state $dir/tmp/puma/state stats
191
- fi
192
- # kill -s USR2 `cat $PIDFILE`
193
- # TODO Check if process exist
194
- else
195
- log_daemon_msg "--> $1 isn't there :(..."
196
- fi
197
- return 0
198
- }
199
-
200
- do_add() {
201
- str=""
202
- # App's directory
203
- if [ -d "$1" ]; then
204
- if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then
205
- str=$1
206
- else
207
- echo "The app is already being managed. Remove it if you want to update its config."
208
- exit 1
209
- fi
210
- else
211
- echo "The directory $1 doesn't exist."
212
- exit 1
213
- fi
214
- # User to run it as
215
- if [ "`grep -c "^$2:" /etc/passwd`" -eq 0 ]; then
216
- echo "The user $2 doesn't exist."
217
- exit 1
218
- else
219
- str="$str,$2"
220
- fi
221
- # Config file
222
- if [ "$3" != "" ]; then
223
- if [ -e $3 ]; then
224
- str="$str,$3"
225
- else
226
- echo "The config file $3 doesn't exist."
227
- exit 1
228
- fi
229
- fi
230
- # Log file
231
- if [ "$4" != "" ]; then
232
- str="$str,$4"
233
- fi
234
-
235
- # Environment variables
236
- if [ "$5" != "" ]; then
237
- str="$str,$5"
238
- fi
239
-
240
- # Add it to the jungle
241
- echo $str >> $CONFIG
242
- log_daemon_msg "Added a Puma to the jungle: $str. You still have to start it though."
243
- }
244
-
245
- do_remove() {
246
- if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then
247
- echo "There's no app $1 to remove."
248
- else
249
- # Stop it first.
250
- do_stop_one $1
251
- # Remove it from the config.
252
- sed -i "\\:^$1:d" $CONFIG
253
- log_daemon_msg "Removed a Puma from the jungle: $1."
254
- fi
255
- }
256
-
257
- config_bundler() {
258
- HOME="$(eval echo ~$(id -un))"
259
- if [ -d "/usr/local/rbenv/bin" ]; then
260
- PATH="/usr/local/rbenv/bin:/usr/local/rbenv/shims:$PATH"
261
- eval "$(rbenv init -)"
262
- USE_LOCAL_BUNDLE=1
263
- return 0
264
- elif [ -d "$HOME/.rbenv/bin" ]; then
265
- PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
266
- eval "$(rbenv init -)"
267
- USE_LOCAL_BUNDLE=1
268
- return 0
269
- # TODO: test rvm
270
- # elif [ -f /etc/profile.d/rvm.sh ]; then
271
- # source /etc/profile.d/rvm.sh
272
- # elif [ -f /usr/local/rvm/scripts/rvm ]; then
273
- # source /etc/profile.d/rvm.sh
274
- # elif [ -f "$HOME/.rvm/scripts/rvm" ]; then
275
- # source "$HOME/.rvm/scripts/rvm"
276
- # TODO: don't know what to do with chruby
277
- # elif [ -f /usr/local/share/chruby/chruby.sh ]; then
278
- # source /usr/local/share/chruby/chruby.sh
279
- # if [ -f /usr/local/share/chruby/auto.sh ]; then
280
- # source /usr/local/share/chruby/auto.sh
281
- # fi
282
- # if you aren't using auto, set your version here
283
- # chruby 2.0.0
284
- fi
285
-
286
- return 1
287
- }
288
-
289
- config_bundler
290
-
291
- case "$1" in
292
- start)
293
- [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
294
- if [ "$#" -eq 1 ]; then
295
- do_start
296
- else
297
- i=`grep $2 $CONFIG`
298
- dir=`echo $i | cut -d , -f 1`
299
- user=`echo $i | cut -d , -f 2`
300
- config_file=`echo $i | cut -d , -f 3`
301
- if [ "$config_file" = "" ]; then
302
- config_file="$dir/config/puma.rb"
303
- fi
304
- log_file=`echo $i | cut -d , -f 4`
305
- if [ "$log_file" = "" ]; then
306
- log_file="$dir/log/puma.log"
307
- fi
308
- do_start_one $dir $user $config_file $log_file
309
- fi
310
- case "$?" in
311
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
312
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
313
- esac
314
- ;;
315
- stop)
316
- [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
317
- if [ "$#" -eq 1 ]; then
318
- do_stop
319
- else
320
- i=`grep $2 $CONFIG`
321
- dir=`echo $i | cut -d , -f 1`
322
- do_stop_one $dir
323
- fi
324
- case "$?" in
325
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
326
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
327
- esac
328
- ;;
329
- status)
330
- # TODO Implement.
331
- log_daemon_msg "Status $DESC" "$NAME"
332
- if [ "$#" -eq 1 ]; then
333
- do_status
334
- else
335
- i=`grep $2 $CONFIG`
336
- dir=`echo $i | cut -d , -f 1`
337
- do_status_one $dir
338
- fi
339
- case "$?" in
340
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
341
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
342
- esac
343
- ;;
344
- restart)
345
- log_daemon_msg "Restarting $DESC" "$NAME"
346
- if [ "$#" -eq 1 ]; then
347
- do_restart
348
- else
349
- i=`grep $2 $CONFIG`
350
- dir=`echo $i | cut -d , -f 1`
351
- do_restart_one $dir
352
- fi
353
- case "$?" in
354
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
355
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
356
- esac
357
- ;;
358
- add)
359
- if [ "$#" -lt 3 ]; then
360
- echo "Please, specifiy the app's directory and the user that will run it at least."
361
- echo " Usage: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
362
- echo " config and log are optionals."
363
- exit 1
364
- else
365
- do_add $2 $3 $4 $5
366
- fi
367
- case "$?" in
368
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
369
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
370
- esac
371
- ;;
372
- remove)
373
- if [ "$#" -lt 2 ]; then
374
- echo "Please, specifiy the app's directory to remove."
375
- exit 1
376
- else
377
- do_remove $2
378
- fi
379
- case "$?" in
380
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
381
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
382
- esac
383
- ;;
384
- *)
385
- echo "Usage:" >&2
386
- echo " Run the jungle: $SCRIPTNAME {start|stop|status|restart}" >&2
387
- echo " Add a Puma: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
388
- echo " config and log are optionals."
389
- echo " Remove a Puma: $SCRIPTNAME remove /path/to/app"
390
- echo " On a Puma: $SCRIPTNAME {start|stop|status|restart} PUMA-NAME" >&2
391
- exit 3
392
- ;;
393
- esac
394
- :