Skip to content

Commit

Permalink
add startsites command. Changed deploy_webservers to deploy_webconf a…
Browse files Browse the repository at this point in the history
…nd webservices to webservers. Added a reload_webservers function. Fixed some issues relating to using the wrong settings file in production
  • Loading branch information
bretth committed Aug 16, 2010
1 parent b54fba1 commit f31acf2
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 31 deletions.
6 changes: 4 additions & 2 deletions woven/api.py
Expand Up @@ -18,14 +18,14 @@
from woven.virtualenv import activate, active_version
from woven.virtualenv import mkvirtualenv, rmvirtualenv, pip_install_requirements

from woven.webservers import deploy_wsgi, deploy_webservers, start_webservices, stop_webservices
from woven.webservers import deploy_wsgi, deploy_webconf, start_webservers, stop_webservers, reload_webservers


def deploy():
"""
deploy a versioned project on the host
"""
deploy_funcs = [deploy_project,deploy_templates, deploy_static, deploy_public, deploy_webservers, deploy_wsgi]
deploy_funcs = [deploy_project,deploy_templates, deploy_static, deploy_public, deploy_webconf, deploy_wsgi]
if not patch_project():
deploy_funcs = [deploy_db,mkvirtualenv,pip_install_requirements] + deploy_funcs
for func in deploy_funcs: func()
Expand Down Expand Up @@ -56,6 +56,8 @@ def setupnode(rollback=False, overwrite=False):
install_packages(overwrite=overwrite)
upload_etc()
set_timezone()
stop_webservers()
start_webservers()


else:
Expand Down
4 changes: 2 additions & 2 deletions woven/management/base.py
Expand Up @@ -90,8 +90,8 @@ def handle(self, *args, **options):
all_role_hosts+=role_host
state.env['roles'] = state.env['roles'] + [r]
if all_role_hosts: comma_hosts = ','.join(all_role_hosts)
state.env.hosts = comma_hosts

if comma_hosts:
state.env.hosts = comma_hosts
if 'hosts' in state.env and isinstance(state.env['hosts'], str):
state.env['hosts'] = state.env['hosts'].split(',')
elif hasattr(settings,'HOSTS') and settings.HOSTS:
Expand Down
8 changes: 3 additions & 5 deletions woven/management/commands/patch.py
Expand Up @@ -5,12 +5,10 @@

from woven.api import deploy, activate
from woven.api import deploy_project, deploy_templates, deploy_static, deploy_public
from woven.api import deploy_wsgi, deploy_webservers
from woven.api import deploy_wsgi, deploy_webconf

from woven.management.base import WovenCommand



class Command(WovenCommand):
"""
Patch the current version of your project on hosts and restart webservices
Expand All @@ -29,7 +27,7 @@ class Command(WovenCommand):
"""

help = "Patch all parts of the current version of your project, or patch part of the project"
args = "[project|templates|static|public|wsgi|webservers] [user@hoststring ...]"
args = "[project|templates|static|public|wsgi|webconf] [user@hoststring ...]"
requires_model_validation = False

def parse_host_args(self, *args):
Expand All @@ -40,7 +38,7 @@ def parse_host_args(self, *args):
new_args = args
try:
sub = args[0]
if sub in ['project','templates','static','public','wsgi','webservers']:
if sub in ['project','templates','static','public','wsgi','webconf']:
self.subcommand = args[0]
new_args = args[1:]
except IndexError:
Expand Down
63 changes: 63 additions & 0 deletions woven/management/commands/startsites.py
@@ -0,0 +1,63 @@
#!/usr/bin/env python
from optparse import make_option
import os

from fabric import state
from fabric.decorators import runs_once
from fabric.context_managers import settings
from fabric.operations import sudo
from fabric.contrib.files import exists

from woven.management.base import WovenCommand
from woven.webservers import _get_django_sites, deploy_wsgi, deploy_webconf, domain_sites, reload_webservers
from woven.project import deploy_sitesettings

class Command(WovenCommand):
"""
Create sitesetting files for new django.contrib.sites.
In django site creation is through the production database. The startsite command
creates the sitesetting files for each of the new sites, and deploys them.
Basic Usage:
``python manage.py startsite [hoststring|role]``
"""
help = "Create a sitesetting file for new django sites"
requires_model_validation = False

