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 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): def add_command_parsers(subparsers):
@ -62,8 +62,12 @@ def add_command_parsers(subparsers):
parser = subparsers.add_parser('purge_deleted') parser = subparsers.add_parser('purge_deleted')
parser.set_defaults(func=purge_deleted) parser.set_defaults(func=purge_deleted)
parser.add_argument('age', nargs='?', parser.add_argument('age', nargs='?', default='90',
help=_('Number of days to preserve.')) 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', command_opt = cfg.SubCommandOpt('command',
title='Commands', title='Commands',

View File

@ -471,18 +471,26 @@ def watch_data_get_all(context):
return results return results
def purge_deleted(age): def purge_deleted(age, granularity='days'):
if age is not None: try:
try: age = int(age)
age = int(age) except ValueError:
except ValueError: raise exception.Error(_("age should be an integer"))
raise exception.Error(_("age should be an integer")) if age < 0:
if age < 0: raise exception.Error(_("age should be a positive integer"))
raise exception.Error(_("age should be a positive integer"))
else:
age = 90
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() engine = get_engine()
meta = sqlalchemy.MetaData() meta = sqlalchemy.MetaData()
meta.bind = engine meta.bind = engine

View File

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

View File

@ -10,9 +10,14 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import mox from datetime import datetime
from datetime import timedelta
import fixtures
from json import loads from json import loads
from json import dumps from json import dumps
import mox
from heat.db.sqlalchemy import api as db_api from heat.db.sqlalchemy import api as db_api
from heat.engine import environment from heat.engine import environment
@ -659,6 +664,45 @@ class DBAPIStackTest(HeatTestCase):
self.assertEqual(2, db_api.stack_count_all_by_tenant(self.ctx)) 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): class DBAPIResourceTest(HeatTestCase):
def setUp(self): def setUp(self):