Skip to content

Commit

Permalink
Merge pull request #1180 from moreati/release-v0.3.16
Browse files Browse the repository at this point in the history
Release v0.3.16
  • Loading branch information
moreati authored Nov 5, 2024
2 parents 33b082f + a41a954 commit c883f17
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 43 deletions.
13 changes: 2 additions & 11 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,30 +156,21 @@ jobs:
"$PYTHON" -m tox -e "${{ matrix.tox_env }}"
macos:
# https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
runs-on: macos-12
# https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md
runs-on: macos-13
timeout-minutes: 120

strategy:
fail-fast: false
matrix:
include:
- name: Mito_27
tox_env: py27-mode_mitogen
- name: Mito_313
python_version: '3.13'
tox_env: py313-mode_mitogen

- name: Loc_27_210
tox_env: py27-mode_localhost-ansible2.10
- name: Loc_313_10
python_version: '3.13'
tox_env: py313-mode_localhost-ansible10

- name: Van_27_210
tox_env: py27-mode_localhost-ansible2.10-strategy_linear
- name: Van_313_10
python_version: '3.13'
tox_env: py313-mode_localhost-ansible10-strategy_linear

steps:
Expand Down
36 changes: 36 additions & 0 deletions ansible_mitogen/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,29 @@ def close(self):
self.binding.close()
self.binding = None

def _mitogen_var_options(self, templar):
# Workaround for https://github.com/ansible/ansible/issues/84238
var_names = C.config.get_plugin_vars('connection', self._load_name)
variables = templar.available_variables
var_options = {
var_name: templar.template(variables[var_name])
for var_name in var_names
if var_name in variables
}

if self.allow_extras:
extras_var_prefix = 'ansible_%s_' % self.extras_prefix
var_options['_extras'] = {
var_name: templar.template(variables[var_name])
for var_name in variables
if var_name not in var_options
and var_name.startswith(extras_var_prefix)
}
else:
var_options['_extras'] = {}

return var_options

reset_compat_msg = (
'Mitogen only supports "reset_connection" on Ansible 2.5.6 or later'
)
Expand Down Expand Up @@ -922,6 +945,19 @@ def reset(self):
shared_loader_obj=0
)

# Workaround for https://github.com/ansible/ansible/issues/84238
try:
task, templar = self._play_context.vars.pop(
'_mitogen.smuggled.reset_connection',
)
except KeyError:
pass
else:
self.set_options(
task_keys=task.dump_attrs(),
var_options=self._mitogen_var_options(templar),
)

# Clear out state in case we were ever connected.
self.close()

Expand Down
22 changes: 22 additions & 0 deletions ansible_mitogen/strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import ansible_mitogen.process

import ansible.executor.process.worker
import ansible.template
import ansible.utils.sentinel


Expand Down Expand Up @@ -326,3 +327,24 @@ def run(self, iterator, play_context, result=0):
self._worker_model.on_strategy_complete()
finally:
ansible_mitogen.process.set_worker_model(None)

def _smuggle_to_connction_reset(self, task, play_context, iterator, target_host):
# Workaround for https://github.com/ansible/ansible/issues/84238
variables = self._variable_manager.get_vars(
play=iterator._play, host=target_host, task=task,
_hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all,
)
templar = ansible.template.Templar(
loader=self._loader, variables=variables,
)
play_context.vars.update({
'_mitogen.smuggled.reset_connection': (task, templar),
})

def _execute_meta(self, task, play_context, iterator, target_host):
if task.args['_raw_params'] == 'reset_connection':
self._smuggle_to_connction_reset(task, play_context, iterator, target_host)

return super(StrategyMixin, self)._execute_meta(
task, play_context, iterator, target_host,
)
67 changes: 40 additions & 27 deletions ansible_mitogen/transport_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ def become(self):
:data:`True` if privilege escalation should be active.
"""

@abc.abstractmethod
def become_flags(self):
"""
The command line arguments passed to the become executable.
"""

@abc.abstractmethod
def become_method(self):
"""
Expand Down Expand Up @@ -290,10 +296,9 @@ def become_exe(self):
@abc.abstractmethod
def sudo_args(self):
"""
The list of additional arguments that should be included in a become
The list of additional arguments that should be included in a sudo
invocation.
"""
# TODO: split out into sudo_args/become_args.

@abc.abstractmethod
def mitogen_via(self):
Expand Down Expand Up @@ -419,7 +424,29 @@ def __init__(self, connection, play_context, transport, inventory_name):

