PatrickWalker
PatrickWalker

Reputation: 550

Apply a chef tag and use straight away with searches

Currently attempting to install a zookeeper ensemble with chef. As part of that in a config file (zoo.cfg) we need to list the servers of the ensemble as below (this file must have the same order accross all members of the ensemble)

initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

So I thought it might be quite nice to have this list generated by searching for nodes which I have tagged as being zookeeper servers. The syntax I'm using is

zk_servers = search(:node, "tags:#{node[:zookeeper][:tag]} AND chef_environment:#{node.chef_environment}")

So my issue is when I go to install and then configure the first server I get no results as there is no SOLR indexed tagged nodes. Is there anyway to enforce that the tag I have applied in an earlier recipe is indexed and searchable within the same run?

I could manipulate the results but I would rather have the search results be more dynamic?

Does Solr only save the tags when the run is completed and we've reported the results?

Upvotes: 2

Views: 767

Answers (1)

Holger Just
Holger Just

Reputation: 55888

Normally, information collected by a node during its Chef run is saved back to the server once at the end of the chef run just before running the report handlers and finishing the run. As such, the Chef server (and its search component) can only index the data after a successful chef run.

That said, you can force a save (and subsequent index of the information collected thus far) by running

node.save

in a recipe. This however is probably not enough as the indexing of the data is asynchronous and might not be finished by the time you query the data again. You could probably wait for some time for the indexing to be complete (i.e. in a loop, query the server, if the current node is included, continue, in not, wait for some seconds and try again).

As this is rather tedious, a common pattern is to search for nodes like you did and then "enriching" the returned data with the current node if applicable. This could look something like this:

zk_servers = search(:node, "tags:#{node[:zookeeper][:tag]} AND chef_environment:#{node.chef_environment}")
zk_servers << node if tagged?(node[:zookeeper][:tag]) && zk_servers.none?{|zk_server| zk_server.name == node.name}

Upvotes: 2

Related Questions