Skip to content

Commit 5e6d7bf

Browse files
committed
ansible_mitogen: Templated connection timeout
Ansible >= 4 (ansible-core >= 2.11) the SSH plugin has a `timeout` option and with variable `ansible_ssh_timeout`, but not a `ansible_timeout` variable. The local plugin has no such option or variable(s). However `ansible_timeout` is backfilled for all conection plugins, by legacy mechanisms that populate the play context attribute: - `ansible.constants.COMMON_CONNECTION_VARS` - `ansible.constants.MAGIC_VARIABLE_MAPPING` The `timeout` keyword is for task completion timeout, not connection timeout.
1 parent 6900e88 commit 5e6d7bf

File tree

8 files changed

+40
-17
lines changed

8 files changed

+40
-17
lines changed

ansible_mitogen/connection.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def _connect_ssh(spec):
145145
'identity_file': private_key_file,
146146
'identities_only': False,
147147
'ssh_path': spec.ssh_executable(),
148-
'connect_timeout': spec.ansible_ssh_timeout(),
148+
'connect_timeout': spec.timeout(),
149149
'ssh_args': spec.ssh_args(),
150150
'ssh_debug_level': spec.mitogen_ssh_debug_level(),
151151
'remote_name': get_remote_name(spec),
@@ -169,7 +169,7 @@ def _connect_buildah(spec):
169169
'username': spec.remote_user(),
170170
'container': spec.remote_addr(),
171171
'python_path': spec.python_path(),
172-
'connect_timeout': spec.ansible_ssh_timeout() or spec.timeout(),
172+
'connect_timeout': spec.timeout(),
173173
'remote_name': get_remote_name(spec),
174174
}
175175
}
@@ -185,7 +185,7 @@ def _connect_docker(spec):
185185
'username': spec.remote_user(),
186186
'container': spec.remote_addr(),
187187
'python_path': spec.python_path(rediscover_python=True),
188-
'connect_timeout': spec.ansible_ssh_timeout() or spec.timeout(),
188+
'connect_timeout': spec.timeout(),
189189
'remote_name': get_remote_name(spec),
190190
}
191191
}
@@ -200,7 +200,7 @@ def _connect_kubectl(spec):
200200
'kwargs': {
201201
'pod': spec.remote_addr(),
202202
'python_path': spec.python_path(),
203-
'connect_timeout': spec.ansible_ssh_timeout() or spec.timeout(),
203+
'connect_timeout': spec.timeout(),
204204
'kubectl_path': spec.mitogen_kubectl_path(),
205205
'kubectl_args': spec.extra_args(),
206206
'remote_name': get_remote_name(spec),
@@ -218,7 +218,7 @@ def _connect_jail(spec):
218218
'username': spec.remote_user(),
219219
'container': spec.remote_addr(),
220220
'python_path': spec.python_path(),
221-
'connect_timeout': spec.ansible_ssh_timeout() or spec.timeout(),
221+
'connect_timeout': spec.timeout(),
222222
'remote_name': get_remote_name(spec),
223223
}
224224
}
@@ -234,7 +234,7 @@ def _connect_lxc(spec):
234234
'container': spec.remote_addr(),
235235
'python_path': spec.python_path(),
236236
'lxc_attach_path': spec.mitogen_lxc_attach_path(),
237-
'connect_timeout': spec.ansible_ssh_timeout() or spec.timeout(),
237+
'connect_timeout': spec.timeout(),
238238
'remote_name': get_remote_name(spec),
239239
}
240240
}
@@ -250,7 +250,7 @@ def _connect_lxd(spec):
250250
'container': spec.remote_addr(),
251251
'python_path': spec.python_path(),
252252
'lxc_path': spec.mitogen_lxc_path(),
253-
'connect_timeout': spec.ansible_ssh_timeout() or spec.timeout(),
253+
'connect_timeout': spec.timeout(),
254254
'remote_name': get_remote_name(spec),
255255
}
256256
}
@@ -273,7 +273,7 @@ def _connect_podman(spec):
273273
'username': spec.remote_user(),
274274
'container': spec.remote_addr(),
275275
'python_path': spec.python_path(rediscover_python=True),
276-
'connect_timeout': spec.ansible_ssh_timeout() or spec.timeout(),
276+
'connect_timeout': spec.timeout(),
277277
'remote_name': get_remote_name(spec),
278278
}
279279
}

ansible_mitogen/strategy.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,22 +328,42 @@ def run(self, iterator, play_context, result=0):
328328
finally:
329329
ansible_mitogen.process.set_worker_model(None)
330330

331-
def _smuggle_to_connction_reset(self, task, play_context, iterator, target_host):
332-
# Workaround for https://github.com/ansible/ansible/issues/84238
331+
def _smuggle_to_connection_reset(self, task, play_context, iterator, target_host):
332+
"""
333+
Create a templar and make it available for use in Connection.reset().
334+
This allows templated connection variables to be used when Mitogen
335+
reconstructs its connection stack.
336+
"""
333337
variables = self._variable_manager.get_vars(
334338
play=iterator._play, host=target_host, task=task,
335339
_hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all,
336340
)
337341
templar = ansible.template.Templar(
338342
loader=self._loader, variables=variables,
339343
)
344+
345+
# Required for remote_user option set by variable (e.g. ansible_user).
346+
# Without it remote_user in ansible.cfg gets used.
347+
play_context = play_context.set_task_and_variable_override(
348+
task=task, variables=variables, templar=templar,
349+
)
350+
play_context.post_validate(templar=templar)
351+
352+
# Required for timeout option set by variable (e.g. ansible_timeout).
353+
# Without it the task timeout keyword (default: 0) gets used.
354+
play_context.update_vars(variables)
355+
356+
# Stash the task and templar somewhere Connection.reset() can find it
340357
play_context.vars.update({
341358
'_mitogen.smuggled.reset_connection': (task, templar),
342359
})
360+
return play_context
343361

