-
Notifications
You must be signed in to change notification settings - Fork 11
/
runplugins.py
94 lines (77 loc) · 3.36 KB
/
runplugins.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""Component commands."""
import logging
import uuid
from django.utils import module_loading
from django.utils import timezone
from django.core.management import base
from defcon.status import models
class Command(base.BaseCommand):
"""Run plugins."""
help = 'Run pluginss'
def add_arguments(self, _):
"""Add arguments."""
pass
def handle(self, *args, **options):
"""Run the command."""
# TODO: add filters by components and plugins.
# Get the status that haven't expired yet to make them expire if
# they disappeared.
now = timezone.now()
existing_statuses = set(models.Status.objects.filter(
time_end__gte=now).values_list('id', flat=True))
updated_statuses = set()
for component_obj in models.Component.objects.all():
for plugin_obj in component_obj.plugins.all():
updated_statuses |= self.run_plugin(component_obj, plugin_obj)
expired_statuses = (existing_statuses - updated_statuses)
if expired_statuses:
self.stdout.write(self.style.SUCCESS('Expiring %s' % expired_statuses))
models.Status.objects.filter(id__in=expired_statuses).update(time_end=now)
def run_plugin(self, component_obj, plugin_obj):
"""Add a plugin."""
self.stdout.write('Running %s %s:%s' % (
plugin_obj.name, component_obj.name, plugin_obj.plugin.name))
plugin_class = module_loading.import_string(plugin_obj.plugin.py_module)
plugin = plugin_class(plugin_obj.config)
try:
statuses = sorted(plugin.statuses().items())
except Exception:
msg = (
"Failed to run %s:%s" %
(component_obj.name, plugin_obj.plugin.name))
logging.exception(msg)
self.stderr.write(self.style.ERROR(msg))
plugin_obj.failure += 1
plugin_obj.failure_on = timezone.now()
plugin_obj.save()
return set()
# Create an identifier unique to this plugin obj.
statuses = [
(uuid.uuid5(status_id, str(plugin_obj.id)), status)
for status_id, status in statuses
]
for status_id, status in statuses:
self._save_status(plugin_obj, status_id, status)
plugin_obj.success += 1
plugin_obj.success_on = timezone.now()
plugin_obj.save()
return set([status_id for status_id, _ in statuses])
def _save_status(self, plugin_obj, status_id, status):
"""Save a status."""
try:
del status['id']
status_obj, created = models.Status.objects.update_or_create(
id=status_id, defaults=status)
# Because statuses can be shared between plugins, we always add them
# to the plugin, not only when they are created.
plugin_obj.statuses.add(status_obj)
except Exception:
msg = "Failed to save status with id #%s" % status_id
logging.exception(msg)
self.stderr.write(self.style.ERROR(msg))
else:
action = 'Created' if created else 'Updated'
self.stdout.write(self.style.SUCCESS(
'%s %s:%s config (%s)' % (action, plugin_obj.plugin.name,
status_obj.title,
status_obj.defcon)))