!407 【opengauss】【共享存储】支持升级

Merge pull request !407 from miffyrcee/upgrade
This commit is contained in:
opengauss-bot 2023-02-24 03:37:28 +00:00 committed by Gitee
commit f5f26bf151
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
20 changed files with 585 additions and 131 deletions

View File

@ -230,3 +230,38 @@ class EnvUtil(object):
if os.getuid() == 0 and user == "":
return ""
return EnvUtil.getEnvironmentParameterValue("DSS_HOME", user)
@staticmethod
def is_fuzzy_upgrade(user, logger=None, env_file=None):
'''
If gauss_env is 2 or the $GAUSSHOME/bin is exist, is upgrade.
'''
app_bin = os.path.realpath(
os.path.join(
EnvUtil.getEnvironmentParameterValue('GAUSSHOME',
user,
env_file=env_file),
'bin'))
gauss_env = EnvUtil.getEnvironmentParameterValue('GAUSS_ENV',
user,
env_file=env_file)
if os.path.isdir(app_bin):
if logger:
logger.debug("The $GAUSSHOME/bin is exist.")
if gauss_env in ["1", "2"]:
if logger:
logger.debug(f"The $GAUSS_ENV is {gauss_env}.")
if os.path.isdir(app_bin) or gauss_env in ["2"]:
if logger:
logger.debug("There is the upgrade is in progress.")
return True
return False
@staticmethod
def is_dss_mode(user):
dss_home = EnvUtil.get_dss_home(user)
vgname = EnvUtil.getEnv('VGNAME')
if os.path.isdir(dss_home) and vgname:
return True
else:
return False

View File

@ -211,6 +211,19 @@ class FileUtil(object):
return True
@staticmethod
def is_in_file_with_context(file_path,
call_back_name=lambda _: True,
call_back_context=lambda _: True):
'''
Easy to match strings in files
'''
if call_back_name(file_path):
with open(file_path, 'r') as fr_any:
if call_back_context(fr_any.read()):
return True
return False
@staticmethod
def readFile(filename, keyword="", rows=0):
"""
@ -398,6 +411,18 @@ class FileUtil(object):
raise Exception(ErrorCode.GAUSS_501["GAUSS_50107"] % path +
" Error:\n%s." % output + "The cmd is %s" % cmd)
@staticmethod
def get_caps(path):
'''
Get the permissions of some root users.
'''
cmd = f'getcap {path}'
status, output = subprocess.getstatusoutput(cmd)
if status != 0:
raise Exception(ErrorCode.GAUSS_501["GAUSS_50107"] % path +
" Error:\n%s." % output + "The cmd is %s" % cmd)
return output.strip()
@staticmethod
def changeOwner(user, path, recursive=False, cmd_type="shell",
@ -920,7 +945,7 @@ class FileUtil(object):
if status != 0:
raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % "log file" +
" Directory:%s." % user_dir + " Error: \n%s" % file_output)
@staticmethod
def checkFileExists(file):
"""

View File

@ -36,13 +36,13 @@ if "--unused-third-party" in sys.argv:
clib_files = os.path.join(package_path, "gspylib/clib/*.so*")
FileUtil.cleanDirectoryContent(lib_path)
FileUtil.removeFile(clib_files)
# use system pip dependecies
import psutil
import netifaces
import cryptography
import paramiko
from gspylib.common.GaussLog import GaussLog
from gspylib.common.Common import DefaultValue
from gspylib.common.ErrorCode import ErrorCode
@ -53,8 +53,10 @@ from gspylib.threads.SshTool import SshTool
from domain_utils.cluster_file.cluster_config_file import ClusterConfigFile
from domain_utils.cluster_file.cluster_dir import ClusterDir
from domain_utils.cluster_file.profile_file import ProfileFile
from domain_utils.cluster_file.version_info import VersionInfo
from domain_utils.cluster_os.cluster_user import ClusterUser
from base_utils.os.net_util import NetUtil
from base_utils.os.file_util import FileUtil
from domain_utils.domain_common.cluster_constants import ClusterConstants
from base_utils.os.user_util import UserUtil
@ -375,28 +377,36 @@ General options:
cm_cmd = 'tar -xpf `ls openGauss*cm.tar.gz|tail -1`'
cmd = self.get_dec_package_cmd(bin_cmd, cm_cmd)
status, output = subprocess.getstatusoutput(cmd)
GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50217"] %
"version.cfg" + "The cmd is %s. " % cmd +
"The output is %s." % output)
if status != 0:
GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50217"] %
"version.cfg" + "The cmd is %s. " % cmd +
"The output is %s." % output)
def get_dec_package_cmd(self, bin_cmd, cm_cmd):
root = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
clib = os.path.join(root, "script/gspylib/clib")
bin_files = ['./bin/encrypt']
clib_app = os.path.realpath(
os.path.join(f'{clib}',
f"dss_app_$(cat {root}/version.cfg | tail -n 1)"))
dss_files = []
cm_files = []
if self.clusterInfo.enable_dss == 'on':
cm_files = ['bin/cm_persist']
bin_files.extend([
dss_files = [
'./bin/perctrl', './bin/dsscmd', './lib/libdssapi.so',
'./bin/dss_clear.sh'
])
]
else:
cm_files = []
cmd = 'cd {} && '.format(root)
cmd += '{} {} && '.format(bin_cmd, ''.join(' '.join(bin_files)))
cmd += '{} {} && '.format(bin_cmd, ' '.join(bin_files + dss_files))
if cm_files:
cmd += '{} {} && '.format(cm_cmd, ''.join(' '.join(cm_files)))
cmd += '\mv {} {} && '.format(' '.join(bin_files + cm_files), clib)
cmd += '{} {} && '.format(cm_cmd, ' '.join(cm_files))
cmd += 'mkdir -p {0} -m u=rwx && '.format(clib_app)
cmd += 'mv {} {} && '.format(' '.join(cm_files + dss_files), clib_app)
cmd += '\mv {} {} && '.format(' '.join(bin_files), clib)
cmd += 'cd {} && rm -rf bin'.format(root)
return cmd

View File

@ -628,7 +628,8 @@ class ErrorCode():
" version from function.",
'GAUSS_51655': "[GAUSS-51655] : There is %s on the cluster when operating on a cluster"
"the %s parameter is not needed.",
'GAUSS_51656': "[GAUSS-51656] : Waiting for udev trigger to end timeout"
'GAUSS_51656': "[GAUSS-51656] : Waiting for udev trigger to end timeout",
'GAUSS_51657': "[GAUSS-51657] : Waiting for start %s to end timeout"
}
###########################################################################

View File

