Module: Chef::MonitWrapper::StartStop

Includes:
Chef::Mixin::ShellOut, Status
Defined in:
libraries/start_stop.rb

Instance Method Summary collapse

Methods included from Status

#get_monit_summary, #get_stable_monit_service_status, #monit_service_exists_and_running?, #monit_service_registered?, #monit_service_running?, #monit_status_stable?, #parse_monit_summary

Instance Method Details

#ensure_monit_daemon_is_runningObject

Ensure the Monit daemon is running.



104
105
106
107
108
109
110
# File 'libraries/start_stop.rb', line 104

def ensure_monit_daemon_is_running
  Chef::Log.info('Ensuring the Monit service is running')
  result = shell_out('service monit start')
  if result.exitstatus != 0 && !result.stderr.include?('start: Job is already running: monit')
    fail "Failed to start Monit. stdout:\n#{result.stdout}\nstderr:\n#{result.stderr}"
  end
end

#restart_monit_service(service_name, options = {}) ⇒ Object

Restarts the given Monit service. Waits for the service status to stabilize before and after issuing the restart command. If a host/port combination is specified, waits for the given host to start listening on the given TCP port before returning.

Parameters:

  • service_name (String)

    service name

  • options (Hash) (defaults to: {})

    a hash with optional arguments:

    • :host - host to wait for
    • :port - TCP port number to wait for
    • :timeout_sec - the maximum number of seconds to wait for the given host/port combination to become available.


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'libraries/start_stop.rb', line 82

def restart_monit_service(service_name, options = {})
  options = options.clone
  host = options.delete(:host) || 'localhost',
  port = options.delete(:port)
  timeout_sec = options.delete(:timeout_sec) || DEFAULT_MONIT_SERVICE_HOST_PORT_TIMEOUT_SEC
  raise "Invalid options: #{options}" unless options.empty?

  get_stable_monit_service_status(service_name)
  shell_out!("monit restart #{service_name}")

  # Wait for service status to stabilize once again.
  get_stable_monit_service_status(service_name)
  if host && port
    require 'waitutil'  # Only require this when necessary, so that the gem is installed.
    Chef::Log.info(
      "Waiting for service #{service_name} to become available on host #{host}, port #{port}")
    WaitUtil.wait_for_service(service_name, host, port, delay_sec: 1,
      timeout_sec: timeout_sec)
  end
end

#start_monit_service(service_name, options = {}) ⇒ Object

Starts the given Monit service. Waits for the service status to stabilize before and after issuing the start command. If a host/port combination is specified, waits for the given host to start listening on the given TCP port before returning.

Parameters:

  • service_name (String)

    service name

  • options (Hash) (defaults to: {})

    a hash with optional arguments:

    • :host - host to wait for
    • :port - TCP port number to wait for
    • :timeout_sec - the maximum number of seconds to wait for the given host/port combination to become available.


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'libraries/start_stop.rb', line 37

def start_monit_service(service_name, options = {})
  options = options.clone
  host = options.delete(:host) || 'localhost',
  port = options.delete(:port)
  timeout_sec = options.delete(:timeout_sec) || DEFAULT_MONIT_SERVICE_HOST_PORT_TIMEOUT_SEC
  raise "Invalid options: #{options}" unless options.empty?

  # Wait for the service status to stabilize to avoid the
  # "Other action already in progress -- please try again later" error.

  get_stable_monit_service_status(service_name)

  shell_out!("monit start #{service_name}")

  # Wait for service status to stabilize once again.
  get_stable_monit_service_status(service_name)

  if host && port
    require 'waitutil'  # Only require this when necessary, so that the gem is installed.
    Chef::Log.info(
      "Waiting for service #{service_name} to become available on host #{host}, port #{port}")
    WaitUtil.wait_for_service(service_name, host, port, delay_sec: 1,
      timeout_sec: timeout_sec)
  end
end

#stop_monit_service(service_name) ⇒ Object

Stops the given Monit service. Waits for the service status to stabilize before and after issuing the stop command.



65
66
67
68
69
# File 'libraries/start_stop.rb', line 65

def stop_monit_service(service_name)
  get_stable_monit_service_status(service_name)
  shell_out!("monit stop #{service_name}")
  get_stable_monit_service_status(service_name)
end

#wait_for_monit_service_to_exist(service_name) ⇒ Object

Wait for the given service to be recognized as a Monit service. This is determined by checking whether the output of the monit status command includes the given service name.

Parameters:

  • service_name (String)

    service name



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'libraries/start_stop.rb', line 115

def wait_for_monit_service_to_exist(service_name)
  require 'waitutil'
  WaitUtil.wait_for_condition(
    "#{service_name} to show up in the output of 'monit status'",
    delay_sec: 1,
    timeout_sec: 120
  ) do
    p = shell_out("#{node['monit']['executable']} status")
    stdout_stderr_combined = "stdout:\n#{p.stdout}\nstderr:#{p.stderr}"
    if p.stderr.include?('Status not available -- the monit daemon is not running')
      # Monit might have crashed on the "monit reload" command. Restart it as a temporary
      # workaround.
      ensure_monit_daemon_is_running
      [false, stdout_stderr_combined]
    else
      if p.exitstatus != 0
        Chef::Log.fatal("Command '#{p.command}' failed\n" +
                        "stdout:\n#{p.stdout}\nstderr:\n#{p.stderr}")
        fail
      end
      [p.stdout.split("\n").include?("Process '#{service_name}'"),
       stdout_stderr_combined]
    end
  end
end