Commit 91116810 authored by David Wilson's avatar David Wilson

ansible: delete utils.py and promote cast() to mitogen.utils

parent a075cc02
......@@ -30,11 +30,12 @@ import os
import ansible.errors
import ansible.plugins.connection
import ansible_mitogen.helpers
import mitogen.unix
from mitogen.utils import cast
import ansible_mitogen.helpers
from ansible_mitogen.strategy.mitogen import ContextService
from ansible_mitogen.utils import cast
class Connection(ansible.plugins.connection.ConnectionBase):
......
......@@ -25,18 +25,37 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import
import pwd
import os
import tempfile
import ansible
import ansible.plugins
import ansible.plugins.action
import mitogen.core
import mitogen.master
from mitogen.utils import cast
import ansible_mitogen.helpers
from ansible.module_utils._text import to_text
from ansible_mitogen.utils import cast
from ansible_mitogen.utils import get_command_module_name
def get_command_module_name(module_name):
"""
Given the name of an Ansible command module, return its canonical module
path within the ansible.
:param module_name:
"shell"
:return:
"ansible.modules.commands.shell"
"""
path = ansible.plugins.module_loader.find_plugin(module_name, '')
relpath = os.path.relpath(path, os.path.dirname(ansible.__file__))
root, _ = os.path.splitext(relpath)
return 'ansible.' + root.replace('/', '.')
class ActionModuleMixin(ansible.plugins.action.ActionBase):
......
# Copyright 2017, David Wilson
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import
import os
import ansible
import ansible.plugins
import mitogen.core
def cast(obj):
"""
Ansible loves to decorate built-in types to implement useful functionality
like Vault, however cPickle loves to preserve those decorations during
serialization, resulting in CallError.
So here we recursively undecorate `obj`, ensuring that any instances of
subclasses of built-in types are downcast to the base type.
"""
if isinstance(obj, dict):
return {cast(k): cast(v) for k, v in obj.iteritems()}
if isinstance(obj, (list, tuple)):
return [cast(v) for v in obj]
if obj is None or isinstance(obj, (int, float)):
return obj
if isinstance(obj, unicode):
return unicode(obj)
if isinstance(obj, str):
return str(obj)
if isinstance(obj, (mitogen.core.Context,
mitogen.core.Dead,
mitogen.core.CallError)):
return obj
raise TypeError("Cannot serialize: %r: %r" % (type(obj), obj))
def get_command_module_name(module_name):
"""
Given the name of an Ansible command module, return its canonical module
path within the ansible.
:param module_name:
"shell"
:return:
"ansible.modules.commands.shell"
"""
path = ansible.plugins.module_loader.find_plugin(module_name, '')
relpath = os.path.relpath(path, os.path.dirname(ansible.__file__))
root, _ = os.path.splitext(relpath)
return 'ansible.' + root.replace('/', '.')
......@@ -971,6 +971,27 @@ Utility Functions
A random assortment of utility functions useful on masters and children.
.. currentmodule:: mitogen.utils
.. function:: cast (obj)
Many tools love to subclass built-in types in order to implement useful
functionality, such as annotating the safety of a Unicode string, or adding
additional methods to a dict. However, cPickle loves to preserve those
subtypes during serialization, resulting in CallError during :py:meth:`call
<mitogen.master.Context.call>` in the target when it tries to deserialize
the data.
This function walks the object graph `obj`, producing a copy with any
custom sub-types removed. The functionality is not default since the
resulting walk may be computationally expensive given a large enough graph.
See :ref:`serialization-rules` for a list of supported types.
:param obj:
Object to undecorate.
:returns:
Undecorated object.
.. currentmodule:: mitogen.utils
.. function:: disable_site_packages
......
......@@ -281,6 +281,9 @@ User-defined types may not be used, except for:
* :py:class:`mitogen.core.Context`
* :py:class:`mitogen.core._DEAD`
Subclasses of built-in types must be undecorated using
:py:func:`mitogen.utils.cast`.
.. _troubleshooting:
......
......@@ -91,3 +91,22 @@ def with_router(func):
return run_with_router(func, *args, **kwargs)
wrapper.func_name = func.func_name
return wrapper
def cast(obj):
if isinstance(obj, dict):
return {cast(k): cast(v) for k, v in obj.iteritems()}
if isinstance(obj, (list, tuple)):
return [cast(v) for v in obj]
if obj is None or isinstance(obj, (int, float)):
return obj
if isinstance(obj, unicode):
return unicode(obj)
if isinstance(obj, str):
return str(obj)
if isinstance(obj, (mitogen.core.Context,
mitogen.core.Dead,
mitogen.core.CallError)):
return obj
raise TypeError("Cannot serialize: %r: %r" % (type(obj), obj))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment