about summary refs log tree commit homepage
path: root/lib/unicorn/configurator.rb
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2017-02-21 16:33:09 -0800
committerEric Wong <e@80x24.org>2017-02-23 20:23:44 +0000
commitd322345251e15125df896bb8f0a5b53b49a1bf3f (patch)
treebe7fce006c6170539f12c7c1b6095edb351f6f5b /lib/unicorn/configurator.rb
parentd4e0ced16710e456cd192784ab106091568ebde3 (diff)
downloadunicorn-d322345251e15125df896bb8f0a5b53b49a1bf3f.tar.gz
This adds a hook that is called after the application has
been loaded by the worker process, directly before it starts
accepting requests.  This hook is necessary if your application
needs to gain access to resources during initialization,
and then drop privileges before serving requests.

This is especially useful in conjunction with chroot support
so the app can load all the normal ruby libraries it needs
to function, and then chroot before accepting requests.

If you are preloading the app, it's possible to drop privileges
or chroot in after_fork, but if you are not preloading the app,
the only way to currently do this is to override the private
HttpServer#init_worker_process method, and overriding private
methods is a recipe for future breakage if the internals are
modified.  This hook allows for such functionality to be
supported and not break in future versions of Unicorn.
Diffstat (limited to 'lib/unicorn/configurator.rb')
-rw-r--r--lib/unicorn/configurator.rb22
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 1e2b6e4..7ed5ffa 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -49,6 +49,9 @@ class Unicorn::Configurator
           server.logger.error(m)
         end
       },
+    :after_worker_ready => lambda { |server, worker|
+        server.logger.info("worker=#{worker.nr} ready")
+      },
     :pid => nil,
     :preload_app => false,
     :check_client_connection => false,
@@ -172,6 +175,21 @@ class Unicorn::Configurator
     set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
   end
 
+  # sets after_worker_ready hook to a given block.  This block will be called
+  # by a worker process after it has been fully loaded, directly before it
+  # starts responding to requests:
+  #
+  #  after_worker_ready do |server,worker|
+  #    server.logger.info("worker #{worker.nr} ready, dropping privileges")
+  #    worker.user('username', 'groupname')
+  #  end
+  #
+  # Do not use Configurator#user if you rely on changing users in the
+  # after_worker_ready hook.
+  def after_worker_ready(*args, &block)
+    set_hook(:after_worker_ready, block_given? ? block : args[0])
+  end
+
   # sets before_fork got be a given Proc object.  This Proc
   # object will be called by the master process before forking
   # each worker.
@@ -569,6 +587,10 @@ class Unicorn::Configurator
   # This switch will occur after calling the after_fork hook, and only
   # if the Worker#user method is not called in the after_fork hook
   # +group+ is optional and will not change if unspecified.
+  #
+  # Do not use Configurator#user if you rely on changing users in the
+  # after_worker_ready hook.  Instead, you need to call Worker#user
+  # directly in after_worker_ready.
   def user(user, group = nil)
     # raises ArgumentError on invalid user/group
     Etc.getpwnam(user)