Skip to content

Commit

Permalink
Merge branch '3.0.1_release' into 'master'
Browse files Browse the repository at this point in the history
V3.0.1

See merge request oceanbase/ob-deploy!269
  • Loading branch information
gys-git committed Jan 9, 2025
2 parents 974dffe + 5efeab1 commit ce3d97a
Show file tree
Hide file tree
Showing 13 changed files with 180 additions and 34 deletions.
13 changes: 7 additions & 6 deletions core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,7 @@ def export_to_ocp(self, name):
return False
self._call_stdio('verbose', 'Get Deploy by name')
deploy = self.deploy_manager.get_deploy_config(name)
self.set_deploy(deploy)
if not deploy:
self._call_stdio('error', 'No such deploy: %s.' % name)
return False
Expand All @@ -1328,12 +1329,6 @@ def export_to_ocp(self, name):
self.set_repositories(repositories)
ssh_clients = self.get_clients(deploy_config, repositories)

self._call_stdio('verbose', 'get plugins by mocking an ocp repository.')
# search and get all related plugins using a mock ocp repository
mock_ocp_repository = Repository(const.COMP_OCP_SERVER_CE, "/")
mock_ocp_repository.version = "4.2.1"
repositories.extend([mock_ocp_repository])

# search and install oceanbase-ce-utils, just log warning when failed since it can be installed after takeover
repositories_utils_map = self.get_repositories_utils(repositories)
if not repositories_utils_map:
Expand All @@ -1342,6 +1337,12 @@ def export_to_ocp(self, name):
if not self.install_utils_to_servers(repositories, repositories_utils_map):
self._call_stdio('warn', 'Failed to install utils to servers')

self._call_stdio('verbose', 'get plugins by mocking an ocp repository.')
# search and get all related plugins using a mock ocp repository
mock_ocp_repository = Repository(const.COMP_OCP_SERVER_CE, "/")
mock_ocp_repository.version = "4.2.1"
repositories.extend([mock_ocp_repository])
self.set_deploy(None)
workflow = self.get_workflows('take_over', repositories=[mock_ocp_repository] + self.repositories, no_found_act='ignore')
if not self.run_workflow(workflow, deploy_config=deploy_config, repositories=[mock_ocp_repository] + self.repositories, no_found_act='ignore', **{mock_ocp_repository.name: {'cluster_config': cluster_config, 'clients': ssh_clients}}):
return False
Expand Down
1 change: 1 addition & 0 deletions plugins/general/0.1/chown_dir.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def dir_read_check(client, path):
if not new_client.execute_command(chown_cmd):
stdio.stop_loading('stop_loading', 'fail')
return False
chown_dir_flags = False
dir_read_check(new_client, server_config['home_path'])

return plugin_context.return_true()
20 changes: 10 additions & 10 deletions plugins/ocp-server/4.2.1/connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,27 @@ def status(self, stdio=None):
return False

def info(self, stdio=None):
resp = self._request('GET', '/api/v2/info', stdio=stdio)
resp = self._request('GET', '/api/v2/info', stdio=stdio, auth=self.auth)
if resp.code == 200:
return resp.content

def upload_packages(self, files, stdio=None):
resp = self._request('POST', '/api/v2/software-packages', files=files, stdio=stdio)
resp = self._request('POST', '/api/v2/software-packages', files=files, stdio=stdio, auth=self.auth)
if resp.code == 200:
return resp.content

def take_over_precheck(self, data, stdio=None):
resp = self._request('POST', '/api/v2/ob/clusters/takeOverPreCheck', data=data, stdio=stdio)
resp = self._request('POST', '/api/v2/ob/clusters/takeOverPreCheck', data=data, stdio=stdio, auth=self.auth)
if resp.code == 200:
return resp.content

def get_host_types(self, stdio=None):
resp = self._request('GET', '/api/v2/compute/hostTypes', stdio=stdio)
resp = self._request('GET', '/api/v2/compute/hostTypes', stdio=stdio, auth=self.auth)
if resp.code == 200:
return resp.content

def create_host_type(self, data, stdio=None):
resp = self._request('POST', '/api/v2/compute/hostTypes', data=data, stdio=stdio)
resp = self._request('POST', '/api/v2/compute/hostTypes', data=data, stdio=stdio, auth=self.auth)
if resp.code == 200:
return resp.content
else:
Expand All @@ -106,7 +106,7 @@ def create_host_type(self, data, stdio=None):
raise Exception("failed to create host type: %s" % msg)

