Move connection plugins to using global display

pull/12547/merge
Toshio Kuratomi 9 years ago
parent 318bfbb207
commit aa4f213cb5

@ -22,7 +22,6 @@ __metaclass__ = type
import fcntl
import gettext
import select
import os
from abc import ABCMeta, abstractmethod, abstractproperty
@ -68,6 +67,7 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
self._play_context = play_context
if not hasattr(self, '_new_stdin'):
self._new_stdin = new_stdin
# Backwards compat: self._display isn't really needed, just import the global display and use that.
if not hasattr(self, '_display'):
self._display = display
if not hasattr(self, '_connected'):
@ -220,11 +220,11 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
def connection_lock(self):
f = self._play_context.connection_lockfd
self._display.vvvv('CONNECTION: pid %d waiting for lock on %d' % (os.getpid(), f))
display.vvvv('CONNECTION: pid %d waiting for lock on %d' % (os.getpid(), f))
fcntl.lockf(f, fcntl.LOCK_EX)
self._display.vvvv('CONNECTION: pid %d acquired lock on %d' % (os.getpid(), f))
display.vvvv('CONNECTION: pid %d acquired lock on %d' % (os.getpid(), f))
def connection_unlock(self):
f = self._play_context.connection_lockfd
fcntl.lockf(f, fcntl.LOCK_UN)
self._display.vvvv('CONNECTION: pid %d released lock on %d' % (os.getpid(), f))
display.vvvv('CONNECTION: pid %d released lock on %d' % (os.getpid(), f))

