Trying to use pexpect ansible module to run interactive script

Hi,

I have composed this ansible task using the pexpect module to run a setup.sh script with npm run

  • name: Setup postcodesiodb
    expect:
    echo: yes
    chdir: “/apps/was/postcodes.io”
    command: npm run setup
    timeout: “10”
    responses:
    Question:
  • ‘Postgresql Superuser (for database creation) [default: postgres]’: ‘postgres’
  • ‘New Database Username (for readonly access) [default: postcodesio]’: ‘postcodesio’
  • ‘Password for new user [default: secret]’: ‘secret’
  • ‘Postgresql Host [default: localhost]’: ‘localhost’
  • ‘Database Name [default: postcodesiodb]’: ‘postcodesiodb’
  • ‘Postgresql Port [default: 5432]’: ‘5432’
    tags:
  • setup
  • install
  • test

Below is the only error logging I have but it’s failed at the first input I am attempting to populate here the postgres Super user. Any ideas how I need to pass in these answers and or variables if I don’t want to hard code? Currently it just looks like it is picking up "] characters.

Fatal: [hostname]: FAILED! => {“changed”: true, “cmd”: “npm run setup”, “delta”: “0:02:00.145566”, “end”: “2020-08-25 21:33:22.107526”, “msg”: “command exceeded timeout”, “rc”: null, “start”: “2020-08-25 21:31:21.961960”,

“Postgresql Superuser (for database creation) [default: postgres]:”]}

The wording / syntax of the questions when the script is called is exactly like this:
Postgresql Superuser (for database creation) [default: postgres]:

I have tried various combinations to frame my inputs e.g.

Question:

  • ‘Postgresql Superuser (for database creation) [default: postgres]’: [postgres]

or

  • ‘Postgresql Superuser (for database creation) [default: postgres]’: $postgres

or

  • ‘Postgresql Superuser (for database creation) [default: postgres]’: { postgres }

But they all seem to produce the same error message. The pexpect module documentation is very limited esp in terms of examples. I am not needing to use pexpect if there are other know working solutions to automate this with ansible.

Any ideas much appreciated.

There are a few problems with your task.

  1. Question as used in the example, is supposed to represent the prompt or string to match. So you need to remove that.
  2. The “questions”, prompts, or matches are regex, so you have to escape characters that have special meaning in regex

responses:
‘Postgresql Superuser (for database creation) [default: postgres]’: ‘postgres’
‘New Database Username (for readonly access) [default: postcodesio]’: ‘postcodesio’
‘Password for new user [default: secret]’: ‘secret’
‘Postgresql Host [default: localhost]’: ‘localhost’
‘Database Name [default: postcodesiodb]’: ‘postcodesiodb’
‘Postgresql Port [default: 5432]’: ‘5432’

Legend! I never would have figured this out, so thanking you kindly.

I have hit one error after this: :

“argument responses is of type <type ‘list’> and we were unable to convert to dict”

for which I have managed to nearly resolve it having found a solution to which you again had provided to someone else: : https://groups.google.com/g/ansible-project/c/dDKvb1m5yM8

I now have the ansible task formed liked this:

  • name: Setup postcodesiodb
    expect:
    echo: yes
    chdir: “/apps/was/postcodes.io”
    command: npm run setup
    timeout: “10”
    responses:
    ‘Postgresql Superuser (for database creation) [default: postgres]’: ‘postgres’
    ‘New Database Username (for readonly access) [default: postcodesio]’: ‘postcodesio’
    ‘Password for new user [default: secret]’: ‘secret’
    ‘Postgresql Host [default: localhost]’: ‘localhost’
    ‘Database Name [default: postcodesiodb]’: ‘postcodesiodb’
    ‘Postgresql Port [default: 5432]’: 5432
    tags:
  • setup
  • install
  • test

The task is no longer producing that error and I can see the values being populated with the exception the the final Port value which still does not look to be parsing “5432” correctly. I have tried removing the single quotes around it, to make it clear it is an integer as opposed to a string but that has made no difference. I also can’t see any discrepancies with the escape characters used for regex compared to the previous responses which are now working. Any ideas what I need to do to close this off?

FAILED! => {“changed”: true, “cmd”: “npm run setup”,

Apply read-only privileges for the new user to the new database", “”, “Postgresql Superuser (for database creation) [default: postgres]:postgres”, “New Database Username (for readonly access) [default: postcodesio]:postcodesio”, “Password for new user [default: secret]:secret”, “Postgresql Host [default: localhost]:localhost”, “Database Name [default: postcodesiodb]:postcodesiodb”, “Postgresql Port: [default: 5432]:”]}

OK,

I see what I was doing the wrong. The last question of the interactive script was framed slightly differently and included an extra colon immediately after the word Port which I had omitted:

Postgresql Port: [default: 5432]:

Now I have added this colon to my final response, the pexpect module is working a treat.

Thanks very much for your help.