Пример #1
0
def deploy_wsgi():
    """
    deploy python wsgi file(s)
    """
    remote_dir = "/".join([deployment_root(), "env", env.project_fullname, "wsgi"])
    deployed = []
    if env.verbosity:
        print env.host, "DEPLOYING wsgi", remote_dir
    domains = domain_sites()
    for domain in domains:
        deployed += mkdirs(remote_dir)
        with cd(remote_dir):
            u_domain = domain.replace(".", "_")
            filename = "%s.wsgi" % u_domain
            context = {
                "deployment_root": deployment_root(),
                "user": env.user,
                "project_name": env.project_name,
                "u_domain": u_domain,
                "root_domain": env.root_domain,
            }
            upload_template("/".join(["woven", "django-wsgi-template.txt"]), filename, context)
            if env.verbosity:
                print " * uploaded", filename
            # finally set the ownership/permissions
            # We'll use the group to allow www-data execute
            sudo("chown %s:www-data %s" % (env.user, filename))
            run("chmod ug+xr %s" % filename)
    return deployed
Пример #2
0
def migration():
    """
    Integrate with south schema migration
    """

    #activate env        
    with cd('/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_package_name,'sitesettings'])):
        #migrates all or specific env.migration
        venv = '/'.join([deployment_root(),'env',env.project_fullname,'bin','activate'])
        cmdpt1 = ' '.join(['source',venv,'&&'])
        
        sites = _get_django_sites()
        site_ids = sites.keys()
        site_ids.sort()
        for site in site_ids:
            for settings_file in _sitesettings_files():
                site_settings = '.'.join([env.project_package_name,'sitesettings',settings_file.replace('.py','')])
                cmdpt2 = ' '.join(["python manage.py migrate",env.migration])
                if hasattr(env,"fakemigration"):
                    cmdpt2 = ' '.join([cmdpt2,'--fake'])
                cmdpt2 = ''.join([cmdpt2,'--settings=',site_settings])
                if env.verbosity:
                    print " *", cmdpt2
                output = sudo(' '.join([cmdpt1,cmdpt2]),user='******'% site)
            if env.verbosity:
                print output
    return           
Пример #3
0
def deploy_project():
    """
    Deploy to the project directory in the virtualenv
    """
    
    project_root = '/'.join([deployment_root(),'env',env.project_fullname,'project'])
    local_dir = os.getcwd()
    
    if env.verbosity:
        print env.host,"DEPLOYING project", env.project_fullname
    #Exclude a few things that we don't want deployed as part of the project folder
    rsync_exclude = ['local_settings*','*.pyc','*.log','.*','/build','/dist','/media*','/static*','/www','/public','/template*']

    #make site local settings if they don't already exist
    _make_local_sitesettings()
    created = deploy_files(local_dir, project_root, rsync_exclude=rsync_exclude)
    if not env.patch:
        #hook the project into sys.path
        pyvers = run('python -V').split(' ')[1].split('.')[0:2] #Python x.x.x
        sitepackages = ''.join(['lib/python',pyvers[0],'.',pyvers[1],'/site-packages'])
        link_name = '/'.join([deployment_root(),'env',env.project_fullname,sitepackages,env.project_package_name])
        target = '/'.join([project_root,env.project_package_name])
        run(' '.join(['ln -s',target,link_name]))
        
        #make sure manage.py has exec permissions
        managepy = '/'.join([target,'sitesettings','manage.py'])
        if exists(managepy):
            sudo('chmod ugo+x %s'% managepy)
    
    return created
Пример #4
0
def _get_django_sites():
    """
    Get a list of sites as dictionaries {site_id:'domain.name'}

    """
    deployed = version_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_package_name,'sitesettings'])):
            venv = '/'.join([deployment_root(),'env',env.project_fullname,'bin','activate'])
            #since this is the first time we run ./manage.py on the server it can be
            #a point of failure for installations
            with settings(warn_only=True):
                output = run(' '.join(['source',venv,'&&',"django-admin.py dumpdata sites --settings=%s.sitesettings.settings"% env.project_package_name]))

                if output.failed:
                    print "ERROR: There was an error running ./manage.py on the node"
                    print "See the troubleshooting docs for hints on how to diagnose deployment issues"
                    if hasattr(output, 'stderr'):
                        print output.stderr
                    sys.exit(1)
            output = output.split('\n')[-1] #ignore any lines prior to the data being dumped
            sites = json.loads(output)
            env.sites = {}
            for s in sites:
                env.sites[s['pk']] = s['fields']['domain']
    return env.sites
Пример #5
0
def _get_django_sites():
    """
    Get a list of sites as dictionaries {site_id:'domain.name'}

    """
    deployed = version_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_package_name,'sitesettings'])):
            venv = '/'.join([deployment_root(),'env',env.project_fullname,'bin','activate'])
            #since this is the first time we run ./manage.py on the server it can be
            #a point of failure for installations
            with settings(warn_only=True):
                output = run(' '.join(['source',venv,'&&',"./manage.py dumpdata sites"]))

                if output.failed:
                    print "ERROR: There was an error running ./manage.py on the node"
                    print "See the troubleshooting docs for hints on how to diagnose deployment issues"
                    if hasattr(output, 'stderr'):
                        print output.stderr
                    sys.exit(1)
            output = output.split('\n')[-1] #ignore any lines prior to the data being dumped
            sites = json.loads(output)
            env.sites = {}
            for s in sites:
                env.sites[s['pk']] = s['fields']['domain']
    return env.sites
Пример #6
0
def sync_db():
    """
    Runs the django syncdb command
    """
    with cd('/'.join([
            deployment_root(), 'env', env.project_fullname, 'project',
            env.project_package_name, 'sitesettings'
    ])):
        venv = '/'.join([
            deployment_root(), 'env', env.project_fullname, 'bin', 'activate'
        ])
        sites = _get_django_sites()
        site_ids = sites.keys()
        site_ids.sort()
        for site in site_ids:
            for settings_file in _sitesettings_files():
                site_settings = '.'.join([
                    env.project_package_name, 'sitesettings',
                    settings_file.replace('.py', '')
                ])
                if env.verbosity:
                    print " * django-admin.py syncdb --noinput --settings=%s" % site_settings
                output = sudo(' '.join([
                    'source', venv, '&&',
                    "django-admin.py syncdb --noinput --settings=%s" %
                    site_settings
                ]),
                              user='******' % site)
                if env.verbosity:
                    print output
