40 Commits

Author SHA1 Message Date
Kevin Carter
f2364022a6 Build skel to separate the OSA connection plugin
This change implements the basic skeleton to create a new repo for the
OSA connection plugin. This change will allow the connection plugin to
be installed standalone, and maintained by a larger community.

This change has pruned the git history so that all of the old history
and commiters record for the connection plugin remains intact.

Signed-off-by: Kevin Carter <kevin@cloudnull.com>
2019-08-08 23:12:40 -05:00
Mohammed Naser
43200c2292 connection: drop shlex_quote import
shlex_quote has been part of the connection plugin since the
Ansible 2.3 release.  We don't need to do this anymore.

Change-Id: I6be4e5fdce16154ea664ccb5cb26add268b8c9b2
2019-06-03 20:13:03 -04:00
Mohammed Naser
e26a8123a4 connection: use close from superclass
We had our own re-implemented close function from when this was
first introduced which has since then drifted a lot from Ansible.

This drops all that code so that we can use the superclass when
closing the connection.

Change-Id: Id62e510af035988084453883278c3db85c8b7519
2019-06-03 19:24:37 -04:00
Mohammed Naser
7a5d042611 connection: stop running chown all the time
We made a change not long ago in order to run chown if the
container user did not match the remote user.  This is running
all the time even if we're on metal.

This code optimizes it to avoid that extra call.

Change-Id: Ia97ee15b452f3d9496a0f575b8c482e9d6bf9018
2019-06-03 19:24:37 -04:00
chengebj5238
5e376372d7 Correct spelling mistakes
Change-Id: I406390b269c00417236379303dd96dd0bffc7c4a
2019-03-28 14:10:17 +01:00
Jimmy McCrory
3333a79b1b Fix connection plugin for Ansible 2.6
inventory_hostname is not reliable to be used as container_name. When
delegating in 2.6+, the inventory_hostname of the delegating host is
passed to the connection plugin, additionally when a host doesn't have
its own container_name variable a cached inventory_hostname is used in
its place.

To get the connection plugin working with Ansible 2.6 this change
essentially allows the container_check to fall through when delegating
to physical hosts or hosts not in the inventory by:
- removing inventory_hostname as a fallback for container_name
- unsetting container_name when delegating to a known physical host
- unsetting container_name when delegating to a host not mentioned in
  the inventory

container_name can no longer be used as a group variable based on
inventory_hostname, it will need to be an inventory/host variable for
each individual host.

Also, when container_user is used the remote_tmp path needs to be set to
a system writable directory instead of the root user's home.

Change-Id: If2eb4c16273e19599f6ec3f0cba6b3573912c6a0
2018-10-18 13:27:27 -07:00
Kevin Carter
4345d676d8 Add retry to execution commands
There are quite a few instances where the "exec_command" function fails
due unrelated issues. This change adds a retry with a backoff. The exec
function will now retry 3 times in the event of an exception with a cool
down of 2 seconds. The play context for retries will also be set if
undefined making it possible to recover from transient UNREACHABLE
errors.

Change-Id: Ic7c7af49e1c5eba21216b33814b92e276e3fba3e
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2018-09-10 12:49:37 -05:00
Andy McCrae
86bed507b2 Fix connection plugin to work with Ansible 2.6.0
The connection plugin needs to follow the upstream connection/ssh
plugin's docstring, otherwise this causes failures for undefined options
sftp_executable and scp_executable. This PR adds those docstrings to
mirror upstream.

This follows on from a patch in upstream ansible:
https://github.com/ansible/ansible/pull/36648/files

Change-Id: Ia2a2f2238bb60710c7efe76e2cd9f86493833a2d
2018-07-04 12:50:08 +01:00
Jimmy McCrory
f242022479 Fix connection plugin for Ansible 2.5
For 'physical_host_addrs' to be able to be looked up by the connection
plugin it will need to be included in the 'task_vars' dictionary which
is eventually passed to the task executor. Moreover, we remove the now
obsoleted[1] 'set_host_overrides' function.

