Назад | Перейти на главную страницу

Запускать доступный обработчик при изменении переменной

Я хотел бы вызвать обработчик при изменении переменной.

Например, у меня есть в файле конфигурации mysql элемент конфигурации innodb-log-file-size. Я хотел бы сделать пару действий при изменении этого пункта:

Смотрите также: https://dba.stackexchange.com/a/1265/3574

Единственная проблема, с которой я столкнулся, - как определить, что переменная (на самом деле какой-то конкретный текст) была изменена в файле конфигурации.

Меня интересует общий подход к решению этой проблемы. Для моего конкретного случая я имею в виду несколько решений.

Изменить 1: Я использую модуль шаблона.

Вы должны иметь возможность отслеживать изменения в файле, используя Incrond. Например (из связанной документации)

_Вам нужно запускать программу abc с полным путем к файлу в качестве аргумента каждый раз, когда файл изменяется в / var / mail. Одно из решений следующее:

/var/mail IN_CLOSE_WRITE abc $@/$#  

Там incrontab (5) Страница руководства также полезна и содержит дополнительные примеры.

Это только сможет сказать вам, что файл был изменен (close_write), он не сможет сказать вам, что было изменено. Чтобы узнать, что было изменено, я думаю, вам нужно написать несколько скриптов.

Для чистого решения Ansible вы можете установить innodb-log-file-size с участием lineinfile модуль

Как это:

- 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

Затем вам нужно будет создать обработчик для каждого перечисленного вами действия. Задача выше вернет только CHANGED и запустить настроенный handlers когда ценность innodb_log_file_size изменилось.

Я предполагаю, что вы используете template модуль для создания конфигурации mysql. template модуль возвращается CHANGED при изменении любого параметра, установленного через Ansible в файле конфигурации. lineinfile модуль позволяет запускать обработчики для определенного изменения.

Однако у этой стратегии есть плохой побочный эффект, который нельзя смешивать. template и lineinfile модуль, потому что при последующих запусках Ansible обе задачи всегда возвращали CHANGED и тем самым нарушить идемпотентность пьесы.

редактировать

Немного подумав о проблеме, я бы порекомендовал следующую стратегию: проверить через command модуль, создать через template, проверьте еще раз через командный модуль и сообщите, если значение изменилось.

- 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

Основываясь на помощи, полученной из других ответов, я решил переместить параметр в отдельный файл и запустить перезапуск + log_expansion при изменении этого файла. Ниже приведены подробности.

В файле /etc/my.cnf я добавил:

!includedir /etc/my.cnf.d

В ролях / mysql / tasks / main.yml я добавил:

- 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

роли / 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

роли / 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