Reputation: 1297
This has been irritating me for the past hour, I use Ansible's expect module to answer to a command prompt, namely:
Re-format filesystem in Storage Directory /mnt/ephemeral-hdfs/dfs/name ? (Y or N)
for which I want to reply
Y
This should work according to standard regex matching and this other stackoverflow question
- name: Run Spark Cluster script
expect:
command: /home/ubuntu/cluster_setup/scripts/shell/utils-cluster_launcher-start_spark.sh
responses:
"Re-format filesystem": "Y"
timeout: 600
echo: yes
The issue I am facing is that when it reaches the point where it expects keyboard input it doesn't get anything, therefore it hangs. There is no error output as such; it just stays still.
Any ideas how to fix this?
Upvotes: 1
Views: 8619
Reputation: 2591
I know this is old but I had the same trouble with this module and these answers didn't help, however I did find my own solutions eventually and thought I'd save people some time.
First the timeout in the poster's example is 10 minutes. Though this makes sense for a reformat, it means that you need to wait 10 minutes before the script will fail. e.g. If it is stopped waiting for a response to "Are you sure?". When debugging keep that timeout low and if you can't then wait patiently.
Second the fields in the responses are listed alphabetically so
responses:
"Test a specific string": "Specific"
"Test": "General"
Will always respond to ALL messages containing Test with General as that is the first alphabetically in the responses map.
Third (following on) this caught me out because in my case expect was simply hitting enter at the prompt and the script asked again for valid data. The problem then is that my timeout never fires and nothing gets returned so I don't see any response from the module, it just hangs. The solution in this case is to go to the server you are provisioning with Ansible, find the command Ansible is running with ps and kill it. This allows Ansible to collect the output and show you where it is stuck in an infinite loop.
Upvotes: 0
Reputation: 68529
The task from the question works properly on the data included in the question:
---
- hosts: localhost
gather_facts: no
connection: local
tasks:
- name: Run script producing the same prompt as Spark Cluster script
expect:
command: ./prompt.sh
responses:
"Re-format filesystem": "Y"
timeout: 600
echo: yes
register: prompt
- debug:
var: prompt.stdout_lines
Contents of the ./prompt.sh
:
#!/bin/bash
read -p "Re-format filesystem in Storage Directory /mnt/ephemeral-hdfs/dfs/name ? (Y or N) " response
echo pressed: $response
Result:
PLAY [localhost] ***************************************************************
TASK [Run script producing the same prompt as Spark Cluster script] ************
changed: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"prompt.stdout_lines": [
"Re-format filesystem in Storage Directory /mnt/ephemeral-hdfs/dfs/name ? (Y or N) Y",
"pressed: Y"
]
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
Upvotes: 2
Reputation: 4089
The Ansible documentation for expect does not have quotes around the regex in the example.
# Case insensitve password string match
- expect:
command: passwd username
responses:
(?i)password: "MySekretPa$$word"
Maybe try:
Re-format\sfilesystem: "Y"
Upvotes: 1