Пример #7
0
def deploy_project():
    """
    Deploy to the project directory in the virtualenv
    """
    
    project_root = '/'.join([deployment_root(),'env',env.project_fullname,'project'])
    local_dir = os.getcwd()
    
    if env.verbosity:
        print env.host,"DEPLOYING project", env.project_fullname
    #Exclude a few things that we don't want deployed as part of the project folder
    rsync_exclude = ['local_settings*','*.pyc','*.log','.*','/build','/dist','/media*','/static*','/www','/public','/template*']

    #make site local settings if they don't already exist
    _make_local_sitesettings()
    created = deploy_files(local_dir, project_root, rsync_exclude=rsync_exclude)
    if not env.patch:
        #hook the project into sys.path
        remote_python_version = run('''python -c "import sys; print 'python%d.%d' % (sys.version_info.major, sys.version_info.minor)"''').strip()
        link_name = '/'.join([deployment_root(),'env',env.project_fullname,'lib', remote_python_version, 'site-packages',env.project_package_name])
        target = '/'.join([project_root,env.project_package_name])

        #create any missing dirs
        run('mkdir -p ' + os.path.dirname(link_name))
        run(' '.join(['ln -s',target,link_name]))
        
        #make sure manage.py has exec permissions
        managepy = '/'.join([target,'sitesettings','manage.py'])
        if exists(managepy):
            sudo('chmod ugo+x %s'% managepy)
    
    return created
Пример #8
0
def rmvirtualenv():
    """
    Remove the current or ``env.project_version`` environment and all content in it
    """
    path = '/'.join([deployment_root(), 'env', env.project_fullname])
    link = '/'.join([deployment_root(), 'env', env.project_name])
    if version_state('mkvirtualenv'):
        sudo(' '.join(['rm -rf', path]))
        sudo(' '.join(['rm -f', link]))
        sudo('rm -f /var/local/woven/%s*' % env.project_fullname)
        set_version_state('mkvirtualenv', delete=True)
Пример #9
0
def rmvirtualenv():
    """
    Remove the current or ``env.project_version`` environment and all content in it
    """
    path = '/'.join([deployment_root(),'env',env.project_fullname])
    if server_state('mkvirtualenv'):
        sudo(' '.join(['rm -rf',path]))
        set_server_state('mkvirtualenv',delete=True)
    #If there are no further remaining envs we'll delete the home directory to effectively teardown the project
    if not server_state('mkvirtualenv',prefix=True):
        sudo('rm -rf '+deployment_root())        
Пример #10
0
def rmvirtualenv():
    """
    Remove the current or ``env.project_version`` environment and all content in it
    """
    path = '/'.join([deployment_root(),'env',env.project_fullname])
    link = '/'.join([deployment_root(),'env',env.project_name])
    if version_state('mkvirtualenv'):
        sudo(' '.join(['rm -rf',path]))
        sudo(' '.join(['rm -f',link]))
        sudo('rm -f /var/local/woven/%s*'% env.project_fullname)
        set_version_state('mkvirtualenv',delete=True)
Пример #11
0
def sync_db():
    """
    Runs the django syncdb command
    """
    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"
        output = run(' '.join(['source',venv,'&&',"./manage.py syncdb --noinput"]))
        if env.verbosity:
            print output
Пример #12
0
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 = ''
    if not static_url: static_url = env.ADMIN_MEDIA_PREFIX
    log_dir = '/'.join([deployment_root(), 'log'])
    deployed = []
    users_added = []

    domains = domain_sites()
    for d in domains:
        u_domain = d.name.replace('.', '_')
        wsgi_filename = d.settings.replace('.py', '.wsgi')
        site_user = ''.join(['site_', str(d.site_id)])
        filename = ''.join(
            [remote_dir, '/', u_domain, '-', env.project_version, '.conf'])
        context = {
            "project_name": env.project_name,
            "deployment_root": deployment_root(),
            "u_domain": u_domain,
            "domain": d.name,
            "root_domain": env.root_domain,
            "user": env.user,
            "site_user": site_user,
            "SITE_ID": d.site_id,
            "host_ip": socket.gethostbyname(env.host),
            "wsgi_filename": wsgi_filename,
            "MEDIA_URL": media_url,
            "STATIC_URL": static_url,
        }

        upload_template('/'.join(['woven', template]),
                        filename,
                        context,
                        use_sudo=True)
        if env.verbosity:
            print " * uploaded", filename

        #add site users if necessary
        site_users = _site_users()
        if site_user not in users_added and site_user not in site_users:
            add_user(username=site_user, group='www-data', site_user=True)
            users_added.append(site_user)
            if env.verbosity:
                print " * useradded", site_user

    return deployed
Пример #13
0
def mkvirtualenv():
    """
    Create the virtualenv project environment
    """
    root = '/'.join([deployment_root(), 'env'])
    path = '/'.join([root, env.project_fullname])
    dirs_created = []
    if env.verbosity:
        print env.host, 'CREATING VIRTUALENV', path
    if not exists(root): dirs_created += mkdirs(root)
    with cd(root):
        run(' '.join(["virtualenv", env.project_fullname]))
    with cd(path):
        dirs_created += mkdirs('egg_cache')
        sudo('chown -R %s:www-data egg_cache' % env.user)
        sudo('chmod -R g+w egg_cache')
        run(''.join([
            "echo 'cd ", path, '/', 'project', '/', env.project_package_name,
            '/sitesettings', "' > bin/postactivate"
        ]))
        sudo('chmod ugo+rwx bin/postactivate')

    #Create a state
    out = State(' '.join([env.host, 'virtualenv', path, 'created']))
    out.object = dirs_created + ['bin', 'lib', 'include']
    out.failed = False
    return out