@ -21,6 +21,7 @@ import os
sys.path.append(sys.path[0] + "/../../")
from gspylib.common.GaussLog import GaussLog
from gspylib.common.DbClusterInfo import dbClusterInfo
from gspylib.common.DbClusterStatus import DbClusterStatus
from gspylib.common.ErrorCode import ErrorCode
from gspylib.component.CM.CM_OLAP.CM_OLAP import CM_OLAP
from gspylib.component.DSS.dss_comp import Dss
@ -28,6 +29,10 @@ from gspylib.component.Kernel.DN_OLAP.DN_OLAP import DN_OLAP
from domain_utils.cluster_file.version_info import VersionInfo
from base_utils.os.net_util import NetUtil
from base_utils.os.user_util import UserUtil
from base_utils.os.env_util import EnvUtil
from gspylib.component.DSS.dss_checker import DssConfig
import impl.upgrade.UpgradeConst as const
class LocalBaseOM(object):
@ -157,13 +162,14 @@ class LocalBaseOM(object):
output: NA
"""
try:
is_dss_mode = EnvUtil.is_dss_mode(self.user)
self.clusterInfo = dbClusterInfo()
hostName = NetUtil.GetHostIpOrName()
dynamicFileExist = False
if self.__class__.__name__ == "Start":
dynamicFileExist = \
self.clusterInfo.dynamicConfigExists(self.user)
if dynamicFileExist:
if dynamicFileExist and not is_dss_mode:
self.clusterInfo.readDynamicConfig(self.user)
self.dbNodeInfo = self.clusterInfo.getDbNodeByName(hostName)
else:

View File

@ -23,16 +23,24 @@ import re
import sys
import base64
import json
import getpass
import time
try:
sys.path.append(sys.path[0] + "/../../../")
from gspylib.common.ErrorCode import ErrorCode
from base_utils.security.security_checker import SecurityChecker
from domain_utils.cluster_file.cluster_dir import ClusterDir
from base_utils.os.file_util import FileUtil
from base_utils.os.cmd_util import CmdUtil
except ImportError as e:
sys.exit("[GAUSS-52200] : Unable to import module: %s." % str(e))
class DssConfig():
DMS_DEFAULT_RESTART_DELAY = 1
DMS_TMP_RESTART_DELAY = 300
def __init__(self, attr='', unzip_str='', offset=0):
self.ids = ''
@ -128,11 +136,103 @@ class DssConfig():
key: value
}).encode()).decode()
else:
if not value.strip():
return ''
b64_ans = json.loads(
base64.urlsafe_b64decode(value.encode()).decode()).get(
key, '')
base64.urlsafe_b64decode(value.encode()).decode()).get(key, '')
return b64_ans
@staticmethod
def get_cm_inst_path(cur_db_info, inst_type='cm_agent'):
if inst_type == 'cm_agent':
return DssConfig.get_simple_value(
DssConfig.get_simple_value(cur_db_info, ['cmagents']),
['datadir'])
elif inst_type == 'cm_server':
return DssConfig.get_simple_value(
DssConfig.get_simple_value(cur_db_info, ['cmservers']),
['datadir'])
return []
@staticmethod
def check_process_exist(check_flag, user=''):
if not user:
user = getpass.getuser()
check_cmd = 'ps -u {} v'.format(user)
sts, out = CmdUtil.getstatusoutput_by_fast_popen(check_cmd)
if sts not in [0]:
raise Exception(ErrorCode.GAUSS_512["GAUSS_51252"] +
' Error: {}.'.format(str(out).strip()))
if str(out).find(check_flag) > -1:
return True
else:
return False
@staticmethod
def set_cm_manual_flag(inst_id, flag, logger):
gauss_home = ClusterDir.get_gauss_home()
file_ = os.path.realpath(
os.path.join(gauss_home,
f'bin/instance_manual_start_{str(inst_id)}'))
logger.debug(
"Start to delete or add manual flag file: {}.".format(file_))
if flag == 'start' and os.path.isfile(file_):
os.remove(file_)
logger.debug("End to delete manual flag file: {}.".format(file_))
elif flag == 'stop' and not os.path.isfile(file_):
FileUtil.createFileInSafeMode(file_)
logger.debug("End to add manual flag file: {}.".format(file_))
@staticmethod
def get_cma_res_value(cma_path, key, res_name='dms_res'):
cma_res = os.path.join(cma_path, 'cm_resource.json')
if os.path.isfile(cma_res):
with open(cma_res, 'r') as fr:
res_dict = json.loads(fr.read())
for dict_ in res_dict.get('resources', {}):
if dict_.get('name') == res_name:
return str(dict_.get(key, ''))
return ''
@staticmethod
def wait_for_process_start(logger, flag, check_flag='', timeout=300):
if not check_flag:
check_flag = flag
logger.log(f"Start to wait for {flag} to be started.")
while timeout > 0:
if not DssConfig.check_process_exist(check_flag=check_flag):
if timeout % 5 == 0:
logger.debug(f'The process {flag} if not running.')
timeout -= 1
time.sleep(1)
continue
else:
break
if timeout == 0:
raise Exception(ErrorCode.GAUSS_516['GAUSS_51657'] % flag)
logger.log(f'The process {flag} is running.')
@staticmethod
def reload_cm_resource(logger, timeout=300, wait_for_start=True):
logger.debug('Start to reload the cm resource file.')
edit_cmd = f'cm_ctl res --edit --res_name="dms_res" ' \
f'--res_attr="restart_delay={timeout}"'
logger.debug(f'The cmd of the reload: {edit_cmd}.')
sts, out = CmdUtil.getstatusoutput_by_fast_popen(edit_cmd)
if sts not in [0]:
raise Exception(ErrorCode.GAUSS_535["GAUSS_53507"] % edit_cmd +
"Error:%s." + out)
kill_cmd = "ps ux | grep 'bin/cm_agent' | grep -v grep " \
"| awk '{print $2}' | xargs -r -n 100 kill -9"
logger.debug(f'The cmd of the kill cm agent is: %s.' % kill_cmd)
status, _ = CmdUtil.retryGetstatusoutput(kill_cmd, 3, 5)
if status == 0:
logger.log("Successfully kill the cm agent.")
else:
raise Exception("Failed to kill the cm agent.")
if wait_for_start:
DssConfig.wait_for_process_start(logger, 'cm_agent', 'bin/cm_agent')
logger.debug("End to kill the cm agent.")
def __str__(self):
'''

View File

@ -122,11 +122,14 @@ class DssInst():
'Error: {}'.format(e))
@staticmethod
def get_dss_id_from_key(dss_home):
def get_dss_id_from_key(dss_home=''):
'''
Obtaining INST_ID Through Configuration Items
'''
try:
if not dss_home:
dss_home = EnvUtil.get_dss_home(getpass.getuser())
cfg = os.path.join(dss_home, 'cfg', 'dss_inst.ini')
inst_id = DssInst(cfg_path=cfg).parser.get('INST_ID', '')
if inst_id.isdigit():
@ -179,7 +182,7 @@ class Dss(BaseComponent):
time.sleep(0.5)
@staticmethod
def unreg_disk(dss_home, user='', clib='', logger=None):
def unreg_disk(dss_home, user='', clib_app='', logger=None):
'''
The minimum ID is 0 and the maximum ID is 8.
There are nine instances in total.
@ -192,12 +195,12 @@ class Dss(BaseComponent):
un_reg_cmd_str = f'sh {dsscmd_path} {dss_home}; '
if clib:
if clib_app:
dsscmd_path = os.path.realpath(
os.path.join(clib, Dss.DSS_IOFENCE_FILENAME))
os.path.join(clib_app, Dss.DSS_IOFENCE_FILENAME))
cmd_str = f'su - {user} -c "export DSS_HOME={dss_home}; '
cmd_str += f'export LD_LIBRARY_PATH={clib}; '
cmd_str += f'export PATH={clib}:$PATH; '
cmd_str += f'export LD_LIBRARY_PATH={clib_app}; '
cmd_str += f'export PATH={clib_app}:$PATH; '
un_reg_cmd_str = cmd_str + f'sh {dsscmd_path} {dss_home}; "'
if logger:
@ -210,7 +213,12 @@ class Dss(BaseComponent):
if logger:
logger.debug(f'The result of the unreg: {out}')
def start_dss_server(self, kill_server=True, unrej=False, exist_so=False):
@staticmethod
def start_dss_server(logger=None,
bin_path='',
kill_server=True,
unrej=False,
exist_so=False):
'''
The OM manually starts the DSS server to obtain the socket file.
'''
@ -222,42 +230,32 @@ class Dss(BaseComponent):
dss_home = EnvUtil.get_dss_home(getpass.getuser())
if unrej:
Dss.unreg_disk(dss_home, logger=self.logger)
Dss.unreg_disk(dss_home, logger=logger)
if bin_path:
dss_cmd = os.path.realpath(os.path.join(bin_path, 'dssserver'))
else:
dss_cmd = 'dssserver'
cmd = 'sh -c "source {} && nohup {} -D {} >/dev/null 2>&1 & "'.format(
EnvUtil.getMpprcFile(), os.path.join(self.binPath, 'dssserver'),
dss_home)
EnvUtil.getMpprcFile(), dss_cmd, dss_home)
proc = FastPopen(cmd)
out, err = proc.communicate()
if proc.returncode != 0:
raise Exception(ErrorCode.GAUSS_512["GAUSS_51252"] +
' Error: {}'.format(str(err + out).strip()))
self.logger.debug('Successfully start dss server')
@staticmethod
def check_dss_exist():
user = getpass.getuser()
check_cmd = 'ps -u {} v | grep dssserver | grep -v grep'.format(user)
sts, out = CmdUtil.getstatusoutput_by_fast_popen(check_cmd)
if sts != 0:
raise Exception(ErrorCode.GAUSS_512["GAUSS_51252"] +
' Error: {}'.format(str(out).strip()))
if str(out).find('dssserver'):
return True
else:
return False
if logger:
logger.debug('Successfully start dss server.')
def initInstance(self):
'''
om init dss server
'''
self.start_dss_server()
Dss.start_dss_server(self.logger, self.binPath)
@staticmethod
def catch_err(exist_so=True):
'''
This command is used to kill the dsserver after
This command is used to kill the dssserver after
the dn initialization is complete to prevent
the initialization process from exiting.
'''

View File

@ -144,7 +144,7 @@ class DN_OLAP(Kernel):
if self.paxos_mode:
cmd += " -c"
elif self.dss_mode:
if not Dss.check_dss_exist():
if not DssConfig.check_process_exist('dssserver'):
raise Exception('The dssserver process does not exist.')
vgname = EnvUtil.getEnv('VGNAME')
dss_home = EnvUtil.getEnv('DSS_HOME')

View File

@ -67,7 +67,7 @@ class Kernel(BaseComponent):
"""
def start(self, time_out=DefaultValue.TIMEOUT_CLUSTER_START,
security_mode="off", cluster_number=None):
security_mode="off", cluster_number=None, is_dss_mode=False):
"""
"""
if cluster_number:
@ -77,12 +77,12 @@ class Kernel(BaseComponent):
else:
cmd = "%s/gs_ctl start -D %s " % (
self.binPath, self.instInfo.datadir)
if self.instInfo.instanceType == DefaultValue.MASTER_INSTANCE:
if not is_dss_mode and self.instInfo.instanceType == DefaultValue.MASTER_INSTANCE:
if len(self.instInfo.peerInstanceInfos) > 0:
cmd += "-M primary"
elif self.instInfo.instanceType == DefaultValue.CASCADE_STANDBY:
elif not is_dss_mode and self.instInfo.instanceType == DefaultValue.CASCADE_STANDBY:
cmd += "-M cascade_standby"
elif self.instInfo.instanceType == DefaultValue.STANDBY_INSTANCE:
elif not is_dss_mode and self.instInfo.instanceType == DefaultValue.STANDBY_INSTANCE:
cmd += "-M standby"
if time_out is not None:
cmd += " -t %s" % time_out

