mirror of
https://github.com/vagrant-libvirt/vagrant-libvirt.git
synced 2025-02-25 18:55:27 -06:00
Refactor WaitTillUp action to make use of the domain IP address retrieval code in the driver to ensure a single place to maintain. Remove references to machine option for driver where already should be available as an instance variable.
105 lines
3.7 KiB
Ruby
105 lines
3.7 KiB
Ruby
require 'log4r'
|
|
require 'vagrant-libvirt/errors'
|
|
require 'vagrant-libvirt/util/timer'
|
|
require 'vagrant/util/retryable'
|
|
|
|
module VagrantPlugins
|
|
module ProviderLibvirt
|
|
module Action
|
|
# Wait till domain is started, till it obtains an IP address and is
|
|
# accessible via ssh.
|
|
class WaitTillUp
|
|
include Vagrant::Util::Retryable
|
|
|
|
def initialize(app, _env)
|
|
@logger = Log4r::Logger.new('vagrant_libvirt::action::wait_till_up')
|
|
@app = app
|
|
end
|
|
|
|
def call(env)
|
|
# Initialize metrics if they haven't been
|
|
env[:metrics] ||= {}
|
|
|
|
# Get domain object
|
|
domain = env[:machine].provider.driver.get_domain(env[:machine].id.to_s)
|
|
if domain.nil?
|
|
raise Errors::NoDomainError,
|
|
error_message: "Domain #{env[:machine].id} not found"
|
|
end
|
|
|
|
# Wait for domain to obtain an ip address. Ip address is searched
|
|
# from arp table, either locally or remotely via ssh, if Libvirt
|
|
# connection was done via ssh.
|
|
env[:ip_address] = nil
|
|
@logger.debug("Searching for IP for MAC address: #{domain.mac}")
|
|
env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip'))
|
|
|
|
env[:metrics]['instance_ip_time'] = Util::Timer.time do
|
|
retryable(on: Fog::Errors::TimeoutError, tries: 300) do
|
|
# just return if interrupted and let the warden call recover
|
|
return if env[:interrupted]
|
|
|
|
# Wait for domain to obtain an ip address
|
|
env[:ip_address] = env[:machine].provider.driver.get_domain_ipaddress(domain)
|
|
end
|
|
end
|
|
|
|
@logger.info("Got IP address #{env[:ip_address]}")
|
|
@logger.info("Time for getting IP: #{env[:metrics]['instance_ip_time']}")
|
|
|
|
# Machine has ip address assigned, now wait till we are able to
|
|
# connect via ssh.
|
|
env[:metrics]['instance_ssh_time'] = Util::Timer.time do
|
|
env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ssh'))
|
|
retryable(on: Fog::Errors::TimeoutError, tries: 60) do
|
|
# If we're interrupted don't worry about waiting
|
|
next if env[:interrupted]
|
|
|
|
# Wait till we are able to connect via ssh.
|
|
loop do
|
|
# If we're interrupted then just back out
|
|
break if env[:interrupted]
|
|
break if env[:machine].communicate.ready?
|
|
sleep 2
|
|
end
|
|
end
|
|
end
|
|
# just return if interrupted and let the warden call recover
|
|
return if env[:interrupted]
|
|
@logger.info("Time for SSH ready: #{env[:metrics]['instance_ssh_time']}")
|
|
|
|
# Booted and ready for use.
|
|
# env[:ui].info(I18n.t("vagrant_libvirt.ready"))
|
|
|
|
@app.call(env)
|
|
end
|
|
|
|
def recover(env)
|
|
# Undo the import
|
|
terminate(env)
|
|
end
|
|
|
|
def terminate(env)
|
|
if env[:machine].provider.state.id != :not_created
|
|
# If we're not supposed to destroy on error then just return
|
|
return unless env[:destroy_on_error]
|
|
|
|
if env[:halt_on_error]
|
|
halt_env = env.dup
|
|
halt_env.delete(:interrupted)
|
|
halt_env[:config_validate] = false
|
|
env[:action_runner].run(Action.action_halt, halt_env)
|
|
else
|
|
destroy_env = env.dup
|
|
destroy_env.delete(:interrupted)
|
|
destroy_env[:config_validate] = false
|
|
destroy_env[:force_confirm_destroy] = true
|
|
env[:action_runner].run(Action.action_destroy, destroy_env)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|