~gandelman-a/charms/precise/swift-proxy/lp1202773

« back to all changes in this revision

Viewing changes to hooks/swift-hooks.py

  • Committer: James Page
  • Date: 2013-02-27 16:18:34 UTC
  • mto: (35.1.7 swift-proxy)
  • mto: This revision was merged to the branch mainline in revision 41.
  • Revision ID: james.page@canonical.com-20130227161834-vpcr5gwiye8gugbs
Fixup missing files

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
 
3
 
import os
4
 
import utils
5
 
import sys
6
 
import shutil
7
 
import uuid
8
 
from subprocess import check_call
9
 
 
10
 
import lib.openstack_common as openstack
11
 
import swift_utils as swift
12
 
 
13
 
extra_pkgs = [
14
 
    "haproxy",
15
 
    "python-jinja2"
16
 
    ]
17
 
 
18
 
def install():
19
 
    src = utils.config_get('openstack-origin')
20
 
    if src != 'distro':
21
 
        openstack.configure_installation_source(src)
22
 
    check_call(['apt-get', 'update'])
23
 
    rel = openstack.get_os_codename_install_source(src)
24
 
 
25
 
    pkgs = swift.determine_packages(rel)
26
 
    utils.install(*pkgs)
27
 
    utils.install(*extra_pkgs)
28
 
 
29
 
    swift.ensure_swift_dir()
30
 
 
31
 
    # initialize swift configs.
32
 
    # swift.conf hash
33
 
    ctxt = {
34
 
        'swift_hash': swift.get_swift_hash()
35
 
    }
36
 
    with open(swift.SWIFT_CONF, 'w') as conf:
37
 
        conf.write(swift.render_config(swift.SWIFT_CONF, ctxt))
38
 
 
39
 
    # swift-proxy.conf
40
 
    swift.write_proxy_config()
41
 
 
42
 
    # memcached.conf
43
 
    ctxt = { 'proxy_ip': utils.get_host_ip() }
44
 
    with open(swift.MEMCACHED_CONF, 'w') as conf:
45
 
        conf.write(swift.render_config(swift.MEMCACHED_CONF, ctxt))
46
 
 
47
 
    # generate or setup SSL certificate
48
 
    swift.configure_ssl()
49
 
 
50
 
    # initialize new storage rings.
51
 
    for ring in swift.SWIFT_RINGS.iteritems():
52
 
        swift.initialize_ring(ring[1],
53
 
                              utils.config_get('partition-power'),
54
 
                              utils.config_get('replicas'),
55
 
                              utils.config_get('min-hours'))
56
 
 
57
 
    # configure a directory on webserver for distributing rings.
58
 
    if not os.path.isdir(swift.WWW_DIR):
59
 
        os.mkdir(swift.WWW_DIR, 0755)
60
 
    uid, gid = swift.swift_user()
61
 
    os.chown(swift.WWW_DIR, uid, gid)
62
 
    swift.write_apache_config()
63
 
 
64
 
 
65
 
def keystone_joined(relid=None):
66
 
    if is_clustered():
67
 
        hostname = utils.config_get('vip')
68
 
    else:
69
 
        hostname = utils.unit_get('private-address')
70
 
    port = utils.config_get('bind-port')
71
 
    ssl = utils.config_get('use-https')
72
 
    if ssl == 'yes':
73
 
        proto = 'https'
74
 
    else:
75
 
        proto = 'http'
76
 
    admin_url = '%s://%s:%s' % (proto, hostname, port)
77
 
    internal_url = public_url = '%s/v1/AUTH_$(tenant_id)s' % admin_url
78
 
    utils.relation_set(service='swift',
79
 
                       region=utils.config_get('region'),
80
 
                       public_url=public_url, internal_url=internal_url,
81
 
                       admin_url=admin_url,
82
 
                       requested_roles=utils.config_get('operator-roles'),
83
 
                       rid=relid)
84
 
 
85
 
 
86
 
def keystone_changed():
87
 
    swift.write_proxy_config()
88
 
 
89
 
 
90
 
def balance_rings():
91
 
    '''handle doing ring balancing and distribution.'''
92
 
    new_ring = False
93
 
    for ring in swift.SWIFT_RINGS.itervalues():
94
 
        if swift.balance_ring(ring):
95
 
            utils.juju_log('INFO', 'Balanced ring %s' % ring)
96
 
            new_ring = True
97
 
    if not new_ring:
98
 
        return
99
 
 
100
 
    for ring in swift.SWIFT_RINGS.keys():
101
 
        f = '%s.ring.gz' % ring
102
 
        shutil.copyfile(os.path.join(swift.SWIFT_CONF_DIR, f),
103
 
                        os.path.join(swift.WWW_DIR, f))
104
 
 
105
 
    if eligible_leader():
106
 
      msg = 'Broadcasting notification to all storage nodes that new '\
107
 
            'ring is ready for consumption.'
108
 
      utils.juju_log('INFO', msg)
109
 
      www_dir = swift.WWW_DIR.split('/var/www/')[1]
110
 
      trigger = uuid.uuid4()
111
 
      swift_hash = swift.get_swift_hash()
112
 
      # notify storage nodes that there is a new ring to fetch.
113
 
      for relid in utils.relation_ids('swift-storage'):
114
 
          utils.relation_set(rid=relid, swift_hash=swift_hash,
115
 
                             www_dir=www_dir, trigger=trigger)
116
 
 
117
 
    swift.proxy_control('restart')
118
 
 
119
 
def storage_changed():
120
 
    account_port = utils.config_get('account-ring-port')
121
 
    object_port = utils.config_get('object-ring-port')
122
 
    container_port = utils.config_get('container-ring-port')
