以下是我在 Ansible 中实现的一段代码,它尝试配置 MySQL 复制:
- stat: path=/etc/mysql/ansible.repl
register: check_sql_path
- name: create replicator user
mysql_user:
name: "replicator"
host: "%"
password: "{{ mypass.password_replication }}"
priv: "*.*:REPLICATION SLAVE"
state: present
notify:
- restart mysql
- mysql_replication:
mode: changemaster
master_host: hostvars[inventory_hostname]['ansible_default_ipv4']['address']
master_user: replicator
master_password: "{{ mypass.password_replication }}"
when: check_sql_path.stat.exists == false
notify:
- restart mysql
- command: touch /etc/mysql/repl.ansible
when: check_sql_path.stat.exists == false
但在执行此操作之前,它会检查
check_sql_path.stat.exists is false
当 Ansible 第一次运行时,该变量check_sql_path.stat.exists
被设置为 true,以便第二次调用 Ansible 时,它不会执行这段代码块。
但不知何故,这是在我第二次运行期间执行的,并且我收到以下异常:
==> site: TASK [mysql_replication] *******************************************************
==> site: fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "(1198, 'This operation cannot be performed with a running slave; run STOP SLAVE first'). Query == CHANGE MASTER TO ['MASTER_HOST=%(master_host)s', 'MASTER_USER=%(master_user)s', 'MASTER_PASSWORD=%(master_password)s']"}
==> site: to retry, use: --limit @/vagrant/ansible/playbook.retry
看起来when
Ansible 没有考虑到这个情况。
我也检查了服务器并且该文件/etc/mysql/ansible.repl
是第一次创建的。
知道我在这里可能做错了什么吗?
答案1
您正在检查 是否存在,/etc/mysql/ansible.repl
并且正在touch
上运行命令/etc/mysql/repl.ansible
。文件名不同。
为了避免错误,请使用常量(定义为变量,可能具有有意义的名称)。
还使用一致的 YAML 语法(即不=
与:
-style 混合)和本机模块(file
而不是command: touch
)。
vars:
mysql_repl_flag_path: /etc/mysql/ansible.repl
tasks:
- stat:
path: "{{ mysql_repl_flag_path }}"
register: mysql_repl_flag
# two tasks skipped for clarity
- file:
path: "{{ mysql_repl_flag_path }}"
state: touch
# because it is "touch" operation, the following condition is not necessary:
# when: mysql_repl_flag.stat.exists == false
# it also could be simpler:
# when: not mysql_repl_flag.stat.exists