예제 #1
0
파일: driver.py 프로젝트: yarntime/calico
    def __init__(self, felix_sck):
        # Wrap the socket with our protocol reader/writer objects.
        self._msg_reader = MessageReader(felix_sck)
        self._msg_writer = MessageWriter(felix_sck)

        # Global stop event used to signal to all threads to stop.
        self._stop_event = Event()

        # Threads to own the connection from/to Felix.  The resync thread
        # is responsible for doing resyncs and merging updates from the
        # watcher thread (which it manages).
        self._reader_thread = Thread(target=self._read_from_socket,
                                     name="reader-thread")
        self._reader_thread.daemon = True
        self._resync_thread = Thread(target=self._resync_and_merge,
                                     name="resync-thread")
        self._resync_thread.daemon = True
        self._watcher_thread = None  # Created on demand
        self._watcher_stop_event = None
        self._watcher_start_index = None

        # High-water mark cache.  Owned by resync thread.
        self._hwms = HighWaterTracker()
        self._first_resync = True
        self._resync_http_pool = None
        self._cluster_id = None

        # Resync thread stats.
        self._snap_keys_processed = RateStat("snapshot keys processed")
        self._event_keys_processed = RateStat("event keys processed")
        self._felix_updates_sent = RateStat("felix updates sent")
        self._resync_stats = [
            self._snap_keys_processed,
            self._event_keys_processed,
            self._felix_updates_sent,
        ]
        self._last_resync_stat_log_time = monotonic_time()

        # Set by the reader thread once the init message has been received
        # from Felix.
        self._init_received = Event()
        # Initial config, received in the init message.
        self._etcd_base_url = None
        self._etcd_other_urls = []
        # Lock for the etcd url fields: this is the only lock, and no thread
        # ever recursively acquires it, so it cannot deadlock.  Must be locked
        # to access the _etcd_base_url and _etcd_other_urls fields (after they
        # are initialized).
        self._etcd_url_lock = Lock()
        self._hostname = None
        # Set by the reader thread once the logging config has been received
        # from Felix.  Triggers the first resync.
        self._config_received = Event()

        # Flag to request a resync.  Set by the reader thread, polled by the
        # resync and merge thread.
        self._resync_requested = False
예제 #2
0
파일: fetcd.py 프로젝트: yarntime/calico
    def _start_driver(self):
        """
        Starts the driver subprocess, connects to it over the socket
        and sends it the init message.

        Stores the Popen object in self._driver_process for future
        access.

        :return: the connected socket to the driver.
        """
        _log.info("Creating server socket.")
        try:
            os.unlink("/run/felix-driver.sck")
        except OSError:
            _log.debug("Failed to delete driver socket, assuming it "
                       "didn't exist.")
        update_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        update_socket.bind("/run/felix-driver.sck")
        update_socket.listen(1)
        self._driver_process = subprocess.Popen([
            sys.executable, "-m", "calico.etcddriver", "/run/felix-driver.sck"
        ])
        _log.info("Started etcd driver with PID %s", self._driver_process.pid)
        update_conn, _ = update_socket.accept()
        _log.info("Accepted connection on socket")
        # No longer need the server socket, remove it.
        try:
            os.unlink("/run/felix-driver.sck")
        except OSError:
            # Unexpected but carry on...
            _log.exception("Failed to unlink socket")
        else:
            _log.info("Unlinked server socket")

        # Wrap the socket in reader/writer objects that simplify using the
        # protocol.
        reader = MessageReader(update_conn)
        writer = MessageWriter(update_conn)
        # Give the driver its config.
        writer.send_message(
            MSG_TYPE_INIT, {
                MSG_KEY_ETCD_URLS: [
                    self._config.ETCD_SCHEME + "://" + addr
                    for addr in self._config.ETCD_ADDRS
                ],
                MSG_KEY_HOSTNAME:
                self._config.HOSTNAME,
                MSG_KEY_KEY_FILE:
                self._config.ETCD_KEY_FILE,
                MSG_KEY_CERT_FILE:
                self._config.ETCD_CERT_FILE,
                MSG_KEY_CA_FILE:
                self._config.ETCD_CA_FILE
            })
        return reader, writer
예제 #3
0
    def _start_driver(self):
        """
        Starts the driver subprocess, connects to it over the socket
        and sends it the init message.

        Stores the Popen object in self._driver_process for future
        access.

        :return: the connected socket to the driver.
        """
        _log.info("Creating server socket.")
        if os.path.exists("/run"):
            # Linux FHS version 3.0+ location for runtime sockets etc.
            sck_filename = "/run/felix-driver.sck"
        else:
            # Older Linux versions use /var/run.
            sck_filename = "/var/run/felix-driver.sck"
        try:
            os.unlink(sck_filename)
        except OSError:
            _log.debug("Failed to delete driver socket, assuming it "
                       "didn't exist.")
        update_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        update_socket.bind(sck_filename)
        update_socket.listen(1)
        if getattr(sys, "frozen", False):
            # We're running under pyinstaller, where we share our executable
            # with the etcd driver.  Re-run this executable with the "driver"
            # argument to invoke the etcd driver.
            cmd = [sys.argv[0], "driver"]
        else:
            # Not running under pyinstaller, execute the etcd driver directly.
            cmd = [sys.executable, "-m", "calico.etcddriver"]
        # etcd driver takes the felix socket name as argument.
        cmd += [sck_filename]
        _log.info("etcd-driver command line: %s", cmd)
        self._driver_process = subprocess.Popen(cmd)
        _log.info("Started etcd driver with PID %s", self._driver_process.pid)
        with gevent.Timeout(10):
            update_conn, _ = update_socket.accept()
        _log.info("Accepted connection on socket")
        # No longer need the server socket, remove it.
        try:
            os.unlink(sck_filename)
        except OSError:
            # Unexpected but carry on...
            _log.exception("Failed to unlink socket")
        else:
            _log.info("Unlinked server socket")

        # Wrap the socket in reader/writer objects that simplify using the
        # protocol.
        reader = MessageReader(update_conn)
        writer = MessageWriter(update_conn)
        # Give the driver its config.
        writer.send_message(
            MSG_TYPE_INIT, {
                MSG_KEY_ETCD_URLS: [
                    self._config.ETCD_SCHEME + "://" + addr
                    for addr in self._config.ETCD_ADDRS
                ],
                MSG_KEY_HOSTNAME:
                self._config.HOSTNAME,
                MSG_KEY_KEY_FILE:
                self._config.ETCD_KEY_FILE,
                MSG_KEY_CERT_FILE:
                self._config.ETCD_CERT_FILE,
                MSG_KEY_CA_FILE:
                self._config.ETCD_CA_FILE,
            })
        return reader, writer
예제 #4
0
 def setUp(self):
     self.sck = StubWriterSocket()
     self.writer = MessageWriter(self.sck)
     self.unpacker = msgpack.Unpacker()