def list_credentials(self, stdio=None):
resp = self._request('GET', '/api/v2/profiles/me/credentials', stdio=stdio)
resp = self._request('GET', '/api/v2/profiles/me/credentials', stdio=stdio, auth=self.auth)
if resp.code == 200:
return resp.content
else:
Expand All @@ -116,7 +116,7 @@ def list_credentials(self, stdio=None):
raise Exception("failed to query credentials: %s" % msg)

def create_credential(self, data, stdio=None):
resp = self._request('POST', '/api/v2/profiles/me/credentials', data=data, stdio=stdio)
resp = self._request('POST', '/api/v2/profiles/me/credentials', data=data, stdio=stdio, auth=self.auth)
if resp.code == 200:
return resp.content
else:
Expand All @@ -126,7 +126,7 @@ def create_credential(self, data, stdio=None):
raise Exception("failed to create credential: %s" % msg)

def take_over(self, data, stdio=None):
resp = self._request('POST', '/api/v2/ob/clusters/takeOver', data=data, stdio=stdio)
resp = self._request('POST', '/api/v2/ob/clusters/takeOver', data=data, stdio=stdio, auth=self.auth)
if resp.code == 200:
return resp.content
else:
Expand All @@ -135,14 +135,14 @@ def take_over(self, data, stdio=None):
msg = resp.content['error']['message']
raise Exception("failed to do take over: %s" % msg)

def _request(self, method, api, data=None, files=None, retry=5, stdio=None):
def _request(self, method, api, data=None, files=None, retry=5, stdio=None, auth=None):
url = self.url_prefix + api
headers = {'Content-Type': 'application/json'} if not files else {}
try:
if data is not None:
data = json.dumps(data)
stdio.verbose('send http request method: {}, url: {}, data: {}, files: {}'.format(method, url, data, files))
resp = requests.request(method, url, data=data, files=files, verify=False, headers=headers, auth=self.auth)
resp = requests.request(method, url, data=data, files=files, verify=False, headers=headers, auth=auth)
return_code = resp.status_code
content = resp.content
except Exception as e:
Expand Down
4 changes: 2 additions & 2 deletions plugins/ocp-server/4.2.1/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from tool import get_option


def start(plugin_context, start_env=None, *args, **kwargs):
def start(plugin_context, multi_process_flag=False, start_env=None, *args, **kwargs):

EXCLUDE_KEYS = plugin_context.get_variable('EXCLUDE_KEYS')
CONFIG_MAPPER = plugin_context.get_variable('CONFIG_MAPPER')
Expand Down Expand Up @@ -146,7 +146,7 @@ def start(plugin_context, start_env=None, *args, **kwargs):
success = False
continue
client.write_file(server_pid[server], os.path.join(home_path, 'run/ocp-server.pid'))
if len(cluster_config.servers) > 1:
if not multi_process_flag and len(cluster_config.servers) > 1:
break
if len(cluster_config.servers) > 1 and node_num == 1:
time.sleep(60)
Expand Down
11 changes: 9 additions & 2 deletions web/src/component/MetaDBConfig/DataBaseNodeConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import { useEffect, useState } from 'react';
import { useModel } from 'umi';

import ServerTags from '@/pages/Obdeploy/ServerTags';
import { serversValidator } from '@/utils';
import { getAllServers } from '@/utils/helper';
import styles from './index.less';
import { IPserversValidator } from '@/utils';

interface DataBaseNodeConfigProps {
tableFormRef: React.MutableRefObject<
Expand Down Expand Up @@ -151,7 +151,14 @@ export default function DataBaseNodeConfig({
},
{
validator: (_: any, value: string[]) => {
return serversValidator(_, value, 'OBServer');
return IPserversValidator(
_,
value,
allOBServer,
'OBServer',
allZoneOBServer,
finalValidate,
);
},
},
],
Expand Down
26 changes: 21 additions & 5 deletions web/src/pages/Obdeploy/NodeConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { getObdInfo } from '@/services/ob-deploy-web/Info';
import { getErrorInfo, handleQuit, serverReg, serversValidator } from '@/utils';
import {
getErrorInfo,
handleQuit,
IPserversValidator,
serverReg,
serversValidator,
} from '@/utils';
import { getAllServers } from '@/utils/helper';
import { intl } from '@/utils/intl';
import useRequest from '@/utils/useRequest';
Expand Down Expand Up @@ -59,7 +65,12 @@ export default function NodeConfig() {
errorsList,
} = useModel('global');
const { components = {}, auth, home_path } = configData || {};
const { oceanbase = {}, ocpexpress = {}, obproxy = {}, obconfigserver = {} } = components;
const {
oceanbase = {},
ocpexpress = {},
obproxy = {},
obconfigserver = {},
} = components;
const [form] = ProForm.useForm();
const [editableForm] = ProForm.useForm();
const finalValidate = useRef<boolean>(false);
Expand Down Expand Up @@ -167,7 +178,6 @@ export default function NodeConfig() {
servers: item?.servers?.map((server) => ({ ip: server })),
})),
};