@ -29,17 +29,23 @@ from ansible import constants as C
from ansible.errors import AnsibleError, AnsibleFileNotFound, AnsibleConnectionFailure
from ansible.parsing.utils.jsonify import jsonify
from ansible.plugins.connection import ConnectionBase
from ansible.plugins.connection.ssh import Connection as SSHConnection
from ansible.plugins.connection.paramiko_ssh import Connection as ParamikoConnection
from ansible.utils.encrypt import key_for_hostname, keyczar_encrypt, keyczar_decrypt
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
# the chunk size to read and send, assuming mtu 1500 and
# leaving room for base64 (+33%) encoding and header (8 bytes)
# ((1400-8)/4)*3) = 1044
# which leaves room for the TCP/IP header. We set this to a
# which leaves room for the TCP/IP header. We set this to a
# multiple of the value to speed up file reads.
CHUNK_SIZE=1044*20
class Connection(ConnectionBase):
''' raw socket accelerated connection '''
@ -62,25 +68,25 @@ class Connection(ConnectionBase):
tries = 3
self.conn = socket.socket()
self.conn.settimeout(C.ACCELERATE_CONNECT_TIMEOUT)
self._display.vvvv("attempting connection to %s via the accelerated port %d" % (self._play_context.remote_addr,self._play_context.accelerate_port))
display.vvvv("attempting connection to %s via the accelerated port %d" % (self._play_context.remote_addr,self._play_context.accelerate_port))
while tries > 0:
try:
self.conn.connect((self._play_context.remote_addr,self._play_context.accelerate_port))
break
except socket.error:
self._display.vvvv("connection to %s failed, retrying..." % self._play_context.remote_addr)
display.vvvv("connection to %s failed, retrying..." % self._play_context.remote_addr)
time.sleep(0.1)
tries -= 1
if tries == 0:
self._display.vvv("Could not connect via the accelerated connection, exceeded # of tries")
display.vvv("Could not connect via the accelerated connection, exceeded # of tries")
raise AnsibleConnectionFailure("Failed to connect to %s on the accelerated port %s" % (self._play_context.remote_addr, self._play_context.accelerate_port))
elif wrong_user:
self._display.vvv("Restarting daemon with a different remote_user")
display.vvv("Restarting daemon with a different remote_user")
raise AnsibleError("The accelerated daemon was started on the remote with a different user")
self.conn.settimeout(C.ACCELERATE_TIMEOUT)
if not self.validate_user():
# the accelerated daemon was started with a
# the accelerated daemon was started with a
# different remote_user. The above command
# should have caused the accelerate daemon to
# shutdown, so we'll reconnect.
@ -97,37 +103,37 @@ class Connection(ConnectionBase):
header_len = 8 # size of a packed unsigned long long
data = b""
try:
self._display.vvvv("%s: in recv_data(), waiting for the header" % self._play_context.remote_addr)
display.vvvv("%s: in recv_data(), waiting for the header" % self._play_context.remote_addr)
while len(data) < header_len:
d = self.conn.recv(header_len - len(data))
if not d:
self._display.vvvv("%s: received nothing, bailing out" % self._play_context.remote_addr)
display.vvvv("%s: received nothing, bailing out" % self._play_context.remote_addr)
return None
data += d
self._display.vvvv("%s: got the header, unpacking" % self._play_context.remote_addr)
display.vvvv("%s: got the header, unpacking" % self._play_context.remote_addr)
data_len = struct.unpack('!Q',data[:header_len])[0]
data = data[header_len:]
self._display.vvvv("%s: data received so far (expecting %d): %d" % (self._play_context.remote_addr,data_len,len(data)))
display.vvvv("%s: data received so far (expecting %d): %d" % (self._play_context.remote_addr,data_len,len(data)))
while len(data) < data_len:
d = self.conn.recv(data_len - len(data))
if not d:
self._display.vvvv("%s: received nothing, bailing out" % self._play_context.remote_addr)
display.vvvv("%s: received nothing, bailing out" % self._play_context.remote_addr)
return None
self._display.vvvv("%s: received %d bytes" % (self._play_context.remote_addr, len(d)))
display.vvvv("%s: received %d bytes" % (self._play_context.remote_addr, len(d)))
data += d
self._display.vvvv("%s: received all of the data, returning" % self._play_context.remote_addr)
display.vvvv("%s: received all of the data, returning" % self._play_context.remote_addr)
return data
except socket.timeout:
raise AnsibleError("timed out while waiting to receive data")
def validate_user(self):
'''
Checks the remote uid of the accelerated daemon vs. the
one specified for this play and will cause the accel
Checks the remote uid of the accelerated daemon vs. the
one specified for this play and will cause the accel
daemon to exit if they don't match
'''
self._display.vvvv("%s: sending request for validate_user" % self._play_context.remote_addr)
display.vvvv("%s: sending request for validate_user" % self._play_context.remote_addr)
data = dict(
mode='validate_user',
username=self._play_context.remote_user,
@ -137,7 +143,7 @@ class Connection(ConnectionBase):
if self.send_data(data):
raise AnsibleError("Failed to send command to %s" % self._play_context.remote_addr)
self._display.vvvv("%s: waiting for validate_user response" % self._play_context.remote_addr)
display.vvvv("%s: waiting for validate_user response" % self._play_context.remote_addr)
while True:
# we loop here while waiting for the response, because a
# long running command may cause us to receive keepalive packets
@ -149,10 +155,10 @@ class Connection(ConnectionBase):
response = json.loads(response)
if "pong" in response:
# it's a keepalive, go back to waiting
self._display.vvvv("%s: received a keepalive packet" % self._play_context.remote_addr)
display.vvvv("%s: received a keepalive packet" % self._play_context.remote_addr)
continue
else:
self._display.vvvv("%s: received the validate_user response: %s" % (self._play_context.remote_addr, response))
display.vvvv("%s: received the validate_user response: %s" % (self._play_context.remote_addr, response))
break
if response.get('failed'):
@ -169,7 +175,7 @@ class Connection(ConnectionBase):
if in_data:
raise AnsibleError("Internal Error: this module does not support optimized module pipelining")
self._display.vvv("EXEC COMMAND %s" % cmd)
display.vvv("EXEC COMMAND %s" % cmd)
data = dict(
mode='command',
@ -180,11 +186,11 @@ class Connection(ConnectionBase):
data = keyczar_encrypt(self.key, data)
if self.send_data(data):
raise AnsibleError("Failed to send command to %s" % self._play_context.remote_addr)
while True:
# we loop here while waiting for the response, because a
# we loop here while waiting for the response, because a
# long running command may cause us to receive keepalive packets
# ({"pong":"true"}) rather than the response we want.
# ({"pong":"true"}) rather than the response we want.
response = self.recv_data()
if not response:
raise AnsibleError("Failed to get a response from %s" % self._play_context.remote_addr)
@ -192,10 +198,10 @@ class Connection(ConnectionBase):
response = json.loads(response)
if "pong" in response:
# it's a keepalive, go back to waiting
self._display.vvvv("%s: received a keepalive packet" % self._play_context.remote_addr)
display.vvvv("%s: received a keepalive packet" % self._play_context.remote_addr)
continue
else:
self._display.vvvv("%s: received the response" % self._play_context.remote_addr)
display.vvvv("%s: received the response" % self._play_context.remote_addr)
break
return (response.get('rc', None), response.get('stdout', ''), response.get('stderr', ''))
@ -203,7 +209,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
''' transfer a file from local to remote '''
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
if not os.path.exists(in_path):
raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
@ -211,10 +217,10 @@ class Connection(ConnectionBase):
fd = file(in_path, 'rb')
fstat = os.stat(in_path)
try:
self._display.vvv("PUT file is %d bytes" % fstat.st_size)
display.vvv("PUT file is %d bytes" % fstat.st_size)
last = False
while fd.tell() <= fstat.st_size and not last:
self._display.vvvv("file position currently %ld, file size is %ld" % (fd.tell(), fstat.st_size))
display.vvvv("file position currently %ld, file size is %ld" % (fd.tell(), fstat.st_size))
data = fd.read(CHUNK_SIZE)
if fd.tell() >= fstat.st_size:
last = True
@ -237,7 +243,7 @@ class Connection(ConnectionBase):
raise AnsibleError("failed to put the file in the requested location")
finally:
fd.close()
self._display.vvvv("waiting for final response after PUT")
display.vvvv("waiting for final response after PUT")
response = self.recv_data()
if not response:
raise AnsibleError("Failed to get a response from %s" % self._play_context.remote_addr)
@ -249,7 +255,7 @@ class Connection(ConnectionBase):
def fetch_file(self, in_path, out_path):
''' save a remote file to the specified path '''
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
data = dict(mode='fetch', in_path=in_path)
data = jsonify(data)
@ -271,7 +277,7 @@ class Connection(ConnectionBase):
out = base64.b64decode(response['data'])
fh.write(out)
bytes += len(out)
# send an empty response back to signify we
# send an empty response back to signify we
# received the last chunk without errors
data = jsonify(dict())
data = keyczar_encrypt(self.key, data)
@ -285,7 +291,7 @@ class Connection(ConnectionBase):
# point in the future or we may just have the put/fetch
# operations not send back a final response at all
response = self.recv_data()
self._display.vvv("FETCH wrote %d bytes to %s" % (bytes, out_path))
display.vvv("FETCH wrote %d bytes to %s" % (bytes, out_path))
fh.close()
def close(self):
@ -295,4 +301,3 @@ class Connection(ConnectionBase):
self.conn.close()
except:
pass

@ -31,6 +31,12 @@ from ansible.errors import AnsibleError
from ansible.plugins.connection import ConnectionBase
from ansible.module_utils.basic import is_executable
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
BUFSIZE = 65536
@ -70,7 +76,7 @@ class Connection(ConnectionBase):
''' connect to the chroot; nothing to do here '''
super(Connection, self)._connect()
if not self._connected:
self._display.vvv("THIS IS A LOCAL CHROOT DIR", host=self.chroot)
display.vvv("THIS IS A LOCAL CHROOT DIR", host=self.chroot)
self._connected = True
def _buffered_exec_command(self, cmd, stdin=subprocess.PIPE):
@ -84,7 +90,7 @@ class Connection(ConnectionBase):
executable = C.DEFAULT_EXECUTABLE.split()[0] if C.DEFAULT_EXECUTABLE else '/bin/sh'
local_cmd = [self.chroot_cmd, self.chroot, executable, '-c', cmd]
self._display.vvv("EXEC %s" % (local_cmd), host=self.chroot)
display.vvv("EXEC %s" % (local_cmd), host=self.chroot)
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@ -116,7 +122,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
''' transfer a file from local to chroot '''
super(Connection, self).put_file(in_path, out_path)
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.chroot)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.chroot)
out_path = pipes.quote(self._prefix_login_path(out_path))
try:
@ -138,7 +144,7 @@ class Connection(ConnectionBase):
def fetch_file(self, in_path, out_path):
''' fetch a file from chroot to local '''
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.chroot)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.chroot)
in_path = pipes.quote(self._prefix_login_path(in_path))
try:

