Example #1
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
Example #2
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
Example #3
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
Example #4
0
def pip_install_requirements():
    """
    Install on current installed virtualenv version from a [dist/project name-version].pybundles or pip ``req.txt``|``requirements.txt``
    or a env.pip_requirements list.
    
    By default it will look for a pybundle 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 server_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(' '.join(['rm -rf' ,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],'.pybundle'])
        if os.path.exists(os.path.join('dist',bundle)):
            req_files[key] = bundle

    #if no requirements file exists create one
    if not req_files:
        f = open("requirements.txt","w+")
        text = render_to_string('woven/requirements.txt')
        f.write(text)
        f.close()
        req_files["requirements.txt"]=''
        
    req_files_list = req_files.keys()
    req_files_list.sort()
        
    #determine the django version
    file_patterns =''
    if 'file://' in env.DJANGO_REQUIREMENT:
        django_req = os.path.split(env.DJANGO_REQUIREMENT.replace('file://',''))[1]
        file_patterns = ''.join([django_req])

    elif env.DJANGO_REQUIREMENT:
        django_req = env.DJANGO_REQUIREMENT
    else:
        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@',svn_version,'#egg=Django'])
        else:
            django_req = ''.join(['Django==',django_version])
    req_files[django_req]=None
    req_files_list.insert(0,django_req)
    
    #patterns for bundles
    if req_files: file_patterns = '|'.join([file_patterns,'req*.pybundle'])

    #create a pip cache & src directory
    cache =  '/'.join(['/home',env.user,'.package-cache'])
    src = '/'.join([deployment_root(),'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 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 '.pybundle' 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('.','_')))
                elif 'django' in req.lower():
                    install = run('pip install %s -q --environment=%s --src=%s --download-cache=%s --log=/home/%s/.pip/django_pip_log.txt'%
                                  (req, python_path, src, cache, env.user))                    
                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'])
                    
                    #fabric 1.0
                    if hasattr(install,'stderr'):
                        out.stderr = '\n'.join([out.stderr,install.stderr])
    
    out.object = deployed
              
    if install.failed:
        print out.stderr
        sys.exit(1)
    return out
Example #5
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
Example #6
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
Example #7
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
Example #8
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 = os.path.join(deployment_root(), '.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=%s/.pip/%s_pip_log.txt'%
                                  (req, python_path, deployment_root(), req.replace('.','_')))
                  
                else:
                    install = run('pip install -q --environment=%s --src=%s --download-cache=%s --requirement=%s --log=%s/.pip/%s_pip_log.txt'%
                                  (python_path,src,cache,req, deployment_root(),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