Puppet: System Administration Automated

Support

Ticket #671: puppet-identify.patch

File puppet-identify.patch, 7.1 kB (added by Tobu, 2 years ago)
  • lib/puppet/parser/interpreter.rb

    old new  
    217217        # until we've gotten rid of all of everything or thrown an error. 
    218218        evaliterate(scope) 
    219219 
    220         # Now make sure we fail if there's anything left to do 
    221         failonleftovers(scope) 
    222  
    223220        # Now finish everything.  This recursively calls finish on the 
    224221        # contained scopes and resources. 
    225222        scope.finish 
    226223 
     224        # Now make sure we fail if there's anything left to do 
     225        failonleftovers(scope) 
     226 
    227227        # Store everything.  We need to do this before translation, because 
    228228        # it operates on resources, not transobjects. 
    229229        if Puppet[:storeconfigs] 
  • lib/puppet/parser/ast/resourceoverride.rb

    old new  
    4444 
    4545            # Now we tell the scope that it's an override, and it behaves as 
    4646            # necessary. 
    47             scope.setoverride(obj) 
    48  
    49             obj 
     47            return scope.setoverride(obj) 
    5048        end 
    5149 
    5250        # Create our ResourceDef.  Handles type checking for us. 
  • lib/puppet/parser/ast/resourcedef.rb

    old new  
    112112                # And then store the resource in the scope. 
    113113                # XXX At some point, we need to switch all of this to return 
    114114                # objects instead of storing them like this. 
    115                 scope.setresource(obj) 
    116                 obj 
     115                return scope.setresource(obj) 
    117116            end 
    118117        }.reject { |obj| obj.nil? } 
    119118    end 
  • lib/puppet/parser/resource.rb

    old new  
    8585        @ref.builtin = bool 
    8686    end 
    8787 
     88    def compareparams(other) 
     89        p1, p2 = self.params, other.params 
     90        return false if p1.keys != p2.keys 
     91        p1.each do |k, v| 
     92            return false if p2[k].value != v.value 
     93        end 
     94        return true 
     95    end 
     96 
    8897    # Retrieve the associated definition and evaluate it. 
    8998    def evaluate 
    9099        if klass = @ref.definedtype 
     
    132141        addmetaparams() 
    133142    end 
    134143 
     144    # Check whether resources are identical. 
     145    # Everything but source location is taken into account. 
     146    # Overrides can be identical too. 
     147    # 
     148    # Maybe a self.new method should be written, that only creates instances 
     149    # if no identical instance exists? 
     150    # 
     151    def identical(other) 
     152        return (self.type == other.type and 
     153                self.title == other.title and 
     154                self.virtual == other.virtual and 
     155                self.exported == other.exported and 
     156                self.override == other.override and 
     157                self.compareparams(other)) 
     158    end 
     159 
    135160    def initialize(options) 
    136161        options = symbolize_options(options) 
    137162 
  • lib/puppet/parser/scope.rb

    old new  
    8484        end 
    8585    end 
    8686 
    87     # Verify that the given object isn't defined elsewhere. 
    88     def chkobjectclosure(obj) 
    89         if exobj = @definedtable[obj.ref] 
    90             typeklass = Puppet::Type.type(obj.type) 
    91             if typeklass and ! typeklass.isomorphic? 
    92                 Puppet.info "Allowing duplicate %s" % type 
    93             else 
    94                 # Either it's a defined type, which are never 
    95                 # isomorphic, or it's a non-isomorphic type. 
    96                 msg = "Duplicate definition: %s is already defined" % obj.ref 
    97  
    98                 if exobj.file and exobj.line 
    99                     msg << " in file %s at line %s" % 
    100                         [exobj.file, exobj.line] 
     87    # Returns the original if an identical object exists 
     88    # Throws if an incompatible object exists 
     89    # Retuns nil if neither exists 
     90    def chkoriginal(obj) 
     91        if obj.override 
     92            overs = @overridetable[obj.ref] 
     93            if overs 
     94                overs.each do |over| 
     95                    return over if over.identical(obj) 
    10196                end 
     97            end 
    10298 
    103                 if obj.line or obj.file 
    104                     msg << "; cannot redefine" 
    105                 end 
     99            # Overrides never conflict at this stage 
     100            # (they may conflict in Resource.merge) 
     101            return nil 
     102        end 
    106103 
    107                 raise Puppet::ParseError.new(msg) 
     104        exobj = @definedtable[obj.ref] 
     105        return nil if ! exobj 
     106        return exobj if exobj.identical(obj) 
     107 
     108        #These are not the same, but it's still OK with some types. 
     109        typeklass = Puppet::Type.type(obj.type) 
     110        if typeklass and ! typeklass.isomorphic? 
     111            Puppet.info "Allowing duplicate %s" % type 
     112            return nil 
     113        else 
     114            # Either it's a defined type, which are never 
     115            # isomorphic, or it's a non-isomorphic type. 
     116            msg = "Duplicate definition: %s is already defined" % obj.ref 
     117 
     118            if exobj.file and exobj.line 
     119                msg << " in file %s at line %s" % 
     120                [exobj.file, exobj.line] 
    108121            end 
     122 
     123            if obj.line or obj.file 
     124                msg << "; cannot redefine" 
     125            end 
     126 
     127            raise Puppet::ParseError.new(msg) 
    109128        end 
    110  
    111         return true 
    112129    end 
    113130 
    114131    # Return the scope associated with a class.  This is just here so 
     
    486503    # Add a new object to our object table and the global list, and do any necessary 
    487504    # checks. 
    488505    def setresource(obj) 
    489         self.chkobjectclosure(obj) 
    490  
    491         @children << obj 
    492  
    493506        # Mark the resource as virtual or exported, as necessary. 
    494507        if self.exported? 
    495508            obj.exported = true 
     
    497510            obj.virtual = true 
    498511        end 
    499512 
     513        orig = self.chkoriginal(obj) 
     514        return orig if orig 
     515 
     516        @children << obj 
    500517        # The global table 
    501518        @definedtable[obj.ref] = obj 
    502519 
    503520        return obj 
    504521    end 
    505522 
    506     # Override a parameter in an existing object.  If the object does not yet 
    507     # exist, then cache the override in a global table, so it can be flushed 
    508     # at the end. 
     523    # Mark a resource as an override of another. 
     524    # Cache the override in a global table. 
    509525    def setoverride(resource) 
    510526        resource.override = true 
    511         if obj = @definedtable[resource.ref] 
    512             obj.merge(resource) 
    513         else 
    514             @overridetable[resource.ref] << resource 
    515         end 
     527 
     528        orig = self.chkoriginal(resource) 
     529        return orig if orig 
     530 
     531        @overridetable[resource.ref] << resource 
    516532    end 
    517533 
    518534    # Set defaults for a type.  The typename should already be downcased,