only the reaper handles deleting objects
Change-Id: I8b2ce61eecc0ed1da8766b0b0dfaf5d3f7ebd03d
diff --git a/xos/core/models/plcorebase.py b/xos/core/models/plcorebase.py
index 9d3d06d..0671e0b 100644
--- a/xos/core/models/plcorebase.py
+++ b/xos/core/models/plcorebase.py
@@ -219,8 +219,21 @@
backend_register = models.CharField(max_length=1024,
default="{}", null=True)
- # If True, then the backend wants to delete this object
+ # backend_need_delete and backend_need_reap are used by the synchronizer to
+ # handle deleting and reaping objects.
+ #
+ # backend_need_delete is set by a syncstep when it starts to work on an
+ # object. It indicates that the syncstep will, in the future, want an
+ # opportunity to delete the object. This bit prevents the reaper from
+ # auto-deleting the object.
+ #
+ # backend_need_reap is set when a syncstep has successfully enacted a delete
+ # and is ready for it to be permanently deleted. The reaper will, assuming
+ # the object has no cascades to other objects that need deleting, permanently
+ # delete the object.
+
backend_need_delete = models.BooleanField(default=False)
+ backend_need_reap = models.BooleanField(default=False)
backend_status = models.CharField(max_length=1024,
default="0 - Provisioning in progress")
diff --git a/xos/core/models/user.py b/xos/core/models/user.py
index e3e5fd2..16a9d18 100644
--- a/xos/core/models/user.py
+++ b/xos/core/models/user.py
@@ -142,6 +142,7 @@
backend_status = StrippedCharField(max_length=1024,
default="Provisioning in progress")
backend_need_delete = models.BooleanField(default=False)
+ backend_need_reap = models.BooleanField(default=False)
deleted = models.BooleanField(default=False)
write_protect = models.BooleanField(default=False)
lazy_blocked = models.BooleanField(default=False)
diff --git a/xos/synchronizers/base/SyncInstanceUsingAnsible.py b/xos/synchronizers/base/SyncInstanceUsingAnsible.py
index 88d636e..d21cc1f 100644
--- a/xos/synchronizers/base/SyncInstanceUsingAnsible.py
+++ b/xos/synchronizers/base/SyncInstanceUsingAnsible.py
@@ -232,6 +232,11 @@
pass
instance = self.get_instance(o)
+
+ if not instance:
+ # the instance is gone. There's nothing left for us to do.
+ return
+
if isinstance(instance, basestring):
# sync to some external host
diff --git a/xos/synchronizers/base/syncstep.py b/xos/synchronizers/base/syncstep.py
index a8951e9..a1e59c1 100644
--- a/xos/synchronizers/base/syncstep.py
+++ b/xos/synchronizers/base/syncstep.py
@@ -225,10 +225,16 @@
for f in failed:
self.check_dependencies(o,f) # Raises exception if failed
if (deletion):
- journal_object(o,"syncstep.call.delete_record")
- self.delete_record(o)
- journal_object(o,"syncstep.call.delete_purge")
- o.delete(purge=True)
+ if getattr(o, "backend_need_reap", False):
+ # the object has already been deleted and marked for reaping
+ journal_object(o,"syncstep.call.already_marked_reap")
+ else:
+ journal_object(o,"syncstep.call.delete_record")
+ self.delete_record(o)
+ journal_object(o,"syncstep.call.delete_set_reap")
+ o.backend_need_reap = True
+ o.save(update_fields=['backend_need_reap'])
+ #o.delete(purge=True)
else:
new_enacted = timezone.now()
try:
diff --git a/xos/synchronizers/model_policy.py b/xos/synchronizers/model_policy.py
index cfc9e90..ef5f4b0 100644
--- a/xos/synchronizers/model_policy.py
+++ b/xos/synchronizers/model_policy.py
@@ -195,7 +195,7 @@
if hasattr(d,"_meta") and hasattr(d._meta,"proxy") and d._meta.proxy:
# skip proxy objects; we'll get the base instead
continue
- if getattr(d, "backend_need_delete", False):
+ if (not getattr(d, "backend_need_reap", False)) and getattr(d, "backend_need_delete", False):
journal_object(d, "reaper.need_delete")
print "Reaper: skipping %r because it has need_delete set" % d
continue