7
from subprocess import check_call
9
import lib.openstack_common as openstack
10
import lib.utils as utils
11
import lib.cluster_utils as cluster
12
import swift_utils as swift
21
src = utils.config_get('openstack-origin')
23
openstack.configure_installation_source(src)
24
check_call(['apt-get', 'update'])
25
rel = openstack.get_os_codename_install_source(src)
27
pkgs = swift.determine_packages(rel)
29
utils.install(*extra_pkgs)
31
swift.ensure_swift_dir()
33
# initialize swift configs.
36
'swift_hash': swift.get_swift_hash()
38
with open(swift.SWIFT_CONF, 'w') as conf:
39
conf.write(swift.render_config(swift.SWIFT_CONF, ctxt))
42
swift.write_proxy_config()
45
ctxt = {'proxy_ip': utils.get_host_ip()}
46
with open(swift.MEMCACHED_CONF, 'w') as conf:
47
conf.write(swift.render_config(swift.MEMCACHED_CONF, ctxt))
48
check_call(['service', 'memcached', 'restart'])
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'))
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
swift.configure_https()
66
def keystone_joined(relid=None):
67
if not cluster.eligible_leader(swift.SWIFT_HA_RES):
69
if cluster.is_clustered():
70
hostname = utils.config_get('vip')
72
hostname = utils.unit_get('private-address')
73
port = utils.config_get('bind-port')
78
admin_url = '%s://%s:%s' % (proto, hostname, port)
79
internal_url = public_url = '%s/v1/AUTH_$(tenant_id)s' % admin_url
80
utils.relation_set(service='swift',
81
region=utils.config_get('region'),
82
public_url=public_url, internal_url=internal_url,
84
requested_roles=utils.config_get('operator-roles'),
88
def keystone_changed():
89
swift.write_proxy_config()
90
swift.configure_https()
91
# Re-fire keystone hooks to ripple back the HTTPS service entry
92
for relid in utils.relation_ids('identity-service'):
93
keystone_joined(relid=relid)
97
'''handle doing ring balancing and distribution.'''
99
for ring in swift.SWIFT_RINGS.itervalues():
100
if swift.balance_ring(ring):
101
utils.juju_log('INFO', 'Balanced ring %s' % ring)
106
for ring in swift.SWIFT_RINGS.keys():
107
f = '%s.ring.gz' % ring
108
shutil.copyfile(os.path.join(swift.SWIFT_CONF_DIR, f),
109
os.path.join(swift.WWW_DIR, f))
111
if cluster.eligible_leader(swift.SWIFT_HA_RES):
112
msg = 'Broadcasting notification to all storage nodes that new '\
113
'ring is ready for consumption.'
114
utils.juju_log('INFO', msg)
115
path = swift.WWW_DIR.split('/var/www/')[1]
116
trigger = uuid.uuid4()
117
swift_hash = swift.get_swift_hash()
119
if cluster.is_clustered():
120
hostname = utils.config_get('vip')
122
hostname = utils.unit_get('private-address')
124
rings_url = 'http://%s/%s' % (hostname, path)
125
# notify storage nodes that there is a new ring to fetch.
126
for relid in utils.relation_ids('swift-storage'):
127
utils.relation_set(rid=relid, swift_hash=swift_hash,
128
rings_url=rings_url, trigger=trigger)
130
swift.proxy_control('restart')
133
def storage_changed():
134
zone = swift.get_zone(utils.config_get('zone-assignment'))
136
'ip': utils.get_host_ip(utils.relation_get('private-address')),
138
'account_port': utils.relation_get('account_port'),
139
'object_port': utils.relation_get('object_port'),
140
'container_port': utils.relation_get('container_port'),
142
if None in node_settings.itervalues():
143
utils.juju_log('INFO', 'storage_changed: Relation not ready.')
146
for k in ['zone', 'account_port', 'object_port', 'container_port']:
147
node_settings[k] = int(node_settings[k])
149
# Grant new node access to rings via apache.
150
swift.write_apache_config()
152
# allow for multiple devs per unit, passed along as a : separated list
153
devs = utils.relation_get('device').split(':')
155
node_settings['device'] = dev
156
for ring in swift.SWIFT_RINGS.itervalues():
157
if not swift.exists_in_ring(ring, node_settings):
158
swift.add_to_ring(ring, node_settings)
160
if swift.should_balance([r for r in swift.SWIFT_RINGS.itervalues()]):
164
def storage_broken():
165
swift.write_apache_config()
168
def config_changed():
169
# Determine whether or not we should do an upgrade, based on the
170
# the version offered in keyston-release.
171
src = utils.config_get('openstack-origin')
172
available = openstack.get_os_codename_install_source(src)
173
installed = openstack.get_os_codename_package('python-swift')
175
openstack.get_os_version_codename(available) > \
176
openstack.get_os_version_codename(installed)):
177
pkgs = swift.determine_packages(available)
178
swift.do_openstack_upgrade(src, pkgs)
180
relids = utils.relation_ids('identity-service')
183
keystone_joined(relid)
184
swift.write_proxy_config()
185
swift.configure_https()
188
def cluster_changed():
189
swift.configure_haproxy()
192
def ha_relation_changed():
193
clustered = utils.relation_get('clustered')
194
if clustered and cluster.is_leader(swift.SWIFT_HA_RES):
195
utils.juju_log('INFO',
196
'Cluster configured, notifying other services and'
197
'updating keystone endpoint configuration')
198
# Tell all related services to start using
200
for r_id in utils.relation_ids('identity-service'):
201
keystone_joined(relid=r_id)
204
def ha_relation_joined():
205
# Obtain the config values necessary for the cluster config. These
206
# include multicast port and interface to bind to.
207
corosync_bindiface = utils.config_get('ha-bindiface')
208
corosync_mcastport = utils.config_get('ha-mcastport')
209
vip = utils.config_get('vip')
210
vip_cidr = utils.config_get('vip_cidr')
211
vip_iface = utils.config_get('vip_iface')
213
utils.juju_log('ERROR',
214
'Unable to configure hacluster as vip not provided')
219
'res_swift_vip': 'ocf:heartbeat:IPaddr2',
220
'res_swift_haproxy': 'lsb:haproxy'
223
'res_swift_vip': 'params ip="%s" cidr_netmask="%s" nic="%s"' % \
224
(vip, vip_cidr, vip_iface),
225
'res_swift_haproxy': 'op monitor interval="5s"'
228
'res_swift_haproxy': 'haproxy'
231
'cl_swift_haproxy': 'res_swift_haproxy'
234
utils.relation_set(init_services=init_services,
235
corosync_bindiface=corosync_bindiface,
236
corosync_mcastport=corosync_mcastport,
238
resource_params=resource_params,
244
'config-changed': config_changed,
245
'identity-service-relation-joined': keystone_joined,
246
'identity-service-relation-changed': keystone_changed,
247
'swift-storage-relation-changed': storage_changed,
248
'swift-storage-relation-broken': storage_broken,
249
"cluster-relation-joined": cluster_changed,
250
"cluster-relation-changed": cluster_changed,
251
"ha-relation-joined": ha_relation_joined,
252
"ha-relation-changed": ha_relation_changed
255
utils.do_hooks(hooks)