def start()

in ccmlib/node.py [0:0]


    def start(self,
              join_ring=True,
              no_wait=False,
              verbose=False,
              update_pid=True,
              wait_other_notice=True,
              replace_token=None,
              replace_address=None,
              jvm_args=None,
              wait_for_binary_proto=False,
              profile_options=None,
              use_jna=False,
              quiet_start=False,
              allow_root=False,
              set_migration_task=True,
              jvm_version=None):
        """
        Start the node. Options includes:
          - join_ring: if false, start the node with -Dcassandra.join_ring=False
          - no_wait: by default, this method returns when the node is started and listening to clients.
            If no_wait=True, the method returns sooner.
          - wait_other_notice: if truthy, this method returns only when all other live node of the cluster
            have marked this node UP. if an integer, sets the timeout for how long to wait
          - replace_token: start the node with the -Dcassandra.replace_token option.
          - replace_address: start the node with the -Dcassandra.replace_address option.
        """
        if jvm_args is None:
            jvm_args = []

        if set_migration_task and self.cluster.cassandra_version() >= '3.0.1':
            jvm_args += ['-Dcassandra.migration_task_wait_in_seconds={}'.format(len(self.cluster.nodes) * 2)]

        # Validate Windows env
        if common.is_modern_windows_install(self.cluster.version()) and not common.is_ps_unrestricted():
            raise NodeError("PS Execution Policy must be unrestricted when running C* 2.1+")

        if not common.is_win() and quiet_start:
            common.warning("Tried to set Windows quiet start behavior, but we're not running on Windows.")

        if self.is_running():
            raise NodeError("{} is already running".format(self.name))

        for itf in list(self.network_interfaces.values()):
            if itf is not None and replace_address is None:
                common.assert_socket_available(itf)

        if wait_other_notice:
            marks = [(node, node.mark_log()) for node in list(self.cluster.nodes.values()) if node.is_live()]
        else:
            marks = []

        self.mark = self.mark_log()

        launch_bin = self.get_launch_bin()

        # If Windows, change entries in .bat file to split conf from binaries
        if common.is_win():
            self.__clean_bat()

        if profile_options is not None:
            config = common.get_config()
            if 'yourkit_agent' not in config:
                raise NodeError("Cannot enable profile. You need to set 'yourkit_agent' to the path of your agent in a ~/.ccm/config")
            cmd = '-agentpath:{}'.format(config['yourkit_agent'])
            if 'options' in profile_options:
                cmd = cmd + '=' + profile_options['options']
            print_(cmd)
            # Yes, it's fragile as shit
            pattern = r'cassandra_parms="-Dlog4j.configuration=log4j-server.properties -Dlog4j.defaultInitOverride=true'
            common.replace_in_file(launch_bin, pattern, '    ' + pattern + ' ' + cmd + '"')

        os.chmod(launch_bin, os.stat(launch_bin).st_mode | stat.S_IEXEC)

        env = self.get_env()

        extension.append_to_server_env(self, env)

        if common.is_win():
            self._clean_win_jmx()

        pidfile = os.path.join(self.get_path(), 'cassandra.pid')
        args = [launch_bin]

        self.add_custom_launch_arguments(args)

        args = args + ['-p', pidfile, '-Dcassandra.join_ring=%s' % str(join_ring)]

        args.append('-Dcassandra.logdir=%s' % os.path.join(self.get_path(), 'logs'))
        if replace_token is not None:
            args.append('-Dcassandra.replace_token=%s' % str(replace_token))
        if replace_address is not None:
            args.append('-Dcassandra.replace_address=%s' % str(replace_address))
        if use_jna is False:
            args.append('-Dcassandra.boot_without_jna=true')
        if allow_root:
            args.append('-R')
        env['JVM_EXTRA_OPTS'] = env.get('JVM_EXTRA_OPTS', "") + " " + " ".join(jvm_args)

        # Upgrade scenarios may want to test upgrades to a specific Java version. In case a prior C* version
        # requires a lower Java version, we would keep its JAVA_HOME in self.__environment_variables and therefore
        # prevent using the "intended" Java version for the C* version to upgrade to.
        if not self.__original_java_home:
            # Save the "original" JAVA_HOME + PATH to restore it.
            self.__original_java_home = os.environ['JAVA_HOME']
            self.__original_path = os.environ['PATH']
            logger.info("Saving original JAVA_HOME={} PATH={}".format(self.__original_java_home, self.__original_path))
        else:
            # Restore the "original" JAVA_HOME + PATH to restore it.
            env['JAVA_HOME'] = self.__original_java_home
            env['PATH'] = self.__original_path
            logger.info("Restoring original JAVA_HOME={} PATH={}".format(self.__original_java_home, self.__original_path))

        env = common.update_java_version(jvm_version=jvm_version,
                                         install_dir=self.get_install_dir(),
                                         cassandra_version=self.get_cassandra_version(),
                                         env=env,
                                         info_message=self.name)
        # Need to update the node's environment for nodetool and other tools.
        # (e.g. the host's JAVA_HOME points to Java 11, but the node's software is only for Java 8)
        for k in 'JAVA_HOME', 'PATH':
            self.__environment_variables[k] = env[k]

        common.info("Starting {} with JAVA_HOME={} java_version={} cassandra_version={}, install_dir={}"
                    .format(self.name, env['JAVA_HOME'], common.get_jdk_version_int(env=env),
                            self.get_cassandra_version(), self.get_install_dir()))

        # In case we are restarting a node
        # we risk reading the old cassandra.pid file
        self._delete_old_pid()

        # Always write the stdout+stderr of the launched process to log files to make finding startup issues easier.
        start_time = time.time()
        stdout_sink = open(os.path.join(self.log_directory(), 'startup-{}-stdout.log'.format(start_time)), "w+")
        stderr_sink = open(os.path.join(self.log_directory(), 'startup-{}-stderr.log'.format(start_time)), "w+")

        if common.is_win():
            # clean up any old dirty_pid files from prior runs
            dirty_pid_path = os.path.join(self.get_path() + "dirty_pid.tmp")
            if (os.path.isfile(dirty_pid_path)):
                os.remove(dirty_pid_path)

            if quiet_start and self.cluster.version() >= '2.2.4':
                args.append('-q')

            process = subprocess.Popen(args, cwd=self.get_bin_dir(), env=env, stdout=stdout_sink, stderr=stderr_sink)
        else:
            process = subprocess.Popen(args, env=env, stdout=stdout_sink, stderr=stderr_sink)

        process.stderr_file = stderr_sink

        if verbose:
            common.debug("verbose mode: waiting for the start process out/err (and termination)")
            stdout, stderr = process.communicate()
            print_(str(stdout))
            print_(str(stderr))

        # Our modified batch file writes a dirty output with more than just the pid - clean it to get in parity
        # with *nix operation here.
        if common.is_win():
            self.__clean_win_pid()
            self._update_pid(process)
            print_("Started: {0} with pid: {1}".format(self.name, self.pid), file=sys.stderr, flush=True)

        if update_pid or wait_for_binary_proto:
            # at this moment we should have PID and it should be running...
            if not self._wait_for_running(process, timeout_s=7):
                raise NodeError("Node {n} is not running".format(n=self.name), process)

        # if requested wait for other nodes to observe this one (via gossip)
        if common.is_int_not_bool(wait_other_notice):
            for node, mark in marks:
                node.watch_log_for_alive(self, from_mark=mark, timeout=wait_other_notice)
        elif wait_other_notice:
            for node, mark in marks:
                node.watch_log_for_alive(self, from_mark=mark)

        # if requested wait for binary protocol to start
        if common.is_int_not_bool(wait_for_binary_proto):
            self.wait_for_binary_interface(from_mark=self.mark, timeout=wait_for_binary_proto)
        elif wait_for_binary_proto:
            self.wait_for_binary_interface(from_mark=self.mark)

        return process