summaryrefslogtreecommitdiffstats
path: root/st_web/st_config.py
blob: 7869e10b560ccfe8216942bdd2dfb6a6ff21ce24 (plain)
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
103
104
105
106
107
108
109
110
111
112
113
114

from xml.sax import make_parser, handler
from sets import Set
from os.path import getmtime

class SteelToeXML(handler.ContentHandler):

	def __init__(self, filename="/etc/steeltoe/steeltoe.xml"):
		self.filename = filename
		self.reload()

	def reload(self):
		self.mtimes = {self.filename: getmtime(self.filename)}
		self.config = {'bootloader': {}}
		self.hosts = []
		self.hostnames = Set()
		self.groups = []
		self.groupnames = Set()
		self.trees = []
		self.treenames = Set()
		self.meta = {}  # tree metadata index
		self._context = []
		self._curname = ""
		parser = make_parser()
		parser.setContentHandler(self)
		parser.parse(self.filename)

	def refresh(self):
		reload = False
		for (fn, mtime) in self.mtimes.items():
			if mtime != getmtime(fn):
				reload = True
		if reload:
			self.reload()

	def get_group(self, name):
		return [x for x in self.groups if x['name'] == name][0]

	def get_host(self, name):
		return [x for x in self.hosts if x['name'] == name][0]

	def characters(self, content):
		self._text = self._text + content

	def startElement(self, name, attrs):
		if name in ['config', 'tree', 'host', 'bootloader', 'kickstart', 'meta']:
			self._context.append(name)
		if name in ['group', 'tree', 'host']:
			self._curname = attrs['name']
		if name == 'repo':
			if not self._curtree.has_key(name):
				self._curtree[name] = [attrs['name']]
			else:
				self._curtree[name].append(attrs['name'])
		if name == 'host':
			self._curhost = {'name': self._curname}
			self.hostnames.add(self._curname)
		if name == 'tree':
			self._curtree = {'name': self._curname, 'meta': {}}
			self.treenames.add(self._curname)
		if name == 'group':
			self.groupnames.add(self._curname)
		# Hack to handle simple XIncludes
		if name == 'xi:include':
			href = attrs['href']
			self.mtimes[href] = getmtime(href)
			subp = make_parser()
			subp.setContentHandler(self)
			subp.parse(href)
		self._text = ""

	def _parent(self):
		if len(self._context):
			return self._context[-1]
		else:
			None

	def endElement(self, name):
		self._text = self._text.strip()
		if self._parent() == name:
			self._context.pop()
		if self._parent() == 'config':
			self.config[name] = self._text
		elif self._parent() == 'bootloader':
			self.config['bootloader'][name] = self._text
		elif name == 'group':
			self.groups.append({   'name': self._curname, 
					    'members': self._text.split()})
			self._curname = None
		elif self._parent() == 'kickstart' or name == 'kickstart':
			# Ignore the kickstart sections for now
			pass
		elif self._parent() == 'host':
			self._curhost[name] = self._text
		elif name == 'host':
			self.hosts.append(self._curhost)
			self._curname = None
		elif self._parent() == 'meta':
			self._curtree['meta'][name] = self._text
			if not self.meta.has_key(name):
				self.meta[name] = {self._text: Set([self._curname])}
			elif not self.meta[name].has_key(self._text):
				self.meta[name][self._text] = Set([self._curname])
			else:
				self.meta[name][self._text].add(self._curname)
		elif self._parent() == 'tree':
			if name == 'path':
				self._curtree[name] = self._text
		elif name == 'tree':
			self.trees.append(self._curtree)
			self._curname = None


steeltoe = SteelToeXML()