On Jun 6, 2008, at 5:07 AM, Paul Lathrop wrote:

>
> After thinking about it for a bit, I thought I'd take a crack at
> adding upwards recursion to the file type (Ticket #86). It seemed to
> me that this would be relatively easy. Upwards recursion is *much*
> simpler than downwards recursion in this case; everything upwards of
> the resource is always going to be  simple file resource. We might
> want to propagate permissions and ownership in some way, but I haven't
> gotten that far yet. I'm not sure what I'm not understanding about how
> this should work, so I thought I'd hit up the list for some advice.
>
> I decided that since this was simpler than downwards recursion, and we
> might want to do both, to add a parameter called :makeparents. Adding
> the parameter was easy, and works as expected. Implementing the
> behavior behind the parameter is giving me some trouble. Here's what I
> have so far (in Ruby-like pseudocode with 'comments' that explain my
> thought process):
>
> # This is called from eval_generate(), like recurse().
> def makeparents
>    # First I want to generate a list of the parent directories.
>    # I don't want the path of the resource I'm defining in this list,
>    # so I start one level up the tree
>    path = File.dirname(self[:path])
>    stack = []
>    until path == stack.last do
>        stack.push(path)
>        path = File.dirname(path)
>    end
>
>    # Make local copy of arguments so I can apply them to created
>    # parent resources.
>    args = symbolize_options(@arghash)
>
>    # Parents are made in one pass, so we don't want the
>    # created resources to try to make their own parents.
>    args.delete(:makeparents)
>
>    # Parents will, be definition, always be directories. On second  
> thought,
>    # they might be symlinks, but, again, I haven't gotten that far  
> yet.
>    args[:ensure] = :directory
>
>    # Now for all of the parent paths we want to generate new
>    # resources. I start at the top (stack.reverse_each) so that it is
>    # easy to hook each resource to its parent.
>    parent = nil
>    stack.reverse_each do |path|
>        # This is to avoid setting :parent for /
>        args[:parent] = parent unless parent.nil?
>        args[:path] = path

Puppet will handle the parent stuff; you don't need to worry about it.

There's plenty of essentially deprecated code here, I think; when  
Puppet still used a tree instead of a graph for the catalog, the  
parent mattered a lot, but now it can be determined from the graph,  
and really, it doesn't matter except for logging.

You might need to set up a relationship between the generated and  
generating resource, but otherwise it shouldn't be a big deal.

>
>        # If there is already a resource in the catalog for this
>        # directory, we should just use it.
>        if current = catalog.resource(:file, path)
>            # pseudocode: I can't figure out how to use an existing
>            # resource. When I was trying tests, adding a file
>            # resource for something somewhere up the tree caused my
>            # code to not even be run anymore.
>            somehow.use(current)

Just ignore these:

   next if catalog.resource(:file, path)

>
>        else
>            # Ignoring the debug lines, I thought this would be how I
>            # generated the new resource.
>            notice "Creating new file with args %s" % args.inspect
>            current =  
> catalog.create_implicit_resource(self.class.name, args)
>            puts "created %s" % current["path"]
>        end
>        parent = current
>    end
> end
>
> Here are some things that are puzzling me:
> 1) Is it enough to just create resources and return them to
> eval_generate()? Will Puppet then know to apply them?

Kind of.  If you look where the transaction uses eval_generate, you'll  
see a call to 'depthfirst?'.  This basically provides a boolean for  
evaluating the created resources first or last.

In this case, it looks like you'll need to switch this boolean, which  
would probably be annoying, since it would mean a give file could  
generate its parents or its children, but not both.

In looking at the code, I think it makes more sense to put both the  
generating resource and all of its generated resources into a separate  
graph, sort that graph, and then apply each resource in order.  This  
way you'd still get the ability to use relationships to manage the  
ordering.

I'm glad to work with you to get this done.

>
> 2) Am I working too hard to get :parent set? Does Puppet know enough
> about directory structures to figure that out?

Yeah, you're working too hard; ignore it.

>
> 3) Here is my "test" (not the actual unit tests I am writing, just an
> exploratory programming thing) that I am using to figure this out:
>
> describe "when creating parent resources" do
>    include PuppetTest
>    require 'tempfile'
>
>    before do
>        @basedir = tempfile
>        @path = File.join(@basedir, "foo/bar/baz")
>        @resource = Puppet.type(:file).create(:path => @path, :ensure
> => :present, :content => "foo", :makeparents => true)
>    after do
>        remove_tmp_files
>    end
>
>    it "should help me understand Puppet internals" do
>        @catalog.add_resource @resource
>        # These are commented out because when I add them, the
>        # :makeparents parameter of @resource is completely ignored
> #         resource = Puppet.type(:file).create(:path =>
> File.dirname(@path), :ensure => :directory)
> #         @catalog.add_resource resource
>        @catalog.apply
>    end
> # Actual unit tests that are all pending snipped because I'm just
> trying to figure out how this works at this point.
> end
>
> 3 [cont.]) Is this enough to supposedly create the resource and apply
> it? If I add FileTest.exists?(@path).should be_true() at the end, it
> fails. What am I missing?
> 4) How is eval_generate supposed to be used?

Hopefully my above comment was sufficient, and in this case, the best  
you can hope for is RTFC.

-- 
I have never met a man so ignorant that I couldn't learn something
from him. --Galileo Galilei
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to