~chad.smith/charms/precise/keystone/ha-support

« back to all changes in this revision

Viewing changes to hooks/keystone-hooks

  • Committer: James Page
  • Date: 2013-02-07 09:22:36 UTC
  • mfrom: (48.2.3 keystone)
  • Revision ID: james.page@canonical.com-20130207092236-iafw325uig9kpvtw
Adds better support for service leaders.

* The service leader is determined depending on how keystone is currently clustered. If there are multiple units, but no hacluster subordinate, the oldest service unit is elected leader (lowest unit number). If hacluster exists and the service is clustered, the CRM is consulted and the node hosting the resources is designated the leader.

* Only the leader may initialize or touch the database (create users, endpoints, etc)

* The leader is responsible for synchronizing a list of service credentials to all peers. The list is stored on disk and resolves the issue of the passwd dump files in /var/lib/keystone/ being out-of-sync among peers.

We can use the same approach in the rabbitmq-server charm if it works out here.

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
                        driver='keystone.token.backends.sql.Token')
78
78
    update_config_block('ec2',
79
79
                        driver='keystone.contrib.ec2.backends.sql.Ec2')
 
80
 
80
81
    execute("service keystone stop", echo=True)
81
82
    execute("keystone-manage db_sync")
82
83
    execute("service keystone start", echo=True)
83
84
    time.sleep(5)
84
85
    ensure_initial_admin(config)
85
86
 
 
87
 
86
88
def db_joined():
87
89
    relation_data = { "database": config["database"],
88
90
                      "username": config["database-user"],
100
102
                             relation_data["password"],
101
103
                             relation_data["private-address"],
102
104
                             config["database"]))
 
105
 
103
106
    execute("service keystone stop", echo=True)
 
107
 
 
108
    if not eligible_leader():
 
109
        juju_log('Deferring DB initialization to service leader.')
 
110
        execute("service keystone start")
 
111
        return
 
112
 
104
113
    execute("keystone-manage db_sync", echo=True)
105
114
    execute("service keystone start")
106
115
    time.sleep(5)
141
150
                                 adminurl=adminurl,
142
151
                                 internalurl=internalurl)
143
152
 
144
 
    if is_clustered() and not is_leader():
145
 
        # Only respond if service unit is the leader
 
153
    if not eligible_leader():
 
154
        juju_log('Deferring identity_changed() to service leader.')
146
155
        return
147
156
 
148
157
    settings = relation_get_dict(relation_id=relation_id,
221
230
    token = get_admin_token()
222
231
    juju_log("Creating service credentials for '%s'" % service_username)
223
232
 
224
 
    # TODO: This needs to be changed as it won't work with ha keystone
225
 
    stored_passwd = '/var/lib/keystone/%s.passwd' % service_username
226
 
    if os.path.isfile(stored_passwd):
227
 
        juju_log("Loading stored service passwd from %s" % stored_passwd)
228
 
        service_password = open(stored_passwd, 'r').readline().strip('\n')
229
 
    else:
230
 
        juju_log("Generating a new service password for %s" % service_username)
231
 
        service_password = execute('pwgen -c 32 1', die=True)[0].strip()
232
 
        open(stored_passwd, 'w+').writelines("%s\n" % service_password)
233
 
 
 
233
    service_password = get_service_password(service_username)
234
234
    create_user(service_username, service_password, config['service-tenant'])
235
235
    grant_role(service_username, config['admin-role'], config['service-tenant'])
236
236
 
258
258
        relation_data["service_port"] = SERVICE_PORTS['keystone_service']
259
259
 
260
260
    relation_set(relation_data)
 
261
    synchronize_service_credentials()
261
262
 
262
263
def config_changed():
263
264
 
272
273
 
273
274
    set_admin_token(config['admin-token'])
274
275
 
275
 
    if is_clustered() and is_leader():
 
276
    if eligible_leader():
276
277
        juju_log('Cluster leader - ensuring endpoint configuration is up to date')
277
278
        ensure_initial_admin(config)
278
 
    elif not is_clustered():
279
 
        ensure_initial_admin(config)
280
279
 
281
280
    update_config_block('logger_root', level=config['log-level'],
282
281
                        file='/etc/keystone/logging.conf')
290
289
 
291
290
def upgrade_charm():
292
291
    cluster_changed()
293
 
    if is_clustered() and is_leader():
 
292
    if eligible_leader():
294
293
        juju_log('Cluster leader - ensuring endpoint configuration is up to date')
295
294
        ensure_initial_admin(config)
296
 
    elif not is_clustered():
297
 
        ensure_initial_admin(config)
298
295
 
299
296
 
300
297
SERVICE_PORTS = {
314
311
    configure_haproxy(cluster_hosts,
315
312
                      SERVICE_PORTS)
316
313
 
 
314
    synchronize_service_credentials()
 
315
 
317
316
 
318
317
def ha_relation_changed():
319
318
    relation_data = relation_get_dict()
391
390
 
392
391
# keystone-hooks gets called by symlink corresponding to the requested relation
393
392
# hook.
394
 
arg0 = sys.argv[0].split("/").pop()
395
 
if arg0 not in hooks.keys():
396
 
    error_out("Unsupported hook: %s" % arg0)
397
 
hooks[arg0]()
 
393
hook = os.path.basename(sys.argv[0])
 
394
if hook not in hooks.keys():
 
395
    error_out("Unsupported hook: %s" % hook)
 
396
hooks[hook]()