Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

fix adding nil if hostname isn't set up first #18

Merged
merged 6 commits into from May 29, 2015

Conversation

TD-4242
Copy link
Contributor

@TD-4242 TD-4242 commented May 20, 2015

This one small block of code had caused me more headache then anything else so I wanted to send a fix.

In my chef runs the hostname may not be setup prior to the first run so I would always get a compile error if cerner_kafka was in my run_list with:

undefined method `+' for nil:NilClass

Then the entire run would die and it would never setup the host. by moving the brokerId increment after the check and using a return I can now bail out of the cerner_kafka cookbook on my first run and allow the host to be setup and kafka can get setup on a consecutive run. I also added a bit better message to output so I could see what each item was set to and what it was looking for.

A better way may be to do a lazy evaluation of the broker ID prior to writing the template.

if brokerId.nil?
errors.push "Unable to find node in node[:kafka][:brokers] : #{node["kafka"]["brokers"]}"
return "Unable to find #{node["fqdn"]}, #{node["ipaddress"]} or #{node["hostname"]} in node[:kafka][:brokers] : #{node["kafka"]["brokers"]}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is return correct here? I would think errors.push would be what we want.

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 20, 2015

I tried with errors.push but then the next line where we increment the brokerId errors with the undefined method +' for nil:NilClass` message halting the chef run. Using the return logs the message but continues the chef run without processing the rest of the recipe. This allows my other recipes to configure the hostname and default setup and kafka will work on the next chef-client run.

Like I mentioned it can probably be done better by moving all the logic to the template generation and use lazy loading for the variables. This would allow the rest of the chef run to complete and still configure kafka in the first path.

I'll dig a little deeper and see what's required to do this.

@bbaugher
Copy link
Member

Ugh duh should learn to read better. If we don't assign a broker id I'm not sure if kafka will start.

Your work around of not running the recipe seems reasonable but conflicts with someone mis-configuring their node and us not being able to come up with an id. It does seem to log a message about it but that assumes someone is watching and possibly watching closely.

If you really need to run chef twice in this instance would it be worth trying to use an override run list the first time?

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 20, 2015

A single pass client run is of course ideal. I'd really just like for my host setup stuff to run before failing the chef run. As it was it wouldn't even compile the run_list unless the servers hostname was in the brokers list. If I could get the rest of the chef run to run first then check if the brokerId can be set and bail on error at that point I think it would work out better overall. At least if the kafka recipe is run last the host should be in a mostly configured state and ready for a second run after fixing the settings.

I'm trying to set this up to automatically deploy with chef-provisioning in a completely hands off manner, and allow for semi-auto up scaling if needed.

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 20, 2015

re-arranged a few things. I still have it return on any errors so the run will complete, but it pushes the errors to the array like it did before.

I also removed some unneeded checks and cast the brokers to an array prior to checking it. This would allow you to specify a single broker as a string.

@bbaugher
Copy link
Member

Can we make the behavior to ignore errors and continue an attribute and by default keep the behavior as it was before?

@bbaugher
Copy link
Member

Should have asked this earlier but if we just make the check run during converge instead of compile will that work for you? We should just be able to wrap that ruby code in a ruby_block.

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

I had the same idea and tried just wrapping it in a ruby_block and it didn't seem to update the node object. I wasn't sure if i was doing it right so I backed that out and made this change. having a continue_on_errorr attribute default to false would be fine as well. Although if it could be moved to converge phase I think that wold be the 'chef' way to do it.

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

Ok, i just retried this and tested it in kitchen. I'll update in a second if you want to take a look. When I unset broker.id in .kitchen.yml I got:

 Recipe: cerner_kafka::default


           ================================================================================
           Error executing action `run` on resource 'ruby_block[assert broker and zookeeper lists are correct]'
           ================================================================================

           RuntimeError
           ------------
           Unable to run kafka::default :
            -node[:kafka][:brokers] or node[:kafka][:server.properties][:broker.id] must be set properly]

           Cookbook Trace:
           ---------------
           /tmp/kitchen/cookbooks/cerner_kafka/recipes/default.rb:36:in `block (2 levels) in from_file'

           Resource Declaration:
           ---------------------
           # In /tmp/kitchen/cookbooks/cerner_kafka/recipes/default.rb

         9: ruby_block 'assert broker and zookeeper lists are correct' do
...

if I set kafka.brokers to [test1,test2] I get:

       Error executing action `run` on resource 'ruby_block[assert broker and zookeeper lists are correct]'
           ================================================================================

           RuntimeError
           ------------
       Unable to run kafka::default :
            -Unable to find kafka, 10.0.2.15 or kafka in node[:kafka][:brokers] : ["test1", "test2"]]

which should be a little more helpful of an error message because you'll see what it's actually looking for if your hostname isn't in the array.

adding kafka (the hostname set in kitchen) to the list it runs as normal with the brokerId based on the array index.

I think this should cover everyone's expectations, am I right?

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

working on the rspec tests now

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

I think chefspec is overriding the code in the ruby_block and not allowing it to execute. Makes sense because if you had something in there to modify the host it would do it to the host running the tests. I'm not sure how to test it other than with an assertion that the ruby_block is there...

@bbaugher
Copy link
Member

I think I'm ok with us not verifying that behavior anymore in chefspec. If we are really worried about we can move the code to a library and test that.

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

ok, i was able to get all the current tests to run with chefdk 0.5.1 lets see if the work in travis under the older version of chefspec.

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

something's not right. The block is running but I don't think it's updating the node object.

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

OK, i found it. because the assignment is happening now at converge time the empty array is being assigned to the template resource for zookeepers and brokerid. I changed those to lazy evaluation so they will be set at run time after the ruby_block

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

Of course now foodcritic is telling us to just make it a library like you suggested earlier.

Ok, not sure I can get to that today. let me see how some of these other deployments go.

@bbaugher
Copy link
Member

I'm fine with ignoring foodcritic for now about this. You can fix it by changing this line, https://github.com/cerner/cerner_kafka/blob/master/Rakefile#L29

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 21, 2015

I added the comment way to disable foodcritic warnings, that allows it to stay visible and works as a reminder that that section of code isn't as awesome as it could be.

@bbaugher
Copy link
Member

I can't remember where we left off but this looks good to me if you are fine with it

@TD-4242
Copy link
Contributor Author

TD-4242 commented May 28, 2015

I'm using it with chef provisioning to deploy kafka to aws and it's working well.

@bbaugher
Copy link
Member

@noslowerdna or @mkwhitacre can you take a look at this?

@bbaugher bbaugher added this to the 1.1.0 milestone May 29, 2015
@mkwhitacre
Copy link
Member

+1

bbaugher added a commit that referenced this pull request May 29, 2015
fix adding nil if hostname isn't set up first
@bbaugher bbaugher merged commit 810283c into cerner:master May 29, 2015
@bbaugher
Copy link
Member

@TD-4242 Thanks for the pull!

@bbaugher
Copy link
Member

@TD-4242 do you mind opening a pull request to add yourself as a contributor.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants