# HG changeset patch
# User rod m <[email protected]>
# Date 1380256655 25200
# Thu Sep 26 21:37:35 2013 -0700
# Node ID 86fdecf116fb2c076533d096df9196e68d9bec67
# Parent ff2ab2706f4c17b87ee29f9db5cfcb7132e319d8
Customize fabfile, add uwsgi support:
+allowed for wsgi listen on nonlocal address
+allowed for override of # wsgi worker processes
+broke out createdb and dropdb into fabric tasks
+added IF EXISTS to dropdb calls
diff -r ff2ab2706f4c -r 86fdecf116fb .hgignore
--- a/.hgignore Thu Sep 26 21:36:35 2013 -0700
+++ b/.hgignore Thu Sep 26 21:37:35 2013 -0700
@@ -5,6 +5,10 @@
.DS_Store
.coverage
local_settings.py
+fabric_settings.py
+*.wpr
+*.wpu
+*~
syntax: regexp
^static/
diff -r ff2ab2706f4c -r 86fdecf116fb deploy/gunicorn.conf.py
--- a/deploy/gunicorn.conf.py Thu Sep 26 21:36:35 2013 -0700
+++ b/deploy/gunicorn.conf.py Thu Sep 26 21:37:35 2013 -0700
@@ -1,6 +1,4 @@
-import os
-
-bind = "127.0.0.1:%(gunicorn_port)s"
-workers = (os.sysconf("SC_NPROCESSORS_ONLN") * 2) + 1
+bind = "%(wsgi_listen)s"
+workers = %(wsgi_workers)s
loglevel = "error"
proc_name = "%(proj_name)s"
diff -r ff2ab2706f4c -r 86fdecf116fb deploy/live_settings.py
--- a/deploy/live_settings.py Thu Sep 26 21:36:35 2013 -0700
+++ b/deploy/live_settings.py Thu Sep 26 21:37:35 2013 -0700
@@ -1,3 +1,5 @@
+
+ALLOWED_HOSTS = ('%(live_host)s', )
SECRET_KEY = "%(secret_key)s"
NEVERCACHE_KEY = "%(nevercache_key)s"
diff -r ff2ab2706f4c -r 86fdecf116fb deploy/nginx.conf
--- a/deploy/nginx.conf Thu Sep 26 21:36:35 2013 -0700
+++ b/deploy/nginx.conf Thu Sep 26 21:37:35 2013 -0700
@@ -1,6 +1,6 @@
upstream %(proj_name)s {
- server 127.0.0.1:%(gunicorn_port)s;
+ server %(wsgi_listen)s;
}
server {
@@ -17,13 +17,18 @@
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
+ include includes/rodmtech_net-extra;
+
location / {
+ if (-f /usr/share/nginx/www/503/503s-enabled/rodmtech_net.html) {
+ return 503;
+ }
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Protocol $scheme;
- proxy_pass http://%(proj_name)s;
+ %(proxy_pass)s;
}
location /static/ {
@@ -44,4 +49,12 @@
log_not_found off;
}
+ # error 503 redirect
+ error_page 503 @maintenance;
+ location @maintenance {
+ root /usr/share/nginx/www;
+ rewrite ^(.*)$ /503/503s-enabled/rodmtech_net.html break;
+ }
+
+
}
diff -r ff2ab2706f4c -r 86fdecf116fb deploy/supervisor.conf
--- a/deploy/supervisor.conf Thu Sep 26 21:36:35 2013 -0700
+++ b/deploy/supervisor.conf Thu Sep 26 21:37:35 2013 -0700
@@ -1,8 +1,8 @@
[group:%(proj_name)s]
-programs=gunicorn_%(proj_name)s
+programs=%(wsgi_server)s_%(proj_name)s
-[program:gunicorn_%(proj_name)s]
-command=%(venv_path)s/bin/gunicorn_django -c gunicorn.conf.py -p
gunicorn.pid
+[program:%(wsgi_server)s_%(proj_name)s]
+command=%(wsgi_command)s
directory=%(proj_path)s
user=%(user)s
autostart=true
diff -r ff2ab2706f4c -r 86fdecf116fb deploy/uwsgi.ini
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/deploy/uwsgi.ini Thu Sep 26 21:37:35 2013 -0700
@@ -0,0 +1,12 @@
+[uwsgi]
+chdir = %(proj_path)s
+module = wsgi:application
+env = DJANGO_SETTINGS_MODULE=settings
+pythonpath = ..
+master = True
+pidfile = %(proj_path)s/uwsgi.pid
+socket = %(wsgi_listen)s
+protocol = uwsgi
+vacuum = True
+virtualenv = %(venv_path)s
+workers = %(wsgi_workers)s
diff -r ff2ab2706f4c -r 86fdecf116fb fabfile.py
--- a/fabfile.py Thu Sep 26 21:36:35 2013 -0700
+++ b/fabfile.py Thu Sep 26 21:37:35 2013 -0700
@@ -8,8 +8,10 @@
from posixpath import join
from fabric.api import env, cd, prefix, sudo as _sudo, run as _run, hide,
task
+from fabric.context_managers import settings
from fabric.contrib.files import exists, upload_template
from fabric.colors import yellow, green, blue, red
+from fabric.operations import prompt
################
@@ -30,6 +32,7 @@
print "Aborting, no hosts defined."
exit()
+prompt("Pointing at {}, confirm with 'xxx':".format(conf["TARGET"]),
validate=r"xxx")
env.db_pass = conf.get("DB_PASS", None)
env.admin_pass = conf.get("ADMIN_PASS", None)
env.user = conf.get("SSH_USER", getuser())
@@ -48,7 +51,18 @@
env.repo_url = conf.get("REPO_URL", "")
env.git = env.repo_url.startswith("git") or env.repo_url.endswith(".git")
env.reqs_path = conf.get("REQUIREMENTS_PATH", None)
-env.gunicorn_port = conf.get("GUNICORN_PORT", 8000)
+env.wsgi_server = conf.get("WSGI_SERVER", "gunicorn")
+env.wsgi_listen = conf.get("WSGI_LISTEN", 8000)
+env.wsgi_workers = lambda : conf.get("WSGI_WORKERS") or \
+ run("""python -c 'import os; print os.sysconf("SC_NPROCESSORS_ONLN")*2
+ 1'""")
+env.wsgi_conf, env.wsgi_command, env.proxy_pass = {
+ "gunicorn": ("gunicorn.conf.py",
+ "%(venv_path)s/bin/gunicorn_django -c gunicorn.conf.py -p
gunicorn.pid" % env,
+ "proxy_pass http://%(proj_name)s" % env),
+ "uwsgi": ("uwsgi.ini",
+ "%(venv_path)s/bin/uwsgi --ini uwsgi.ini" % env,
+ "uwsgi_pass %(proj_name)s; include uwsgi_params" % env)
+ }[env.wsgi_server]
env.locale = conf.get("LOCALE", "en_US.UTF-8")
env.secret_key = conf.get("SECRET_KEY", "")
@@ -80,9 +94,9 @@
"owner": "root",
"mode": "600",
},
- "gunicorn": {
- "local_path": "deploy/gunicorn.conf.py",
- "remote_path": "%(proj_path)s/gunicorn.conf.py",
+ env.wsgi_server: {
+ "local_path": "deploy/%(wsgi_conf)s",
+ "remote_path": "%(proj_path)s/%(wsgi_conf)s",
},
"settings": {
"local_path": "deploy/live_settings.py",
@@ -229,7 +243,8 @@
clean = lambda s: s.replace("\n", "").replace("\r", "").strip()
if clean(remote_data) == clean(local_data):
return
- upload_template(local_path, remote_path, env, use_sudo=True,
backup=False)
+ with settings(wsgi_workers=env.wsgi_workers()):
+ upload_template(local_path, remote_path, env, use_sudo=True,
backup=False)
if owner:
sudo("chown %s %s" % (owner, remote_path))
if mode:
@@ -261,7 +276,7 @@
Installs one or more Python packages within the virtual environment.
"""
with virtualenv():
- return sudo("pip install %s" % packages)
+ return run("pip install %s" % packages)
def postgres(command):
@@ -350,6 +365,30 @@
sudo("easy_install pip")
sudo("pip install virtualenv mercurial")
+@task
+@log_call
+def createdb():
+ """
+ Create DB and DB user.
+ """
+ pw = db_pass()
+ user_sql_args = (env.proj_name, pw.replace("'", "\'"))
+ user_sql = "CREATE USER %s WITH ENCRYPTED PASSWORD '%s';" %
user_sql_args
+ psql(user_sql, show=False)
+ shadowed = "*" * len(pw)
+ print_command(user_sql.replace("'%s'" % pw, "'%s'" % shadowed))
+ psql("CREATE DATABASE %s WITH OWNER %s ENCODING = 'UTF8' "
+ "LC_CTYPE = '%s' LC_COLLATE = '%s' TEMPLATE template0;" %
+ (env.proj_name, env.proj_name, env.locale, env.locale))
+
+@task
+@log_call
+def dropdb():
+ """
+ Drop DB and DB user.
+ """
+ psql("DROP DATABASE IF EXISTS %s;" % env.proj_name)
+ psql("DROP USER IF EXISTS %s;" % env.proj_name)
@task
@log_call
@@ -375,15 +414,7 @@
run("%s clone %s %s" % (vcs, env.repo_url, env.proj_path))
# Create DB and DB user.
- pw = db_pass()
- user_sql_args = (env.proj_name, pw.replace("'", "\'"))
- user_sql = "CREATE USER %s WITH ENCRYPTED PASSWORD '%s';" %
user_sql_args
- psql(user_sql, show=False)
- shadowed = "*" * len(pw)
- print_command(user_sql.replace("'%s'" % pw, "'%s'" % shadowed))
- psql("CREATE DATABASE %s WITH OWNER %s ENCODING = 'UTF8' "
- "LC_CTYPE = '%s' LC_COLLATE = '%s' TEMPLATE template0;" %
- (env.proj_name, env.proj_name, env.locale, env.locale))
+ createdb()
# Set up SSL certificate.
conf_path = "/etc/nginx/conf"
@@ -409,8 +440,8 @@
with project():
if env.reqs_path:
pip("-r %s/%s" % (env.proj_path, env.reqs_path))
- pip("gunicorn setproctitle south psycopg2 "
- "django-compressor python-memcached")
+ pip("%(wsgi_server)s setproctitle south psycopg2 "
+ "django-compressor python-memcached" % env)
manage("createdb --noinput --nodata")
python("from django.conf import settings;"
"from django.contrib.sites.models import Site;"
@@ -439,13 +470,12 @@
Blow away the current project.
"""
if exists(env.venv_path):
- sudo("rm -rf %s" % env.venv_path)
+ run("rm -rf %s" % env.venv_path)
for template in get_templates().values():
remote_path = template["remote_path"]
if exists(remote_path):
sudo("rm %s" % remote_path)
- psql("DROP DATABASE %s;" % env.proj_name)
- psql("DROP USER %s;" % env.proj_name)
+ dropdb()
##############
@@ -456,14 +486,14 @@
@log_call
def restart():
"""
- Restart gunicorn worker processes for the project.
+ Restart wsgi worker processes for the project.
"""
- pid_path = "%s/gunicorn.pid" % env.proj_path
+ pid_path = "%(proj_path)s/%(wsgi_server)s.pid" % env
if exists(pid_path):
sudo("kill -HUP `cat %s`" % pid_path)
else:
- start_args = (env.proj_name, env.proj_name)
- sudo("supervisorctl start %s:gunicorn_%s" % start_args)
+ start_args = (env.proj_name, env.wsgi_server, env.proj_name)
+ sudo("supervisorctl start %s:%s_%s" % start_args)
@task
@@ -473,7 +503,7 @@
Deploy latest version of the project.
Check out the latest version of the project from version
control, install new requirements, sync and migrate the database,
- collect any new static assets, and restart gunicorn's work
+ collect any new static assets, and restart wsgi server's work
processes for the project.
"""
if not exists(env.venv_path):
diff -r ff2ab2706f4c -r 86fdecf116fb settings.py
--- a/settings.py Thu Sep 26 21:36:35 2013 -0700
+++ b/settings.py Thu Sep 26 21:37:35 2013 -0700
@@ -323,6 +323,10 @@
# These settings are used by the default fabfile.py provided.
# Check fabfile.py for defaults.
+try:
+ from fabric_settings import *
+except ImportError:
+ pass
# FABRIC = {
# "SSH_USER": "", # SSH username
--
You received this message because you are subscribed to the Google Groups
"Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.