1module MCollective 2 class Application::Service < Application 3 description "Manages system services" 4 5 usage <<-END_OF_USAGE 6mco service <SERVICE> <ACTION> 7 8ACTION can be one of the following : 9 10 start - start service 11 stop - stop service 12 restart - restart or reload service 13 status - determine the current staus of the remote service 14END_OF_USAGE 15 16 option :yes, 17 :arguments => ["--yes", "-y"], 18 :description => "Assume yes on any prompts", 19 :type => :bool 20 21 def handle_message(action, message, *args) 22 messages = {1 => "Please specify service name and action", 23 2 => "Action has to be one of start, stop, restart or status", 24 3 => "Do you really want to operate on services unfiltered? (y/n): "} 25 26 send(action, messages[message] % args) 27 end 28 29 def post_option_parser(configuration) 30 if ARGV.size < 2 31 handle_message(:raise, 1) 32 else 33 valid_actions = ['start', 'stop', 'restart', 'status'] 34 35 if valid_actions.include?(ARGV[0]) 36 configuration[:action] = ARGV.shift 37 configuration[:service] = ARGV.shift 38 elsif valid_actions.include?(ARGV[1]) 39 configuration[:service] = ARGV.shift 40 configuration[:action] = ARGV.shift 41 else 42 handle_message(:raise, 2) 43 end 44 end 45 end 46 47 def validate_configuration(configuration) 48 unless configuration[:action] == 'status' 49 if Util.empty_filter?(options[:filter]) && !configuration[:yes] 50 handle_message(:print, 3) 51 52 STDOUT.flush 53 54 exit(1) unless STDIN.gets.strip.match(/^(?:y|yes)$/i) 55 end 56 end 57 end 58 59 def main 60 # We have to change our process name in order to hide name of the 61 # service we are looking for from our execution arguments. Puppet 62 # provider will look at the process list for the name of the service 63 # it wants to manage and it might find us with our arguments there 64 # which is not what we really want ... 65 $0 = 'mco' 66 67 service = rpcclient('service') 68 service_result = service.send(configuration[:action], :service => configuration[:service]) 69 70 if !service_result.empty? 71 sender_width = service_result.map{|s| s[:sender]}.map{|s| s.length}.max + 3 72 pattern = "%%%ds: %%s" % sender_width 73 74 service_result.each do |result| 75 if result[:statuscode] == 0 76 if service.verbose 77 puts pattern % [result[:sender], result[:data][:status]] 78 else 79 case configuration[:action] 80 when 'start', 'restart' 81 puts(pattern % [result[:sender], result[:data][:status]]) unless result[:data][:status] == 'running' 82 when 'stop' 83 puts(pattern % [result[:sender], result[:data][:status]]) unless result[:data][:status] == 'stopped' 84 when 'status' 85 puts(pattern % [result[:sender], result[:data][:status]]) 86 end 87 end 88 else 89 puts(pattern % [result[:sender], result[:statusmsg]]) 90 end 91 end 92 93 puts 94 end 95 96 printrpcstats :summarize => true, :caption => "%s Service results" % configuration[:action] 97 halt(service.stats) 98 end 99 end 100end 101