summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/chef/run_lock.rb6
-rw-r--r--spec/functional/run_lock_spec.rb17
2 files changed, 21 insertions, 2 deletions
diff --git a/lib/chef/run_lock.rb b/lib/chef/run_lock.rb
index ffe4d66045..c63895e87b 100644
--- a/lib/chef/run_lock.rb
+++ b/lib/chef/run_lock.rb
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+require 'chef/mixin/create_path'
+
class Chef
# == Chef::RunLock
@@ -24,6 +26,8 @@ class Chef
# Used by Chef::Client to ensure only one instance of chef-client (or solo)
# is modifying the system at a time.
class RunLock
+ include Chef::Mixin::CreatePath
+
attr_reader :runlock
attr_reader :runlock_file
@@ -48,6 +52,8 @@ class Chef
#
# The implementation is based on File#flock (see also: flock(2)).
def acquire
+ # ensure the runlock_file path exists
+ create_path(File.dirname(runlock_file))
@runlock = File.open(runlock_file,'w+')
unless runlock.flock(File::LOCK_EX|File::LOCK_NB)
# Another chef client running...
diff --git a/spec/functional/run_lock_spec.rb b/spec/functional/run_lock_spec.rb
index af9bd1aa1f..1efc4ad42d 100644
--- a/spec/functional/run_lock_spec.rb
+++ b/spec/functional/run_lock_spec.rb
@@ -22,9 +22,22 @@ describe Chef::RunLock do
# This behavior is believed to work on windows, but the tests use UNIX APIs.
describe "when locking the chef-client run", :unix_only => true do
+ let(:random_temp_root){ "/tmp/#{Random.rand(Time.now.to_i + Process.pid)}" }
+
+ let(:file_cache_path){ "/var/chef/cache" }
+ let(:lockfile){ "#{random_temp_root}/this/long/path/does/not/exist/chef-client-running.pid" }
+
+ after(:each){ FileUtils.rm_r(random_temp_root) }
+
+ it "creates the full path to the lockfile" do
+ run_lock = Chef::RunLock.new(:file_cache_path => file_cache_path, :lockfile => lockfile)
+ lambda { run_lock.acquire }.should_not raise_error(Errno::ENOENT)
+ File.should exist(lockfile)
+ end
+
it "allows only one chef client run per lockfile" do
read, write = IO.pipe
- run_lock = Chef::RunLock.new(:file_cache_path => "/var/chef/cache", :lockfile => "/tmp/chef-client-running.pid")
+ run_lock = Chef::RunLock.new(:file_cache_path => file_cache_path, :lockfile => lockfile)
p1 = fork do
run_lock.acquire
write.puts 1
@@ -56,7 +69,7 @@ describe Chef::RunLock do
it "clears the lock if the process dies unexpectedly" do
read, write = IO.pipe
- run_lock = Chef::RunLock.new(:file_cache_path => "/var/chef/cache", :lockfile => "/tmp/chef-client-running.pid")
+ run_lock = Chef::RunLock.new(:file_cache_path => file_cache_path, :lockfile => lockfile)
p1 = fork do
run_lock.acquire
write.puts 1