aoh

A tool for running Ansible playbooks with `curl <url> | python` commands
git clone https://git.ashermorgan.net/aoh/
Log | Files | Refs | README

commit 964a00230e4ed8257a416d38b96639f862354216
parent 1102ebc98a5e059cb430295a2b62050c70e52b81
Author: Asher Morgan <asher@ashermorgan.net>
Date:   Wed,  2 Sep 2026 19:05:33 -0700

Set client keep-alive frequency server-side

Diffstat:
Maoh/client.py | 10++++------
Maoh/connection_plugins/aoh.py | 31+++++++++++++++++++++++++++----
2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/aoh/client.py b/aoh/client.py @@ -20,9 +20,6 @@ PASSWORD_PROMPTS = { 'vault_password': 'Vault password: ', } -# Set 10s EXEC keep alive interval (see also TIMEOUT in aoh.py) -KEEP_ALIVE_INTERVAL = 10 - # How long to sleep after receiving an empty responses WAIT_INTERVAL = 0.1 @@ -31,7 +28,7 @@ class ClientError(Exception): """Raised for miscellaneous client errors.""" -def exec(args, keep_alive_handler=None): +def exec(args, keep_alive_interval=None, keep_alive_handler=None): """Run a command on the local host.""" try: @@ -45,7 +42,7 @@ def exec(args, keep_alive_handler=None): while p.returncode is None: try: - p.wait(KEEP_ALIVE_INTERVAL) + p.wait(keep_alive_interval) except subprocess.TimeoutExpired: if keep_alive_handler: keep_alive_handler() @@ -158,7 +155,8 @@ def runner_loop(runner_url, cookies): { 'id': res['id'], 'keep-alive': True }, keep_alive=True ) - req = exec(res['exec'], keep_alive_handler) + req = exec(res['exec'], res['keep-alive-interval'], + keep_alive_handler) req['id'] = res['id'] elif 'put' in res: req = put(res['put']) diff --git a/aoh/connection_plugins/aoh.py b/aoh/connection_plugins/aoh.py @@ -12,6 +12,27 @@ DOCUMENTATION = """ required: true vars: - name: ansible_aoh_dir + aoh_timeout: + description: The timeout for AoH responses, in seconds + type: integer + default: 60 + env: + - name: ANSIBLE_TIMEOUT + ini: + - key: timeout + section: defaults + vars: + - name: ansible_aoh_timeout + cli: + - name: timeout + aoh_keep_alive_count: + description: The number of keep alive messages expected per timeout + type: integer + default: 10 + env: + - name: ANSIBLE_AOH_KEEP_ALIVE_COUNT + vars: + - name: ansible_aoh_keep_alive_count """ import base64 @@ -32,9 +53,6 @@ from ansible.utils.display import Display display = Display() -# Set 1m timeout (see also KEEP_ALIVE_INTERVAL in client.py) -TIMEOUT = 60 - class Connection(ConnectionBase): """Ansible-over-HTTP (AoH) connection.""" @@ -46,6 +64,10 @@ class Connection(ConnectionBase): def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: super().__init__(*args, **kwargs) + self.timeout = self.get_option('aoh_timeout') + self.keep_alive_count = self.get_option('aoh_keep_alive_count') + self.keep_alive_interval = round(self.timeout/self.keep_alive_count, 1) + self._sendbuf = None self._recvbuf = None self._recvpoll = None @@ -95,11 +117,12 @@ class Connection(ConnectionBase): assert self._recvpoll is not None msg['id'] = str(uuid4()) + msg['keep-alive-interval'] = self.keep_alive_interval self._sendbuf.write(json.dumps(msg) + '\n') self._sendbuf.flush() while True: - if not self._recvpoll.poll(TIMEOUT * 1000): + if not self._recvpoll.poll(self.timeout * 1000): raise AnsibleConnectionFailure('Timed out waiting for AoH ' 'response')