Skip to content

Commit

Permalink
Relocate the service implementation code in to a separate class
Browse files Browse the repository at this point in the history
Allows for alternative service managers
  • Loading branch information
Graham Christensen committed Jan 27, 2017
1 parent 05c7a89 commit 06e7e11
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/jetpants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
module Jetpants; end

$LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'jetpants'), File.join(File.dirname(__FILE__), '..', 'plugins')
%w(output callback table host db pool topology shard shardpool monkeypatch commandsuite).each {|g| require g}
%w(output callback table host hostservice db pool topology shard shardpool monkeypatch commandsuite).each {|g| require g}

# Since Jetpants is extremely multi-threaded, we need to force uncaught exceptions to
# kill all threads in order to have any kind of sane error handling.
Expand Down
34 changes: 16 additions & 18 deletions lib/jetpants/host.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def initialize(ip)
@lock = Mutex.new
@available = nil
@clone_multi_threaded = false # default use fast_copy_chain
@service_manager = nil
end

# Returns a Host object for the machine Jetpants is running on.
Expand Down Expand Up @@ -770,40 +771,37 @@ def mount_stats(mount)
end
end

###### Misc methods ########################################################
###### Service management methods ##########################################
def service_api
if @service_manager.nil?
@service_manager = Jetpants::HostService.pick_by_preflight(self)
end

@service_manager
end

def service_start(name, options=[])
output service(:start, name, options.join(' '))
output service_api.start(name, options)
end

def service_restart(name, options=[])
output service(:restart, name, options.join(' '))
output service_api.restart(name, options)
end

def service_stop(name)
output service(:stop, name)
output service_api.stop(name)
end

def service_running?(name)
status = service(:status, name).downcase
# mysql is running if the output of "service mysql status" doesn't include any of these strings
not_running_strings = ['not running', 'stop/waiting']

not_running_strings.none? {|str| status.include? str}
service_api.running?(name)
end

# Performs the given operation (:start, :stop, :restart, :status) for the
# specified service (ie "mysql"). Requires that the "service" bin is in
# root's PATH.
# Please be aware that the output format and exit codes for the service
# binary vary between Linux distros! You may find that you need to override
# methods that call Host#service with :status operation (such as
# DB#probe_running) in a custom plugin, to parse the output properly on
# your chosen Linux distro.
def service(operation, name, options='')
ssh_cmd "service #{name} #{operation.to_s} #{options}".rstrip
output "Warning: Calling Host.service directly is deprecated!".red
service_manager.service_direct(operation, name, options).rstrip
end

###### Misc methods ########################################################
# `stat` call to get all the information about the given file
def get_file_stats(filename)
mode_re = /^Access:\s+\((?<mode>\d+)\/(?<permissions>[drwx-]+)\)\s+Uid:\s+\(\s+\d+\/\s+(?<user>\w+)\)\s+Gid:\s+\(\s+\d+\/\s+(?<group>\w+)\)$/x
Expand Down
26 changes: 26 additions & 0 deletions lib/jetpants/hostservice.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'hostservice/upstart'

module Jetpants
module HostService
def self.pick_by_preflight(host)
# We want to pick the first provider which the machine supports. Ruby 1.9.2 has no
# `first_where` method like
# [1, 2, 3].first { |i| i > 1 } == 2
# but the next line fakes it, by deleting items until we find one which does match, then
# taking the first item in the array.
# This could be a `.map` or a `.select` but we really don't want to try any more than we
# have to.
provider = all_providers.drop_while { |candidate| ! candidate.preflight(host) }.first
raise "Cannot detect a valid service provider for #{host}" if provider.nil?

return provider.new(host)
end

def self.all_providers
# Service managers that we can support, in order of most to least likely
[
Jetpants::HostService::Upstart,
]
end
end
end
47 changes: 47 additions & 0 deletions lib/jetpants/hostservice/upstart.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Jetpants
module HostService
class Upstart
def self.preflight(host)
host.has_installed('service')
end

def initialize(host)
@host = host
end

def start(name, options=[])
service(:start, name, options.join(' '))
end

def restart(name, options=[])
service(:restart, name, options.join(' '))
end

def stop(name)
service(:stop, name)
end

def running?(name)
status = service(:status, name).downcase
# the service is running if the output of "service #{name} status" doesn't include any of
# these strings
not_running_strings = ['not running', 'stop/waiting']

not_running_strings.none? {|str| status.include? str}
end

def service_direct(operation, name, options='')
service(operation, name, options)
end

# Performs the given operation (:start, :stop, :restart, :status) for the
# specified service (ie "mysql"). Requires that the "service" bin is in
# root's PATH.
# Please be aware that the output format and exit codes for the service
# binary vary between Linux distros!
def service(operation, name, options='')
@host.ssh_cmd "service #{name} #{operation.to_s} #{options}".rstrip
end
end
end
end

0 comments on commit 06e7e11

Please sign in to comment.