core: lock around machine actions
This commit is contained in:
parent
8a76c2bc76
commit
862414af12
|
@ -404,6 +404,10 @@ module Vagrant
|
|||
error_key(:local_data_dir_not_accessible)
|
||||
end
|
||||
|
||||
class MachineActionLockedError < VagrantError
|
||||
error_key(:machine_action_locked)
|
||||
end
|
||||
|
||||
class MachineGuestNotReady < VagrantError
|
||||
error_key(:machine_guest_not_ready)
|
||||
end
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require "digest/md5"
|
||||
require "thread"
|
||||
|
||||
require "log4r"
|
||||
|
@ -147,18 +148,28 @@ module Vagrant
|
|||
def action(name, extra_env=nil)
|
||||
@logger.info("Calling action: #{name} on provider #{@provider}")
|
||||
|
||||
# Get the callable from the provider.
|
||||
callable = @provider.action(name)
|
||||
# Create a deterministic ID for this machine
|
||||
id = Digest::MD5.hexdigest("#{@env.root_path}#{@name}")
|
||||
|
||||
# If this action doesn't exist on the provider, then an exception
|
||||
# must be raised.
|
||||
if callable.nil?
|
||||
raise Errors::UnimplementedProviderAction,
|
||||
:action => name,
|
||||
:provider => @provider.to_s
|
||||
# Lock this machine for the duration of this action
|
||||
@env.lock("machine-action-#{id}") do
|
||||
# Get the callable from the provider.
|
||||
callable = @provider.action(name)
|
||||
|
||||
# If this action doesn't exist on the provider, then an exception
|
||||
# must be raised.
|
||||
if callable.nil?
|
||||
raise Errors::UnimplementedProviderAction,
|
||||
:action => name,
|
||||
:provider => @provider.to_s
|
||||
end
|
||||
|
||||
action_raw(name, callable, extra_env)
|
||||
end
|
||||
|
||||
action_raw(name, callable, extra_env)
|
||||
rescue Errors::EnvironmentLockedError
|
||||
raise Errors::MachineActionLockedError,
|
||||
action: name,
|
||||
name: @name
|
||||
end
|
||||
|
||||
# This calls a raw callable in the proper context of the machine using
|
||||
|
|
|
@ -744,6 +744,16 @@ en:
|
|||
that the NFS client software is properly installed, and consult any resources
|
||||
specific to the linux distro you're using for more information on how to
|
||||
do this.
|
||||
machine_action_locked: |-
|
||||
An action '%{action}' was attempted on the machine '%{name}',
|
||||
but another process is already executing an action on the machine.
|
||||
Vagrant locks each machine for access by only one process at a time.
|
||||
Please wait until the other Vagrant process finishes modifying this
|
||||
machine, then try again.
|
||||
|
||||
If you believe this message is in error, please check the process
|
||||
listing for any "ruby" or "vagrant" processes and kill them. Then
|
||||
try again.
|
||||
machine_guest_not_ready: |-
|
||||
Guest-specific operations were attempted on a machine that is not
|
||||
ready for guest communication. This should not happen and a bug
|
||||
|
|
|
@ -208,7 +208,7 @@ describe Vagrant::Machine do
|
|||
end
|
||||
end
|
||||
|
||||
describe "actions" do
|
||||
describe "#action" do
|
||||
it "should be able to run an action that exists" do
|
||||
action_name = :up
|
||||
called = false
|
||||
|
|
Loading…
Reference in New Issue