From 23f9f0c5b90416cd3f7f260c5215d90d6c512ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Botond=20D=C3=A9nes?= Date: Thu, 21 Mar 2024 10:53:56 -0400 Subject: [PATCH] ccmlib/scylla_node.py: remove JMX related code JMX is no longer needed, remove it completely, so it can be dropped from Scylla packages as well. --- ccmlib/scylla_node.py | 153 +----------------------------------------- 1 file changed, 2 insertions(+), 151 deletions(-) diff --git a/ccmlib/scylla_node.py b/ccmlib/scylla_node.py index 6aabc7c7..8025beb9 100644 --- a/ccmlib/scylla_node.py +++ b/ccmlib/scylla_node.py @@ -54,8 +54,6 @@ def __init__(self, name, cluster, auto_bootstrap, thrift_interface, self.__global_log_level = 'info' self.__classes_log_level = {} self.get_cassandra_version() - self._process_jmx = None - self._process_jmx_waiter = None self._process_scylla = None self._process_scylla_waiter = None self._process_agent = None @@ -67,7 +65,6 @@ def __init__(self, name, cluster, auto_bootstrap, thrift_interface, self._memory = None self.__conf_updated = False self.scylla_manager = scylla_manager - self.jmx_pid = None self.agent_pid = None self.upgraded = False self.upgrader = NodeUpgrader(node=self) @@ -191,10 +188,6 @@ def cpuset(self, id, count, cluster_id): def memory(self): return self._memory - def _wait_for_jmx(self): - if self._process_jmx: - self._process_jmx.wait() - def _wait_for_scylla(self): if self._process_scylla: self._process_scylla.wait() @@ -203,47 +196,6 @@ def _wait_for_agent(self): if self._process_agent: self._process_agent.wait() - def _start_jmx(self, data): - jmx_jar_dir = os.path.join(self.get_path(), BIN_DIR) - jmx_java_bin = os.path.join(jmx_jar_dir, 'symlinks', 'scylla-jmx') - jmx_jar = os.path.join(jmx_jar_dir, 'scylla-jmx-1.0.jar') - args = [jmx_java_bin, - f"-Dapiaddress={data['listen_address']}", - '-Djavax.management.builder.initial=com.scylladb.jmx.utils.APIBuilder', - f"-Djava.rmi.server.hostname={data['listen_address']}", - '-Dcom.sun.management.jmxremote', - f"-Dcom.sun.management.jmxremote.host={data['listen_address']}", - f'-Dcom.sun.management.jmxremote.port={self.jmx_port}', - f'-Dcom.sun.management.jmxremote.rmi.port={self.jmx_port}', - '-Dcom.sun.management.jmxremote.local.only=false', - '-Xmx256m', - '-XX:+UseSerialGC', - '-Dcom.sun.management.jmxremote.authenticate=false', - '-Dcom.sun.management.jmxremote.ssl=false', - '-jar', - jmx_jar] - log_file = os.path.join(self.get_path(), 'logs', 'system.log.jmx') - env = self._get_environ(SCYLLA_HOME=self.get_path()) - - message = f"Starting scylla-jmx: args={args}" - self.debug(message) - with open(log_file, 'a') as jmx_log: - jmx_log.write(f"{message}\n") - self._process_jmx = subprocess.Popen(args, stdout=jmx_log, stderr=jmx_log, close_fds=True, env=env) - self._process_jmx.poll() - # When running on ccm standalone, the waiter thread would block - # the create commands. Besides in that mode, waiting is unnecessary, - # since the original popen reference is garbage collected. - standalone = os.environ.get('SCYLLA_CCM_STANDALONE', None) - if standalone is None: - self._process_jmx_waiter = threading.Thread(target=self._wait_for_jmx) - # Don't block the main thread on abnormal shutdown - self._process_jmx_waiter.daemon = True - self._process_jmx_waiter.start() - pid_filename = os.path.join(self.get_path(), 'scylla-jmx.pid') - with open(pid_filename, 'w') as pid_file: - pid_file.write(str(self._process_jmx.pid)) - # Wait for a starting node until is starts listening for CQL. # Possibly poll the log for long-running offline processes, like # bootstrap or resharding. @@ -429,18 +381,6 @@ def stop_scylla_manager_agent(self, gently): except OSError: pass - def _wait_java_up(self, ip_addr, jmx_port): - def is_java_up(): - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as _socket: - _socket.settimeout(1.0) - try: - _socket.connect((ip_addr, jmx_port)) - return True - except (socket.timeout, ConnectionRefusedError): - return False - - return wait_for(func=is_java_up, timeout=30, step=0.05) - def node_install_dir_version(self): if not self.node_install_dir: return None @@ -688,14 +628,6 @@ def process_opts(opts): wait_normal_token_owner=wait_normal_token_owner, wait_for_binary_proto=wait_for_binary_proto, ext_env=ext_env) - self._start_jmx(data) - - ip_addr, _ = self.network_interfaces['storage'] - jmx_port = int(self.jmx_port) - if not self._wait_java_up(ip_addr, jmx_port): - e_msg = "Error starting node {}: unable to connect to scylla-jmx port {}:{}".format( - self.name, ip_addr, jmx_port) - raise NodeError(e_msg, scylla_process) self._update_pid(scylla_process) wait_for(func=lambda: self.is_running(), timeout=10, step=0.01) @@ -733,33 +665,6 @@ def start_dse(self, jvm_args = [] raise NotImplementedError('ScyllaNode.start_dse') - def _update_jmx_pid(self, wait=True): - pidfile = os.path.join(self.get_path(), 'scylla-jmx.pid') - - start = time.time() - while not (os.path.isfile(pidfile) and os.stat(pidfile).st_size > 0): - elapsed = time.time() - start - if elapsed > 30.0 or not wait: - if wait: - print("Timed out waiting for pidfile {} to be filled (after {} seconds): File {} size={}".format( - pidfile, - elapsed, - 'exists' if os.path.isfile(pidfile) else 'does not exist' if not os.path.exists(pidfile) else 'is not a file', - os.stat(pidfile).st_size if os.path.exists(pidfile) else -1)) - break - else: - time.sleep(0.1) - - if os.path.isfile(pidfile) and os.stat(pidfile).st_size > 0: - try: - with open(pidfile, 'r') as f: - self.jmx_pid = int(f.readline().strip()) - except IOError as e: - raise NodeError('Problem starting node %s scylla-jmx due to %s' % - (self.name, e)) - else: - self.jmx_pid = None - def nodetool(self, cmd, capture_output=True, wait=True, timeout=None, verbose=True): if self.is_docker(): host = 'localhost' @@ -770,11 +675,6 @@ def nodetool(self, cmd, capture_output=True, wait=True, timeout=None, verbose=Tr nodetool.extend(cmd.split()) return self._do_run_nodetool(nodetool, capture_output, wait, timeout, verbose) - - def kill_jmx(self, __signal): - if self.jmx_pid: - os.kill(self.jmx_pid, __signal) - def _update_scylla_agent_pid(self): pidfile = os.path.join(self.get_path(), 'scylla-agent.pid') @@ -805,10 +705,9 @@ def do_stop(self, gently=True): """ did_stop = False - self._update_jmx_pid(wait=False) if self.scylla_manager and self.scylla_manager.is_agent_available: self._update_scylla_agent_pid() - for proc in [self._process_jmx, self._process_scylla, self._process_agent]: + for proc in [self._process_scylla, self._process_agent]: if proc: did_stop = True if gently: @@ -823,7 +722,7 @@ def do_stop(self, gently=True): pass else: signal_mapping = {True: signal.SIGTERM, False: signal.SIGKILL} - for pid in [self.jmx_pid, self.pid, self.agent_pid]: + for pid in [self.pid, self.agent_pid]: if pid: did_stop = True try: @@ -866,22 +765,6 @@ def wait_until_stopped(self, wait_seconds=None, marks=None, dump_core=True): os.kill(self.pid, signal.SIGKILL) self._wait_until_stopped(10) - while self.jmx_pid and time.time() - start < wait_seconds: - try: - os.kill(self.jmx_pid, 0) - time.sleep(1) - except OSError: - self.jmx_pid = None - pass - - if self.jmx_pid: - try: - self.warning("{} scylla-jmx is still running. Killing process using kill({}, SIGKILL)...".format( - self.name, wait_seconds, self.jmx_pid)) - os.kill(self.jmx_pid, signal.SIGKILL) - except OSError: - pass - if self.is_running(): raise NodeError(f"Problem stopping node {self.name}") @@ -941,9 +824,6 @@ def copy_config_files(self): def get_tools_java_dir(self): return common.get_tools_java_dir(self.node_install_dir, self._relative_repos_root or '..') - def get_jmx_dir(self): - return common.get_jmx_dir(self.node_install_dir, self._relative_repos_root or '..') - def get_cqlsh_dir(self): return os.path.join(self.node_install_dir, 'tools', 'cqlsh') @@ -1057,35 +937,6 @@ def run_patchelf(patchelf_cmd): if returncode != 0: raise RuntimeError(f'{patchelf_cmd} exited with status {returncode}.\nstdout:{stdout}\nstderr:\n{stderr}') - if 'scylla-repository' in self.node_install_dir: - self.hard_link_or_copy(os.path.join(self.get_jmx_dir(), 'scylla-jmx-1.0.jar'), - os.path.join(self.get_bin_dir(), 'scylla-jmx-1.0.jar'), replace=replace) - self.hard_link_or_copy(os.path.join(self.get_jmx_dir(), 'scylla-jmx'), - os.path.join(self.get_bin_dir(), 'scylla-jmx'), replace=replace) - select_java = Path(self.get_jmx_dir()) / 'select-java' - else: - self.hard_link_or_copy(os.path.join(self.get_jmx_dir(), 'target', 'scylla-jmx-1.0.jar'), - os.path.join(self.get_bin_dir(), 'scylla-jmx-1.0.jar'), replace=replace) - self.hard_link_or_copy(os.path.join(self.get_jmx_dir(), 'scripts', 'scylla-jmx'), - os.path.join(self.get_bin_dir(), 'scylla-jmx'), replace=replace) - select_java = Path(self.get_jmx_dir()) / 'scripts' / 'select-java' - - os.makedirs(os.path.join(self.get_bin_dir(), 'symlinks'), exist_ok=exist_ok) - scylla_jmx_file = os.path.join(self.get_bin_dir(), 'symlinks', 'scylla-jmx') - if os.path.exists(scylla_jmx_file) and replace: - os.remove(scylla_jmx_file) - if java_home := os.environ.get('JAVA_HOME'): - # user selecting specific Java - java_exe = Path(java_home) / 'bin' / 'java' - os.symlink(java_exe, scylla_jmx_file) - elif select_java.exists(): - # JMX lookup logic - os.symlink(select_java, scylla_jmx_file) - else: - # older scylla versions, just use default java - java_exe = Path('/usr') / 'bin' / 'java' - os.symlink(java_exe, scylla_jmx_file) - parent_dir = os.path.dirname(os.path.realpath(__file__)) resources_bin_dir = os.path.join(parent_dir, 'resources', BIN_DIR) for name in os.listdir(resources_bin_dir):