Пример #14
0
def deploy_webconf():
    """ Deploy nginx and other wsgi server site configurations to the host """
    deployed = []
    log_dir = '/'.join([deployment_root(), 'log'])
    #TODO - incorrect - check for actual package to confirm installation
    if webserver_list():
        if env.verbosity:
            print env.host, "DEPLOYING webconf:"
        if not exists(log_dir):
            run('ln -s /var/log log')
        #deploys confs for each domain based on sites app
        if 'apache2' in get_packages():
            deployed += _deploy_webconf('/etc/apache2/sites-available',
                                        'django-apache-template.txt')
            deployed += _deploy_webconf('/etc/nginx/sites-available',
                                        'nginx-template.txt')
        elif 'gunicorn' in get_packages():
            deployed += _deploy_webconf('/etc/nginx/sites-available',
                                        'nginx-gunicorn-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:
        print env.host, """WARNING: Apache or Nginx not installed"""

    return deployed
Пример #15
0
def _make_local_sitesettings(overwrite=False):
    local_settings_dir = os.path.join(os.getcwd(),env.project_package_name,'sitesettings')
    if not os.path.exists(local_settings_dir) or overwrite:
        if overwrite:
            shutil.rmtree(local_settings_dir,ignore_errors=True)
        os.mkdir(local_settings_dir)
        f = open(os.path.join(local_settings_dir,'__init__.py'),"w")
        f.close()

    settings_file_path = os.path.join(local_settings_dir,'settings.py')
    if not os.path.exists(settings_file_path):
        root_domain = _root_domain()    
        u_domain = root_domain.replace('.','_')
        output = render_to_string('woven/sitesettings.txt',
                {"deployment_root":deployment_root(),
                "site_id":"1",
                "project_name": env.project_name,
                "project_fullname": env.project_fullname,
                "project_package_name": env.project_package_name,
                "u_domain":u_domain,
                "domain":root_domain,
                "user":env,
                "MEDIA_URL":env.MEDIA_URL,
                "STATIC_URL":env.STATIC_URL}
            )
                    
        f = open(settings_file_path,"w+")
        f.writelines(output)
        f.close()
        #copy manage.py into that directory
        manage_path = os.path.join(os.getcwd(),env.project_package_name,'manage.py')
        dest_manage_path = os.path.join(os.getcwd(),env.project_package_name,'sitesettings','manage.py')
        shutil.copy(manage_path, dest_manage_path)

    return
Пример #16
0
def mkvirtualenv():
    """
    Create the virtualenv project environment
    """
    root = '/'.join([deployment_root(), 'env'])
    path = '/'.join([root, env.project_fullname])
    dirs_created = []
    if env.verbosity:
        print env.host, 'CREATING VIRTUALENV', path
    if not exists(root):
        dirs_created += mkdirs(root)
    with cd(root):
        run(' '.join(["virtualenv", env.project_fullname]))
    with cd(path):
        dirs_created += mkdirs('egg_cache')
        sudo('chown -R %s:www-data egg_cache' % env.user)
        sudo('chmod -R g+w egg_cache')
        run(''.join([
                "echo 'cd ",
                path,
                '/',
                'project',
                '/',
                env.project_package_name,
                '/sitesettings',
                "' > bin/postactivate"]))
        sudo('chmod ugo+rwx bin/postactivate')

    #Create a state
    out = State(' '.join([env.host, 'virtualenv', path, 'created']))
    out.object = dirs_created + ['bin', 'lib', 'include']
    out.failed = False
    return out
Пример #17
0
def deploy_templates():
    """ Deploy any templates from your shortest TEMPLATE_DIRS setting. """
    deployed = None
    if not hasattr(env, 'project_template_dir'):
        # The normal pattern would mean the shortest path is the main
        # one. It's probably the last listed.
        length = 1000
        for directory in env.TEMPLATE_DIRS:
            if directory:
                len_dir = len(directory)
                if len_dir < length:
                    length = len_dir
                    env.project_template_dir = directory

    if hasattr(env, 'project_template_dir'):
        remote_dir = '/'.join([
                deployment_root(),
                'env',
                env.project_fullname,
                'templates',
                ])
        if env.verbosity:
            print env.host, "DEPLOYING templates", remote_dir
        deployed = deploy_files(env.project_template_dir, remote_dir)
    return deployed
Пример #18
0
def deploy_static():
    """
    Deploy static (application) versioned media
    """
    if (not env.STATIC_ROOT and not env.ADMIN_MEDIA_PREFIX) or 'http://' in env.STATIC_URL: return
        
    remote_dir = '/'.join([deployment_root(),'env',env.project_fullname,'static'])
    
    #if app media is not handled by django-staticfiles we can install admin media by default
    if 'django.contrib.admin' in env.INSTALLED_APPS and not env.STATIC_ROOT:
        if env.MEDIA_URL in env.ADMIN_MEDIA_PREFIX:
            print "ERROR: Your ADMIN_MEDIA_PREFIX must not be on the same path as your MEDIA_URL"
            print "for example you cannot use MEDIA_URL = /media/ and ADMIN_MEDIA_PREFIX = /media/admin/"
            sys.exit(1)
        env.STATIC_URL = env.ADMIN_MEDIA_PREFIX    
        admin = AdminMediaHandler('DummyApp')
        local_dir = admin.media_dir
        remote_dir =  ''.join([remote_dir,env.ADMIN_MEDIA_PREFIX])
    else:
        if env.MEDIA_URL in env.STATIC_URL:
            print "ERROR: Your STATIC_URL must not be on the same path as your MEDIA_URL"
            print "for example you cannot use MEDIA_URL = /media/ and STATIC_URL = /media/static/"
            sys.exit(1)
        elif env.STATIC_ROOT:
            local_dir = env.STATIC_ROOT
            static_url = env.STATIC_URL[1:]
            if static_url:
                remote_dir = '/'.join([remote_dir,static_url])
        else: return
    if env.verbosity:
        print env.host,"DEPLOYING static",remote_dir
    return deploy_files(local_dir,remote_dir)
Пример #19
0
def deploy_db(rollback=False):
    """
    Deploy a sqlite database from development
    """
    db_name = ''.join([env.project_name,'.db'])
    db_dir = '/'.join([deployment_root(),'database'])
    db_path = '/'.join([db_dir,db_name])
    if not rollback:
        if env.DEFAULT_DATABASE_ENGINE=='django.db.backends.sqlite3' and not exists(db_path):
            if env.verbosity:
                print env.host,"DEPLOYING DEFAULT SQLITE DATABASE",db_path
            if not os.path.exists(env.DEFAULT_DATABASE_NAME) or not env.DEFAULT_DATABASE_NAME:
                print "ERROR: the database does not exist. Run python manage.py syncdb to create your database first."
                sys.exit(1)
            run('mkdir -p '+db_dir)
            put(env.DEFAULT_DATABASE_NAME,db_path)
            #directory and file must be writable by webserver
            sudo("chown -R %s:www-data %s"% (env.user,db_dir))
            sudo("chmod -R ug+w %s"% db_dir)
    elif rollback and env.DEFAULT_DATABASE_ENGINE=='django.db.backends.sqlite3':
        if env.INTERACTIVE:
            delete = confirm('DELETE the database on the host?',default=False)
            if delete:
                run('rm -f '+db_name)
    return
Пример #20
0
def deploy_static():
    """
    Deploy static (application) versioned media
    """

    if not env.STATIC_URL or 'http://' in env.STATIC_URL: return
    from django.core.servers.basehttp import AdminMediaHandler
    remote_dir = '/'.join(
        [deployment_root(), 'env', env.project_fullname, 'static'])
    m_prefix = len(env.MEDIA_URL)
    #if app media is not handled by django-staticfiles we can install admin media by default
    if 'django.contrib.admin' in env.INSTALLED_APPS and not 'django.contrib.staticfiles' in env.INSTALLED_APPS:

        if env.MEDIA_URL and env.MEDIA_URL == env.ADMIN_MEDIA_PREFIX[:m_prefix]:
            print "ERROR: Your ADMIN_MEDIA_PREFIX (Application media) must not be on the same path as your MEDIA_URL (User media)"
            sys.exit(1)
        admin = AdminMediaHandler('DummyApp')
        local_dir = admin.base_dir
        remote_dir = ''.join([remote_dir, env.ADMIN_MEDIA_PREFIX])
    else:
        if env.MEDIA_URL and env.MEDIA_URL == env.STATIC_URL[:m_prefix]:
            print "ERROR: Your STATIC_URL (Application media) must not be on the same path as your MEDIA_URL (User media)"
            sys.exit(1)
        elif env.STATIC_ROOT:
            local_dir = env.STATIC_ROOT
            static_url = env.STATIC_URL[1:]
            if static_url:
                remote_dir = '/'.join([remote_dir, static_url])
        else:
            return
    if env.verbosity:
        print env.host, "DEPLOYING static", remote_dir
    return deploy_files(local_dir, remote_dir)
Пример #21
0
def deploy_webconf():
    """ Deploy nginx and other wsgi server site configurations to the host """
    deployed = []
    log_dir = '/'.join([deployment_root(),'log'])
    #TODO - incorrect - check for actual package to confirm installation
    if webserver_list():
        if env.verbosity:
            print env.host,"DEPLOYING webconf:"
        if not exists(log_dir):
            run('ln -s /var/log log')
        #deploys confs for each domain based on sites app
        if 'apache2' in get_packages():
            deployed += _deploy_webconf('/etc/apache2/sites-available','django-apache-template.txt')
            deployed += _deploy_webconf('/etc/nginx/sites-available','nginx-template.txt')
        elif 'gunicorn' in get_packages():
            deployed += _deploy_webconf('/etc/nginx/sites-available','nginx-gunicorn-template.txt')
        
        if not exists('/var/www/nginx-default'):
            sudo('mkdir /var/www/nginx-default')
        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:
        print env.host,"""WARNING: Apache or Nginx not installed"""
        
    return deployed
Пример #22
0
def deploy_static():
    """
    Deploy static (application) versioned media
    """
    
    if not env.STATIC_URL or 'http://' in env.STATIC_URL: return
    from django.core.servers.basehttp import AdminMediaHandler
    remote_dir = '/'.join([deployment_root(),'env',env.project_fullname,'static'])
    m_prefix = len(env.MEDIA_URL)
    #if app media is not handled by django-staticfiles we can install admin media by default
    if 'django.contrib.admin' in env.INSTALLED_APPS and not 'django.contrib.staticfiles' in env.INSTALLED_APPS:
        
        if env.MEDIA_URL and env.MEDIA_URL == env.ADMIN_MEDIA_PREFIX[:m_prefix]:
            print "ERROR: Your ADMIN_MEDIA_PREFIX (Application media) must not be on the same path as your MEDIA_URL (User media)"
            sys.exit(1)
        admin = AdminMediaHandler('DummyApp')
        local_dir = admin.base_dir
        remote_dir =  ''.join([remote_dir,env.ADMIN_MEDIA_PREFIX])
    else:
        if env.MEDIA_URL and env.MEDIA_URL == env.STATIC_URL[:m_prefix]:
            print "ERROR: Your STATIC_URL (Application media) must not be on the same path as your MEDIA_URL (User media)"
            sys.exit(1)
        elif env.STATIC_ROOT:
            local_dir = env.STATIC_ROOT
            static_url = env.STATIC_URL[1:]
            if static_url:
                remote_dir = '/'.join([remote_dir,static_url])
        else: return
    if env.verbosity:
        print env.host,"DEPLOYING static",remote_dir
    return deploy_files(local_dir,remote_dir)
Пример #23
0
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 = ''
    if not static_url: static_url = env.ADMIN_MEDIA_PREFIX
    log_dir = '/'.join([deployment_root(),'log'])
    deployed = []
    users_added = []
    
    domains = domain_sites()
    for d in domains:
        u_domain = d.name.replace('.','_')
        wsgi_filename = d.settings.replace('.py','.wsgi')
        site_user = ''.join(['site_',str(d.site_id)])
        filename = ''.join([remote_dir,'/',u_domain,'-',env.project_version,'.conf'])
        context = {"project_name": env.project_name,
                   "deployment_root":deployment_root(),
                    "u_domain":u_domain,
                    "domain":d.name,
                    "root_domain":env.root_domain,
                    "user":env.user,
                    "site_user":site_user,
                    "SITE_ID":d.site_id,
                    "host_ip":socket.gethostbyname(env.host),
                    "wsgi_filename":wsgi_filename,
                    "MEDIA_URL":media_url,
                    "STATIC_URL":static_url,
                    }

        upload_template('/'.join(['woven',template]),
                        filename,
                        context,
                        use_sudo=True)
        if env.verbosity:
            print " * uploaded", filename
            
        #add site users if necessary
        site_users = _site_users()
        if site_user not in users_added and site_user not in site_users:
            add_user(username=site_user,group='www-data',site_user=True)
            users_added.append(site_user)
            if env.verbosity:
                print " * useradded",site_user

    return deployed
Пример #24
0
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, "sitesettings"])
        ):
            venv = "/".join([deployment_root(), "env", env.project_fullname, "bin", "activate"])
            output = run(" ".join(["source", venv, "&&", "./manage.py dumpdata sites"]))
            sites = json.loads(output)
            env.sites = {}
            for s in sites:
                env.sites[s["pk"]] = s["fields"]["domain"]
    return env.sites
