This ia a post in a series of posts I am doing about MCollective 2.0 and later.
In the past discovery was reasonably functional, certainly at the time I first demoed it around 2009 it was very unique. Now other discovery frameworks exist that does all sorts of interesting things and so we did 3 huge improvements to discovery in MCollective that again puts it apart from the rest, these are:
- Complex discovery language with full boolean support etc
- Plugins that lets you query any node data as discovery sources
- Plugins that lets you use any data available to the client as discovery sources
I’ll focus on the first one today. A quick example will be best.
$ mco service restart httpd -S "((customer=acme and environment=staging) or environment=development) and /apache/" |
Here we are a hypothetical hosting company and we want to restart all the apache services for development. One of the customers though use their staging environment as development so it’s a bit more complex. This discovery query will find the acme customers staging environment and development for everyone else and then select the apache machines out of those.
You can also do excludes and some other bits, these 2 statements are identical:
$ mco find -S "environment=development and !customer=acme" $ mco find -S "environment=development and not customer=acme" |
This basic form of the language can be described with the EBNF below:
compound = ["("] expression [")"] {["("] expression [")"]} expression = [!|not]statement ["and"|"or"] [!|not] statement char = A-Z | a-z | < | > | => | =< | _ | - |* | / { A-Z | a-z | < | > | => | =< | _ | - | * | / | } int = 0|1|2|3|4|5|6|7|8|9{|0|1|2|3|4|5|6|7|8|9|0} |
It’s been extended since but more on that below and in a future post.
It’s very easy to use this filter in your code, here’s a Ruby script that sets the same compound filter and restarts apache:
#!/usr/bin/ruby require "mcollective" include MCollective::RPC c = rpcclient("service") c.compound_filter '((customer=acme and environment=staging) or environment=development) and /apache/' printrpc c.restart(:service => "httpd") |
These filters are combined with other filters so you’re welcome to mix in Identity filters etc using the other filter types and they will be evaluated additively.
These filters also supports querying node data, a simple example of such a query can be seen here:
$ mco service restart httpd -S "fstat('/etc/httpd/conf/httpd.conf').md5 = /51b08b8/" |
This will match all machines with a certain MD5 hash for the apache config file and restart them. More on these plugins the next post where I’ll show you how to write your own and use them.