344362
def _execute_meta(self, task, play_context, iterator, target_host):
345363
if task.args['_raw_params'] == 'reset_connection':
346-
self._smuggle_to_connction_reset(task, play_context, iterator, target_host)
364+
play_context = self._smuggle_to_connection_reset(
365+
task, play_context, iterator, target_host,
366+
)
347367

348368
return super(StrategyMixin, self)._execute_meta(
349369
task, play_context, iterator, target_host,

ansible_mitogen/transport_config.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -513,14 +513,10 @@ def ssh_executable(self):
513513
return self._connection_option('ssh_executable')
514514

515515
def timeout(self):
516-
return self._play_context.timeout
516+
return self._connection_option('timeout')
517517

518518
def ansible_ssh_timeout(self):
519-
return (
520-
self._connection.get_task_var('ansible_timeout') or
521-
self._connection.get_task_var('ansible_ssh_timeout') or
522-
self.timeout()
523-
)
519+
return self.timeout()
524520

525521
def ssh_args(self):
526522
return [

docs/changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ In progress (unreleased)
2525
timeout with templated ``ansible_python_interpreter``
2626
* :gh:issue:`1079` :mod:`ansible_mitogen`: Fix templated python interpreter
2727
with `meta: reset_connection`
28+
* :gh:issue:`1083` :mod:`ansible_mitogen`: Templated connection timeout
29+
(e.g. ``ansible_timeout``).
2830

2931

3032
v0.3.19 (2024-12-02)

tests/ansible/hosts/default.hosts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ tt-port ansible_host=localhost ansible_password=has_sudo_
5252
tt-private-key-file ansible_host=localhost ansible_private_key_file="{{ git_basedir }}/tests/data/docker/mitogen__has_sudo_pubkey.key" ansible_user=mitogen__has_sudo_pubkey
5353
tt-remote-user ansible_host=localhost ansible_password=has_sudo_nopw_password ansible_user="{{ 'mitogen__has_sudo_nopw' | trim }}"
5454
tt-ssh-executable ansible_host=localhost ansible_password=has_sudo_nopw_password ansible_ssh_executable="{{ 'ssh' | trim }}" ansible_user=mitogen__has_sudo_nopw
55+
tt-timeout ansible_host=localhost ansible_password=has_sudo_nopw_password ansible_timeout="{{ 5 | int }}" ansible_user=mitogen__has_sudo_nopw

tests/ansible/integration/ssh/templated_by_play_taskvar.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
ansible_password: "{{ 'has_sudo_nopw_password' | trim }}"
88
ansible_port: "{{ hostvars[groups['test-targets'][0]].ansible_port | default(22) }}"
99
ansible_ssh_executable: "{{ 'ssh' | trim }}"
10+
ansible_timeout: "{{ 5 | int }}"
1011
ansible_user: "{{ 'mitogen__has_sudo_nopw' | trim }}"
1112

1213
tasks:
@@ -23,6 +24,7 @@
2324
ansible_private_key_file: "{{ git_basedir }}/tests/data/docker/mitogen__has_sudo_pubkey.key"
2425
ansible_port: "{{ hostvars[groups['test-targets'][0]].ansible_port | default(22) }}"
2526
ansible_ssh_executable: "{{ 'ssh' | trim }}"
27+
ansible_timeout: "{{ 5 | int }}"
2628
ansible_user: "{{ 'mitogen__has_sudo_pubkey' | trim }}"
2729

2830
tasks:

tests/ansible/regression/issue_109__target_has_old_ansible_installed.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- env.cwd == ansible_user_dir
2727
- (not env.mitogen_loaded) or (env.python_path.count("") == 1)
2828
fail_msg: |
29+
ansible_user_dir={{ ansible_user_dir }}
2930
env={{ env }}
3031
3132
- name: Run some new-style from ansible.module_utils... modules

tests/ansible/templates/test-targets.j2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,4 @@ tt-port ansible_host={{ tt.hostname }} ansible_password=h
8686
tt-private-key-file ansible_host={{ tt.hostname }} ansible_port={{ tt.port }} ansible_private_key_file="{{ '{{' }} git_basedir {{ '}}' }}/tests/data/docker/mitogen__has_sudo_pubkey.key" ansible_python_interpreter={{ tt.python_path }} ansible_user=mitogen__has_sudo_pubkey
8787
tt-remote-user ansible_host={{ tt.hostname }} ansible_password=has_sudo_nopw_password ansible_port={{ tt.port }} ansible_python_interpreter={{ tt.python_path }} ansible_user="{{ '{{' }} 'mitogen__has_sudo_nopw' | trim {{ '}}' }}"
8888
tt-ssh-executable ansible_host={{ tt.hostname }} ansible_password=has_sudo_nopw_password ansible_port={{ tt.port }} ansible_python_interpreter={{ tt.python_path }} ansible_ssh_executable="{{ '{{' }} 'ssh' | trim {{ '}}' }}" ansible_user=mitogen__has_sudo_nopw
89+
tt-timeout ansible_host={{ tt.hostname }} ansible_password=has_sudo_nopw_password ansible_port={{ tt.port }} ansible_python_interpreter={{ tt.python_path }} ansible_timeout="{{ '{{' }} 5 | int {{ '}}' }}" ansible_user=mitogen__has_sudo_nopw

0 commit comments

Comments
 (0)