The input device is not a TTY

Hi everyone,

I’m fairly new to ansible and I stumbled across a problem which I’m unable to solve.

Problem
It occurs when I try to run a playbook that should execute two commands (proprietary sw).
The error is either “the input device is not a TTY” or it just hangs with python indend errors depending on the -t or -tt flag for ssh.

Hosts file

[SERVERS]
server ansible_host=** dest ip **

[SERVERS:vars]
ansible_user = test2
ansible_port = 22
ansible_private_key_file = ~/.ssh/id_rsa
ansible_ssh_common_args='-tt -o ServerAliveInterval=30 -o ServerAliveCountMax=60'

Playbook

---
  - name: test
    hosts: SERVERS
    vars:
      logfile: "/home/test/reports/{{inventory_hostname}}_{{ansible_date_time.date}}_{{ansible_date_time.hour}}-{{ansible_date_time.minute}}.log"
      loghost: "localhost"
      jumphost: "**src ip**"
    tasks:
      - name: ice tool
        shell: . ~/toolrc && tool
        async: 1200
        poll: 10
        register: output
      - debug: var=output.stdout_lines

      - name: find logs
        find:
          paths: "/home/test2/"
          patterns: "*2023-09*.log"
        register: files_to_fetch

      - name: fetch logs
        fetch:
          src: "{{ item.path }}"
          dest: "/home/test/reports/{{inventory_hostname}}/"
          flat: yes
        with_items: "{{ files_to_fetch.files }}"

I turned the debug output on.
ansible.cfg shows #usetty = True

Ouput
Example with no -tt in the ansible_ssh_common_args

1603371 1693992535.99884: attempt loop complete, returning result
1603371 1693992535.99896: _execute() done
1603371 1693992535.99898: dumping result to json
1603371 1693992535.99902: done dumping result, returning
1603371 1693992535.99913: done running TaskExecutor() for server/TASK: tool [005056bd-514d-af4f-7949-000000000009]
1603371 1693992535.99927: sending task result for task 005056bd-514d-af4f-7949-000000000009
1603371 1693992535.99979: done sending task result for task 005056bd-514d-af4f-7949-000000000009
1603371 1693992536.00018: WORKER PROCESS EXITING
changed: [server] => {
    "ansible_job_id": "452358306988.608654",
    "changed": true,
    "cmd": ". ~/toolrc && tool;",
    "delta": "0:00:01.791007",
    "end": "2023-09-06 11:28:47.296398",
    "finished": 1,
    "invocation": {
        "module_args": {
            "_raw_params": ". ~/toolrc && tool;",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true,
            "warn": true
        }
    },
    "rc": 0,
    "start": "2023-09-06 11:28:45.505391",
    "stderr": "the input device is not a TTY",
    "stderr_lines": [
        "the input device is not a TTY"
    ],
    "stdout": "",
    "stdout_lines": []
}

Example with -t in the ansible_ssh_common_args

1605471 1693992665.10629: attempt loop complete, returning result
1605471 1693992665.10642: _execute() done
1605471 1693992665.10644: dumping result to json
1605471 1693992665.10647: done dumping result, returning
1605471 1693992665.10659: done running TaskExecutor() for server/TASK: tool [005056bd-514d-4bf1-ae78-000000000009]
1605471 1693992665.10671: sending task result for task 005056bd-514d-4bf1-ae78-000000000009
1605471 1693992665.10715: done sending task result for task 005056bd-514d-4bf1-ae78-000000000009
1605471 1693992665.10753: WORKER PROCESS EXITING
changed: [server] => {
    "ansible_job_id": "359810881181.622306",
    "changed": true,
    "cmd": ". ~/toolrc && tool;",
    "delta": "0:00:01.693101",
    "end": "2023-09-06 11:30:56.355022",
    "finished": 1,
    "invocation": {
        "module_args": {
            "_raw_params": ". ~/toolrc && tool;",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true,
            "warn": true
        }
    },
    "rc": 0,
    "start": "2023-09-06 11:30:54.661921",
    "stderr": "the input device is not a TTY",
    "stderr_lines": [
        "the input device is not a TTY"
    ],
    "stdout": "",
    "stdout_lines": []
}

