summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeth Chisamore <schisamo@opscode.com>2012-11-17 16:39:25 -0500
committerSeth Chisamore <schisamo@opscode.com>2012-11-17 16:39:25 -0500
commitd84c5056f458efb4b26fa9d4b1ee7065e11dea10 (patch)
treee8c8a229d8c6e9661f32dd7da78bff1d491a5c84
parent55a1a45dfc54e12820d2bdb76cc8eebf05be9675 (diff)
parent6d7fd257a4c64e548f90faa7dc9212f14270e1f7 (diff)
downloadchef-d84c5056f458efb4b26fa9d4b1ee7065e11dea10.tar.gz
Merge branch 'CHEF-3617'
-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