View File

@ -21,6 +21,7 @@ import subprocess
import sys
import re
import time
import getpass
sys.path.append(sys.path[0] + "/../../../../")
from gspylib.common.DbClusterInfo import queryCmd
@ -32,6 +33,10 @@ from gspylib.common.OMCommand import OMCommand
from impl.om.OmImpl import OmImpl
from gspylib.os.gsfile import g_file
from base_utils.os.net_util import NetUtil
from base_utils.os.env_util import EnvUtil
from gspylib.component.DSS.dss_checker import DssConfig
###########################################
@ -154,6 +159,15 @@ class OmImplOLAP(OmImpl):
cluster_normal_status = [DbClusterStatus.CLUSTER_STATUS_NORMAL,
DbClusterStatus.CLUSTER_STATUS_DEGRADED]
if EnvUtil.is_dss_mode(self.context.g_opts.user):
cma_paths = DssConfig.get_cm_inst_path(
self.clusterInfo.dbNodes[nodeId])
if cma_paths and DssConfig.get_cma_res_value(
cma_paths[0], key='restart_delay') != str(
DssConfig.DMS_DEFAULT_RESTART_DELAY):
DssConfig.reload_cm_resource(
self.logger, timeout=DssConfig.DMS_DEFAULT_RESTART_DELAY)
if nodeId == 0 and self.dataDir:
raise Exception(ErrorCode.GAUSS_516["GAUSS_51655"] % ("cm", "-D"))
# start cluster

View File

