Wait for a remote service to start up

Sometimes service startup must wait for another service on a remote host. For example, Sensu Client requires that RabbitMQ has already started up.

In a shell script:

waitforport(){
  local host=$1 port=$2 interval=$3 retries=$4 i
  for i in `seq "$retries"`; do
    nc -z "$host" "$port" && break
    sleep "$interval"
  done
  nc -z "$host" "$port"
}

# Scans rabbit:5672 1+10 times at most, with 5 seconds interval
waitforport rabbit 5672 5 10

In Puppet configuration:

class sensu::client::service(
    $rabbit_host = $sensu::client::params::rabbit_host,
    $rabbit_port = $sensu::client::params::rabbit_port,
) inherits sensu::client::params {
    exec { 'await-rabbit-for-sensu-client':
        provider => 'shell',
        command => "for i in `seq 10`; do nc -z ${rabbit_host} ${rabbit_port} && break; sleep 5; done; nc -z ${rabbit_host} ${rabbit_port}",
    }
    service { 'sensu-client':
        enable => true,
        ensure => running,
        require => Exec['await-rabbit-for-sensu-client'],
    }
}