Beispiel #1
0
    def onConnect(self):
        """
        Called when the worker has connected to the node's management router.
        """
        self._node_id = self.config.extra.node
        self._worker_id = self.config.extra.worker
        self._uri_prefix = u'crossbar.worker.{}'.format(self._worker_id)

        NativeProcess.onConnect(self, False)

        self._module_tracker = TrackingModuleReloader(snapshot=False)

        self._profiles = {}

        # flag indicating when worker is shutting down
        self._is_shutting_down = False

        # Jinja2 templates for Web (like WS status page et al)
        #
        template_dirs = []
        for package, directory in self.personality.TEMPLATE_DIRS:
            dir_path = os.path.abspath(
                pkg_resources.resource_filename(package, directory))
            template_dirs.append(dir_path)
        self.log.debug("Using Web templates from {template_dirs}",
                       template_dirs=template_dirs)
        self._templates = jinja2.Environment(
            loader=jinja2.FileSystemLoader(template_dirs), autoescape=True)

        self.join(self.config.realm)
Beispiel #2
0
    def __init__(self, node):
        # base ctor
        NativeProcess.__init__(self,
                               config=None,
                               reactor=node._reactor,
                               personality=node.personality)

        # associated node
        self._node = node
        self._realm = node._realm

        self.cbdir = self._node._cbdir

        self._uri_prefix = u'crossbar'

        self._started = None
        self._pid = os.getpid()

        # map of worker processes: worker_id -> NativeWorkerProcess
        self._workers = {}

        # shutdown of node is requested, and further requests to shutdown (or start)
        # are denied
        self._shutdown_requested = False

        # when shutting down, this flags marks if the shutdown is graceful and clean,
        # and expected (under the node configuration/settings) or if the shutdown is
        # under error or unnormal conditions. this flag controls the final exit
        # code returned by crossbar: 0 in case of "clean shutdown", and 1 otherwise
        self._shutdown_was_clean = None

        # node-wide system monitor running here in the node controller
        self._smonitor = SystemMonitor()
Beispiel #3
0
    def __init__(self, node):
        """

        :param node: The node singleton for this node controller session.
        :type node: obj
        """
        # base ctor
        NativeProcess.__init__(self, config=None, reactor=node._reactor, personality=node.personality)

        # associated node
        self._node = node
        self._realm = node._realm

        self.cbdir = self._node._cbdir

        self._uri_prefix = u'crossbar'

        self._started = None
        self._pid = os.getpid()

        # map of worker processes: worker_id -> NativeWorkerProcess
        self._workers = {}

        # shutdown of node is requested, and further requests to shutdown (or start)
        # are denied
        self._shutdown_requested = False

        # when shutting down, this flags marks if the shutdown is graceful and clean,
        # and expected (under the node configuration/settings) or if the shutdown is
        # under error or unnormal conditions. this flag controls the final exit
        # code returned by crossbar: 0 in case of "clean shutdown", and 1 otherwise
        self._shutdown_was_clean = None
Beispiel #4
0
    def onConnect(self):
        """
        Called when the worker has connected to the node's management router.
        """
        self._node_id = self.config.extra.node
        self._worker_id = self.config.extra.worker
        self._uri_prefix = u'crossbar.worker.{}'.format(self._worker_id)

        NativeProcess.onConnect(self, False)

        self._module_tracker = TrackingModuleReloader(snapshot=False)

        self._profiles = {}

        # flag indicating when worker is shutting down
        self._is_shutting_down = False

        # Jinja2 templates for Web (like WS status page et al)
        #
        template_dirs = []
        for package, directory in self.personality.TEMPLATE_DIRS:
            dir_path = os.path.abspath(pkg_resources.resource_filename(package, directory))
            template_dirs.append(dir_path)
        self.log.debug("Using Web templates from {template_dirs}",
                       template_dirs=template_dirs)
        self._templates = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dirs), autoescape=True)

        self.join(self.config.realm)
Beispiel #5
0
    def onConnect(self):

        self.log.debug("Connected to node management router")

        NativeProcess.onConnect(self, False)

        # self.join(self.config.realm)
        self.join(self._realm)
Beispiel #6
0
    def onConnect(self):

        self.log.debug("Connected to node management router")

        NativeProcess.onConnect(self, False)

        # self.join(self.config.realm)
        self.join(self._realm)
Beispiel #7
0
    def __init__(self, config=None, reactor=None, personality=None):
        # base ctor
        NativeProcess.__init__(self,
                               config=config,
                               reactor=reactor,
                               personality=personality)

        # Release (public) key
        self._release_pubkey = _read_release_key()