@ -354,11 +354,17 @@ class PreinstallImplOLAP(PreinstallImpl):
Create a VG on the first node.
'''
if not self.context.clusterInfo.enable_dss == 'on':
self.context.logger.debug('The mode is non-dss')
self.context.logger.debug('The mode is non-dss.')
return
clib_path = os.path.join(self.context.clusterToolPath,
'script/gspylib/clib')
self.context.logger.debug('Start to create vg.')
if EnvUtil.is_fuzzy_upgrade(self.context.user, self.context.logger,
self.context.mpprcFile):
return
clib_app = os.path.join(self.context.clusterToolPath,
'script/gspylib/clib',
f'dss_app_{VersionInfo.getCommitid()}')
dss_home = self.context.clusterInfo.dss_home
for vgname, dss_disk in UdevContext.get_all_vgname_disk_pair(
self.context.clusterInfo.dss_shared_disks,
@ -371,13 +377,13 @@ class PreinstallImplOLAP(PreinstallImpl):
'{2}/dsscmd showdisk -g {3} -s vg_header -D {1}"'
cv_cmd = 'su - {0} -c "export DSS_HOME={1}; export LD_LIBRARY_PATH={2};' \
'{2}/dsscmd cv -g {3} -v {4} -s {5} -D {1}"'
show_cmd = show_cmd.format(self.context.user, dss_home, clib_path,
show_cmd = show_cmd.format(self.context.user, dss_home, clib_app,
vgname, dss_disk)
cv_cmd = cv_cmd.format(self.context.user, dss_home, clib_path,
cv_cmd = cv_cmd.format(self.context.user, dss_home, clib_app,
vgname, dss_disk, au_size)
self.context.logger.debug(
'The cmd of the showdisk: {}'.format(show_cmd))
self.context.logger.debug('The cmd of the cv: {}'.format(cv_cmd))
'The cmd of the showdisk: {}.'.format(show_cmd))
self.context.logger.debug('The cmd of the cv: {}.'.format(cv_cmd))
sts, out = subprocess.getstatusoutput(show_cmd)
if sts == 0:
if out.find('vg_name = {}'.format(vgname)) > -1:
@ -396,6 +402,7 @@ class PreinstallImplOLAP(PreinstallImpl):
raise Exception(
"Failed to query the volume using dsscmd, cmd: {}, Error: {}"
.format(show_cmd, out.strip()))
self.context.logger.debug("End to create vg.")
def reset_lun_device(self):
@ -403,17 +410,16 @@ class PreinstallImplOLAP(PreinstallImpl):
Low-level user disk with dd
'''
if not self.context.clusterInfo.enable_dss == 'on':
self.context.logger.debug('The mode is non-dss')
self.context.logger.debug('The mode is non-dss.')
return
if EnvUtil.getEnvironmentParameterValue(
'GAUSS_ENV', self.context.user) not in ["", "1"]:
if EnvUtil.is_fuzzy_upgrade(self.context.user, self.context.logger,
self.context.mpprcFile):
self.context.logger.debug(
"If the value of GAUSS_ENV is not empty or 1, the LUN does not need to be reset."
)
"The luns doesn't need to be reset in the upgrade.")
return
self.context.logger.log("Cleaning up the dss luns.", "addStep")
infos = list(
filter(None, re.split(r':|,',
self.context.clusterInfo.dss_vg_info)))
@ -424,17 +430,8 @@ class PreinstallImplOLAP(PreinstallImpl):
self.context.clusterInfo.cm_share_disk
]))
app_bin = os.path.realpath(
os.path.join(
EnvUtil.getEnvironmentParameterValue('GAUSSHOME',
self.context.user), 'bin'))
if os.path.isdir(app_bin):
self.context.logger.debug(
'The $GAUSSHOME/bin directory exists. LUNs are not cleared.')
return
self.context.logger.debug(
"LUNs are about to be cleared, contains: {}.".format(
"The luns are about to be cleared, contains: {}.".format(
', '.join(cm_devs + dss_devs)))
cmd = []
@ -445,7 +442,7 @@ class PreinstallImplOLAP(PreinstallImpl):
self.context.logger.debug("Clear lun cmd: {}.".format(' && '.join(cmd)))
CmdExecutor.execCommandLocally(' && '.join(cmd))
self.context.logger.log("Successfully Cleaning Up Lun.")
self.context.logger.log("Successfully cleaned up the dss lun.")
def setPssh(self):
"""
@ -726,9 +723,9 @@ class PreinstallImplOLAP(PreinstallImpl):
DSS initialization
'''
if not self.context.clusterInfo.enable_dss == 'on':
self.context.logger.debug('The mode is Non-dss')
self.context.logger.debug('The mode is non-dss.')
return
self.context.logger.log("Unreg the dss lun.", "addStep")
self.context.logger.log("Unreging the dss lun.", "addStep")
try:
cmd = (
"%s -t %s -u %s -g %s -X %s -Q %s -l %s" %
@ -746,6 +743,7 @@ class PreinstallImplOLAP(PreinstallImpl):
self.context.localMode,
self.context.mpprcFile,
parallelism=False)
self.context.logger.log("Successfully unreg the dss lun.")
except Exception as e:
raise Exception(str(e))

View File

@ -18,6 +18,7 @@ import subprocess
import os
import pwd
import sys
import re
import getpass
sys.path.append(sys.path[0] + "/../")
@ -976,6 +977,8 @@ class PreinstallImpl:
self.context.sshTool,
self.context.localMode or self.context.isSingle,
self.context.mpprcFile)
self.context.logger.debug(
f"The cmd of the create cluster path: {cmd}.")
except Exception as e:
raise Exception(str(e))
self.context.logger.log("Successfully created cluster's path.",
@ -1625,9 +1628,15 @@ class PreinstallImpl:
# close log file
self.context.logger.closeLog()
except Exception as e:
is_upgrade_func = lambda x: re.findall(r'GAUSS_ENV[ ]*=[ ]*2', x)
for rmPath in self.context.needFixOwnerPaths:
if os.path.isfile(rmPath):
FileUtil.removeFile(rmPath)
if FileUtil.is_in_file_with_context(
rmPath, call_back_context=is_upgrade_func):
self.context.logger.debug(
f'In upgrade process, no need to delete {rmPath}.')
else:
FileUtil.removeFile(rmPath)
elif os.path.isdir(rmPath):
FileUtil.removeDirectory(rmPath)
self.context.logger.logExit(str(e))

View File

@ -77,6 +77,7 @@ ACTION_GREY_SYNC_GUC = "grey_sync_guc"
ACTION_GREY_UPGRADE_CONFIG_SYNC = "grey_upgrade_config_sync"
ACTION_CREATE_CM_CA_FOR_ROLLING_UPGRADE = "create_cm_ca_for_rolling_upgrade"
ACTION_SWITCH_DN = "switch_dn"
ACTION_WAIT_OM_MONITOR = "wait_om_monitor"
ACTION_GET_LSN_INFO = "get_lsn_info"
ACTION_GREY_RESTORE_CONFIG = "grey_restore_config"
ACTION_GREY_RESTORE_GUC = "grey_restore_guc"

View File

@ -24,6 +24,7 @@ import csv
import traceback
import copy
import re
import getpass
from datetime import datetime, timedelta
@ -51,6 +52,8 @@ from domain_utils.cluster_file.package_info import PackageInfo
from domain_utils.cluster_file.version_info import VersionInfo
from domain_utils.sql_handler.sql_result import SqlResult
from base_utils.os.net_util import NetUtil
from gspylib.component.DSS.dss_checker import DssConfig
class OldVersionModules():
@ -240,7 +243,7 @@ class UpgradeImpl:
+ "Error: \n%s" % str(output))
if (not self.context.isSingle):
# send file to remote nodes
# send file to remote nodes
self.context.sshTool.scpFiles(filePath, self.context.tmpDir)
self.context.logger.debug("Successfully write file %s." % filePath)
@ -1420,7 +1423,43 @@ class UpgradeImpl:
self.context.logger.debug("Old cluster exclude CMS instance. So no need to switch UDF.")
return False
def waif_for_om_monitor_start(self, is_rollback):
if not EnvUtil.is_dss_mode(self.context.user):
self.context.logger.debug(
"In non-dss-enabled, no need to wait for om_monitor to start.")
self.context.logger.log("Start to wait for om_monitor.")
is_rolling = False
start_time = timeit.default_timer()
cmd = "%s -t %s -U %s -V %d --old_cluster_app_path=%s " \
"--new_cluster_app_path=%s -X '%s' -l %s" % \
(OMCommand.getLocalScript("Local_Upgrade_Utility"),
const.ACTION_WAIT_OM_MONITOR,
self.context.user,
int(float(self.context.oldClusterNumber) * 1000),
self.context.oldClusterAppPath,
self.context.newClusterAppPath,
self.context.xmlFile,
self.context.localLog)
if is_rollback:
cmd += " --rollback"
if self.context.forceRollback:
cmd += " --force"
if len(self.context.nodeNames) != len(self.context.clusterNodes):
is_rolling = True
if self.need_rolling(is_rollback) or is_rolling:
cmd += " --rolling"
self.context.logger.debug("Command for waiting for om_monitor: %s." % cmd)
hostList = copy.deepcopy(self.context.nodeNames)
self.context.sshTool.executeCommand(cmd, hostList=hostList)
elapsed = timeit.default_timer() - start_time
self.context.logger.debug("Time to wait for om_monitor: %s." %
elapsed)
def switchDn(self, isRollback):
self.waif_for_om_monitor_start(is_rollback=isRollback)
self.context.logger.log("Switching DN processes.")
is_rolling = False
start_time = timeit.default_timer()
@ -1446,8 +1485,19 @@ class UpgradeImpl:
if self.need_rolling(isRollback) or is_rolling:
self.context.logger.log("Switch DN processes for rolling upgrade.")
cmd += " --rolling"
if EnvUtil.is_dss_mode(
getpass.getuser()) and DefaultValue.isgreyUpgradeNodeSpecify(
self.context.user,
DefaultValue.GREY_UPGRADE_STEP_UPGRADE_PROCESS, None,
self.context.logger):
self.context.logger.debug(
"In dss_mode, have cm configuration, upgrade all nodes together."
)
cmd += " --upgrade_dss_config={}".format(
DssConfig.get_value_b64_handler('dss_upgrade_all', 'on'))
self.context.logger.debug(
"Command for switching DN processes: %s" % cmd)
"Command for switching DN processes: %s." % cmd)
hostList = copy.deepcopy(self.context.nodeNames)
self.context.sshTool.executeCommand(cmd, hostList=hostList)
start_cluster_time = timeit.default_timer()
@ -2622,6 +2672,7 @@ class UpgradeImpl:
cmd = ClusterCommand.getQueryStatusCmd("", outFile=tmpFile)
SharedFuncs.runShellCmd(cmd, self.context.user,
self.context.userProfile)
self.context.logger.debug(f"The generator cmd is {cmd}.")
if not os.path.exists(tmpFile):
raise Exception("Can not genetate dynamic info file")
self.context.distributeFileToSpecialNode(tmpFile,
@ -4183,6 +4234,9 @@ class UpgradeImpl:
output: NA
"""
try:
if EnvUtil.is_dss_mode(self.context.user):
# there is any dss_clear process
self.stop_strategy(is_final=False)
self.start_strategy(is_final=False)
self.setUpgradeFromParam(const.UPGRADE_UNSET_NUM)
self.setUpgradeMode(0)

View File

@ -98,7 +98,6 @@ class CheckUninstall:
self.__checkOSVersion()
self.__checkOsUser()
self.__checkInstanllPath()
self.unregister()
self.logger.closeLog()
def unregister(self):

View File

@ -351,18 +351,46 @@ class Install(LocalBaseOM):
def link_dss_bin(self):
clib_path = os.path.join(
EnvUtil.getEnvironmentParameterValue("GPHOME", self.user),
'script/gspylib/clib')
bin_path = os.path.join(self.installPath, 'bin')
if not os.path.isdir(clib_path) or not os.path.isdir(bin_path):
raise Exception('ss')
cmd = 'ln -snf {0}/cm_persist {0}/perctrl {1}'.format(
clib_path, bin_path)
status, output = subprocess.getstatusoutput(cmd)
'''
The install user doesn't have the root permissions.
Therefore, privileges escaation is not supported.
In the preinstall process, the binary privileges is
escalated and is linked during the install process.
'''
clib_app = os.path.realpath(
os.path.join(
EnvUtil.getEnvironmentParameterValue("GPHOME", self.user),
'script/gspylib/clib', f'dss_app_{VersionInfo.getCommitid()}'))
dss_app = os.path.realpath(
os.path.join(os.path.dirname(self.installPath),
f'dss_app_{VersionInfo.getCommitid()}'))
bin_path = os.path.realpath(os.path.join(self.installPath, 'bin'))
if not os.path.isdir(bin_path):
raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % bin_path)
if not os.path.isdir(dss_app):
raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % dss_app)
sudo_bin = ['perctrl', 'cm_persist']
for bin_ in sudo_bin:
clib_bin = os.path.realpath(os.path.join(clib_app, bin_))
app_bin = os.path.realpath(os.path.join(dss_app, bin_))
if os.path.isfile(clib_bin):
mv_cmd = r'\mv {0} {1}'.format(clib_bin, app_bin)
status, output = subprocess.getstatusoutput(mv_cmd)
if status != 0:
raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % mv_cmd +
"Error:\n%s" % output)
link_cmd = 'ln -snf {0}/cm_persist {0}/perctrl {1}'.format(
dss_app, bin_path)
self.logger.debug(f"The cmd of the link: {link_cmd}.")
status, output = subprocess.getstatusoutput(link_cmd)
if status != 0:
raise Exception("Dss bin file link failed. Output: %s" % output)
self.logger.log("Dss bin file package successfully.")
raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % link_cmd +
"Error:\n%s." % output)
self.logger.log("Successfully generated the soft link.")
def decompress_cm_package(self):
@ -452,12 +480,13 @@ class Install(LocalBaseOM):
# decompress CM package
self.decompress_cm_package()
# change owner for tar file.
FileUtil.changeOwner(self.user, self.installPath, True)
# link bin with cap on dss mode
if self.clusterInfo.enable_dss == 'on':
self.link_dss_bin()
# change owner for tar file.
FileUtil.changeOwner(self.user, self.installPath, True)
self.logger.log("Successfully decompressed bin file.")
def __saveUpgradeVerionInfo(self):