def _become_option(self, name):
plugin = self._connection.become
return plugin.get_option(name, self._task_vars, self._play_context)
try:
return plugin.get_option(name, self._task_vars, self._play_context)
except AttributeError:
# A few ansible_mitogen connection plugins look more like become
# plugins. They don't quite fit Ansible's plugin.get_option() API.
# https://github.com/mitogen-hq/mitogen/issues/1173
fallback_plugins = {'mitogen_doas', 'mitogen_sudo', 'mitogen_su'}
if self._connection.transport not in fallback_plugins:
raise

fallback_options = {
'become_exe',
'become_flags',
}
if name not in fallback_options:
raise

LOG.info(
'Used PlayContext fallback for plugin=%r, option=%r',
self._connection, name,
)
return getattr(self._play_context, name)


def _connection_option(self, name):
try:
Expand All @@ -443,6 +470,9 @@ def remote_user(self):
def become(self):
return self._connection.become

def become_flags(self):
return self._become_option('become_flags')

def become_method(self):
return self._play_context.become_method

Expand Down Expand Up @@ -481,7 +511,7 @@ def private_key_file(self):
return self._play_context.private_key_file

def ssh_executable(self):
return C.config.get_config_value("ssh_executable", plugin_type="connection", plugin_name="ssh", variables=self._task_vars.get("vars", {}))
return self._connection_option('ssh_executable')

def timeout(self):
return self._play_context.timeout
Expand All @@ -505,30 +535,10 @@ def ssh_args(self):
]

def become_exe(self):
# In Ansible 2.8, PlayContext.become_exe always has a default value due
# to the new options mechanism. Previously it was only set if a value
# ("somewhere") had been specified for the task.
# For consistency in the tests, here we make older Ansibles behave like
# newer Ansibles.
exe = self._play_context.become_exe
if exe is None and self._play_context.become_method == 'sudo':
exe = 'sudo'
return exe
return self._become_option('become_exe')

def sudo_args(self):
return [
mitogen.core.to_text(term)
for term in ansible.utils.shlex.shlex_split(
first_true((
self._play_context.become_flags,
# Ansible <=2.7.
getattr(self._play_context, 'sudo_flags', ''),
# Ansible <=2.3.
getattr(C, 'DEFAULT_BECOME_FLAGS', ''),
getattr(C, 'DEFAULT_SUDO_FLAGS', '')
), default='')
)
]
return ansible.utils.shlex.shlex_split(self.become_flags() or '')

def mitogen_via(self):
return self._connection.get_task_var('mitogen_via')
Expand Down Expand Up @@ -663,6 +673,9 @@ def remote_user(self):
def become(self):
return bool(self._become_user)

def become_flags(self):
return self._host_vars.get('ansible_become_flags')

def become_method(self):
return (
self._become_method or
Expand Down Expand Up @@ -758,7 +771,7 @@ def sudo_args(self):
mitogen.core.to_text(term)
for s in (
self._host_vars.get('ansible_sudo_flags') or '',
self._host_vars.get('ansible_become_flags') or '',
self.become_flags() or '',
)
for term in ansible.utils.shlex.shlex_split(s)
]
Expand Down
14 changes: 14 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ To avail of fixes in an unreleased version, please download a ZIP file
`directly from GitHub <https://github.com/mitogen-hq/mitogen/>`_.


v0.3.16 (2024-11-05)
--------------------

* :gh:issue:`1083` :mod:`ansible_mitogen`: Templated become executable
(e.g. ``become_exe``).
* :gh:issue:`1083` :mod:`ansible_mitogen`: Templated become executable
arguments (e.g. ``become_flags``).
* :gh:issue:`1083` :mod:`ansible_mitogen`: Templated ssh executable
(``ansible_ssh_executable``).
* :gh:issue:`1083` :mod:`ansible_mitogen`: Fixed templated connection options
during a ``meta: reset_connection`` task.
* :gh:issue:`1129` CI: Migrated macOS 12 runners to macOS 13, due to EOL.


v0.3.15 (2024-10-28)
--------------------

Expand Down
2 changes: 1 addition & 1 deletion mitogen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@


#: Library version as a tuple.
__version__ = (0, 3, 15)
__version__ = (0, 3, 16)


#: This is :data:`False` in slave contexts. Previously it was used to prevent
Expand Down
3 changes: 3 additions & 0 deletions tests/ansible/hosts/default.hosts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ ansible_host=localhost
ansible_user="{{ lookup('pipe', 'whoami') }}"

[tt_become_by_inv]
tt-become-exe ansible_become=true ansible_become_exe="{{ 'sudo' | trim }}" ansible_become_user=root
tt-become-flags ansible_become=true ansible_become_flags="{{ '--set-home --stdin --non-interactive' | trim }}" ansible_become_user=root
tt-become-pass ansible_become=true ansible_become_pass="{{ 'pw_required_password' | trim }}" ansible_become_user=mitogen__pw_required
tt-become-user ansible_become=true ansible_become_user="{{ 'root' | trim }}"

