providers/docker: wait for running state, error if not
This commit is contained in:
parent
09cc823065
commit
c0f5095783
|
@ -34,8 +34,8 @@ module VagrantPlugins
|
||||||
b2.use SyncedFolderCleanup
|
b2.use SyncedFolderCleanup
|
||||||
b2.use SyncedFolders
|
b2.use SyncedFolders
|
||||||
b2.use PrepareNFSSettings
|
b2.use PrepareNFSSettings
|
||||||
# This will actually create and start, but that's fine
|
|
||||||
b2.use Create
|
b2.use Create
|
||||||
|
b2.use WaitForRunning
|
||||||
b2.use action_boot
|
b2.use action_boot
|
||||||
else
|
else
|
||||||
b2.use PrepareNFSValidIds
|
b2.use PrepareNFSValidIds
|
||||||
|
@ -205,6 +205,7 @@ module VagrantPlugins
|
||||||
Vagrant::Action::Builder.new.tap do |b|
|
Vagrant::Action::Builder.new.tap do |b|
|
||||||
# TODO: b.use SetHostname
|
# TODO: b.use SetHostname
|
||||||
b.use Start
|
b.use Start
|
||||||
|
b.use WaitForRunning
|
||||||
|
|
||||||
b.use Call, HasSSH do |env, b2|
|
b.use Call, HasSSH do |env, b2|
|
||||||
if env[:result]
|
if env[:result]
|
||||||
|
@ -230,6 +231,7 @@ module VagrantPlugins
|
||||||
autoload :PrepareNFSValidIds, action_root.join("prepare_nfs_valid_ids")
|
autoload :PrepareNFSValidIds, action_root.join("prepare_nfs_valid_ids")
|
||||||
autoload :PrepareNFSSettings, action_root.join("prepare_nfs_settings")
|
autoload :PrepareNFSSettings, action_root.join("prepare_nfs_settings")
|
||||||
autoload :Start, action_root.join("start")
|
autoload :Start, action_root.join("start")
|
||||||
|
autoload :WaitForRunning, action_root.join("wait_for_running")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
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
|
||||||
|
wait = false
|
||||||
|
elsif machine.provider.state.id == :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.provider.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.provider.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
|
|
@ -14,6 +14,12 @@ module VagrantPlugins
|
||||||
# provisioning, etc.
|
# provisioning, etc.
|
||||||
attr_accessor :has_ssh
|
attr_accessor :has_ssh
|
||||||
|
|
||||||
|
# True if the docker container is meant to stay in the "running"
|
||||||
|
# state (is a long running process). By default this is true.
|
||||||
|
#
|
||||||
|
# @return [Boolean]
|
||||||
|
attr_accessor :remains_running
|
||||||
|
|
||||||
# The name of the machine in the Vagrantfile set with
|
# The name of the machine in the Vagrantfile set with
|
||||||
# "vagrant_vagrantfile" that will be the docker host. Defaults
|
# "vagrant_vagrantfile" that will be the docker host. Defaults
|
||||||
# to "default"
|
# to "default"
|
||||||
|
@ -43,6 +49,7 @@ module VagrantPlugins
|
||||||
@image = UNSET_VALUE
|
@image = UNSET_VALUE
|
||||||
@ports = []
|
@ports = []
|
||||||
@privileged = UNSET_VALUE
|
@privileged = UNSET_VALUE
|
||||||
|
@remains_running = UNSET_VALUE
|
||||||
@volumes = []
|
@volumes = []
|
||||||
@vagrant_machine = UNSET_VALUE
|
@vagrant_machine = UNSET_VALUE
|
||||||
@vagrant_vagrantfile = UNSET_VALUE
|
@vagrant_vagrantfile = UNSET_VALUE
|
||||||
|
@ -54,6 +61,7 @@ module VagrantPlugins
|
||||||
@has_ssh = false if @has_ssh == UNSET_VALUE
|
@has_ssh = false if @has_ssh == UNSET_VALUE
|
||||||
@image = nil if @image == UNSET_VALUE
|
@image = nil if @image == UNSET_VALUE
|
||||||
@privileged = false if @privileged == UNSET_VALUE
|
@privileged = false if @privileged == UNSET_VALUE
|
||||||
|
@remains_running = true if @remains_running == UNSET_VALUE
|
||||||
@vagrant_machine = nil if @vagrant_machine == UNSET_VALUE
|
@vagrant_machine = nil if @vagrant_machine == UNSET_VALUE
|
||||||
@vagrant_vagrantfile = nil if @vagrant_vagrantfile == UNSET_VALUE
|
@vagrant_vagrantfile = nil if @vagrant_vagrantfile == UNSET_VALUE
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,7 +58,7 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
def start(cid)
|
def start(cid)
|
||||||
unless running?(cid)
|
if !running?(cid)
|
||||||
execute('docker', 'start', cid)
|
execute('docker', 'start', cid)
|
||||||
# This resets the cached information we have around, allowing `vagrant reload`s
|
# This resets the cached information we have around, allowing `vagrant reload`s
|
||||||
# to work properly
|
# to work properly
|
||||||
|
|
|
@ -21,6 +21,14 @@ module VagrantPlugins
|
||||||
error_key(:docker_provider_nfs_without_privileged)
|
error_key(:docker_provider_nfs_without_privileged)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class StateNotRunning < DockerError
|
||||||
|
error_key(:state_not_running)
|
||||||
|
end
|
||||||
|
|
||||||
|
class StateStopped < DockerError
|
||||||
|
error_key(:state_stopped)
|
||||||
|
end
|
||||||
|
|
||||||
class SyncedFolderNonDocker < DockerError
|
class SyncedFolderNonDocker < DockerError
|
||||||
error_key(:synced_folder_non_docker)
|
error_key(:synced_folder_non_docker)
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,8 @@ en:
|
||||||
ssh_through_host_vm: |-
|
ssh_through_host_vm: |-
|
||||||
SSH will be proxied through the Docker virtual machine since we're
|
SSH will be proxied through the Docker virtual machine since we're
|
||||||
not running Docker natively. This is just a notice, and not an error.
|
not running Docker natively. This is just a notice, and not an error.
|
||||||
|
waiting_for_running: |-
|
||||||
|
Waiting for container to enter "running" state...
|
||||||
|
|
||||||
messages:
|
messages:
|
||||||
destroying: |-
|
destroying: |-
|
||||||
|
@ -99,6 +101,31 @@ en:
|
||||||
Stderr: %{stderr}
|
Stderr: %{stderr}
|
||||||
|
|
||||||
Stdout: %{stdout}
|
Stdout: %{stdout}
|
||||||
|
state_not_running: |-
|
||||||
|
The container never entered the "running" state, or entered it
|
||||||
|
briefly but reverted back to another state. Please verify that
|
||||||
|
the configuration of the container is correct.
|
||||||
|
|
||||||
|
If you meant for this container to not remain running, please
|
||||||
|
set the Docker provider configuration "remains_running" to "false":
|
||||||
|
|
||||||
|
config.vm.provider "docker" do |d|
|
||||||
|
d.remains_running = false
|
||||||
|
end
|
||||||
|
|
||||||
|
state_stopped: |-
|
||||||
|
The container started either never left the "stopped" state or
|
||||||
|
very quickly reverted to the "stopped" state. This is usually
|
||||||
|
because the container didn't execute a command that kept it running,
|
||||||
|
and usually indicates a misconfiguration.
|
||||||
|
|
||||||
|
If you meant for this container to not remain running, please
|
||||||
|
set the Docker provider configuration "remains_running" to "false":
|
||||||
|
|
||||||
|
config.vm.provider "docker" do |d|
|
||||||
|
d.remains_running = false
|
||||||
|
end
|
||||||
|
|
||||||
synced_folder_non_docker: |-
|
synced_folder_non_docker: |-
|
||||||
The "docker" synced folder type can't be used because the provider
|
The "docker" synced folder type can't be used because the provider
|
||||||
in use is not Docker. This synced folder type only works with the
|
in use is not Docker. This synced folder type only works with the
|
||||||
|
|
Loading…
Reference in New Issue