5 from fabric
.api
import env
, abort
, task
6 from fabric
.context_managers
import settings
, hide
, lcd
7 from fabric
.contrib
.console
import confirm
8 from fabric
.contrib
.files
import exists
9 from fabric
.operations
import local
, require
, prompt
11 # Required dependencies
13 # PIP_INSTALL - install packages from pip: name:version
15 # GIT_INSTALL - install packages from git:
17 # url - git url for checkouts
18 # development - head to checkout for dev.
20 # production - head to checkout for prod.
22 # symlink - directory to symlink into project.
23 # Uses project name if blank
24 # Packages from git are given preference for dev environment. PIP is given
25 # preference for production environments
27 PIP_INSTALL
= dict((r
.project_name
, str(r
)) for r
in
28 pkg_resources
.parse_requirements(
29 open("requirements/prod.txt").read()
33 'django-object-permissions': {
34 'url': 'git://git.osuosl.org/gitolite/django/'
35 'django_object_permissions',
36 'development': 'develop',
38 'django-object-log': {
39 'url': 'git://git.osuosl.org/gitolite/django/'
41 'development': 'develop',
43 'twisted_vncauthproxy': {
44 'url': 'git://git.osuosl.org/gitolite/ganeti/'
45 'twisted_vncauthproxy',
46 'development': 'develop',
53 # default environment settings - override these in environment methods if you
54 # wish to have an environment that functions differently
57 env
.environment
= PROD
59 # List of stuff to include in the tarball, recursive.
86 Configure development deployment.
94 Install all dependencies from git and pip.
97 install_dependencies_pip()
98 install_dependencies_git()
105 In a development environment, remove all installed packages and symlinks.
107 with
lcd('%(doc_root)s' % env
):
108 gitcmd
= 'git clean -%sdX -e \!settings.py'
109 print('Files to be removed:')
111 if confirm('Are you certain you would like to remove these files?'):
114 abort('Aborting clean.')
120 In a development environment, update all develop branches.
123 if env
.environment
!= DEV
:
124 raise Exception('must be in a development environment in order to'
125 'update develop branches.')
127 with
lcd('%(doc_root)s/dependencies' % env
):
128 for git_dir
, opts
in GIT_INSTALL
.items():
129 env
.git_repo
= git_dir
130 if (_exists('%(doc_root)s/dependencies/%(git_repo)s' % env
) and
131 'development' in opts
and 'checkout' not in opts
):
133 print 'Updating git repo: %(git_repo)s' % env
134 local('git pull --ff')
139 A helper function to determine whether a path exists.
141 This function does the right thing in both remote and local environments.
147 return os
.path
.exists(path
)
150 def create_virtualenv(virtualenv
='venv', force
=False):
152 Create a virtualenv for pip installations.
154 By default, the environment will be placed in the document root. Pass a
155 path to override the location.
157 If ``force`` is False, then the environment will not be recreated if it
161 env
.virtualenv
= virtualenv
if virtualenv
else env
.doc_root
163 with
lcd(env
.doc_root
):
164 if force
or not _exists('%(virtualenv)s/lib' % env
):
165 # XXX does this actually create a new environment if one already
167 local('virtualenv %(virtualenv)s --distribute' % env
)
169 # now lets make sure the virtual env has the the newest pip
170 local(str(verbose_check()+'--upgrade pip') % env
)
175 Setup environment for git dependencies.
178 with
lcd(env
.doc_root
):
179 if _exists('dependencies'):
180 print 'dependencies directory exists already'
182 local('mkdir dependencies')
187 Default to quiet install when env.verbose is false
189 install_str
= '%(virtualenv)s/bin/pip install '
196 def install_dependencies_pip():
198 Install all dependencies available from pip.
203 with
lcd(env
.doc_root
):
204 # Run the installation with pip, passing in our
205 # requirements/prod.txt.
206 local(str(verbose_check()+'-r requirements/prod.txt') % env
)
209 def install_dependencies_git():
211 Install all dependencies available from git.
214 if env
.environment
!= DEV
:
215 # If we can satisfy all of our dependencies from pip alone, then don't
216 # bother running the git installation.
217 if all(p
in PIP_INSTALL
for p
in GIT_INSTALL
):
218 print 'No git repos to install! Yay!'
223 for name
in (set(GIT_INSTALL
) - set(PIP_INSTALL
)):
224 opts
= GIT_INSTALL
[name
]
226 # check for required values
227 if 'url' not in opts
:
228 raise Exception('missing required argument "url" '
229 'for git repo: %s' % name
)
231 # set git head to check out
232 if env
.environment
in opts
:
233 opts
['head'] = opts
[env
.environment
]
234 elif env
.environment
== DEV
and 'production' in opts
:
235 opts
['head'] = opts
['production']
237 opts
['head'] = 'master'
240 with
lcd('%(doc_root)s/dependencies' % env
):
242 env
.git_url
= opts
['url']
243 if not _exists('%(doc_root)s/dependencies/%(git_repo)s' % env
):
244 local('git clone %(git_url)s %(git_repo)s' % env
)
246 # create branch if not using master
247 if opts
['head'] != 'master':
251 # Attempt to create a tracked branch and update it.
252 with
settings(hide('warnings', 'stderr'), warn_only
=True):
253 local('git checkout -t origin/%(head)s' % opts
)
256 # install to virtualenv using setup.py if it exists. Some repos might
257 # not have it and will need to be symlinked into the project
258 if _exists('%(doc_root)s/dependencies/%(git_repo)s/setup.py' % env
):
259 with
lcd(env
.doc_root
):
261 str(verbose_check()+'-e dependencies/%(git_repo)s') % env
265 # else, configure and create symlink to git repo
266 with
lcd(env
.doc_root
):
267 if 'symlink' in opts
:
268 env
.symlink
= opts
['symlink']
269 env
.symlink_path
= '%(doc_root)s/dependencies/' \
270 '%(git_repo)s/%(symlink)s' % env
273 env
.symlink_path
= '%(doc_root)s/dependencies/' \
276 with
settings(hide('warnings', 'stderr'), warn_only
=True):
277 local('ln -sf %(symlink_path)s %(doc_root)s' % env
)
285 if _exists("%(doc_root)s/noVNC" % env
):
288 # Grab the tarball, pass it through filters. Heavy abuse of the fact that
289 # shell=True in local().
290 with
lcd(env
.doc_root
):
291 # -L follows redirects.
292 local("curl https://github.com/kanaka/noVNC/tarball/v0.3 -L | tar xz")
293 # The glob replaces a git revision.
294 local("mv kanaka-noVNC-*/ noVNC")
300 Package a release tarball.
303 tarball
= prompt('tarball name', default
='ganeti-webmgr.tar.gz')
304 files
= ['ganeti_webmgr/%s' % file for file in env
.MANIFEST
]
305 files
= ' '.join(files
)
312 local('tar zcf %(tarball)s %(files)s --exclude=*.pyc' % data
)
313 local('mv %(tarball)s ./ganeti_webmgr/' % data
)
316 def _uncomment(filen
, com
):
317 args
= dict(filen
=filen
, com
=com
)
318 local('sed -i.bak -r -e "/%(com)s/ '
319 's/^([[:space:]]*)#[[:space:]]?/\\1/g" %(filen)s' % args
)
322 def _comment(filen
, com
):
323 args
= dict(filen
=filen
, com
=com
)
324 local('sed -i.bak -r -e "s/(%(com)s)/#\\1/g" %(filen)s' % args
)
327 def ldap(state
="enable"):
329 Enable LDAP settings, and install packages
330 Depends on: libldap2-dev, libsasl2-dev
333 filename
= 'settings.py' % env
334 env
.virtualenv
= env
.doc_root
336 with
lcd(env
.doc_root
):
337 if state
== "enable":
338 # Install and enable LDAP settings
339 if not _exists('/usr/include/lber.h'):
340 abort("Make sure libldap-dev is installed before continuing")
341 if not _exists('/usr/include/sasl'):
342 abort("Make sure libsasl2-dev is"
343 " installed before continuing")
344 local('%(virtualenv)s/bin/pip install -qr'
345 ' requirements-ldap.txt' % env
)
347 _uncomment(filename
, 'from ldap_settings')
348 _uncomment(filename
, "'django_auth_ldap")
349 elif state
== "disable":
350 # Disable LDAP settings and uninstall requirments
351 local('%(virtualenv)s/bin/pip uninstall -qyr'
352 ' requirements-ldap.txt' % env
)
354 _comment(filename
, 'from ldap_settings')
355 _comment(filename
, "'django_auth_ldap")
361 Enable verbose output in some commands