Merge lp:~wesmason/charms/precise/mongodb/add-storage-subordinate-support into lp:charms/mongodb

Proposed by Wes Mason
Status: Merged
Merged at revision: 49
Proposed branch: lp:~wesmason/charms/precise/mongodb/add-storage-subordinate-support
Merge into: lp:charms/mongodb
Diff against target: 206 lines (+98/-4)
4 files modified
README.md (+18/-2)
config.yaml (+4/-1)
hooks/hooks.py (+72/-1)
metadata.yaml (+4/-0)
To merge this branch: bzr merge lp:~wesmason/charms/precise/mongodb/add-storage-subordinate-support
Reviewer Review Type Date Requested Status
Stuart Bishop (community) Approve
Review via email: mp+223539@code.launchpad.net

Description of the change

This adds support for the storage subordinate as a way to automatically handle attaching/mounting volumes from both OpenStack and AWS EBS, by using the data- relation hooks to setup a /srv/juju/mongodb-data mount which is then used by the existing volume management code to symlink in place and rsync any existing MongoDB data over, similar to the way the postgres charm works with the subordinate.

We need this internally to support automated Mongo-on-persistent-volume deploys with juju-deployer.

To post a comment you must log in.
Revision history for this message
Wes Mason (wesmason) wrote :

Bug 1206468 is related to this.

Revision history for this message
Stuart Bishop (stub) wrote :

This all seems good to me.

