def get_rabbitmq_cluster_nodes(self): cluster_nodes = None if self.rabbitmq_major_release == '3' and \ self.rabbitmq_maintenance_release == '8': rmq_cluster_status_cmd = '/usr/sbin/rabbitmqctl cluster_status' + \ ' --formatter json' output, error, returncode = SimpleProcess(rmq_cluster_status_cmd).run() try: rabbitmq_cluster_status = json.loads(output) except Exception: raise SetupError( errno.EINVAL, "RabbitMQ cluster status is not okay! \n, status : %s", output) if returncode: raise SetupError(returncode, error) running_nodes = rabbitmq_cluster_status['running_nodes'] for i, node in enumerate(running_nodes): running_nodes[i] = node.replace('rabbit@', '') cluster_nodes = " ".join(running_nodes) elif self.rabbitmq_version == '3.3.5': rmq_cluster_status_cmd = "rabbitmqctl cluster_status" output, error, returncode = SimpleProcess(rmq_cluster_status_cmd).run() cluster_nodes = re.search( r"running_nodes,\['rabbit@(?P<cluster_nodes>.+?)'\]", output.decode()).groupdict()["cluster_nodes"] else: raise SetupError( errno.EINVAL, "This RabbitMQ version : %s is not supported", self.rabbitmq_version) return cluster_nodes
def validate(self): self.PRODUCT_NAME = Conf.get(GLOBAL_CONFIG_INDEX, 'release>product') # Validate product if not self.PRODUCT_NAME: raise SetupError(1, "%s - validation failure. %s", self.name, "Product not found in global config copy.") if not enabled_products: raise SetupError(1, "No enabled products!") if self.PRODUCT_NAME not in enabled_products: raise SetupError( 1, "Product '%s' is not in enabled products list: %s", self.PRODUCT_NAME, enabled_products)
def process(self): """Configure SSPL logs and service based on config.""" # Copy and load product specific sspl config if not os.path.exists(file_store_config_path): shutil.copyfile( "%s/conf/sspl.conf.%s.yaml" % (SSPL_BASE_DIR, self.PRODUCT_NAME), file_store_config_path) # Global config copy path in sspl.conf will be referred by sspl-ll service later. Conf.load(SSPL_CONFIG_INDEX, sspl_config_path) Conf.set(SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>global_config_url", self.global_config_url) Conf.set(SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>global_config_copy_url", self.global_config_copy_url) Conf.save(SSPL_CONFIG_INDEX) environ = Conf.get(SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>environment") if environ == "DEV": self.ENVIRONMENT = environ # sspl_setup_consul script install consul in dev env and checks if consul process is running # on prod. For node replacement scenario consul will not be running on the new node. But, # there will be two instance of consul running on healthy node. When new node is configured # consul will be brought back on it. We are using VIP to connect to consul. So, if consul # is not running on new node, we dont need to error out. So, need to skip this step for # node replacement case # TODO: Need to avoid LDR in CORTX and check if we can use "CORTXr1" # Onward LR2, consul will be abstracted out and it won't exit as hard dependeny of SSPL if self.PRODUCT_NAME == "LDR_R1": # setup consul if not running already if not os.path.exists(REPLACEMENT_NODE_ENV_VAR_FILE): sspl_setup_consul = "%s/sspl_setup_consul -e %s" % ( self._script_dir, self.ENVIRONMENT) output, error, returncode = SimpleProcess( sspl_setup_consul).run() if returncode != 0: raise SetupError(returncode, error, sspl_setup_consul) # Install packages which are not available in YUM repo, from PIP pip_cmd = "python3 -m pip install -r %s/low-level/requirements.txt" % ( SSPL_BASE_DIR) output, error, returncode = SimpleProcess(pip_cmd).run() if returncode != 0: raise SetupError(returncode, error, pip_cmd) # Splitting current function into 2 functions to reduce the complexity of the code. self.install_files(self.PRODUCT_NAME)
def validate(self): """Validate config command arguments""" if not self.args.config: raise SetupError(1, "%s - Argument validation failure. %s", self.name, "Global config is required.")
def validate(self): """Validate init command arguments""" if not self.args.config: raise SetupError( errno.EINVAL, "%s - Argument validation failure. Global config is needed", self.name)
def replace_expr(self, filename:str, key, new_str:str): """The function helps to replace the expression provided as key with new string in the file provided in filename OR It inserts the new string at given line as a key in the provided file. """ with open(filename, 'r+') as f: lines = f.readlines() if isinstance(key, str): for i, line in enumerate(lines): if re.search(key, line): lines[i] = re.sub(key, new_str, lines[i]) elif isinstance(key, int): if not re.search(new_str, lines[key]): lines.insert(key, new_str) else: raise SetupError( errno.EINVAL, "Key data type : '%s', should be string or int", type(key)) f.seek(0) for line in lines: f.write(line)
def validate(self): """Validate config for supported role and product""" # Validate role self.role = Conf.get(consts.GLOBAL_CONFIG_INDEX, 'release>setup') if not self.role: raise SetupError( errno.EINVAL, "%s - validation failure. %s", self.name, "Role not found in global config copy.") if self.role not in consts.setups: raise SetupError( errno.EINVAL, "%s - validation failure. %s", self.name, "Role '%s' is not supported. Check Usage" % self.role)
def get_cluster_running_nodes(self, msg_broker : str): if(msg_broker == 'rabbitmq'): return self.get_rabbitmq_cluster_nodes() else: raise SetupError(errno.EINVAL, "Provided message broker '%s' is not supported", msg_broker)
def validate(self): """Validate test command arguments""" if not self.args.config: raise SetupError(errno.EINVAL, "%s - Argument validation failure. %s", self.name, "Global config is required.") if not self.args.plan: raise SetupError( errno.EINVAL, "%s - Argument validation failure. Test plan is needed", self.name) result = PkgV().validate("rpms", "sspl-test") if result == -1: raise SetupError(1, "'sspl-test' rpm pkg not found.")
def update_sensor_info(config_index): key = 'monitor' sensors = dict() sensors["REALSTORSENSORS"] = "true" sensors["NODEHWSENSOR"] = "true" sensors["SYSTEMDWATCHDOG"] = "true" sensors["RAIDSENSOR"] = "true" sensors["SASPORTSENSOR"] = "true" sensors["MEMFAULTSENSOR"] = "true" sensors["CPUFAULTSENSOR"] = "true" try: with open("/etc/machine-id") as f: machine_id = f.read().strip("\n") except Exception as err: raise SetupError(1, "Failed to get machine-id. - %s" % (err)) srvnode = Conf.get(GLOBAL_CONFIG_INDEX, "cluster>server_nodes>%s" % (machine_id)) enclosure_id = Conf.get(GLOBAL_CONFIG_INDEX, "cluster>%s>storage>enclosure_id" % (srvnode)) node_key_id = Conf.get(GLOBAL_CONFIG_INDEX, 'cluster>server_nodes>%s' % (machine_id)) storage_type = Conf.get(GLOBAL_CONFIG_INDEX, 'storage>%s>type' % enclosure_id) if storage_type and storage_type.lower() in ["virtual", "jbod"]: sensors["REALSTORSENSORS"] = "false" server_type = Conf.get(GLOBAL_CONFIG_INDEX, 'cluster>%s>node_type' % (node_key_id)) if server_type and server_type.lower() in ["virtual"]: sensors["NODEHWSENSOR"] = "false" sensors["SASPORTSENSOR"] = "false" sensors["MEMFAULTSENSOR"] = "false" sensors["CPUFAULTSENSOR"] = "false" sensors["RAIDSENSOR"] = "false" # Onward LDR_R2, consul will be abstracted out and it won't exit as hard dependeny of SSPL # Note: SSPL has backward compatibility to LDR_R1 and there consul is a dependency of SSPL. if SSPL_STORE_TYPE == "consul": host = os.getenv('CONSUL_HOST', CONSUL_HOST) port = os.getenv('CONSUL_PORT', CONSUL_PORT) try: consul_conn = consul.Consul(host=host, port=port) for sect, value in sensors.items(): consul_conn.kv.put("sspl/config/%s/monitor" % sect, value) except Exception as cerror: print("Error in connecting with consul: {}".format(cerror)) # Update sensor information in config for sect, value in sensors.items(): Conf.set(config_index, '%s>%s' % (sect, key), value) Conf.save(config_index)
def process(self): args = ' '.join(self._args.args) manifest_support_bundle = "%s/%s %s" % (self._script_dir, self.script, args) output, error, returncode = SimpleProcess(manifest_support_bundle).run(realtime_output=True) if returncode != 0: raise SetupError(returncode, "%s - validation failure. %s", self.name, error)
def process(self): # stop sspl service Service('dbus').process('stop', 'sspl-ll.service') # Remove sspl_conf self.del_file(file_store_config_path) # Remove sspl-configured file self.del_file(SSPL_CONFIGURED) # Remove sspl data shutil.rmtree(DATA_PATH, ignore_errors=True) # Remove sspl-ll user if preset CMD = "id -u sspl-ll" output, error, returncode = SimpleProcess(CMD).run() if returncode != 0: raise SetupError(returncode, "ERROR: %s - CMD %s", error, CMD) else: self.user_present = True if self.user_present: CMD = "/usr/sbin/userdel sspl-ll" output, error, returncode = SimpleProcess(CMD).run() if returncode != 0: raise SetupError(returncode, "ERROR: %s - CMD %s", error, CMD) # Remove log directories shutil.rmtree(f"/var/log/{PRODUCT_FAMILY}/sspl", ignore_errors=True) shutil.rmtree(f"/var/log/{PRODUCT_FAMILY}/iem", ignore_errors=True) # Remove rsyslog config files self.del_file("/etc/rsyslog.d/0-iemfwd.conf") self.del_file("/etc/rsyslog.d/1-ssplfwd.conf") # Remove logrotate config files self.del_file("/etc/logrotate.d/iem_messages") self.del_file("/etc/logrotate.d/sspl_logs") # Remove SSPL configuration files shutil.rmtree("/etc/sspl-ll", ignore_errors=True) self.del_file("/etc/sspl.conf.bak")
def recursive_chown(self, path: str, user: str, grpid: int = -1): uid = self.get_uid(user) if uid == -1: raise SetupError(errno.EINVAL, "No User Found with name : %s", user) os.chown(path, uid, grpid) for root, dirs, files in os.walk(path): for item in dirs: os.chown(os.path.join(root, item), uid, grpid) for item in files: os.chown(os.path.join(root, item), uid, grpid)
def validate(self): if not self.args.config: raise SetupError( errno.EINVAL, "%s - Argument validation failure. Global config is required.", self.name) if not self.args.type: raise SetupError( errno.EINVAL, "%s - Argument validation failure. Reset type is required.", self.name) reset_type = self.args.type[0] if reset_type == "hard": self.process_class = "HardReset" elif reset_type == "soft": self.process_class = "SoftReset" else: raise SetupError(1, "Invalid reset type specified. Please check usage.")
def process(self): self.role = Conf.get('global_config', 'release>setup') if self.dp: # Extract the data path sspldp = Conf.get('sspl', 'SYSTEM_INFORMATION>data_path') if not sspldp: raise SetupError( errno.EINVAL, "Data Path Not set in %s" % file_store_config_path) # Crete the directory and assign permissions os.makedirs(sspldp, mode=0o766, exist_ok=True) self.recursive_chown(sspldp, 'sspl-ll') # Create /tmp/dcs/hpi if required. Not needed for '<product>' role if self.role != "cortx": os.makedirs(HPI_PATH, mode=0o777, exist_ok=True) zabbix_uid = self.get_uid('zabbix') if zabbix_uid != -1: os.chown(HPI_PATH, zabbix_uid, -1) # Check for sspl required processes and misc dependencies like # installation, etc based on 'role' if self.role: self.check_dependencies() # Create mdadm.conf to set ACL on it. with open(MDADM_PATH, 'a'): os.utime(MDADM_PATH) # TODO : verify for below replacement of setfacl command which # gives rw permission to sspl-ll user for mdadm.conf file. os.chmod(MDADM_PATH, mode=0o666) sspl_ll_uid = self.get_uid('sspl-ll') if sspl_ll_uid == -1: raise SetupError(errno.EINVAL, "No User Found with name : %s", 'sspl-ll') os.chown(MDADM_PATH, sspl_ll_uid, -1)
def _send_command(self, command, fail_on_error=True): """ Execute command and retrun response Parameters: command: shell command to execute fail_on_error: Set to False will ignore command failure """ print(f"Executing: {command}") output, error, returncode = SimpleProcess(command).run() if fail_on_error and returncode != 0: raise SetupError(returncode, "ERROR: Command '%s' failed with error\n %s", command, error) return output.decode('utf-8')
def process(self): self.plan = self.args.plan[0] self.avoid_rmq = self.args.avoid_rmq # Take back up of sspl test config sspl_test_backup = '/etc/sspl_tests.conf.back' shutil.copyfile(sspl_test_file_path, sspl_test_backup) # Add global config in sspl_test config and revert the changes once test completes. # Global config path in sspl_tests.conf will be referred by sspl_tests later global_config_copy_url = Conf.get( SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>global_config_copy_url") Conf.copy(GLOBAL_CONFIG_INDEX, SSPL_TEST_CONFIG_INDEX) Conf.set(SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>global_config_copy_url", sspl_test_config_path) Conf.save(SSPL_CONFIG_INDEX) # Enable & disable sensors based on environment update_sensor_info(SSPL_TEST_CONFIG_INDEX) # Get rabbitmq values from sspl.conf and update sspl_tests.conf rmq_passwd = Conf.get(SSPL_CONFIG_INDEX, "RABBITMQEGRESSPROCESSOR>password") Conf.set(SSPL_TEST_CONFIG_INDEX, "RABBITMQEGRESSPROCESSOR>password", rmq_passwd) Conf.save(SSPL_TEST_CONFIG_INDEX) # TODO: Convert shell script to python # from cortx.sspl.sspl_test.run_qa_test import RunQATest # RunQATest(self.plan, self.avoid_rmq).run() CMD = "%s/run_qa_test.sh %s %s" % (TEST_DIR, self.plan, self.avoid_rmq) output, error, returncode = SimpleProcess(CMD).run( realtime_output=True) # Restore the original path/file & service, then throw exception # if execution is failed. Conf.set(SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>global_config_copy_url", global_config_copy_url) Conf.save(SSPL_CONFIG_INDEX) shutil.copyfile(sspl_test_backup, sspl_test_file_path) Service('dbus').process('restart', 'sspl-ll.service') if returncode != 0: raise SetupError(returncode, "%s - ERROR: %s - CMD %s", self.name, error, CMD)
def validate(self): # Common validator classes to check Cortx/system wide validator if not os.path.exists(self.SSPL_CONFIGURED): error = "SSPL is not configured. Run provisioner scripts in %s" % (self._script_dir) syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_LOCAL3) syslog.syslog(syslog.LOG_ERR, error) raise SetupError(1, "%s - validation failure. %s", self.name, error) # Validate required services are running retry = 3 while retry > 0: try: ServiceV().validate('isrunning', self.services) except VError: retry -= 1 time.sleep(5) else: break ServiceV().validate('isrunning', self.services)
def process(self): cmd = "config" if(cmd == "config"): self.config_sspl() else: raise SetupError(errno.EINVAL, "cmd val should be config") # Get the version. Output can be 3.3.5 or 3.8.9 or in this format rmq_cmd = "rpm -qi rabbitmq-server" output, error, returncode = SimpleProcess(rmq_cmd).run() if returncode: raise SetupError(returncode, error) self.rabbitmq_version = re.search( r'Version :\s*([\d.]+)', str(output)).group(1) # Get the Major release version parsed. (Eg: 3 from 3.8.9) self.rabbitmq_major_release = self.rabbitmq_version[0] # Get the Minor release version parsed. (Eg: 3.8 from 3.8.9) self.rabbitmq_minor_release = self.rabbitmq_version[:3] # Get the Maitenance release version parsed from minor release. # (Eg: 8 from 3.8) self.rabbitmq_maintenance_release = self.rabbitmq_minor_release[-1] # Skip this step if sspl is being configured for node replacement # scenario as consul data is already # available on healthy node # Updating RabbitMQ cluster nodes. # In node replacement scenario, avoiding feeding again to avoid # over writing already configured values # with which rabbitmq cluster may have been created if not os.path.exists(consts.REPLACEMENT_NODE_ENV_VAR_FILE): message_broker="rabbitmq" # Get the running nodes from a cluster pout = self.get_cluster_running_nodes(message_broker) # Update cluster_nodes key in consul if consts.PRODUCT_NAME == 'LDR_R1': host = os.getenv('CONSUL_HOST', consts.CONSUL_HOST) port = os.getenv('CONSUL_PORT', consts.CONSUL_PORT) consul_conn = consul.Consul(host=host, port=port) consul_conn.kv.put( "sspl/config/RABBITMQCLUSTER/cluster_nodes", pout) else: Conf.set(consts.SSPL_CONFIG_INDEX, 'RABBITMQCLUSTER>cluster_nodes', pout) Conf.save(consts.SSPL_CONFIG_INDEX) # Skip this step if sspl is being configured for node replacement # scenario as consul data is already # available on healthy node # Updating build requested log level if not os.path.exists(consts.REPLACEMENT_NODE_ENV_VAR_FILE): with open(f'{consts.SSPL_BASE_DIR}/low-level/files/opt/seagate' + \ '/sspl/conf/build-requested-loglevel', 'r') as f: log_level = f.readline().strip() if not log_level: log_level = "INFO" if log_level == "DEBUG" or log_level == "INFO" or \ log_level == "WARNING" or log_level == "ERROR" or \ log_level == "CRITICAL": if consts.PRODUCT_NAME == "LDR_R1": host = os.getenv('CONSUL_HOST', consts.CONSUL_HOST) port = os.getenv('CONSUL_PORT', consts.CONSUL_PORT) consul_conn = consul.Consul(host=host, port=port) consul_conn.kv.put( "sspl/config/SYSTEM_INFORMATION/log_level", log_level) else: Conf.set(consts.SSPL_CONFIG_INDEX, 'SYSTEM_INFORMATION>log_level', log_level) Conf.save(consts.SSPL_CONFIG_INDEX) else: raise SetupError( errno.EINVAL, "Unexpected log level is requested, '%s'", log_level )
def install_files(self, PRODUCT): """Configure required log files.""" # Copy rsyslog configuration if not os.path.exists(self.RSYSLOG_CONF): shutil.copyfile( "%s/low-level/files/%s" % (SSPL_BASE_DIR, self.RSYSLOG_CONF), self.RSYSLOG_CONF) if not os.path.exists(self.RSYSLOG_SSPL_CONF): shutil.copyfile( "%s/low-level/files/%s" % (SSPL_BASE_DIR, self.RSYSLOG_SSPL_CONF), self.RSYSLOG_SSPL_CONF) # Create soft link for SINGLE product name service to existing LDR_R1, LR2 service # Instead of keeping separate service file for SINGLE product with same content. currentProduct = "%s/conf/sspl-ll.service.%s" % (SSPL_BASE_DIR, PRODUCT) if (PRODUCT == "SINGLE" and not os.path.exists(currentProduct)) or \ (PRODUCT == "DUAL" and not os.path.exists(currentProduct)): os.symlink("%s/conf/sspl-ll.service.%s" % (SSPL_BASE_DIR, PRODUCT), currentProduct) if PRODUCT == "CLUSTER" and not os.path.exists(currentProduct): os.symlink("%s/conf/sspl-ll.service.LR2" % (SSPL_BASE_DIR), currentProduct) # Copy sspl-ll.service file and enable service shutil.copyfile(currentProduct, "/etc/systemd/system/sspl-ll.service") Service('dbus').process('enable', 'sspl-ll.service') daemon_reload_cmd = "systemctl daemon-reload" output, error, returncode = SimpleProcess(daemon_reload_cmd).run() if returncode != 0: raise SetupError(returncode, error, daemon_reload_cmd) # Copy IEC mapping files os.makedirs("%s/iem/iec_mapping" % (PRODUCT_BASE_DIR), exist_ok=True) distutils.dir_util.copy_tree( "%s/low-level/files/iec_mapping/" % (SSPL_BASE_DIR), "%s/iem/iec_mapping" % (PRODUCT_BASE_DIR)) # Skip this step if sspl is being configured for node replacement scenario as sspl configurations are # already available in consul on the healthy node # Running script for fetching the config using salt and feeding values to consul # Onward LR2, consul will be abstracted out and it won't exit as hard dependeny of SSPL if PRODUCT == "LDR_R1": if not os.path.exists(REPLACEMENT_NODE_ENV_VAR_FILE): config_from_salt = "%s/sspl_fetch_config_from_salt.py %s %s" % ( self._script_dir, self.ENVIRONMENT, PRODUCT) output, error, returncode = SimpleProcess( config_from_salt).run() if returncode != 0: raise SetupError(returncode, error, config_from_salt) # Skip this step if sspl is being configured for node replacement scenario as rabbitmq cluster is # already configured on the healthy node # Configure rabbitmq if not os.path.exists(REPLACEMENT_NODE_ENV_VAR_FILE): setup_rmq = Conf.get(SSPL_CONFIG_INDEX, "RABBITMQCLUSTER>setup_rmq") if setup_rmq: Service('dbus').process('start', 'rabbitmq-server.service') sspl_rabbitmq_reinit.main(PRODUCT)
def validate(self): if not self.args.nodes: raise SetupError(1, "Validation failure. %s", "join_cluster requires comma separated node names as argument.") self.nodes = self.args.nodes[0]
def config_sspl(self): if(os.geteuid() != 0): raise SetupError( errno.EINVAL, "Run this command with root privileges!!") if not os.path.isfile(consts.file_store_config_path): raise SetupError( errno.EINVAL, "Missing configuration!! Create and rerun.", consts.file_store_config_path) # Put minion id, consul_host and consul_port in conf file # Onward LDR_R2, salt will be abstracted out and it won't # exist as a hard dependeny of SSPL if consts.PRODUCT_NAME == "LDR_R1": from cortx.sspl.bin.salt_util import SaltInterface salt_util = SaltInterface() salt_util.update_config_file(consts.file_store_config_path) if os.path.isfile(consts.SSPL_CONFIGURED): os.remove(consts.SSPL_CONFIGURED) # Add sspl-ll user to required groups and sudoers file etc. sspl_reinit = [f"{consts.SSPL_BASE_DIR}/bin/sspl_reinit", self.product] _ , error, returncode = SimpleProcess(sspl_reinit).run() if returncode: raise SetupError(returncode, "%s/bin/sspl_reinit failed for product %s with error : %e", consts.SSPL_BASE_DIR, product, error ) os.makedirs(consts.SSPL_CONFIGURED_DIR, exist_ok=True) with open(consts.SSPL_CONFIGURED, 'a'): os.utime(consts.SSPL_CONFIGURED) # SSPL Log file configuration # SSPL_LOG_FILE_PATH = self.getval_from_ssplconf('sspl_log_file_path') SSPL_LOG_FILE_PATH = Conf.get( consts.SSPL_CONFIG_INDEX, 'SYSTEM_INFORMATION>sspl_log_file_path') IEM_LOG_FILE_PATH = Conf.get( consts.SSPL_CONFIG_INDEX, 'IEMSENSOR>log_file_path') if SSPL_LOG_FILE_PATH: self.replace_expr(consts.RSYSLOG_SSPL_CONF, 'File.*[=,"]', 'File="%s"' % SSPL_LOG_FILE_PATH) self.replace_expr( f"{consts.SSPL_BASE_DIR}/low-level/files/etc/logrotate.d/sspl_logs", 0, SSPL_LOG_FILE_PATH) # IEM configuration # Configure log file path in Rsyslog and logrotate configuration file IEM_LOG_FILE_PATH = Conf.get( consts.SSPL_CONFIG_INDEX, 'IEMSENSOR>log_file_path') if IEM_LOG_FILE_PATH: self.replace_expr(consts.RSYSLOG_IEM_CONF, 'File.*[=,"]', 'File="%s"' % IEM_LOG_FILE_PATH) self.replace_expr( f'{consts.SSPL_BASE_DIR}/low-level/files/etc/logrotate.d/iem_messages', 0, IEM_LOG_FILE_PATH) else: self.replace_expr(consts.RSYSLOG_IEM_CONF, 'File.*[=,"]', 'File="/var/log/%s/iem/iem_messages"' % consts.PRODUCT_FAMILY) # Create logrotate dir in case it's not present for dev environment if not os.path.exists(consts.LOGROTATE_DIR): os.makedirs(consts.LOGROTATE_DIR) shutil.copy2( '%s/low-level/files/etc/logrotate.d/iem_messages' % consts.SSPL_BASE_DIR, consts.IEM_LOGROTATE_CONF) shutil.copy2( '%s/low-level/files/etc/logrotate.d/sspl_logs' % consts.SSPL_BASE_DIR, consts.SSPL_LOGROTATE_CONF) # This rsyslog restart will happen after successful updation of rsyslog # conf file and before sspl starts. If at all this will be removed from # here, there will be a chance that SSPL intial logs will not be present in # "/var/log/<product>/sspl/sspl.log" file. So, initial logs needs to be collected from # "/var/log/messages" Service('dbus').process("restart", 'rsyslog.service') # For node replacement scenario consul will not be running on the new node. But, # there will be two instance of consul running on healthy node. When new node is configured # consul will be brought back on it. We are using VIP to connect to consul. So, if consul # is not running on new node, we dont need to error out. # If consul is not running, exit # Onward LDR_R2, consul will be abstracted out and it won't # exit as hard dependeny of SSPL if consts.PRODUCT_NAME == 'LDR_R1': if not os.path.exists(consts.REPLACEMENT_NODE_ENV_VAR_FILE): ServiceV().validate('isrunning', ['consul'], is_process=True) # Get the types of server and storage we are currently running on and # enable/disable sensor groups in the conf file accordingly. update_sensor_info(consts.SSPL_CONFIG_INDEX)