View File

@ -52,6 +52,7 @@ from domain_utils.cluster_file.profile_file import ProfileFile
from domain_utils.cluster_file.version_info import VersionInfo
from domain_utils.cluster_file.package_info import PackageInfo
from base_utils.os.sshd_config import SshdConfig
from base_utils.os.env_util import EnvUtil
from base_utils.os.net_util import NetUtil
from domain_utils.domain_common.cluster_constants import ClusterConstants
from os_platform.linux_distro import LinuxDistro
@ -857,11 +858,12 @@ Common options:
if self.clusterInfo.enable_dss == 'on':
idx = DssConfig.get_current_dss_id_by_dn(self.clusterInfo.dbNodes,
self.dbNodeInfo)
if idx != -1:
if idx != -1 and not EnvUtil.is_fuzzy_upgrade(
self.user, self.logger, self.mpprcFile):
self.prepare_dss_home_path(idx)
else:
self.logger.debug('In dss-mode, the dn does not ' \
'exist on the current node.')
'exist on the current node or in upgrade.')
self.logger.debug("Successfully created paths for cluster.")
@ -917,12 +919,12 @@ Common options:
Creating a disk soft link
'''
self.logger.debug("Creating disk link.")
self.logger.debug("Creating dss disk link.")
context = list(
UdevContext((self.user, self.group), self.clusterInfo,
DiskUtil.get_scsi_dev_id))
self.logger.debug("Checking udev directory.")
self.logger.debug("Checking dss udev directory.")
if os.path.isdir(UdevContext.DSS_UDEV_DIR):
rule_file = os.path.join(UdevContext.DSS_UDEV_DIR,
UdevContext.DSS_UDEV_NAME) % self.user
@ -966,7 +968,7 @@ Common options:
time.sleep(1)
elif flags:
break
self.logger.debug("Successfully created disk link.")
self.logger.debug("Successfully created dss disk link.")
def prepareGaussLogPath(self):
"""
@ -1103,6 +1105,13 @@ Common options:
self.prepareGivenPath(installPath, needCheckEmpty)
self.checkUpperPath(needCheckEmpty, installPath)
if self.clusterInfo.enable_dss:
dss_app = os.path.realpath(
os.path.join(os.path.dirname(installPath),
f'dss_app_{commitid}'))
self.logger.debug("Dss app path %s." % dss_app)
self.prepareGivenPath(dss_app, False)
self.logger.debug("Successfully created installation path.")
def checkUpperPath(self, needCheckEmpty, installPath):
@ -2664,11 +2673,32 @@ Common options:
FileUtil.changeMode(DefaultValue.MIN_FILE_MODE, "%s/version.cfg" %
package_path)
def fix_dss_cap_permission(self):
'''
Modifying the dss binary cap permissions.
'''
self.logger.debug("Modifying dss cap permissions.")
clib_app = os.path.realpath(
os.path.join(self.clusterToolPath, "script/gspylib/clib",
f"dss_app_{VersionInfo.getCommitid()}"))
dss_files = ['dsscmd', 'perctrl', 'dss_clear.sh']
for file_ in dss_files:
FileUtil.changeMode(DefaultValue.BIN_FILE_MODE,
os.path.join(clib_app, file_))
caps = ['perctrl', 'cm_persist']
for file_ in caps:
FileUtil.change_caps(DefaultValue.CAP_WIO,
os.path.join(clib_app, file_))
self.logger.debug("Successfully modified dss cap permissions.")
def fix_dss_dir_permission(self):
'''
Modify the permissions on some DSS-related directories and
escalate the permissions in binary mode.
'''
self.logger.debug("Modifying dss home permissions.")
dss_home = self.clusterInfo.dss_home
cfg_dir = os.path.realpath(os.path.join(dss_home, 'cfg'))
log_path = os.path.realpath(os.path.join(dss_home, 'log'))
@ -2681,20 +2711,7 @@ Common options:
files = ["{}/*ini".format(cfg_dir)]
for file_ in files:
FileUtil.changeMode(DefaultValue.KEY_FILE_MODE, file_)
clib_path = os.path.realpath(
os.path.join(self.clusterToolPath, "script/gspylib/clib"))
dss_files = ['dsscmd', 'perctrl', 'dss_clear.sh']
for file_ in dss_files:
FileUtil.changeMode(DefaultValue.BIN_FILE_MODE,
os.path.join(clib_path, file_))
caps = ['perctrl', 'cm_persist']
for file_ in caps:
FileUtil.change_caps(DefaultValue.CAP_WIO,
os.path.join(clib_path, file_))
self.logger.debug("Successfully modified dss home permissions.")
def fix_dss_disk_permission(self):
'''
@ -2734,6 +2751,9 @@ Common options:
self.logger.debug('In dss-mode, the dn does not' \
' exist on the current node.')
return
self.fix_dss_cap_permission()
if EnvUtil.is_fuzzy_upgrade(self.user, self.logger, self.mpprcFile):
return
self.fix_dss_dir_permission()
self.fix_dss_disk_permission()
self.fix_cm_disk_permission()
@ -2758,12 +2778,16 @@ Common options:
' exist on the current node.')
return
if EnvUtil.is_fuzzy_upgrade(self.user, self.logger, self.mpprcFile):
self.logger.debug('In upgrade, the disk lock will not to be unregistered.')
return
clib = os.path.realpath(
os.path.join(self.clusterToolPath, 'script', 'gspylib', 'clib'))
clib_app = os.path.realpath(
os.path.join(self.clusterToolPath, 'script', 'gspylib', 'clib',
f'dss_app_{VersionInfo.getCommitid()}'))
Dss.unreg_disk(self.clusterInfo.dss_home,
user=self.user,
clib=clib,
clib_app=clib_app,
logger=self.logger)
def clean_dss_env(self, mpprc_file):

