24.1.1
by Patrick Hetu
first draft of python hooks |
1 |
# Mostly from django-fab-deploy
|
2 |
||
3 |
import os |
|
4 |
import sys |
|
5 |
from subprocess import Popen, PIPE |
|
6 |
||
7 |
import yaml |
|
8 |
||
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
9 |
from fabric.api import env, run, sudo, task, put |
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
10 |
from fabric.context_managers import cd, shell_env |
24.1.1
by Patrick Hetu
first draft of python hooks |
11 |
from fabric.contrib import files |
65
by Patrick Hetu
pull playbooks and minor fixes |
12 |
from fabric.state import output |
13 |
||
14 |
# Be quiet by default
|
|
15 |
env.output_prefix = '' |
|
16 |
output['running'] = False |
|
17 |
output['status'] = False |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
18 |
|
19 |
||
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
20 |
# helpers
|
21 |
def _sanitize(s): |
|
22 |
s = s.replace(':', '_') |
|
23 |
s = s.replace('-', '_') |
|
24 |
s = s.replace('/', '_') |
|
25 |
s = s.replace('"', '_') |
|
26 |
s = s.replace("'", '_') |
|
27 |
return s |
|
28 |
||
29 |
||
30 |
def _config_get(service_name): |
|
31 |
yaml_conf = Popen(['juju', 'get', service_name], stdout=PIPE) |
|
32 |
conf = yaml.safe_load(yaml_conf.stdout) |
|
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
33 |
return {k: (v['value'] if 'value' in v else v['default']) for k,v in conf['settings'].iteritems()} |
34 |
||
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
35 |
|
36 |
def _find_django_admin_cmd(): |
|
37 |
for cmd in ['django-admin.py', 'django-admin']: |
|
38 |
remote_environ = run('echo $PATH') |
|
39 |
for path in remote_environ.split(':'): |
|
40 |
path = path.strip('"') |
|
41 |
path = os.path.join(path, cmd) |
|
42 |
if files.exists(path): |
|
43 |
return path |
|
44 |
||
24.1.1
by Patrick Hetu
first draft of python hooks |
45 |
# Initialisation
|
46 |
env.user = 'ubuntu' |
|
47 |
||
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
48 |
d = yaml.safe_load(Popen(['juju', 'status'], stdout=PIPE).stdout) |
24.1.1
by Patrick Hetu
first draft of python hooks |
49 |
|
50 |
services = d.get("services", {}) |
|
51 |
if services is None: |
|
52 |
sys.exit(0) |
|
53 |
||
54 |
env.roledefs = {} |
|
55 |
for service in services.items(): |
|
56 |
if service is None: |
|
57 |
continue
|
|
58 |
||
59 |
units = services.get(service[0], {}).get("units", {}) |
|
60 |
if units is None: |
|
61 |
continue
|
|
62 |
||
63 |
for unit in units.items(): |
|
64 |
if 'public-address' in unit[1].keys(): |
|
65 |
env.roledefs.setdefault(service[0], []).append(unit[1]['public-address']) |
|
24.1.39
by Patrick Hetu
ajust the fabfile for latest version of juju |
66 |
env.roledefs.setdefault(unit[0], []).append(unit[1]['public-address']) |
24.1.1
by Patrick Hetu
first draft of python hooks |
67 |
|
45
by Patrick Hetu
fix configuration reading for Django task |
68 |
if not env.roles: |
69 |
print "You must select a charm or a unit with the -R option to perform a task" |
|
70 |
print "Charms: %s" % [role for role in env.roledefs.keys() if not '/' in role] |
|
71 |
print "Units: %s" % [host for host in env.roledefs.keys() if '/' in host] |
|
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
72 |
print
|
73 |
else: |
|
74 |
env.service_name = env.roles[0].split('/')[0] |
|
75 |
env.sanitized_service_name = _sanitize(env.service_name) |
|
76 |
env.conf = _config_get(env.service_name) |
|
77 |
if not env.conf['django_settings']: |
|
51
by Patrick Hetu
fix settings path in the fabfile |
78 |
django_settings_modules = '.'.join([env.sanitized_service_name, 'settings']) |
64
by Patrick Hetu
migrate to Ansible |
79 |
if env.conf['application_path']: |
80 |
django_settings_modules = '.'.join([os.path.basename(env.conf['application_path']), |
|
81 |
'settings']) |
|
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
82 |
else: |
83 |
django_settings_modules = env.conf['django_settings'] |
|
84 |
||
85 |
env.project_dir = os.path.join(env.conf['install_root'], env.sanitized_service_name) |
|
86 |
env.site_path = os.path.join(env.project_dir, env.conf['application_path']) |
|
54
by Patrick Hetu
fix single python-path for fabfile.py |
87 |
if env.conf['python_path']: |
88 |
env.python_path = ':'.join([env.conf['install_root'], env.conf['python_path'].replace(',', ':')]) |
|
89 |
else: |
|
90 |
env.python_path = env.conf['install_root'] |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
91 |
|
92 |
||
93 |
# Debian
|
|
94 |
@task() |
|
95 |
def apt_install(packages): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
96 |
"""
|
97 |
Install one or more packages.
|
|
98 |
"""
|
|
24.1.1
by Patrick Hetu
first draft of python hooks |
99 |
sudo('apt-get install -y %s' % packages) |
100 |
||
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
101 |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
102 |
@task
|
103 |
def apt_update(): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
104 |
"""
|
105 |
Update APT package definitions.
|
|
106 |
"""
|
|
24.1.1
by Patrick Hetu
first draft of python hooks |
107 |
sudo('apt-get update') |
108 |
||
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
109 |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
110 |
@task
|
111 |
def apt_dist_upgrade(): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
112 |
"""
|
113 |
Upgrade all packages.
|
|
114 |
"""
|
|
24.1.1
by Patrick Hetu
first draft of python hooks |
115 |
sudo('apt-get dist-upgrade -y') |
116 |
||
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
117 |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
118 |
@task
|
119 |
def apt_install_r(): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
120 |
"""
|
121 |
Install one or more packages listed in your requirements_apt_files.
|
|
122 |
"""
|
|
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
123 |
with cd(env.project_dir): |
124 |
for req_file in env.conf['requirements_apt_files'].split(','): |
|
24.1.39
by Patrick Hetu
ajust the fabfile for latest version of juju |
125 |
sudo("apt-get install -y $(cat %s | tr '\\n' ' '" % req_file) |
24.1.1
by Patrick Hetu
first draft of python hooks |
126 |
|
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
127 |
|
47
by Patrick Hetu
add the pip_freeze task in the fabfile |
128 |
# Pip
|
24.1.1
by Patrick Hetu
first draft of python hooks |
129 |
@task
|
130 |
def pip_install(packages): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
131 |
"""
|
132 |
Install one or more packages.
|
|
133 |
"""
|
|
24.1.1
by Patrick Hetu
first draft of python hooks |
134 |
sudo("pip install %s" % packages) |
135 |
||
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
136 |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
137 |
@task
|
138 |
def pip_install_r(): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
139 |
"""
|
140 |
Install one or more python packages listed in your requirements_pip_files.
|
|
141 |
"""
|
|
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
142 |
with cd(env.project_dir): |
143 |
for req_file in env.conf['requirements_pip_files'].split(','): |
|
24.1.39
by Patrick Hetu
ajust the fabfile for latest version of juju |
144 |
sudo("pip install -r %s" % req_file) |
24.1.1
by Patrick Hetu
first draft of python hooks |
145 |
|
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
146 |
|
47
by Patrick Hetu
add the pip_freeze task in the fabfile |
147 |
@task
|
148 |
def pip_freeze(): |
|
149 |
"""
|
|
150 |
List installed python packages
|
|
151 |
"""
|
|
152 |
sudo("pip freeze") |
|
153 |
||
154 |
||
24.1.1
by Patrick Hetu
first draft of python hooks |
155 |
# Users
|
156 |
@task
|
|
157 |
def adduser(username): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
158 |
"""
|
159 |
Adduser without password.
|
|
160 |
"""
|
|
24.1.1
by Patrick Hetu
first draft of python hooks |
161 |
sudo('adduser %s --disabled-password --gecos ""' % username) |
162 |
||
163 |
||
164 |
# VCS
|
|
165 |
||
166 |
@task
|
|
167 |
def pull(): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
168 |
"""
|
169 |
pull or update your project code on the remote machine.
|
|
170 |
"""
|
|
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
171 |
with cd(env.project_dir): |
172 |
if env.conf['vcs'] is 'bzr': |
|
173 |
run('bzr pull %s' % env.conf['repos_url']) |
|
174 |
if env.conf['vcs'] is 'git': |
|
175 |
run('git pull %s' % env.conf['repos_url']) |
|
176 |
if env.conf['vcs'] is 'hg': |
|
177 |
run('hg pull -u %s' % env.conf['repos_url']) |
|
178 |
if env.conf['vcs'] is 'svn': |
|
179 |
run('svn up %s' % env.conf['repos_url']) |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
180 |
|
181 |
delete_pyc() |
|
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
182 |
reload() |
24.1.1
by Patrick Hetu
first draft of python hooks |
183 |
|
184 |
||
185 |
# Gunicorn
|
|
186 |
@task
|
|
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
187 |
def reload(): |
24.1.43
by Patrick Hetu
improve documentation a bit |
188 |
"""
|
189 |
Reload gunicorn.
|
|
190 |
"""
|
|
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
191 |
sudo('service %s reload' % env.sanitized_service_name) |
24.1.1
by Patrick Hetu
first draft of python hooks |
192 |
|
193 |
||
194 |
# Django
|
|
195 |
@task
|
|
196 |
def manage(command): |
|
24.1.43
by Patrick Hetu
improve documentation a bit |
197 |
""" Runs management commands."""
|
24.1.39
by Patrick Hetu
ajust the fabfile for latest version of juju |
198 |
django_admin_cmd = _find_django_admin_cmd() |
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
199 |
|
200 |
with cd(env.site_path): |
|
62
by Patrick Hetu
get the latest version of charmhelpers |
201 |
with shell_env(PYTHONPATH=':'.join([os.path.join(env.site_path, '../'), env.python_path])): |
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
202 |
sudo('%s %s --settings=%s' % |
203 |
(django_admin_cmd, command, django_settings_modules), |
|
204 |
user=env.conf['wsgi_user']) |
|
205 |
||
24.1.1
by Patrick Hetu
first draft of python hooks |
206 |
|
24.1.45
by Patrick Hetu
sync with the latest gunicorn and memcached charm |
207 |
@task
|
208 |
def load_fixture(fixture_path): |
|
209 |
""" Upload and load a fixture file"""
|
|
210 |
fixture_file = fixture_path.split('/')[-1] |
|
211 |
put(fixture_path, '/tmp/') |
|
212 |
manage('loaddata %s' % os.path.join('/tmp/', fixture_file)) |
|
213 |
run('rm %s' % os.path.join('/tmp/', fixture_file)) |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
214 |
|
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
215 |
|
24.1.1
by Patrick Hetu
first draft of python hooks |
216 |
# Utils
|
217 |
@task
|
|
218 |
def delete_pyc(): |
|
219 |
""" Deletes *.pyc files from project source dir """
|
|
46
by Patrick Hetu
fix fabfile for latest version of juju-core |
220 |
with cd(env.project_dir): |
221 |
sudo("find . -name '*.pyc' -delete", user="www-data") |
|
222 |
reload() |