Puppet: System Administration Automated

Support

There are two clear use cases for Puppet using its own objects internally, and it is not terribly easy to do so in either case.

For instance, Puppet File objects can back themselves up when they are modifying themselves, yet they use Ruby's internal File Utils?.cp method to do so. This works fine for most cases, but it appears that the functionality of this method is not consistent across Ruby versions, so extra work has to be done to make sure the copy has the correct modes and ownership. Once this work is done, it's clear that the copy should just be another Puppet File instance. This is not easy to do right now, though, because of how transactions and instance hierarchies work; it just wasn't something I was thinking about when planning the internals.

Another use case is more complicated: Puppet objects should sometimes use other objects as values to an attribute. For instance, a File should be use a User object as the value to "owner". This allows it to reuse the User object's ability to retrieve the user's UID (which is needed because Ruby's chown method only accepts numbers, not names). I could also see a service's configuration file specifying a Port object as a value rather than a port number; this way, Puppet could keep track of the fact that this port number is consumed, and report an error if some other service tries to run on the same port.

Being able to use an object as a value should also take care of most validation for that value. In the case of File, you could have something like this:

Puppet::Type.newtype(:file) do
    newstate(:owner) do
        is_a :user, [:name, :uid]
    end
end

In other words, the value to the owner state should map to a user object, and it can be specified by either the user's name or UID. Puppet should automatically handle validation of the input, since the User object already knows how to valid UID and user name values, and it should list the user object as a dependency so that it is automatically applied first. One nice thing this would do in validation is that Puppet could automatically check if the user object either exists or will be created by Puppet, which would catch a lot of edge cases that crop up where Puppet is creating and using an object in a single run.

I'm guessing a lot of this modeling can copy aspects of how Rails does object associations.