setConfigData({
...configData,
components: newComponents,
Expand Down Expand Up @@ -458,7 +468,14 @@ export default function NodeConfig() {
},
{
validator: (_: any, value: string[]) =>
serversValidator(_, value, 'OBServer'),
IPserversValidator(
_,
value,
allOBServer,
'OBServer',
allZoneOBServer,
finalValidate,
),
},
],
},
Expand Down Expand Up @@ -643,7 +660,6 @@ export default function NodeConfig() {
editableItem?.id,
'servers',
]);

if (editorServers.length) {
if (!rootService || !editorServers.includes(rootService)) {
newRootService = editorServers[0];
Expand Down
119 changes: 119 additions & 0 deletions web/src/utils/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,125 @@ export const updateClusterNameReg = /^[a-zA-Z][a-zA-Z0-9_-]{0,30}[a-zA-Z0-9]$/;
//用户格式:以英文字母开头,可包含英文、数字、下划线和连字符,且不超过32位
export const nameReg = /^[a-zA-Z][a-zA-Z0-9_-]{0,31}$/;

const checkIsRepeatByAllServers = (allZoneServers: any, id: string) => {
let currentServers: string[] = [],
otherServers: string[] = [];
Object.keys(allZoneServers).forEach((key) => {
if (id === key) {
currentServers = [...allZoneServers[key]];
} else {
otherServers = [...otherServers, ...allZoneServers[key]];
}
});
for (let server of currentServers) {
if (otherServers.includes(server)) {
return true;
}
}
return false;
};

const checkIp = (value: string[], type: 'OBServer' | 'OBProxy'): ResultType => {
let response: ResultType = { success: false, msg: '' };
if (value && value.length) {
value.some((item) => {
response.success = serverReg.test(item.trim());
return !serverReg.test(item.trim());
});
}
if (!response.success) {
response.msg =
type === 'OBServer'
? intl.formatMessage({
id: 'OBD.src.utils.EnterTheCorrectIpAddress',
defaultMessage: '请输入正确的 IP 地址',
})
: intl.formatMessage({
id: 'OBD.src.utils.SelectTheCorrectObproxyNode',
defaultMessage: '请选择正确的 OBProxy 节点',
});
}
return response;
};

const checkIsRepeatByPreServers = (
preAllServers: string[],
inputServer: string,
) => {
if (preAllServers.includes(inputServer)) {
return true;
}
return false;
};

const checkRepeat = (
finalValidate,
allZoneServers,
id,
inputServer,
preAllServers,
type,
) => {
let response: ResultType = { msg: '', success: true };
if (type === 'OBProxy') return response;
if (finalValidate.current) {
response.success = !checkIsRepeatByAllServers(allZoneServers, id);
} else {
response.success = !checkIsRepeatByPreServers(preAllServers, inputServer);
}
if (!response.success) {
response.msg = intl.formatMessage({
id: 'OBD.src.utils.DoNotEnterDuplicateNodes',
defaultMessage: '禁止输入重复节点',
});
}
return response;
};

type ResultType = {
success: boolean;
msg: string;
};
const resultHandlePipeline = (...results: ResultType[]): ResultType => {
for (let result of results) {
if (!result.success) {
return result;
}
}
return {
success: true,
msg: '',
};
};
export const IPserversValidator = (
_: any,
value: string[],
preAllServers: string[],
type: 'OBServer' | 'OBProxy',
allZoneServers?: any,
finalValidate?: any,
) => {
let result: ResultType = {
success: false,
msg: '',
},
inputServer = value[0];
let id = _.field?.split('.')[0];
result = resultHandlePipeline(
checkIp(value, type),
checkRepeat(
finalValidate,
allZoneServers,
id,
inputServer,
preAllServers,
type,
),
);
if (!result.success) return Promise.reject(new Error(result.msg));
return Promise.resolve();
};

export const ocpServersValidator = (_: any, value: string[]) => {
let validtor = true;
if (value && value.length) {
Expand Down
3 changes: 2 additions & 1 deletion workflows/ocp-server/4.2.1/add_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def add_component(plugin_context, workflow, *args, **kwargs):

workflow.add(const.STAGE_SECOND, 'parameter_pre', 'ocp_const', 'cursor_check', 'start', 'health_check', 'stop_pre')
workflow.add_with_component(const.STAGE_SECOND, 'general', 'stop')
workflow.add(const.STAGE_SECOND, 'start', 'health_check', 'bootstrap')
workflow.add_with_kwargs(const.STAGE_SECOND, {'multi_process_flag': True}, 'start')
workflow.add(const.STAGE_SECOND, 'health_check', 'bootstrap')

plugin_context.return_true()
4 changes: 3 additions & 1 deletion workflows/ocp-server/4.2.1/reinstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@

def reinstall(plugin_context, workflow, *args, **kwargs):
workflow.add(const.STAGE_FIRST, 'parameter_pre')
workflow.add_with_kwargs(const.STAGE_FIRST, {'is_reinstall': True}, 'cursor_check', 'start', 'health_check', 'stop', 'start', 'health_check')
workflow.add_with_kwargs(const.STAGE_FIRST, {'is_reinstall': True}, 'cursor_check', 'start')
workflow.add_with_component(const.STAGE_FIRST, 'general', 'stop')
workflow.add_with_kwargs(const.STAGE_FIRST, {'is_reinstall': True, 'multi_process_flag': True}, 'start', 'health_check')
plugin_context.return_true()
5 changes: 1 addition & 4 deletions workflows/ocp-server/4.2.1/restart.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def restart(plugin_context, workflow, *args, **kwargs):
if not plugin_context.cluster_config.depends:
workflow.add_with_kwargs(const.STAGE_FIRST, {'need_connect': False}, 'cursor_check')
workflow.add_with_kwargs(const.STAGE_FIRST, {'cursor': cursor if cursor else None, 'need_bootstrap': need_bootstrap,
'clients': new_clients if new_clients else clients, 'new_cluster_config': new_cluster_config,
'clients': new_clients if new_clients else clients, 'new_cluster_config': new_cluster_config, 'multi_process_flag': True,
'cluster_config': new_cluster_config if new_cluster_config else cluster_config}, 'parameter_pre', 'ocp_const', 'start', 'health_check')

finally_plugins = plugin_context.get_variable('finally_plugins')
Expand All @@ -55,6 +55,3 @@ def restart(plugin_context, workflow, *args, **kwargs):

return plugin_context.return_true()




2 changes: 1 addition & 1 deletion workflows/ocp-server/4.2.1/scale_out.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ def scale_out(plugin_context, workflow, *args, **kwargs):
workflow.add(const.STAGE_THIRD, 'parameter_pre', 'ocp_const')
workflow.add_with_kwargs(const.STAGE_THIRD, {'target_servers': added_servers}, 'cursor_check', 'start', 'health_check')
workflow.add_with_component_version_kwargs(const.STAGE_THIRD, 'general', '0.1', {'target_servers': added_servers}, 'stop')
workflow.add_with_kwargs(const.STAGE_THIRD, {'target_servers': added_servers}, 'start', 'health_check', 'bootstrap')
workflow.add_with_kwargs(const.STAGE_THIRD, {'target_servers': added_servers, 'multi_process_flag': True}, 'start', 'health_check', 'bootstrap')

plugin_context.return_true()
3 changes: 2 additions & 1 deletion workflows/ocp-server/4.2.1/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ def start(plugin_context, workflow, *args, **kwargs):
workflow.add(const.STAGE_FIRST, 'start', 'health_check')
workflow.add(const.STAGE_FIRST, 'stop_pre')
workflow.add_with_component(const.STAGE_FIRST, 'general', 'stop')
workflow.add(const.STAGE_FIRST, 'start', 'health_check', 'bootstrap', 'connect', 'upload_packages')
workflow.add_with_kwargs(const.STAGE_FIRST, {'multi_process_flag': True}, 'start')
workflow.add(const.STAGE_FIRST, 'health_check', 'bootstrap', 'connect', 'upload_packages')
plugin_context.return_true()
Loading

0 comments on commit ce3d97a

Please sign in to comment.