Create error messages instead of tracebacks.

This commit is contained in:
Toshio Kuratomi 2015-09-30 19:16:00 -07:00
parent 946c56657b
commit 888bcd65a8

View file

@ -3,6 +3,7 @@
# Connection plugin for configuring docker containers
# (c) 2014, Lorin Hochstein
# (c) 2015, Leendert Brouwer
# (c) 2015, Toshio Kuratomi <tkuratomi@ansible.com>
#
# Maintainer: Leendert Brouwer (https://github.com/objectified)
#
@ -20,7 +21,10 @@
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import distutils.spawn
import os
import subprocess
import re
@ -36,8 +40,8 @@ BUFSIZE = 65536
class Connection(ConnectionBase):
has_pipelining = True
transport = 'docker'
has_pipelining = True
# su currently has an undiagnosed issue with calculating the file
# checksums (so copy, for instance, doesn't work right)
# Have to look into that before re-enabling this
@ -52,10 +56,13 @@ class Connection(ConnectionBase):
# group). But if the user is getting a permission denied error it
# probably means that docker on their system is only configured to be
# connected to by root and they are not running as root.
if 'docker_command' in kwargs:
self.docker_cmd = kwargs['docker_command']
else:
self.docker_cmd = 'docker'
self.docker_cmd = distutils.spawn.find_executable('docker')
if not self.docker_cmd:
raise AnsibleError("docker command not found in PATH")
self.can_copy_bothways = False
@ -93,7 +100,7 @@ class Connection(ConnectionBase):
""" Connect to the container. Nothing to do """
super(Connection, self)._connect()
if not self._connected:
self._display.vvv("ESTABLISH LOCAL CONNECTION FOR USER: {0}".format(
self._display.vvv("ESTABLISH DOCKER CONNECTION FOR USER: {0}".format(
self._play_context.remote_user, host=self._play_context.remote_addr)
)
self._connected = True
@ -107,6 +114,8 @@ class Connection(ConnectionBase):
local_cmd = [self.docker_cmd, "exec", '-i', self._play_context.remote_addr, executable, '-c', cmd]
self._display.vvv("EXEC %s" % (local_cmd), host=self._play_context.remote_addr)
# FIXME: cwd= needs to be set to the basedir of the playbook, which
# should come from loader, but is not in the connection plugins
p = subprocess.Popen(local_cmd,
shell=False,
stdin=subprocess.PIPE,
@ -127,13 +136,11 @@ class Connection(ConnectionBase):
if self.can_copy_bothways:
# only docker >= 1.8.1 can do this natively
args = [
self.docker_cmd,
"cp",
"%s" % in_path,
"%s:%s" % (self._play_context.remote_addr, out_path)
]
subprocess.check_call(args)
args = [ self.docker_cmd, "cp", in_path, "%s:%s" % (self._play_context.remote_addr, out_path) ]
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, stdout, stderr))
else:
# Older docker doesn't have native support for copying files into
# running containers, so we use docker exec to implement this
@ -145,7 +152,7 @@ class Connection(ConnectionBase):
p = subprocess.Popen(args, stdin=in_file,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except OSError:
raise AnsibleError("docker connection requires dd command in the chroot")
raise AnsibleError("docker connection with docker < 1.8.1 requires dd command in the chroot")
stdout, stderr = p.communicate()
if p.returncode != 0:
@ -174,4 +181,5 @@ class Connection(ConnectionBase):
def close(self):
""" Terminate the connection. Nothing to do for Docker"""
super(Connection, self).close()
self._connected = False