If the 'container_name' variable is available, it should take precedence
over 'inventory_hostname' for determining a container's name.

The 'container_user' variable is now set through 'set_options' instead
of a host variable and, when it is available, the connection plugin's
shell is initialized with a system writable temp directory to avoid
requiring additional privileges for the user.

The container check has been updated to also check 'container_name'
against 'ansible_host'. If these match, the container is only known by
an IP address and will require a direct SSH connection.

[1]: 23b1dbacaf
Co-Authored-By: Markos Chandras <mchandras@suse.de>
Change-Id: I16bc76f17ae5d2da4803fd7cdcdcfe72e77f9df1
2018-06-22 17:05:30 -07:00
Jimmy McCrory
b78f3cf3a1 Fix delegation to hosts not in inventory
When using Ansible 2.5, delegation of a task from a container to a host
that is not mentioned in the inventory is currently broken.

The connection plugin works by comparing the host vars 'container_name'
and 'physical_host' to determine if a target host is a container. Both
of these variables are specific to hosts within an OSA generated
inventory. When delegating to a host outside of the inventory however,
the variables will remain cached from the originating host, so a task
wouldn't actually delegate at all.

This is fixed by checking that the 'inventory_hostname' is the same as
the 'container_name'.

Change-Id: I69f2eed35859bdc149e5ed21441eab7c8a8352cf
2018-03-29 20:29:02 -07:00
Logan V
535dc8bf8e Revert "Only su within container if container_user is provided"
This reverts commit 85259066cf59ff4aa666cc5d05746fe990fd2a0e.

Change-Id: I7b819721e1eef39f28af5d4d6fb45a43047ede28
2018-03-28 23:02:42 +00:00
Logan V
030c03752b Only su within container if container_user is provided
Instead of always su - container_user -c /bin/sh.....

Now it will only pass su if container_user is set, otherwise the
execution will begin at /bin/sh inside the container.

Change-Id: I50ff0f0788855115c8bae3cb5fe5eabb4e2d74b1
2018-03-24 12:07:40 -05:00
Paul Belanger
29cfb53c29 Fix bug with pipelining disable and container_user
When using SFTP to put files onto the remote node, we place those
files into the container as the remote_user (eg: root), however when
the container_user tries to use said file, it will have the incorrect
permission.

Update put_file function to chmod files after they are copied into the
container.

Change-Id: I09d341923f43c7bc3b18252f7791880eba5469f2
Signed-off-by: Paul Belanger <pabelanger@redhat.com>
2018-03-21 11:24:01 -04:00
Paul Belanger
202eeef34d Add container_user to SSH connection plugin
This exposes the container_user setting to an operator and allows them
to override it. This is helpful when you want to use 2 different
username for your physical_host user and container user.  Today if the
physical_host user is root, the container user will always be root
too.

Change-Id: Ie8e32b0441a5d72fcbc3cbf9769d8a7dc7548f08
Signed-off-by: Paul Belanger <pabelanger@redhat.com>
2018-03-19 11:35:11 -04:00
Paul Belanger
b0d9a73803 Remove duplicate check of self.container_user
Clean up some duplicate code that is already setup in the init()
function.

Change-Id: I8e1b448a1eba483f90cbf1c43cb45d18bf0db91b
Signed-off-by: Paul Belanger <pabelanger@redhat.com>
2018-03-19 11:34:40 -04:00
Kevin Carter
a240b7b5ce Resolve nsenter fork exception
with the consolidation of container attachment methods we've seen issues
where attaching to a container a container can result in the following
error.

