234 lines
8.6 KiB
Python
234 lines
8.6 KiB
Python
# -*- 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)
|