community.general icon indicating copy to clipboard operation
community.general copied to clipboard

doas on Alpine 3.21 fails with "a tty is required"

Open Spiffyk opened this issue 8 months ago • 6 comments

Summary

When I try to use Ansible with an Alpine 3.21 machine (installed with setup-alpine, which installs doas by default), I get doas: a tty is required in stderr.

use_tty is set to the default true value, and even if I reset it to true explicitly, this still happens.

Issue Type

Bug Report

Component Name

doas

Ansible Version

$ ansible --version
ansible [core 2.18.4]
  config file = None
  configured module search path = ['/home/spiffyk/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.13/site-packages/ansible
  ansible collection location = /home/spiffyk/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.13.2 (main, Feb  5 2025, 08:05:21) [GCC 14.2.1 20250128] (/usr/bin/python)
  jinja version = 3.1.5
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general

# /usr/lib/python3.13/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 10.5.0 

Configuration

$ ansible-config dump --only-changed

ANSIBLE_NOCOWS(/home/spiffyk/Projects/<project>/ansible.cfg) = True
ANSIBLE_PIPELINING(/home/spiffyk/Projects/<project>/ansible.cfg) = True
CONFIG_FILE() = /home/spiffyk/Projects/<project>/ansible.cfg
DEFAULT_HOST_LIST(/home/spiffyk/Projects/<project>/ansible.cfg) = ['/home/spiffyk/Projects/<project>/inventory.yaml']
EDITOR(env: EDITOR) = helix
INTERPRETER_PYTHON(/home/spiffyk/Projects/<project>/ansible.cfg) = /usr/bin/python3

GALAXY_SERVERS:

OS / Environment

On my machine: Arch Linux The other machine: Alpine Linux 3.21

Steps to Reproduce

Any playbook with become: true and become_method: community.general.doas paired with an Alpine 3.21 remote with doas will immediately fail during Gathering Facts.

Expected Results

I expected doas to change the user to root properly.

Actual Results

fatal: [ci-test01]: FAILED! => 
    ansible_facts: {}
    changed: false
    failed_modules:
        ansible.legacy.setup:
            failed: true
            module_stderr: |-
                doas: a tty is required
            module_stdout: ''
            msg: |-
                MODULE FAILURE: No start of json char found
                See stdout/stderr for the exact error
            rc: 1
    msg: |-
        The following modules failed to execute: ansible.legacy.setup

Code of Conduct

  • [x] I agree to follow the Ansible Code of Conduct

Spiffyk avatar Apr 09 '25 14:04 Spiffyk

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot avatar Apr 09 '25 14:04 ansibullbot

cc @JoergFiedler @MacLemon @bcoca @dch @eest @jasperla @mekanix @opoplawski @overhacked @tuxillo click here for bot help

ansibullbot avatar Apr 09 '25 14:04 ansibullbot

can you supply a full reproducer? Where/how are you setting use_tty? Also provide -vvv output of the failure

bcoca avatar Apr 09 '25 15:04 bcoca

https://github.com/Spiffyk/ansible-repro

This minimal repo reproduces the problem. A -vvvv log (with IPs redacted) is in log.txt. The remote is a virtual machine - should be reproducible locally with a very simple VM.

Spiffyk avatar Apr 09 '25 15:04 Spiffyk

Note: A workaround is to create a /etc/doas.d/nopass.conf file containing this line on the Alpine machine:

permit nopass :wheel

But that is not ideal, obviously. We do want to keep the extra little bit of security provided by the password prompt.

Spiffyk avatar Apr 10 '25 14:04 Spiffyk

Thanks for your detailed report @Spiffyk !

russoz avatar Apr 10 '25 20:04 russoz

pipelining=true appears to be a necessary condition to replicate this.

So disabling pipelining may be another workaround. At one point I thought I had bisected the commit that introduced the issue to https://github.com/ansible/ansible/commit/6d2d476113b3a26e46c9917e213f09494fbc0a13, but now I can't replicate that. Ansible (ansible-core) releases before and after it fail the same way when pipelining=true.

moreati avatar Jul 31 '25 11:07 moreati

There's a PR for the machinectl become plugin that tries to disable pipelining: #9908. Unfortunately that PR depends on support in ansible-core (https://github.com/ansible/ansible/pull/84878), but that PR isn't looking active.

felixfontein avatar Jul 31 '25 21:07 felixfontein

Hmm, though it looks like https://github.com/ansible/ansible/pull/78111 replaces that PR in ansible/ansible, with a slightly different mechanism (the option is called slightly differently). Have to take a closer look tomorrow or so...

(In any case, this fix will only work with ansible-core 2.19+...)

felixfontein avatar Jul 31 '25 21:07 felixfontein

ansible/ansible#78111 replaces that PR in ansible/ansible, with a slightly different mechanism

Setting a class attribute pipelining = False is what I had concluded.

moreati avatar Jul 31 '25 22:07 moreati

I created a PR for this: #10537. Would be glad if someone could test / review it.

felixfontein avatar Aug 01 '25 11:08 felixfontein