capistrano-puma-a 2.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/CHANGELOG.md +40 -0
- data/CONTRIBUTORS.md +45 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +128 -0
- data/Rakefile +1 -0
- data/capistrano-puma-a.gemspec +24 -0
- data/lib/capistrano/puma.rb +2 -0
- data/lib/capistrano/puma/jungle.rb +2 -0
- data/lib/capistrano/puma/monit.rb +2 -0
- data/lib/capistrano/puma/nginx.rb +1 -0
- data/lib/capistrano/puma/version.rb +5 -0
- data/lib/capistrano/puma/workers.rb +2 -0
- data/lib/capistrano/tasks/jungle.rake +81 -0
- data/lib/capistrano/tasks/monit.rake +72 -0
- data/lib/capistrano/tasks/nginx.rake +25 -0
- data/lib/capistrano/tasks/puma.rake +197 -0
- data/lib/capistrano/tasks/workers.rake +38 -0
- data/lib/capistrano/templates/nginx_conf.erb +82 -0
- data/lib/capistrano/templates/puma-deb.erb +336 -0
- data/lib/capistrano/templates/puma-rpm.erb +328 -0
- data/lib/capistrano/templates/puma.rb.erb +48 -0
- data/lib/capistrano/templates/puma_monit.conf.erb +7 -0
- data/lib/capistrano/templates/run-puma.erb +9 -0
- data/lib/capistrano3-puma.rb +0 -0
- data/lib/generators/capistrano/nginx_puma/USAGE +9 -0
- data/lib/generators/capistrano/nginx_puma/config_generator.rb +21 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1a88362a8db972f708d5fb507140a5a6c4a0c214
|
4
|
+
data.tar.gz: 07574feef309763f8376affb71e4dd35ae437e29
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 05306a6bfa0e12e4e8a5c1352a404e7c707c37971dd30aef61131949691977eb5cae33041aee5f32763e4e9df3198addb7d044887d52a35bb711a422fb267776
|
7
|
+
data.tar.gz: 9b3094c815ed1d850fda379c2a209398ad2e164a2f56e4fba5d3ac0b0e1cacf3af0b711ca9287c0e733daf5d5da7ff835f4316f5ae4c22fe0fc71afd1962629d
|
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
## Changelog
|
2
|
+
- 2.0.0:
|
3
|
+
- Require puma 3.4+
|
4
|
+
- Require Capistrano 3.5+
|
5
|
+
- Require capistrano-bundler
|
6
|
+
|
7
|
+
- 1.2.0: add support for puma user for puma user @mcb & @seuros
|
8
|
+
- 1.1.0: Set :puma_preload_app to false; Reload Monit after uploading any monit configuration; Always refresh Gemfile @rafaelgoulart @suhailpatel @sime
|
9
|
+
- 1.0.0: Add activate control app @askagirl
|
10
|
+
- 0.8.5: Fix smart_restart task to check if puma preloads app
|
11
|
+
- 0.8.4: Allow patch method (Nginx template) @lonre
|
12
|
+
- 0.8.2: Start task creates a conf file if none exists @stevemadere
|
13
|
+
- 0.8.1: Fixed nginx task @hnatt, support for prune_bundler @behe
|
14
|
+
- 0.8.0: Some changes
|
15
|
+
- 0.7.0: added Nginx template generator @dfang
|
16
|
+
- 0.6.1: added :puma_default_hooks, you can turn off the automatic hooks by setting it false
|
17
|
+
- 0.6.0: Remove `daemonize true` from default puma.rb file. Explicitly pass `--daemon` flag when needed.
|
18
|
+
- 0.5.1: Added worker_timeout option
|
19
|
+
- 0.5.0: Bugs fixes
|
20
|
+
- 0.4.2: Fix monit template to support chruby
|
21
|
+
- 0.4.1: Fix puma jungle (debian)
|
22
|
+
- 0.4.0: Multi-bind support
|
23
|
+
- 0.3.7: Dependency bug fix
|
24
|
+
- 0.3.5: Fixed a prehistoric bug
|
25
|
+
- 0.3.4: I don't remember what i did here
|
26
|
+
- 0.3.3: Puma jungle start fix
|
27
|
+
- 0.3.2: Tag option support (require puma 2.8.2+)
|
28
|
+
- 0.3.1: Typo fix
|
29
|
+
- 0.3.0: Initial support for puma signals
|
30
|
+
- 0.2.2: Application pre-loading is optional now (set puma_preload_app to false to turn it off)
|
31
|
+
- 0.2.1: Tasks are run within rack context
|
32
|
+
- 0.2.0: Support for puma `ActiveRecord::Base.establish_connection` on
|
33
|
+
boot
|
34
|
+
- 0.1.3: Capistrano 3.1 support
|
35
|
+
- 0.1.2: Gemfile are refreshed between deploys now
|
36
|
+
- 0.1.1: Initial support for Monit and configuration override added.
|
37
|
+
- 0.1.0: Phased restart will be used if puma is in cluster mode
|
38
|
+
- 0.0.9: puma.rb location changed to shared_path root. puma:check moved to after deploy:check
|
39
|
+
- 0.0.8: puma.rb is automatically generated if not present. Fixed RVM issue.
|
40
|
+
- 0.0.7: Gem pushed to rubygems as capistrano3-puma. Support of Redhat based OS for Jungle init script.
|
data/CONTRIBUTORS.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
## Contributors
|
2
|
+
|
3
|
+
Abdelkader Boudih
|
4
|
+
André Arko
|
5
|
+
Ariel Zerahia
|
6
|
+
ayaya
|
7
|
+
Bin Huang
|
8
|
+
Bryan Liles
|
9
|
+
Claudio Poli
|
10
|
+
Cyril Rohr
|
11
|
+
dfang
|
12
|
+
Fritz Lee
|
13
|
+
Hnat Kubov
|
14
|
+
Ivan Schneider
|
15
|
+
James-Hendrickson
|
16
|
+
Jens Hausherr
|
17
|
+
Jeremy Rottman
|
18
|
+
Jesse Cooke
|
19
|
+
Johan Lind
|
20
|
+
Jordan Hollinger
|
21
|
+
Jun Lin
|
22
|
+
Kamil Giszczak
|
23
|
+
Kevin Collignon
|
24
|
+
Konstantin Papkovskiy
|
25
|
+
Kyle Decot
|
26
|
+
Lisa Hagemann
|
27
|
+
Lonre Wang
|
28
|
+
marshall-lee
|
29
|
+
Matias De Santi
|
30
|
+
Michael C. Beck
|
31
|
+
Molfar
|
32
|
+
msbrigna
|
33
|
+
Neil Bartley
|
34
|
+
Peter
|
35
|
+
Ponomarev Nikolay
|
36
|
+
Rafael Goulart
|
37
|
+
RavWar
|
38
|
+
ruohan.chen
|
39
|
+
Ruslan
|
40
|
+
Sergey Ponomarev
|
41
|
+
Shane O'Grady
|
42
|
+
Simon Males
|
43
|
+
Steve Madere
|
44
|
+
Suhail Patel
|
45
|
+
Suraj Shirvankar
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013-2016 Abdelkader Boudih
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# Capistrano::Puma
|
2
|
+
|
3
|
+
A clone of [https://github.com/seuros/capistrano-puma]. If you don't know what
|
4
|
+
this does, please use that version instead.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'capistrano3-puma', github: "seuros/capistrano-puma"
|
11
|
+
|
12
|
+
or:
|
13
|
+
|
14
|
+
gem 'capistrano3-puma' , group: :development
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
```ruby
|
22
|
+
# Capfile
|
23
|
+
|
24
|
+
require 'capistrano/puma'
|
25
|
+
require 'capistrano/puma/workers' # if you want to control the workers (in cluster mode)
|
26
|
+
require 'capistrano/puma/jungle' # if you need the jungle tasks
|
27
|
+
require 'capistrano/puma/monit' # if you need the monit tasks
|
28
|
+
require 'capistrano/puma/nginx' # if you want to upload a nginx site template
|
29
|
+
```
|
30
|
+
|
31
|
+
### Config
|
32
|
+
|
33
|
+
To list available tasks use `cap -T`
|
34
|
+
|
35
|
+
To upload puma config use:
|
36
|
+
```ruby
|
37
|
+
cap puma:config
|
38
|
+
```
|
39
|
+
By default the file located in `shared/puma.config`
|
40
|
+
|
41
|
+
|
42
|
+
Ensure that `tmp/pids` and ` tmp/sockets log` are shared (via `linked_dirs`):
|
43
|
+
|
44
|
+
`This step is mandatory before deploying, otherwise puma server won't start`
|
45
|
+
|
46
|
+
### Nginx
|
47
|
+
|
48
|
+
To upload a nginx site config (eg. /etc/nginx/sites-enabled/) use:
|
49
|
+
```ruby
|
50
|
+
cap puma:nginx_config
|
51
|
+
```
|
52
|
+
|
53
|
+
To customize these two templates locally before uploading use:
|
54
|
+
```
|
55
|
+
rails g capistrano:nginx_puma:config
|
56
|
+
```
|
57
|
+
|
58
|
+
if your nginx server configuration is not located in `/etc/nginx`, you may need to customize:
|
59
|
+
```ruby
|
60
|
+
set :nginx_sites_available_path, "/etc/nginx/sites-available"
|
61
|
+
set :nginx_sites_enabled_path, "/etc/nginx/sites-enabled"
|
62
|
+
```
|
63
|
+
|
64
|
+
By default, `nginx_config` will be executed with `:web` role. But you can assign it to a different role:
|
65
|
+
```ruby
|
66
|
+
set :puma_nginx, :foo
|
67
|
+
```
|
68
|
+
or define a standalone one:
|
69
|
+
```ruby
|
70
|
+
role :puma_nginx, %w{root@example.com}
|
71
|
+
```
|
72
|
+
|
73
|
+
### Jungle
|
74
|
+
|
75
|
+
For Jungle tasks (beta), these options exist:
|
76
|
+
```ruby
|
77
|
+
set :puma_jungle_conf, '/etc/puma.conf'
|
78
|
+
set :puma_run_path, '/usr/local/bin/run-puma'
|
79
|
+
```
|
80
|
+
|
81
|
+
### Multi bind
|
82
|
+
|
83
|
+
Multi-bind can be set with an array in the puma_bind variable
|
84
|
+
```ruby
|
85
|
+
set :puma_bind, %w(tcp://0.0.0.0:9292 unix:///tmp/puma.sock)
|
86
|
+
```
|
87
|
+
* Listening on tcp://0.0.0.0:9220
|
88
|
+
* Listening on unix:///tmp/puma.sock
|
89
|
+
|
90
|
+
### Active Record
|
91
|
+
|
92
|
+
For ActiveRecord the following line to your deploy.rb
|
93
|
+
```ruby
|
94
|
+
set :puma_init_active_record, true
|
95
|
+
```
|
96
|
+
|
97
|
+
### Other configs
|
98
|
+
|
99
|
+
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.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
set :puma_user, fetch(:user)
|
103
|
+
set :puma_rackup, -> { File.join(current_path, 'config.ru') }
|
104
|
+
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
|
105
|
+
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
|
106
|
+
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock" #accept array for multi-bind
|
107
|
+
set :puma_default_control_app, "unix://#{shared_path}/tmp/sockets/pumactl.sock"
|
108
|
+
set :puma_conf, "#{shared_path}/puma.rb"
|
109
|
+
set :puma_access_log, "#{shared_path}/log/puma_access.log"
|
110
|
+
set :puma_error_log, "#{shared_path}/log/puma_error.log"
|
111
|
+
set :puma_role, :app
|
112
|
+
set :puma_env, fetch(:rack_env, fetch(:rails_env, 'production'))
|
113
|
+
set :puma_threads, [0, 16]
|
114
|
+
set :puma_workers, 0
|
115
|
+
set :puma_worker_timeout, nil
|
116
|
+
set :puma_init_active_record, false
|
117
|
+
set :puma_preload_app, false
|
118
|
+
set :puma_plugins, [] #accept array of plugins
|
119
|
+
set :nginx_use_ssl, false
|
120
|
+
```
|
121
|
+
|
122
|
+
## Contributing
|
123
|
+
|
124
|
+
1. Fork it
|
125
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
126
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
127
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
128
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'capistrano/puma/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'capistrano-puma-a'
|
8
|
+
spec.version = Capistrano::Puma::VERSION
|
9
|
+
spec.authors = ['Abdelkader Boudih']
|
10
|
+
spec.email = ['Terminale@gmail.com']
|
11
|
+
spec.description = %q{A clone of seuros/capistrano-puma used here for version bump}
|
12
|
+
spec.summary = %q{Puma integration for Capistrano}
|
13
|
+
spec.homepage = 'https://github.com/seuros/capistrano-puma'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.required_ruby_version = '>= 1.9.3'
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($/)
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'capistrano', '~> 3.5'
|
22
|
+
spec.add_dependency 'capistrano-bundler', '~> 1.1'
|
23
|
+
spec.add_dependency 'puma' , '~> 3.4'
|
24
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path('../../tasks/nginx.rake', __FILE__)
|
@@ -0,0 +1,81 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
set :puma_jungle_conf, '/etc/puma.conf'
|
4
|
+
set :puma_run_path, '/usr/local/bin/run-puma'
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
namespace :puma do
|
10
|
+
namespace :jungle do
|
11
|
+
|
12
|
+
desc 'Install Puma jungle'
|
13
|
+
task :install do
|
14
|
+
on roles(fetch(:puma_role)) do |role|
|
15
|
+
@role = role
|
16
|
+
template_puma 'run-puma', "#{fetch(:tmp_dir)}/run-puma", role
|
17
|
+
execute "chmod +x #{fetch(:tmp_dir)}/run-puma"
|
18
|
+
sudo "mv #{fetch(:tmp_dir)}/run-puma #{fetch(:puma_run_path)}"
|
19
|
+
if test '[ -f /etc/redhat-release ]'
|
20
|
+
#RHEL flavor OS
|
21
|
+
rhel_install
|
22
|
+
elsif test '[ -f /etc/lsb-release ]'
|
23
|
+
#Debian flavor OS
|
24
|
+
debian_install
|
25
|
+
else
|
26
|
+
#Some other OS
|
27
|
+
error 'This task is not supported for your OS'
|
28
|
+
end
|
29
|
+
sudo "touch #{fetch(:puma_jungle_conf)}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def debian_install
|
35
|
+
template_puma 'puma-deb', "#{fetch(:tmp_dir)}/puma", @role
|
36
|
+
execute "chmod +x #{fetch(:tmp_dir)}/puma"
|
37
|
+
sudo "mv #{fetch(:tmp_dir)}/puma /etc/init.d/puma"
|
38
|
+
sudo 'update-rc.d -f puma defaults'
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def rhel_install
|
43
|
+
template_puma 'puma-rpm', "#{fetch(:tmp_dir)}/puma" , @role
|
44
|
+
execute "chmod +x #{fetch(:tmp_dir)}/puma"
|
45
|
+
sudo "mv #{fetch(:tmp_dir)}/puma /etc/init.d/puma"
|
46
|
+
sudo 'chkconfig --add puma'
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
desc 'Setup Puma config and install jungle script'
|
51
|
+
task :setup do
|
52
|
+
invoke 'puma:config'
|
53
|
+
invoke 'puma:jungle:install'
|
54
|
+
invoke 'puma:jungle:add'
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'Add current project to the jungle'
|
58
|
+
task :add do
|
59
|
+
on roles(fetch(:puma_role)) do|role|
|
60
|
+
sudo "/etc/init.d/puma add '#{current_path}' #{fetch(:puma_user, role.user)}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc 'Remove current project from the jungle'
|
65
|
+
task :remove do
|
66
|
+
on roles(fetch(:puma_role)) do
|
67
|
+
sudo "/etc/init.d/puma remove '#{current_path}'"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
%w[start stop restart status].each do |command|
|
72
|
+
desc "#{command} puma"
|
73
|
+
task command do
|
74
|
+
on roles(fetch(:puma_role)) do
|
75
|
+
sudo "service puma #{command} #{current_path}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
set :puma_monit_conf_dir, -> { "/etc/monit/conf.d/#{puma_monit_service_name}.conf" }
|
4
|
+
set :puma_monit_use_sudo, true
|
5
|
+
set :puma_monit_bin, '/usr/bin/monit'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
namespace :puma do
|
10
|
+
namespace :monit do
|
11
|
+
desc 'Config Puma monit-service'
|
12
|
+
task :config do
|
13
|
+
on roles(fetch(:puma_role)) do |role|
|
14
|
+
@role = role
|
15
|
+
template_puma 'puma_monit.conf', "#{fetch(:tmp_dir)}/monit.conf", @role
|
16
|
+
sudo_if_needed "mv #{fetch(:tmp_dir)}/monit.conf #{fetch(:puma_monit_conf_dir)}"
|
17
|
+
sudo_if_needed "#{fetch(:puma_monit_bin)} reload"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Monitor Puma monit-service'
|
22
|
+
task :monitor do
|
23
|
+
on roles(fetch(:puma_role)) do
|
24
|
+
sudo_if_needed "#{fetch(:puma_monit_bin)} monitor #{puma_monit_service_name}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Unmonitor Puma monit-service'
|
29
|
+
task :unmonitor do
|
30
|
+
on roles(fetch(:puma_role)) do
|
31
|
+
sudo_if_needed "#{fetch(:puma_monit_bin)} unmonitor #{puma_monit_service_name}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Start Puma monit-service'
|
36
|
+
task :start do
|
37
|
+
on roles(fetch(:puma_role)) do
|
38
|
+
sudo_if_needed "#{fetch(:puma_monit_bin)} start #{puma_monit_service_name}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Stop Puma monit-service'
|
43
|
+
task :stop do
|
44
|
+
on roles(fetch(:puma_role)) do
|
45
|
+
sudo_if_needed "#{fetch(:puma_monit_bin)} stop #{puma_monit_service_name}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'Restart Puma monit-service'
|
50
|
+
task :restart do
|
51
|
+
on roles(fetch(:puma_role)) do
|
52
|
+
sudo_if_needed "#{fetch(:puma_monit_bin)} restart #{puma_monit_service_name}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
before 'deploy:updating', 'puma:monit:unmonitor'
|
57
|
+
after 'deploy:published', 'puma:monit:monitor'
|
58
|
+
|
59
|
+
def puma_monit_service_name
|
60
|
+
fetch(:puma_monit_service_name, "puma_#{fetch(:application)}_#{fetch(:stage)}")
|
61
|
+
end
|
62
|
+
|
63
|
+
def sudo_if_needed(command)
|
64
|
+
if fetch(:puma_monit_use_sudo)
|
65
|
+
sudo command
|
66
|
+
else
|
67
|
+
execute command
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|