capistrano3-puma 6.0.0.alpha.2 → 6.0.0.alpha.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8994d61613bb960a5e753c753365cf417333d155ea477e8760af443d0f7e7170
4
- data.tar.gz: b7426b4eacc480a6b147635cafb57de7dd69fe20a581d8cea036d8841485564a
3
+ metadata.gz: dc9d3b7a50af328c1bcfad01eb6ea87682d832f9374d28377af3fbb541822c10
4
+ data.tar.gz: 33b973e9d091377a6b33081500837441c4f46e7d02ce5ea4cbe26fa5de9b8217
5
5
  SHA512:
6
- metadata.gz: a50d1881978d12a09369b0c134f831ce87b6718001f819ad62a923823b4072f9c9a698acbf7ef18b4f684f02cc0fd18e14b400e17ebdec81347c1d5515657799
7
- data.tar.gz: e1e9df600d4297b908346403f004614de6f49553295b2cc2431d33a78b75326f3de9d76b3bed6b35a719eb5557c77316b689a761af06c82b69ada0c939c474c0
6
+ metadata.gz: 1e52735bdd57312b44d904463ff0f4df530bff86f8d1f3d6fb88c0c64893104e071b299ea70fd2fbcb5d337e1b4bfa0bab3003c56ba0251173eca361ded38da9
7
+ data.tar.gz: b04d88ed6d87ce4d63f83efefd0a8489f7db5dcb470d292f776fc385daf1341802a6ae24ea17653581e7b621fc6a0ebdb0150e68951d1844e6f8d9e4b87e9d60
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ [Unreleased](https://github.com/seuros/capistrano-puma/compare/v5.2.0...master)
4
+ - Removed support for support for monit and upstart. (will add them back if someone is willing to maintain them)
5
+ - Sync configuration with capistrano-sidekiq
6
+ - Support for notify systemd service. Add sd_notify gem to your Gemfile.
7
+ - Add example application for easier testing.
8
+ - Deprecate Nginx support. (configuration tools should be preferred over capistrano tasks)
9
+
3
10
  ## [5.2.0](https://github.com/seuros/capistrano-puma/tree/5.2.0) (2021-09-11)
4
11
 
5
12
  [Full Changelog](https://github.com/seuros/capistrano-puma/compare/v5.1.1...5.2.0)
data/README.md CHANGED
@@ -22,17 +22,13 @@ And then execute:
22
22
  require 'capistrano/puma'
23
23
  install_plugin Capistrano::Puma # Default puma tasks
24
24
  install_plugin Capistrano::Puma::Systemd
25
- install_plugin Capistrano::Puma::Monit # if you need the monit tasks
26
- install_plugin Capistrano::Puma::Nginx # if you want to upload a nginx site template
27
25
  ```
28
26
 
29
27
  To prevent loading the hooks of the plugin, add false to the load_hooks param.
30
28
  ```ruby
31
29
  # Capfile
32
30
 
33
- require 'capistrano/puma'
34
31
  install_plugin Capistrano::Puma, load_hooks: false # Default puma tasks without hooks
35
- install_plugin Capistrano::Puma::Monit, load_hooks: false # Monit tasks without hooks
36
32
  ```
37
33
 
38
34
  To make it work with rvm, rbenv and chruby, install the plugin after corresponding library inclusion.
@@ -48,61 +44,14 @@ To make it work with rvm, rbenv and chruby, install the plugin after correspondi
48
44
 
49
45
  To list available tasks use `cap -T`
50
46
 
51
- To upload puma config use:
52
- ```ruby
53
- cap production puma:config
54
- ```
55
- By default the file located in `shared/puma.rb`
56
-
57
47
 
58
48
  Ensure that `tmp/pids` and ` tmp/sockets log` are shared (via `linked_dirs`):
59
49
 
60
50
  `This step is mandatory before deploying, otherwise puma server won't start`
61
51
 
62
- ### Nginx
63
-
64
- To upload a nginx site config (eg. /etc/nginx/sites-enabled/) use:
65
- ```ruby
66
- cap production puma:nginx_config
67
- ```
52
+ ## Example
68
53
 
69
- To customize these two templates locally before uploading use:
70
- ```
71
- rails g capistrano:nginx_puma:config
72
- ```
73
-
74
- if your nginx server configuration is not located in `/etc/nginx`, you may need to customize:
75
- ```ruby
76
- set :nginx_sites_available_path, "/etc/nginx/sites-available"
77
- set :nginx_sites_enabled_path, "/etc/nginx/sites-enabled"
78
- ```
79
-
80
- By default, `nginx_config` will be executed with `:web` role. But you can assign it to a different role:
81
- ```ruby
82
- set :puma_nginx, :foo
83
- ```
84
- or define a standalone one:
85
- ```ruby
86
- role :puma_nginx, %w{root@example.com}
87
- ```
88
-
89
- To use customize environment variables
90
-
91
- ```ruby
92
- set :puma_service_unit_env_file, '/etc/environment'
93
- ```
94
- ```ruby
95
- set :puma_service_unit_env_vars, %w[
96
- RAILS_ENV=development
97
- PUMA_METRICS_HTTP=tcp://0.0.0.0:9393
98
- ]
99
- ```
100
-
101
- To use [phased restart](https://github.com/puma/puma/blob/master/docs/restart.md) for zero downtime deployments:
102
-
103
- ```ruby
104
- set :puma_phased_restart, true
105
- ```
54
+ A sample application is provided to show how to use this gem at https://github.com/seuros/capistrano-example-app
106
55
 
107
56
  ### Systemd Socket Activation
108
57
 
@@ -120,48 +69,15 @@ cap puma:systemd:restart_socket
120
69
  ```
121
70
  This would also restart the puma instance as the puma service depends on the socket service being active
122
71
 
123
- ### Multi bind
124
-
125
- Multi-bind can be set with an array in the puma_bind variable
126
- ```ruby
127
- set :puma_bind, %w(tcp://0.0.0.0:9292 unix:///tmp/puma.sock)
128
- ```
129
- * Listening on tcp://0.0.0.0:9292
130
- * Listening on unix:///tmp/puma.sock
131
-
132
- ### Active Record
133
-
134
- For ActiveRecord the following line to your deploy.rb
135
- ```ruby
136
- set :puma_init_active_record, true
137
- ```
138
-
139
72
  ### Other configs
140
73
 
141
74
  Configurable options, shown here with defaults: Please note the configuration options below are not required unless you are trying to override a default setting, for instance if you are deploying on a host on which you do not have sudo or root privileges and you need to restrict the path. These settings go in the deploy.rb file.
142
75
 
143
76
  ```ruby
144
77
  set :puma_user, fetch(:user)
145
- set :puma_role, :app
146
- set :puma_service_unit_name, "puma_#{fetch(:application)}_#{fetch(:stage)}"
147
- set :puma_systemctl_user, :system # accepts :user
148
- set :puma_enable_lingering, fetch(:puma_systemctl_user) != :system # https://wiki.archlinux.org/index.php/systemd/User#Automatic_start-up_of_systemd_user_instances
149
- set :puma_lingering_user, fetch(:user)
150
- set :puma_service_unit_env_file, nil
78
+ set :puma_role, :web
79
+ set :puma_service_unit_env_files, []
151
80
  set :puma_service_unit_env_vars, []
152
-
153
- set :nginx_config_name, "#{fetch(:application)}_#{fetch(:stage)}"
154
- set :nginx_flags, 'fail_timeout=0'
155
- set :nginx_http_flags, fetch(:nginx_flags)
156
- set :nginx_server_name, "localhost #{fetch(:application)}.local"
157
- set :nginx_sites_available_path, '/etc/nginx/sites-available'
158
- set :nginx_sites_enabled_path, '/etc/nginx/sites-enabled'
159
- set :nginx_socket_flags, fetch(:nginx_flags)
160
- set :nginx_ssl_certificate, "/etc/ssl/certs/#{fetch(:nginx_config_name)}.crt"
161
- set :nginx_ssl_certificate_key, "/etc/ssl/private/#{fetch(:nginx_config_name)}.key"
162
- set :nginx_use_ssl, false
163
- set :nginx_use_http2, true
164
- set :nginx_downstream_uses_ssl, false
165
81
  ```
166
82
 
167
83
  __Notes:__ If you are setting values for variables that might be used by other plugins, use `append` instead of `set`. For example:
@@ -169,6 +85,9 @@ __Notes:__ If you are setting values for variables that might be used by other p
169
85
  append :rbenv_map_bins, 'puma', 'pumactl'
170
86
  ```
171
87
 
88
+ # Nginx documentation
89
+ Nginx documentation was moved to [nginx.md](docs/nginx.md)
90
+
172
91
  ## Contributing
173
92
 
174
93
  1. Fork it
@@ -12,15 +12,15 @@ module Capistrano
12
12
 
13
13
  def set_defaults
14
14
  set_if_empty :puma_systemctl_bin, -> { fetch(:systemctl_bin, '/bin/systemctl') }
15
- set_if_empty :puma_service_unit_name, -> { "puma_#{fetch(:application)}_#{fetch(:stage)}" }
16
- set_if_empty :puma_enable_socket_service, -> { false }
17
- set_if_empty :puma_phased_restart, -> { false }
15
+ set_if_empty :puma_service_unit_name, -> { "#{fetch(:application)}_puma_#{fetch(:stage)}" }
16
+ set_if_empty :puma_enable_socket_service, false
17
+
18
+ set_if_empty :puma_service_unit_env_files, -> { fetch(:service_unit_env_files, []) }
19
+ set_if_empty :puma_service_unit_env_vars, -> { fetch(:service_unit_env_vars, []) }
18
20
 
19
21
  set_if_empty :puma_systemctl_user, -> { fetch(:systemctl_user, :user) }
20
22
  set_if_empty :puma_enable_lingering, -> { fetch(:puma_systemctl_user) != :system }
21
23
  set_if_empty :puma_lingering_user, -> { fetch(:lingering_user, fetch(:user)) }
22
- set_if_empty :puma_access_log, -> { File.join(shared_path, 'log', "#{fetch(:puma_env)}.log") }
23
- set_if_empty :puma_error_log, -> { File.join(shared_path, 'log', "#{fetch(:puma_env)}.log") }
24
24
 
25
25
  set_if_empty :puma_service_templates_path, fetch(:service_templates_path, 'config/deploy/templates')
26
26
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capistrano
4
- PUMAVERSION = '6.0.0.alpha.2'
4
+ PUMAVERSION = '6.0.0.alpha.3'
5
5
  end
@@ -28,6 +28,15 @@ module Capistrano
28
28
  end.join("\n")
29
29
  end
30
30
 
31
+ def service_unit_type
32
+ ## Jruby don't support notify
33
+ return "simple" if RUBY_ENGINE == "jruby"
34
+ fetch(:puma_service_unit_type,
35
+ ## Check if sd_notify is available in the bundle
36
+ Gem::Specification.find_all_by_name("sd_notify").any? ? "notify" : "simple")
37
+
38
+ end
39
+
31
40
  def compiled_template_puma(from, role)
32
41
  @role = role
33
42
  file = [
@@ -95,13 +104,15 @@ module Capistrano
95
104
  include PumaCommon
96
105
 
97
106
  def set_defaults
98
- set_if_empty :puma_role, :app
107
+ set_if_empty :puma_role, :web
99
108
  set_if_empty :puma_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:stage))) }
109
+ set_if_empty :puma_access_log, -> { File.join(shared_path, 'log', "puma.log") }
110
+ set_if_empty :puma_error_log, -> { File.join(shared_path, 'log', "puma.log") }
100
111
 
101
112
  # Chruby, Rbenv and RVM integration
102
- append :chruby_map_bins, 'puma', 'pumactl'
103
- append :rbenv_map_bins, 'puma', 'pumactl'
104
- append :rvm_map_bins, 'puma', 'pumactl'
113
+ append :chruby_map_bins, 'puma', 'pumactl' if fetch(:chruby_map_bins)
114
+ append :rbenv_map_bins, 'puma', 'pumactl' if fetch(:rbenv_map_bins)
115
+ append :rvm_map_bins, 'puma', 'pumactl' if fetch(:rvm_map_bins)
105
116
 
106
117
  # Bundler integration
107
118
  append :bundle_bins, 'puma', 'pumactl'
@@ -110,5 +121,3 @@ module Capistrano
110
121
  end
111
122
 
112
123
  require 'capistrano/puma/systemd'
113
- require 'capistrano/puma/monit'
114
- require 'capistrano/puma/nginx'
@@ -26,6 +26,7 @@ namespace :puma do
26
26
 
27
27
  # Reload systemd
28
28
  git_plugin.execute_systemd("daemon-reload")
29
+ invoke "puma:enable"
29
30
  end
30
31
  end
31
32
 
@@ -15,19 +15,19 @@ Description=Puma HTTP Server for <%= "#{fetch(:application)} (#{fetch(:stage)})"
15
15
  After=syslog.target network.target
16
16
 
17
17
  [Service]
18
- Type=notify
18
+ Type=<%= service_unit_type %>
19
19
  WatchdogSec=10
20
- <%="User=#{puma_user(@role)}" if fetch(:puma_systemctl_user) == :system -%>
20
+ <%="User=#{puma_user(@role)}" if fetch(:puma_systemctl_user) == :system %>
21
21
  WorkingDirectory=<%= current_path %>
22
- # Support older bundler versions where file descriptors weren't kept
23
- # See https://github.com/rubygems/rubygems/issues/3254
24
- ExecStart=<%= expanded_bundle_command %> exec --keep-file-descriptors puma
22
+ ExecStart=<%= expanded_bundle_command %> exec puma -e <%= fetch(:puma_env) %>
25
23
  ExecReload=/bin/kill -USR1 $MAINPID
24
+ <%- Array(fetch(:puma_service_unit_env_files)).each do |file| %>
25
+ <%="EnvironmentFile=#{file}" -%>
26
+ <% end -%>
27
+ <% Array(fetch(:puma_service_unit_env_vars)).each do |environment_variable| %>
28
+ <%="Environment=\"#{environment_variable}\"" -%>
29
+ <% end -%>
26
30
 
27
- <%="EnvironmentFile=#{fetch(:puma_service_unit_env_file)}" if fetch(:puma_service_unit_env_file) %>
28
- <% fetch(:puma_service_unit_env_vars, []).each do |environment_variable| %>
29
- <%="Environment=#{environment_variable}" %>
30
- <% end %>
31
31
  # if we crash, restart
32
32
  RestartSec=1
33
33
  Restart=on-failure
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano3-puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.alpha.2
4
+ version: 6.0.0.alpha.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-20 00:00:00.000000000 Z
11
+ date: 2022-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capistrano
@@ -69,19 +69,14 @@ files:
69
69
  - LICENSE.txt
70
70
  - README.md
71
71
  - lib/capistrano/puma.rb
72
- - lib/capistrano/puma/monit.rb
73
72
  - lib/capistrano/puma/nginx.rb
74
73
  - lib/capistrano/puma/systemd.rb
75
74
  - lib/capistrano/puma/version.rb
76
- - lib/capistrano/tasks/monit.rake
77
75
  - lib/capistrano/tasks/nginx.rake
78
76
  - lib/capistrano/tasks/systemd.rake
79
77
  - lib/capistrano/templates/nginx_conf.erb
80
- - lib/capistrano/templates/puma-deb.erb
81
- - lib/capistrano/templates/puma-rpm.erb
82
78
  - lib/capistrano/templates/puma.service.erb
83
79
  - lib/capistrano/templates/puma.socket.erb
84
- - lib/capistrano/templates/puma_monit.conf.erb
85
80
  - lib/capistrano3-puma.rb
86
81
  - lib/generators/capistrano/nginx_puma/USAGE
87
82
  - lib/generators/capistrano/nginx_puma/config_generator.rb
@@ -1,34 +0,0 @@
1
- module Capistrano
2
- class Puma::Monit < Capistrano::Plugin
3
- include PumaCommon
4
- def register_hooks
5
- before 'deploy:updating', 'puma:monit:unmonitor'
6
- after 'deploy:published', 'puma:monit:monitor'
7
- end
8
-
9
- def define_tasks
10
- eval_rakefile File.expand_path('../../tasks/monit.rake', __FILE__)
11
- end
12
-
13
- def set_defaults
14
- set_if_empty :puma_monit_conf_dir, -> { "/etc/monit/conf.d/#{puma_monit_service_name}.conf" }
15
- set_if_empty :puma_monit_use_sudo, true
16
- set_if_empty :puma_monit_bin, '/usr/bin/monit'
17
- end
18
-
19
- def puma_monit_service_name
20
- fetch(:puma_monit_service_name, "puma_#{fetch(:application)}_#{fetch(:stage)}")
21
- end
22
-
23
- def sudo_if_needed(command)
24
- if fetch(:puma_monit_use_sudo)
25
- backend.sudo command
26
- else
27
- puma_role = fetch(:puma_role)
28
- backend.on(puma_role) do
29
- backend.execute command
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,61 +0,0 @@
1
- git_plugin = self
2
-
3
- namespace :puma do
4
- namespace :monit do
5
- desc 'Config Puma monit-service'
6
- task :config do
7
- on roles(fetch(:puma_role)) do |role|
8
- git_plugin.template_puma 'puma_monit.conf', "#{fetch(:tmp_dir)}/monit.conf", role
9
- git_plugin.sudo_if_needed "mv #{fetch(:tmp_dir)}/monit.conf #{fetch(:puma_monit_conf_dir)}"
10
- git_plugin.sudo_if_needed "#{fetch(:puma_monit_bin)} reload"
11
- # Wait for Monit to be reloaded
12
- sleep 1
13
- end
14
- end
15
-
16
- desc 'Monitor Puma monit-service'
17
- task :monitor do
18
- on roles(fetch(:puma_role)) do
19
- begin
20
- git_plugin.sudo_if_needed "#{fetch(:puma_monit_bin)} monitor #{git_plugin.puma_monit_service_name}"
21
- rescue
22
- invoke 'puma:monit:config'
23
- git_plugin.sudo_if_needed "#{fetch(:puma_monit_bin)} monitor #{git_plugin.puma_monit_service_name}"
24
- end
25
- end
26
- end
27
-
28
- desc 'Unmonitor Puma monit-service'
29
- task :unmonitor do
30
- on roles(fetch(:puma_role)) do
31
- begin
32
- git_plugin.sudo_if_needed "#{fetch(:puma_monit_bin)} unmonitor #{git_plugin.puma_monit_service_name}"
33
- rescue
34
- # no worries here (still no monitoring)
35
- end
36
- end
37
- end
38
-
39
- desc 'Start Puma monit-service'
40
- task :start do
41
- on roles(fetch(:puma_role)) do
42
- git_plugin.sudo_if_needed "#{fetch(:puma_monit_bin)} start #{git_plugin.puma_monit_service_name}"
43
- end
44
- end
45
-
46
- desc 'Stop Puma monit-service'
47
- task :stop do
48
- on roles(fetch(:puma_role)) do
49
- git_plugin.sudo_if_needed "#{fetch(:puma_monit_bin)} stop #{git_plugin.puma_monit_service_name}"
50
- end
51
- end
52
-
53
- desc 'Restart Puma monit-service'
54
- task :restart do
55
- on roles(fetch(:puma_role)) do
56
- git_plugin.sudo_if_needed "#{fetch(:puma_monit_bin)} restart #{git_plugin.puma_monit_service_name}"
57
- end
58
- end
59
-
60
- end
61
- end
@@ -1,421 +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: Puma web server
9
- # Description: A ruby web server built for concurrency http://puma.io
10
- # initscript to be 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=<%=fetch(:puma_jungle_conf)%>
24
- JUNGLE=`cat $CONFIG`
25
- RUNPUMA=<%=fetch(:puma_run_path)%>
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
- do_start_one $dir
43
- done
44
- }
45
-
46
- do_start_one() {
47
- PIDFILE=$1/tmp/pids/puma.pid
48
- if [ -e $PIDFILE ]; then
49
- PID=`cat $PIDFILE`
50
- # If the puma isn't running, run it, otherwise restart it.
51
- if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
52
- do_start_one_do $1
53
- else
54
- do_restart_one $1
55
- fi
56
- else
57
- do_start_one_do $1
58
- fi
59
- }
60
-
61
- do_start_one_do() {
62
- i=`grep $1 $CONFIG`
63
- dir=`echo $i | cut -d , -f 1`
64
- user=`echo $i | cut -d , -f 2`
65
- config_file=`echo $i | cut -d , -f 3`
66
- if [ "$config_file" = "" ]; then
67
- config_file="$dir/config/puma.rb"
68
- fi
69
- log_file=`echo $i | cut -d , -f 4`
70
- if [ "$log_file" = "" ]; then
71
- log_file="$dir/log/puma.log"
72
- fi
73
- environment=`echo $i | cut -d , -f 5`
74
-
75
- log_daemon_msg "--> Woke up puma $dir"
76
- log_daemon_msg "user $user"
77
- log_daemon_msg "log to $log_file"
78
-
79
- if [ ! -z "$environment" ]; then
80
- for e in $(echo "$environment" | tr ';' '\n'); do
81
- log_daemon_msg "environment $e"
82
- v=${e%%\=*} ; eval "$e" ; export $v
83
- done
84
- fi
85
-
86
- start-stop-daemon --verbose --start --chdir $dir --chuid $user --background --exec $RUNPUMA -- $dir $config_file $log_file
87
- }
88
-
89
- #
90
- # Function that stops the jungle
91
- #
92
- do_stop() {
93
- log_daemon_msg "=> Putting all the beasts to bed..."
94
- for i in $JUNGLE; do
95
- dir=`echo $i | cut -d , -f 1`
96
- do_stop_one $dir
97
- done
98
- }
99
- #
100
- # Function that stops the daemon/service
101
- #
102
- do_stop_one() {
103
- log_daemon_msg "--> Stopping $1"
104
- PIDFILE=$1/tmp/pids/puma.pid
105
- STATEFILE=$1/tmp/pids/puma.state
106
- if [ -e $PIDFILE ]; then
107
- PID=`cat $PIDFILE`
108
- if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
109
- log_daemon_msg "---> Puma $1 isn't running."
110
- else
111
- log_daemon_msg "---> About to kill PID `cat $PIDFILE`"
112
- if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
113
- cd $1 && bundle exec pumactl --state $STATEFILE stop
114
- else
115
- pumactl --state $STATEFILE stop
116
- fi
117
- # Many daemons don't delete their pidfiles when they exit.
118
- rm -f $PIDFILE $STATEFILE
119
- fi
120
- else
121
- log_daemon_msg "---> No puma here..."
122
- fi
123
- return 0
124
- }
125
-
126
- #
127
- # Function that restarts the jungle
128
- #
129
- do_restart() {
130
- for i in $JUNGLE; do
131
- dir=`echo $i | cut -d , -f 1`
132
- do_restart_one $dir
133
- done
134
- }
135
-
136
- #
137
- # Function that sends a SIGUSR2 to the daemon/service
138
- #
139
- do_restart_one() {
140
- PIDFILE=$1/tmp/pids/puma.pid
141
-
142
- if [ -e $PIDFILE ]; then
143
- log_daemon_msg "--> About to restart puma $1"
144
- kill -s USR2 `cat $PIDFILE`
145
- # TODO Check if process exist
146
- else
147
- log_daemon_msg "--> Your puma was never playing... Let's get it out there first"
148
- do_start_one $1
149
- fi
150
- return 0
151
- }
152
-
153
- #
154
- # Function that phased restarts the jungle
155
- #
156
- do_phased_restart() {
157
- for i in $JUNGLE; do
158
- dir=`echo $i | cut -d , -f 1`
159
- do_phased_restart_one $dir
160
- done
161
- }
162
-
163
- #
164
- # Function that sends a SIGUSR1 to the daemon/service
165
- #
166
- do_phased_restart_one() {
167
- PIDFILE=$1/tmp/pids/puma.pid
168
-
169
- if [ -e $PIDFILE ]; then
170
- log_daemon_msg "--> About to restart puma $1"
171
- kill -s USR1 `cat $PIDFILE`
172
- # TODO Check if process exist
173
- else
174
- log_daemon_msg "--> Your puma was never playing... Let's get it out there first"
175
- do_start_one $1
176
- fi
177
- return 0
178
- }
179
-
180
- #
181
- # Function that statuss the jungle
182
- #
183
- do_status() {
184
- for i in $JUNGLE; do
185
- dir=`echo $i | cut -d , -f 1`
186
- do_status_one $dir
187
- done
188
- }
189
-
190
- #
191
- # Function that sends a SIGUSR2 to the daemon/service
192
- #
193
- do_status_one() {
194
- PIDFILE=$1/tmp/pids/puma.pid
195
- i=`grep $1 $CONFIG`
196
- dir=`echo $i | cut -d , -f 1`
197
-
198
- if [ -e $PIDFILE ]; then
199
- log_daemon_msg "--> About to status puma $1"
200
- if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
201
- cd $1 && bundle exec pumactl --state $dir/tmp/pids/puma.state stats
202
- else
203
- pumactl --state $dir/tmp/pids/puma.state stats
204
- fi
205
- # kill -s USR2 `cat $PIDFILE`
206
- # TODO Check if process exist
207
- else
208
- log_daemon_msg "--> $1 isn't there :(..."
209
- fi
210
- return 0
211
- }
212
-
213
- do_add() {
214
- str=""
215
- # App's directory
216
- if [ -d "$1" ]; then
217
- if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then
218
- str=$1
219
- else
220
- echo "The app is already being managed. Remove it if you want to update its config."
221
- exit 1
222
- fi
223
- else
224
- echo "The directory $1 doesn't exist."
225
- exit 1
226
- fi
227
- # User to run it as
228
- if [ "`grep -c "^$2:" /etc/passwd`" -eq 0 ]; then
229
- echo "The user $2 doesn't exist."
230
- exit 1
231
- else
232
- str="$str,$2"
233
- fi
234
- # Config file
235
- if [ "$3" != "" ]; then
236
- if [ -e $3 ]; then
237
- str="$str,$3"
238
- else
239
- echo "The config file $3 doesn't exist."
240
- exit 1
241
- fi
242
- fi
243
- # Log file
244
- if [ "$4" != "" ]; then
245
- str="$str,$4"
246
- fi
247
-
248
- # Environment variables
249
- if [ "$5" != "" ]; then
250
- str="$str,$5"
251
- fi
252
-
253
- # Add it to the jungle
254
- echo $str >> $CONFIG
255
- log_daemon_msg "Added a Puma to the jungle: $str. You still have to start it though."
256
- }
257
-
258
- do_remove() {
259
- if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then
260
- echo "There's no app $1 to remove."
261
- else
262
- # Stop it first.
263
- do_stop_one $1
264
- # Remove it from the config.
265
- sed -i "\\:^$1:d" $CONFIG
266
- log_daemon_msg "Removed a Puma from the jungle: $1."
267
- fi
268
- }
269
-
270
- config_bundler() {
271
- HOME="$(eval echo ~$(id -un))"
272
-
273
- if [ -d "$1/.rbenv/bin" ]; then
274
- PATH="$1/.rbenv/bin:$1/.rbenv/shims:$1"
275
- eval "$(rbenv init -)"
276
- USE_LOCAL_BUNDLE=1
277
- return 0
278
-
279
- elif [ -d "/usr/local/rbenv/bin" ]; then
280
- PATH="/usr/local/rbenv/bin:/usr/local/rbenv/shims:$PATH"
281
- eval "$(rbenv init -)"
282
- USE_LOCAL_BUNDLE=1
283
- return 0
284
-
285
- elif [ -d "$HOME/.rbenv/bin" ]; then
286
- PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
287
- eval "$(rbenv init -)"
288
- USE_LOCAL_BUNDLE=1
289
- return 0
290
-
291
- # TODO: test rvm
292
- # elif [ -f /etc/profile.d/rvm.sh ]; then
293
- # source /etc/profile.d/rvm.sh
294
- # elif [ -f /usr/local/rvm/scripts/rvm ]; then
295
- # source /etc/profile.d/rvm.sh
296
- # elif [ -f "$HOME/.rvm/scripts/rvm" ]; then
297
- # source "$HOME/.rvm/scripts/rvm"
298
- # TODO: don't know what to do with chruby
299
- # elif [ -f /usr/local/share/chruby/chruby.sh ]; then
300
- # source /usr/local/share/chruby/chruby.sh
301
- # if [ -f /usr/local/share/chruby/auto.sh ]; then
302
- # source /usr/local/share/chruby/auto.sh
303
- # fi
304
- # if you aren't using auto, set your version here
305
- # chruby 2.0.0
306
- fi
307
-
308
- return 1
309
- }
310
-
311
- config_bundler
312
-
313
- case "$1" in
314
- start)
315
- [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
316
- if [ "$#" -eq 1 ]; then
317
- do_start
318
- else
319
- i=`grep $2 $CONFIG`
320
- dir=`echo $i | cut -d , -f 1`
321
- do_start_one $dir
322
- fi
323
- case "$?" in
324
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
325
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
326
- esac
327
- ;;
328
- stop)
329
- [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
330
- if [ "$#" -eq 1 ]; then
331
- do_stop
332
- else
333
- i=`grep $2 $CONFIG`
334
- dir=`echo $i | cut -d , -f 1`
335
- do_stop_one $dir
336
- fi
337
- case "$?" in
338
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
339
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
340
- esac
341
- ;;
342
- status)
343
- # TODO Implement.
344
- log_daemon_msg "Status $DESC" "$NAME"
345
- if [ "$#" -eq 1 ]; then
346
- do_status
347
- else
348
- i=`grep $2 $CONFIG`
349
- dir=`echo $i | cut -d , -f 1`
350
- do_status_one $dir
351
- fi
352
- case "$?" in
353
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
354
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
355
- esac
356
- ;;
357
- restart)
358
- log_daemon_msg "Restarting $DESC" "$NAME"
359
- if [ "$#" -eq 1 ]; then
360
- do_restart
361
- else
362
- i=`grep $2 $CONFIG`
363
- dir=`echo $i | cut -d , -f 1`
364
- do_restart_one $dir
365
- fi
366
- case "$?" in
367
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
368
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
369
- esac
370
- ;;
371
- phased-restart)
372
- log_daemon_msg "Restarting (phased) $DESC" "$NAME"
373
- if [ "$#" -eq 1 ]; then
374
- do_phased_restart
375
- else
376
- i=`grep $2 $CONFIG`
377
- dir=`echo $i | cut -d , -f 1`
378
- do_phased_restart_one $dir
379
- fi
380
- case "$?" in
381
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
382
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
383
- esac
384
- ;;
385
- add)
386
- if [ "$#" -lt 3 ]; then
387
- echo "Please, specify the app's directory and the user that will run it at least."
388
- echo " Usage: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
389
- echo " config and log are optionals."
390
- exit 1
391
- else
392
- do_add $2 $3 $4 $5
393
- fi
394
- case "$?" in
395
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
396
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
397
- esac
398
- ;;
399
- remove)
400
- if [ "$#" -lt 2 ]; then
401
- echo "Please, specifiy the app's directory to remove."
402
- exit 1
403
- else
404
- do_remove $2
405
- fi
406
- case "$?" in
407
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
408
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
409
- esac
410
- ;;
411
- *)
412
- echo "Usage:" >&2
413
- echo " Run the jungle: $SCRIPTNAME {start|stop|status|restart|phased-restart}" >&2
414
- echo " Add a Puma: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
415
- echo " config and log are optionals."
416
- echo " Remove a Puma: $SCRIPTNAME remove /path/to/app"
417
- echo " On a Puma: $SCRIPTNAME {start|stop|status|restart|phased-restart} PUMA-NAME" >&2
418
- exit 3
419
- ;;
420
- esac
421
- :
@@ -1,328 +0,0 @@
1
- #!/bin/sh
2
- #
3
- # puma - this script starts and stops the puma daemon
4
- #
5
- # chkconfig: - 85 15
6
- # description: Description \
7
- # goes here...
8
- # processname: puma
9
- # config: /etc/puma.conf
10
- # pidfile: /home/stanislaw/apps/micro-apps/puma/puma.pid
11
- # Author: Darío Javier Cravero <'dario@exordo.com'>
12
- #
13
- # Do NOT "set -e"
14
- # Original script https://github.com/puma/puma/blob/master/tools/jungle/puma
15
- # It was modified here by Stanislaw Pankevich <'s.pankevich@gmail.com'>
16
- # to run on CentOS 5.5 boxes.
17
- # Script works perfectly on CentOS 5: script uses its native daemon().
18
- # Puma is being stopped/restarted by sending signals, control app is not used.
19
- # Source function library.
20
- . /etc/rc.d/init.d/functions
21
-
22
- # Source networking configuration.
23
- . /etc/sysconfig/network
24
- # Check that networking is up.
25
- [ "$NETWORKING" = "no" ] && exit 0
26
- # PATH should only include /usr/* if it runs after the mountnfs.sh script
27
- PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin
28
- DESC="Puma rack web server"
29
- NAME=puma
30
- DAEMON=$NAME
31
- SCRIPTNAME=/etc/init.d/$NAME
32
- CONFIG=<%=fetch(:puma_jungle_conf)%>
33
- JUNGLE=`cat $CONFIG`
34
- RUNPUMA=<%=fetch(:puma_run_path)%>
35
- # Skipping the following non-CentOS string
36
- # Load the VERBOSE setting and other rcS variables
37
- # . /lib/init/vars.sh
38
- # CentOS does not have these functions natively
39
- log_daemon_msg() { echo "$@"; }
40
- log_end_msg() { [ $1 -eq 0 ] && RES=OK; logger ${RES:=FAIL}; }
41
- # Define LSB log_* functions.
42
- # Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
43
- . /lib/lsb/init-functions
44
-
45
- #
46
- # Function that starts the jungle
47
- #
48
- do_start() {
49
- log_daemon_msg "=> Running the jungle..."
50
- for i in $JUNGLE; do
51
- dir=`echo $i | cut -d , -f 1`
52
- user=`echo $i | cut -d , -f 2`
53
- config_file=`echo $i | cut -d , -f 3`
54
- if [ "$config_file" = "" ]; then
55
- config_file="$dir/config/puma.rb"
56
- fi
57
- log_file=`echo $i | cut -d , -f 4`
58
- if [ "$log_file" = "" ]; then
59
- log_file="$dir/log/puma.log"
60
- fi
61
- do_start_one $dir $user $config_file $log_file
62
- done
63
- }
64
- do_start_one() {
65
- PIDFILE=$1/tmp/pids/puma.pid
66
- if [ -e $PIDFILE ]; then
67
- PID=`cat $PIDFILE`
68
- # If the puma isn't running, run it, otherwise restart it.
69
- if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
70
- do_start_one_do $1 $2
71
- else
72
- do_restart_one $1
73
- fi
74
- else
75
- do_start_one_do $1 $2 $3 $4
76
- fi
77
- }
78
- do_start_one_do() {
79
- log_daemon_msg "--> Woke up puma $1"
80
- daemon --user $2 $RUNPUMA $1
81
- }
82
- #
83
- # Function that stops the jungle
84
- #
85
- do_stop() {
86
- log_daemon_msg "=> Putting all the beasts to bed..."
87
- for i in $JUNGLE; do
88
- dir=`echo $i | cut -d , -f 1`
89
- do_stop_one $dir
90
- done
91
- }
92
- #
93
- # Function that stops the daemon/service
94
- #
95
- do_stop_one() {
96
- log_daemon_msg "--> Stopping $1"
97
- PIDFILE=$1/tmp/pids/puma.pid
98
- STATEFILE=$1/tmp/pids/puma.state
99
- echo $PIDFILE
100
- if [ -e $PIDFILE ]; then
101
- PID=`cat $PIDFILE`
102
- echo "Pid:"
103
- echo $PID
104
- if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then
105
- log_daemon_msg "---> Puma $1 isn't running."
106
- else
107
- log_daemon_msg "---> About to kill PID `cat $PIDFILE`"
108
- pumactl --state $STATEFILE stop
109
- rm -f $PIDFILE $STATEFILE
110
- fi
111
- else
112
- log_daemon_msg "---> No puma here..."
113
- fi
114
- return 0
115
- }
116
- #
117
- # Function that restarts the jungle
118
- #
119
- do_restart() {
120
- for i in $JUNGLE; do
121
- dir=`echo $i | cut -d , -f 1`
122
- do_restart_one $dir
123
- done
124
- }
125
- #
126
- # Function that sends a SIGUSR2 to the daemon/service
127
- #
128
- do_restart_one() {
129
- PIDFILE=$1/tmp/pids/puma.pid
130
- i=`grep $1 $CONFIG`
131
- dir=`echo $i | cut -d , -f 1`
132
- if [ -e $PIDFILE ]; then
133
- log_daemon_msg "--> About to restart puma $1"
134
- pumactl --state $dir/tmp/pids/puma.state restart
135
-
136
- else
137
- log_daemon_msg "--> Your puma was never playing... Let's get it out there first"
138
- user=`echo $i | cut -d , -f 2`
139
- config_file=`echo $i | cut -d , -f 3`
140
- if [ "$config_file" = "" ]; then
141
- config_file="$dir/config/puma.rb"
142
- fi
143
- log_file=`echo $i | cut -d , -f 4`
144
- if [ "$log_file" = "" ]; then
145
- log_file="$dir/log/puma.log"
146
- fi
147
- do_start_one $dir $user $config_file $log_file
148
- fi
149
- return 0
150
- }
151
- #
152
- # Function that statuss then jungle
153
- #
154
- do_status() {
155
- for i in $JUNGLE; do
156
- dir=`echo $i | cut -d , -f 1`
157
- do_status_one $dir
158
- done
159
- }
160
- #
161
- # Function that sends a SIGUSR2 to the daemon/service
162
- #
163
- do_status_one() {
164
- PIDFILE=$1/tmp/pids/puma.pid
165
- i=`grep $1 $CONFIG`
166
- dir=`echo $i | cut -d , -f 1`
167
- if [ -e $PIDFILE ]; then
168
- log_daemon_msg "--> About to status puma $1"
169
- pumactl --state $dir/tmp/pids/puma.state stats
170
-
171
- else
172
- log_daemon_msg "--> $1 isn't there :(..."
173
- fi
174
- return 0
175
- }
176
- do_add() {
177
- str=""
178
- # App's directory
179
- if [ -d "$1" ]; then
180
- if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then
181
- str=$1
182
- else
183
- echo "The app is already being managed. Remove it if you want to update its config."
184
- exit 1
185
- fi
186
- else
187
- echo "The directory $1 doesn't exist."
188
- exit 1
189
- fi
190
- # User to run it as
191
- if [ "`grep -c "^$2:" /etc/passwd`" -eq 0 ]; then
192
- echo "The user $2 doesn't exist."
193
- exit 1
194
- else
195
- str="$str,$2"
196
- fi
197
- # Config file
198
- if [ "$3" != "" ]; then
199
- if [ -e $3 ]; then
200
- str="$str,$3"
201
- else
202
- echo "The config file $3 doesn't exist."
203
- exit 1
204
- fi
205
- fi
206
- # Log file
207
- if [ "$4" != "" ]; then
208
- str="$str,$4"
209
- fi
210
- # Add it to the jungle
211
- echo $str >> $CONFIG
212
- log_daemon_msg "Added a Puma to the jungle: $str. You still have to start it though."
213
- }
214
- do_remove() {
215
- if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then
216
- echo "There's no app $1 to remove."
217
- else
218
- # Stop it first.
219
- do_stop_one $1
220
- # Remove it from the config.
221
- sed -i "\\:^$1:d" $CONFIG
222
- log_daemon_msg "Removed a Puma from the jungle: $1."
223
- fi
224
- }
225
- case "$1" in
226
- start)
227
- [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
228
- if [ "$#" -eq 1 ]; then
229
- do_start
230
- else
231
- i=`grep $2 $CONFIG`
232
- dir=`echo $i | cut -d , -f 1`
233
- user=`echo $i | cut -d , -f 2`
234
- config_file=`echo $i | cut -d , -f 3`
235
- if [ "$config_file" = "" ]; then
236
- config_file="$dir/config/puma.rb"
237
- fi
238
- log_file=`echo $i | cut -d , -f 4`
239
- if [ "$log_file" = "" ]; then
240
- log_file="$dir/log/puma.log"
241
- fi
242
- do_start_one $dir $user $config_file $log_file
243
- fi
244
- case "$?" in
245
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
246
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
247
- esac
248
- ;;
249
- stop)
250
- [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
251
- if [ "$#" -eq 1 ]; then
252
- do_stop
253
- else
254
- i=`grep $2 $CONFIG`
255
- dir=`echo $i | cut -d , -f 1`
256
- do_stop_one $dir
257
- fi
258
- case "$?" in
259
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
260
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
261
- esac
262
- ;;
263
- status)
264
- # TODO Implement.
265
- log_daemon_msg "Status $DESC" "$NAME"
266
- if [ "$#" -eq 1 ]; then
267
- do_status
268
- else
269
- i=`grep $2 $CONFIG`
270
- dir=`echo $i | cut -d , -f 1`
271
- do_status_one $dir
272
- fi
273
- case "$?" in
274
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
275
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
276
- esac
277
- ;;
278
- restart)
279
- log_daemon_msg "Restarting $DESC" "$NAME"
280
- if [ "$#" -eq 1 ]; then
281
- do_restart
282
- else
283
- i=`grep $2 $CONFIG`
284
- dir=`echo $i | cut -d , -f 1`
285
- do_restart_one $dir
286
- fi
287
- case "$?" in
288
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
289
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
290
- esac
291
- ;;
292
- add)
293
- if [ "$#" -lt 3 ]; then
294
- echo "Please, specifiy the app's directory and the user that will run it at least."
295
- echo " Usage: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
296
- echo " config and log are optionals."
297
- exit 1
298
- else
299
- do_add $2 $3 $4 $5
300
- fi
301
- case "$?" in
302
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
303
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
304
- esac
305
- ;;
306
- remove)
307
- if [ "$#" -lt 2 ]; then
308
- echo "Please, specifiy the app's directory to remove."
309
- exit 1
310
- else
311
- do_remove $2
312
- fi
313
- case "$?" in
314
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
315
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
316
- esac
317
- ;;
318
- *)
319
- echo "Usage:" >&2
320
- echo " Run the jungle: $SCRIPTNAME {start|stop|status|restart}" >&2
321
- echo " Add a Puma: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
322
- echo " config and log are optionals."
323
- echo " Remove a Puma: $SCRIPTNAME remove /path/to/app"
324
- echo " On a Puma: $SCRIPTNAME {start|stop|status|restart} PUMA-NAME" >&2
325
- exit 3
326
- ;;
327
- esac
328
- :
@@ -1,7 +0,0 @@
1
- # Monit configuration for Puma
2
- # Service name: <%= puma_monit_service_name %>
3
- #
4
- check process <%= puma_monit_service_name %>
5
- with pidfile "<%= fetch(:puma_pid) %>"
6
- start program = "/usr/bin/sudo -iu <%= puma_user(@role) %> /bin/bash -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:puma] %> %> --daemon'"
7
- stop program = "/usr/bin/sudo -iu <%= puma_user(@role) %> /bin/bash -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:pumactl] %> -S <%= fetch(:puma_state) %> stop'"