@ -37,8 +37,16 @@ import ansible.constants as C
from ansible.errors import AnsibleError, AnsibleFileNotFound
from ansible.plugins.connection import ConnectionBase
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
BUFSIZE = 65536
class Connection(ConnectionBase):
''' Local docker based connections '''
@ -103,7 +111,7 @@ class Connection(ConnectionBase):
""" Connect to the container. Nothing to do """
super(Connection, self)._connect()
if not self._connected:
self._display.vvv("ESTABLISH DOCKER CONNECTION FOR USER: {0}".format(
display.vvv("ESTABLISH DOCKER CONNECTION FOR USER: {0}".format(
self._play_context.remote_user, host=self._play_context.remote_addr)
)
self._connected = True
@ -116,7 +124,7 @@ class Connection(ConnectionBase):
# -i is needed to keep stdin open which allows pipelining to work
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)
display.vvv("EXEC %s" % (local_cmd), host=self._play_context.remote_addr)
p = subprocess.Popen(local_cmd, shell=False, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@ -140,7 +148,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
""" Transfer a file from local to docker container """
super(Connection, self).put_file(in_path, out_path)
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
out_path = self._prefix_login_path(out_path)
if not os.path.exists(in_path):
@ -175,7 +183,7 @@ class Connection(ConnectionBase):
def fetch_file(self, in_path, out_path):
""" Fetch a file from container to local. """
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
in_path = self._prefix_login_path(in_path)
# out_path is the final file path, but docker takes a directory, not a

@ -31,6 +31,12 @@ from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.plugins.connection import ConnectionBase
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
BUFSIZE = 65536
@ -58,7 +64,7 @@ class Connection(ConnectionBase):
self.jls_cmd = self._search_executable('jls')
self.jexec_cmd = self._search_executable('jexec')
if not self.jail in self.list_jails():
if self.jail not in self.list_jails():
raise AnsibleError("incorrect jail name %s" % self.jail)
@staticmethod
@ -90,7 +96,7 @@ class Connection(ConnectionBase):
''' connect to the jail; nothing to do here '''
super(Connection, self)._connect()
if not self._connected:
self._display.vvv("THIS IS A LOCAL JAIL DIR", host=self.jail)
display.vvv("THIS IS A LOCAL JAIL DIR", host=self.jail)
self._connected = True
def _buffered_exec_command(self, cmd, stdin=subprocess.PIPE):
@ -104,7 +110,7 @@ class Connection(ConnectionBase):
executable = C.DEFAULT_EXECUTABLE.split()[0] if C.DEFAULT_EXECUTABLE else '/bin/sh'
local_cmd = [self.jexec_cmd, self.jail, executable, '-c', cmd]
self._display.vvv("EXEC %s" % (local_cmd), host=self.jail)
display.vvv("EXEC %s" % (local_cmd), host=self.jail)
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@ -143,7 +149,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
''' transfer a file from local to jail '''
super(Connection, self).put_file(in_path, out_path)
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.jail)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.jail)
out_path = pipes.quote(self._prefix_login_path(out_path))
try:
@ -165,7 +171,7 @@ class Connection(ConnectionBase):
def fetch_file(self, in_path, out_path):
''' fetch a file from jail to local '''
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.jail)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.jail)
in_path = pipes.quote(self._prefix_login_path(in_path))
try:

