[chef] Re: Including Cookbooks Conditionally


Chronological Thread 
  • From: Adam Jacob < >
  • To:
  • Subject: [chef] Re: Including Cookbooks Conditionally
  • Date: Sun, 25 Apr 2010 10:06:45 -0700

On Sat, Apr 24, 2010 at 10:45 AM, Chad Woolley 
< >
 wrote:
> New to chef, and trying to get my head around best practices.
>
> I'm using Chef to automate the building of EC2 AMI images (from an EC2
> instance).  This is a bit of a special case, because I'm running chef
> from within a chroot environment, so I can't start services.
>
> So, I can see four categories of cookbooks I need:
>
> A. Third party cookbooks
> B. My own original cookbooks to perform specific tasks (e.g.
> installing required dev packages)
> C. Cookbooks which perform necessary overrides to third party
> cookbooks (e.g. I find a bug in the third party cookbook)
>
> These first three categories are "normal", and should be able to run
> in the chroot environment, and also be run to update/fix EC2 images
> which are created from the built AMI.  However, the fourth is a
> special case:
>
> D. Cookbooks which perform overrides to third party cookbooks, in
> order to prevent services from automatically
> starting/stopping/restarting (which will fail in a chroot env).
>
> Obviously, I only want to include this category when I'm building the
> AMI, but not when running normally on an instance started from the
> AMI.
>
> So, questions:
>
> * Does anything sound wrong about this approach
> * How should I organize these cookbooks?  I can have a custom repo,
> which includes all the third-party cookbooks (A) as submodules, and
> the others (B,C,D) checked in directly.  However, I would want to
> conditionally exclude "D" from running if I'm not in a chroot
> environment.
>
> Seems like I want to use "Roles" here to do some conditional logic
> based on whether I'm in chroot env or not, but I'm not sure what it
> should look like.  I'm not even really sure where to stick the logic.
> Right now I just have cookbooks listed in the 'cookbook_path' array in
> node.rb.  I'm having problems finding detailed examples online which
> are similar to what I want to do.  Pointers to docs/examples would be
> greatly appreciated.

Interesting use case.

For your wanting to make sure that no services get restarted, you can
probably do something like this.  Make sure it's the last recipe in
the run list:

collection.each do |r|
  # Switch every service resource off
  r.action :nothing if r.resource_name == :service
  # Find all notified/subscribed actions on services and switch them off too
  r.actions.each do |action, timings|
    timings.each do |timing, resources|
      resources.each do |notified_resource|
        notified_resource.action :nothing if
notified_resource.resource_name == :service
      end
    end
  end
end

That's off the top of my head, so it may not run.  But the idea here is:

If you are running in the chroot, and we don't want any service
actions to be taken, we walk the resource collection and set the
action for every service resource we encounter to :nothing.  The
result will be that no service resources are ever run, no matter what
changes happen in the cookbooks you add.

The only caveat is that this must be the *last* recipe in the
run-list, or you're not certain to have seen every possible resource
in the collection.

The benefit should be obvious - just include this recipe when you want
to do your chroot sauce, and skip the need to do complicated overrides
entirely.

Adam
-- 
Opscode, Inc.
Adam Jacob, CTO
T: (206) 508-7449 E: 




Archive powered by MHonArc 2.6.16.

§