Revert "Merge pull request #1678 from coreos-inc/delete-repo-fix"
This reverts commitdf64caf133
, reversing changes made to0d1e453566
.
This commit is contained in:
parent
ce14b9dddf
commit
22a25ac2d3
2 changed files with 5 additions and 36 deletions
|
@ -46,32 +46,6 @@ def real_for_update(query):
|
||||||
def null_for_update(query):
|
def null_for_update(query):
|
||||||
return query
|
return query
|
||||||
|
|
||||||
def _clear_log_entries(instance, model_class, log_entry_field, *extra_fields):
|
|
||||||
""" Temporary method for clearing out LogEntry records before the general deletion of a
|
|
||||||
dependent record (e.g. Repository or User). Used because deleting all of the log entries
|
|
||||||
under a transaction destroys the database for all other work.
|
|
||||||
"""
|
|
||||||
# TODO: Remove this hack once LogEntry no longer has foreign key constraints to everything.
|
|
||||||
# Delete all records in LogEntry that reference the instance.
|
|
||||||
where_clause = (log_entry_field == instance)
|
|
||||||
for field in extra_fields:
|
|
||||||
where_clause = where_clause | (field == instance)
|
|
||||||
|
|
||||||
# Delete the log entries in chunks of 1000.
|
|
||||||
deleted_count = 1
|
|
||||||
while deleted_count >= 1:
|
|
||||||
todelete = (LogEntry
|
|
||||||
.select(LogEntry.id)
|
|
||||||
.where(where_clause)
|
|
||||||
.limit(1000)
|
|
||||||
.alias('todelete'))
|
|
||||||
|
|
||||||
subquery = (LogEntry
|
|
||||||
.select(todelete.c.id)
|
|
||||||
.from_(todelete))
|
|
||||||
|
|
||||||
deleted_count = LogEntry.delete().where(LogEntry.id << subquery).execute()
|
|
||||||
|
|
||||||
def delete_instance_filtered(instance, model_class, delete_nullable, skip_transitive_deletes):
|
def delete_instance_filtered(instance, model_class, delete_nullable, skip_transitive_deletes):
|
||||||
""" Deletes the DB instance recursively, skipping any models in the skip_transitive_deletes set.
|
""" Deletes the DB instance recursively, skipping any models in the skip_transitive_deletes set.
|
||||||
|
|
||||||
|
@ -114,7 +88,6 @@ def delete_instance_filtered(instance, model_class, delete_nullable, skip_transi
|
||||||
with db_transaction():
|
with db_transaction():
|
||||||
for query, fk in filtered_ops:
|
for query, fk in filtered_ops:
|
||||||
model = fk.model_class
|
model = fk.model_class
|
||||||
|
|
||||||
if fk.null and not delete_nullable:
|
if fk.null and not delete_nullable:
|
||||||
model.update(**{fk.name: None}).where(query).execute()
|
model.update(**{fk.name: None}).where(query).execute()
|
||||||
else:
|
else:
|
||||||
|
@ -347,7 +320,6 @@ class User(BaseModel):
|
||||||
# These models don't need to use transitive deletes, because the referenced objects
|
# These models don't need to use transitive deletes, because the referenced objects
|
||||||
# are cleaned up directly
|
# are cleaned up directly
|
||||||
skip_transitive_deletes = {Image}
|
skip_transitive_deletes = {Image}
|
||||||
_clear_log_entries(self, User, LogEntry.performer, LogEntry.account)
|
|
||||||
delete_instance_filtered(self, User, delete_nullable, skip_transitive_deletes)
|
delete_instance_filtered(self, User, delete_nullable, skip_transitive_deletes)
|
||||||
|
|
||||||
|
|
||||||
|
@ -444,7 +416,7 @@ class Repository(BaseModel):
|
||||||
# are cleaned up directly
|
# are cleaned up directly
|
||||||
skip_transitive_deletes = {RepositoryTag, RepositoryBuild, RepositoryBuildTrigger, BlobUpload,
|
skip_transitive_deletes = {RepositoryTag, RepositoryBuild, RepositoryBuildTrigger, BlobUpload,
|
||||||
Image, TagManifest, DerivedStorageForImage}
|
Image, TagManifest, DerivedStorageForImage}
|
||||||
_clear_log_entries(self, User, LogEntry.repository)
|
|
||||||
delete_instance_filtered(self, Repository, delete_nullable, skip_transitive_deletes)
|
delete_instance_filtered(self, Repository, delete_nullable, skip_transitive_deletes)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1654,17 +1654,14 @@ class log_queries(object):
|
||||||
|
|
||||||
|
|
||||||
class check_transitive_deletes(log_queries):
|
class check_transitive_deletes(log_queries):
|
||||||
def __init__(self, allowed_query_check=None):
|
def __init__(self):
|
||||||
super(check_transitive_deletes, self).__init__(query_filter=r'^DELETE.+IN \(SELECT.+$')
|
super(check_transitive_deletes, self).__init__(query_filter=r'^DELETE.+IN \(SELECT.+$')
|
||||||
self.allowed_query_check = allowed_query_check
|
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
super(check_transitive_deletes, self).__exit__(exc_type, exc_val, exc_tb)
|
super(check_transitive_deletes, self).__exit__(exc_type, exc_val, exc_tb)
|
||||||
queries = self.get_queries()
|
queries = self.get_queries()
|
||||||
if queries and self.allowed_query_check:
|
if queries:
|
||||||
for query in queries:
|
raise Exception('Detected transitive deletion in queries: %s' % queries)
|
||||||
if query.find(self.allowed_query_check) < 0:
|
|
||||||
raise Exception('Detected transitive deletion in queries: %s' % queries)
|
|
||||||
|
|
||||||
|
|
||||||
class TestDeleteRepository(ApiTestCase):
|
class TestDeleteRepository(ApiTestCase):
|
||||||
|
@ -1750,7 +1747,7 @@ class TestDeleteRepository(ApiTestCase):
|
||||||
date=datetime.datetime.now() - datetime.timedelta(days=5), count=6)
|
date=datetime.datetime.now() - datetime.timedelta(days=5), count=6)
|
||||||
|
|
||||||
# Delete the repository.
|
# Delete the repository.
|
||||||
with check_transitive_deletes(allowed_query_check='todelete'):
|
with check_transitive_deletes():
|
||||||
self.deleteResponse(Repository, params=dict(repository=self.COMPLEX_REPO))
|
self.deleteResponse(Repository, params=dict(repository=self.COMPLEX_REPO))
|
||||||
|
|
||||||
# Verify the repo was deleted.
|
# Verify the repo was deleted.
|
||||||
|
|
Reference in a new issue