在 Ansible 中模拟 Enter 键

在 Ansible 中模拟 Enter 键

我正在尝试创建一个剧本来运行 mysql_secure_installation 命令。

该命令询问几个问题。我正在使用 pexpect,但不确定如何模拟“输入” 它询问的第一个问题是“输入 root 密码” 我不想输入 root 密码。 sql server 只能是本地的。

- name: "Secure MariaDB"
  expect:
    command: /bin/mysql_secure_installation
    responses:
      Question:
        - ''          #I want to have ansible hit enter
        - 'n'         # Type n
        - 'y'         # Type y
        - 'y'         # Type y
        - 'y'         # Type y
        - 'y'         # Type y

我尝试过使用“”、命令/bin/bash -c "echo",甚至只是一个空行,但我不断收到下面的响应。

FAILED! => {"changed": true, "cmd": "/bin/mysql_secure_installation", "delta": "0:00:30.128184", "end": "2018-08-29 18:54:30.983455", "msg": "non-zero return code", "rc": 1, "start": "2018-08-29 18:54:00.855271", "stdout": "\r\nNOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB\r\n      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!\r\n\r\nIn order to log into MariaDB to secure it, we'll need the current\r\npassword for the root user.  If you've just installed MariaDB, and\r\nyou haven't set the root password yet, the password will be blank,\r\nso you should just press enter here.\r\n\r\nEnter current password for root (enter for none): ", "stdout_lines": ["", "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB", "      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!", "", "In order to log into MariaDB to secure it, we'll need the current", "password for the root user.  If you've just installed MariaDB, and", "you haven't set the root password yet, the password will be blank,", "so you should just press enter here.", "", "Enter current password for root (enter for none): "]}

答案1

成功了。事实证明,有些内容被识别为正则表达式特殊字符。

- name: "Secure MariaDB"
  expect:
    command: /bin/mysql_secure_installation
    responses:
      'Enter current password for root \(enter for none\): ': ''
      'Set root password\? \[Y\/n\] ': 'n'
      'Remove anonymous users\? \[Y\/n\] ': 'y'
      'Disallow root login remotely\? \[Y\/n\] ': 'y'
      'Remove test database and access to it\? \[Y\/n\] ': 'y'
      'Reload privilege tables now\? \[Y\/n\] ': 'y'
    echo: yes

答案2

根据,您只需指定一个空字符串; Ansible 会自动跟随“enter”。

如果这不起作用,还有另一个建议这里用于/bin/bash -c "echo"答案。

答案3

根据模块文档 expect被标记为预览版,因此可能会发生变化,并且该模块非常简单。使用脚本可能更明智expect;这将允许检测每个问题,并且能够在问题在某些新版本中发生变化时失败mysql_secure_installation(或者如果有人偷偷溜进来并在rootmysql 帐户上输入密码,或者......)

然而,这需要更多的工作,因为expect可能需要安装软件包并将脚本复制到系统,详细信息将根据所涉及的端口或软件包系统以及本地脚本的确切安装位置而有所不同(希望安装到不受信任的本地用户无法读取的位置)或运行它们...)

- name: install packages for centos
  yum: name={{ item }} state=present
  with_items:
    - expect
    ...
- name: copy script
  copy: src=root/bin/do-setup-mysql dest=/root/bin/do-setup-mysql ...
- name: initial setup of mysql
  command: /root/bin/do-setup-mysql
  args:
    creates: /todofixme

然后脚本do-setup-mysql可能会这样开始:

#!/usr/bin/env expect
proc die {msg} { puts stderr $msg; exit 1 }
#log_file /root/do-setup-mysql.log
spawn -noecho mysql_secure_installation
expect "Enter current password for root"
send "\r"
expect {
    timeout { die "timeout before response" }
    "Access denied" { die "root password already set" }
    "Setting the root password" {}
}
expect "Change the root password"
send "n\r"
...

其余问题依此类推。该脚本必须 create /todofixme,或者该文件可以是由已知创建的文件,mysql_secure_installation以便初始设置不会运行每个 ansible 运行。

相关内容