evertrue / zookeeper-cookbook

Chef cookbook for installing and managing Zookeeper.
https://supermarket.chef.io/cookbooks/zookeeper
Apache License 2.0
81 stars 117 forks source link

Wrapper cookbooks are hard coded to use version 3.4.6 because not using lazy evaluation #151

Closed spuder closed 8 years ago

spuder commented 8 years ago

This is related to https://github.com/SimpleFinance/chef-zookeeper/issues/134

Because the default.rb file sets an attribute based on another attribute, this causes wrapper cookbooks to fail to overwrite the installation path.

Base cookbook

default[:zookeeper][:version]     = '3.4.6'
default[:zookeeper][:config_dir]  = "#{node[:zookeeper][:install_dir]}/" \
                                    "zookeeper-#{node[:zookeeper][:version]}/conf"
If you then do the following in your wrapper cookbook
default[:zookeeper][:version] = '3.4.7'
zookeeper_config "#{node[:zookeeper][:config_dir]}//#{node[:zookeeper][:conf_file]}" do
  config node[:zookeeper][:config]
  user   node[:zookeeper][:user]
  action :render
end

You will get the following error

Recipe: nd-zookeeper::default
         * zookeeper_config[/opt/zookeeper/zookeeper-3.4.6/conf//zoo.cfg] action render
         Recipe: <Dynamically Defined Resource>
           * file[/opt/zookeeper/zookeeper-3.4.6/conf//zoo.cfg] action create
             * Parent directory /opt/zookeeper/zookeeper-3.4.6/conf does not exist.
             ================================================================================
             Error executing action `create` on resource 'file[/opt/zookeeper/zookeeper-3.4.6/conf//zoo.cfg]'
             ================================================================================

             Chef::Exceptions::EnclosingDirectoryDoesNotExist
             ------------------------------------------------
             Parent directory /opt/zookeeper/zookeeper-3.4.6/conf does not exist.

             Cookbook Trace:
             ---------------
             /tmp/kitchen/cookbooks/zookeeper/providers/config.rb:19:in `block in class_from_file'

             Compiled Resource:
             ------------------
             # Declared in

Took me a while to understand what was happening since 3.4.6 is not hard coded anywhere in my wrapper cookbook. This blog post explains it clearly.

https://coderanger.net/derived-attributes/

spuder commented 8 years ago

The work around is to make sure to set the following on the wrapper cookbook in the default attributes

default[:zookeeper][:config_dir]  = "#{node[:zookeeper][:install_dir]}/zookeeper-#{node[:zookeeper][:version]}/conf"
jeffbyrnes commented 8 years ago

Hmm; it’s unclear to me if the derived attributes solution @coderanger proposes can just be used like so:

default[:zookeeper][:version]     = '3.4.6'
default[:zookeeper][:config_dir]  = "%{node[:zookeeper][:install_dir]}/" \
                                    "zookeeper-%{node[:zookeeper][:version]}/conf"

or if more is needed (which his code suggests).

spuder commented 8 years ago

I've been experimenting with this for a couple hours in my fork. No luck yet. I still can't quite wrap my brain around what the correct solution is.

https://github.com/spuder/chef-zookeeper/commit/7380a96aed13ab08e757fe65ae2e9d36d72f391a

Berksfile

source "https://supermarket.chef.io"

metadata

cookbook 'apt'
cookbook 'java'
cookbook 'zookeeper', '~> 2.13.1', github: "spuder/chef-zookeeper", ref: "master"
cookbook 'exhibitor', '~> 0.6.0'

rm Berksfile.lock && berks install

jeffbyrnes commented 8 years ago

In the past, I’ve dealt with this by moving the derived attribute to a recipe, but that won’t necessarily work here, since this cookbook is primarily a library cookbook, and an end-user may not utilize the recipe(s).