Beispiel #8
0
    def __init__(self, config=None, reactor=None, personality=None):
        # base ctor
        NativeProcess.__init__(self, config=config, reactor=reactor, personality=personality)

        # Release (public) key
        self._release_pubkey = _read_release_key()

        # Node (private) key (as a string, in hex)
        node_key_hex = _read_node_key(self.config.extra.cbdir, private=True)['hex']
        privkey = nacl.signing.SigningKey(node_key_hex, encoder=nacl.encoding.HexEncoder)

        # WAMP-cryptosign signing key
        self._node_key = cryptosign.SigningKey(privkey)
Beispiel #9
0
    def onJoin(self, details):

        from autobahn.wamp.types import SubscribeOptions

        self.log.debug("Joined realm '{realm}' on node management router", realm=details.realm)

        # When a (native) worker process has connected back to the router of
        # the node controller, the worker will publish this event
        # to signal it's readyness.
        #
        def on_worker_ready(res):
            worker_id = res['id']
            if worker_id in self._workers:
                ready = self._workers[worker_id].ready
                if not ready.called:
                    # fire the Deferred previously stored for
                    # signaling "worker ready"
                    ready.callback(worker_id)
                else:
                    self.log.error("Internal error: on_worker_ready() fired for process {process}, but already called earlier",
                                   process=worker_id)
            else:
                self.log.error("Internal error: on_worker_ready() fired for process {process}, but no process with that ID",
                               process=worker_id)

        self.subscribe(on_worker_ready, u'crossbar.worker..on_worker_ready', SubscribeOptions(match=u'wildcard'))

        yield NativeProcess.onJoin(self, details)
        # above upcall registers procedures we have marked with @wamp.register(None)

        # we need to catch SIGINT here to properly shutdown the
        # node explicitly (a Twisted system trigger wouldn't allow us to distinguish
        # different reasons/origins of exiting ..)
        def signal_handler(_signal, frame):
            if _signal == signal.SIGINT:
                # CTRL-C'ing Crossbar.io is considered "willful", and hence we want to exit cleanly
                self._shutdown_was_clean = True
            elif _signal == signal.SIGTERM:
                self._shutdown_was_clean = False
            else:
                # FIXME: can we run into others here?
                self._shutdown_was_clean = False

            self.log.warn('Controller received SIGINT [signal={signal}]: shutting down node [shutdown_was_clean={shutdown_was_clean}] ..', signal=_signal, shutdown_was_clean=self._shutdown_was_clean)

            # the following will shutdown the Twisted reactor in the end
            self.shutdown()

        signal.signal(signal.SIGINT, signal_handler)
        self.log.info('Signal handler installed on process {pid} thread {tid}', pid=os.getpid(), tid=threading.get_ident())

        self._started = utcnow()

        self.publish(u"crossbar.on_ready")

        self.log.debug("Node controller ready")
Beispiel #10
0
    def onJoin(self, details):

        from autobahn.wamp.types import SubscribeOptions

        self.log.debug("Joined realm '{realm}' on node management router", realm=details.realm)

        # When a (native) worker process has connected back to the router of
        # the node controller, the worker will publish this event
        # to signal it's readyness.
        #
        def on_worker_ready(res):
            worker_id = res['id']
            if worker_id in self._workers:
                ready = self._workers[worker_id].ready
                if not ready.called:
                    # fire the Deferred previously stored for
                    # signaling "worker ready"
                    ready.callback(worker_id)
                else:
                    self.log.error("Internal error: on_worker_ready() fired for process {process}, but already called earlier",
                                   process=worker_id)
            else:
                self.log.error("Internal error: on_worker_ready() fired for process {process}, but no process with that ID",
                               process=worker_id)

        self.subscribe(on_worker_ready, u'crossbar.worker..on_worker_ready', SubscribeOptions(match=u'wildcard'))

        yield NativeProcess.onJoin(self, details)
        # above upcall registers procedures we have marked with @wamp.register(None)

        # we need to catch SIGINT here to properly shutdown the
        # node explicitly (a Twisted system trigger wouldn't allow us to distinguish
        # different reasons/origins of exiting ..)
        def signal_handler(_signal, frame):
            if _signal == signal.SIGINT:
                # CTRL-C'ing Crossbar.io is considered "willful", and hence we want to exit cleanly
                self._shutdown_was_clean = True
            elif _signal == signal.SIGTERM:
                self._shutdown_was_clean = False
            else:
                # FIXME: can we run into others here?
                self._shutdown_was_clean = False

            self.log.warn('Controller received SIGINT [signal={signal}]: shutting down node [shutdown_was_clean={shutdown_was_clean}] ..', signal=_signal, shutdown_was_clean=self._shutdown_was_clean)

            # the following will shutdown the Twisted reactor in the end
            self.shutdown()

        signal.signal(signal.SIGINT, signal_handler)
        self.log.info('Signal handler installed on process {pid} thread {tid}', pid=os.getpid(), tid=threading.get_ident())

        self._started = utcnow()

        self.publish(u"crossbar.on_ready")

        self.log.debug("Node controller ready")
