about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-11-01 11:56:16 -0800
committerEric Wong <normalperson@yhbt.net>2009-11-01 11:57:13 -0800
commit171df888464ec24d94a8e92e38742f86ac55d0f7 (patch)
tree75dd699efe76103e7a1e87785869647b079ef642
parent66a99327d91e3dd1974e615aa985759f984c5c64 (diff)
downloadunicorn-171df888464ec24d94a8e92e38742f86ac55d0f7.tar.gz
This basically a prettier way of saying:

  Dir.chdir(Unicorn::HttpServer::START_CTX[:cwd] = path)

In the config file.  Unfortunately, this is configuration
directive where order matters and you should specify it
before any other path[1] directives if you're using relative
paths (relative paths are not recommended anyways)

[1] pid, stderr_path, stdout_path
-rw-r--r--lib/unicorn/configurator.rb11
-rw-r--r--test/exec/test_exec.rb39
2 files changed, 50 insertions, 0 deletions
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index a074fcf..1f0852a 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -9,6 +9,7 @@ module Unicorn
   #
   # Example (when used with the unicorn config file):
   #   worker_processes 4
+  #   working_directory "/path/to/deploy/app/current"
   #   listen '/tmp/my_app.sock', :backlog => 1
   #   listen 9292, :tcp_nopush => true
   #   timeout 10
@@ -345,6 +346,16 @@ module Unicorn
       set_path(:stdout_path, path)
     end
 
+    # sets the working directory for Unicorn.  This ensures USR2 will
+    # start a new instance of Unicorn in this directory.  This may be
+    # a symlink.  You should specify this directive near the top or
+    # your config file before any relative paths for other config
+    # directives (or avoid relative paths entirely).
+    def working_directory(path)
+      # just let chdir raise errors
+      Dir.chdir(HttpServer::START_CTX[:cwd] = path)
+    end
+
     # expands "unix:path/to/foo" to a socket relative to the current path
     # expands pathnames of sockets if relative to "~" or "~username"
     # expands "*:port and ":port" to "0.0.0.0:port"
diff --git a/test/exec/test_exec.rb b/test/exec/test_exec.rb
index 268a84e..7edfa71 100644
--- a/test/exec/test_exec.rb
+++ b/test/exec/test_exec.rb
@@ -75,6 +75,45 @@ end
     end
   end
 
+  def test_working_directory
+    other = Tempfile.new('unicorn.wd')
+    File.unlink(other.path)
+    Dir.mkdir(other.path)
+    File.open("config.ru", "wb") do |fp|
+      fp.syswrite <<EOF
+use Rack::ContentLength
+run proc { |env| [ 200, { 'Content-Type' => 'text/plain' }, [ Dir.pwd ] ] }
+EOF
+    end
+    FileUtils.cp("config.ru", other.path + "/config.ru")
+    tmp = Tempfile.new('unicorn.config')
+    tmp.syswrite <<EOF
+working_directory '#@tmpdir'
+listen '#@addr:#@port'
+EOF
+    pid = xfork { redirect_test_io { exec($unicorn_bin, "-c#{tmp.path}") } }
+    wait_workers_ready("test_stderr.#{pid}.log", 1)
+    results = hit(["http://#@addr:#@port/"])
+    assert_equal @tmpdir, results.first
+    File.truncate("test_stderr.#{pid}.log", 0)
+
+    tmp.sysseek(0)
+    tmp.truncate(0)
+    tmp.syswrite <<EOF
+working_directory '#{other.path}'
+listen '#@addr:#@port'
+EOF
+
+    Process.kill(:HUP, pid)
+    wait_workers_ready("test_stderr.#{pid}.log", 1)
+    results = hit(["http://#@addr:#@port/"])
+    assert_equal other.path, results.first
+
+    Process.kill(:QUIT, pid)
+    ensure
+      FileUtils.rmtree(other.path)
+  end
+
   def test_exit_signals
     %w(INT TERM QUIT).each do |sig|
       File.open("config.ru", "wb") { |fp| fp.syswrite(HI) }