Пример #25
0
def deploy_files(local_dir, remote_dir, pattern = '',rsync_exclude=['*.pyc','.*'], use_sudo=False):
    """
    Generic deploy function for cases where one or more files are being deployed to a host.
    Wraps around ``rsync_project`` and stages files locally and/or remotely
    for network efficiency.
    
    ``local_dir`` is the directory that will be deployed.
   
    ``remote_dir`` is the directory the files will be deployed to.
    Directories will be created if necessary.
    
    Note: Unlike other ways of deploying files, all files under local_dir will be
    deployed into remote_dir. This is the equivalent to cp -R local_dir/* remote_dir.

    ``pattern`` finds all the pathnames matching a specified glob pattern relative
    to the local_dir according to the rules used by the Unix shell.
    ``pattern`` enhances the basic functionality by allowing the python | to include
    multiple patterns. eg '*.txt|Django*'
     
    ``rsync_exclude`` as per ``rsync_project``
    
    Returns a list of directories and files created on the host.
    
    """
    #normalise paths
    if local_dir[-1] == os.sep: local_dir = local_dir[:-1]
    if remote_dir[-1] == '/': remote_dir = remote_dir[:-1]
    created_list = []
    staging_dir = local_dir
    
    #resolve pattern into a dir:filename dict
    local_files = _get_local_files(local_dir,pattern)
    #If we are only copying specific files or rendering templates we need to stage locally
    if local_files: staging_dir = _stage_local_files(local_dir, local_files)
    remote_staging_dir = os.path.join(deployment_root(), '.staging')
    if not exists(remote_staging_dir):
        run(' '.join(['mkdir -pv',remote_staging_dir])).split('\n')
        created_list = [remote_staging_dir]
    
    #upload into remote staging
    rsync_project(local_dir=staging_dir,remote_dir=remote_staging_dir,exclude=rsync_exclude,delete=True)

    #create the final destination
    created_dir_list = mkdirs(remote_dir, use_sudo)
    
    if not os.listdir(staging_dir): return created_list

    func = use_sudo and sudo or run
    #cp recursively -R from the staging to the destination and keep a list
    remote_base_path = '/'.join([remote_staging_dir,os.path.basename(local_dir),'*'])
    copy_file_list = func(' '.join(['cp -Ruv',remote_base_path,remote_dir])).split('\n')
    if copy_file_list[0]: created_list += [file.split(' ')[2][1:-1] for file in copy_file_list if file]

    #cleanup any tmp staging dir
    if staging_dir <> local_dir:
        shutil.rmtree(staging_dir,ignore_errors=True)
    
    return created_list
