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
95
96
97
98
99
100
101
102
|
import binascii
import difflib
import logging
import lxml.etree
import platform
import sys
import time
try:
from django.core.exceptions import MultipleObjectsReturned
except ImportError:
pass
import Bcfg2.Server.Plugin
from Bcfg2.Server.Reports.importscript import load_stat
from Bcfg2.Server.Reports.reports.models import Client
# for debugging output only
logger = logging.getLogger('Bcfg2.Plugins.DBStats')
class DBStats(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.ThreadedStatistics,
Bcfg2.Server.Plugin.PullSource):
name = 'DBStats'
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.ThreadedStatistics.__init__(self, core, datastore)
Bcfg2.Server.Plugin.PullSource.__init__(self)
self.cpath = "%s/Metadata/clients.xml" % datastore
self.core = core
logger.debug("Searching for new models to "
"add to the statistics database")
def handle_statistic(self, metadata, data):
newstats = data.find("Statistics")
newstats.set('time', time.asctime(time.localtime()))
start = time.time()
for i in [1, 2, 3]:
try:
load_stat(metadata,
newstats,
self.core.encoding,
0,
logger,
True,
platform.node())
logger.info("Imported data for %s in %s seconds" \
% (metadata.hostname, time.time() - start))
return
except MultipleObjectsReturned:
e = sys.exc_info()[1]
logger.error("DBStats: MultipleObjectsReturned while "
"handling %s: %s" % (metadata.hostname, e))
logger.error("DBStats: Data is inconsistent")
break
except:
logger.error("DBStats: Failed to write to db (lock); retrying",
exc_info=1)
logger.error("DBStats: Retry limit failed for %s; aborting operation" \
% metadata.hostname)
def GetExtra(self, client):
c_inst = Client.objects.filter(name=client)[0]
return [(a.entry.kind, a.entry.name) for a in
c_inst.current_interaction.extra()]
def GetCurrentEntry(self, client, e_type, e_name):
try:
c_inst = Client.objects.filter(name=client)[0]
except IndexError:
self.logger.error("Unknown client: %s" % client)
raise Bcfg2.Server.Plugin.PluginExecutionError
result = c_inst.current_interaction.bad().filter(entry__kind=e_type,
entry__name=e_name)
if not result:
raise Bcfg2.Server.Plugin.PluginExecutionError
entry = result[0]
ret = []
data = ('owner', 'group', 'perms')
for t in data:
if getattr(entry.reason, "current_%s" % t) == '':
ret.append(getattr(entry.reason, t))
else:
ret.append(getattr(entry.reason, "current_%s" % t))
if entry.reason.is_sensitive:
raise Bcfg2.Server.Plugin.PluginExecutionError
elif len(entry.reason.unpruned) != 0:
ret.append('\n'.join(entry.reason.unpruned))
elif entry.reason.current_diff != '':
if entry.reason.is_binary:
ret.append(binascii.a2b_base64(entry.reason.current_diff))
else:
ret.append('\n'.join(difflib.restore(\
entry.reason.current_diff.split('\n'), 1)))
elif entry.reason.is_binary:
# If len is zero the object was too large to store
raise Bcfg2.Server.Plugin.PluginExecutionError
else:
ret.append(None)
return ret
|