Add action for running archive-deleted-rows

Add an action for moving stale data to shadow tables using
nova-manage *1. This will speed up other operations such as
map_instances which no longer need to work against stale
data.

*1 https://docs.openstack.org/nova/pike/cli/nova-manage.html

Change-Id: I03f3d641b50cfc6f02262edb0f714ba6e9566775
Partial-Bug: #1742115
This commit is contained in:
Liam Young 2018-01-11 17:27:20 +00:00
parent 0f14eac672
commit edd9b1face
5 changed files with 75 additions and 2 deletions

View File

@ -4,3 +4,10 @@ pause:
description: Pause the nova-cloud-controller unit. This action will stop related services.
resume:
descrpition: Resume the nova-cloud-controller unit. This action will start related services.
archive-data:
descrpition: Run job to archive deleted rows in database
params:
batch-size:
type: integer
default: 10000
description: Archive old data to shadow tables

View File

@ -19,11 +19,16 @@ import sys
sys.path.append('hooks/')
from charmhelpers.core.hookenv import action_fail
from charmhelpers.core.hookenv import (
action_fail,
action_get,
action_set,
)
from nova_cc_utils import (
pause_unit_helper,
resume_unit_helper,
register_configs,
archive_deleted_rows,
)
@ -40,9 +45,20 @@ def resume(args):
resume_unit_helper(register_configs())
def archive_data(args):
"""Run data archival process
@raises Exception should the archival fail"""
action_set({
'archive-deleted-rows': archive_deleted_rows(
max_rows=action_get('batch-size'))})
# A dictionary of all the defined actions to callables (which take
# parsed arguments).
ACTIONS = {"pause": pause, "resume": resume}
ACTIONS = {
"pause": pause,
"resume": resume,
"archive-data": archive_data}
def main(args):

1
actions/archive-data Symbolic link
View File

@ -0,0 +1 @@
actions.py

View File

@ -775,6 +775,24 @@ def map_instances():
raise
def archive_deleted_rows(max_rows=None):
log('Archiving deleted rows', level=INFO)
cmd = ['nova-manage', 'db', 'archive_deleted_rows', '--verbose']
if max_rows:
cmd.extend(['--max_rows', str(max_rows)])
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
exit_code = process.wait()
if exit_code not in [0, 1]:
msg = 'Archiving deleted rows failed\nstdout: {}\nstderr: {}'.format(
stdout,
stderr)
log(msg, level=ERROR)
raise Exception(msg)
else:
return stdout
def add_hosts_to_cell():
'''Map compute hosts to cell'''
log('Cell1 discover_hosts', level=INFO)

View File

@ -1033,6 +1033,37 @@ class NovaCCUtilsTests(CharmTestCase):
'map_instances', '--cell_uuid',
cell_uuid])
@patch('subprocess.Popen')
def test_archive_deleted_rows(self, mock_popen):
process_mock = MagicMock()
attrs = {
'communicate.return_value': ('output', 'error'),
'wait.return_value': 0}
process_mock.configure_mock(**attrs)
mock_popen.return_value = process_mock
expectd_calls = [
call([
'nova-manage',
'db',
'archive_deleted_rows',
'--verbose'], stdout=-1),
call().communicate(),
call().wait()]
utils.archive_deleted_rows()
self.assertEqual(mock_popen.mock_calls, expectd_calls)
@patch('subprocess.Popen')
def test_archive_deleted_rows_excpetion(self, mock_popen):
process_mock = MagicMock()
attrs = {
'communicate.return_value': ('output', 'error'),
'wait.return_value': 123}
process_mock.configure_mock(**attrs)
mock_popen.return_value = process_mock
with self.assertRaises(Exception):
utils.archive_deleted_rows()
@patch.object(utils, 'get_cell_uuid')
@patch('subprocess.check_output')
def test_add_hosts_to_cell(self, mock_check_output, mock_get_cell_uuid):