123
 
    zone = swift.get_zone(utils.config_get('zone-assignment'))
124
 
    node_settings = {
125
 
        'ip': utils.get_host_ip(utils.relation_get('private-address')),
126
 
        'zone': zone,
127
 
        'account_port': utils.relation_get('account_port'),
128
 
        'object_port': utils.relation_get('object_port'),
129
 
        'container_port': utils.relation_get('container_port'),
130
 
    }
131
 
    if None in node_settings.itervalues():
132
 
        utils.juju_log('INFO', 'storage_changed: Relation not ready.')
133
 
        return None
134
 
 
135
 
    for k in ['zone', 'account_port', 'object_port', 'container_port']:
136
 
        node_settings[k] = int(node_settings[k])
137
 
 
138
 
    # Grant new node access to rings via apache.
139
 
    swift.write_apache_config()
140
 
 
141
 
    # allow for multiple devs per unit, passed along as a : separated list
142
 
    devs = utils.relation_get('device').split(':')
143
 
    for dev in devs:
144
 
        node_settings['device'] = dev
145
 
        for ring in swift.SWIFT_RINGS.itervalues():
146
 
            if not swift.exists_in_ring(ring, node_settings):
147
 
                swift.add_to_ring(ring, node_settings)
148
 
 
149
 
    if swift.should_balance([r for r in swift.SWIFT_RINGS.itervalues()]):
150
 
        balance_rings()
151
 
 
152
 
def storage_broken():
153
 
    swift.write_apache_config()
154
 
 
155
 
def config_changed():
156
 
    relids = utils.relation_ids('identity-service')
157
 
    if relids:
158
 
        for relid in relids:
159
 
            keystone_joined(relid)
160
 
    swift.write_proxy_config()
161
 
    cluster_changed()
162
 
 
163
 
 
164
 
SERVICE_PORTS = {
165
 
    "swift": [
166
 
        utils.config_get('bind-port'),
167
 
        int(utils.config_get('bind-port')) - 10
168
 
        ]
169
 
    }
170
 
 
171
 
def cluster_changed():
172
 
    cluster_hosts = {}
173
 
    cluster_hosts[os.getenv('JUJU_UNIT_NAME').replace('/','-')] = \
174
 
        utils.util_get('private-address')
175
 
    for r_id in relation_ids('cluster'):
176
 
        for unit in relation_list(r_id):
177
 
            cluster_hosts[unit.replace('/','-')] = \
178
 
                utils.relation_get(attribute='private-address',
179
 
                                   rid=r_id,
180
 
                                   unit=unit)
181
 
    configure_haproxy(cluster_hosts,
182
 
                      SERVICE_PORTS)
183
 
    utils.restart('haproxy')
184
 
 
185
 
 
186
 
def ha_relation_changed():
187
 
    clustered = utils.relation_get('clustered')
188
 
    if clustered and is_leader():
189
 
        juju_log('Cluster configured, notifying other services and updating'
190
 
                 'keystone endpoint configuration')
191
 
        # Tell all related services to start using
192
 
        # the VIP and haproxy ports instead
193
 
        for r_id in relation_ids('identity-service'):
194
 
            keystone_joined(relid=r_id)
195
 
 
196
 
 
197
 
def ha_relation_joined():
198
 
    # Obtain the config values necessary for the cluster config. These
199
 
    # include multicast port and interface to bind to.
200
 
    corosync_bindiface = utils.config_get('ha-bindiface')
201
 
    corosync_mcastport = utils.config_get('ha-mcastport')
202
 
    vip = utils.config_get('vip')
203
 
    vip_cidr = utils.config_get('vip_cidr')
204
 
    vip_iface = utils.config_get('vip_iface')
205
 
    if not vip:
206
 
        utils.juju_log('ERROR',
207
 
                       'Unable to configure hacluster as vip not provided')
208
 
        sys.exit(1)
209
 
 
210
 
    # Obtain resources
211
 
    resources = {
212
 
            'res_swift_vip': 'ocf:heartbeat:IPaddr2',
213
 
            'res_swift_haproxy': 'lsb:haproxy'
214
 
        }
215
 
    resource_params = {
216
 
            'res_swift_vip': 'params ip="%s" cidr_netmask="%s" nic="%s"' % \
217
 
                              (vip, vip_cidr, vip_iface),
218
 
            'res_swift_haproxy': 'op monitor interval="5s"'
219
 
        }
220
 
    init_services = {
221
 
            'res_swift_haproxy': 'haproxy'
222
 
        }
223
 
    clones = {
224
 
            'cl_swift_haproxy': 'res_swift_haproxy'
225
 
        }
226
 
 
227
 
    utils.relation_set(init_services=init_services,
228
 
                       corosync_bindiface=corosync_bindiface,
229
 
                       corosync_mcastport=corosync_mcastport,
230
 
                       resources=resources,
231
 
                       resource_params=resource_params,
232
 
                       clones=clones)
233
 
 
234
 
 
235
 
hooks = {
236
 
    'install': install,
237
 
    'config-changed': config_changed,
238
 
    'identity-service-relation-joined': keystone_joined,
239
 
    'identity-service-relation-changed': keystone_changed,
240
 
    'swift-storage-relation-changed': storage_changed,
241
 
    'swift-storage-relation-broken': storage_broken,
242
 
    "cluster-relation-joined": cluster_changed,
243
 
    "cluster-relation-changed": cluster_changed,
244
 
    "ha-relation-joined": ha_relation_joined,
245
 
    "ha-relation-changed": ha_relation_changed
246
 
}
247
 
 
248
 
utils.do_hooks(hooks)
249
 
 
250
 
sys.exit(0)