Example with -tt in the ansible_ssh_common_args

1607836 1693992806.87791: stdout chunk (state=3):
>>>Python 2.7.5 (default, Oct 14 2020, 14:45:30) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
<<<
1607836 1693992806.88345: stdout chunk (state=3):
>>>ESC[?1034h>>> ... ... >>> ... ... >>> >>> >>> >>> <<<
1607836 1693992806.89308: stdout chunk (state=3):
>>>>>> >>> >>> >>> >>> >>> ... ... ... ... ... >>>   File "<stdin>", line 1
    return content
    ^
IndentationError: unexpected indent
>>> >>> >>> ... ... >>>   File "<stdin>", line 1
    if hasattr(platform, 'dist'):
    ^
IndentationError: unexpected indent
>>>   File "<stdin>", line 1
    result['platform_dist_result'] = platform.dist()
    ^
IndentationError: unexpected indent
>>> >>>   File "<stdin>", line 1
    osrelease_content = read_utf8_file('/etc/os-release')
    ^
IndentationError: unexpected indent
>>> ...   File "<stdin>", line 2
    if not osrelease_content:
    ^
IndentationError: unexpected indent
>>>   File "<stdin>", line 1
    osrelease_content = read_utf8_file('/usr/lib/os-release')
    ^
IndentationError: unexpected indent
>>> >>>   File "<stdin>", line 1
    result['osrelease_content'] = osrelease_content
    ^
IndentationError: unexpected indent
>>> >>>   File "<stdin>", line 1
    return result
    ^
IndentationError: unexpected indent
>>> >>> >>> ... ... >>>   File "<stdin>", line 1
    print(json.dumps(info))
    ^
IndentationError: unexpected indent
>>> >>> >>> ... ... <<<
1607836 1693992881.03244: _low_level_execute_command(): starting
1607836 1693992881.03257: _low_level_execute_command(): executing: /bin/sh -c 'rm -f -r /home/test2/.ansible/tmp/ansible-tmp-1693992806.503195-1607836-118059838868414/ > /dev/null 2>&1 && sleep 0'
<** dest ip **> ESTABLISH SSH CONNECTION FOR USER: test2
<** dest ip **> SSH: ansible.cfg set ssh_args: (-C)(-o)(ControlMaster=auto)(-o)(ControlPersist=60s)
<** dest ip **> SSH: ANSIBLE_REMOTE_PORT/remote_port/ansible_port set: (-o)(Port=22)
<** dest ip **> SSH: ANSIBLE_PRIVATE_KEY_FILE/private_key_file/ansible_ssh_private_key_file set: (-o)(IdentityFile="/home/test/.ssh/id_rsa")
<** dest ip **> SSH: ansible_password/ansible_ssh_password not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no)
<** dest ip **> SSH: ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set: (-o)(User="test2")
1607829 1693992881.03295: RUNNING CLEANUP
<** dest ip **> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10)

Is it really about the -tt attribute?
Or is there a python issue?

I might get beaten by this but I recall that it worked a few weeks before when I tried it but now it doesn’t anymore. No one touched the servers in the meantime…

edit: “tool” runs perfectly fine when started directly on the destination.

If usetty is true, then it’s already adding -tt to the ssh invocation. You could be overcomplicating things.

The tool you’re using could be looking for other indicators to determine if a TTY is being used, specifically COLS or ROWS environmental variables. I noticed the RC for the tool invocation is 0 anyway, looks like the error message could be a warning…

I’d remove the ssh args, they’re not helping here. The python errors are not normal, but you’re using -tt in the ssh args, which is not expected by the connection plugin.

2 Likes

Thank you for your reply.
I removed the ssh arguments → “the input device is not a TTY”
I set usetty to true → “the input device is not a TTY”
ssh -t test2@* dest ip ** “source toolrc && tool” → works
So it is basically possible to run the script via ssh with the -t argument.

If I delete these two lines it works! But I would like to start the task on all of the servers at once which needs async, right?

start the task on all of the servers at once which needs async, right?

No, Ansible performs parallelism by default, so you don’t need to add async here

1 Like