Changeset 29 for trunk/provisioner.py

Show
Ignore:
Timestamp:
27/11/07 17:40:17 (4 years ago)
Author:
daedalus
Message:

* Manual bailout when in authoritarian mode now works correctly.
* Fixed up some of the log level and stats reporting.
* Added 'backout' mode, that will only run the backout portion of changes. More

useful for testing, but can also be used to undo provisioning by repurposing
the same set of templates used for provisioning.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/provisioner.py

    r28 r29  
    8080        pass 
    8181 
    82     def perform_change(self, ignored, change, namespace={}): 
     82    def perform_change(self, ignored, change, namespace={}, backout=False): 
    8383        """ 
    8484        Perform a change on one or more (potentially) remote entities. 
     
    120120                namespace.update(device.namespace) 
    121121 
    122                 log.debug("applying change with namespace: %s", namespace) 
    123                 d.addCallback(self.apply_change, device, change, namespace) 
    124  
    125                 d.addCallback(self.change_complete_success, change, namespace) 
    126                 d.addErrback(self.change_failure, change, namespace) 
     122                if backout: 
     123                    # Just do the backout portion 
     124                    d.addCallback(self.backout_change, device, change, namespace) 
     125 
     126                else: 
     127                    log.debug("applying change with namespace: %s", namespace) 
     128                    d.addCallback(self.apply_change, device, change, namespace) 
     129                     
     130                    d.addCallback(self.change_complete_success, change, namespace) 
     131                    d.addErrback(self.change_failure, change, namespace) 
     132                    pass 
    127133                pass 
    128134            pass 
     
    158164        e = failure.check( ChangeConditionFailure, UserBailout ) 
    159165        if e: 
    160             log.error("  failure was: %s", failure.value ) 
    161             if isinstance(e, UserBailout): 
    162                 log.info("User bailout detected.") 
    163                 return defer.succeed('bailout') 
     166            log.error("  failure was: %s, %s", failure.type, failure.value ) 
     167 
     168            # If we want to bail out, bail now 
     169            if failure.type == UserBailout: 
     170                return defer.fail(failure) 
    164171        else: 
     172            log.error("Unhandled failure in provisioner.change_apply_failed()") 
    165173            tlog.err(failure) 
    166174         
     
    193201                change.state = CHANGE_STATE['total_failure'] 
    194202        else: 
    195             change.state = CHANGE_STATE['backout_failed'] 
    196             pass 
     203            log.error("change_failure unhandled change state: %s", change.state) 
     204            raise ValueError("Invalid change state: %s" % change.state) 
     205 
     206        # Propogate a UserBailout failure 
     207        if failure.type == UserBailout: 
     208            return failure 
     209         
    197210        #tlog.err(failure) 
    198211 
     
    202215            log.info("Change '%s' was a success!", change.name) 
    203216        else: 
     217            log.error("change_complete_success in weird state: %s", change.state) 
     218            raise ValueError("wrong change state: %s" % change.state) 
    204219            change.state = CHANGE_STATE['backout_ok'] 
    205220            log.info("Change '%s' backed out successfully", change.name) 
     
    241256    def backout_success(self, ignored, device, change, namespace): 
    242257        log.info("Successfully backed out change: '%s' from device '%s'", change.name, device) 
     258        change.state = CHANGE_STATE['backout_ok'] 
    243259        self.backout_ok[device] = change 
    244260 
    245261    def backout_failure(self, failure, device, change, namespace): 
    246262        log.critical("Backout of change '%s' failed for device '%s'!", change.name, device) 
     263        change.state = CHANGE_STATE['backout_failed'] 
    247264        self.backout_failed[device] = change 
    248         tlog.err(failure) 
     265        #tlog.err(failure) 
    249266        return failure 
    250267 
     
    611628            pass 
    612629 
    613         d.addCallback(self.all_commands_done) 
    614          
     630        d.addCallbacks(self.all_commands_done, self.all_commands_failure) 
    615631        return self.all_commands_defer 
    616632 
     
    662678        log.error("Command failed: %s", errorstr) 
    663679        #self.all_commands_defer.errback( Exception(errorstr) ) 
    664  
     680        return failure 
     681     
    665682    def all_commands_done(self, result): 
    666683        """ 
     
    669686        log.debug("All commands have finished.") 
    670687        self.all_commands_defer.callback( (self.exitcode, self.cmdoutput) ) 
     688 
     689    def all_commands_failure(self, failure): 
     690        """ 
     691        Some kind of failure in the commands occurred. 
     692        """ 
     693        e = failure.check( UserBailout ) 
     694        if e: 
     695            #log.error("User bailout detected.") 
     696            self.all_commands_defer.errback( failure ) 
    671697 
    672698class CommandFailure(Exception):