Parsing for win_updates reboot hint

Hello, all.

With help from the list, I have windows updates working via the rewritten win_updates module found here. I’m now looking for a way to creat a reboot hint based on the return output. Here’s what that output partially looks like when I run the module (using -v):

changed: [sawintest02] => {“changed”: true, “failed_update_count”: 0, “found_update_count”: 23, “installed_update_count”: 23, “reboot_required”: true, “updates”: {“04f04253-f803-43b8-8b37-6841c614dd9f”: {“id”: “04f04253-f803-43b8-8b37-6841c614dd9f”, “installed”: true, “kb”: [“3084135”], “title”: “Security Update for Windows Server 2012 R2 (KB3084135)”}, ~

How would I parse this output to create a hint so that a reboot will be done if “reboot_required”: true, and nothing be done if “reboot_required”: false,

I’m a terrible programmer, so your help is greatly appreciated.

Dimitri

You need to use ‘register’ to capture the results into a variable: http://docs.ansible.com/ansible/playbooks_variables.html#registered-variables

Then you can call another module to do the reboot followed by a ‘when’, probably something like

when: result_var.reboot_required

worth having a look at Trond Hindenes’ win_reboot role in galaxy too: https://galaxy.ansible.com/list#/roles/4576

Thanks, Jon.

This should work?:

  • name: win update
    win_updates:
    category: [‘SecurityUpdates’,‘CriticalUpdates’,‘Updates’,‘Tools’,‘DefinitionUpdates’,‘UpdateRollups’]
    register: reboot_hint

  • name: reboot server
    raw: ‘cmd /c shutdown /r /t 0’
    when: reboot_hint.stdout.find(‘“reboot_required”: true’) != -1

I’ll also be sure to take a look at Trond’s win_reboot role in galaxy.

The above doesn’t work. If I run as-is, then I get the following error:

when: reboot_hint.stdout.find(‘“reboot_required”: true’) != -1
^
This one looks easy to fix. There seems to be an extra unquoted colon in the line
and this is confusing the parser. It was only expecting to find one free
colon. The solution is just add some quotes around the colon, or quote the
entire line after the first colon.

I have to parse for “reboot_required”: true, since if no reboot is required, output is “reboot_required”: false. Neither quoting the second colon nor the entire line after the first colon work. How do I correct for this?

I suggest you add a debug on the registered variable and/or run ansible-playbook with -v
this will show you the contents of the registered variable. It will be some JSON. Sometimes its useful to paste the JSON into http://jsonlint.com/ so you can see a pretty printed version of the JSON.

then it should be fairly straightforward to work out what you need in the when:

I think

when: reboot_hint.results.reboot_required

might be enough or possibly

when: reboot_hint.results.reboot_required == true

Hope this helps.

Jon

Jon,

Both of your suggestions work; thanks!

For my edification, why do either work when “reboot_required”: true, and not “reboot_required”: false, or why don’t they simply resolve against “reboot_required” (without true or false)?

Dimitri

Breaking it down a bit

reboot_hint

is the name of the variable you have chosen to store the registered output in.

Inside reboot_hint is the output from the module. The module results are put into a key value structure with a key of results. This is probably done to keep the structured module output separate from other things that might come out of the module (like stdout and stderr contents). Within results there are more key-and-value pairs, and the one we are interested in is reboot_required.

So that gets us to

reboot_hint.results.reboot_required

For when: to be useful it need to receive the some kind of test result - something that is either true or false. We are in luck here because
reboot_required contains a value of false or true so when: can use that directly.

To make a slightly silly example, if reboot_required returned a string like “next_wednesday” then you would have to write the when: like this

when: reboot_hint.results.reboot_required == “next_wednesday”

There’s a lot more you can do with this. Two things that are well worth understanding are the kinds of things you can put in module output - well worth a read of the JSON spec which is only 1 page and can be found here: www.json.org and the other is getting an idea of the things you can do with variables using filters in Ansible see http://docs.ansible.com/ansible/playbooks_filters.html for ansible’s built in filters and here for the full list of stuff that jinja2 (which ansible uses) can do. http://jinja.pocoo.org/docs/templates/#builtin-filters

Hope this helps,

Jon

Thank you so much for the explanation. I understand it, but am curious as to why “reboot required”, without == true or == false, will reboot the server if true is, in fact, returned, and not reboot if false is returned. Does “when” default to true if no argument is explicitly provided?

the when: doesn’t really default to true. Instead when: just needs to ‘see’ a true or a false. It doesn’t care if that is from finding a value of true or false by looking up what is stored in a variable or by running something that returns a true or false.

adding the ‘== true’ makes the when: test that reboot_required is set to true. Without it, the when: just sees the contents of the reboot_required variable (which happens to be either true or false).

Hope that helps

Jon