commit
ae7ad88c93
|
@ -88,6 +88,18 @@ def _connect_docker(spec):
|
|||
}
|
||||
|
||||
|
||||
def _connect_jail(spec):
|
||||
return {
|
||||
'method': 'jail',
|
||||
'kwargs': {
|
||||
'username': spec['remote_user'],
|
||||
'container': spec['remote_addr'],
|
||||
'python_path': spec['python_path'],
|
||||
'connect_timeout': spec['ansible_ssh_timeout'] or spec['timeout'],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def _connect_lxc(spec):
|
||||
return {
|
||||
'method': 'lxc',
|
||||
|
@ -115,6 +127,7 @@ def _connect_sudo(spec):
|
|||
|
||||
CONNECTION_METHOD = {
|
||||
'docker': _connect_docker,
|
||||
'jail': _connect_jail,
|
||||
'local': _connect_local,
|
||||
'lxc': _connect_lxc,
|
||||
'lxd': _connect_lxc,
|
||||
|
@ -515,3 +528,7 @@ class LxcConnection(Connection):
|
|||
|
||||
class LxdConnection(Connection):
|
||||
transport = 'lxd'
|
||||
|
||||
|
||||
class JailConnection(Connection):
|
||||
transport = 'jail'
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
# 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.
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
#
|
||||
# This is not the real Connection implementation module, it simply exists as a
|
||||
# proxy to the real module, which is loaded using Python's regular import
|
||||
# mechanism, to prevent Ansible's PluginLoader from making up a fake name that
|
||||
# results in ansible_mitogen plugin modules being loaded twice: once by
|
||||
# PluginLoader with a name like "ansible.plugins.connection.mitogen", which is
|
||||
# stuffed into sys.modules even though attempting to import it will trigger an
|
||||
# ImportError, and once under its canonical name, "ansible_mitogen.connection".
|
||||
#
|
||||
# Therefore we have a proxy module that imports it under the real name, and
|
||||
# sets up the duff PluginLoader-imported module to just contain objects from
|
||||
# the real module, so duplicate types don't exist in memory, and things like
|
||||
# debuggers and isinstance() work predictably.
|
||||
#
|
||||
|
||||
try:
|
||||
import ansible_mitogen
|
||||
except ImportError:
|
||||
base_dir = os.path.dirname(__file__)
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(base_dir, '../../..')))
|
||||
del base_dir
|
||||
|
||||
from ansible_mitogen.connection import JailConnection as Connection
|
||||
del os
|
||||
del sys
|
|
@ -68,7 +68,7 @@ def wrap_connection_loader__get(name, play_context, new_stdin, **kwargs):
|
|||
'mitogen' connection type, passing the original transport name into it as
|
||||
an argument, so that it can emulate the original type.
|
||||
"""
|
||||
if name in ('ssh', 'local', 'docker', 'lxc', 'lxd'):
|
||||
if name in ('ssh', 'local', 'docker', 'lxc', 'lxd', 'jail'):
|
||||
name = 'mitogen_' + name
|
||||
return connection_loader__get(name, play_context, new_stdin, **kwargs)
|
||||
|
||||
|
|
|
@ -116,8 +116,8 @@ Noteworthy Differences
|
|||
* The ``sudo`` become method is available and ``su`` is planned. File bugs to
|
||||
register interest in additional methods.
|
||||
|
||||
* The ``docker``, ``local``, ``lxc`` and ``ssh`` connection types are
|
||||
available, with more planned. File bugs to register interest.
|
||||
* The ``docker``, ``jail``, ``local``, ``lxc``, ``lxd`` and ``ssh`` connection
|
||||
types are available, with more planned. File bugs to register interest.
|
||||
|
||||
* Local commands execute in a reuseable interpreter created identically to
|
||||
interpreters on targets. Presently one interpreter per ``become_user``
|
||||
|
@ -467,24 +467,29 @@ Sudo
|
|||
Docker
|
||||
~~~~~~
|
||||
|
||||
Docker support is fairly new, expect increased surprises for now.
|
||||
|
||||
* ``ansible_host``: Name of Docker container.
|
||||
* ``ansible_host``: Name of Docker container (default: inventory hostname).
|
||||
* ``ansible_user``: Name of user within the container to execute as.
|
||||
|
||||
|
||||
FreeBSD Jails
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* ``ansible_host``: Name of Jail container (default: inventory hostname).
|
||||
* ``ansible_user``: Name of user within the jail to execute as.
|
||||
|
||||
|
||||
LXC
|
||||
~~~
|
||||
|
||||
LXC support is fairly new, expect increased surprises for now. Both ``lxc`` and
|
||||
``lxd`` connection plug-ins are hijacked, however the resulting implementation
|
||||
always uses the ``lxc-attach`` command line tool rather than th LXC Python
|
||||
bindings.
|
||||
Both ``lxc`` and ``lxd`` connection plug-ins are hijacked, however the
|
||||
resulting implementation always uses the ``lxc-attach`` command line tool
|
||||
rather than the LXC Python bindings, as is usual with the Ansible ``lxd``
|
||||
plug-in.
|
||||
|
||||
Consequently the ``lxc-attach`` command is required to be available on the host
|
||||
machine.
|
||||
|
||||
* ``ansible_host``: Name of LXC container.
|
||||
* ``ansible_host``: Name of LXC container (default: inventory hostname).
|
||||
|
||||
|
||||
Debugging
|
||||
|
|
21
docs/api.rst
21
docs/api.rst
|
@ -704,7 +704,10 @@ Router Class
|
|||
Accepts all parameters accepted by :py:meth:`local`, in addition to:
|
||||
|
||||
:param str container:
|
||||
Existing container to connect to. Defaults to ``None``.
|
||||
Existing container to connect to. Defaults to :data:`None`.
|
||||
:param str username:
|
||||
Username within the container to :func:`setuid` to. Defaults to
|
||||
:data:`None`, which Docker interprets as ``root``.
|
||||
:param str image:
|
||||
Image tag to use to construct a temporary container. Defaults to
|
||||
``None``.
|
||||
|
@ -712,6 +715,22 @@ Router Class
|
|||
Filename or complete path to the Docker binary. ``PATH`` will be
|
||||
searched if given as a filename. Defaults to ``docker``.
|
||||
|
||||
.. method:: jail (container, jexec_path=None, \**kwargs)
|
||||
|
||||
Construct a context on the local machine within a FreeBSD jail. The
|
||||
``jexec`` program must be available.
|
||||
|
||||
Accepts all parameters accepted by :py:meth:`local`, in addition to:
|
||||
|
||||
:param str container:
|
||||
Existing container to connect to. Defaults to :data:`None`.
|
||||
:param str username:
|
||||
Username within the container to :func:`setuid` to. Defaults to
|
||||
:data:`None`, which ``jexec`` interprets as ``root``.
|
||||
:param str jexec_path:
|
||||
Filename or complete path to the ``jexec`` binary. ``PATH`` will be
|
||||
searched if given as a filename. Defaults to ``/usr/sbin/jexec``.
|
||||
|
||||
.. method:: lxc (container, lxc_attach_path=None, \**kwargs)
|
||||
|
||||
Construct a context on the local machine within an LXC container. The
|
||||
|
|
|
@ -488,6 +488,7 @@ class Importer(object):
|
|||
'docker',
|
||||
'fakessh',
|
||||
'fork',
|
||||
'jail',
|
||||
'lxc',
|
||||
'master',
|
||||
'parent',
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# 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.
|
||||
|
||||
import logging
|
||||
|
||||
import mitogen.core
|
||||
import mitogen.parent
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Stream(mitogen.parent.Stream):
|
||||
create_child_args = {
|
||||
'merge_stdio': True
|
||||
}
|
||||
|
||||
container = None
|
||||
username = None
|
||||
jexec_path = '/usr/sbin/jexec'
|
||||
|
||||
def construct(self, container, jexec_path=None, username=None, **kwargs):
|
||||
super(Stream, self).construct(**kwargs)
|
||||
self.container = container
|
||||
self.username = username
|
||||
if jexec_path:
|
||||
self.jexec_path = jexec_path
|
||||
|
||||
def connect(self):
|
||||
super(Stream, self).connect()
|
||||
self.name = 'jail.' + self.container
|
||||
|
||||
def get_boot_command(self):
|
||||
bits = [self.jexec_path]
|
||||
if self.username:
|
||||
bits += ['-U', self.username]
|
||||
bits += [self.container]
|
||||
return bits + super(Stream, self).get_boot_command()
|
|
@ -49,8 +49,7 @@ class Stream(mitogen.parent.Stream):
|
|||
|
||||
def construct(self, container, lxc_attach_path=None, **kwargs):
|
||||
super(Stream, self).construct(**kwargs)
|
||||
if container:
|
||||
self.container = container
|
||||
self.container = container
|
||||
if lxc_attach_path:
|
||||
self.lxc_attach_path = lxc_attach_apth
|
||||
|
||||
|
|
|
@ -1008,24 +1008,27 @@ class Router(mitogen.core.Router):
|
|||
self._context_by_id[context.context_id] = context
|
||||
return context
|
||||
|
||||
def lxc(self, **kwargs):
|
||||
return self.connect('lxc', **kwargs)
|
||||
|
||||
def docker(self, **kwargs):
|
||||
return self.connect('docker', **kwargs)
|
||||
|
||||
def local(self, **kwargs):
|
||||
return self.connect('local', **kwargs)
|
||||
|
||||
def fork(self, **kwargs):
|
||||
return self.connect('fork', **kwargs)
|
||||
|
||||
def sudo(self, **kwargs):
|
||||
return self.connect('sudo', **kwargs)
|
||||
def jail(self, **kwargs):
|
||||
return self.connect('jail', **kwargs)
|
||||
|
||||
def local(self, **kwargs):
|
||||
return self.connect('local', **kwargs)
|
||||
|
||||
def lxc(self, **kwargs):
|
||||
return self.connect('lxc', **kwargs)
|
||||
|
||||
def ssh(self, **kwargs):
|
||||
return self.connect('ssh', **kwargs)
|
||||
|
||||
def sudo(self, **kwargs):
|
||||
return self.connect('sudo', **kwargs)
|
||||
|
||||
|
||||
class ProcessMonitor(object):
|
||||
def __init__(self):
|
||||
|
|
Loading…
Reference in New Issue