Add a pre-connect hook

This can be used for hooks that should run before connecting to remote
hosts. An example use case is pre-warming DNS.
This commit is contained in:
Donal McBreen
2023-05-24 11:39:48 +01:00
parent 483b893018
commit 66f9ce0e90
8 changed files with 75 additions and 9 deletions

View File

@@ -76,6 +76,8 @@ module Mrsk::Cli
if MRSK.holding_lock?
yield
else
run_hook "pre-connect"
acquire_lock
begin
@@ -135,7 +137,7 @@ module Mrsk::Cli
if !options[:skip_hooks] && MRSK.hook.hook_exists?(hook)
say "Running the #{hook} hook...", :magenta
run_locally do
MRSK.with_verbosity(:debug) { execute *MRSK.hook.run(hook, **details) }
MRSK.with_verbosity(:debug) { execute *MRSK.hook.run(hook, **details, hosts: MRSK.hosts.join(",")) }
rescue SSHKit::Command::Failed
raise HookError.new("Hook `#{hook}` failed")
end

View File

@@ -12,6 +12,8 @@
# MRSK_RECORDED_AT
# MRSK_PERFORMER
# MRSK_VERSION
# MRSK_HOSTS
# MRSK_ROLE (if set)
# MRSK_DESTINATION (if set)
# MRSK_RUNTIME

View File

@@ -12,6 +12,8 @@
# MRSK_RECORDED_AT
# MRSK_PERFORMER
# MRSK_VERSION
# MRSK_HOSTS
# MRSK_ROLE (if set)
# MRSK_DESTINATION (if set)
if [ -n "$(git status --porcelain)" ]; then

View File

@@ -0,0 +1,47 @@
#!/usr/bin/env ruby
# A sample pre-connect check
#
# Warms DNS before connecting to hosts in parallel
#
# These environment variables are available:
# MRSK_RECORDED_AT
# MRSK_PERFORMER
# MRSK_VERSION
# MRSK_HOSTS
# MRSK_ROLE (if set)
# MRSK_DESTINATION (if set)
# MRSK_RUNTIME
hosts = ENV["MRSK_HOSTS"].split(",")
results = nil
max = 3
elapsed = Benchmark.realtime do
results = hosts.map do |host|
Thread.new do
tries = 1
begin
Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME)
rescue SocketError
if tries < max
puts "Retrying DNS warmup: #{host}"
tries += 1
sleep rand
retry
else
puts "DNS warmup failed: #{host}"
host
end
end
tries
end
end.map(&:value)
end
retries = results.sum - hosts.size
nopes = results.count { |r| r == max }
puts "Prewarmed %d DNS lookups in %.2f sec: %d retries, %d failures" % [ hosts.size, elapsed, retries, nopes ]