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.
84 "ldap_settings.py.dist",
92 Configure development deployment.
100 Install all dependencies from git and pip.
103 install_dependencies_pip()
104 install_dependencies_git()
111 In a development environment, remove all installed packages and symlinks.
113 with
lcd('%(doc_root)s' % env
):
114 gitcmd
= 'git clean -%sdX -e \!settings.py'
115 print('Files to be removed:')
117 if confirm('Are you certain you would like to remove these files?'):
120 abort('Aborting clean.')
126 In a development environment, update all develop branches.
129 if env
.environment
!= DEV
:
130 raise Exception('must be in a development environment in order to'
131 'update develop branches.')
133 with
lcd('%(doc_root)s/dependencies' % env
):
134 for git_dir
, opts
in GIT_INSTALL
.items():
135 env
.git_repo
= git_dir
136 if (_exists('%(doc_root)s/dependencies/%(git_repo)s' % env
) and
137 'development' in opts
and 'checkout' not in opts
):
139 print 'Updating git repo: %(git_repo)s' % env
140 local('git pull --ff')
145 A helper function to determine whether a path exists.
147 This function does the right thing in both remote and local environments.
153 return os
.path
.exists(path
)
156 def create_virtualenv(virtualenv
='venv', force
=False):
158 Create a virtualenv for pip installations.
160 By default, the environment will be placed in the document root. Pass a
161 path to override the location.
163 If ``force`` is False, then the environment will not be recreated if it
167 env
.virtualenv
= virtualenv
if virtualenv
else env
.doc_root
169 with
lcd(env
.doc_root
):
170 if force
or not _exists('%(virtualenv)s/lib' % env
):
171 # XXX does this actually create a new environment if one already
173 local('virtualenv %(virtualenv)s --distribute --no-site-packages' % env
)
175 # now lets make sure the virtual env has the the newest pip
176 local(str(verbose_check()+'--upgrade pip') % env
)
181 Setup environment for git dependencies.
184 with
lcd(env
.doc_root
):
185 if _exists('dependencies'):
186 print 'dependencies directory exists already'
188 local('mkdir dependencies')
193 Default to quiet install when env.verbose is false
195 install_str
= '%(virtualenv)s/bin/pip install '
202 def install_dependencies_pip():
204 Install all dependencies available from pip.
209 with
lcd(env
.doc_root
):
210 # Run the installation with pip, passing in our
211 # requirements/prod.txt.
212 local(str(verbose_check()+'-r requirements/prod.txt') % env
)
215 def install_dependencies_git():
217 Install all dependencies available from git.
220 if env
.environment
!= DEV
:
221 # If we can satisfy all of our dependencies from pip alone, then don't
222 # bother running the git installation.
223 if all(p
in PIP_INSTALL
for p
in GIT_INSTALL
):
224 print 'No git repos to install! Yay!'
229 for name
in (set(GIT_INSTALL
) - set(PIP_INSTALL
)):
230 opts
= GIT_INSTALL
[name
]
232 # check for required values
233 if 'url' not in opts
:
234 raise Exception('missing required argument "url" '
235 'for git repo: %s' % name
)
237 # set git head to check out
238 if env
.environment
in opts
:
239 opts
['head'] = opts
[env
.environment
]
240 elif env
.environment
== DEV
and 'production' in opts
:
241 opts
['head'] = opts
['production']
243 opts
['head'] = 'master'
246 with
lcd('%(doc_root)s/dependencies' % env
):
248 env
.git_url
= opts
['url']
249 if not _exists('%(doc_root)s/dependencies/%(git_repo)s' % env
):
250 local('git clone %(git_url)s %(git_repo)s' % env
)
252 # create branch if not using master
253 if opts
['head'] != 'master':
257 # Attempt to create a tracked branch and update it.
258 with
settings(hide('warnings', 'stderr'), warn_only
=True):
259 local('git checkout -t origin/%(head)s' % opts
)
262 # install to virtualenv using setup.py if it exists. Some repos might
263 # not have it and will need to be symlinked into the project
264 if _exists('%(doc_root)s/dependencies/%(git_repo)s/setup.py' % env
):
265 with
lcd(env
.doc_root
):
267 str(verbose_check()+'-e dependencies/%(git_repo)s') % env
271 # else, configure and create symlink to git repo
272 with
lcd(env
.doc_root
):
273 if 'symlink' in opts
:
274 env
.symlink
= opts
['symlink']
275 env
.symlink_path
= '%(doc_root)s/dependencies/' \
276 '%(git_repo)s/%(symlink)s' % env
279 env
.symlink_path
= '%(doc_root)s/dependencies/' \
282 with
settings(hide('warnings', 'stderr'), warn_only
=True):
283 local('ln -sf %(symlink_path)s %(doc_root)s' % env
)
291 if _exists("%(doc_root)s/noVNC" % env
):
294 # Grab the tarball, pass it through filters. Heavy abuse of the fact that
295 # shell=True in local().
296 with
lcd(env
.doc_root
):
297 # -L follows redirects.
298 local("curl https://github.com/kanaka/noVNC/tarball/v0.3 -L | tar xz")
299 # The glob replaces a git revision.
300 local("mv kanaka-noVNC-*/ noVNC")
306 Package a release tarball.
309 tarball
= prompt('tarball name', default
='ganeti-webmgr.tar.gz')
310 files
= ['ganeti_webmgr/%s' % file for file in env
.MANIFEST
]
311 files
= ' '.join(files
)
318 local('tar zcf %(tarball)s %(files)s --exclude=*.pyc' % data
)
319 local('mv %(tarball)s ./ganeti_webmgr/' % data
)
322 def _uncomment(filen
, com
):
323 args
= dict(filen
=filen
, com
=com
)
324 local('sed -i.bak -r -e "/%(com)s/ '
325 's/^([[:space:]]*)#[[:space:]]?/\\1/g" %(filen)s' % args
)
328 def _comment(filen
, com
):
329 args
= dict(filen
=filen
, com
=com
)
330 local('sed -i.bak -r -e "s/(%(com)s)/#\\1/g" %(filen)s' % args
)
334 def ldap(state
="enable", virtualenv
='venv'):
336 Enable LDAP settings, and install packages
337 Depends on: libldap2-dev, libsasl2-dev
340 filename
= 'settings.py'
341 env
.virtualenv
= virtualenv
if virtualenv
else env
.doc_root
343 with
lcd(env
.doc_root
):
344 if state
== "enable":
345 # Install and enable LDAP settings
346 if not _exists('/usr/include/lber.h'):
347 abort("Make sure libldap-dev is installed before continuing")
348 if not _exists('/usr/include/sasl'):
349 abort("Make sure libsasl2-dev is"
350 " installed before continuing")
351 local(str(verbose_check()+'-r requirements/ldap.txt') % env
)
353 _uncomment(filename
, 'from ldap_settings')
354 _uncomment(filename
, "'django_auth_ldap")
355 elif state
== "disable":
356 # Disable LDAP settings and uninstall requirments
357 local('%(virtualenv)s/bin/pip uninstall '
358 '-r requirements/ldap.txt' % env
)
360 _comment(filename
, 'from ldap_settings')
361 _comment(filename
, "'django_auth_ldap")
367 Enable verbose output in some commands