blob: 2813416b0b8ce8f0cebb16f6ffce4b4df8ef982b [file] [log] [blame]
Sapan Bhatia0235e982014-09-03 13:14:40 -04001from django.db.models.signals import post_save
2from django.dispatch import receiver
3import pdb
Sapan Bhatia14356b72014-11-05 10:32:41 -05004from dependency_walker import *
Sapan Bhatiafe9bc892014-09-15 03:48:11 -04005import model_policies
Tony Mack3066a952015-01-05 22:48:11 -05006from util.logger import logger
Sapan Bhatiab3507b92015-01-23 16:09:28 +00007from datetime import datetime
8import time
9from core.models import *
Scott Baker5b961e02015-06-22 10:56:16 -070010from django.db import reset_queries
Sapan Bhatiab3507b92015-01-23 16:09:28 +000011from django.db.transaction import atomic
12from django.db.models import F, Q
Sapan Bhatia7a1e6be2015-01-16 22:17:42 +000013
Scott Bakerf3428702014-10-21 15:05:29 -070014modelPolicyEnabled = True
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020015bad_instances=[]
Scott Bakerf3428702014-10-21 15:05:29 -070016
17def EnableModelPolicy(x):
18 global modelPolicyEnabled
19 modelPolicyEnabled = x
20
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020021def update_wp(d, o):
22 try:
23 save_fields = []
24 if (d.write_protect != o.write_protect):
25 d.write_protect = o.write_protect
26 save_fields.append('write_protect')
27 if (save_fields):
28 d.save(update_fields=save_fields)
29 except AttributeError,e:
30 raise e
31
Sapan Bhatia14356b72014-11-05 10:32:41 -050032def update_dep(d, o):
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020033 try:
34 print 'Trying to update %s'%d
35 save_fields = []
36 if (d.updated < o.updated):
37 save_fields = ['updated']
38
39 if (save_fields):
40 d.save(update_fields=save_fields)
41 except AttributeError,e:
42 raise e
Scott Baker5b961e02015-06-22 10:56:16 -070043 except Exception,e:
44 logger.info('Could not save %r. Exception: %r'%(d,e))
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020045
Sapan Bhatia14356b72014-11-05 10:32:41 -050046def delete_if_inactive(d, o):
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020047 try:
48 d.delete()
49 print "Deleted %s (%s)"%(d,d.__class__.__name__)
50 except:
51 pass
52 return
53
Sapan Bhatia14356b72014-11-05 10:32:41 -050054
Sapan Bhatiab3507b92015-01-23 16:09:28 +000055@atomic
56def execute_model_policy(instance, deleted):
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020057 # Automatic dirtying
58 if (instance in bad_instances):
59 return
Sapan Bhatia7a1e6be2015-01-16 22:17:42 +000060
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020061 # These are the models whose children get deleted when they are
62 delete_policy_models = ['Slice','Sliver','Network']
63 sender_name = instance.__class__.__name__
64 policy_name = 'model_policy_%s'%sender_name
65 noargs = False
Sapan Bhatiab3507b92015-01-23 16:09:28 +000066
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020067 if (not deleted):
68 walk_inv_deps(update_dep, instance)
69 walk_deps(update_wp, instance)
70 elif (sender_name in delete_policy_models):
71 walk_inv_deps(delete_if_inactive, instance)
Sapan Bhatia7a1e6be2015-01-16 22:17:42 +000072
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020073
74
75 try:
76 policy_handler = getattr(model_policies, policy_name, None)
77 logger.error("POLICY HANDLER: %s %s" % (policy_name, policy_handler))
78 if policy_handler is not None:
79 if (deleted):
80 try:
81 policy_handler.handle_delete(instance)
82 except AttributeError:
83 pass
84 else:
85 policy_handler.handle(instance)
86 except:
87 logger.log_exc("Model Policy Error:")
88
89 try:
90 instance.policed=datetime.now()
Sapan Bhatiab3507b92015-01-23 16:09:28 +000091 instance.save(update_fields=['policed'])
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +020092 except:
93 logging.error('Object %r is defective'%instance)
94 bad_instances.append(instance)
Sapan Bhatia7a1e6be2015-01-16 22:17:42 +000095
Sapan Bhatia35dab9d2015-05-27 19:11:12 +020096def noop(o,p):
97 pass
98
Sapan Bhatiab3507b92015-01-23 16:09:28 +000099def run_policy():
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +0200100 from core.models import Sliver,Slice,Controller,Network,User,SlicePrivilege,Site,SitePrivilege,Image,ControllerSlice,ControllerUser,ControllerSite
101 while (True):
102 start = time.time()
103 models = [Sliver,Slice, Controller, Network, User, SlicePrivilege, Site, SitePrivilege, Image, ControllerSlice, ControllerSite, ControllerUser]
104 objects = []
105 deleted_objects = []
Sapan Bhatia14356b72014-11-05 10:32:41 -0500106
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +0200107 for m in models:
108 res = m.objects.filter(Q(policed__lt=F('updated')) | Q(policed=None))
109 objects.extend(res)
110 res = m.deleted_objects.filter(Q(policed__lt=F('updated')) | Q(policed=None))
111 deleted_objects.extend(res)
112
113 for o in objects:
114 execute_model_policy(o, o.deleted)
115
116 for o in deleted_objects:
117 execute_model_policy(o, True)
118
Sapan Bhatia35dab9d2015-05-27 19:11:12 +0200119 # Reap non-sync'd models here
120 reaped = [Slice]
121
122 for m in reaped:
123 dobjs = m.deleted_objects.all()
124 for d in dobjs:
125 deps = walk_inv_deps(noop, d)
126 if (not deps):
127 print 'Purging object %r'%d
128 d.delete(purge=True)
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +0200129
Scott Baker5b961e02015-06-22 10:56:16 -0700130 try:
131 reset_queries()
132 except:
133 # this shouldn't happen, but in case it does, catch it...
134 logger.log_exc("exception in reset_queries")
135
Sapan Bhatiaa4fadac2015-05-09 18:10:17 +0200136 if (time.time()-start<1):
137 time.sleep(1)