summaryrefslogtreecommitdiff
path: root/contrib/python/podman/libs/_containers_start.py
blob: ad9f32eab19cd827f2e2897a0b901deeed6ed5b7 (plain)
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)