Пример #26
0
def sync_db():
    """
    Runs the django syncdb command
    """
    with cd('/'.join([deployment_root(),'env',env.project_fullname,'project',env.project_package_name,'sitesettings'])):
        venv = '/'.join([deployment_root(),'env',env.project_fullname,'bin','activate'])
        sites = _get_django_sites()
        site_ids = sites.keys()
        site_ids.sort()
        for site in site_ids:
            for settings_file in _sitesettings_files():
                site_settings = '.'.join([env.project_package_name,'sitesettings',settings_file.replace('.py','')])
                if env.verbosity:
                    print " * python manage.py syncdb --noinput --settings=%s"% site_settings
                output = sudo(' '.join(['source',venv,'&&',"./manage.py syncdb --noinput --settings=%s"% site_settings]),
                              user='******'% site)
                if env.verbosity:
                    print output
Пример #27
0
 def handle_host(self,*args, **options):
     opts = options.get('options')
     command = args[0]
     root = deployment_root()
     path = '%s/%s/env/%s/project/%s/'% (root,root_domain(),env.project_fullname,env.project_name)
     pythonpath = '%s/%s/env/%s/bin/python'% (root,env.root_domain,env.project_fullname)
     with cd(path):     
         result = run(' '.join([pythonpath,'manage.py',command,opts]))
     if env.verbosity:
         print result
Пример #28
0
def active_version():
    """
    Determine the current active version on the server
    
    Just examine the which environment is symlinked
    """

    link = '/'.join([deployment_root(), 'env', env.project_name])
    if not exists(link): return None
    active = os.path.split(run('ls -al ' + link).split(' -> ')[1])[1]
    return active
Пример #29
0
def active_version():
    """
    Determine the current active version on the server
    
    Just examine the which environment is symlinked
    """
    
    link = '/'.join([deployment_root(),'env',env.project_name])
    if not exists(link): return None
    active = os.path.split(run('ls -al '+link).split(' -> ')[1])[1]
    return active
Пример #30
0
def migration():
    """
    Integrate with south schema migration
    """

    #activate env        
    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,'&&'])
        cmdpt2 = ' '.join(["python manage.py migrate",env.migration])
        
        if hasattr(env,"fakemigration"):
            cmdpt2 = ' '.join([cmdpt2,'--fake'])
        if env.verbosity:
            print " *", cmdpt2
        output = run(' '.join([cmdpt1,cmdpt2]))
        if env.verbosity:
            print output
    return           
Пример #31
0
def deploy_project():
    """
    Deploy to the project directory in the virtualenv
    """

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

    if env.verbosity:
        print env.host, "DEPLOYING project", env.project_fullname
    #Exclude a few things that we don't want deployed as part of the project folder
    rsync_exclude = [
        'local_settings*', '*.pyc', '*.log', '.*', '/build', '/dist',
        '/media*', '/static*', '/www', '/public', '/template*'
    ]

    #make site local settings if they don't already exist
    _make_local_sitesettings()
    created = deploy_files(local_dir,
                           project_root,
                           rsync_exclude=rsync_exclude)
    if not env.patch:
        #hook the project into sys.path
        pyvers = run('python -V').split(' ')[1].split('.')[0:2]  #Python x.x.x
        sitepackages = ''.join(
            ['lib/python', pyvers[0], '.', pyvers[1], '/site-packages'])
        link_name = '/'.join([
            deployment_root(), 'env', env.project_fullname, sitepackages,
            env.project_package_name
        ])
        target = '/'.join([project_root, env.project_package_name])
        run(' '.join(['ln -s', target, link_name]))

        #make sure manage.py has exec permissions
        managepy = '/'.join([target, 'sitesettings', 'manage.py'])
        if exists(managepy):
            sudo('chmod ugo+x %s' % managepy)

    return created
Пример #32
0
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
Пример #33
0
def deploy_project():
    """
    Deploy to the project directory in the virtualenv
    """
    
    project_root = '/'.join([deployment_root(),'env',env.project_fullname,'project'])
    local_dir = os.getcwd()
    
    if env.verbosity:
        print env.host,"DEPLOYING project", env.project_fullname
    #Exclude a few things that we don't want deployed as part of the project folder
    rsync_exclude = ['*.pyc','*.log','.*','/build','/dist','/media*','/static*','/www','/public','/templates']

    #make site local settings if they don't already exist
    _make_local_sitesettings()
    created = deploy_files(local_dir, project_root, rsync_exclude=rsync_exclude)
    if not env.patch:
        #hook the project into sys.path - #TODO make the python version not fixed
        link_name = '/'.join([deployment_root(),'env',env.project_fullname,'lib/python2.6/site-packages',env.project_name])
        target = '/'.join([project_root,env.project_name])
        run(' '.join(['ln -s',target,link_name]))
    
    return created
Пример #34
0
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 = ""
    if not static_url:
        static_url = env.ADMIN_MEDIA_PREFIX
    log_dir = "/".join([deployment_root(), "log"])
    deployed = []
    domains = domain_sites()
    for d in domains:

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

        filename = "".join([remote_dir, "/", u_domain, "-", env.project_version, ".conf"])
        context = {
            "project_name": env.project_name,
            "deployment_root": deployment_root(),
            "u_domain": u_domain,
            "domain": d,
            "root_domain": env.root_domain,
            "user": env.user,
            "host_ip": socket.gethostbyname(env.host),
            "media_url": media_url,
            "static_url": static_url,
        }

        upload_template("/".join(["woven", template]), filename, context, use_sudo=True)
        if env.verbosity:
            print " * uploaded", filename

    return deployed
Пример #35
0
def deploy_db(rollback=False):
    """
    Deploy a sqlite database from development
    """
    if not rollback:

        if env.DEFAULT_DATABASE_ENGINE == 'django.db.backends.sqlite3':
            db_dir = '/'.join([deployment_root(), 'database'])
            db_name = ''.join([env.project_name, '_', 'site_1', '.db'])
            dest_db_path = '/'.join([db_dir, db_name])
            if exists(dest_db_path): return
            if env.verbosity:
                print env.host, "DEPLOYING DEFAULT SQLITE DATABASE"
            if not env.DEFAULT_DATABASE_NAME:
                print "ERROR: A database name has not been defined in your Django settings file"
                sys.exit(1)

            if env.DEFAULT_DATABASE_NAME[0] not in [os.path.sep,
                                                    '.']:  #relative path
                db_path = os.path.join(os.getcwd(), env.project_package_name,
                                       env.DEFAULT_DATABASE_NAME)

            elif env.DEFAULT_DATABASE_NAME[:2] == '..':
                print "ERROR: Use a full expanded path to the database in your Django settings"
                sys.exit(1)
            else:
                db_path = env.DEFAULT_DATABASE_NAME

            if not db_path or not os.path.exists(db_path):
                print "ERROR: the database %s does not exist. \nRun python manage.py syncdb to create your database locally first, or check your settings." % db_path
                sys.exit(1)

            db_name = os.path.split(db_path)[1]
            run('mkdir -p ' + db_dir)
            put(db_path, dest_db_path)
            #directory and file must be writable by webserver
            sudo("chown -R %s:www-data %s" % (env.user, db_dir))
            sudo("chmod -R ug+w %s" % db_dir)

        elif env.DEFAULT_DATABASE_ENGINE == 'django.db.backends.':
            print "ERROR: The default database engine has not been defined in your Django settings file"
            print "At a minimum you must define an sqlite3 database for woven to deploy, or define a database that is managed outside of woven."
            sys.exit(1)
    elif rollback and env.DEFAULT_DATABASE_ENGINE == 'django.db.backends.sqlite3':
        if env.INTERACTIVE:
            delete = confirm('DELETE the database on the host?', default=False)
            if delete:
                run('rm -f ' + db_name)
    return
