def __init__(self, fullpath, vendor_flag=False): cn.is_exist_path(fullpath) self.fullpath = fullpath self.vendor_flag = vendor_flag self.basepath, self.dirpath = os.path.split(fullpath) if cn.is_win(): self.statfile_info = cn.get_statfile(self.fullpath) # 生成文件(FL_File对象)的列表 self.filelist = [] # 生成目录(FL_Dir对象)的列表 self.dirlist = [] for root, dirs, files in os.walk(self.fullpath, topdown=True): for f in files: if f in self.skip_list: continue fpath = os.path.join(root, f) new_f = FL_File(fpath, self.fullpath, self.vendor_flag) if cn.is_win(): new_f.set_info(self.statfile_info[new_f.rela_path]) self.filelist.append(new_f) sys.stderr.write("Found file %-99s\r" % f) for d in dirs: dpath = os.path.join(root, d) new_d = FL_Dir(dpath, self.fullpath, self.vendor_flag) if cn.is_win(): new_d.set_info(self.statfile_info[new_d.rela_path]) self.dirlist.append(new_d) cn.clean_line() # 生成文件相对路径的列表 self.file_pathlist = [f.spath for f in self.filelist] # 生成目录相对路径的列表 self.dir_pathlist = [f.spath for f in self.dirlist] # 为文件和目录对象设置selabel属性 if not self.set_selabels(self.basepath): if cn.is_win(): bootimg_ramdisk_path = cn.extract_bootimg( os.path.join(self.basepath, "boot.img")) if not self.set_selabels(bootimg_ramdisk_path): raise Exception( "Could not find (plat_)file_contexts(.bin)!" " So we can not get selabel of files!") else: if os.system("ls -Z") == 0: for f in (self.filelist + self.dirlist): f.selabel = cn.get_selabel_linux(f.path) else: raise Exception("Can not get selabel with " "\"ls -Z\" command!")
def watch_log_for(self, exprs, from_mark=None, timeout=600, process=None, verbose=False): """ Watch the log until one or more (regular) expression are found. This methods when all the expressions have been found or the method timeouts (a TimeoutError is then raised). On successful completion, a list of pair (line matched, match object) is returned. """ elapsed = 0 tofind = [exprs] if isinstance(exprs, basestring) else exprs tofind = [ re.compile(e) for e in tofind ] matchings = [] reads = "" if len(tofind) == 0: return None while not os.path.exists(self.logfilename()): time.sleep(.5) if process: process.poll() if process.returncode is not None: self.print_process_output(self.name, process, verbose) if process.returncode != 0: raise RuntimeError() # Shouldn't reuse RuntimeError but I'm lazy with open(self.logfilename()) as f: if from_mark: f.seek(from_mark) while True: # First, if we have a process to check, then check it. # Skip on Windows - stdout/stderr is cassandra.bat if not common.is_win(): if process: process.poll() if process.returncode is not None: self.print_process_output(self.name, process, verbose) if process.returncode != 0: raise RuntimeError() # Shouldn't reuse RuntimeError but I'm lazy line = f.readline() if line: reads = reads + line for e in tofind: m = e.search(line) if m: matchings.append((line, m)) tofind.remove(e) if len(tofind) == 0: return matchings[0] if isinstance(exprs, basestring) else matchings else: # yep, it's ugly time.sleep(1) elapsed = elapsed + 1 if elapsed > timeout: raise TimeoutError(time.strftime("%d %b %Y %H:%M:%S", time.gmtime()) + " [" + self.name + "] Missing: " + str([e.pattern for e in tofind]) + ":\n" + reads) if process: process.poll() if process.returncode is not None and process.returncode == 0: return None
def check_win_requirements(): if common.is_win(): # Make sure ant.bat is in the path and executable before continuing try: process = subprocess.Popen('ant.bat', stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except Exception as e: sys.exit("ERROR! Could not find or execute ant.bat. Please fix this before attempting to run ccm on Windows.")
def __update_status(self): if self.pid is None: if self.status == Status.UP or self.status == Status.DECOMMISIONNED: self.status = Status.DOWN return old_status = self.status # os.kill on windows doesn't allow us to ping a process if common.is_win(): self.__update_status_win() else: try: os.kill(self.pid, 0) except OSError as err: if err.errno == errno.ESRCH: # not running if self.status == Status.UP or self.status == Status.DECOMMISIONNED: self.status = Status.DOWN elif err.errno == errno.EPERM: # no permission to signal this process if self.status == Status.UP or self.status == Status.DECOMMISIONNED: self.status = Status.DOWN else: # some other error raise err else: if self.status == Status.DOWN or self.status == Status.UNINITIALIZED: self.status = Status.UP if not old_status == self.status: if old_status == Status.UP and self.status == Status.DOWN: self.pid = None self.__update_config()
def __update_log4j(self): append_pattern = 'log4j.appender.R.File=' conf_file = os.path.join(self.get_conf_dir(), common.LOG4J_CONF) log_file = os.path.join(self.get_path(), 'logs', 'system.log') # log4j isn't partial to Windows \. I can't imagine why not. if common.is_win(): log_file = re.sub("\\\\", "/", log_file) common.replace_in_file(conf_file, append_pattern, append_pattern + log_file) # Setting the right log level # Replace the global log level if self.__global_log_level is not None: append_pattern = 'log4j.rootLogger=' common.replace_in_file( conf_file, append_pattern, append_pattern + self.__global_log_level + ',stdout,R') # Class specific log levels for class_name in self.__classes_log_level: logger_pattern = 'log4j.logger' full_logger_pattern = logger_pattern + '.' + class_name + '=' common.replace_or_add_into_file_tail( conf_file, full_logger_pattern, full_logger_pattern + self.__classes_log_level[class_name])
def watch_log_for(self, exprs, from_mark=None, timeout=600, process=None, verbose=False): """ Watch the log until one or more (regular) expression are found. This methods when all the expressions have been found or the method timeouts (a TimeoutError is then raised). On successful completion, a list of pair (line matched, match object) is returned. """ elapsed = 0 tofind = [exprs] if isinstance(exprs, string_types[0]) else exprs tofind = [ re.compile(e) for e in tofind ] matchings = [] reads = "" if len(tofind) == 0: return None while not os.path.exists(self.logfilename()): time.sleep(.5) if process: process.poll() if process.returncode is not None: self.print_process_output(self.name, process, verbose) if process.returncode != 0: raise RuntimeError() # Shouldn't reuse RuntimeError but I'm lazy with open(self.logfilename()) as f: if from_mark: f.seek(from_mark) while True: # First, if we have a process to check, then check it. # Skip on Windows - stdout/stderr is cassandra.bat if not common.is_win(): if process: process.poll() if process.returncode is not None: self.print_process_output(self.name, process, verbose) if process.returncode != 0: raise RuntimeError() # Shouldn't reuse RuntimeError but I'm lazy line = f.readline() if line: reads = reads + line for e in tofind: m = e.search(line) if m: matchings.append((line, m)) tofind.remove(e) if len(tofind) == 0: return matchings[0] if isinstance(exprs, string_types[0]) else matchings else: # yep, it's ugly time.sleep(1) elapsed = elapsed + 1 if elapsed > timeout: raise TimeoutError(time.strftime("%d %b %Y %H:%M:%S", time.gmtime()) + " [" + self.name + "] Missing: " + str([e.pattern for e in tofind]) + ":\n" + reads) if process: process.poll() if process.returncode is not None and process.returncode == 0: return None
def __init__(self, path, name, partitioner=None, cassandra_dir=None, create_directory=True, cassandra_version=None, verbose=False): self.name = name self.nodes = {} self.seeds = [] self.partitioner = partitioner self._config_options = {} self.__log_level = "INFO" self.__path = path self.__version = None if create_directory: # we create the dir before potentially downloading to throw an error sooner if need be os.mkdir(self.get_path()) try: if cassandra_version is None: # at this point, cassandra_dir should always not be None, but # we keep this for backward compatibility (in loading old cluster) if cassandra_dir is not None: if common.is_win(): self.__cassandra_dir = cassandra_dir else: self.__cassandra_dir = os.path.abspath(cassandra_dir) self.__version = self.__get_version_from_build() else: dir, v = repository.setup(cassandra_version, verbose) self.__cassandra_dir = dir self.__version = v if v is not None else self.__get_version_from_build() if create_directory: common.validate_cassandra_dir(self.__cassandra_dir) self.__update_config() except: if create_directory: shutil.rmtree(self.get_path()) raise
def __update_status(self): if self.pid is None: if self.status == Status.UP or self.status == Status.DECOMMISIONNED: self.status = Status.DOWN return old_status = self.status # os.kill on windows doesn't allow us to ping a process if common.is_win(): self.__update_status_win() else: try: os.kill(self.pid, 0) except OSError, err: if err.errno == errno.ESRCH: # not running if self.status == Status.UP or self.status == Status.DECOMMISIONNED: self.status = Status.DOWN elif err.errno == errno.EPERM: # no permission to signal this process if self.status == Status.UP or self.status == Status.DECOMMISIONNED: self.status = Status.DOWN else: # some other error raise err else:
def unpack_img(self, img_path, is_new, is_vendor=False): oon, sov = self.pars_init(is_new, is_vendor) print("\nUnpacking %s Rom's %s.img..." % (oon, sov)) if cn.is_win(): spath = cn.extract_img(img_path) cn.remove_path(img_path) else: spath = cn.mount_img(img_path) return spath
def clean_temp(): print("\nCleaning temp files...") for d in os.listdir(tempfile.gettempdir()): if d.startswith("GOTAPGS_"): if not cn.is_win(): for mdir in ("system_", "vendor_"): os.system("sudo umount %s > /dev/null" % os.path.join(tempfile.gettempdir(), d, mdir)) cn.remove_path(os.path.join(tempfile.gettempdir(), d))
def check_win_requirements(): if common.is_win(): # Make sure ant.bat is in the path and executable before continuing try: process = subprocess.Popen('ant.bat', stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except Exception as e: sys.exit( "ERROR! Could not find or execute ant.bat. Please fix this before attempting to run ccm on Windows." )
def clean_temp(): print("\nCleaning temp files...") for d in os.listdir(tempfile.gettempdir()): if d.startswith("GOTAPGS_"): if not cn.is_win(): for mdir in ("system_", "vendor_"): mount_path = os.path.join(tempfile.gettempdir(), d, mdir) os.system( "mountpoint -q {0} && sudo umount {0}".format( mount_path)) cn.remove_path(os.path.join(tempfile.gettempdir(), d))
def __init__(self, path, root_path): self.uid = self.gid = self.perm = self.slink = self.sha1 = self.old_sha1 = self.selabel = "" # 文件绝对路径 self.path = path # 文件相对于"/"的路径 if root_path in self.path: self.rela_path = self.path.replace(root_path, "", 1).replace("\\", "/") else: self.rela_path = "" self.filename = os.path.split(path)[1] if not common.is_win(): self.set_info(self.get_stat(self.path))
def stop(self, wait=True, wait_other_notice=False, gently=True): """ Stop the node. - wait: if True (the default), wait for the Cassandra process to be really dead. Otherwise return after having sent the kill signal. - wait_other_notice: return only when the other live nodes of the cluster have marked this node has dead. - gently: Let Cassandra clean up and shut down properly. Otherwise do a 'kill -9' which shuts down faster. """ if self.is_running(): if wait_other_notice: #tstamp = time.time() marks = [ (node, node.mark_log()) for node in self.cluster.nodes.values() if node.is_running() and node is not self ] if common.is_win(): # Gentle on Windows is relative. WM_CLOSE is the best we get without external scripting if gently: os.system("taskkill /PID " + str(self.pid)) else: os.system("taskkill /F /PID " + str(self.pid)) else: if gently: os.kill(self.pid, signal.SIGTERM) else: os.kill(self.pid, signal.SIGKILL) if wait_other_notice: for node, mark in marks: node.watch_log_for_death(self, from_mark=mark) #print node.name, "has marked", self.name, "down in " + str(time.time() - tstamp) + "s" else: time.sleep(.1) still_running = self.is_running() if still_running and wait: wait_time_sec = 1 for i in xrange(0, 7): # we'll double the wait time each try and cassandra should # not take more than 1 minute to shutdown time.sleep(wait_time_sec) if not self.is_running(): return True wait_time_sec = wait_time_sec * 2 raise NodeError("Problem stopping node %s" % self.name) else: return True else: return False
def stop(self, wait=True, wait_other_notice=False, gently=True): """ Stop the node. - wait: if True (the default), wait for the Cassandra process to be really dead. Otherwise return after having sent the kill signal. - wait_other_notice: return only when the other live nodes of the cluster have marked this node has dead. - gently: Let Cassandra clean up and shut down properly. Otherwise do a 'kill -9' which shuts down faster. """ if self.is_running(): if wait_other_notice: #tstamp = time.time() marks = [ (node, node.mark_log()) for node in list(self.cluster.nodes.values()) if node.is_running() and node is not self ] if common.is_win(): # Gentle on Windows is relative. WM_CLOSE is the best we get without external scripting if gently: os.system("taskkill /PID " + str(self.pid)) else: os.system("taskkill /F /PID " + str(self.pid)) else: if gently: os.kill(self.pid, signal.SIGTERM) else: os.kill(self.pid, signal.SIGKILL) if wait_other_notice: for node, mark in marks: node.watch_log_for_death(self, from_mark=mark) #print node.name, "has marked", self.name, "down in " + str(time.time() - tstamp) + "s" else: time.sleep(.1) still_running = self.is_running() if still_running and wait: wait_time_sec = 1 for i in xrange(0, 7): # we'll double the wait time each try and cassandra should # not take more than 1 minute to shutdown time.sleep(wait_time_sec) if not self.is_running(): return True wait_time_sec = wait_time_sec * 2 raise NodeError("Problem stopping node %s" % self.name) else: return True else: return False
def stress(self, stress_options): stress = common.get_stress_bin(self.get_cassandra_dir()) livenodes = [ node.network_interfaces['storage'][0] for node in list(self.nodes.values()) if node.is_live() ] if len(livenodes) == 0: print_("No live node") return args = [ stress, '-d', ",".join(livenodes) ] + stress_options try: # need to set working directory for env on Windows if common.is_win(): subprocess.call(args, cwd=common.parse_path(stress)) else: subprocess.call(args) except KeyboardInterrupt: pass return self
def validate_cassandra_dir(cassandra_dir): if cassandra_dir is None: raise ArgumentError('Undefined cassandra directory') # Windows requires absolute pathing on cassandra dir - abort if specified cygwin style if common.is_win(): if ':' not in cassandra_dir: raise ArgumentError('%s does not appear to be a cassandra source directory. Please use absolute pathing (e.g. C:/cassandra.' % cassandra_dir) bin_dir = os.path.join(cassandra_dir, CASSANDRA_BIN_DIR) conf_dir = os.path.join(cassandra_dir, CASSANDRA_CONF_DIR) cnd = os.path.exists(bin_dir) cnd = cnd and os.path.exists(conf_dir) cnd = cnd and os.path.exists(os.path.join(conf_dir, CASSANDRA_CONF)) if not cnd: raise ArgumentError('%s does not appear to be a cassandra source directory' % cassandra_dir)
def is_metric_valid(metric): if 'name' not in metric or 'cmd' not in metric: logging.warn('incompleted metric definition %s', metric) return False name = metric['name'] os = metric.get('os') cmd = metric['cmd'] checkcmd = 'which' if is_win(): checkcmd = 'where' if is_sunos(): checkcmd = 'type' if os is None or os == ostype(): valid = call([checkcmd, cmd[0]]) == 0 else: valid = False logging.info('check metric %s with os=%s -> %s', name, os, valid) return valid
def __init__(self, path, name, partitioner=None, cassandra_dir=None, create_directory=True, cassandra_version=None, verbose=False): self.name = name self.nodes = {} self.seeds = [] self.partitioner = partitioner self._config_options = {} self.__log_level = "INFO" self.__path = path self.__version = None if create_directory: # we create the dir before potentially downloading to throw an error sooner if need be os.mkdir(self.get_path()) try: if cassandra_version is None: # at this point, cassandra_dir should always not be None, but # we keep this for backward compatibility (in loading old cluster) if cassandra_dir is not None: if common.is_win(): self.__cassandra_dir = cassandra_dir else: self.__cassandra_dir = os.path.abspath(cassandra_dir) self.__version = self.__get_version_from_build() else: dir, v = repository.setup(cassandra_version, verbose) self.__cassandra_dir = dir self.__version = v if v is not None else self.__get_version_from_build( ) if create_directory: common.validate_cassandra_dir(self.__cassandra_dir) self.__update_config() except: if create_directory: shutil.rmtree(self.get_path()) raise
def stress(self, stress_options): stress = common.get_stress_bin(self.get_cassandra_dir()) livenodes = [ node.network_interfaces['storage'][0] for node in self.nodes.values() if node.is_live() ] if len(livenodes) == 0: print "No live node" return args = [stress, '-d', ",".join(livenodes)] + stress_options try: # need to set working directory for env on Windows if common.is_win(): subprocess.call(args, cwd=common.parse_path(stress)) else: subprocess.call(args) except KeyboardInterrupt: pass return self
def validate_cassandra_dir(cassandra_dir): if cassandra_dir is None: raise ArgumentError('Undefined cassandra directory') # Windows requires absolute pathing on cassandra dir - abort if specified cygwin style if common.is_win(): if ':' not in cassandra_dir: raise ArgumentError( '%s does not appear to be a cassandra source directory. Please use absolute pathing (e.g. C:/cassandra.' % cassandra_dir) bin_dir = os.path.join(cassandra_dir, CASSANDRA_BIN_DIR) conf_dir = os.path.join(cassandra_dir, CASSANDRA_CONF_DIR) cnd = os.path.exists(bin_dir) cnd = cnd and os.path.exists(conf_dir) cnd = cnd and os.path.exists(os.path.join(conf_dir, CASSANDRA_CONF)) if not cnd: raise ArgumentError( '%s does not appear to be a cassandra source directory' % cassandra_dir)
def __update_log4j(self): append_pattern='log4j.appender.R.File=' conf_file = os.path.join(self.get_conf_dir(), common.LOG4J_CONF) log_file = os.path.join(self.get_path(), 'logs', 'system.log') # log4j isn't partial to Windows \. I can't imagine why not. if common.is_win(): log_file = re.sub("\\\\", "/", log_file) common.replace_in_file(conf_file, append_pattern, append_pattern + log_file) # Setting the right log level # Replace the global log level if self.__global_log_level is not None: append_pattern='log4j.rootLogger=' common.replace_in_file(conf_file, append_pattern, append_pattern + self.__global_log_level + ',stdout,R') # Class specific log levels for class_name in self.__classes_log_level: logger_pattern='log4j.logger' full_logger_pattern = logger_pattern + '.' + class_name + '=' common.replace_or_add_into_file_tail(conf_file, full_logger_pattern, full_logger_pattern + self.__classes_log_level[class_name])
def __init__(self, path, root_path, vendor_flag): self.uid = self.gid = self.perm = self.slink = "" # 文件绝对路径 self.path = path # 文件"根"路径 self.root_path = root_path self.vendor_flag = vendor_flag # 文件父目录路径 & 文件名 self.pare_path, self.name = os.path.split(path) # 文件相对"根"路径的相对路径 if root_path in self.path: self.rela_path = self.path.replace(root_path, "", 1)[1:] else: self.rela_path = "" # 文件在卡刷包中存在的路径 if self.vendor_flag: self.spath = "/vendor/" + self.rela_path.replace("\\", "/") else: self.spath = "/system/" + self.rela_path.replace("\\", "/") if not cn.is_win(): self.set_info(self.get_stat(self.path))
def start(self, join_ring=True, no_wait=False, verbose=False, update_pid=True, wait_other_notice=False, replace_token=None, replace_address=None, jvm_args=[], wait_for_binary_proto=False, profile_options=None, use_jna=False): """ 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 True, this method returns only when all other live node of the cluster have marked this node UP. - replace_token: start the node with the -Dcassandra.replace_token option. - replace_address: start the node with the -Dcassandra.replace_address option. """ if self.is_running(): raise NodeError("%s is already running" % self.name) for itf in self.network_interfaces.values(): if itf is not None and replace_address is None: common.check_socket_available(itf) if wait_other_notice: marks = [(node, node.mark_log()) for node in self.cluster.nodes.values() if node.is_running()] cdir = self.get_cassandra_dir() cass_bin = common.join_bin(cdir, 'bin', 'cassandra') # Copy back the cassandra scripts since profiling may have modified it the previous time shutil.copy(cass_bin, self.get_bin_dir()) cass_bin = common.join_bin(self.get_path(), 'bin', 'cassandra') # 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 not 'yourkit_agent' 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:%s' % 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(cass_bin, pattern, ' ' + pattern + ' ' + cmd + '"') os.chmod(cass_bin, os.stat(cass_bin).st_mode | stat.S_IEXEC) env = common.make_cassandra_env(cdir, self.get_path()) pidfile = os.path.join(self.get_path(), 'cassandra.pid') args = [ cass_bin, '-p', pidfile, '-Dcassandra.join_ring=%s' % str(join_ring) ] 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') args = args + jvm_args process = None if common.is_win(): # clean up any old dirty_pid files from prior runs if (os.path.isfile(self.get_path() + "/dirty_pid.tmp")): os.remove(self.get_path() + "/dirty_pid.tmp") process = subprocess.Popen(args, cwd=self.get_bin_dir(), env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: process = subprocess.Popen(args, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 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) elif update_pid: if no_wait: time.sleep( 2 ) # waiting 2 seconds nevertheless to check for early errors and for the pid to be set else: for line in process.stdout: if verbose: print line.rstrip('\n') self._update_pid(process) if not self.is_running(): raise NodeError("Error starting node %s" % self.name, process) if wait_other_notice: for node, mark in marks: node.watch_log_for_alive(self, from_mark=mark) if wait_for_binary_proto: self.watch_log_for("Starting listening for CQL clients") # we're probably fine at that point but just wait some tiny bit more because # the msg is logged just before starting the binary protocol server time.sleep(0.2) return process
def start(self, join_ring=True, no_wait=False, verbose=False, update_pid=True, wait_other_notice=False, replace_token=None, replace_address=None, jvm_args=[], wait_for_binary_proto=False, profile_options=None, use_jna=False): """ 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 True, this method returns only when all other live node of the cluster have marked this node UP. - replace_token: start the node with the -Dcassandra.replace_token option. - replace_address: start the node with the -Dcassandra.replace_address option. """ if self.is_running(): raise NodeError("%s is already running" % self.name) for itf in list(self.network_interfaces.values()): if itf is not None and replace_address is None: common.check_socket_available(itf) if wait_other_notice: marks = [ (node, node.mark_log()) for node in list(self.cluster.nodes.values()) if node.is_running() ] cdir = self.get_cassandra_dir() cass_bin = common.join_bin(cdir, 'bin', 'cassandra') # Copy back the cassandra scripts since profiling may have modified it the previous time shutil.copy(cass_bin, self.get_bin_dir()) cass_bin = common.join_bin(self.get_path(), 'bin', 'cassandra') # 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 not 'yourkit_agent' 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:%s' % 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(cass_bin, pattern, ' ' + pattern + ' ' + cmd + '"') os.chmod(cass_bin, os.stat(cass_bin).st_mode | stat.S_IEXEC) env = common.make_cassandra_env(cdir, self.get_path()) pidfile = os.path.join(self.get_path(), 'cassandra.pid') args = [ cass_bin, '-p', pidfile, '-Dcassandra.join_ring=%s' % str(join_ring) ] 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') args = args + jvm_args process = None if common.is_win(): process = subprocess.Popen(args, cwd=self.get_bin_dir(), env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: process = subprocess.Popen(args, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 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(): # short delay could give us a false positive on a node being started as it could die and delete the pid file # after we check, however dtests have assumptions on how long the starting process takes. time.sleep(.5) self.__clean_win_pid() self._update_pid(process) elif update_pid: if no_wait: time.sleep(2) # waiting 2 seconds nevertheless to check for early errors and for the pid to be set else: for line in process.stdout: if verbose: print_(line.rstrip('\n')) self._update_pid(process) if not self.is_running(): raise NodeError("Error starting node %s" % self.name, process) if wait_other_notice: for node, mark in marks: node.watch_log_for_alive(self, from_mark=mark) if wait_for_binary_proto: self.watch_log_for("Starting listening for CQL clients") # we're probably fine at that point but just wait some tiny bit more because # the msg is logged just before starting the binary protocol server time.sleep(0.2) return process