| 165 | | |
| 166 | | def oldloader(self): |
| 167 | | # A new provisioner |
| 168 | | if name == 'provisioner': |
| 169 | | log.debug("Creating new provisioner") |
| 170 | | self.add_provisioner(element) |
| 171 | | |
| 172 | | elif name == 'device': |
| 173 | | log.debug("Creating new device") |
| 174 | | self.add_device(element) |
| 175 | | |
| 176 | | elif name == 'change': |
| 177 | | log.debug("Creating new change") |
| 178 | | self.add_change(element) |
| 179 | | |
| 180 | | elif name == 'namespace': |
| 181 | | log.debug("Creating new namespace") |
| 182 | | self.add_namespace(element) |
| 183 | | |
| 184 | | elif name == 'config': |
| 185 | | # We've finished the config |
| 186 | | #self.global_namespace = self.namespace_stack.pop() |
| 187 | | |
| 188 | | # Add some global elements to the namespace |
| 189 | | element.namespace['ALL_TARGETS'] = [ x for x in self.devices.keys() ] |
| 190 | | |
| 191 | | self.global_namespace = element.namespace |
| 192 | | |
| 193 | | |
| 194 | | ## elif name == 'dependencies': |
| 195 | | ## # We've finish a list of dependency elements |
| 196 | | ## log.info("Finished loaded dependencies.") |
| 197 | | ## self.dependency_tree = element |
| 335 | | |
| | 314 | |
| | 315 | def add_changetemplate(self, node): |
| | 316 | """ |
| | 317 | Add a change template to my list of available templates. |
| | 318 | A change template is a change object that may not have |
| | 319 | all of its parameters set yet. |
| | 320 | """ |
| | 321 | log.debug("Adding change template...") |
| | 322 | # Create the change template object |
| | 323 | change_tmpl = self.create_change_object(node) |
| | 324 | |
| | 325 | # Set any namespaces |
| | 326 | self.set_change_namespace(change_tmpl, node) |
| | 327 | |
| | 328 | # Set change parameters that are common to all changes |
| | 329 | self.set_change_params(change_tmpl, node) |
| | 330 | |
| | 331 | # Set the optional change iterator |
| | 332 | self.set_change_iterator(change_tmpl, node) |
| | 333 | |
| | 334 | # Add an optional onfail mode |
| | 335 | self.set_change_onfail(change_tmpl, node) |
| | 336 | |
| | 337 | self.change_templates[change_tmpl.name] = change_tmpl |
| | 338 | |
| | 339 | return change_tmpl |
| | 340 | |
| 338 | | Add a change to my configuration based on the parsed element. |
| | 343 | When adding a change, check for some extra options such as a |
| | 344 | change template, which will cause this change to be based on |
| | 345 | an existing change template. |
| | 346 | """ |
| | 347 | log.debug("Adding change...") |
| | 348 | try: |
| | 349 | tmpl_name = node.attrib['template'] |
| | 350 | log.debug("Change is based on a template: '%s'", tmpl_name) |
| | 351 | # Do template based processing |
| | 352 | try: |
| | 353 | template = self.change_templates[tmpl_name] |
| | 354 | except KeyError: |
| | 355 | raise ValueError("Change template '%s' is not defined" % tmpl_name) |
| | 356 | |
| | 357 | change = template.copy() |
| | 358 | # Make sure we set the change name to the actual change, |
| | 359 | # not the name of the template |
| | 360 | change.name = node.attrib['name'] |
| | 361 | |
| | 362 | # Now do non-templated specific processing |
| | 363 | self.set_change_namespace(change, node) |
| | 364 | self.set_change_params(change, node) |
| | 365 | self.set_change_iterator(change, node) |
| | 366 | self.set_change_onfail(change, node) |
| | 367 | |
| | 368 | except KeyError: |
| | 369 | # Use the same processing stream as a template, with the |
| | 370 | # assumption that all the required parameters have been |
| | 371 | # defined. If they haven't, the change will fail. |
| | 372 | change = self.add_change_template(node) |
| | 373 | pass |
| | 374 | |
| | 375 | # If the change doesn't have a provisioner, use the first one |
| | 376 | # in our config by default. |
| | 377 | if getattr(change, 'provisioner', None) is None: |
| | 378 | log.info("Change '%s' has no provisioner. Using default.", change.name ) |
| | 379 | # FIXME: This should find the first *compatible* provisioner, |
| | 380 | # rather than just the first one. |
| | 381 | change.provisioner = self.provisioners.values()[0] |
| | 382 | pass |
| | 383 | |
| | 384 | self.changes[change.name] = change |
| | 385 | self.pending_changes.append( change ) |
| | 386 | |
| | 387 | def create_change_object(self, node): |
| | 388 | """ |
| | 389 | Create a change object from a node. |
| | 390 | This may be used as a change template, or a regular change. |
| 366 | | # Add change attributes that are common to all changes |
| | 422 | def set_change_provisioner(self, change, node): |
| | 423 | # which provisioner to use for the change |
| | 424 | try: |
| | 425 | provname = node.attrib['provisioner'] |
| | 426 | except KeyError: |
| | 427 | return |
| | 428 | |
| | 429 | provname = util.substituteVariables(provname, change.namespace) |
| | 430 | try: |
| | 431 | change.provisioner = self.provisioners[provname] |
| | 432 | log.debug("change '%s' will use provisioner '%s'", change, provname) |
| | 433 | except KeyError: |
| | 434 | raise KeyError("Provisioner named '%s' is not defined" % provname) |
| | 435 | |
| | 436 | def set_change_params(self, change, node): |
| | 437 | """ |
| | 438 | Set common change parameters, defined in subnodes. |
| | 439 | """ |
| 600 | | def apply_namespaces(self, string): |
| 601 | | """ |
| 602 | | Apply namespaces mid parse. |
| 603 | | Deprecated. |
| 604 | | """ |
| 605 | | # Find the first namespace in the element stack, and use it, |
| 606 | | # which will implicitly apply its parents. |
| 607 | | ## tempstack = self.element_stack |
| 608 | | ## tempstack.reverse() |
| 609 | | ## for elem in tempstack: |
| 610 | | ## if getattr(elem, 'namespace', None) is not None: |
| 611 | | ## log.debug("applying namespace: %s", elem.namespace) |
| 612 | | ## string = string % elem.namespace |
| 613 | | ## break |
| 614 | | ## pass |
| 615 | | log.warn("Inline namespace usage not yet supported.") |
| | 665 | def _apply_namespace(self, string, namespace): |
| | 666 | """ |
| | 667 | Apply a namespace to a string |
| | 668 | Deprecated |
| | 669 | """ |
| | 670 | if namespace is not None: |
| | 671 | string = string % namespace |
| | 672 | |