View File

@ -18,6 +18,7 @@
import sys
import getopt
import getpass
sys.path.append(sys.path[0] + "/../")
from gspylib.common.GaussLog import GaussLog
@ -26,6 +27,8 @@ from gspylib.common.LocalBaseOM import LocalBaseOM
from gspylib.common.ParameterParsecheck import Parameter
from domain_utils.cluster_file.cluster_log import ClusterLog
from domain_utils.domain_common.cluster_constants import ClusterConstants
from base_utils.os.env_util import EnvUtil
from gspylib.component.DSS.dss_checker import DssConfig
class Start(LocalBaseOM):
@ -136,13 +139,35 @@ General options:
output : NA
"""
isDataDirCorrect = False
is_dss_mode = EnvUtil.is_dss_mode(self.user)
for dn in self.dnCons:
if self.dataDir != "" and dn.instInfo.datadir != self.dataDir:
continue
if self.cluster_number:
dn.start(self.time_out, self.security_mode, self.cluster_number)
else:
dn.start(self.time_out, self.security_mode)
try:
if is_dss_mode:
DssConfig.wait_for_process_start(self.logger, 'dssserver', 'dssserver -D')
DssConfig.set_cm_manual_flag(dn.instInfo.instanceId,
'start', self.logger)
if self.cluster_number:
dn.start(self.time_out,
self.security_mode,
self.cluster_number,
is_dss_mode=is_dss_mode)
else:
dn.start(self.time_out,
self.security_mode,
is_dss_mode=is_dss_mode)
finally:
if is_dss_mode:
# recover the parameters of the cma resource file.
cma_paths = DssConfig.get_cm_inst_path(self.dbNodeInfo)
if cma_paths and DssConfig.get_cma_res_value(
cma_paths[0], key='restart_delay') != str(
DssConfig.DMS_DEFAULT_RESTART_DELAY):
DssConfig.reload_cm_resource(
self.logger,
timeout=DssConfig.DMS_DEFAULT_RESTART_DELAY)
isDataDirCorrect = True
if not isDataDirCorrect:

View File

@ -108,9 +108,14 @@ class Uninstall(LocalBaseOM):
'''
Deregistering a Disk in dss-mode
'''
self.logger.log("Start to unregist the lun.")
gausshome = ClusterDir.getInstallDir(self.user)
dsscmd = os.path.realpath(os.path.join(gausshome, 'bin', 'dsscmd'))
if os.path.isfile(dsscmd):
perctrl = os.path.realpath(os.path.join(gausshome, 'bin', 'perctrl'))
if os.path.isfile(dsscmd) and os.path.isfile(perctrl):
if not FileUtil.get_caps(perctrl):
self.logger.log("The perctrl does not have permissions.")
return
dss_home = EnvUtil.get_dss_home(self.user)
cfg = os.path.join(dss_home, 'cfg', 'dss_inst.ini')
if os.path.isfile(cfg):
@ -119,7 +124,7 @@ class Uninstall(LocalBaseOM):
else:
self.logger.log(f"The {cfg} not exist.")
else:
self.logger.debug("Non-dss-mode or not find dsscmd.")
self.logger.log("Non-dss-mode or not find dsscmd.")
def __changeuserEnv(self):
"""