Beispiel #11
0
    def __init__(self, node):
        # call base ctor
        extra = namedtuple('Extra', ['node', 'worker'])(node._node_id,
                                                        'controller')
        config = ComponentConfig(realm=node._realm, extra=extra)
        NativeProcess.__init__(self,
                               config=config,
                               reactor=node._reactor,
                               personality=node.personality)

        # associated node
        self._node = node

        # node directory
        self.cbdir = self._node._cbdir

        # overwrite URI prefix for controller (normally: "crossbar.worker.<worker_id>")
        self._uri_prefix = 'crossbar'

        self._started = None
        self._pid = os.getpid()

        # map of worker processes: worker_id -> NativeWorkerProcess
        self._workers = {
            # add worker tracking instance to the worker map for the controller itself (!) ..
            # 'controller': self
        }

        # shutdown of node is requested, and further requests to shutdown (or start)
        # are denied
        self._shutdown_requested = False

        # when shutting down, this flags marks if the shutdown is graceful and clean,
        # and expected (under the node configuration/settings) or if the shutdown is
        # under error or unnormal conditions. this flag controls the final exit
        # code returned by crossbar: 0 in case of "clean shutdown", and 1 otherwise
        self._shutdown_was_clean = None

        # node-wide system monitor running here in the node controller
        self._smonitor = SystemMonitor()
Beispiel #12
0
    def onConnect(self):
        """
        Called when the worker has connected to the node's management router.
        """
        NativeProcess.onConnect(self, False)

        self._module_tracker = TrackingModuleReloader(snapshot=False)

        self._profiles = {}

        # flag indicating when worker is shutting down
        self._is_shutting_down = False

        # Jinja2 templates for Web (like WS status page et al)
        #
        self._templates_dir = []
        for package, directory in self.personality.TEMPLATE_DIRS:
            dir_path = os.path.abspath(
                pkg_resources.resource_filename(package, directory))
            self._templates_dir.append(dir_path)
        self.log.debug("Using Web templates from {template_dirs}",
                       template_dirs=self._templates_dir)

        # FIXME: make configurable, but default should remain SandboxedEnvironment for security
        if True:
            # The sandboxed environment. It works like the regular environment but tells the compiler to
            # generate sandboxed code.
            # https://jinja.palletsprojects.com/en/2.11.x/sandbox/#jinja2.sandbox.SandboxedEnvironment
            self._templates = SandboxedEnvironment(
                loader=jinja2.FileSystemLoader(self._templates_dir),
                autoescape=True)
        else:
            self._templates = Environment(loader=jinja2.FileSystemLoader(
                self._templates_dir),
                                          autoescape=True)

        self.join(self.config.realm)
Beispiel #13
0
    def onJoin(self, details, publish_ready=True):
        """
        Called when worker process has joined the node management realm.
        """
        yield NativeProcess.onJoin(self, details)
        # above upcall registers all our "@wamp.register(None)" methods

        # setup SIGTERM handler to orderly shutdown the worker
        def shutdown(sig, frame):
            self.log.warn("Native worker received SIGTERM - shutting down ..")
            self.shutdown()
        signal.signal(signal.SIGTERM, shutdown)

        # the worker is ready for work!
        if publish_ready:
            yield self.publish_ready()
Beispiel #14
0
    def onJoin(self, details, publish_ready=True):
        """
        Called when worker process has joined the node management realm.
        """
        yield NativeProcess.onJoin(self, details)
        # above upcall registers all our "@wamp.register(None)" methods

        # setup SIGTERM handler to orderly shutdown the worker
        def shutdown(sig, frame):
            self.log.warn("Native worker received SIGTERM - shutting down ..")
            self.shutdown()
        signal.signal(signal.SIGTERM, shutdown)

        # the worker is ready for work!
        if publish_ready:
            yield self.publish_ready()
Beispiel #15
0
 def __init__(self, config=None, reactor=None, personality=None):
     # base ctor
     NativeProcess.__init__(self,
                            config=config,
                            reactor=reactor,
                            personality=personality)
Beispiel #16
0
 def __init__(self, config=None, reactor=None, personality=None):
     # base ctor
     NativeProcess.__init__(self, config=config, reactor=reactor, personality=personality)