~patrick-hetu/charms/precise/python-django/ansible

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