Merge "Add granularity option to purge_deleted"

This commit is contained in:
Jenkins 2013-10-21 18:14:22 +00:00 committed by Gerrit Code Review
commit daa8d6c216
4 changed files with 73 additions and 17 deletions

View File

@ -48,7 +48,7 @@ def purge_deleted():
"""
Remove database records that have been previously soft deleted
"""
utils.purge_deleted(CONF.command.age)
utils.purge_deleted(CONF.command.age, CONF.command.granularity)
def add_command_parsers(subparsers):
@ -62,8 +62,12 @@ def add_command_parsers(subparsers):
parser = subparsers.add_parser('purge_deleted')
parser.set_defaults(func=purge_deleted)
parser.add_argument('age', nargs='?',
help=_('Number of days to preserve.'))
parser.add_argument('age', nargs='?', default='90',
help=_('How long to preserve deleted data.'))
parser.add_argument(
'-g', '--granularity', default='days',
choices=['days', 'hours', 'minutes', 'seconds'],
help=_('Granularity to use for age argument, defaults to days.'))
command_opt = cfg.SubCommandOpt('command',
title='Commands',

View File

@ -471,18 +471,26 @@ def watch_data_get_all(context):
return results
def purge_deleted(age):
if age is not None:
try:
age = int(age)
except ValueError:
raise exception.Error(_("age should be an integer"))
if age < 0:
raise exception.Error(_("age should be a positive integer"))
else:
age = 90
def purge_deleted(age, granularity='days'):
try:
age = int(age)
except ValueError:
raise exception.Error(_("age should be an integer"))
if age < 0:
raise exception.Error(_("age should be a positive integer"))
time_line = datetime.now() - timedelta(days=age)
if granularity not in ('days', 'hours', 'minutes', 'seconds'):
raise exception.Error(
_("granularity should be days, hours, minutes, or seconds"))
if granularity == 'days':
age = age * 86400
elif granularity == 'hours':
age = age * 3600
elif granularity == 'minutes':
age = age * 60
time_line = datetime.now() - timedelta(seconds=age)
engine = get_engine()
meta = sqlalchemy.MetaData()
meta.bind = engine

View File

@ -45,5 +45,5 @@ IMPL = LazyPluggable('db_backend',
sqlalchemy='heat.db.sqlalchemy.api')
def purge_deleted(age):
IMPL.purge_deleted(age)
def purge_deleted(age, granularity='days'):
IMPL.purge_deleted(age, granularity)

View File

@ -10,9 +10,14 @@
# License for the specific language governing permissions and limitations
# under the License.
import mox
from datetime import datetime
from datetime import timedelta
import fixtures
from json import loads
from json import dumps
import mox
from heat.db.sqlalchemy import api as db_api
from heat.engine import environment
@ -659,6 +664,45 @@ class DBAPIStackTest(HeatTestCase):
self.assertEqual(2, db_api.stack_count_all_by_tenant(self.ctx))
def test_purge_deleted(self):
now = datetime.now()
delta = timedelta(seconds=3600 * 7)
deleted = [now - delta * i for i in range(1, 6)]
templates = [create_raw_template(self.ctx) for i in range(5)]
creds = [create_user_creds(self.ctx) for i in range(5)]
stacks = [create_stack(self.ctx, templates[i], creds[i],
deleted_at=deleted[i]) for i in range(5)]
class MyDatetime():
def now(self):
return now
self.useFixture(fixtures.MonkeyPatch('heat.db.sqlalchemy.api.datetime',
MyDatetime()))
db_api.purge_deleted(age=1, granularity='days')
self._deleted_stack_existance(utils.dummy_context(), stacks,
(0, 1, 2), (3, 4))
db_api.purge_deleted(age=22, granularity='hours')
self._deleted_stack_existance(utils.dummy_context(), stacks,
(0, 1, 2), (3, 4))
db_api.purge_deleted(age=1100, granularity='minutes')
self._deleted_stack_existance(utils.dummy_context(), stacks,
(0, 1), (2, 3, 4))
db_api.purge_deleted(age=3600, granularity='seconds')
self._deleted_stack_existance(utils.dummy_context(), stacks,
(), (0, 1, 2, 3, 4))
def _deleted_stack_existance(self, ctx, stacks, existing, deleted):
for s in existing:
self.assertIsNotNone(db_api.stack_get(ctx, stacks[s].id,
show_deleted=True))
for s in deleted:
self.assertIsNone(db_api.stack_get(ctx, stacks[s].id,
show_deleted=True))
class DBAPIResourceTest(HeatTestCase):
def setUp(self):