vaguerent/plugins/providers/docker/action/wait_for_running.rb
Paul Hinze 8d46b09a11
Fix Docker machines being lost in go side
By pruning machines that are in "unknown" status after each operation,
the Go code path exposed the fact that the Docker provider was not
updating the machine index during an "up" - leaving the state as
"unknown".

This is basically a bug within the Docker provider, so I think it's okay
to update the plugin code to correct this rather than working around the
issue in Go.

All we need to do is call `machine.state` instead of reaching through to
`machine.provider.state` while waiting for the container to be started.
That causes the extra logic for updating the machine index in
`machine.state` to fire.
2022-07-13 14:04:32 -05:00

69 lines
1.6 KiB
Ruby

require "thread"
require "log4r"
module VagrantPlugins
module DockerProvider
module Action
class WaitForRunning
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::docker::waitforrunning")
end
def call(env)
machine = env[:machine]
wait = true
if !machine.provider_config.remains_running
@logger.debug("remains_running is false")
wait = false
elsif machine.state.id == :running
@logger.debug("container is already running")
wait = false
end
# If we're not waiting, just return
return @app.call(env) if !wait
machine.ui.output(I18n.t("docker_provider.waiting_for_running"))
# First, make sure it leaves the stopped state if its supposed to.
after = sleeper(5)
while machine.state.id == :stopped
if after[:done]
raise Errors::StateStopped
end
sleep 0.2
end
# Then, wait for it to become running
after = sleeper(30)
while true
state = machine.state
break if state.id == :running
@logger.info("Waiting for container to run. State: #{state.id}")
if after[:done]
raise Errors::StateNotRunning
end
sleep 0.2
end
@app.call(env)
end
protected
def sleeper(duration)
Thread.new(duration) do |d|
sleep(d)
Thread.current[:done] = true
end
end
end
end
end
end