1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from xml.dom.minidom import parse
17 import os
18 import sys
19
20 from spacewalk.common.usix import raise_with_tb
21
22
23
24
25
26
27 -class DomainConfigError(Exception): pass
28
29
30
31
32
36
38 - def __init__(self, path, data_type):
39 self.path = path
40 self.data_type = data_type
41
43
44
45
46
47
48 NAME = DomainConfigItem("domain/name", DataType.VALUE)
49 UUID = DomainConfigItem("domain/uuid", DataType.VALUE)
50 BOOTLOADER = DomainConfigItem("domain/bootloader", DataType.VALUE)
51 MEMORY = DomainConfigItem("domain/memory", DataType.VALUE)
52 VCPU = DomainConfigItem("domain/vcpu", DataType.VALUE)
53 OS = DomainConfigItem("domain/os", DataType.VALUE)
54 OS_TYPE = DomainConfigItem("domain/os/type", DataType.VALUE)
55 ROOT_DEVICE = DomainConfigItem("domain/os/root", DataType.VALUE)
56 COMMAND_LINE = DomainConfigItem("domain/os/cmdline", DataType.VALUE)
57 KERNEL_PATH = DomainConfigItem("domain/os/kernel", DataType.VALUE)
58 RAMDISK_PATH = DomainConfigItem("domain/os/initrd", DataType.VALUE)
59 DISK_IMAGE_PATH = DomainConfigItem("domain/devices/disk/source/file",
60 DataType.ATTRIBUTE)
61 DOMAIN_ID = DomainConfigItem("domain/id", DataType.ATTRIBUTE)
62
63
64
65
66
67 - def __init__(self, config_path, uuid):
68
69 if uuid.find(".xml") > 1 and os.path.exists(uuid):
70 self.__file_name = uuid
71 else:
72 self.__file_name = "%s/%s.xml" % (config_path, uuid)
73
74 self.__dom_tree = None
75 try:
76 self.__dom_tree = parse(self.__file_name).documentElement
77 except Exception:
78 e = sys.exc_info()[1]
79 raise_with_tb(DomainConfigError("Error reading config file '%s': %s" % (self.__file_name, str(e))),
80 sys.exc_info()[2])
81
82
84 """Saves any changes made to this configuration."""
85 file = None
86 try:
87 try:
88 file = open(self.__file_name, "w")
89 file.write(self.__dom_tree.toxml())
90 except IOError:
91 ioe = sys.exc_info()[1]
92 raise_with_tb(DomainConfigError("Error saving config file '%s': %s" % (self.__file_name, str(ioe))),
93 sys.exc_info()[2])
94
95 finally:
96 if file is not None:
97 file.close()
98
99 - def getFileName(self):
100 """
101 Returns the path to the configuration file represented by this
102 object.
103 """
104 return self.__file_name
105
107 """Returns the XML representation of this configuration."""
108 return self.__dom_tree.toxml()
109
110 - def getConfigItem(self, config_item):
111 if config_item.data_type == DataType.ATTRIBUTE:
112 return self.__getElementAttribute(
113 self.__dom_tree,
114 *config_item.path.split("/"))
115 elif config_item.data_type == DataType.VALUE:
116 return self.__getElementValue(
117 self.__dom_tree,
118 *config_item.path.split("/"))
119
120 raise DomainConfigError("Unknown config item data type '%s'" % \
121 str(config_item.data_type))
122
123 - def hasConfigItem(self, config_item):
124 try:
125 self.getConfigItem(config_item)
126 except DomainConfigError:
127 return 0
128 return 1
129
130 - def removeConfigItem(self, config_item):
131 if config_item.data_type == DataType.ATTRIBUTE:
132 return self.__removeElementAttribute(
133 self.__dom_tree,
134 *config_item.path.split("/"))
135 elif config_item.data_type == DataType.VALUE:
136 return self.__removeElementValue(
137 self.__dom_tree,
138 *config_item.path.split("/"))
139
140 raise DomainConfigError("Unknown config item data type '%s'" % \
141 str(config_item.data_type))
142
143 - def setConfigItem(self, config_item, value):
144 """
145 Sets the value of an item in the tree. If the item does not yet exist,
146 it will be created.
147 """
148 if config_item.data_type == DataType.ATTRIBUTE:
149 return self.__setElementAttribute(
150 self.__dom_tree,
151 value,
152 *config_item.path.split("/"))
153 elif config_item.data_type == DataType.VALUE:
154 return self.__setElementValue(
155 self.__dom_tree,
156 value,
157 *config_item.path.split("/"))
158
159 raise DomainConfigError("Unknown config item data type '%s'" % \
160 str(config_item.data_type))
161
163 """
164 Returns true if this configuration indicates that the domain was
165 started in a method that would put it into the installer.
166 """
167 result = 0
168 if self.hasConfigItem(DomainConfig.COMMAND_LINE):
169
170 command_line = self.getConfigItem(DomainConfig.COMMAND_LINE)
171 command_line_parts = command_line.strip().split(" ")
172 command_line_dict = {}
173 for part in command_line_parts:
174 command_line_args = part.split("=")
175 key = command_line_args[0]
176 command_line_dict[key] = None
177 if len(command_line_args) >= 2:
178 command_line_dict[key] = '='.join(command_line_args[1:])
179
180
181
182 if "method" in command_line_dict or "ks" in command_line_dict or "autoyast" in command_line_dict:
183 result = 1
184
185 return result
186
187
188
189
190
191 - def __getElementValue(self, start_tree, *tag_path):
192 found = self.__extractElement(start_tree, *tag_path)
193
194 if len(found.childNodes) == 0:
195 raise DomainConfigError("Unable to find config value: " + "/".join(tag_path))
196
197 return found.childNodes[0].data
198
199 - def __getElementAttribute(self, start_tree, *tag_path):
200 """
201 Returns the value of the requested XML attribute. The attribute name
202 is the last value in the tag_path.
203 """
204 attribute_name = tag_path[-1]
205 found = self.__extractElement(start_tree, *tag_path[:-1])
206
207
208 if not found.hasAttribute(attribute_name):
209 raise DomainConfigError("Unable to find config attribute: " + "/".join(tag_path))
210
211 return found.getAttribute(attribute_name)
212
213 - def __removeElementValue(self, start_tree, *tag_path):
214 found = self.__extractElement(start_tree, *tag_path)
215
216 if len(found.childNodes) == 0:
217 raise DomainConfigError("Unable to find config value: " + "/".join(tag_path))
218
219 found.parentNode.removeChild(found)
220
221 - def __removeElementAttribute(self, start_tree, *tag_path):
222 attribute_name = tag_path[-1]
223 found = self.__extractElement(start_tree, *tag_path[:-1])
224
225 if not found.hasAttribute(attribute_name):
226 raise DomainConfigError("Unable to find config attribute: " + "/".join(tag_path))
227
228 found.removeAttribute(attribute_name)
229
230 - def __setElementValue(self, start_tree, value, *tag_path):
231 try:
232 found = self.__extractElement(start_tree, *tag_path)
233 except DomainConfigError:
234
235
236 found = self.__makeElement(start_tree, *tag_path)
237
238 if len(found.childNodes) == 0:
239 document = self.__dom_tree.parentNode
240 element_text = document.createTextNode('')
241 found.appendChild(element_text)
242
243 try:
244 found.childNodes[0].data = str(value)
245 except IndexError:
246 raise_with_tb(DomainConfigError("Error writing %s tag in '%s'." % ('/'.join(tag_path), self.__file_name)),
247 sys.exc_info()[2])
248
249 - def __setElementAttribute(self, start_tree, value, *tag_path):
250 attribute_name = tag_path[-1]
251 found = self.__extractElement(start_tree, *tag_path[:-1])
252 found.setAttribute(attribute_name, str(value))
253
254 - def __makeElement(self, start_tree, *tag_path):
255
256
257 if len(tag_path) == 0:
258 return start_tree
259
260
261 tag = tag_path[0]
262 try:
263 element = self.__extractElement(start_tree, tag)
264 except DomainConfigError:
265
266 document = self.__dom_tree.parentNode
267 element = document.createElement(tag)
268 start_tree.appendChild(element)
269
270 tag_path = tag_path[1:]
271 return self.__makeElement(element, *tag_path)
272
273 - def __extractElement(self, start_tree, *tag_path):
274
275 if len(tag_path) == 0:
276 return start_tree
277
278
279 tag = tag_path[0]
280
281 if start_tree == self.__dom_tree:
282
283
284
285 if start_tree.nodeName != tag:
286
287 raise DomainConfigError("Could not locate tag <%s>." % tag)
288 else:
289
290
291 tag_path = tag_path[1:]
292 if len(tag_path) == 0:
293 return start_tree
294 else:
295 tag = tag_path[0]
296
297 node_list = start_tree.getElementsByTagName(tag)
298
299 if node_list is not None and len(node_list) > 0:
300 tag_node = node_list[0]
301 return self.__extractElement(tag_node, *tag_path[1:])
302
303
304
305 raise DomainConfigError("Could not locate tag " + str(tag))
306
307
308
309
310
311 if __name__ == "__main__":
312 import sys
313 uuid = sys.argv[1]
314 f = DomainConfig("/etc/sysconfig/rhn/virt", uuid)
315 print("name=", f.getConfigItem(DomainConfig.NAME))
316 print("memory=", f.getConfigItem(DomainConfig.MEMORY))
317 print("domain_id=", f.getConfigItem(DomainConfig.DOMAIN_ID))
318 f.setConfigItem(DomainConfig.DOMAIN_ID, 22322)
319 f.setConfigItem(DomainConfigItem("domain/argh", DataType.ATTRIBUTE), 22322)
320 f.setConfigItem(DomainConfigItem("domain/pete", DataType.VALUE), "hello")
321 f.setConfigItem(DomainConfigItem("domain/vcpu", DataType.VALUE), "22")
322 f.setConfigItem(DomainConfig.BOOTLOADER, "/usr/pete/bin/pygrub")
323 f.removeConfigItem(DomainConfigItem("domain/os", DataType.VALUE))
324 print(f.toXML())
325