# -*- coding:utf-8 -*- # Copyright (c) 2020 Huawei Technologies Co.,Ltd. # # openGauss is licensed under Mulan PSL v2. # You can use this software according to the terms # and conditions of the Mulan PSL v2. # You may obtain a copy of Mulan PSL v2 at: # # http://license.coscl.org.cn/MulanPSL2 # # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OF ANY KIND, # EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. # See the Mulan PSL v2 for more details. # ---------------------------------------------------------------------------- import subprocess import os import sys sys.path.append(sys.path[0] + "/../../") from gspylib.common.Common import DefaultValue from gspylib.common.OMCommand import OMCommand from gspylib.common.ErrorCode import ErrorCode from gspylib.os.gsfile import g_file from impl.backup.BackupImpl import BackupImpl from base_utils.executor.local_remote_cmd import LocalRemoteCmd from base_utils.os.env_util import EnvUtil from base_utils.os.file_util import FileUtil from base_utils.os.net_util import NetUtil from base_utils.common.constantsbase import ConstantsBase class BackupImplOLAP(BackupImpl): """ The class is used to do perform backup or restore binary files and parameter files. """ def __init__(self, backupObj): """ function: Constructor input : backupObj output: NA """ super(BackupImplOLAP, self).__init__(backupObj) def parseConfigFile(self): """ function: Parsing configuration files input : NA output: NA """ self.context.logger.log("Parsing configuration files.") if self.context.isForce and self.context.nodename != "" \ and self.context.action == BackupImpl.ACTION_RESTORE: self.context.initSshTool([self.context.nodename], DefaultValue.TIMEOUT_PSSH_BACKUP) self.context.logger.log( "Successfully init restore nodename: %s." % self.context.nodename) return try: self.context.initClusterInfoFromStaticFile(self.context.user) nodeNames = self.context.clusterInfo.getClusterNodeNames() if self.context.nodename == "": self.context.nodename = nodeNames else: remoteNode = self.context.clusterInfo.getDbNodeByName( self.context.nodename) if remoteNode is None: raise Exception(ErrorCode.GAUSS_512["GAUSS_51209"] % ( "the node", self.context.nodename)) self.context.nodename = [self.context.nodename] self.context.initSshTool(self.context.nodename, DefaultValue.TIMEOUT_PSSH_BACKUP) except Exception as e: raise Exception(str(e)) self.context.logger.log("Successfully parsed the configuration file.") def doRemoteBackup(self): """ function: Get user and group input : NA output: NA """ self.context.logger.log("Performing remote backup.") # check backupdir permission if os.path.exists(self.context.backupDir) and not os.access( self.context.backupDir, os.R_OK | os.W_OK | os.X_OK): raise Exception(ErrorCode.GAUSS_501["GAUSS_50111"] % self.context.backupDir) localHostName = NetUtil.GetHostIpOrName() tmp_backupDir = "%s/backupTemp_%d" % ( EnvUtil.getTmpDirFromEnv(), os.getpid()) cmd = "%s -U %s --nodeName %s -P %s -l %s --ingore_miss" % \ (OMCommand.getLocalScript("Local_Backup"), self.context.user, localHostName, tmp_backupDir, self.context.localLog) if self.context.isParameter: cmd += " -p" if self.context.isBinary: cmd += " -b" self.context.logger.debug("Remote backup command is %s." % cmd) try: if not os.path.exists(tmp_backupDir): os.makedirs(tmp_backupDir, ConstantsBase.KEY_DIRECTORY_PERMISSION) self._runCmd(cmd) if self.context.isParameter: self.__distributeBackupFile(tmp_backupDir, "parameter") if self.context.isBinary: self.__distributeBackupFile(tmp_backupDir, "binary") LocalRemoteCmd.cleanFileDir(tmp_backupDir, self.context.sshTool) self.context.logger.log("Remote backup succeeded.") self.context.logger.log("Successfully backed up cluster files.") except Exception as e: LocalRemoteCmd.cleanFileDir(tmp_backupDir, self.context.sshTool) raise Exception(str(e)) def __distributeBackupFile(self, tmp_backupDir, flag): """ function: distribute Backup File input : tmp_backupDir, flag output: NA """ # compresses the configuration files for all node backups tarFiles = "%s_*.tar" % flag tarName = "%s.tar" % flag cmd = g_file.SHELL_CMD_DICT["compressTarFile"] \ % (tmp_backupDir, tarName, tarFiles, DefaultValue.KEY_FILE_MODE, tarName) if (flag == "parameter"): (status, output) = subprocess.getstatusoutput(cmd) if (status != 0): raise Exception( ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output) else: self._runCmd(cmd) # prepares the backup directory for the specified node cmd = g_file.SHELL_CMD_DICT["createDir"] \ % (self.context.backupDir, self.context.backupDir, DefaultValue.KEY_DIRECTORY_MODE) self._runCmd(cmd, self.context.nodename) # send backup package to the specified node from the local node originalFile = "'%s'/%s.tar" % (tmp_backupDir, flag) if flag == "parameter": if self.context.nodename != [NetUtil.getHostName()]: self.context.sshTool.scpFiles( originalFile, self.context.backupDir, self.context.nodename) else: FileUtil.cpFile(originalFile, self.context.backupDir) else: targetFile = "'%s'/%s.tar" % (self.context.backupDir, flag) cmd = g_file.SHELL_CMD_DICT["copyFile"] % ( originalFile, targetFile) self._runCmd(cmd) def __cleanTmpTar(self): """ function: delete tmp tar package input : NA output: NA """ cmd = "" if (self.context.isParameter and self.context.isBinary): cmd += g_file.SHELL_CMD_DICT["deleteBatchFiles"] % ( "%s/parameter_" % self.context.backupDir) cmd += " ; " cmd += g_file.SHELL_CMD_DICT["deleteBatchFiles"] % ( "%s/binary_" % self.context.backupDir) elif (self.context.isParameter and not self.context.isBinary): cmd += g_file.SHELL_CMD_DICT["deleteBatchFiles"] % ( "%s/parameter_" % self.context.backupDir) elif (not self.context.isParameter and self.context.isBinary): cmd += g_file.SHELL_CMD_DICT["deleteBatchFiles"] % ( "%s/binary_" % self.context.backupDir) self._runCmd(cmd) def doRemoteRestore(self): """ function: Get user and group input : NA output: NA """ self.context.logger.log("Performing remote restoration.") cmd = "%s -U %s -l %s " % ( OMCommand.getLocalScript("Local_Restore"), self.context.user, self.context.localLog) if (self.context.backupDir != ""): cmd += " -P %s" % self.context.backupDir if self.context.isParameter: cmd += " -p" if self.context.isBinary: cmd += " -b" if self.context.isForce: cmd += " -f" self.context.logger.debug("Remote restoration command: %s." % cmd) try: self._runCmd(cmd) self.__cleanTmpTar() self.context.logger.log("Successfully restored cluster files.") except Exception as e: self.__cleanTmpTar() raise Exception(str(e)) def _runCmd(self, cmd, nodes=None): (status, output) = \ self.context.sshTool.getSshStatusOutput(cmd, nodes) for node in status.keys(): if status[node] != DefaultValue.SUCCESS: raise Exception(output)