Acionar o manipulador ansible quando uma variável é alterada

3

Gostaria de acionar um manipulador quando uma variável é alterada.

Por exemplo, eu tenho no arquivo de configuração mysql o item de configuração innodb-log-file-size. Gostaria de fazer algumas ações quando este item for alterado:

  • assegura que o MySQL está rodando (devemos começar de um estado estável)
  • executado no mysql: SET GLOBAL innodb_fast_shutdown = 0
  • pare o MySQL
  • mova / var / lib / mysql / ib_logfile [01] para uma pasta de backup
  • inicie o MySQL
  • verifique se o MySQL está rodando bem executando uma consulta MySQL

Veja também: link

O único problema que tenho é como posso determinar que uma variável (na verdade, algum texto específico) foi alterada no arquivo de configuração.

Estou interessado em uma abordagem genérica de como resolver esse problema. Para o meu caso em particular, tenho em mente algumas soluções.

Editar 1: Estou usando o módulo de modelo.

    
por Mircea Vutcovici 04.11.2016 / 13:59

3 respostas

3

Você deve poder assistir ao arquivo em busca de alterações usando incron d. Por exemplo (da documentação vinculada)

_You need to run program 'abc' with the full file path as an argument every time a file is changed in /var/mail. One of the solutions follows:

/var/mail IN_CLOSE_WRITE abc $@/$#  

A página de manual incrontab (5) também é útil e contém outros exemplos.

Isso só será capaz de dizer que o arquivo foi alterado (close_write) não será capaz de dizer o que foi alterado. Para descobrir o que foi alterado, acho que você precisará escrever alguns scripts.

    
por 04.11.2016 / 14:18
2

Para uma solução Ansible pura, você pode definir o innodb-log-file-size com o módulo lineinfile

Assim:

- name: Set innodb-log-file-size for MySQL.
  lineinfile:
    dest: /etc/mysql/my.cnf
    line: 'innodb-log-file-size = {{ innodb_log_file_size }}'
  notify: restart mysql

Você precisaria criar um manipulador para cada ação listada. A tarefa acima só retornaria CHANGED e acionaria o handlers configurado quando o valor de innodb_log_file_size fosse alterado.

Eu presumo aqui que você está usando template module para criar a configuração do mysql. template module retorna CHANGED quando qualquer parâmetro configurado via Ansible no arquivo de configuração for alterado. O módulo lineinfile permite que você acione manipuladores para uma alteração específica.

Esta estratégia tem, no entanto, o efeito colateral ruim que você não pode misturar template e lineinfile module porque nas execuções Ansible subseqüentes, ambas as tarefas sempre retornam CHANGED e portanto quebram a idempotência da peça.

editar

Depois de pensar um pouco sobre o problema, eu recomendaria a seguinte estratégia: verificar via command module, criar via template , verificar novamente via módulo de comando e notificar se o valor foi alterado.

- name: Register innodb-log-file-size in my.cnf
  command: grep -Fxq "innodb-log-file-size" /etc/mysql/my.cnf
  register: innodb_log_file_size_pre
  always_run: True
  ignore_errors: True
  changed_when: False

- name: Create my.cnf via template.
  template:
    src: my.cnf.j2
    dest: /etc/mysql/my.cnf

- name: Restart mysql service when innodb_log_file_size changed
  debug: msg="Restart mysql to activate innodb_log_file_size change"
  when: innodb_log_file_size_pre !== innodb_log_file_size
  notify: restart mysql
    
por 04.11.2016 / 14:34
0

Com base na ajuda recebida das outras respostas, decidi mover a opção em um arquivo separado e acionar a reinicialização + log_expansion quando esse arquivo for alterado. Abaixo estão os detalhes.

No arquivo /etc/my.cnf, adicionei:

!includedir /etc/my.cnf.d

Em roles / mysql / tasks / main.yml eu adicionei:

- name: Create /etc/my.cnf.d MySQL config dir
  file: state=directory name=/etc/my.cnf.d owner=mysql group=mysql mode="u=rwx,go=rx" setype=mysqld_etc_t

- name: Configure innodb_log_file
  template: dest=/etc/my.cnf.d/set_innodb_log_file.cnf src=set_innodb_log_file.cnf.j2 backup=yes mode="u=rw,go=r"
  when: innodb_log_file_size_mb is defined
  register: innodb_log_file

- name: Expand innodb_log_file
  include: expand-innodb-log-file.yml
  static: no
  when: innodb_log_file.changed

roles / mysql / tasks / expand-innodb-log-file.yml:

- name: Stop MySQL
  service: name=mysql state=stopped

- name: Rename old log files
  shell: |
    cd /var/lib/mysql/
    for file in ib_logfile*;do
      mv $file remove-me-$file
    done
  when: mysql_minor_version == 5

- name: Start MySQL
  service: name=mysql state=started

- name: Remove old log files
  shell: rm -f /var/lib/mysql/remove-me-ib_logfile*
  args:
    warn: no
  when: mysql_minor_version == 5

roles / mysql / templates / set_innodb_log_file.cnf.j2:

[mysqld]
innodb_log_file_size = {{ innodb_log_file_size_mb }}M
innodb_log_files_in_group = 2
    
por 04.11.2016 / 20:51