Пример #36
0
def migration():
    """
    Integrate with south schema migration
    """

    #activate env
    with cd('/'.join([
            deployment_root(), 'env', env.project_fullname, 'project',
            env.project_package_name, 'sitesettings'
    ])):
        #migrates all or specific env.migration
        venv = '/'.join([
            deployment_root(), 'env', env.project_fullname, 'bin', 'activate'
        ])
        cmdpt1 = ' '.join(['source', venv, '&&'])

        sites = _get_django_sites()
        site_ids = sites.keys()
        site_ids.sort()
        for site in site_ids:
            for settings_file in _sitesettings_files():
                site_settings = '.'.join([
                    env.project_package_name, 'sitesettings',
                    settings_file.replace('.py', '')
                ])
                cmdpt2 = ' '.join(["django-admin.py migrate", env.migration])
                if hasattr(env, "fakemigration"):
                    cmdpt2 = ' '.join([cmdpt2, '--fake'])
                cmdpt2 = ''.join([cmdpt2, '--settings=', site_settings])
                if env.verbosity:
                    print " *", cmdpt2
                output = sudo(' '.join([cmdpt1, cmdpt2]),
                              user='******' % site)
            if env.verbosity:
                print output
    return
Пример #37
0
def deploy_db(rollback=False):
    """
    Deploy a sqlite database from development
    """
    if not rollback:

        if env.DEFAULT_DATABASE_ENGINE=='django.db.backends.sqlite3':
            db_dir = '/'.join([deployment_root(),'database'])
            db_name = ''.join([env.project_name,'_','site_1','.db'])
            dest_db_path = '/'.join([db_dir,db_name])
            if exists(dest_db_path): return
            if env.verbosity:
                print env.host,"DEPLOYING DEFAULT SQLITE DATABASE"
            if not env.DEFAULT_DATABASE_NAME:
                print "ERROR: A database name has not been defined in your Django settings file"
                sys.exit(1)

            if env.DEFAULT_DATABASE_NAME[0] not in [os.path.sep,'.']: #relative path
                db_path = os.path.join(os.getcwd(),env.project_package_name,env.DEFAULT_DATABASE_NAME)

            elif env.DEFAULT_DATABASE_NAME[:2] == '..':
                print "ERROR: Use a full expanded path to the database in your Django settings"
                sys.exit(1)
            else:
                db_path = env.DEFAULT_DATABASE_NAME

            if not db_path or not os.path.exists(db_path):
                print "ERROR: the database %s does not exist. \nRun python manage.py syncdb to create your database locally first, or check your settings."% db_path
                sys.exit(1)

            db_name = os.path.split(db_path)[1]  
            run('mkdir -p '+db_dir)
            put(db_path,dest_db_path)
            #directory and file must be writable by webserver
            sudo("chown -R %s:www-data %s"% (env.user,db_dir))
            sudo("chmod -R ug+w %s"% db_dir)
        
        elif env.DEFAULT_DATABASE_ENGINE=='django.db.backends.':
            print "ERROR: The default database engine has not been defined in your Django settings file"
            print "At a minimum you must define an sqlite3 database for woven to deploy, or define a database that is managed outside of woven."
            sys.exit(1)
    elif rollback and env.DEFAULT_DATABASE_ENGINE=='django.db.backends.sqlite3':
        if env.INTERACTIVE:
            delete = confirm('DELETE the database on the host?',default=False)
            if delete:
                run('rm -f '+db_name)
    return