def handle_host(self,*args, **options):
if not hasattr(state.env,'sites_created'):
local_settings_dir = os.path.join(os.getcwd(),state.env.project_name,'sitesettings')
sites = _get_django_sites()
site_ids = sites.keys()
site_ids.sort()
for id in site_ids:
sitesetting_path = os.path.join(state.env.project_name,'sitesettings',''.join([sites[id].replace('.','_'),'.py']))
if not os.path.exists(sitesetting_path):
f = open(sitesetting_path, "w+")
f.write("from %s.sitesettings.settings import *"% state.env.project_name)
f.write("\nSITE_ID=%s\n"% str(id))
f.close()
state.env.sites_created = True
created = deploy_sitesettings()
with settings(patch=True):
deploy_wsgi()
deploy_webconf()

#activate sites
activate_sites = [''.join([d.replace('.','_'),'-',state.env.project_version,'.conf']) for d in domain_sites()]
site_paths = ['/etc/apache2','/etc/nginx']

#activate new sites
for path in site_paths:
for site in activate_sites:
if not exists('/'.join([path,'sites-enabled',site])):
sudo("chmod 644 %s" % '/'.join([path,'sites-available',site]))
sudo("ln -s %s/sites-available/%s %s/sites-enabled/%s"% (path,site,path,site))
if state.env.verbosity:
print " * enabled", "%s/sites-enabled/%s"% (path,site)
reload_webservers()



15 changes: 15 additions & 0 deletions woven/project.py
Expand Up @@ -84,6 +84,21 @@ def deploy_project():

return created

def deploy_sitesettings():
"""
Deploy to the project directory in the virtualenv
"""

sitesettings = '/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_name,'sitesettings'])
local_dir = os.path.join(os.getcwd(),env.project_name,'sitesettings')

created = deploy_files(local_dir, sitesettings)
if env.verbosity and created:
print env.host,"DEPLOYING sitesettings"
for path in created:
tail = path.split('/')[-1]
print ' * uploaded',tail

@run_once_per_host_version
def deploy_templates():
"""
Expand Down
4 changes: 2 additions & 2 deletions woven/templates/woven/nginx-template.txt
Expand Up @@ -21,14 +21,14 @@ server {
{% if media_url %}
location {{ media_url }} {
root {{ deployment_root }}/public/;
#expires 1d;

}
{% endif %}

{% if static_url %}
location {{ static_url }} {
root {{ deployment_root }}/env/{{ project_name }}/static/;
#expires 1d;

}
{% endif %}

Expand Down
10 changes: 5 additions & 5 deletions woven/virtualenv.py
Expand Up @@ -15,7 +15,7 @@

from woven.deployment import mkdirs, run_once_per_host_version, deploy_files
from woven.environment import deployment_root,set_server_state, server_state, State
from woven.webservers import _ls_sites, stop_webservices, start_webservices, domain_sites
from woven.webservers import _ls_sites, stop_webservers, start_webservers, domain_sites
from fabric.contrib.files import append

def active_version():
Expand Down Expand Up @@ -48,7 +48,7 @@ def activate():
active = active_version()

if env.patch or active <> env.project_fullname:
stop_webservices()
stop_webservers()

if not env.patch and active <> env.project_fullname:

Expand Down Expand Up @@ -96,7 +96,7 @@ def activate():
print env.project_fullname,"is the active version"

if env.patch or active <> env.project_fullname:
start_webservices()
start_webservers()
print
return

Expand All @@ -105,7 +105,7 @@ def sync_db():
"""
Runs the django syncdb command
"""
with cd('/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_name])):
with cd('/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_name,'sitesettings'])):
venv = '/'.join([deployment_root(),'env',env.project_fullname,'bin','activate'])
if env.verbosity:
print " * python manage.py syncdb --noinput"
Expand Down Expand Up @@ -139,7 +139,7 @@ def migration():
"""

