From e8e9612527a833a89477a09f95545ba2604cd667 Mon Sep 17 00:00:00 2001 From: Hungerdream <1710233908@qq.com> Date: Mon, 27 Jul 2026 15:17:46 +0800 Subject: [PATCH] fix(ansible): use dict-form shell tasks with explicit bash Free-form split_args breaks on quotes/Jinja at AWX runtime, and default dash rejects pipefail. --- ansible/mysql-deploy.yml | 74 +++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/ansible/mysql-deploy.yml b/ansible/mysql-deploy.yml index fb07795..ceb7fbb 100644 --- a/ansible/mysql-deploy.yml +++ b/ansible/mysql-deploy.yml @@ -89,18 +89,19 @@ run_once: true - name: Probe target-host port occupancy (SQL + GR) - ansible.builtin.shell: | - set -o pipefail - for p in {{ mysql_probe_ports | join(' ') }}; do - if ss -lntH "sport = :${p}" | grep -q .; then - # already listening: only tolerated when owned by this instance service - if ! systemctl is-active --quiet "mysql-delivery@{{ mysql_instance }}.service"; then - echo "port ${p} already in use on target host" >&2 - exit 3 + # cmd 字典形式不经过 free-form split_args 解析,避免引号/Jinja 块导致的解析失败。 + ansible.builtin.shell: + cmd: | + set -o pipefail + for p in {{ mysql_probe_ports | join(' ') }}; do + if ss -lntH "sport = :${p}" | grep -q .; then + # already listening: only tolerated when owned by this instance service + if ! systemctl is-active --quiet "mysql-delivery@{{ mysql_instance }}.service"; then + echo "port ${p} already in use on target host" >&2 + exit 3 + fi fi - fi - done - args: + done executable: /bin/bash vars: mysql_probe_ports: "{{ [mysql_port_value, mysql_gr_port_value] if topology == 'mgr_3' else [mysql_port_value] }}" @@ -284,32 +285,33 @@ timeout: 60 - name: Configure local administrative accounts - ansible.builtin.shell: | - set -euo pipefail - client_file="$(mktemp)" - sql_file="$(mktemp)" - trap 'rm -f "$client_file" "$sql_file"' EXIT - chmod 600 "$client_file" "$sql_file" - cat >"$client_file" <<'EOF' - [client] - user=root - password={{ mysql_root_password_value }} - socket={{ mysql_run_dir }}/mysql.sock - EOF - if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then + # cmd 字典形式不经过 free-form split_args 解析,heredoc SQL 中的奇数个单引号才不会报错。 + ansible.builtin.shell: + cmd: | + set -euo pipefail + client_file="$(mktemp)" + sql_file="$(mktemp)" + trap 'rm -f "$client_file" "$sql_file"' EXIT + chmod 600 "$client_file" "$sql_file" + cat >"$client_file" <<'EOF' + [client] + user=root + password={{ mysql_root_password_value }} + socket={{ mysql_run_dir }}/mysql.sock + EOF + if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then + cat >"$sql_file" <<'EOF' + ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}'; + EOF + /usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file" + fi cat >"$sql_file" <<'EOF' - ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}'; - EOF - /usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file" - fi - cat >"$sql_file" <<'EOF' - CREATE USER IF NOT EXISTS 'xinfra_admin'@'%' IDENTIFIED BY '{{ mysql_admin_password_value | replace("'", "''") }}'; - ALTER USER 'xinfra_admin'@'%' IDENTIFIED BY '{{ mysql_admin_password_value | replace("'", "''") }}'; - GRANT ALL PRIVILEGES ON *.* TO 'xinfra_admin'@'%' WITH GRANT OPTION; - FLUSH PRIVILEGES; - EOF - /usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file" - args: + CREATE USER IF NOT EXISTS 'xinfra_admin'@'%' IDENTIFIED BY '{{ mysql_admin_password_value | replace("'", "''") }}'; + ALTER USER 'xinfra_admin'@'%' IDENTIFIED BY '{{ mysql_admin_password_value | replace("'", "''") }}'; + GRANT ALL PRIVILEGES ON *.* TO 'xinfra_admin'@'%' WITH GRANT OPTION; + FLUSH PRIVILEGES; + EOF + /usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file" executable: /bin/bash changed_when: false no_log: true