sam-shepherd 0.8.2
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 +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +22 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +227 -0
- data/Guardfile +35 -0
- data/LICENSE.txt +21 -0
- data/README.md +56 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/exe/sam +7 -0
- data/lib/sam.rb +5 -0
- data/lib/sam/cli.rb +42 -0
- data/lib/sam/cli/puma.rb +4 -0
- data/lib/sam/cli/puma/monitor.rb +28 -0
- data/lib/sam/cli/puma/reaper.rb +34 -0
- data/lib/sam/cli/puma/spawner.rb +29 -0
- data/lib/sam/cli/unicorn.rb +10 -0
- data/lib/sam/cli/unicorn/monitor.rb +28 -0
- data/lib/sam/cli/unicorn/reaper.rb +34 -0
- data/lib/sam/cli/unicorn/reloader.rb +25 -0
- data/lib/sam/cli/unicorn/runner.rb +33 -0
- data/lib/sam/cli/unicorn/spawner.rb +29 -0
- data/lib/sam/cli/version.rb +15 -0
- data/lib/sam/errors.rb +14 -0
- data/lib/sam/puma.rb +6 -0
- data/lib/sam/puma/breeder.rb +16 -0
- data/lib/sam/puma/identifier.rb +33 -0
- data/lib/sam/puma/predator.rb +12 -0
- data/lib/sam/puma/shepherd.rb +55 -0
- data/lib/sam/unicorn.rb +7 -0
- data/lib/sam/unicorn/breeder.rb +16 -0
- data/lib/sam/unicorn/cloner.rb +22 -0
- data/lib/sam/unicorn/identifier.rb +32 -0
- data/lib/sam/unicorn/predator.rb +12 -0
- data/lib/sam/unicorn/shepherd.rb +55 -0
- data/lib/sam/version.rb +5 -0
- data/sam.gemspec +52 -0
- metadata +310 -0
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'sam'
|
|
6
|
+
|
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
+
|
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
+
# require "pry"
|
|
12
|
+
# Pry.start
|
|
13
|
+
|
|
14
|
+
require 'irb'
|
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/sam
ADDED
data/lib/sam.rb
ADDED
data/lib/sam/cli.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'hanami/cli'
|
|
4
|
+
|
|
5
|
+
module Sam
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
extend Hanami::CLI::Registry
|
|
9
|
+
|
|
10
|
+
require_relative 'cli/version'
|
|
11
|
+
|
|
12
|
+
register 'version', Version
|
|
13
|
+
begin
|
|
14
|
+
gem 'unicorn'
|
|
15
|
+
require_relative 'unicorn'
|
|
16
|
+
require_relative 'cli/unicorn'
|
|
17
|
+
register 'unicorn' do |cmd|
|
|
18
|
+
cmd.register 'start', Unicorn::Spawner
|
|
19
|
+
cmd.register 'stop', Unicorn::Reaper
|
|
20
|
+
cmd.register 'reload', Unicorn::Reloader
|
|
21
|
+
cmd.register 'monitor', Unicorn::Monitor
|
|
22
|
+
cmd.register 'run', Unicorn::Runner
|
|
23
|
+
end
|
|
24
|
+
rescue Gem::LoadError
|
|
25
|
+
warn 'Unicorn not found. Not loading unicorn commands'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
begin
|
|
29
|
+
gem 'puma'
|
|
30
|
+
require_relative 'puma'
|
|
31
|
+
require_relative 'cli/puma'
|
|
32
|
+
register 'puma' do |cmd|
|
|
33
|
+
cmd.register 'start', Puma::Spawner
|
|
34
|
+
cmd.register 'stop', Puma::Reaper
|
|
35
|
+
# cmd.register 'stop', Puma::Reaper
|
|
36
|
+
end
|
|
37
|
+
rescue Gem::LoadError
|
|
38
|
+
warn 'Puma not found. Not loading puma commands'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/sam/cli/puma.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Puma
|
|
7
|
+
class Monitor < Hanami::CLI::Command
|
|
8
|
+
# rubocop:disable Metrics/LineLength
|
|
9
|
+
desc 'Monitor an already running unicorn'
|
|
10
|
+
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
11
|
+
option :timeout, type: :integer, desc: 'The number of seconds to wait for starting the unicorn server', aliases: ['-t']
|
|
12
|
+
example [
|
|
13
|
+
'--config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
14
|
+
]
|
|
15
|
+
# rubocop:enable Metrics/LineLength
|
|
16
|
+
|
|
17
|
+
def call(config:)
|
|
18
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
19
|
+
Sam::Puma::Shepherd.new.call(path)
|
|
20
|
+
rescue Errors::ProcessNotFound
|
|
21
|
+
warn 'Puma exited'
|
|
22
|
+
exit 1
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Puma
|
|
7
|
+
class Reaper < Hanami::CLI::Command
|
|
8
|
+
NO_MORE_PUMAS = 'Pumas are extinct =('
|
|
9
|
+
|
|
10
|
+
# rubocop:disable Metrics/LineLength
|
|
11
|
+
desc 'Stops the puma process'
|
|
12
|
+
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
13
|
+
|
|
14
|
+
example [
|
|
15
|
+
'-config config/server_settings.rb Stops the server in production mode using the config/server_settings.rb config file'
|
|
16
|
+
]
|
|
17
|
+
# rubocop:enable Metrics/LineLength
|
|
18
|
+
|
|
19
|
+
def call(config:)
|
|
20
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
21
|
+
result = Sam::Puma::Predator.new.call(path)
|
|
22
|
+
warn "Hunted a puma with pid #{result}"
|
|
23
|
+
rescue Errors::PidfileNotFound
|
|
24
|
+
warn NO_MORE_PUMAS
|
|
25
|
+
exit 1
|
|
26
|
+
rescue Errors::ConfigfileNotFound => ex
|
|
27
|
+
warn ex.message
|
|
28
|
+
exit 1
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Puma
|
|
7
|
+
class Spawner < Hanami::CLI::Command
|
|
8
|
+
# rubocop:disable Metrics/LineLength
|
|
9
|
+
desc 'Start the puma process'
|
|
10
|
+
|
|
11
|
+
option :environment, values: %w[production development test staging], default: 'production', desc: 'RACK_ENV to be used', aliases: %w[--env -e]
|
|
12
|
+
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/puma/production.rb', aliases: ['-c']
|
|
13
|
+
|
|
14
|
+
example [
|
|
15
|
+
'-e development #Starts the server in development mode',
|
|
16
|
+
'-e production --config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
17
|
+
]
|
|
18
|
+
# rubocop:enable Metrics/LineLength
|
|
19
|
+
|
|
20
|
+
def call(environment:, config:)
|
|
21
|
+
config = Pathname.new(Dir.pwd).join(config)
|
|
22
|
+
Sam::Puma::Breeder.new.call(environment, config)
|
|
23
|
+
warn "We have a newborn puma for environment #{environment} and configuration file: #{config}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'unicorn/monitor'
|
|
4
|
+
require_relative 'unicorn/reaper'
|
|
5
|
+
require_relative 'unicorn/reloader'
|
|
6
|
+
require_relative 'unicorn/spawner'
|
|
7
|
+
require_relative 'unicorn/runner'
|
|
8
|
+
|
|
9
|
+
# Upstart reload sends SIGHUP to the process
|
|
10
|
+
# Systemd expects an ExecReload= that syncronously reloads the confs.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Unicorn
|
|
7
|
+
class Monitor < Hanami::CLI::Command
|
|
8
|
+
# rubocop:disable Metrics/LineLength
|
|
9
|
+
desc 'Monitor an already running unicorn'
|
|
10
|
+
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
11
|
+
option :timeout, type: :integer, desc: 'The number of seconds to wait for starting the unicorn server', aliases: ['-t']
|
|
12
|
+
example [
|
|
13
|
+
'--config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
14
|
+
]
|
|
15
|
+
# rubocop:enable Metrics/LineLength
|
|
16
|
+
|
|
17
|
+
def call(config:)
|
|
18
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
19
|
+
Sam::Unicorn::Shepherd.new.call(path)
|
|
20
|
+
rescue Errors::ProcessNotFound
|
|
21
|
+
warn 'Unicorn exited'
|
|
22
|
+
exit 1
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Unicorn
|
|
7
|
+
class Reaper < Hanami::CLI::Command
|
|
8
|
+
NO_MORE_UNICORNS = 'Unicorns are already extinct'
|
|
9
|
+
|
|
10
|
+
# rubocop:disable Metrics/LineLength
|
|
11
|
+
desc 'Stops the unicorn process'
|
|
12
|
+
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
13
|
+
|
|
14
|
+
example [
|
|
15
|
+
'-config config/server_settings.rb Stops the server in production mode using the config/server_settings.rb config file'
|
|
16
|
+
]
|
|
17
|
+
# rubocop:enable Metrics/LineLength
|
|
18
|
+
|
|
19
|
+
def call(config:)
|
|
20
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
21
|
+
result = Sam::Unicorn::Predator.new.call(path)
|
|
22
|
+
warn "Hunted unicorn with pid #{result}"
|
|
23
|
+
rescue Errors::PidfileNotFound
|
|
24
|
+
warn NO_MORE_UNICORNS
|
|
25
|
+
exit 1
|
|
26
|
+
rescue Errors::ConfigfileNotFound => ex
|
|
27
|
+
warn ex.message
|
|
28
|
+
exit 1
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Unicorn
|
|
7
|
+
class Reloader < Hanami::CLI::Command
|
|
8
|
+
# rubocop:disable Metrics/LineLength
|
|
9
|
+
desc 'Reloads the unicorn configuration'
|
|
10
|
+
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
11
|
+
|
|
12
|
+
example [
|
|
13
|
+
'--config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
14
|
+
]
|
|
15
|
+
# rubocop:enable Metrics/LineLength
|
|
16
|
+
|
|
17
|
+
def call(config)
|
|
18
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
19
|
+
Sam::Unicorn::Cloner.new.call(path)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Unicorn
|
|
7
|
+
class Runner < Hanami::CLI::Command
|
|
8
|
+
# rubocop:disable Metrics/LineLength
|
|
9
|
+
desc 'Monitor an already running unicorn'
|
|
10
|
+
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
11
|
+
option :environment, values: %w[production development test staging], default: 'production', desc: 'RACK_ENV to be used', aliases: %w[--env -e]
|
|
12
|
+
option :timeout, type: :integer, desc: 'The number of seconds to wait for starting the unicorn server', default: 5, aliases: ['-t']
|
|
13
|
+
example [
|
|
14
|
+
'--config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file',
|
|
15
|
+
'-t 20 # Waits for 20 seconds for the master process to fork',
|
|
16
|
+
'-e production --config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
17
|
+
|
|
18
|
+
]
|
|
19
|
+
# rubocop:enable Metrics/LineLength
|
|
20
|
+
|
|
21
|
+
def call(config:, environment:, timeout:)
|
|
22
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
23
|
+
Sam::Unicorn::Breeder.new.call(environment, path)
|
|
24
|
+
Sam::Unicorn::Shepherd.new.call(path, timeout: Integer(timeout))
|
|
25
|
+
rescue Errors::ProcessNotFound
|
|
26
|
+
warn 'Unicorn seems dead.'
|
|
27
|
+
exit 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Unicorn
|
|
7
|
+
class Spawner < Hanami::CLI::Command
|
|
8
|
+
# rubocop:disable Metrics/LineLength
|
|
9
|
+
desc 'Start the unicorn process'
|
|
10
|
+
|
|
11
|
+
option :environment, values: %w[production development test staging], default: 'production', desc: 'RACK_ENV to be used', aliases: %w[--env -e]
|
|
12
|
+
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
13
|
+
|
|
14
|
+
example [
|
|
15
|
+
'-e development #Starts the server in development mode',
|
|
16
|
+
'-e production --config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
17
|
+
]
|
|
18
|
+
# rubocop:enable Metrics/LineLength
|
|
19
|
+
|
|
20
|
+
def call(environment:, config:)
|
|
21
|
+
config = Pathname.new(Dir.pwd).join(config)
|
|
22
|
+
Sam::Unicorn::Breeder.new.call(environment, config)
|
|
23
|
+
warn "We have a newborn unicorn for environment #{environment} and configuration file: #{config}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/sam/errors.rb
ADDED
data/lib/sam/puma.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'tty-command'
|
|
4
|
+
|
|
5
|
+
module Sam
|
|
6
|
+
module Puma
|
|
7
|
+
class Breeder
|
|
8
|
+
COMMAND = 'bundle exec puma -C ${CONF_PATH} -e ${RACK_ENV}'
|
|
9
|
+
|
|
10
|
+
def call(env, config)
|
|
11
|
+
cmd = TTY::Command.new(timeout: 120)
|
|
12
|
+
cmd.run(COMMAND, env: { CONF_PATH: config, RACK_ENV: env })
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'puma/cli'
|
|
4
|
+
|
|
5
|
+
module Sam
|
|
6
|
+
module Puma
|
|
7
|
+
class Identifier
|
|
8
|
+
def call(config_file)
|
|
9
|
+
setup_configurator(config_file)
|
|
10
|
+
Integer(read_pidfile)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def configuration
|
|
16
|
+
setup_configurator unless @configurator
|
|
17
|
+
@configurator
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def setup_configurator(config_file)
|
|
21
|
+
@configurator ||= (::Puma::Configuration.new({}) { |config| config.load config_file.to_s }).load
|
|
22
|
+
rescue Errno::ENOENT
|
|
23
|
+
raise Errors::ConfigfileNotFound, "File #{config_file} not found"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def read_pidfile
|
|
27
|
+
IO.readlines(@configurator.fetch(:pidfile)).join.chomp
|
|
28
|
+
rescue Errno::ENOENT # frozen_string_literal: true
|
|
29
|
+
raise Errors::PidfileNotFound, "PID File #{@configurator.fetch(:pidfile)} not found"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|