2

I'm trying to gather information on a mysql cluster in order to then use in some local logic.

My trouble is if I run my command on the remote hosts I won't have access to those results

- name: get uuids for existing cluster nodes
  shell: mysql -N -B -u {{ db_user }} -p {{ db_user_password }} -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_state_uuid';" | sed 's/\t/,/g' | cut -f2 -d','
  register: maria_cluster_uuids

This gives me the data I need but what I'd really like is a combined list/dict of the results.

I could try:

- name: get uuids for existing cluster nodes
  run_once: true
  shell: mysql -N -B -u {{ db_user }} -h {{ item }} -p {{ db_user_password }} -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_state_uuid';" | sed 's/\t/,/g' | cut -f2 -d','
  register: maria_cluster_uuids
  with_items: play_hosts
  delegate_to: 127.0.0.1

however, mysql kicks up a warning and to be honest, I don't want to impose a requirement of the local machine having a mysql client installed.

Nasty feeling I'm going to have to write some python here...

  • what's the warning? – xddsg Aug 13 '15 at 17:36
  • not got it to hand as on mobile but basically it's a mysql warning about providing your password in plain view – Jason Aug 14 '15 at 12:47
8

Use set_fact module and hostvars:

---
- hosts: all
  vars:
    uuids: |
      {%- set o=[] %}
      {%- for i in play_hosts %}
        {%- if o.append(hostvars[i].uuid) %}
        {%- endif %}
      {%- endfor %}
      {{ o }}
  tasks:
    - name: get uuids for existing cluster nodes
      shell: mysql -N -B -u {{ db_user }} -p {{ db_user_password }} -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_state_uuid';" | sed 's/\t/,/g' | cut -f2 -d','
      register: maria_cluster_uuids
    - set_fact:
        uuid: "{{ maria_cluster_uuids.stdout }}"
    - debug:
        var: uuids
      run_once: true
      delegate_to: 127.0.0.1
  • YES! this is it. Thanks a lot @yaegashi! So much tidier and now I can delete all that Python code \o/ – Jason Aug 17 '15 at 9:25
1

Would it help to write the output of the mysql command on the local host or ansible host, and keep on appending the results from all the servers. Once done, you can parse that file within your playbook, or even write a parser script and execute if from the playbook.

Collecting the output would look something like this -

---
- hosts: production
  tasks:
  - name: get uuids for existing cluster nodes
    shell: mysql -N -B -u {{ db_user }} -p {{ db_user_password }} -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_state_uuid';" | sed 's/\t/,/g' | cut -f2 -d','
    register: maria_cluster_uuids

  - name: Write to local disk
    lineinfile: dest=/tmp/mysqlcluster create=yes line="{{ maria_cluster_uuids.stdout_lines }}"
    delegate_to: 127.0.0.1

Then you can parse /tmp/mysqlcluster file.

  • 1
    if you run this with multiple hosts you will need to run in serial:1 or with --forks=1. otherwise the default of 5 threads will intermittently overwrite each other's output in the file. – Mike D Aug 13 '15 at 2:25
  • i was hoping to avoid writing to files and do things a bit "purer" I guess but thanks for the suggestion. For now I've written a python script to do it for me but I wouldn't call it an Answer as such so will leave this open. For those who are interested: gist.github.com/h1ppo/9473cf624bf5456522a8 – Jason Aug 13 '15 at 10:45
  • @MikeD - I agree. Another not pretty way of getting around this is to use the shell module and do an append redirection >>. – Daniel t. Aug 15 '15 at 19:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.