def _get_actual_db_status(self): try: out, err = utils.execute_with_timeout("/usr/bin/mysqladmin", "ping", run_as_root=True, root_helper="sudo") LOG.info("Service Status is RUNNING.") return rd_instance.ServiceStatuses.RUNNING except exception.ProcessExecutionError: LOG.error("Process execution ") try: out, err = utils.execute_with_timeout("/bin/ps", "-C", "mysqld", "h") pid = out.split()[0] # TODO(rnirmal): Need to create new statuses for instances # where the mysql service is up, but unresponsive LOG.info('MySQL pid: %(pid)s' % {'pid': pid}) LOG.info("Service Status is BLOCKED.") return rd_instance.ServiceStatuses.BLOCKED except exception.ProcessExecutionError: mysql_args = load_mysqld_options() pid_file = mysql_args.get('pid_file', '/var/run/mysqld/mysqld.pid') if os.path.exists(pid_file): LOG.info("Service Status is CRASHED.") return rd_instance.ServiceStatuses.CRASHED else: LOG.info("Service Status is SHUTDOWN.") return rd_instance.ServiceStatuses.SHUTDOWN
def _enable_mysql_on_boot(self): LOG.info("Enabling mysql on boot.") try: mysql_service = operating_system.service_discovery(MYSQL_SERVICE_CANDIDATES) utils.execute_with_timeout(mysql_service["cmd_enable"], shell=True) except KeyError: raise RuntimeError("Service is not discovered.")
def _get_actual_db_status(self): try: out, err = utils.execute_with_timeout( "/usr/bin/mysqladmin", "ping", run_as_root=True, root_helper="sudo") LOG.info("Service Status is RUNNING.") return rd_instance.ServiceStatuses.RUNNING except exception.ProcessExecutionError: LOG.error("Process execution ") try: out, err = utils.execute_with_timeout("/bin/ps", "-C", "mysqld", "h") pid = out.split()[0] # TODO(rnirmal): Need to create new statuses for instances # where the mysql service is up, but unresponsive LOG.info('MySQL pid: %(pid)s' % {'pid': pid}) LOG.info("Service Status is BLOCKED.") return rd_instance.ServiceStatuses.BLOCKED except exception.ProcessExecutionError: mysql_args = load_mysqld_options() pid_file = mysql_args.get('pid_file', '/var/run/mysqld/mysqld.pid') if os.path.exists(pid_file): LOG.info("Service Status is CRASHED.") return rd_instance.ServiceStatuses.CRASHED else: LOG.info("Service Status is SHUTDOWN.") return rd_instance.ServiceStatuses.SHUTDOWN
def start_mysql(self, update_db=False): LOG.info(_("Starting mysql...")) # This is the site of all the trouble in the restart tests. # Essentially what happens is that mysql start fails, but does not # die. It is then impossible to kill the original, so self._enable_mysql_on_boot() try: mysql_service = operating_system.service_discovery( MYSQL_SERVICE_CANDIDATES) utils.execute_with_timeout(mysql_service['cmd_start'], shell=True) except KeyError: raise RuntimeError("Service is not discovered.") except exception.ProcessExecutionError: # it seems mysql (percona, at least) might come back with [Fail] # but actually come up ok. we're looking into the timing issue on # parallel, but for now, we'd like to give it one more chance to # come up. so regardless of the execute_with_timeout() response, # we'll assume mysql comes up and check it's status for a while. pass if not self.status.wait_for_real_status_to_change_to( rd_instance.ServiceStatuses.RUNNING, self.state_change_wait_time, update_db): LOG.error(_("Start up of MySQL failed!")) # If it won't start, but won't die either, kill it by hand so we # don't let a rouge process wander around. try: utils.execute_with_timeout("sudo", "pkill", "-9", "mysql") except exception.ProcessExecutionError as p: LOG.error("Error killing stalled mysql start command.") LOG.error(p) # There's nothing more we can do... self.status.end_install_or_restart() raise RuntimeError("Could not start MySQL!")
def _disable_mysql_on_boot(self): try: mysql_service = operating_system.service_discovery( MYSQL_SERVICE_CANDIDATES) utils.execute_with_timeout(mysql_service['cmd_disable'], shell=True) except KeyError: raise RuntimeError("Service is not discovered.")
def _write_temp_mycnf_with_admin_account(self, original_file_path, temp_file_path, password): utils.execute_with_timeout("sudo", "chmod", "0711", MYSQL_BASE_DIR) mycnf_file = open(original_file_path, "r") tmp_file = open(temp_file_path, "w") for line in mycnf_file: tmp_file.write(line) if "[client]" in line: tmp_file.write("user\t\t= %s\n" % ADMIN_USER_NAME) tmp_file.write("password\t= %s\n" % password) mycnf_file.close() tmp_file.close()
def _replace_mycnf_with_template(self, template_path, original_path): LOG.debug("replacing the mycnf with template") LOG.debug("template_path(%s) original_path(%s)" % (template_path, original_path)) if os.path.isfile(template_path): if os.path.isfile(original_path): utils.execute_with_timeout( "sudo", "mv", original_path, "%(name)s.%(date)s" % {"name": original_path, "date": date.today().isoformat()}, ) utils.execute_with_timeout("sudo", "cp", template_path, original_path)
def _write_temp_mycnf_with_admin_account(self, original_file_path, temp_file_path, password): utils.execute_with_timeout("sudo", "chmod", "0711", MYSQL_BASE_DIR) mycnf_file = open(original_file_path, 'r') tmp_file = open(temp_file_path, 'w') for line in mycnf_file: tmp_file.write(line) if "[client]" in line: tmp_file.write("user\t\t= %s\n" % ADMIN_USER_NAME) tmp_file.write("password\t= %s\n" % password) mycnf_file.close() tmp_file.close()
def _clear_mysql_config(self): """Clear old configs, which can be incompatible with new version """ LOG.debug("Clearing old mysql config") random_uuid = str(uuid.uuid4()) configs = ["/etc/my.cnf", "/etc/mysql/conf.d", "/etc/mysql/my.cnf"] for config in configs: command = "mv %s %s_%s" % (config, config, random_uuid) try: utils.execute_with_timeout(command, shell=True, root_helper="sudo") LOG.debug("%s saved to %s_%s" % (config, config, random_uuid)) except exception.ProcessExecutionError: pass
def _replace_mycnf_with_template(self, template_path, original_path): LOG.debug("replacing the mycnf with template") LOG.debug("template_path(%s) original_path(%s)" % (template_path, original_path)) if os.path.isfile(template_path): if os.path.isfile(original_path): utils.execute_with_timeout( "sudo", "mv", original_path, "%(name)s.%(date)s" % { 'name': original_path, 'date': date.today().isoformat() }) utils.execute_with_timeout("sudo", "cp", template_path, original_path)
def _clear_mysql_config(self): """Clear old configs, which can be incompatible with new version.""" LOG.debug("Clearing old mysql config") random_uuid = str(uuid.uuid4()) configs = ["/etc/my.cnf", "/etc/mysql/conf.d", "/etc/mysql/my.cnf"] for config in configs: command = "mv %s %s_%s" % (config, config, random_uuid) try: utils.execute_with_timeout(command, shell=True, root_helper="sudo") LOG.debug("%s saved to %s_%s" % (config, config, random_uuid)) except exception.ProcessExecutionError: pass
def stop_db(self, update_db=False, do_not_start_on_reboot=False): LOG.info(_("Stopping mysql...")) if do_not_start_on_reboot: self._disable_mysql_on_boot() try: mysql_service = operating_system.service_discovery(MYSQL_SERVICE_CANDIDATES) utils.execute_with_timeout(mysql_service["cmd_stop"], shell=True) except KeyError: raise RuntimeError("Service is not discovered.") if not self.status.wait_for_real_status_to_change_to( rd_instance.ServiceStatuses.SHUTDOWN, self.state_change_wait_time, update_db ): LOG.error(_("Could not stop MySQL!")) self.status.end_install_or_restart() raise RuntimeError("Could not stop MySQL!")
def stop_db(self, update_db=False, do_not_start_on_reboot=False): LOG.info(_("Stopping mysql...")) if do_not_start_on_reboot: self._disable_mysql_on_boot() try: mysql_service = operating_system.service_discovery( MYSQL_SERVICE_CANDIDATES) utils.execute_with_timeout(mysql_service['cmd_stop'], shell=True) except KeyError: raise RuntimeError("Service is not discovered.") if not self.status.wait_for_real_status_to_change_to( rd_instance.ServiceStatuses.SHUTDOWN, self.state_change_wait_time, update_db): LOG.error(_("Could not stop MySQL!")) self.status.end_install_or_restart() raise RuntimeError("Could not stop MySQL!")
def get_auth_password(): pwd, err = utils.execute_with_timeout("sudo", "awk", "/password\\t=/{print $3; exit}", MYSQL_CONFIG) if err: LOG.error(err) raise RuntimeError("Problem reading my.cnf! : %s" % err) return pwd.strip()
def _write_mycnf(self, admin_password, config_contents): """ Install the set of mysql my.cnf templates. Update the os_admin user and password to the my.cnf file for direct login from localhost """ LOG.info(_("Writing my.cnf templates.")) if admin_password is None: admin_password = get_auth_password() with open(TMP_MYCNF, "w") as t: t.write(config_contents) utils.execute_with_timeout("sudo", "mv", TMP_MYCNF, MYSQL_CONFIG) self._write_temp_mycnf_with_admin_account(MYSQL_CONFIG, TMP_MYCNF, admin_password) utils.execute_with_timeout("sudo", "mv", TMP_MYCNF, MYSQL_CONFIG) self.wipe_ib_logfiles()
def get_auth_password(): pwd, err = utils.execute_with_timeout( "sudo", "awk", "/password\\t=/{print $3; exit}", MYSQL_CONFIG) if err: LOG.error(err) raise RuntimeError("Problem reading my.cnf! : %s" % err) return pwd.strip()
def _write_mycnf(self, admin_password, config_contents): """ Install the set of mysql my.cnf templates. Update the os_admin user and password to the my.cnf file for direct login from localhost. """ LOG.info(_("Writing my.cnf templates.")) if admin_password is None: admin_password = get_auth_password() with open(TMP_MYCNF, 'w') as t: t.write(config_contents) utils.execute_with_timeout("sudo", "mv", TMP_MYCNF, MYSQL_CONFIG) self._write_temp_mycnf_with_admin_account(MYSQL_CONFIG, TMP_MYCNF, admin_password) utils.execute_with_timeout("sudo", "mv", TMP_MYCNF, MYSQL_CONFIG) self.wipe_ib_logfiles()
def wipe_ib_logfiles(self): """Destroys the iblogfiles. If for some reason the selected log size in the conf changes from the current size of the files MySQL will fail to start, so we delete the files to be safe. """ LOG.info(_("Wiping ib_logfiles...")) for index in range(2): try: (utils.execute_with_timeout("sudo", "rm", "%s/ib_logfile%d" % (MYSQL_BASE_DIR, index))) except exception.ProcessExecutionError as pe: # On restarts, sometimes these are wiped. So it can be a race # to have MySQL start up before it's restarted and these have # to be deleted. That's why its ok if they aren't found. LOG.error("Could not delete logfile!") LOG.error(pe) if "No such file or directory" not in str(pe): raise
def wipe_ib_logfiles(self): """Destroys the iblogfiles. If for some reason the selected log size in the conf changes from the current size of the files MySQL will fail to start, so we delete the files to be safe. """ LOG.info(_("Wiping ib_logfiles...")) for index in range(2): try: (utils.execute_with_timeout( "sudo", "rm", "%s/ib_logfile%d" % (MYSQL_BASE_DIR, index))) except exception.ProcessExecutionError as pe: # On restarts, sometimes these are wiped. So it can be a race # to have MySQL start up before it's restarted and these have # to be deleted. That's why its ok if they aren't found. LOG.error("Could not delete logfile!") LOG.error(pe) if "No such file or directory" not in str(pe): raise
def _create_mysql_confd_dir(self): conf_dir = "/etc/mysql/conf.d" LOG.debug("Creating %s" % conf_dir) command = "sudo mkdir -p %s" % conf_dir utils.execute_with_timeout(command, shell=True)