Expand All @@ -44,6 +46,7 @@ ansible_user="{{ lookup('pipe', 'whoami') }}"
tt-password ansible_password="{{ 'has_sudo_nopw_password' | trim }}" ansible_user=mitogen__has_sudo_nopw
tt-port ansible_password=has_sudo_nopw_password ansible_port="{{ 22 | int }}" ansible_user=mitogen__has_sudo_nopw
tt-remote-user ansible_password=has_sudo_nopw_password ansible_user="{{ 'mitogen__has_sudo_nopw' | trim }}"
tt-ssh-executable ansible_password=has_sudo_nopw_password ansible_ssh_executable="{{ 'ssh' | trim }}" ansible_user=mitogen__has_sudo_nopw

[tt_targets_inventory:vars]
ansible_host=localhost
2 changes: 2 additions & 0 deletions tests/ansible/integration/become/templated_by_inv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
- name: Templated become in inventory
vars:
expected_become_users:
tt-become-exe: root
tt-become-flags: root
tt-become-pass: mitogen__pw_required
tt-become-user: root
command:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
hosts: tt_become_bare
gather_facts: false
become: true
become_exe: "{{ 'sudo' | trim }}"
become_flags: "{{ '--set-home --stdin --non-interactive' | trim }}"
become_user: "{{ 'root' | trim }}"
tasks:
- meta: reset_connection
Expand All @@ -20,6 +22,8 @@
hosts: tt_become_bare
gather_facts: false
become: true
become_exe: "{{ 'sudo' | trim }}"
become_flags: "{{ '--set-home --stdin --non-interactive' | trim }}"
become_user: "{{ 'mitogen__pw_required' | trim }}"
vars:
ansible_become_pass: "{{ 'pw_required_password' | trim }}"
Expand Down
4 changes: 4 additions & 0 deletions tests/ansible/integration/become/templated_by_play_vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
gather_facts: false
vars:
ansible_become: true
ansible_become_exe: "{{ 'sudo' | trim }}"
ansible_become_flags: "{{ '--set-home --stdin --non-interactive' | trim }}"
ansible_become_user: "{{ 'root' | trim }}"
tasks:
- name: Templated become by play vars, no password
Expand All @@ -20,6 +22,8 @@
gather_facts: false
vars:
ansible_become: true
ansible_become_exe: "{{ 'sudo' | trim }}"
ansible_become_flags: "{{ '--set-home --stdin --non-interactive' | trim }}"
ansible_become_pass: "{{ 'pw_required_password' | trim }}"
ansible_become_user: "{{ 'mitogen__pw_required' | trim }}"
tasks:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# FIXME Resetting the connection shouldn't require credentials
# https://github.com/mitogen-hq/mitogen/issues/1132
become: true
become_exe: "{{ 'sudo' | trim }}"
become_flags: "{{ '--set-home --stdin --non-interactive' | trim }}"
become_user: "{{ 'root' | trim }}"
tasks:
- name: Reset connection to target that will be delegate_to
Expand All @@ -15,6 +17,8 @@
tasks:
- name: Templated become by task keywords, with delegate_to
become: true
become_exe: "{{ 'sudo' | trim }}"
become_flags: "{{ '--set-home --stdin --non-interactive' | trim }}"
become_user: "{{ 'root' | trim }}"
delegate_to: "{{ groups.tt_become_bare[0] }}"
command:
Expand All @@ -33,6 +37,8 @@
# FIXME Resetting the connection shouldn't require credentials
# https://github.com/mitogen-hq/mitogen/issues/1132
become: true
become_exe: "{{ 'sudo' | trim }}"
become_flags: "{{ '--set-home --stdin --non-interactive' | trim }}"
become_user: "{{ 'mitogen__pw_required' | trim }}"
vars:
ansible_become_pass: "{{ 'pw_required_password' | trim }}"
Expand All @@ -52,6 +58,8 @@

- name: Templated become by task keywords, with delegate_to
become: true
become_exe: "{{ 'sudo' | trim }}"
become_flags: "{{ '--set-home --stdin --non-interactive' | trim }}"
become_user: "{{ 'mitogen__pw_required' | trim }}"
delegate_to: "{{ groups.tt_become_bare[0] }}"
vars:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
vars:
ansible_password: "{{ 'has_sudo_nopw_password' | trim }}"
ansible_port: "{{ hostvars[groups['test-targets'][0]].ansible_port | default(22) }}"
ansible_ssh_executable: "{{ 'ssh' | trim }}"
ansible_user: "{{ 'mitogen__has_sudo_nopw' | trim }}"

tasks:
Expand Down
Loading

0 comments on commit c883f17

Please sign in to comment.