Create error messages instead of tracebacks.

pull/12587/head
Toshio Kuratomi 9 years ago
parent 946c56657b
commit 888bcd65a8

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

Loading…
Cancel
Save