1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
"""Exported method Container.start()."""
import logging
import os
import select
import signal
import socket
import sys
import termios
import tty
CONMON_BUFSZ = 8192
class Mixin:
"""Publish start() for inclusion in Container class."""
def start(self):
"""Start container, return container on success.
Will block if container has been detached.
"""
with self._client() as podman:
results = podman.StartContainer(self.id)
logging.debug('Started Container "{}"'.format(
results['container']))
if not hasattr(self, 'pseudo_tty') or self.pseudo_tty is None:
return self._refresh(podman)
logging.debug('Setting up PseudoTTY for Container "{}"'.format(
results['container']))
try:
# save off the old settings for terminal
tcoldattr = termios.tcgetattr(self.pseudo_tty.stdin)
tty.setraw(self.pseudo_tty.stdin)
# initialize container's window size
self.resize_handler(None, sys._getframe(0))
# catch any resizing events and send the resize info
# to the control fifo "socket"
signal.signal(signal.SIGWINCH, self.resize_handler)
except termios.error:
tcoldattr = None
try:
# TODO: Is socket.SOCK_SEQPACKET supported in Windows?
with socket.socket(socket.AF_UNIX,
socket.SOCK_SEQPACKET) as skt:
# Prepare socket for use with conmon/container
skt.connect(self.pseudo_tty.io_socket)
sources = [skt, self.pseudo_tty.stdin]
while sources:
logging.debug('Waiting on sources: {}'.format(sources))
readable, _, _ = select.select(sources, [], [])
if skt in readable:
data = skt.recv(CONMON_BUFSZ)
if data:
# Remove source marker when writing
os.write(self.pseudo_tty.stdout, data[1:])
else:
sources.remove(skt)
if self.pseudo_tty.stdin in readable:
data = os.read(self.pseudo_tty.stdin, CONMON_BUFSZ)
if data:
skt.sendall(data)
if self.pseudo_tty.eot in data:
sources.clear()
else:
sources.remove(self.pseudo_tty.stdin)
finally:
if tcoldattr:
termios.tcsetattr(self.pseudo_tty.stdin, termios.TCSADRAIN,
tcoldattr)
signal.signal(signal.SIGWINCH, signal.SIG_DFL)
return self._refresh(podman)
|