@ -31,6 +31,12 @@ from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.plugins.connection import ConnectionBase
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
BUFSIZE = 65536
@ -70,7 +76,7 @@ class Connection(ConnectionBase):
''' connect to the lxc; nothing to do here '''
super(Connection, self)._connect()
if not self._connected:
self._display.vvv("THIS IS A LOCAL LXC DIR", host=self.lxc)
display.vvv("THIS IS A LOCAL LXC DIR", host=self.lxc)
self._connected = True
def _buffered_exec_command(self, cmd, stdin=subprocess.PIPE):
@ -84,7 +90,7 @@ class Connection(ConnectionBase):
executable = C.DEFAULT_EXECUTABLE.split()[0] if C.DEFAULT_EXECUTABLE else '/bin/sh'
local_cmd = [self.virsh, '-q', '-c', 'lxc:///', 'lxc-enter-namespace', self.lxc, '--', executable , '-c', cmd]
self._display.vvv("EXEC %s" % (local_cmd), host=self.lxc)
display.vvv("EXEC %s" % (local_cmd), host=self.lxc)
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@ -116,7 +122,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
''' transfer a file from local to lxc '''
super(Connection, self).put_file(in_path, out_path)
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.lxc)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.lxc)
out_path = pipes.quote(self._prefix_login_path(out_path))
try:
@ -138,7 +144,7 @@ class Connection(ConnectionBase):
def fetch_file(self, in_path, out_path):
''' fetch a file from lxc to local '''
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.lxc)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.lxc)
in_path = pipes.quote(self._prefix_login_path(in_path))
try:

@ -18,7 +18,6 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import traceback
import os
import shutil
import subprocess
@ -31,6 +30,14 @@ import ansible.constants as C
from ansible.errors import AnsibleError, AnsibleFileNotFound
from ansible.plugins.connection import ConnectionBase
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
class Connection(ConnectionBase):
''' Local based connections '''
@ -48,7 +55,7 @@ class Connection(ConnectionBase):
self._play_context.remote_user = getpass.getuser()
if not self._connected:
self._display.vvv("ESTABLISH LOCAL CONNECTION FOR USER: {0}".format(self._play_context.remote_user, host=self._play_context.remote_addr))
display.vvv("ESTABLISH LOCAL CONNECTION FOR USER: {0}".format(self._play_context.remote_user, host=self._play_context.remote_addr))
self._connected = True
return self
@ -57,15 +64,15 @@ class Connection(ConnectionBase):
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
self._display.debug("in local.exec_command()")
display.debug("in local.exec_command()")
if in_data:
raise AnsibleError("Internal Error: this module does not support optimized module pipelining")
executable = C.DEFAULT_EXECUTABLE.split()[0] if C.DEFAULT_EXECUTABLE else None
self._display.vvv("{0} EXEC {1}".format(self._play_context.remote_addr, cmd))
display.vvv("{0} EXEC {1}".format(self._play_context.remote_addr, cmd))
# FIXME: cwd= needs to be set to the basedir of the playbook
self._display.debug("opening command with Popen()")
display.debug("opening command with Popen()")
p = subprocess.Popen(
cmd,
shell=isinstance(cmd, basestring),
@ -74,7 +81,7 @@ class Connection(ConnectionBase):
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
self._display.debug("done running command with Popen()")
display.debug("done running command with Popen()")
if self._play_context.prompt and sudoable:
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
@ -99,11 +106,11 @@ class Connection(ConnectionBase):
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) & ~os.O_NONBLOCK)
self._display.debug("getting output with communicate()")
display.debug("getting output with communicate()")
stdout, stderr = p.communicate()
self._display.debug("done communicating")
display.debug("done communicating")
self._display.debug("done with local.exec_command()")
display.debug("done with local.exec_command()")
return (p.returncode, stdout, stderr)
def put_file(self, in_path, out_path):
@ -111,7 +118,7 @@ class Connection(ConnectionBase):
super(Connection, self).put_file(in_path, out_path)
self._display.vvv("{0} PUT {1} TO {2}".format(self._play_context.remote_addr, in_path, out_path))
display.vvv("{0} PUT {1} TO {2}".format(self._play_context.remote_addr, in_path, out_path))
if not os.path.exists(in_path):
raise AnsibleFileNotFound("file or module does not exist: {0}".format(in_path))
try:
@ -126,7 +133,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv("{0} FETCH {1} TO {2}".format(self._play_context.remote_addr, in_path, out_path))
display.vvv("{0} FETCH {1} TO {2}".format(self._play_context.remote_addr, in_path, out_path))
self.put_file(in_path, out_path)
def close(self):