#activate env
with cd('/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_name])):
with cd('/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_name,'sitesettings'])):
#migrates all or specific env.migration
venv = '/'.join([deployment_root(),'env',env.project_fullname,'bin','activate'])
cmdpt1 = ' '.join(['source',venv,'&&'])
Expand Down
59 changes: 44 additions & 15 deletions woven/webservers.py
Expand Up @@ -25,16 +25,17 @@ def _activate_sites(path, filenames):
if not exists('/etc/apache2/sites-enabled'+ filename):
sudo("ln -s %s%s %s%s"% (self.deploy_root,filename,self.enabled_path,filename))

def _deploy_webserver(remote_dir,template):
def _deploy_webconf(remote_dir,template):

if not 'http:' in env.MEDIA_URL: media_url = env.MEDIA_URL
else: media_url = ''
if not 'http:' in env.STATIC_URL: static_url = env.STATIC_URL
else: static_url = ''
else: static_url = ''
if not static_url: static_url = env.ADMIN_MEDIA_PREFIX
log_dir = '/'.join([deployment_root(),'log'])
deployed = []

for d in domain_sites():
domains = domain_sites()
for d in domains:

u_domain = d.replace('.','_')

Expand Down Expand Up @@ -74,15 +75,14 @@ def _ls_sites(path):
dom_sites.append(s)
return dom_sites

@runs_once
def _get_django_sites():
"""
Get a list of sites as dictionaries {site_id:'domain.name'}
"""
deployed = server_state('deploy_project')
if not env.sites and 'django.contrib.sites' in env.INSTALLED_APPS and deployed:
with cd('/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_name])):
with cd('/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_name,'sitesettings'])):
venv = '/'.join([deployment_root(),'env',env.project_fullname,'bin','activate'])
output = run(' '.join(['source',venv,'&&',"./manage.py dumpdata sites"]))
sites = json.loads(output)
Expand Down Expand Up @@ -111,19 +111,19 @@ def domain_sites():
return env.domains

@run_once_per_host_version
def deploy_webservers():
def deploy_webconf():
""" Deploy apache & nginx site configurations to the host """
deployed = []
log_dir = '/'.join([deployment_root(),'log'])
#TODO - incorrect - check for actual package to confirm installation
if exists('/etc/apache2/sites-enabled/') and exists('/etc/nginx/sites-enabled'):
if env.verbosity:
print env.host,"DEPLOYING webservers:"
print env.host,"DEPLOYING webconf:"
if not exists(log_dir):
run('ln -s /var/log log')

deployed += _deploy_webserver('/etc/apache2/sites-available','django-apache-template.txt')
deployed += _deploy_webserver('/etc/nginx/sites-available','nginx-template.txt')
deployed += _deploy_webconf('/etc/apache2/sites-available','django-apache-template.txt')
deployed += _deploy_webconf('/etc/nginx/sites-available','nginx-template.txt')
upload_template('woven/maintenance.html','/var/www/nginx-default/maintenance.html',use_sudo=True)
sudo('chmod ugo+r /var/www/nginx-default/maintenance.html')
else:
Expand All @@ -140,7 +140,8 @@ def deploy_wsgi():
deployed = []
if env.verbosity:
print env.host,"DEPLOYING wsgi", remote_dir
for domain in domain_sites():
domains = domain_sites()
for domain in domains:
deployed += mkdirs(remote_dir)
with cd(remote_dir):
u_domain = domain.replace('.','_')
Expand All @@ -163,7 +164,34 @@ def deploy_wsgi():
run("chmod ug+xr %s"% filename)
return deployed

def stop_webservices():
def reload_webservers():
"""
Reload apache2 and nginx
"""
if env.verbosity:
print env.host, "RELOADING apache2"
with settings(warn_only=True):
a = sudo("/etc/init.d/apache2 reload")
if env.verbosity:
print '',a
if env.verbosity:

#Reload used to fail on Ubuntu but at least in 10.04 it works
print env.host,"RELOADING nginx"
with settings(warn_only=True):
s = run("/etc/init.d/nginx status")
if 'running' in s:
n = sudo("/etc/init.d/nginx reload")
else:
n = sudo("/etc/init.d/nginx start")
if env.verbosity:
print ' *',n
return True

def stop_webservers():
"""
Stop apache2
"""
#TODO - distinguish between a warning and a error on apache
with settings(warn_only=True):
if env.verbosity:
Expand All @@ -174,7 +202,10 @@ def stop_webservices():

return True

def start_webservices():
def start_webservers():
"""
Start apache2 and start/reload nginx
"""
with settings(warn_only=True):
if env.verbosity:
print env.host,"STARTING apache2"
Expand All @@ -188,8 +219,6 @@ def start_webservices():
sys.exit(1)
if env.verbosity:
#Reload used to fail on Ubuntu but at least in 10.04 it works

#TODO - Check that it is already running
print env.host,"RELOADING nginx"
with settings(warn_only=True):
s = run("/etc/init.d/nginx status")
Expand Down

0 comments on commit f31acf2

Please sign in to comment.