def post_install(): """ Performs post install operations """ # check whether zookeeper and kafka are running ServiceV().validate('isrunning', ['kafka-zookeeper.service', \ 'kafka.service']) # Check required python packages utils_path = Utils._get_utils_path() with open(f"{utils_path}/conf/python_requirements.txt") as file: req_pack = [] for package in file.readlines(): pack = package.strip().split('==') req_pack.append(f"{pack[0]} ({pack[1]})") try: with open(f"{utils_path}/conf/python_requirements.ext.txt" ) as extfile: for package in extfile.readlines(): pack = package.strip().split('==') req_pack.append(f"{pack[0]} ({pack[1]})") except Exception: Log.info("Not found: " + f"{utils_path}/conf/python_requirements.ext.txt") PkgV().validate(v_type='pip3s', args=req_pack) return 0
def validate_dependencies(setup): """Validate pre-requisites software packages.""" pip3_3ps_packages_main = { "cryptography": "2.8", "jsonschema": "3.2.0", "pika": "1.1.0", "pyinotify": "0.9.6", "python-daemon": "2.2.4", "requests": "2.25.1", "zope.component": "4.6.2", "zope.event": "4.5.0", "zope.interface": "5.2.0" } rpm_3ps_packages = { "hdparm": "9.43", "ipmitool": "1.8.18", "lshw": "B.02.18", "python3": "3.6.8", "python36-dbus": "1.2.4", "python36-gobject": "3.22.0", "python36-paramiko": "2.1.1", "python36-psutil": "5.6.7", "shadow-utils": "4.6", "smartmontools": "7.0", "systemd-python36": "1.0.0", "udisks2": "2.8.4" } ssu_dependency_rpms = [ "sg3_utils", "gemhpi", "pull_sea_logs", "python-hpi", "zabbix-agent-lib", "zabbix-api-gescheit", "zabbix-xrtx-lib", "python-openhpi-baselib", "zabbix-collector" ] ssu_required_process = [ "openhpid", "dcs-collectord" ] vm_dependency_rpms = [] pkg_validator = PkgV() pkg_validator.validate_pip3_pkgs(host=socket.getfqdn(), pkgs=pip3_3ps_packages_main, skip_version_check=False) pkg_validator.validate_rpm_pkgs(host=socket.getfqdn(), pkgs=rpm_3ps_packages, skip_version_check=False) # Check for sspl required processes and misc dependencies if # setup/role is other than cortx if setup == "ssu": pkg_validator.validate("rpms", ssu_dependency_rpms) ServiceV().validate("isrunning", ssu_required_process) elif setup == "vm" or setup == "gw" or setup == "cmu": # No dependency currently. Keeping this section as it # may be needed in future. pkg_validator.validate("rpms", vm_dependency_rpms)
def init(self): """Perform initialization. Raises exception on error.""" max_retry = 3 for i in range(max_retry): try: Service("consul.service").start() ServiceV().validate('isrunning', ["consul"]) break except (VError, ServiceError): if i == (max_retry - 1): raise time.sleep(0.5)
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 validate_pre_requisites(self, rpms: list = None, pip3s: list = None, services: list = None): try: if pip3s: PkgV().validate('pip3s', pip3s) if services: ServiceV().validate('isrunning', services) if rpms: PkgV().validate('rpms', rpms) except Exception as e: print(f"{e}, config:{self.__preqs_conf_file}") return False return True
def check_dependencies(self): # Check for dependency rpms and required processes active state based # on role if self.role == "ssu": PkgV().validate("rpms", self.SSU_DEPENDENCY_RPMS) ServiceV().validate("isrunning", self.SSU_REQUIRED_PROCESSES, is_process=True) elif self.role == "vm" or self.role == "gw" or self.role == "cmu": # No dependency currently. Keeping this section as it may be # needed in future. PkgV().validate("rpms", self.VM_DEPENDENCY_RPMS)
def validate_pre_requisites(self, rpms: list = None, pip3s: list = None, services: list = None, files: list = None): """Validate pre requisites using cortx-py-utils validator.""" sys.stdout.write(f'Validations running from {self._preqs_conf_file}\n') if pip3s: PkgV().validate('pip3s', pip3s) if services: ServiceV().validate('isrunning', services) if rpms: PkgV().validate('rpms', rpms) if files: PathV().validate('exists', files)
def post_install(post_install_template: str): """ Performs post install operations """ # check whether zookeeper and kafka are running ServiceV().validate('isrunning', ['kafka-zookeeper.service', \ 'kafka.service']) # Check required python packages install_path = Utils._get_from_conf_file('install_path') utils_path = install_path + '/cortx/utils' with open(f"{utils_path}/conf/python_requirements.txt") as file: req_pack = [] for package in file.readlines(): pack = package.strip().split('==') req_pack.append(f"{pack[0]} ({pack[1]})") try: with open(f"{utils_path}/conf/python_requirements.ext.txt" ) as extfile: for package in extfile.readlines(): pack = package.strip().split('==') req_pack.append(f"{pack[0]} ({pack[1]})") except Exception: Log.info("Not found: " + f"{utils_path}/conf/python_requirements.ext.txt") PkgV().validate(v_type='pip3s', args=req_pack) default_sb_path = '/var/log/cortx/support_bundle' Utils._set_to_conf_file('support>local_path', default_sb_path) os.makedirs(default_sb_path, exist_ok=True) post_install_template_index = 'post_install_index' Conf.load(post_install_template_index, post_install_template) machine_id = Conf.machine_id key_list = [ f'server_node>{machine_id}>hostname', f'server_node>{machine_id}>name' ] ConfKeysV().validate('exists', post_install_template_index, key_list) #set cluster nodename:hostname mapping to cluster.conf (needed for Support Bundle) Conf.load('cluster', 'json:///etc/cortx/cluster.conf', skip_reload=True) Utils._copy_cluster_map(post_install_template_index) return 0
def validate_pre_requisites(self, rpms: list = None, pip3s: list = None, services: list = None, files: list = None): """Validate pre requisites using cortx-py-utils validator.""" try: if pip3s: PkgV().validate('pip3s', pip3s) if services: ServiceV().validate('isrunning', services) if rpms: PkgV().validate('rpms', rpms) if files: PathV().validate('exists', files) except Exception as e: sys.stderr.write('ERROR: post_install validations failed.\n') sys.stderr.write(f"{e}, config:{self._preqs_conf_file}\n") raise e
def test_013_verify_SB_generate_after_elasticsearch_service_stop(self): """Validate SB generate while elasticsearch service is down.""" cmd = "systemctl stop elasticsearch" cmd_proc = SimpleProcess(cmd) _, _, rc = cmd_proc.run() self.assertEqual(rc, 0) bundle_obj = SupportBundle.generate( comment=TestSupportBundle.sb_description, \ components=['provisioner']) time.sleep(15) tar_file_name = f"{bundle_obj.bundle_id}_"\ f"{TestSupportBundle.node_name}.tar.gz" sb_file_path = f"{bundle_obj.bundle_path}/{bundle_obj.bundle_id}/"\ f"{TestSupportBundle.node_name}/{tar_file_name}" self.assertEqual(os.path.exists(sb_file_path), True) cmd = "systemctl start elasticsearch" cmd_proc = SimpleProcess(cmd) _, _, rc = cmd_proc.run() self.assertEqual(rc, 0) ServiceV().validate('isrunning', ['elasticsearch'])
def post_install(): """ Performs post install operations """ # check whether zookeeper and kafka are running ServiceV().validate('isrunning', ['kafka-zookeeper.service', \ 'kafka.service']) # Check python packages and install if something is missing cmd = "pip3 freeze" cmd_proc = SimpleProcess(cmd) stdout, stderr, rc = cmd_proc.run() result = stdout.decode('utf-8') if rc == 0 else \ stderr.decode('utf-8') with open('/opt/seagate/cortx/utils/conf/requirements.txt') as f: packages = f.readlines() # packages will have \n in every string. Need to remove that for package in enumerate(packages): if result.find(package[1][:-1]) == -1: raise SetupError(errno.EINVAL, "Required python package %s \ is missing", package[1][:-1]) return 0
def test_009_cli_verify_SB_generate_after_rsyslog_service_stop(self): """Validate SB generate while rsyslog service is down.""" cmd = "systemctl stop rsyslog" cmd_proc = SimpleProcess(cmd) _, _, rc = cmd_proc.run() self.assertEqual(rc, 0) stdout, stderr, rc = SB_generate_CLI(configs['SB_single_comp']) self.assertIsInstance(stdout, bytes) self.assertEqual(stderr, b'') self.assertEqual(rc, 0) time.sleep(15) bundle_id = stdout.decode('utf-8').split('|')[1] bundle_path = stdout.decode('utf-8').split('->')[1] tar_file_name = f"{bundle_id.strip()}_{TestSupportBundleCli.node_name}.tar.gz" sb_file_path = f"{(bundle_path.split('.')[0]).strip()}/"\ f"{bundle_id.strip()}/{TestSupportBundleCli.node_name}/{tar_file_name}" self.assertEqual(os.path.exists(sb_file_path), True) cmd = "systemctl start rsyslog" cmd_proc = SimpleProcess(cmd) _, _, rc = cmd_proc.run() self.assertEqual(rc, 0) ServiceV().validate('isrunning', ['rsyslog'])
def validate(self, phase: str): """Perform validations for phase.""" try: Conf.load(phase, f'json://{self._preqs_conf_file}') prereqs_block = Conf.get(phase, f'{phase}') if prereqs_block: pip3s = Conf.get(phase, f'{phase}>pip3s') if pip3s: PkgV().validate('pip3s', pip3s) rpms = Conf.get(phase, f'{phase}>rpms') if rpms: PkgV().validate('rpms', rpms) services = Conf.get(phase, f'{phase}>services') if services: ServiceV().validate('isrunning', services) files = Conf.get(phase, f'{phase}>files') if files: PathV().validate('exists', files) Log.debug("%s - pre-requisite validation complete" % phase) except Exception: Log.debug("%s - pre-requisite validation failed" % phase) raise Exception("prereqs validation failed") return 0
def test_remote_service_running(self): """Check if services are running.""" ServiceV().validate('isrunning', self.services, self.host)
def test_service_running(self): ServiceV().validate('isrunning', ['consul'])
def test_service_running(self): ServiceV().validate('isrunning', ["elasticsearch"])
def test_neg_service_running(self): """Check if ned services are running.""" neg_service = ['rabbitmq-server'] self.assertRaises(VError, ServiceV().validate, 'isrunning', neg_service)
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 framework.utils.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}/low-level/framework/sspl_reinit", self.product ] _, error, returncode = SimpleProcess(sspl_reinit).run() if returncode: raise SetupError( returncode, "%s/low-level/framework/sspl_reinit failed for" "product %s with error : %e", consts.SSPL_BASE_DIR, self.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 = DbusServiceHandler() service.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) self.create_message_types()