~george-edison55/charms/precise/uwsgi/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env python

import json
import os
import sys

from charmhelpers import fetch
from charmhelpers.core import hookenv
from charmhelpers.core import host

hooks = hookenv.Hooks()

#####################
# UTILITY FUNCTIONS #
#####################

UWSGI_CONFIG_DIR = '/etc/uwsgi/apps-enabled'

def get_app_filename(app=None):
    """Return the absolute filename for an app."""
    if app is None:
        app = '%s.json' % hookenv.remote_unit().split('/')[0]
    return os.path.join(UWSGI_CONFIG_DIR, app)

# Translates data coming from the WSGI relation to
# configuration settings that uWSGI understands.
UWSGI_CONFIG_MAP = {
    'python_path':    'python-path',
    'working_dir':    'chdir',
    'wsgi_group':     'gid',
    'wsgi_timeout':   'harakiri',
    'wsgi_user':      'uid',
    'wsgi_wsgi_file': 'wsgi',
}

def get_unit_app_config():
    """Return the unit config settings."""
    config = hookenv.config()
    return {
        'processes': config['uwsgi_processes'],
        'threads':   config['uwsgi_threads'],
    }

def get_relation_app_config():
    """Return the config settings provided by the relation."""
    relation = hookenv.relation_get()
    config = {
        'http-socket': '%s:%s' % (
            relation.get('listen_ip', '0.0.0.0'),
            relation.get('port', 8080),
        ),
    }
    for key, value in relation.items():
        if key in UWSGI_CONFIG_MAP:
            config[UWSGI_CONFIG_MAP[key]] = value
    return config

def update_uwsgi_app(app, new_config):
    """Update an app with new config values."""
    try:
        with open(get_app_filename(app), 'r') as f:
            config = json.loads(f.read())
            config['uwsgi']
    except (IOError, KeyError, ValueError,):
        config = {'uwsgi': {},}
    config['uwsgi'].update(new_config)
    with open(get_app_filename(app), 'w') as f:
        f.write(json.dumps(config))

def update_all_uwsgi_apps():
    """Write the updated config to all uWSGI apps."""
    for app in os.listdir(UWSGI_CONFIG_DIR):
        if app.endswith('.json'):
            update_uwsgi_app(app, get_unit_app_config())

##################
# HOOK FUNCTIONS #
##################

@hooks.hook('install', 'upgrade-charm')
def install():
    """Install or upgrade the charm."""
    fetch.apt_update()
    fetch.apt_install(['uwsgi', 'uwsgi-plugin-python',])

@hooks.hook('config-changed')
def config_changed():
    """Update all configuration files."""
    update_all_uwsgi_apps()
    host.service_restart('uwsgi')

@hooks.hook('wsgi-file-relation-changed')
def wsgi_file_relation_changed():
    """Update the app configuration."""
    update_uwsgi_app(get_app_filename(), get_relation_app_config())
    update_all_uwsgi_apps()
    host.service_restart('uwsgi')
    
if __name__ == "__main__":
    hooks.execute(sys.argv)