Skip to content

Commit

Permalink
Stop cassandra during configuration and volume migration
Browse files Browse the repository at this point in the history
The cassandra service is left running after installation.
The next operation(s) are to rewrite the configuration, and
migrate the data onto a volume (if provided). It is not a
good thing for the database to be running during the latter,
and a restart is required after the former.

Failing to stop the database during the data migration can
result in an rsync error 24 because files that were present
when rsync made its list may be missing by the time rsync
gets around to trying to sync that file. This can lead rsync
to not make a 'true' copy of the source on the destination.

The only way around this is to stop the database, something
that is already done by both MongoDB and MySQL in their
guest agents.

Change-Id: I74ecc5c12d43eccc6295488e344bc0e75fe8116d
Closes-bug: #1338660
  • Loading branch information
Amrith Kumar committed Jul 11, 2014
1 parent 7e170cc commit e527ad8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 17 deletions.
44 changes: 28 additions & 16 deletions trove/guestagent/datastore/cassandra/manager.py
Expand Up @@ -66,22 +66,34 @@ def prepare(self, context, packages, databases, memory_mb, users,
LOG.info("Installing cassandra")
self.app.install_if_needed(packages)
self.app.init_storage_structure(mount_point)
if config_contents:
LOG.info(_("Config processing"))
self.app.write_config(config_contents)
self.app.make_host_reachable()
if device_path:
device = volume.VolumeDevice(device_path)
# unmount if device is already mounted
device.unmount_device(device_path)
device.format()
if os.path.exists(mount_point):
#rsync exiting data
device.migrate_data(mount_point)
#mount the volume
device.mount(mount_point)
LOG.debug("Mounting new volume.")
self.app.restart()

if config_contents or device_path:
# Stop the db while we configure
# FIXME(amrith) Once the cassandra bug
# https://issues.apache.org/jira/browse/CASSANDRA-2356
# is fixed, this code may have to be revisited.
LOG.debug("Stopping database prior to changes.")
self.app.stop_db()

if config_contents:
LOG.debug("Processing configuration.")
self.app.write_config(config_contents)
self.app.make_host_reachable()

if device_path:
device = volume.VolumeDevice(device_path)
# unmount if device is already mounted
device.unmount_device(device_path)
device.format()
if os.path.exists(mount_point):
#rsync exiting data
device.migrate_data(mount_point)
#mount the volume
device.mount(mount_point)
LOG.debug("Mounting new volume.")

LOG.debug("Restarting database after changes.")
self.app.start_db()

self.appStatus.end_install_or_restart()
LOG.info(_('"prepare" call has finished.'))
Expand Down
5 changes: 4 additions & 1 deletion trove/tests/unittests/guestagent/test_cassandra_manager.py
Expand Up @@ -115,6 +115,8 @@ def _prepare_dynamic(self, packages,
mock_app.write_config = MagicMock(return_value=None)
mock_app.make_host_reachable = MagicMock(return_value=None)
mock_app.restart = MagicMock(return_value=None)
mock_app.start_db = MagicMock(return_value=None)
mock_app.stop_db = MagicMock(return_value=None)
os.path.exists = MagicMock(return_value=True)
volume.VolumeDevice.format = MagicMock(return_value=None)
volume.VolumeDevice.migrate_data = MagicMock(return_value=None)
Expand All @@ -136,4 +138,5 @@ def _prepare_dynamic(self, packages,
mock_app.install_if_needed.assert_any_call(packages)
mock_app.init_storage_structure.assert_any_call('/var/lib/cassandra')
mock_app.make_host_reachable.assert_any_call()
mock_app.restart.assert_any_call()
mock_app.start_db.assert_any_call()
mock_app.stop_db.assert_any_call()

0 comments on commit e527ad8

Please sign in to comment.