Пример #38
0
def deploy_sitesettings():
    """
    Deploy to the project directory in the virtualenv
    """

    sitesettings = '/'.join([
        deployment_root(), 'env', env.project_fullname, 'project',
        env.project_package_name, 'sitesettings'
    ])
    local_dir = os.path.join(os.getcwd(), env.project_package_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
Пример #39
0
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 webconf:"
        if not exists(log_dir):
            run("ln -s /var/log log")

        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:
        print env.host, """WARNING: Apache or Nginx not installed"""

    return deployed
Пример #40
0
def deploy_public():
    """
    Deploy MEDIA_ROOT unversioned on host
    """
    if not env.MEDIA_ROOT or 'http://' in env.MEDIA_URL: return
    local_dir = env.MEDIA_ROOT
    
    remote_dir = '/'.join([deployment_root(),'public']) 
    media_url = env.MEDIA_URL[1:]
    if media_url:
        remote_dir = '/'.join([remote_dir,media_url])
    if env.verbosity:
        print env.host,"DEPLOYING public",remote_dir    
    deployed = deploy_files(local_dir,remote_dir)
    
    #make writable for www-data for file uploads
    sudo("chown -R www-data:sudo %s" % remote_dir)
    sudo("chmod -R ug+w %s"% remote_dir)
    return deployed
Пример #41
0
def deploy_media():
    """
    Deploy MEDIA_ROOT unversioned on host
    """
    if not env.MEDIA_URL or not env.MEDIA_ROOT or 'http://' in env.MEDIA_URL:
        return
    local_dir = env.MEDIA_ROOT

    remote_dir = '/'.join([deployment_root(), 'public'])
    media_url = env.MEDIA_URL[1:]
    if media_url:
        remote_dir = '/'.join([remote_dir, media_url])
    if env.verbosity:
        print env.host, "DEPLOYING media", remote_dir
    deployed = deploy_files(local_dir, remote_dir)

    #make writable for www-data for file uploads
    sudo("chown -R www-data:sudo %s" % remote_dir)
    sudo("chmod -R ug+w %s" % remote_dir)
    return deployed
Пример #42
0
def _make_local_sitesettings(overwrite=False):
    local_settings_dir = os.path.join(os.getcwd(), env.project_package_name,
                                      'sitesettings')
    if not os.path.exists(local_settings_dir) or overwrite:
        if overwrite:
            shutil.rmtree(local_settings_dir, ignore_errors=True)
        os.mkdir(local_settings_dir)
        f = open(os.path.join(local_settings_dir, '__init__.py'), "w")
        f.close()

    settings_file_path = os.path.join(local_settings_dir, 'settings.py')
    if not os.path.exists(settings_file_path):
        root_domain = _root_domain()
        u_domain = root_domain.replace('.', '_')
        output = render_to_string(
            'woven/sitesettings.txt', {
                "deployment_root": deployment_root(),
                "site_id": "1",
                "project_name": env.project_name,
                "project_fullname": env.project_fullname,
                "project_package_name": env.project_package_name,
                "u_domain": u_domain,
                "domain": root_domain,
                "user": env,
                "MEDIA_URL": env.MEDIA_URL,
                "STATIC_URL": env.STATIC_URL
            })

        f = open(settings_file_path, "w+")
        f.writelines(output)
        f.close()
        if env.verbosity:
            print "Created local sitesettings folder and default settings file"
        #copy manage.py into that directory
        manage_path = os.path.join(os.getcwd(), env.project_package_name,
                                   'manage.py')
        dest_manage_path = os.path.join(os.getcwd(), env.project_package_name,
                                        'sitesettings', 'manage.py')
        shutil.copy(manage_path, dest_manage_path)

    return
Пример #43
0
def _make_local_sitesettings(overwrite=False):
    local_settings_dir = os.path.join(os.getcwd(),env.project_name,'sitesettings')
    if not os.path.exists(local_settings_dir) or overwrite:
        if overwrite:
            shutil.rmtree(local_settings_dir,ignore_errors=True)
        os.mkdir(local_settings_dir)
        f = open(os.path.join(local_settings_dir,'__init__.py'),"w")
        f.close()

    settings_file_path = os.path.join(local_settings_dir,'settings.py')
    if not os.path.exists(settings_file_path):
        root_domain = _root_domain()    
        u_domain = root_domain.replace('.','_')
        output = render_to_string('woven/sitesettings.txt',
                {"deployment_root":deployment_root(),
                "site_id":"1",
                "project_name": env.project_name,
                "project_fullname": env.project_fullname,
                "u_domain":u_domain,
                "domain":root_domain,
                "user":env.user},
            )
                    
        f = open(settings_file_path,"w+")
        f.writelines(output)
        f.close()
        
        #create a convenience settings file link for the first site
        settings_file_path = os.path.join(local_settings_dir,''.join([u_domain,'.py']))
        if not os.path.exists(settings_file_path):
            f = open(settings_file_path, "w+")
            f.write("from %s.sitesettings.settings import *"% env.project_name)
            f.write("\nSITE_ID=1\n")
            f.close()
            #copy manage.py into that directory
            manage_path = os.path.join(os.getcwd(),env.project_name,'manage.py')
            dest_manage_path = os.path.join(os.getcwd(),env.project_name,'sitesettings','manage.py')
            shutil.copy(manage_path, dest_manage_path)
    return
Пример #44
0
def deploy_templates():
    """
    Deploy any templates from your shortest TEMPLATE_DIRS setting
    """

    deployed = None
    if not hasattr(env, 'project_template_dir'):
        #the normal pattern would mean the shortest path is the main one.
        #its probably the last listed
        length = 1000
        for dir in env.TEMPLATE_DIRS:
            if dir:
                len_dir = len(dir)
                if len_dir < length:
                    length = len_dir
                    env.project_template_dir = dir

    if hasattr(env, 'project_template_dir'):
        remote_dir = '/'.join(
            [deployment_root(), 'env', env.project_fullname, 'templates'])
        if env.verbosity:
            print env.host, "DEPLOYING templates", remote_dir
        deployed = deploy_files(env.project_template_dir, remote_dir)
    return deployed
Пример #45
0
def activate():
    """
    Activates the version specified in ``env.project_version`` if it is different
    from the current active version.
    
    An active version is just the version that is symlinked.
    """

    env_path = '/'.join([deployment_root(),'env',env.project_fullname])

    if not exists(env_path):
        print env.host,"ERROR: The version",env.project_version,"does not exist at"
        print env_path
        sys.exit(1)

    active = active_version()

    if env.patch or active <> env.project_fullname:
        stop_webservers()
        
    if not env.patch and active <> env.project_fullname:
        
        if env.verbosity:
            print env.host, "ACTIVATING version", env_path
        
        if not env.nomigration:
            sync_db()
        
        #south migration
        if 'south' in env.INSTALLED_APPS and not env.nomigration and not env.manualmigration:
            migration()
            
        if env.manualmigration or env.MANUAL_MIGRATION: manual_migration()
      
        #activate sites
        activate_sites = [''.join([d.replace('.','_'),'-',env.project_version,'.conf']) for d in domain_sites()]
        site_paths = ['/etc/apache2','/etc/nginx']
        
        #disable existing sites
        for path in site_paths:
            for site in _ls_sites('/'.join([path,'sites-enabled'])):
                if site not in activate_sites:
                    sudo("rm %s/sites-enabled/%s"% (path,site))
        
        #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 env.verbosity:
                        print " * enabled", "%s/sites-enabled/%s"% (path,site)
        
        #delete existing symlink
        ln_path = '/'.join([deployment_root(),'env',env.project_name])
        run('rm -f '+ln_path)
        run('ln -s %s %s'% (env_path,ln_path))

  
        if env.verbosity:
            print env.host,env.project_fullname, "ACTIVATED"
    else:
        if env.verbosity and not env.patch:
            print env.project_fullname,"is the active version"

    if env.patch or active <> env.project_fullname:
        start_webservers()
        print
    return
Пример #46
0
def deploy_wsgi():
    """
    deploy python wsgi file(s)
    """
    if 'libapache2-mod-wsgi' in get_packages():
        remote_dir = '/'.join(
            [deployment_root(), 'env', env.project_fullname, 'wsgi'])
        wsgi = 'apache2'
    elif 'gunicorn' in get_packages():
        remote_dir = '/etc/init'
        wsgi = 'gunicorn'
    deployed = []

    #ensure project apps path is also added to environment variables as well as wsgi
    if env.PROJECT_APPS_PATH:
        pap = '/'.join([
            deployment_root(), 'env', env.project_name, 'project',
            env.project_package_name, env.PROJECT_APPS_PATH
        ])
        pap = ''.join(['export PYTHONPATH=$PYTHONPATH:', pap])
        postactivate = '/'.join([deployment_root(), 'env', 'postactivate'])
        if not exists(postactivate):
            append('#!/bin/bash', postactivate)
            run('chmod +x %s' % postactivate)
        if not contains('PYTHONPATH', postactivate):
            append(pap, postactivate)

    if env.verbosity:
        print env.host, "DEPLOYING wsgi", wsgi, remote_dir

    for file in _sitesettings_files():
        deployed += mkdirs(remote_dir)
        with cd(remote_dir):
            settings_module = file.replace('.py', '')
            context = {
                "deployment_root": deployment_root(),
                "user": env.user,
                "project_name": env.project_name,
                "project_package_name": env.project_package_name,
                "project_apps_path": env.PROJECT_APPS_PATH,
                "settings": settings_module,
            }
            if wsgi == 'apache2':
                filename = file.replace('.py', '.wsgi')
                upload_template(
                    '/'.join(['woven', 'django-wsgi-template.txt']),
                    filename,
                    context,
                )
            elif wsgi == 'gunicorn':
                filename = 'gunicorn-%s.conf' % env.project_name
                upload_template('/'.join(['woven', 'gunicorn.conf']),
                                filename,
                                context,
                                backup=False,
                                use_sudo=True)

            if env.verbosity:
                print " * uploaded", filename
            #finally set the ownership/permissions
            #We'll use the group to allow www-data execute
            if wsgi == 'apache2':
                sudo("chown %s:www-data %s" % (env.user, filename))
                run("chmod ug+xr %s" % filename)
            elif wsgi == 'gunicorn':
                sudo("chown root:root %s" % filename)
                sudo("chmod go+r %s" % filename)

    return deployed
Пример #47
0
def pip_install_requirements():
    """
    Install on current installed virtualenv version from a pip bundle [dist/project name-version].zip or pip ``req.txt``|``requirements.txt``
    or a env.pip_requirements list.
    
    By default it will look for a zip bundle in the dist directory first then a requirements file.

    
    The limitations of installing requirements are that you cannot point directly to packages
    in your local filesystem. In this case you would bundle instead.
    """
    if not version_state('mkvirtualenv'):
        print env.host, 'Error: Cannot run pip_install_requirements. A virtualenv is not created for this version. Run mkvirtualenv first'
        return
    if env.verbosity:
        print env.host, 'PIP INSTALLING REQUIREMENTS:'

    #Remove any pre-existing pip-log from any previous failed installation
    pip_log_dir = '/'.join(['/home', env.user, '.pip'])
    if exists(pip_log_dir): run('rm -f %s/*.txt' % pip_log_dir)

    #determine what req files or bundle files we need to deploy
    if not env.PIP_REQUIREMENTS:
        req_files = {}.fromkeys(glob('req*'))
    else:
        req_files = {}.fromkeys(env.PIP_REQUIREMENTS)

    for key in req_files:
        bundle = ''.join([key.split('.')[0], '.zip'])
        if os.path.exists(os.path.join('dist', bundle)):
            req_files[key] = bundle

    #determine the django version
    file_patterns = ''
    django_version = get_version()
    svn_version = django_version.find('SVN')
    if svn_version > -1:
        django_version = django_version[svn_version + 4:]
        django_req = ''.join([
            '-e svn+http://code.djangoproject.com/svn/django/trunk@',
            django_version, '#egg=Django'
        ])
    else:
        other_builds = ['alpha', 'beta', 'rc']
        for b in other_builds:
            if b in django_version:
                print "ERROR: Unsupported Django version", django_version
                print "Define a DJANGO_REQUIREMENT pointing to the tar.gz for", django_version
                print "and re-deploy, or use the official or SVN release of Django."
                sys.exit(1)
        django_req = ''.join(['Django==', django_version])

    #if no requirements file exists create one
    if not req_files:
        f = open("requirements.txt", "w+")
        text = render_to_string('woven/requirements.txt',
                                {'django': django_req})
        f.write(text)
        f.close()
        if env.verbosity:
            print "Created local requirements.txt"
        req_files["requirements.txt"] = ''

    req_files_list = req_files.keys()
    req_files_list.sort()

    #patterns for bundles
    if req_files: file_patterns = '|'.join([file_patterns, 'req*.zip'])

    #create a pip cache & src directory
    cache = '/'.join([deployment_root(), '.pip', 'cache'])
    src = '/'.join([deployment_root(), '.pip', 'src'])
    deployed = mkdirs(cache)
    deployed += mkdirs(src)
    #deploy bundles and any local copy of django
    local_dir = os.path.join(os.getcwd(), 'dist')
    remote_dir = '/'.join(
        [deployment_root(), 'env', env.project_fullname, 'dist'])
    if os.path.exists(local_dir):
        if file_patterns:
            deployed += deploy_files(local_dir,
                                     remote_dir,
                                     pattern=file_patterns)

    #deploy any requirement files
    deployed += deploy_files(os.getcwd(), remote_dir, pattern='req*')

    #install in the env
    out = State(' '.join([env.host, 'pip install requirements']))
    python_path = '/'.join(
        [deployment_root(), 'env', env.project_fullname, 'bin', 'python'])
    with settings(warn_only=True):
        with cd(remote_dir):
            for req in req_files_list:
                bundle = req_files[req]
                if bundle: req = bundle
                if env.verbosity:
                    print ' * installing', req
                if '.zip' in req.lower():
                    install = run(
                        'pip install %s -q --environment=%s --log=/home/%s/.pip/%s_pip_log.txt'
                        % (req, python_path, env.user, req.replace('.', '_')))

                else:
                    install = run(
                        'pip install -q --environment=%s --src=%s --download-cache=%s --requirement=%s --log=/home/%s/.pip/%s_pip_log.txt'
                        % (python_path, src, cache, req, env.user,
                           req.replace('.', '_')))
                if install.failed:
                    out.failed = True
                    out.stderr += ' '.join(
                        [env.host, "ERROR INSTALLING", req, '\n'])

    out.object = deployed

    if out.failed:
        print out.stderr
        print "Review the pip install logs at %s/.pip and re-deploy" % deployment_root(
        )
        sys.exit(1)
    return out
Пример #48
0
def activate():
    """
    Activates the version specified in ``env.project_version`` if it is different
    from the current active version.
    
    An active version is just the version that is symlinked.
    """

    env_path = '/'.join([deployment_root(), 'env', env.project_fullname])

    if not exists(env_path):
        print env.host, "ERROR: The version", env.project_version, "does not exist at"
        print env_path
        sys.exit(1)

    active = active_version()
    servers = webserver_list()

    if env.patch or active <> env.project_fullname:
        for s in servers:
            stop_webserver(s)

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

        if env.verbosity:
            print env.host, "ACTIVATING version", env_path

        if not env.nomigration:
            sync_db()

        #south migration
        if 'south' in env.INSTALLED_APPS and not env.nomigration and not env.manualmigration:
            migration()

        if env.manualmigration or env.MANUAL_MIGRATION: manual_migration()

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

        #disable existing sites
        for path in site_paths:
            for site in _ls_sites('/'.join([path, 'sites-enabled'])):
                if site not in activate_sites:
                    sudo("rm %s/sites-enabled/%s" % (path, site))

        #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 env.verbosity:
                        print " * enabled", "%s/sites-enabled/%s" % (path,
                                                                     site)

        #delete existing symlink
        ln_path = '/'.join([deployment_root(), 'env', env.project_name])
        run('rm -f ' + ln_path)
        #run post deploy hooks
        post_exec_hook('post_deploy')
        #activate
        run('ln -s %s %s' % (env_path, ln_path))

        if env.verbosity:
            print env.host, env.project_fullname, "ACTIVATED"
    else:
        if env.verbosity and not env.patch:
            print env.project_fullname, "is the active version"

    if env.patch or active <> env.project_fullname:
        for s in servers:
            start_webserver(s)
        print
    return