View File

@ -26,6 +26,7 @@ import os
import subprocess
import pwd
import re
import getpass
import time
import timeit
import traceback
@ -65,6 +66,8 @@ from domain_utils.sql_handler.sql_result import SqlResult
from domain_utils.sql_handler.sql_file import SqlFile
from domain_utils.domain_common.cluster_constants import ClusterConstants
from base_diff.sql_commands import SqlCommands
from gspylib.component.DSS.dss_comp import Dss, DssInst
from gspylib.component.DSS.dss_checker import DssConfig
@ -141,6 +144,7 @@ class CmdOptions():
self.fromFile = False
self.setType = "reload"
self.isSingleInst = False
self.upgrade_dss_config = ''
class OldVersionModules():
@ -313,11 +317,12 @@ def parseCommandLine():
output: NA
"""
try:
opts, args = getopt.getopt(sys.argv[1:], "t:U:R:l:V:X:",
["help", "upgrade_bak_path=", "script_type=",
"old_cluster_app_path=", "new_cluster_app_path=", "rollback",
"force", "rolling", "oldcluster_num=", "guc_string=",
"fromFile", "setType=", "HA"])
opts, args = getopt.getopt(sys.argv[1:], "t:U:R:l:V:X:", [
"help", "upgrade_bak_path=", "script_type=",
"old_cluster_app_path=", "new_cluster_app_path=", "rollback",
"force", "rolling", "oldcluster_num=", "guc_string=", "fromFile",
"setType=", "HA", "upgrade_dss_config="
])
except Exception as er:
usage()
raise Exception(ErrorCode.GAUSS_500["GAUSS_50000"] % str(er))
@ -384,6 +389,8 @@ def parseLongOptions(key, value):
if "=" in value and len(value.split("=")) == 2 and "'" not in value.split("=")[1]:
value = value.split("=")[0] + "=" + "'%s'" % value.split("=")[1]
g_opts.gucStr = value
elif key == "--upgrade_dss_config":
g_opts.upgrade_dss_config = value
elif key == "--fromFile":
g_opts.fromFile = True
elif key == "--setType":
@ -409,6 +416,7 @@ def checkParameter():
const.ACTION_COPY_CERTS,
const.ACTION_GREY_UPGRADE_CONFIG_SYNC,
const.ACTION_SWITCH_DN,
const.ACTION_WAIT_OM_MONITOR,
const.ACTION_GREY_RESTORE_CONFIG] and \
(not g_opts.newClusterAppPath or not g_opts.oldClusterAppPath):
GaussLog.exitWithError(
@ -708,12 +716,12 @@ def touchInstanceInitFile():
g_logger.logExit(str(e))
def reloadCmagent():
def reloadCmagent(signal=1):
"""
reload the cm_agent instance, make the guc parameter working
"""
cmd = "ps ux | grep '%s/bin/cm_agent' | grep -v grep | awk '{print $2}' | " \
"xargs -r -n 100 kill -1" % g_clusterInfo.appPath
"xargs -r -n 100 kill -%s" % (g_clusterInfo.appPath, str(signal))
g_logger.debug("Command for reload cm_agent:%s" % cmd)
(status, output) = CmdUtil.retryGetstatusoutput(cmd, 3, 5)
if status == 0:
@ -1528,7 +1536,18 @@ def backupConfig():
g_logger.debug("Backup CM cert files command: %s" % back_up_cm_cert_file_cmd)
CmdExecutor.execCommandLocally(back_up_cm_cert_file_cmd)
g_logger.debug("Backup CM cert files successfully.")
dss_cert_file_dir = os.path.realpath(
os.path.join(clusterAppPath, 'share/sslcert/dss'))
if os.path.isdir(dss_cert_file_dir):
back_up_dss_cert_file_cmd = "if [ -d '%s' ]; " \
"then cp -r '%s' '%s'; fi" % (dss_cert_file_dir,
dss_cert_file_dir, bakPath)
g_logger.debug("Backup dss cert files command: %s" %
back_up_dss_cert_file_cmd)
CmdExecutor.execCommandLocally(back_up_dss_cert_file_cmd)
g_logger.debug("Backup dss cert files successfully.")
om_cert_file_dir = "'%s'/share/sslcert/om" % clusterAppPath
back_up_om_cert_file_cmd = "if [ -d '%s' ]; " \
"then cp -r '%s' '%s'; fi" % (om_cert_file_dir,
@ -1876,10 +1895,9 @@ def restoreConfig():
cm_cert_backup_dir = os.path.realpath(os.path.join(bakPath, "cm"))
cm_cert_dest_dir = os.path.realpath(os.path.join(clusterAppPath, "share", "sslcert"))
restore_cm_cert_file_cmd = "if [ -d '%s' ]; " \
"then cp -r '%s' '%s'; fi" % (cm_cert_backup_dir,
cm_cert_backup_dir,
cm_cert_dest_dir)
restore_cm_cert_file_cmd = "if [ -d '{0}' ]; then " \
"cp -r '{0}' '{1}'; chmod -R 400 {1}/cm/*; fi".format(
cm_cert_backup_dir, cm_cert_dest_dir)
g_logger.debug("Restore CM cert files command: %s" % restore_cm_cert_file_cmd)
CmdExecutor.execCommandLocally(restore_cm_cert_file_cmd)
g_logger.debug("Restore CM cert files successfully.")
@ -2260,6 +2278,14 @@ def cleanInstallPath():
output : NA
"""
installPath = g_opts.appPath
commit_id = installPath[-8:]
if commit_id:
dss_app = os.path.realpath(
os.path.join(os.path.dirname(installPath), f'dss_app_{commit_id}'))
cmd = "(if [ -d '%s' ]; then rm -rf '%s'; fi)" % (dss_app, dss_app)
g_logger.log("Command for cleaning install path: %s." % cmd)
CmdExecutor.execCommandLocally(cmd)
if not os.path.exists(installPath):
g_logger.debug(ErrorCode.GAUSS_502[
"GAUSS_50201"] % installPath + " No need to clean.")
@ -2295,6 +2321,9 @@ def cleanInstallPath():
cmd += " && (if [ -d '%s' ]; then chmod -R %d '%s'; fi)" % (cm_cert_dir,
DefaultValue.KEY_DIRECTORY_MODE,
cm_cert_dir)
dss_cert_dir = os.path.realpath(os.path.join(installPath, "share", "sslcert", "dss"))
cmd += " && (if [ -d '%s' ]; then chmod -R %d '%s'; fi)" % (
dss_cert_dir, DefaultValue.KEY_DIRECTORY_MODE, dss_cert_dir)
appBakPath = "%s/to_be_delete" % tmpDir
cmd += " && (if [ -d '%s' ]; then chmod -R %d '%s'; fi)" % (appBakPath,
DefaultValue.KEY_DIRECTORY_MODE,
@ -2379,6 +2408,23 @@ def copyCerts():
FileUtil.changeMode(DefaultValue.KEY_FILE_MODE, "%s/*" %
newOmSslCerts)
if EnvUtil.is_dss_mode(getpass.getuser()) and EnvUtil.get_dss_ssl_status(
getpass.getuser()) == 'on':
old_dss_certs = os.path.join(g_opts.oldClusterAppPath,
"share/sslcert/dss")
new_dss_certs = os.path.join(g_opts.newClusterAppPath,
"share/sslcert/dss")
FileUtil.createDirectory(new_dss_certs,
mode=DefaultValue.KEY_DIRECTORY_MODE)
for cert_file in DefaultValue.GDS_CERT_LIST:
cert_ = os.path.realpath(os.path.join(old_dss_certs, cert_file))
if FileUtil.checkFileExists(cert_):
FileUtil.cpFile(cert_, new_dss_certs)
FileUtil.changeMode(DefaultValue.MIN_FILE_MODE, "%s/*" % new_dss_certs)
def prepareUpgradeSqlFolder():
"""
@ -2768,7 +2814,12 @@ def backupOldClusterCatalogPhysicalFiles():
connect to each cn and dn,
connect to each database, and do backup
"""
if EnvUtil.is_dss_mode(getpass.getuser()):
g_logger.log(
"In dss-enabled, the physical catalog file is not to be backuped.")
return
g_logger.log("Backing up old cluster catalog physical files.")
try:
InstanceList = []
# find all instances need to do backup
@ -3057,6 +3108,12 @@ def restoreOneInstanceOldClusterCatalogPhysicalFiles(instance):
read database and catalog info from file
connect each database, do restore
"""
if EnvUtil.is_dss_mode(getpass.getuser()):
g_logger.log(
"In dss-enabled, there is no backup file" \
" for physical catalog file to restore."
)
return
g_logger.debug("Restore instance catalog physical files. "
"Instance data dir: %s" % instance.datadir)
try:
@ -3218,6 +3275,12 @@ def cleanOldClusterCatalogPhysicalFiles():
connect to each cn and dn,
connect to each database, and do backup
"""
if EnvUtil.is_dss_mode(getpass.getuser()):
g_logger.log(
"In dss-enabled, there is no backup file" \
" for physical catalog file to clean up."
)
return
g_logger.log("Cleaning old cluster catalog physical files.")
try:
# kill any pending processes that are
@ -4094,11 +4157,51 @@ def setOneInstanceGuc(instance):
raise Exception(ErrorCode.GAUSS_500["GAUSS_50007"] % cmd + " Error: \n%s" % str(output))
def switch_dss_server():
is_dss_mode = EnvUtil.is_dss_mode(getpass.getuser())
if not is_dss_mode:
g_logger.debug("Non-dss-enabled, no need to switch dssserver.")
return
# Start the dssserver firstly.
DssConfig.set_cm_manual_flag(DssInst.get_dss_id_from_key() + 20001, 'start',
g_logger)
g_logger.log("Start to kill dssserver.")
Dss.kill_dss_server(logger=g_logger)
g_logger.log("End to kill dssserver.")
def wait_for_om_monitor_start():
is_dss_mode = EnvUtil.is_dss_mode(getpass.getuser())
if not is_dss_mode:
g_logger.debug("Non-dss-enabled, no need to wait om_monitor.")
return
if isNeedSwitch('cm_agent', True):
DssConfig.wait_for_process_start(g_logger, 'om_monitor',
'bin/om_monitor')
def switchDnNodeProcess():
"""
function: switch node process which CN or DN exits
:return:
"""
is_cm_killed = False
is_dss_mode = EnvUtil.is_dss_mode(getpass.getuser())
is_all_upgrade = DssConfig.get_value_b64_handler('dss_upgrade_all',
g_opts.upgrade_dss_config,
action='decode') == 'on'
if is_dss_mode and g_opts.rolling and not is_all_upgrade:
if isNeedSwitch('cm_agent', True):
# disabling cm from starting the dn process
DssConfig.reload_cm_resource(
g_logger,
timeout=DssConfig.DMS_TMP_RESTART_DELAY,
wait_for_start=False)
is_cm_killed = True
if is_dss_mode and g_opts.rolling and not is_cm_killed:
if isNeedSwitch('cm_agent', True):
reloadCmagent(signal=9)
if g_opts.rolling:
# for rolling upgrade, gaussdb fenced udf will be
# switched after cm_agent has been switched
@ -4112,6 +4215,8 @@ def switchDnNodeProcess():
switchDn()
elapsed = timeit.default_timer() - start_time
g_logger.log("Time to switch DN: %s" % getTimeFormat(elapsed))
if is_dss_mode and isNeedSwitch('dssserver'):
switch_dss_server()
def switchFencedUDFProcess():
@ -4134,7 +4239,7 @@ def switchFencedUDFProcess():
raise Exception("Failed to kill gaussdb fenced UDF master process.")
def isNeedSwitch(process, dataDir=""):
def isNeedSwitch(process, dataDir="", is_dss_mode=False):
"""
get the pid from ps ux command, and then get the realpth of this pid from
/proc/$pid/exe, under upgrade, if we can find the new path, then we do not
@ -4157,6 +4262,20 @@ def isNeedSwitch(process, dataDir=""):
r"xargs `; if [ `echo $dir | grep %s` ];then echo 'True'; " \
r"else echo 'False'; fi; done"
cmd = cmd % (process, g_gausshome, dataDir, path)
elif is_dss_mode and process == 'cm_agent':
cmd = r"pidList=`ps ux | grep '\<%s\>' | grep -v 'grep'" \
r" | awk '{print $2}' | xargs `; " \
r"for pid in $pidList; do dir=`readlink -f /proc/$pid/exe | " \
r"xargs `; if [ `echo $dir | grep %s` ];then echo 'True'; " \
r"else echo 'False'; fi; done"
cmd = cmd % (process, path)
elif process == 'dssserver':
cmd = r"pidList=`ps ux | grep -E 'dssserver[ ]+-D' | grep -v 'grep'" \
r" | awk '{print $2}' | xargs `; " \
r"for pid in $pidList; do dir=`readlink -f /proc/$pid/exe | " \
r"xargs `; if [ `echo $dir | grep %s` ];then echo 'True'; " \
r"else echo 'False'; fi; done"
cmd = cmd % path
else:
cmd = r"pidList=`ps ux | grep '\<%s\>' | grep '%s' | grep -v 'grep'" \
r" | awk '{print $2}' | xargs `; " \
@ -4735,6 +4854,7 @@ def checkAction():
const.ACTION_GREY_UPGRADE_CONFIG_SYNC,
const.ACTION_CREATE_CM_CA_FOR_ROLLING_UPGRADE,
const.ACTION_SWITCH_DN,
const.ACTION_WAIT_OM_MONITOR,
const.ACTION_GET_LSN_INFO,
const.ACTION_GREY_RESTORE_CONFIG,
const.ACTION_GREY_RESTORE_GUC,
@ -4797,6 +4917,7 @@ def main():
const.ACTION_GREY_UPGRADE_CONFIG_SYNC: greyUpgradeSyncConfig,
const.ACTION_CREATE_CM_CA_FOR_ROLLING_UPGRADE: createCmCaForRollingUpgrade,
const.ACTION_SWITCH_DN: switchDnNodeProcess,
const.ACTION_WAIT_OM_MONITOR: wait_for_om_monitor_start,
const.ACTION_CLEAN_GS_SECURE_FILES: clean_gs_secure_files,
const.ACTION_GET_LSN_INFO: getLsnInfo,
const.ACTION_GREY_RESTORE_CONFIG: greyRestoreConfig,