Testing OpenStack upgrades
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

81 lines
2.6 KiB

"""Exported method Container.attach()."""
from __future__ import absolute_import
import collections
import fcntl
import logging
import struct
import sys
import termios
class Mixin:
"""Publish attach() for inclusion in Container class."""
def attach(self, eot=4, stdin=None, stdout=None):
"""Attach to container's PID1 stdin and stdout.
stderr is ignored.
PseudoTTY work is done in start().
"""
if stdin is None:
stdin = sys.stdin.fileno()
elif hasattr(stdin, 'fileno'):
stdin = stdin.fileno()
if stdout is None:
stdout = sys.stdout.fileno()
elif hasattr(stdout, 'fileno'):
stdout = stdout.fileno()
with self._client() as podman:
attach = podman.GetAttachSockets(self._id)
# This is the UDS where all the IO goes
io_socket = attach['sockets']['io_socket']
assert len(io_socket) <= 107,\
'Path length for sockets too long. {} > 107'.format(
len(io_socket)
)
# This is the control socket where resizing events are sent to conmon
# attach['sockets']['control_socket']
self.pseudo_tty = collections.namedtuple(
'PseudoTTY',
['stdin', 'stdout', 'io_socket', 'control_socket', 'eot'])(
stdin,
stdout,
attach['sockets']['io_socket'],
attach['sockets']['control_socket'],
eot,
)
@property
def resize_handler(self):
"""Send the new window size to conmon."""
def wrapped(signum, frame): # pylint: disable=unused-argument
packed = fcntl.ioctl(self.pseudo_tty.stdout, termios.TIOCGWINSZ,
struct.pack('HHHH', 0, 0, 0, 0))
rows, cols, _, _ = struct.unpack('HHHH', packed)
logging.debug('Resize window(%dx%d) using %s', rows, cols,
self.pseudo_tty.control_socket)
# TODO: Need some kind of timeout in case pipe is blocked
with open(self.pseudo_tty.control_socket, 'w') as skt:
# send conmon window resize message
skt.write('1 {} {}\n'.format(rows, cols))
return wrapped
@property
def log_handler(self):
"""Send command to reopen log to conmon."""
def wrapped(signum, frame): # pylint: disable=unused-argument
with open(self.pseudo_tty.control_socket, 'w') as skt:
# send conmon reopen log message
skt.write('2\n')
return wrapped