The charm could be tidied up with support of charmhelpers, eg. using @hooks.hook instead of the if/then statement to invoke the correct hook handler. But that is unrelated to this branch, which is nicely contained and doesn't want the scope creep.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'README.md'
--- README.md 2014-02-19 15:47:55 +0000
+++ README.md 2014-06-18 11:23:00 +0000
@@ -164,10 +164,26 @@
164- `run sh.status()`164- `run sh.status()`
165You should see your the hosts for your shards in the status output.165You should see your the hosts for your shards in the status output.
166166
167### Use the storage subordinate to store mongodb data on a permanent OpenStack or Amazon EBS volume
168
169The [storage](http://manage.jujucharms.com/charms/precise/storage) subordinate and [block-storage-broker](http://manage.jujucharms.com/charms/precise/block-storage-broker) service can automatically handle attaching the volume and mounting it to the unit before MongoDB is setup to use it.
170
171For example if you've created the volumes `vol-id-00001` and `vol-id-00002` and want to attach them to your 2 mongo units, with your OpenStack or AWS credentials in a `credential.yaml` file:
172
173 juju deploy block-storage-broker --config credentials.yaml
174 juju deploy storage
175 juju add-relation block-storage-broker storage
176 juju set storage provider=block-storage-broker
177 juju set volume_map="{mongodb/0: vol-id-00001, mongodb/1: vol-id-00002}"
178 juju add-relation storage mongodb
179
180
181### Use a permanent Openstack volume to store mongodb data. (DEPRECATED)
182
183**Note**: Although these steps will still work they are now deprecated, you should use the storage subordinate above instead.
184
167To deploy mongodb using permanent volume on Openstack, the permanent volume should be attached to the mongodb unit just after the deployment, then the configuration should be updated like follows.185To deploy mongodb using permanent volume on Openstack, the permanent volume should be attached to the mongodb unit just after the deployment, then the configuration should be updated like follows.
168186
169### Use a permanent Openstack volume to store mongodb data.
170
171 juju set mongodb volume-dev-regexp="/dev/vdc" volume-map='{"mongodb/0": "vol-id-00000000000000"}' volume-ephemeral-storage=false187 juju set mongodb volume-dev-regexp="/dev/vdc" volume-map='{"mongodb/0": "vol-id-00000000000000"}' volume-ephemeral-storage=false
172188
173### Backups189### Backups
174190
=== modified file 'config.yaml'
--- config.yaml 2014-04-11 21:00:49 +0000
+++ config.yaml 2014-06-18 11:23:00 +0000
@@ -168,7 +168,7 @@
168 type: int168 type: int
169 description: "Number of backups to keep. Keeps one week's worth by default."169 description: "Number of backups to keep. Keeps one week's worth by default."
170 #------------------------------------------------------------------------170 #------------------------------------------------------------------------
171 # Volume management171 # Legacy volume management (DEPRECATED)
172 # volume-map, volume-dev_regexp are only used 172 # volume-map, volume-dev_regexp are only used
173 # if volume-ephemeral-storage == False173 # if volume-ephemeral-storage == False
174 #------------------------------------------------------------------------174 #------------------------------------------------------------------------
@@ -176,6 +176,7 @@
176 type: boolean176 type: boolean
177 default: true177 default: true
178 description: >178 description: >
179 Deprecated, use the storage subordinate.
179 If false, a configure-error state will be raised if180 If false, a configure-error state will be raised if
180 volume-map[$JUJU_UNIT_NAME] is not set (see "volume-map"181 volume-map[$JUJU_UNIT_NAME] is not set (see "volume-map"
181 below) - see "volume-map" below.182 below) - see "volume-map" below.
@@ -187,6 +188,7 @@
187 type: string188 type: string
188 default: ""189 default: ""
189 description: >190 description: >
191 Deprecated, use the storage subordinate.
190 YAML map as e.g. "{ mongodb/0: vol-0000010, mongodb/1: vol-0000016 }".192 YAML map as e.g. "{ mongodb/0: vol-0000010, mongodb/1: vol-0000016 }".
191 Service units will raise a "configure-error" condition if no volume-map193 Service units will raise a "configure-error" condition if no volume-map
192 value is set for it - it expects a human to set it properly to resolve it.194 value is set for it - it expects a human to set it properly to resolve it.
@@ -194,6 +196,7 @@
194 type: string196 type: string
195 default: "/dev/vd[b-z]"197 default: "/dev/vd[b-z]"
196 description: >198 description: >
199 Deprecated, use the storage subordinate.
197 Block device for attached volumes as seen by the VM, will be "scanned"200 Block device for attached volumes as seen by the VM, will be "scanned"
198 for an unused device when "volume-map" is valid for the unit.201 for an unused device when "volume-map" is valid for the unit.
199 source:202 source:
200203
=== added symlink 'hooks/data-relation-changed'
=== target is u'hooks.py'
=== added symlink 'hooks/data-relation-departed'
=== target is u'hooks.py'
=== added symlink 'hooks/data-relation-joined'
=== target is u'hooks.py'
=== modified file 'hooks/hooks.py'
--- hooks/hooks.py 2014-04-11 21:00:49 +0000
+++ hooks/hooks.py 2014-06-18 11:23:00 +0000
@@ -212,6 +212,20 @@
212 return(relation_data)212 return(relation_data)
213213
214214
215def relation_ids(relation_name=None):
216 juju_log("relation_ids: relation_name: %s" % relation_name)
217 try:
218 relation_cmd_line = ['relation-ids', '--format=json']
219 if relation_name is not None:
220 relation_cmd_line.append(relation_name)
221 relation_data = json.loads(subprocess.check_output(relation_cmd_line))
222 except Exception, e:
223 juju_log(str(e))
224 relation_data = None
225 finally:
226 juju_log("relation_ids %s returns: %s" % (relation_name, relation_data))
227 return(relation_data)
228
215#------------------------------------------------------------------------------229#------------------------------------------------------------------------------
216# open_port: Convenience function to open a port in juju to230# open_port: Convenience function to open a port in juju to
217# expose a service231# expose a service
@@ -930,7 +944,7 @@
930 "'volume-ephemeral-storage' and 'volume-map'")944 "'volume-ephemeral-storage' and 'volume-map'")
931 sys.exit(1)945 sys.exit(1)
932 if volume_is_permanent(volid):946 if volume_is_permanent(volid):
933 ## config_changed_volume_apply will stop the service if it founds947 ## config_changed_volume_apply will stop the service if it finds
934 ## it necessary, ie: new volume setup948 ## it necessary, ie: new volume setup
935 if config_changed_volume_apply():949 if config_changed_volume_apply():
936 start_hook()950 start_hook()
@@ -1159,6 +1173,30 @@
1159 return(True)1173 return(True)
11601174
11611175
1176def data_relation_joined():
1177 juju_log("data_relation_joined")
1178
1179 return(relation_set(
1180 {
1181 'mountpoint': '/srv/juju/mongodb-data'
1182 }))
1183
1184
1185def data_relation_changed():
1186 juju_log("data_relation_changed")
1187
1188 if volume_get_id_for_storage_subordinate() is None:
1189 juju_log("mountpoint from storage subordinate not ready, let's wait")
1190 return(True)
1191
1192 return(config_changed())
1193
1194
1195def data_relation_departed():
1196 juju_log("data_relation_departed")
1197 return(config_changed())
1198
1199
1162def configsvr_relation_joined():1200def configsvr_relation_joined():
1163 juju_log("configsvr_relation_joined")1201 juju_log("configsvr_relation_joined")
1164 my_hostname = unit_get('public-address')1202 my_hostname = unit_get('public-address')
@@ -1312,10 +1350,37 @@
1312 return None1350 return None
13131351
13141352
1353#------------------------------
1354# Returns a stub volume id based on the mountpoint from the storage
1355# subordinate relation, if present.
1356#
1357# @return volid eg vol-000012345
1358#------------------------------
1359def volume_get_id_for_storage_subordinate():
1360 # storage charm is a subordinate so we should only ever have one
1361 # relation_id for the data relation
1362 ids = relation_ids('data')
1363 if len(ids) > 0:
1364 mountpoint = relation_get('mountpoint',
1365 os.environ['JUJU_UNIT_NAME'],
1366 ids[0])
1367
1368 juju_log('mountpoint: %s' % (mountpoint,))
1369 if mountpoint and os.path.exists(mountpoint):
1370 return mountpoint.split('/')[-1]
1371
1372
1373
1315# Do we have a valid storage state?1374# Do we have a valid storage state?
1316# @returns volid1375# @returns volid
1317# None config state is invalid - we should not serve1376# None config state is invalid - we should not serve
1318def volume_get_volume_id():1377def volume_get_volume_id():
1378
1379
1380 volid = volume_get_id_for_storage_subordinate()
1381 if volid:
1382 return volid
1383
1319 config_data = config_get()1384 config_data = config_get()
1320 ephemeral_storage = config_data['volume-ephemeral-storage']1385 ephemeral_storage = config_data['volume-ephemeral-storage']
1321 volid = volume_get_volid_from_volume_map()1386 volid = volume_get_volid_from_volume_map()
@@ -1520,6 +1585,12 @@
1520 retVal = mongos_relation_changed()1585 retVal = mongos_relation_changed()
1521 elif hook_name == "mongos-relation-broken":1586 elif hook_name == "mongos-relation-broken":
1522 retVal = mongos_relation_broken()1587 retVal = mongos_relation_broken()
1588 elif hook_name == "data-relation-joined":
1589 retVal = data_relation_joined()
1590 elif hook_name == "data-relation-changed":
1591 retVal = data_relation_changed()
1592 elif hook_name == "data-relation-departed":
1593 retVal = data_relation_departed()
1523 else:1594 else:
1524 print "Unknown hook"1595 print "Unknown hook"
1525 retVal = False1596 retVal = False
15261597
=== modified file 'metadata.yaml'
--- metadata.yaml 2014-01-09 20:41:59 +0000
+++ metadata.yaml 2014-06-18 11:23:00 +0000
@@ -22,6 +22,10 @@
22 interface: mongodb22 interface: mongodb
23 configsvr:23 configsvr:
24 interface: shard24 interface: shard
25 data:
26 interface: block-storage
27 scope: container
28 optional: true
25requires:29requires:
26 mongos-cfg:30 mongos-cfg:
27 interface: shard31 interface: shard

Subscribers

People subscribed via source and target branches