Permalink
Browse files

Import gunicorn version 1.0.0

  • Loading branch information...
1 parent 7575f6c commit ed86b74bf282ee88dbef36a5a2f79b01bddbaf1d @schisamo schisamo committed May 3, 2011
@@ -0,0 +1,101 @@
+Description
+===========
+
+Installs and configures the latest version of Gunicorn (via pip), aka `Green Unicorn`, a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model ported from Ruby's Unicorn project. Includes an LWRP for managing Gunicorn config files. By default Gunicorn is installed system-wide but you can target a particular `virtualenv` by overriding the `node["gunicorn"]["virtualenv"]` attribute.
+
+Requirements
+============
+
+Platform
+--------
+
+* Debian, Ubuntu
+* CentOS, Red Hat, Fedora
+
+Cookbooks
+---------
+
+* python
+
+Attributes
+==========
+
+* `node["gunicorn"]["virtualenv"]` - the virtualenv you want to target Gunicorn installation into. The virtualenv will be created if it doesn't exist.
+
+Resource/Provider
+=================
+
+This cookbook includes LWRPs for managing gunicorn config files.
+
+`gunicorn_config`
+-----------------
+
+Creates a Gunicorn configuration file at the path specified. Meant to be deployed with a service init scheme/supervisor such as runit. Please see the `appliation::gunicorn` recipe for a complete working example. In depth information about Gunicorn's configuration values can be [found in the Gunicorn documentation](http://gunicorn.org/configure.html).
+
+# Actions
+
+- :create: create a Gunicorn configuration file.
+- :delete: delete an existing Gunicorn configuration file.
+
+# Attribute Parameters
+
+- path: name attribute. The path where the configuration file will be created
+- template: template to use when rendering the configuration file. default is `gunicorn.py.erb` (part of this cookbook)
+- cookbook: cookbook to look for template file in. default is this cookbook `gunicorn`
+- listen: the socket to bind to. A string of the form: 'HOST', 'HOST:PORT', 'unix:PATH'. default is `0.0.0.0:8000` or listen on port 8000 on all interfaces
+- backlog: The maximum number of pending connections. default is `2048`
+- preload_app: Whether application code should be loaded before the worker processes are forked. default is `false`
+- worker_processes: The number of worker process for handling requests. default is `4`
+- worker_class: The type of workers to use. default is `sync`
+- worker_timeout: The number of seconds to wait before a worker is killed and restarted. default is `60`
+- worker_keepalive: The number of seconds to wait for requests on a Keep-Alive connection. default is `2`
+- worker_max_requests: The maximum number of requests a worker will process before restarting. default is `0` or restarts disabled
+- server_hooks: A hash with whose values will be rendered as a [Gunicorn server hook](http://gunicorn.org/configure.html#server-hooks) callables (functions) named after the hash item's key name. default is `{}` or no serves hooks
+- owner: The owner for the configuration file.
+- group: The group owner of the configuration file (string or id).
+- pid: A filename to use for the PID file. default is no pidfile
+
+# Example
+
+ # create a config with the default values
+ gunicorn_config "/etc/gunicorn/myapp.py" do
+ action :create
+ end
+
+ # tweak some worker related values...we're web scale baby
+ gunicorn_config "/etc/gunicorn/myapp.py" do
+ worker_processes 8
+ backlog 4096
+ action :create
+ end
+
+ # use the 'pre_fork' server hook to
+ # sleep for a second before forking
+ gunicorn_config "/etc/gunicorn/myapp.py" do
+ server_hooks({:pre_fork => 'import time;time.sleep(1)'})
+ action :create
+ end
+
+Usage
+=====
+
+Simply include the recipe where you want Gunicorn installed.
+
+License and Author
+==================
+
+Author:: Seth Chisamore (<schisamo@opscode.com>)
+
+Copyright:: 2011, Opscode, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
@@ -0,0 +1,21 @@
+#
+# Author:: Seth Chisamore (<schisamo@opscode.com>)
+# Cookbook Name:: gunicorn
+# Attribute:: default
+#
+# Copyright 2011, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+default["gunicorn"]["virtualenv"] = nil
@@ -0,0 +1,32 @@
+{
+ "name": "gunicorn",
+ "description": "Installs/Configures Gunicorn",
+ "long_description": "Description\n===========\n\nInstalls and configures the latest version of Gunicorn (via pip), aka `Green Unicorn`, a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model ported from Ruby's Unicorn project. Includes an LWRP for managing Gunicorn config files. By default Gunicorn is installed system-wide but you can target a particular `virtualenv` by overriding the `node[\"gunicorn\"][\"virtualenv\"]` attribute.\n\nRequirements\n============\n\nPlatform\n--------\n\n* Debian, Ubuntu\n* CentOS, Red Hat, Fedora\n\nCookbooks\n---------\n\n* python\n\nAttributes\n==========\n\n* `node[\"gunicorn\"][\"virtualenv\"]` - the virtualenv you want to target Gunicorn installation into. The virtualenv will be created if it doesn't exist.\n\nResource/Provider\n=================\n\nThis cookbook includes LWRPs for managing gunicorn config files.\n\n`gunicorn_config`\n-----------------\n\nCreates a Gunicorn configuration file at the path specified. Meant to be deployed with a service init scheme/supervisor such as runit. Please see the `appliation::gunicorn` recipe for a complete working example. In depth information about Gunicorn's configuration values can be [found in the Gunicorn documentation](http://gunicorn.org/configure.html).\n\n# Actions\n\n- :create: create a Gunicorn configuration file.\n- :delete: delete an existing Gunicorn configuration file.\n\n# Attribute Parameters\n\n- path: name attribute. The path where the configuration file will be created\n- template: template to use when rendering the configuration file. default is `gunicorn.py.erb` (part of this cookbook)\n- cookbook: cookbook to look for template file in. default is this cookbook `gunicorn`\n- listen: the socket to bind to. A string of the form: 'HOST', 'HOST:PORT', 'unix:PATH'. default is `0.0.0.0:8000` or listen on port 8000 on all interfaces\n- backlog: The maximum number of pending connections. default is `2048`\n- preload_app: Whether application code should be loaded before the worker processes are forked. default is `false`\n- worker_processes: The number of worker process for handling requests. default is `4`\n- worker_class: The type of workers to use. default is `sync`\n- worker_timeout: The number of seconds to wait before a worker is killed and restarted. default is `60`\n- worker_keepalive: The number of seconds to wait for requests on a Keep-Alive connection. default is `2`\n- worker_max_requests: The maximum number of requests a worker will process before restarting. default is `0` or restarts disabled\n- server_hooks: A hash with whose values will be rendered as a [Gunicorn server hook](http://gunicorn.org/configure.html#server-hooks) callables (functions) named after the hash item's key name. default is `{}` or no serves hooks\n- owner: The owner for the configuration file.\n- group: The group owner of the configuration file (string or id).\n- pid: A filename to use for the PID file. default is no pidfile\n\n# Example\n \n # create a config with the default values\n gunicorn_config \"/etc/gunicorn/myapp.py\" do\n action :create\n end\n \n # tweak some worker related values...we're web scale baby\n gunicorn_config \"/etc/gunicorn/myapp.py\" do\n worker_processes 8\n backlog 4096\n action :create\n end\n \n # use the 'pre_fork' server hook to \n # sleep for a second before forking\n gunicorn_config \"/etc/gunicorn/myapp.py\" do\n server_hooks({:pre_fork => 'import time;time.sleep(1)'})\n action :create\n end\n \nUsage\n=====\n\nSimply include the recipe where you want Gunicorn installed.\n\nLicense and Author\n==================\n\nAuthor:: Seth Chisamore (<schisamo@opscode.com>)\n\nCopyright:: 2011, Opscode, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
+ "maintainer": "Opscode, Inc.",
+ "maintainer_email": "cookbooks@opscode.com",
+ "license": "Apache 2.0",
+ "platforms": {
+ },
+ "dependencies": {
+ "python": [
+
+ ]
+ },
+ "recommendations": {
+ },
+ "suggestions": {
+ },
+ "conflicting": {
+ },
+ "providing": {
+ },
+ "replacing": {
+ },
+ "attributes": {
+ },
+ "groupings": {
+ },
+ "recipes": {
+ },
+ "version": "1.0.0"
+}
@@ -0,0 +1,8 @@
+maintainer "Opscode, Inc."
+maintainer_email "cookbooks@opscode.com"
+license "Apache 2.0"
+description "Installs/Configures Gunicorn"
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
+version "1.0.0"
+
+depends "python"
@@ -0,0 +1,72 @@
+#
+# Author:: Seth Chisamore (<schisamo@opscode.com>)
+# Cookbook Name:: gunicorn
+# Provider:: config
+#
+# Copyright:: 2011, Opscode, Inc <legal@opscode.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+action :create do
+
+ Chef::Log.info("Creating #{@new_resource} at #{@new_resource.path}") unless exists?
+
+ template_variables = {}
+ %w{listen backlog preload_app worker_processes worker_class worker_timeout worker_keepalive worker_max_requests server_hooks pid}.each do |a|
+ template_variables[a.to_sym] = new_resource.send(a)
+ end
+
+ Chef::Log.debug("Using variables #{template_variables} to configure #{@new_resource}")
+
+ config_dir = ::File.dirname(new_resource.path)
+
+ d = directory config_dir do
+ recursive true
+ action :create
+ end
+
+ t = template new_resource.path do
+ source new_resource.template
+ cookbook new_resource.cookbook
+ mode "0644"
+ owner new_resource.owner if new_resource.owner
+ group new_resource.group if new_resource.group
+ variables template_variables
+ end
+
+ new_resource.updated_by_last_action(d.updated_by_last_action? || t.updated_by_last_action?)
+end
+
+action :delete do
+ if exists?
+ if ::File.writable?(@new_resource.path)
+ Chef::Log.info("Deleting #{@new_resource} at #{@new_resource.path}")
+ ::File.delete(@new_resource.path)
+ new_resource.updated_by_last_action(true)
+ else
+ raise "Cannot delete #{@new_resource} at #{@new_resource.path}!"
+ end
+ end
+end
+
+def load_current_resource
+ @current_resource = Chef::Resource::GunicornConfig.new(@new_resource.name)
+ @current_resource.path(@new_resource.path)
+ @current_resource
+end
+
+private
+ def exists?
+ ::File.exist?(@current_resource.path)
+ end
@@ -0,0 +1,32 @@
+#
+# Author:: Seth Chisamore (<schisamo@opscode.com>)
+# Cookbook Name:: gunicorn
+# Recipe:: default
+#
+# Copyright 2011, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include_recipe 'python'
+
+unless node["gunicorn"]["virtualenv"].nil?
+ python_virtualenv node["gunicorn"]["virtualenv"] do
+ action :create
+ end
+end
+
+python_pip "gunicorn" do
+ virtualenv node["gunicorn"]["virtualenv"] unless node["gunicorn"]["virtualenv"].nil?
+ action :install
+end
@@ -0,0 +1,51 @@
+#
+# Author:: Seth Chisamore (<schisamo@opscode.com>)
+# Cookbook Name:: gunicorn
+# Resource:: config
+#
+# Copyright:: 2011, Opscode, Inc <legal@opscode.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+actions :create, :delete
+
+attribute :path, :kind_of => String, :name_attribute => true
+attribute :template, :kind_of => String, :default => 'gunicorn.py.erb'
+attribute :cookbook, :kind_of => String, :default => 'gunicorn'
+
+attribute :listen, :kind_of => String, :default => '0.0.0.0:8000'
+attribute :backlog, :kind_of => Integer, :default => 2048
+attribute :preload_app, :kind_of => [TrueClass, FalseClass], :default => false
+
+attribute :worker_processes, :kind_of => Integer, :default => 4
+attribute :worker_class, :kind_of => String, :default => 'sync'
+attribute :worker_timeout, :kind_of => Integer, :default => 60
+attribute :worker_keepalive, :kind_of => Integer, :default => 2
+attribute :worker_max_requests, :kind_of => Integer, :default => 0
+
+attribute :server_hooks, :kind_of => Hash, :default => {}, \
+ :callbacks => {
+ "should contain a valid gunicorn server hook name" => lambda { |hooks| Chef::Resource::GunicornConfig.validate_server_hook_hash_keys(hooks)}
+ }
+
+attribute :owner, :regex => Chef::Config[:user_valid_regex]
+attribute :group, :regex => Chef::Config[:group_valid_regex]
+attribute :pid, :kind_of => String
+
+VALID_SERVER_HOOK_NAMES = [:when_ready, :pre_fork, :post_fork, :pre_exec, :pre_request, :post_request, :worker_exit]
+
+private
+ def self.validate_server_hook_hash_keys(server_hooks)
+ server_hooks.keys.reject{|key| VALID_SERVER_HOOK_NAMES.include?(key.to_sym)}.empty?
+ end
Oops, something went wrong.

0 comments on commit ed86b74

Please sign in to comment.