@ -26,14 +26,11 @@ __metaclass__ = type
import warnings
import os
import pipes
import socket
import random
import logging
import tempfile
import traceback
import fcntl
import re
import sys
from termios import tcflush, TCIFLUSH
@ -46,6 +43,13 @@ from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNo
from ansible.plugins.connection import ConnectionBase
from ansible.utils.path import makedirs_safe
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
AUTHENTICITY_MSG="""
paramiko: The authenticity of host '%s' can't be established.
The %s key fingerprint is %s.
@ -114,6 +118,7 @@ class MyAddPolicy(object):
SSH_CONNECTION_CACHE = {}
SFTP_CONNECTION_CACHE = {}
class Connection(ConnectionBase):
''' SSH based connections with Paramiko '''
@ -140,7 +145,7 @@ class Connection(ConnectionBase):
raise AnsibleError("paramiko is not installed")
port = self._play_context.port or 22
self._display.vvv("ESTABLISH CONNECTION FOR USER: %s on PORT %s TO %s" % (self._play_context.remote_user, port, self._play_context.remote_addr), host=self._play_context.remote_addr)
display.vvv("ESTABLISH CONNECTION FOR USER: %s on PORT %s TO %s" % (self._play_context.remote_user, port, self._play_context.remote_addr), host=self._play_context.remote_addr)
ssh = paramiko.SSHClient()
@ -214,7 +219,7 @@ class Connection(ConnectionBase):
if C.PARAMIKO_PTY:
chan.get_pty(term=os.getenv('TERM', 'vt100'), width=int(os.getenv('COLUMNS', 0)), height=int(os.getenv('LINES', 0)))
self._display.vvv("EXEC %s" % cmd, host=self._play_context.remote_addr)
display.vvv("EXEC %s" % cmd, host=self._play_context.remote_addr)
no_prompt_out = ''
no_prompt_err = ''
@ -225,7 +230,7 @@ class Connection(ConnectionBase):
if self._play_context.prompt:
passprompt = False
while True:
self._display.debug('Waiting for Privilege Escalation input')
display.debug('Waiting for Privilege Escalation input')
if self.check_become_success(become_output):
break
elif self.check_password_prompt(become_output):
@ -233,7 +238,7 @@ class Connection(ConnectionBase):
break
chunk = chan.recv(bufsize)
self._display.debug("chunk is: %s" % chunk)
display.debug("chunk is: %s" % chunk)
if not chunk:
if 'unknown user' in become_output:
raise AnsibleError( 'user %s does not exist' % self._play_context.become_user)
@ -262,7 +267,7 @@ class Connection(ConnectionBase):
super(Connection, self).put_file(in_path, out_path)
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
if not os.path.exists(in_path):
raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
@ -291,7 +296,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
try:
self.sftp = self._connect_sftp()
@ -305,7 +310,6 @@ class Connection(ConnectionBase):
def _any_keys_added(self):
added_any = False
for hostname, keys in iteritems(self.ssh._host_keys):
for keytype, key in iteritems(keys):
added_this_time = getattr(key, '_added_by_ansible_this_time', False)
@ -402,4 +406,3 @@ class Connection(ConnectionBase):
fcntl.lockf(KEY_LOCK, fcntl.LOCK_UN)
self.ssh.close()

@ -34,8 +34,16 @@ from ansible.plugins.connection import ConnectionBase
from ansible.utils.path import unfrackpath, makedirs_safe
from ansible.utils.unicode import to_bytes, to_unicode
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
SSHPASS_AVAILABLE = None
class Connection(ConnectionBase):
''' ssh based connections '''
@ -109,7 +117,7 @@ class Connection(ConnectionBase):
explanation of why they were added.
"""
self._command += args
self._display.vvvvv('SSH: ' + explanation + ': (%s)' % ')('.join(args), host=self._play_context.remote_addr)
display.vvvvv('SSH: ' + explanation + ': (%s)' % ')('.join(args), host=self._play_context.remote_addr)
def _build_command(self, binary, *other_args):
'''
@ -242,7 +250,7 @@ class Connection(ConnectionBase):
just hang forever waiting for more commands.)
'''
self._display.debug('Sending initial data')
display.debug('Sending initial data')
try:
fh.write(in_data)
@ -250,7 +258,7 @@ class Connection(ConnectionBase):
except (OSError, IOError):
raise AnsibleConnectionFailure('SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh')
self._display.debug('Sent initial data (%d bytes)' % len(in_data))
display.debug('Sent initial data (%d bytes)' % len(in_data))
# Used by _run() to kill processes on failures
@staticmethod
@ -277,20 +285,20 @@ class Connection(ConnectionBase):
for l in chunk.splitlines(True):
suppress_output = False
# self._display.debug("Examining line (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
# display.debug("Examining line (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
if self._play_context.prompt and self.check_password_prompt(l):
self._display.debug("become_prompt: (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
display.debug("become_prompt: (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
self._flags['become_prompt'] = True
suppress_output = True
elif self._play_context.success_key and self.check_become_success(l):
self._display.debug("become_success: (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
display.debug("become_success: (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
self._flags['become_success'] = True
suppress_output = True
elif sudoable and self.check_incorrect_password(l):
self._display.debug("become_error: (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
display.debug("become_error: (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
self._flags['become_error'] = True
elif sudoable and self.check_missing_password(l):
self._display.debug("become_nopasswd_error: (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
display.debug("become_nopasswd_error: (source=%s, state=%s): '%s'" % (source, state, l.rstrip('\r\n')))
self._flags['become_nopasswd_error'] = True
if not suppress_output:
@ -314,7 +322,7 @@ class Connection(ConnectionBase):
'''
display_cmd = map(pipes.quote, cmd[:-1]) + [cmd[-1]]
self._display.vvv('SSH: EXEC {0}'.format(' '.join(display_cmd)), host=self.host)
display.vvv('SSH: EXEC {0}'.format(' '.join(display_cmd)), host=self.host)
# Start the given command. If we don't need to pipeline data, we can try
# to use a pseudo-tty (ssh will have been invoked with -tt). If we are
@ -364,12 +372,12 @@ class Connection(ConnectionBase):
# We're requesting escalation with a password, so we have to
# wait for a password prompt.
state = states.index('awaiting_prompt')
self._display.debug('Initial state: %s: %s' % (states[state], self._play_context.prompt))
display.debug('Initial state: %s: %s' % (states[state], self._play_context.prompt))
elif self._play_context.become and self._play_context.success_key:
# We're requesting escalation without a password, so we have to
# detect success/failure before sending any initial data.
state = states.index('awaiting_escalation')
self._display.debug('Initial state: %s: %s' % (states[state], self._play_context.success_key))
display.debug('Initial state: %s: %s' % (states[state], self._play_context.success_key))
# We store accumulated stdout and stderr output from the process here,
# but strip any privilege escalation prompt/confirmation lines first.
@ -415,14 +423,14 @@ class Connection(ConnectionBase):
if chunk == '':
rpipes.remove(p.stdout)
tmp_stdout += chunk
self._display.debug("stdout chunk (state=%s):\n>>>%s<<<\n" % (state, chunk))
display.debug("stdout chunk (state=%s):\n>>>%s<<<\n" % (state, chunk))
if p.stderr in rfd:
chunk = p.stderr.read()
if chunk == '':
rpipes.remove(p.stderr)
tmp_stderr += chunk
self._display.debug("stderr chunk (state=%s):\n>>>%s<<<\n" % (state, chunk))
display.debug("stderr chunk (state=%s):\n>>>%s<<<\n" % (state, chunk))
# We examine the output line-by-line until we have negotiated any
# privilege escalation prompt and subsequent success/error message.
@ -446,7 +454,7 @@ class Connection(ConnectionBase):
# If we see a privilege escalation prompt, we send the password.
if states[state] == 'awaiting_prompt' and self._flags['become_prompt']:
self._display.debug('Sending become_pass in response to prompt')
display.debug('Sending become_pass in response to prompt')
stdin.write(self._play_context.become_pass + '\n')
self._flags['become_prompt'] = False
state += 1
@ -456,23 +464,23 @@ class Connection(ConnectionBase):
if states[state] == 'awaiting_escalation':
if self._flags['become_success']:
self._display.debug('Escalation succeeded')
display.debug('Escalation succeeded')
self._flags['become_success'] = False
state += 1
elif self._flags['become_error']:
self._display.debug('Escalation failed')
display.debug('Escalation failed')
self._terminate_process(p)
self._flags['become_error'] = False
raise AnsibleError('Incorrect %s password' % self._play_context.become_method)
elif self._flags['become_nopasswd_error']:
self._display.debug('Escalation requires password')
display.debug('Escalation requires password')
self._terminate_process(p)
self._flags['become_nopasswd_error'] = False
raise AnsibleError('Missing %s password' % self._play_context.become_method)
elif self._flags['become_prompt']:
# This shouldn't happen, because we should see the "Sorry,
# try again" message first.
self._display.debug('Escalation prompt repeated')
display.debug('Escalation prompt repeated')
self._terminate_process(p)
self._flags['become_prompt'] = False
raise AnsibleError('Incorrect %s password' % self._play_context.become_method)
@ -501,7 +509,7 @@ class Connection(ConnectionBase):
# written to stderr between the time we called select() and when
# we learned that the process had finished.
if not p.stdout in rpipes:
if p.stdout not in rpipes:
timeout = 0
continue
@ -537,7 +545,7 @@ class Connection(ConnectionBase):
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
self._display.vvv("ESTABLISH SSH CONNECTION FOR USER: {0}".format(self._play_context.remote_user), host=self._play_context.remote_addr)
display.vvv("ESTABLISH SSH CONNECTION FOR USER: {0}".format(self._play_context.remote_user), host=self._play_context.remote_addr)
# we can only use tty when we are not pipelining the modules. piping
# data into /usr/bin/python inside a tty automatically invokes the
@ -593,7 +601,7 @@ class Connection(ConnectionBase):
else:
msg = "ssh_retry: attempt: %d, caught exception(%s) from cmd (%s), pausing for %d seconds" % (attempt, e, cmd_summary, pause)
self._display.vv(msg)
display.vv(msg)
time.sleep(pause)
continue
@ -605,7 +613,7 @@ class Connection(ConnectionBase):
super(Connection, self).put_file(in_path, out_path)
self._display.vvv("PUT {0} TO {1}".format(in_path, out_path), host=self.host)
display.vvv("PUT {0} TO {1}".format(in_path, out_path), host=self.host)
if not os.path.exists(in_path):
raise AnsibleFileNotFound("file or module does not exist: {0}".format(in_path))
@ -630,7 +638,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv("FETCH {0} TO {1}".format(in_path, out_path), host=self.host)
display.vvv("FETCH {0} TO {1}".format(in_path, out_path), host=self.host)
# scp and sftp require square brackets for IPv6 addresses, but
# accept them for hostnames and IPv4 addresses too.

@ -42,13 +42,19 @@ try:
except ImportError:
pass
from ansible import constants as C
from ansible.errors import AnsibleConnectionFailure, AnsibleFileNotFound
from ansible.errors import AnsibleFileNotFound
from ansible.plugins.connection import ConnectionBase
from ansible.plugins import shell_loader
from ansible.utils.path import makedirs_safe
from ansible.utils.unicode import to_bytes, to_unicode, to_str
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
class Connection(ConnectionBase):
'''WinRM connections over HTTP/HTTPS.'''
@ -111,7 +117,7 @@ class Connection(ConnectionBase):
'''
Establish a WinRM connection over HTTP/HTTPS.
'''
self._display.vvv("ESTABLISH WINRM CONNECTION FOR USER: %s on PORT %s TO %s" % \
display.vvv("ESTABLISH WINRM CONNECTION FOR USER: %s on PORT %s TO %s" %
(self._winrm_user, self._winrm_port, self._winrm_host), host=self._winrm_host)
netloc = '%s:%d' % (self._winrm_host, self._winrm_port)
endpoint = urlunsplit((self._winrm_scheme, netloc, self._winrm_path, '', ''))
@ -120,7 +126,7 @@ class Connection(ConnectionBase):
if transport == 'kerberos' and not HAVE_KERBEROS:
errors.append('kerberos: the python kerberos library is not installed')
continue
self._display.vvvvv('WINRM CONNECT: transport=%s endpoint=%s' % (transport, endpoint), host=self._winrm_host)
display.vvvvv('WINRM CONNECT: transport=%s endpoint=%s' % (transport, endpoint), host=self._winrm_host)
try:
protocol = Protocol(endpoint, transport=transport, **self._winrm_kwargs)
protocol.send_message('')
@ -137,7 +143,7 @@ class Connection(ConnectionBase):
elif code == 411:
return protocol
errors.append('%s: %s' % (transport, err_msg))
self._display.vvvvv('WINRM CONNECTION ERROR: %s\n%s' % (err_msg, traceback.format_exc()), host=self._winrm_host)
display.vvvvv('WINRM CONNECTION ERROR: %s\n%s' % (err_msg, traceback.format_exc()), host=self._winrm_host)
if errors:
raise AnsibleError(', '.join(errors))
else:
@ -145,9 +151,9 @@ class Connection(ConnectionBase):
def _winrm_exec(self, command, args=(), from_exec=False):
if from_exec:
self._display.vvvvv("WINRM EXEC %r %r" % (command, args), host=self._winrm_host)
display.vvvvv("WINRM EXEC %r %r" % (command, args), host=self._winrm_host)
else:
self._display.vvvvvv("WINRM EXEC %r %r" % (command, args), host=self._winrm_host)
display.vvvvvv("WINRM EXEC %r %r" % (command, args), host=self._winrm_host)
if not self.protocol:
self.protocol = self._winrm_connect()
if not self.shell_id:
@ -157,11 +163,11 @@ class Connection(ConnectionBase):
command_id = self.protocol.run_command(self.shell_id, to_bytes(command), map(to_bytes, args))
response = Response(self.protocol.get_command_output(self.shell_id, command_id))
if from_exec:
self._display.vvvvv('WINRM RESULT %r' % to_unicode(response), host=self._winrm_host)
display.vvvvv('WINRM RESULT %r' % to_unicode(response), host=self._winrm_host)
else:
self._display.vvvvvv('WINRM RESULT %r' % to_unicode(response), host=self._winrm_host)
self._display.vvvvvv('WINRM STDOUT %s' % to_unicode(response.std_out), host=self._winrm_host)
self._display.vvvvvv('WINRM STDERR %s' % to_unicode(response.std_err), host=self._winrm_host)
display.vvvvvv('WINRM RESULT %r' % to_unicode(response), host=self._winrm_host)
display.vvvvvv('WINRM STDOUT %s' % to_unicode(response.std_out), host=self._winrm_host)
display.vvvvvv('WINRM STDERR %s' % to_unicode(response.std_err), host=self._winrm_host)
return response
finally:
if command_id:
@ -192,12 +198,12 @@ class Connection(ConnectionBase):
if '-EncodedCommand' in cmd_parts:
encoded_cmd = cmd_parts[cmd_parts.index('-EncodedCommand') + 1]
decoded_cmd = to_unicode(base64.b64decode(encoded_cmd).decode('utf-16-le'))
self._display.vvv("EXEC %s" % decoded_cmd, host=self._winrm_host)
display.vvv("EXEC %s" % decoded_cmd, host=self._winrm_host)
else:
self._display.vvv("EXEC %s" % cmd, host=self._winrm_host)
display.vvv("EXEC %s" % cmd, host=self._winrm_host)
try:
result = self._winrm_exec(cmd_parts[0], cmd_parts[1:], from_exec=True)
except Exception as e:
except Exception:
traceback.print_exc()
raise AnsibleError("failed to exec cmd %s" % cmd)
result.std_out = to_bytes(result.std_out)
@ -207,7 +213,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
super(Connection, self).put_file(in_path, out_path)
out_path = self._shell._unquote(out_path)
self._display.vvv('PUT "%s" TO "%s"' % (in_path, out_path), host=self._winrm_host)
display.vvv('PUT "%s" TO "%s"' % (in_path, out_path), host=self._winrm_host)
if not os.path.exists(in_path):
raise AnsibleFileNotFound('file or module does not exist: "%s"' % in_path)
with open(in_path) as in_file:
@ -235,7 +241,7 @@ class Connection(ConnectionBase):
out_path = out_path + '.ps1'
b64_data = base64.b64encode(out_data)
script = script_template % (self._shell._escape(out_path), offset, b64_data, in_size)
self._display.vvvvv('WINRM PUT "%s" to "%s" (offset=%d size=%d)' % (in_path, out_path, offset, len(out_data)), host=self._winrm_host)
display.vvvvv('WINRM PUT "%s" to "%s" (offset=%d size=%d)' % (in_path, out_path, offset, len(out_data)), host=self._winrm_host)
cmd_parts = self._shell._encode_script(script, as_list=True)
result = self._winrm_exec(cmd_parts[0], cmd_parts[1:])
if result.status_code != 0:
@ -248,7 +254,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path)
in_path = self._shell._unquote(in_path)
out_path = out_path.replace('\\', '/')
self._display.vvv('FETCH "%s" TO "%s"' % (in_path, out_path), host=self._winrm_host)
display.vvv('FETCH "%s" TO "%s"' % (in_path, out_path), host=self._winrm_host)
buffer_size = 2**19 # 0.5MB chunks
makedirs_safe(os.path.dirname(out_path))
out_file = None
@ -277,7 +283,7 @@ class Connection(ConnectionBase):
Exit 1;
}
''' % dict(buffer_size=buffer_size, path=self._shell._escape(in_path), offset=offset)
self._display.vvvvv('WINRM FETCH "%s" to "%s" (offset=%d)' % (in_path, out_path, offset), host=self._winrm_host)
display.vvvvv('WINRM FETCH "%s" to "%s" (offset=%d)' % (in_path, out_path, offset), host=self._winrm_host)
cmd_parts = self._shell._encode_script(script, as_list=True)
result = self._winrm_exec(cmd_parts[0], cmd_parts[1:])
if result.status_code != 0:

@ -32,6 +32,12 @@ from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.plugins.connection import ConnectionBase
try:
from __main__ import display
display = display
except ImportError:
from ansible.utils.display import Display
display = Display()
BUFSIZE = 65536
@ -59,7 +65,7 @@ class Connection(ConnectionBase):
self.zoneadm_cmd = self._search_executable('zoneadm')
self.zlogin_cmd = self._search_executable('zlogin')
if not self.zone in self.list_zones():
if self.zone not in self.list_zones():
raise AnsibleError("incorrect zone name %s" % self.zone)
@staticmethod
@ -76,15 +82,15 @@ class Connection(ConnectionBase):
zones = []
for l in process.stdout.readlines():
# 1:work:running:/zones/work:3126dc59-9a07-4829-cde9-a816e4c5040e:native:shared
s = l.split(':')
if s[1] != 'global':
zones.append(s[1])
# 1:work:running:/zones/work:3126dc59-9a07-4829-cde9-a816e4c5040e:native:shared
s = l.split(':')
if s[1] != 'global':
zones.append(s[1])
return zones
def get_zone_path(self):
#solaris10vm# zoneadm -z cswbuild list -p
#solaris10vm# zoneadm -z cswbuild list -p
#-:cswbuild:installed:/zones/cswbuild:479f3c4b-d0c6-e97b-cd04-fd58f2c0238e:native:shared
process = subprocess.Popen([self.zoneadm_cmd, '-z', self.zone, 'list', '-p'],
stdin=subprocess.PIPE,
@ -98,7 +104,7 @@ class Connection(ConnectionBase):
''' connect to the zone; nothing to do here '''
super(Connection, self)._connect()
if not self._connected:
self._display.vvv("THIS IS A LOCAL ZONE DIR", host=self.zone)
display.vvv("THIS IS A LOCAL ZONE DIR", host=self.zone)
self._connected = True
def _buffered_exec_command(self, cmd, stdin=subprocess.PIPE):
@ -113,11 +119,11 @@ class Connection(ConnectionBase):
# -c. Not sure why as cmd could contain shell metachars (like
# cmd = "mkdir -p $HOME/pathname && echo $HOME/pathname") which
# probably wouldn't work without a shell. Get someone to test that
# this connection plugin works and then we can remove this note
# this connection plugin works and then we can remove this note
executable = C.DEFAULT_EXECUTABLE.split()[0] if C.DEFAULT_EXECUTABLE else '/bin/sh'
local_cmd = [self.zlogin_cmd, self.zone, executable, '-c', cmd]
self._display.vvv("EXEC %s" % (local_cmd), host=self.zone)
display.vvv("EXEC %s" % (local_cmd), host=self.zone)
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@ -156,7 +162,7 @@ class Connection(ConnectionBase):
def put_file(self, in_path, out_path):
''' transfer a file from local to zone '''
super(Connection, self).put_file(in_path, out_path)
self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.zone)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.zone)
out_path = pipes.quote(self._prefix_login_path(out_path))
try:
@ -178,7 +184,7 @@ class Connection(ConnectionBase):
def fetch_file(self, in_path, out_path):
''' fetch a file from zone to local '''
super(Connection, self).fetch_file(in_path, out_path)
self._display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.zone)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.zone)
in_path = pipes.quote(self._prefix_login_path(in_path))
try:

Loading…
Cancel
Save