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)
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
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)
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
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)
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
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
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
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
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
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
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
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
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
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
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