> __libc_fork: Assertion `THREAD_GETMEM (self, tid) != ppid'

This error is being caused by a bug in glibc which has been resolved in
2.25+.

* https://sourceware.org/bugzilla/show_bug.cgi?id=15392

To resolve this issue the lxc-attach method has been put back when
interacting with lxc type containers. While this issue has been fixed it
is not something we can rely on being fixed in all supported distros at
this time. To resolve this across the board the old lxc-attach command
has been restored to the connection plugin which has worked around the
libc issues internally.

Change-Id: I97cb3f92ae67b2c5c098c8792a0793972ec0105a
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2018-03-09 14:19:06 -06:00
Kevin Carter
1a1d722bd3 Reduce interactions by nearly 50%
The container interactions require a couple interactions to address the
container namespace as well as pad the pathing when transmitting a file.
This change reduces those interactions by nearly half for a single task
by storing information about a target container instead of looking it up
for every interaction.

Example file transfer:
  > Before this PR: http://paste.openstack.org/show/691341/
  > After this PR: http://paste.openstack.org/show/691338/

In the example we can see the "Before" runnins 20 commands to transfer
a file to a target while the "After" is running only 11.

Example command:
  > Before: http://paste.openstack.org/show/691343/
  > After: http://paste.openstack.org/show/691344/

In the command example we can see the "Before" is running 10 commands
to run a single command task while the "After" is running only 6.

This change will improve general ansible performance by cutting down the
number of operations needed to be completed to execute any one task.

Change-Id: Ia8405ec5c3b55ed3f7f134c4882d337c5e0b625f
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2018-03-05 07:32:14 +00:00
Kevin Carter
f7382e432b Update the ssh plugin for selective namespaces
The ssh plugin will now use the `nsenter` command to attach to the
container instead of splitting the command functionality between nspawn
and lxc. With the use of `nsenter` we can now selectively use different
namespaces when remotely executing against a container. A new option was
added to the plugin for "container_namespaces" which is a user provided
interface for passing in the namespaces used to attach to the container.
If this option is undefined the default namespaces will be used for full
container isolation.

Change-Id: I904ee68bbc59a0ee4458401a243246bb3f4c3523
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2018-03-01 04:47:24 -06:00
Jimmy McCrory
4a3b193579 Make connection plugin compatible with Ansible 2.5
Previously, the MAGIC_VARIABLE_MAPPING constant was updated to make
additional OSA required hostvars available to the play_context. In 2.5,
MAGIC_VARIABLE_MAPPING has a different location but updating it is no
longer necessary. Connection plugins are now able to access any hostvars
and options defined within their docstrings. The upstream connection/ssh
plugin's docstring has been copied here with the addition of OSA's
required options.

Change-Id: I6b1bcd4ec5e9d2701bd26e24e0f7645629ae4f3d
2018-02-20 09:43:51 -08:00
Kevin Carter
76db20dd32 Fix nsenter commands on centos
The follow-context switch is not valid on early releases of systemd. This
change removes the optional switch so that nsenter can work on all of
our platforms.

Change-Id: I13d05ba8bcfe785257a9cf98dbdb6024ec937816
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2018-02-05 18:15:12 +00:00
Markos Chandras
3768269e0a connection: ssh: Use individuals' host variables for physical host IP
It appears that since Ansible 2.4 the 'hostvars' variable does not
contain the host variables set by the linear plugin. However, the
physical_host_addrs variable set by that plugin is already present on
the host we are interested in. As such we can obtain that variable by
simply using the get_vars() method on the Host object.

Change-Id: Ibe2cff5fabf23e5ba6d5d165fb5406bca690a1e2
2018-01-11 17:25:05 +00:00
Kevin Carter
858a6ce432 Add basic plugin support for nspawn type containers
This change modifies our connection plugins to allow us to use nspawn
type containers. The change will pull in the container_type variable and
set the padding for commands accordingly.

While the module has been setup to default to LXC which ensures we've no
conflicts with existing deployments, the container_check function has been
set to ignore "nspawn" type containers until we have a suitable/reliable
method to connect to them without envoking ssh.

Change-Id: I8877c244af6458ca9840ea0519ab457a726feefd
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2017-12-01 04:33:18 +00:00
Jimmy McCrory
216780bf7f Make connection plugin 2.4.1 compatible
In a recent Ansible change[0], when the set_host_overrides function is
overridden it will need to include an additional argument.

[0]
1665178626

Change-Id: I1bbfddcda49b8c8a6ae21ee77d51c6db19cb212e
2017-10-09 09:56:34 -07:00
Jimmy McCrory
873f6454ab Avoid double-encoding to bytes
Both the 'container_user' used within the 'cmd' variable and the
container path padding added to the 'out_file' variable in the
connection plugin should be strings since they're later encoded
to bytes by the inherited class.

Change-Id: I8874c439fc9c006125bb39ff6a2cd386bfc8f561
2017-06-24 20:31:39 +00:00
Jenkins
b3135eaed4 Merge "conditional import of shlex_quote" 2017-06-20 17:33:01 +00:00
Kevin Carter
0097baff9d conditional import of shlex_quote
Change-Id: Ic61d680d8442d63bcf0e1c525bd27e2d5d4f1e65
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2017-06-20 17:01:27 +00:00
Jenkins
f22cafd093 Merge "Correct ansible imports" 2017-06-20 07:10:50 +00:00
Kevin Carter
8b70f0bccd Correct ansible imports
The import `to_bytes` was broken with recent ansible changes. This change
ensures that we're using the method from the embeded Ansible ssh plugin
instead of trying to import it. I've also moved the `shlex_quote`
method back to the embeded module so that we ensure we're not facing
similar import issues in the future.

Change-Id: I24b0e1c71650598f8ff5e7b4e1823411787266d2
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2017-06-19 23:40:29 -05:00
Jimmy McCrory
7abdffedf4 Fix delegation to containers between hosts
Tasks which delegate from a container to a container on a separate host
currently fail because the 'physical_host_addr' variable, which those
tasks use to connect to a physical host, is exclusively set as the
address of the originating container's physical host.

Assign a new host variable, 'physical_host_addrs', which contains a
mapping of each physical host and its address, so the tasks can now
lookup of the correct address to use depending on the target container.

Change-Id: If594914df53efacc6d5bba148f4f46280f5a117d
2017-06-19 16:14:47 -07:00
Jean-Philippe Evrard
cccfaa1a54 Python fix to the connection issue
Instead of having a conditional, we should directly use python .get()
internals, that allow to have a default.

Change-Id: I9908e83e3faa2fcc22c891c0fd6caa1fd8e92cc4
Related-Bug: 1695944
2017-06-15 06:50:11 +00:00
Markos Chandras
97e10df3fe connection: ssh: Clear environment when connecting to LXC containers
We should clear the environment before connecting to an LXC container to
avoid inheriting host variables that may break container services like
the following failure in rabbitmqctl:

TASK [Get status of rabbitmq] *************************************************************************************************************************************************************************************
fatal: [container1]: FAILED! => {"changed": true, "cmd": ["rabbitmqctl", "status"], "delta": "0:00:00.705116", "end": "2017-06-06 20:03:13.771796", "failed": true, "rc": 69, "start": "2017-06-06 20:03:13.066680", "stderr": "Error: unable to connect to node 'rabbit@vagrant-openSUSE-Leap': nodedown\n\nDIAGNOSTICS\n===========\n\nattempted to contact: ['rabbit@vagrant-openSUSE-Leap']\n\nrabbit@vagrant-openSUSE-Leap:\n  * unable to connect to epmd (port 4369) on vagrant-openSUSE-Leap: address (cannot connect to host/port)\n\n\ncurrent node details:\n- node name: 'rabbitmq-cli-82@localhost'\n- home dir: /var/lib/rabbitmq\n- cookie hash: NqWRA5RzO5daz4Jb5LJsXg==", "stderr_lines": ["Error: unable to connect to node 'rabbit@vagrant-openSUSE-Leap': nodedown", "", "DIAGNOSTICS", "===========", "", "attempted to contact: ['rabbit@vagrant-openSUSE-Leap']", "", "rabbit@vagrant-openSUSE-Leap:", "  * unable to connect to epmd (port 4369) on vagrant-openSUSE-Leap: address (cannot connect to host/port)", "", "", "current node details:", "- node name: 'rabbitmq-cli-82@localhost'", "- home dir: /var/lib/rabbitmq", "- cookie hash: NqWRA5RzO5daz4Jb5LJsXg=="], "stdout": "Status of node 'rabbit@vagrant-openSUSE-Leap' ...", "stdout_lines": ["Status of node 'rabbit@vagrant-openSUSE-Leap' ..."]}
	to retry, use: --limit @/vagrant/tests/test-rabbitmq-server-functional.retry

The reason for this failure is that the HOSTNAME variable is being
inherited by the host (vagrant-openSUSE-Leap) and the rabbitmqctl
command uses this variable to guess the host it should try to
connect to.

This is similar to what the upstream lxc connection module is doing.

This is an attempt to fix problems introduced in
https://review.openstack.org/#/c/471472/ and subsequently
reverted in https://review.openstack.org/#/c/471713/

The reason for these failures was that 'lxc-attach' executed commands
which assumed that basic variables like HOME are set properly. However,
--clear-env didn't preserve these variables so various operations started
to fail. In order to fix that, it's best if we start a real login shell
using 'su' in order to mimic an expected user environment when executing
commands within the container.

Change-Id: I684a11f4380f91b1cb0585f38817859dfaa68f80
2017-06-13 12:47:09 +00:00
Logan V
96f413af59 Actually fix connection plugin physical host var
If ansible_host is defined on the physical_host inventory item,
physical_host_addr will be set and used as the ssh destination.

However if ansible_host is not defined, we will fall back to the
physical_host inventory hostname.

Related-Bug: 1695944
Change-Id: I90ccc12fd044f08a60c84f0b8ae5d7fd783760dd
2017-06-12 09:28:53 +00:00
Logan V
618d8a2394 Fix connection plugin physical host set
I75f9d0f55ecd875caa1bf608a77c92f950b679a1 introduced a problem when
ansible_host is not defined on a host.

Related-Bug: 1695944
Change-Id: I9863757eef363cb05f581ab1449eb2f4aa3a0dda
2017-06-09 11:43:14 -05:00
Jimmy McCrory
45ef6f46cb Connect using physical host's ansible_host var
Within the strategy plugin set a host var, 'physical_host_addr', which
corresponds to the 'ansible_host' var of the host's 'physical_host'.

Use this within the connection plugin rather than the hostname of the
physical host, which may not exist in DNS or the deployment host's
hosts file.

Closes-Bug: 1695944
Change-Id: I75f9d0f55ecd875caa1bf608a77c92f950b679a1
2017-06-07 21:46:23 -07:00
Jesse Pretorius (odyssey4me)
93aa9ce2e0 Revert "connection: ssh: Clear environment when connecting to LXC containers"
Unfortunately this breaks other roles/deployments as there are now
no environment variables set for the user. This is being reverted to
unblock the gate. We'll need to more carefully cross-repo test this
when it comes in again.

This reverts commit c2c71bc2b078ad6b16774e76b735dd8251565633.

Change-Id: I5981e72d8153e6ea490446ac9e2e8e31959d9f72
2017-06-07 10:36:08 +00:00
Markos Chandras
84dd7d3235 connection: ssh: Clear environment when connecting to LXC containers
We should clear the environment before connecting to an LXC container to
avoid inheriting host variables that may break container services like
the following failure in rabbitmqctl:

TASK [Get status of rabbitmq] *************************************************************************************************************************************************************************************
fatal: [container1]: FAILED! => {"changed": true, "cmd": ["rabbitmqctl", "status"], "delta": "0:00:00.705116", "end": "2017-06-06 20:03:13.771796", "failed": true, "rc": 69, "start": "2017-06-06 20:03:13.066680", "stderr": "Error: unable to connect to node 'rabbit@vagrant-openSUSE-Leap': nodedown\n\nDIAGNOSTICS\n===========\n\nattempted to contact: ['rabbit@vagrant-openSUSE-Leap']\n\nrabbit@vagrant-openSUSE-Leap:\n  * unable to connect to epmd (port 4369) on vagrant-openSUSE-Leap: address (cannot connect to host/port)\n\n\ncurrent node details:\n- node name: 'rabbitmq-cli-82@localhost'\n- home dir: /var/lib/rabbitmq\n- cookie hash: NqWRA5RzO5daz4Jb5LJsXg==", "stderr_lines": ["Error: unable to connect to node 'rabbit@vagrant-openSUSE-Leap': nodedown", "", "DIAGNOSTICS", "===========", "", "attempted to contact: ['rabbit@vagrant-openSUSE-Leap']", "", "rabbit@vagrant-openSUSE-Leap:", "  * unable to connect to epmd (port 4369) on vagrant-openSUSE-Leap: address (cannot connect to host/port)", "", "", "current node details:", "- node name: 'rabbitmq-cli-82@localhost'", "- home dir: /var/lib/rabbitmq", "- cookie hash: NqWRA5RzO5daz4Jb5LJsXg=="], "stdout": "Status of node 'rabbit@vagrant-openSUSE-Leap' ...", "stdout_lines": ["Status of node 'rabbit@vagrant-openSUSE-Leap' ..."]}
	to retry, use: --limit @/vagrant/tests/test-rabbitmq-server-functional.retry

The reason for this failure is that the HOSTNAME variable is being
inherited by the host (vagrant-openSUSE-Leap) and the rabbitmqctl
command uses this variable to guess the host it should try to
connect to.

This is similar to what the upstream lxc connection module is doing.

Link: https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/lxc.py#L121
Change-Id: Ic3b8bf9a9aaf8738c49490e22fec2fc0b5140ac0
2017-06-06 21:09:32 +01:00
Logan V
6fd65d3614 Support delegation in strategy plugin
The strategy plugin previously did not support container detection
when the delegate_to host was a container. This adds support for
delegating tasks to other containers, so the strategy will perform
the same container vars lookups so the SSH connection is toward the
physical host of the container, and the command is wrapped with
lxc-attach based on the container_name.

Co-Authored-By: Jimmy McCrory <jimmy.mccrory@gmail.com>
Change-Id: I56d8afddbccf01f2944d2fdd505b601a4b048374
2017-04-21 23:52:09 +00:00
Kevin Carter
815f92f70e Updated connection plugin for ansible 2.3 support
This change allows the connection plugin to work with Ansible 2.3.
Upstream changes now require the use of the public method.

Change-Id: I044aa442f116cbbf5fbdb6e6ca0b691c04c56a2d
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2017-03-23 13:26:20 -05:00
Jesse Pretorius
59e5f8168b Add ability to execute against a remote chroot
In some situations it may be useful to execute a role or
set of tasks against a remote chroot.

This patch aims to add that capability.

Change-Id: Icebec389807aa8782f97a95f63687eb5606f7b22
2016-11-22 12:28:35 +00:00
Kevin Carter
267317d028 Implement an opportunistic strategy and connection plugin
This change is creating an opportunistic Ansible execution strategy and
an update the ssh connection plugin so that it supports direct access to lxc
containers within ever having to ssh into them.

The intention of this change is to speed up execution time and reliability by
tuning the execution environment within Ansible to run faster while also attempting
to subvert transient ssh issues.

Change-Id: Ide34513bf82523257bdd2a8a68dff165f9927c56
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
2016-08-25 17:45:10 +00:00