83 lines
2.4 KiB
Ruby
83 lines
2.4 KiB
Ruby
# Copyright (c) HashiCorp, Inc.
|
|
# SPDX-License-Identifier: BUSL-1.1
|
|
|
|
module Vagrant
|
|
module Action
|
|
module Builtin
|
|
# This waits for the communicator to be ready for a set amount of
|
|
# time.
|
|
class WaitForCommunicator
|
|
def initialize(app, env, states=nil)
|
|
@app = app
|
|
@states = states
|
|
end
|
|
|
|
def call(env)
|
|
# Wait for ready in a thread so that we can continually check
|
|
# for interrupts.
|
|
ready_thr = Thread.new do
|
|
Thread.current[:result] = env[:machine].communicate.wait_for_ready(
|
|
env[:machine].config.vm.boot_timeout)
|
|
end
|
|
|
|
# Start a thread that verifies the VM stays in a good state.
|
|
states_thr = Thread.new do
|
|
Thread.current[:result] = true
|
|
|
|
# Otherwise, periodically verify the VM isn't in a bad state.
|
|
while true
|
|
state = env[:machine].state.id
|
|
|
|
# Used to report invalid states
|
|
Thread.current[:last_known_state] = state
|
|
|
|
# Check if we have the proper state so we can break out
|
|
if @states && !@states.include?(state)
|
|
Thread.current[:result] = false
|
|
break
|
|
end
|
|
|
|
# Sleep a bit so we don't hit 100% CPU constantly.
|
|
sleep 1
|
|
end
|
|
end
|
|
|
|
# Wait for a result or an interrupt
|
|
env[:ui].output(I18n.t("vagrant.boot_waiting"))
|
|
while ready_thr.alive? && states_thr.alive?
|
|
sleep 1
|
|
return if env[:interrupted]
|
|
end
|
|
|
|
# Join so that they can raise exceptions if there were any
|
|
ready_thr.join if !ready_thr.alive?
|
|
states_thr.join if !states_thr.alive?
|
|
|
|
# If it went into a bad state, then raise an error
|
|
if !states_thr[:result]
|
|
raise Errors::VMBootBadState,
|
|
valid: @states.join(", "),
|
|
invalid: states_thr[:last_known_state]
|
|
end
|
|
|
|
# If it didn't boot, raise an error
|
|
if !ready_thr[:result]
|
|
raise Errors::VMBootTimeout
|
|
end
|
|
|
|
env[:ui].output(I18n.t("vagrant.boot_completed"))
|
|
|
|
# Make sure our threads are all killed
|
|
ready_thr.kill
|
|
states_thr.kill
|
|
|
|
@app.call(env)
|
|
ensure
|
|
ready_thr.kill
|
|
states_thr.kill
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|