From 8d9c539cf656ea9aa034a3a4b60bc49b0e08987b Mon Sep 17 00:00:00 2001 From: iSecloud <869820505@qq.com> Date: Tue, 7 Nov 2023 19:27:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(backend):=20=E9=95=9C=E5=83=8F=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=BC=96=E8=AF=91=E5=8F=82=E6=95=B0=E6=94=B9=E9=80=A0?= =?UTF-8?q?=20&=20riak=E5=BC=80=E5=8F=91=20#1688?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bigdata/db-tools/dbactuator/Makefile | 3 +- .../mysql/db-tools/dbactuator/Makefile | 7 +- .../mysql/db-tools/mysql-crond/Makefile | 3 +- .../mysql/db-tools/mysql-monitor/Makefile | 3 +- .../db-tools/mysql-rotatebinlog/Makefile | 3 +- .../db-tools/mysql-table-checksum/Makefile | 3 +- .../redis/db-tools/dbactuator/Makefile | 3 +- .../db_meta/api/cluster/riak/detail.py | 25 ++++ dbm-ui/backend/db_package/views.py | 2 +- .../db_services/bigdata/riak/__init__.py | 10 ++ .../db_services/bigdata/riak/constants.py | 12 ++ .../backend/db_services/bigdata/riak/query.py | 34 +++++ .../backend/db_services/bigdata/riak/urls.py | 19 +++ .../backend/db_services/bigdata/riak/views.py | 75 ++++++++++ dbm-ui/backend/db_services/bigdata/urls.py | 1 + dbm-ui/backend/dbm_init/medium/Dockerfile | 134 +++++++++++------- dbm-ui/backend/dbm_init/medium/handlers.py | 22 ++- dbm-ui/backend/dbm_init/medium/main.py | 4 +- .../collections/riak/get_riak_resource.py | 29 ++-- dbm-ui/backend/ticket/builders/mysql/base.py | 2 +- dbm-ui/backend/ticket/builders/riak/base.py | 3 + .../ticket/builders/riak/riak_apply.py | 6 +- .../ticket/builders/riak/riak_shrink.py | 2 +- dbm-ui/backend/ticket/exclusive_ticket.xlsx | Bin 26671 -> 28977 bytes helm-charts/bk-dbm/Chart.lock | 6 +- 25 files changed, 317 insertions(+), 94 deletions(-) create mode 100644 dbm-ui/backend/db_meta/api/cluster/riak/detail.py create mode 100644 dbm-ui/backend/db_services/bigdata/riak/__init__.py create mode 100644 dbm-ui/backend/db_services/bigdata/riak/constants.py create mode 100644 dbm-ui/backend/db_services/bigdata/riak/query.py create mode 100644 dbm-ui/backend/db_services/bigdata/riak/urls.py create mode 100644 dbm-ui/backend/db_services/bigdata/riak/views.py diff --git a/dbm-services/bigdata/db-tools/dbactuator/Makefile b/dbm-services/bigdata/db-tools/dbactuator/Makefile index 0597f378bb..f2740f560f 100644 --- a/dbm-services/bigdata/db-tools/dbactuator/Makefile +++ b/dbm-services/bigdata/db-tools/dbactuator/Makefile @@ -1,9 +1,10 @@ SHELL := /bin/bash BASE_DIR = $(shell pwd) VERSION = 0.0.1 +GITHASH = "" APPNAME = dbactuator GOOS ?= linux -BUILD_FLAG = "-X main.version=${VERSION} -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=`git rev-parse HEAD` " +BUILD_FLAG = "-X main.version=${VERSION} -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=${GITHASH} " .PHONY: all build clean diff --git a/dbm-services/mysql/db-tools/dbactuator/Makefile b/dbm-services/mysql/db-tools/dbactuator/Makefile index f5e0ed8904..346cf0a727 100644 --- a/dbm-services/mysql/db-tools/dbactuator/Makefile +++ b/dbm-services/mysql/db-tools/dbactuator/Makefile @@ -1,11 +1,12 @@ SHELL := /bin/bash BASE_DIR = $(shell pwd) VERSION = 0.0.1 +GITHASH = "" APPNAME = dbactuator GOOS ?= linux -BUILD_FLAG = " -X main.version=${VERSION} -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=`git rev-parse HEAD` " -BUILD_EXTERNAL_FLAG = " -X main.external=ON -X main.version=${VERSION} -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=`git rev-parse HEAD` " -BUILD_MINI_FLAG = " -s -w -X main.version=${VERSION} -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=`git rev-parse HEAD` " +BUILD_FLAG = " -X main.version=${VERSION} -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=${GITHASH} " +BUILD_EXTERNAL_FLAG = " -X main.external=ON -X main.version=${VERSION} -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=${GITHASH} " +BUILD_MINI_FLAG = " -s -w -X main.version=${VERSION} -X main.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=${GITHASH} " .PHONY: all build clean diff --git a/dbm-services/mysql/db-tools/mysql-crond/Makefile b/dbm-services/mysql/db-tools/mysql-crond/Makefile index a9d77f72f6..2893b55541 100644 --- a/dbm-services/mysql/db-tools/mysql-crond/Makefile +++ b/dbm-services/mysql/db-tools/mysql-crond/Makefile @@ -1,10 +1,11 @@ PROJ="mysql-crond" MODULE="dbm-services/mysql/db-tools/mysql-crond" VERSION = $(error please set VERSION flag) +GITHASH = "" #VERSION=$(shell date +'%y%m%d.%H.%M') PKG=${PROJ}.tar.gz OUTPUT_DIR=build -RELEASE_BUILD_FLAG = "-X ${MODULE}/cmd.version=${VERSION} -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash=`git rev-parse HEAD` " +RELEASE_BUILD_FLAG = "-X ${MODULE}/cmd.version=${VERSION} -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash=${GITHASH} " DEV_BUILD_FLAG = "-X ${MODULE}/cmd.version="develop" -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash="" " .PHONY: release-bin diff --git a/dbm-services/mysql/db-tools/mysql-monitor/Makefile b/dbm-services/mysql/db-tools/mysql-monitor/Makefile index 1c1298776d..93824a5211 100644 --- a/dbm-services/mysql/db-tools/mysql-monitor/Makefile +++ b/dbm-services/mysql/db-tools/mysql-monitor/Makefile @@ -1,9 +1,10 @@ PROJ="mysql-monitor" MODULE="dbm-services/mysql/db-tools/mysql-monitor" VERSION = $(error please set VERSION flag) +GITHASH = "" PKG = ${PROJ}.tar.gz OUTPUT_DIR = build -RELEASE_BUILD_FLAG = "-X ${MODULE}/cmd.version=${VERSION} -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash=`git rev-parse HEAD` " +RELEASE_BUILD_FLAG = "-X ${MODULE}/cmd.version=${VERSION} -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash=${GITHASH} " DEV_BUILD_FLAG = "-X ${MODULE}/cmd.version="develop" -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash="" " diff --git a/dbm-services/mysql/db-tools/mysql-rotatebinlog/Makefile b/dbm-services/mysql/db-tools/mysql-rotatebinlog/Makefile index 5bcb0ea909..22053541b0 100644 --- a/dbm-services/mysql/db-tools/mysql-rotatebinlog/Makefile +++ b/dbm-services/mysql/db-tools/mysql-rotatebinlog/Makefile @@ -2,9 +2,10 @@ PROJ="mysql-rotatebinlog" PROJ_BIN="rotatebinlog" MODULE="dbm-services/mysql/db-tools/mysql-rotatebinlog" VERSION = $(error please set VERSION flag) +GITHASH = "" PROJ_PKG = ${PROJ}.tar.gz OUTPUT_DIR = build -RELEASE_BUILD_FLAG = "-X ${MODULE}/cmd.version=${VERSION} -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash=`git rev-parse HEAD` " +RELEASE_BUILD_FLAG = "-X ${MODULE}/cmd.version=${VERSION} -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash=${GITHASH} " BETA_BUILD_FLAG = "-X ${MODULE}/cmd.version="develop" -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash="" " BASE_DIR = $(shell pwd) diff --git a/dbm-services/mysql/db-tools/mysql-table-checksum/Makefile b/dbm-services/mysql/db-tools/mysql-table-checksum/Makefile index 1de5074a03..a05d489038 100644 --- a/dbm-services/mysql/db-tools/mysql-table-checksum/Makefile +++ b/dbm-services/mysql/db-tools/mysql-table-checksum/Makefile @@ -1,9 +1,10 @@ PROJ="mysql-table-checksum" MODULE="dbm-services/mysql/db-tools/mysql-table-checksum" VERSION = $(error please set VERSION flag) +GITHASH = "" PKG="mysql-checksum.tar.gz" # 这是个不太好改的错误了 OUTPUT_DIR=build -RELEASE_BUILD_FLAG = "-X ${MODULE}/cmd.version=${VERSION} -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash=`git rev-parse HEAD` " +RELEASE_BUILD_FLAG = "-X ${MODULE}/cmd.version=${VERSION} -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash=${GITHASH} " DEV_BUILD_FLAG = "-X ${MODULE}/cmd.version="develop" -X ${MODULE}/cmd.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X ${MODULE}/cmd.gitHash="" " .PHONY: release-bin diff --git a/dbm-services/redis/db-tools/dbactuator/Makefile b/dbm-services/redis/db-tools/dbactuator/Makefile index 568a1c226a..daba8db33b 100644 --- a/dbm-services/redis/db-tools/dbactuator/Makefile +++ b/dbm-services/redis/db-tools/dbactuator/Makefile @@ -2,10 +2,11 @@ SHELL := /bin/bash BASE_DIR = $(shell pwd) SRV_NAME=dbactuator_redis VERSION = 0.0.1 +GITHASH = "" PACKAGE_PATH="dbm-services/redis/db-tools/dbactuator/cmd" -BUILD_FLAG = " -X ${PACKAGE_PATH}.version=${VERSION} -X ${PACKAGE_PATH}.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%z'` -X ${PACKAGE_PATH}.githash=`git rev-parse HEAD` " +BUILD_FLAG = " -X ${PACKAGE_PATH}.version=${VERSION} -X ${PACKAGE_PATH}.buildstamp=`date -u '+%Y-%m-%d_%I:%M:%S%z'` -X ${PACKAGE_PATH}.githash=${GITHASH} " build: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags="all=-trimpath=${PWD}" -asmflags="all=-trimpath=${PWD}" -ldflags ${BUILD_FLAG} -o ${BASE_DIR}/build/$(SRV_NAME) -v main.go diff --git a/dbm-ui/backend/db_meta/api/cluster/riak/detail.py b/dbm-ui/backend/db_meta/api/cluster/riak/detail.py new file mode 100644 index 0000000000..7094c319b9 --- /dev/null +++ b/dbm-ui/backend/db_meta/api/cluster/riak/detail.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" + +from django.utils.translation import gettext as _ + +from backend.db_meta.api.cluster.base.graph import Graphic, LineLabel +from backend.db_meta.enums import InstanceRole +from backend.db_meta.models import Cluster + + +def scan_cluster(cluster: Cluster) -> Graphic: + """ + 绘制kafka的拓扑结构图 + """ + graph = Graphic(node_id=Graphic.generate_graphic_id(cluster)) + graph.add_instance_nodes(cluster=cluster, roles=InstanceRole.RIAK_NODE, group_name=_("Riak 节点")) + return graph diff --git a/dbm-ui/backend/db_package/views.py b/dbm-ui/backend/db_package/views.py index 00e8850307..0f51b1e221 100644 --- a/dbm-ui/backend/db_package/views.py +++ b/dbm-ui/backend/db_package/views.py @@ -53,7 +53,7 @@ def create(self, request, *args, **kwargs): @action(methods=["POST"], detail=False, serializer_class=UpdateOrCreateSerializer) def update_or_create(self, request, *args, **kwargs): data = self.params_validate(self.get_serializer_class()) - Package.objects.update_or_create(md5=data["md5"], defaults=data) + Package.objects.update_or_create(md5=data["md5"], db_type=data["db_type"], defaults=data) return Response() @common_swagger_auto_schema( diff --git a/dbm-ui/backend/db_services/bigdata/riak/__init__.py b/dbm-ui/backend/db_services/bigdata/riak/__init__.py new file mode 100644 index 0000000000..aa5085c628 --- /dev/null +++ b/dbm-ui/backend/db_services/bigdata/riak/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" diff --git a/dbm-ui/backend/db_services/bigdata/riak/constants.py b/dbm-ui/backend/db_services/bigdata/riak/constants.py new file mode 100644 index 0000000000..d55ccb2c27 --- /dev/null +++ b/dbm-ui/backend/db_services/bigdata/riak/constants.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" + +RESOURCE_TAG = "db_services/resources/riak" diff --git a/dbm-ui/backend/db_services/bigdata/riak/query.py b/dbm-ui/backend/db_services/bigdata/riak/query.py new file mode 100644 index 0000000000..872e764646 --- /dev/null +++ b/dbm-ui/backend/db_services/bigdata/riak/query.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" + +from django.utils.translation import ugettext_lazy as _ + +from backend.db_meta.api.cluster.riak.detail import scan_cluster +from backend.db_meta.enums import InstanceRole +from backend.db_meta.enums.cluster_type import ClusterType +from backend.db_meta.models import Cluster +from backend.db_services.bigdata.resources.query import BigDataBaseListRetrieveResource + + +class RiakListRetrieveResource(BigDataBaseListRetrieveResource): + + cluster_types = [ClusterType.Riak] + instance_roles = [InstanceRole.RIAK_NODE] + fields = [ + *BigDataBaseListRetrieveResource.fields, + {"name": _("riak节点"), "key": "riak_node"}, + ] + + @classmethod + def get_topo_graph(cls, bk_biz_id: int, cluster_id: int) -> dict: + cluster = Cluster.objects.get(bk_biz_id=bk_biz_id, id=cluster_id) + graph = scan_cluster(cluster).to_dict() + return graph diff --git a/dbm-ui/backend/db_services/bigdata/riak/urls.py b/dbm-ui/backend/db_services/bigdata/riak/urls.py new file mode 100644 index 0000000000..c8c4bc35d0 --- /dev/null +++ b/dbm-ui/backend/db_services/bigdata/riak/urls.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" + +from rest_framework.routers import DefaultRouter + +from backend.db_services.bigdata.riak.views import RiakClusterViewSet + +router = DefaultRouter(trailing_slash=True) +router.register(r"riak_resources", RiakClusterViewSet, basename="riak_resources") + +urlpatterns = router.urls diff --git a/dbm-ui/backend/db_services/bigdata/riak/views.py b/dbm-ui/backend/db_services/bigdata/riak/views.py new file mode 100644 index 0000000000..4cd9740398 --- /dev/null +++ b/dbm-ui/backend/db_services/bigdata/riak/views.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" +from django.utils.decorators import method_decorator +from django.utils.translation import ugettext as _ +from rest_framework import status + +from backend.bk_web.swagger import common_swagger_auto_schema +from backend.db_services.bigdata.kafka import constants +from backend.db_services.bigdata.resources import yasg_slz +from backend.db_services.bigdata.resources.views import ResourceViewSet +from backend.db_services.bigdata.riak.query import RiakListRetrieveResource +from backend.db_services.dbbase.resources import serializers + + +@method_decorator( + name="list", + decorator=common_swagger_auto_schema( + operation_summary=_("获取集群列表"), + query_serializer=serializers.ListResourceSLZ(), + responses={status.HTTP_200_OK: yasg_slz.PaginatedResourceSLZ()}, + tags=[constants.RESOURCE_TAG], + ), +) +@method_decorator( + name="retrieve", + decorator=common_swagger_auto_schema( + operation_summary=_("获取集群详情"), + responses={status.HTTP_200_OK: yasg_slz.ResourceSLZ()}, + tags=[constants.RESOURCE_TAG], + ), +) +@method_decorator( + name="list_instances", + decorator=common_swagger_auto_schema( + operation_summary=_("获取实例列表"), + query_serializer=serializers.ListInstancesSerializer(), + responses={status.HTTP_200_OK: yasg_slz.PaginatedResourceSLZ()}, + tags=[constants.RESOURCE_TAG], + ), +) +@method_decorator( + name="retrieve_instance", + decorator=common_swagger_auto_schema( + operation_summary=_("获取实例详情"), + query_serializer=serializers.RetrieveInstancesSerializer(), + tags=[constants.RESOURCE_TAG], + ), +) +@method_decorator( + name="get_table_fields", + decorator=common_swagger_auto_schema( + operation_summary=_("获取查询返回字段"), + responses={status.HTTP_200_OK: yasg_slz.ResourceFieldSLZ()}, + tags=[constants.RESOURCE_TAG], + ), +) +@method_decorator( + name="get_topo_graph", + decorator=common_swagger_auto_schema( + operation_summary=_("获取集群拓扑"), + responses={status.HTTP_200_OK: yasg_slz.ResourceTopoGraphSLZ()}, + tags=[constants.RESOURCE_TAG], + ), +) +class RiakClusterViewSet(ResourceViewSet): + query_class = RiakListRetrieveResource + query_serializer_class = serializers.ListResourceSLZ diff --git a/dbm-ui/backend/db_services/bigdata/urls.py b/dbm-ui/backend/db_services/bigdata/urls.py index 98b131e4be..2c5301690b 100644 --- a/dbm-ui/backend/db_services/bigdata/urls.py +++ b/dbm-ui/backend/db_services/bigdata/urls.py @@ -17,4 +17,5 @@ path("bizs//kafka/", include("backend.db_services.bigdata.kafka.urls")), path("bizs//pulsar/", include("backend.db_services.bigdata.pulsar.urls")), path("bizs//influxdb/", include("backend.db_services.bigdata.influxdb.urls")), + path("bizs//riak/", include("backend.db_services.bigdata.riak.urls")), ] diff --git a/dbm-ui/backend/dbm_init/medium/Dockerfile b/dbm-ui/backend/dbm_init/medium/Dockerfile index 2f05d9457a..d8068aaa8c 100644 --- a/dbm-ui/backend/dbm_init/medium/Dockerfile +++ b/dbm-ui/backend/dbm_init/medium/Dockerfile @@ -1,7 +1,8 @@ FROM golang:1.21 as go-builder -## 标准化时区 -RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ +## 标准化时区,安装依赖 +RUN set -ex && \ + ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone ## 安装go import工具 @@ -16,40 +17,6 @@ ADD ./dbm-services ./dbm-services RUN set -ex && \ goimports -w . && find . -name go.mod -execdir go mod tidy \; -FROM go-mod-builder as mysql-medium-builder - -## 构建mysql介质 -RUN set -ex && \ - cd /blueking-dbm/dbm-services/mysql/db-tools/dbactuator && make VERSION= -j4 && \ - cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-dbbackup && sh build.sh -t txsql && \ - cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-table-checksum && make release-bin VERSION= -j4 && \ - cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-crond && make release-bin VERSION= -j4 && \ - cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-rotatebinlog && make release VERSION= -j4 && \ - cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-monitor && make release-bin VERSION= -j4 - - -FROM go-mod-builder as redis-medium-builder - -## 构建redis介质 -RUN set -ex && \ - cd /blueking-dbm/dbm-services/redis/db-tools/dbactuator && make VERSION= -j4 && \ - cd /blueking-dbm/dbm-services/redis/db-tools/dbmon && bash package.sh - - -FROM go-mod-builder as bigdata-medium-builder - -## 构建大数据介质 -RUN set -ex && \ - cd /blueking-dbm/dbm-services/bigdata/db-tools/dbactuator && make VERSION= -j4 - - -FROM go-builder as medium-builder - -WORKDIR /blueking-dbm -COPY --from=mysql-medium-builder /blueking-dbm/dbm-services/mysql ./dbm-services/mysql -COPY --from=redis-medium-builder /blueking-dbm/dbm-services/redis ./dbm-services/redis -COPY --from=bigdata-medium-builder /blueking-dbm/dbm-services/bigdata ./dbm-services/bigdata - FROM python:3.6.12-slim-buster AS base @@ -76,7 +43,7 @@ RUN set -ex && \ RUN set -ex && mkdir ~/.pip && printf '[global]\nindex-url = https://mirrors.tencent.com/pypi/simple/' > ~/.pip/pip.conf -FROM base AS builder +FROM base AS python-builder WORKDIR / @@ -108,10 +75,7 @@ WORKDIR /app USER root ## 拷贝虚拟环境 -COPY --from=builder /venv /venv - -## 拷贝第一阶段的文件,构建制品 -COPY --from=medium-builder /blueking-dbm /blueking-dbm +COPY --from=python-builder /venv /venv ## 拷贝脚本文件 ADD ./dbm-ui/backend/dbm_init/medium/ ./ @@ -124,25 +88,91 @@ ARG GITHUB_TOKEN='' ARG GITHUB_USERNAME='' ARG GITHUB_USER_EMAIL='' -## 将相关制品移动到指定目录,提交medicum.lock文件 +##更新并提交medicum.lock文件 RUN set -ex && \ # 克隆线上的dbm仓库 git config --global user.email ${GITHUB_USER_EMAIL} && \ git config --global user.name ${GITHUB_USERNAME} && \ git clone https://${GITHUB_TOKEN}@github.com/TencentBlueKing/blueking-dbm.git && \ - # 注意:这里需要将.git文件复制给前面构建文件夹,用作判断commit是否需要更新 - cp -r blueking-dbm/.git /blueking-dbm && \ - python main.py --type build && \ - rm -rf /blueking-dbm && \ + # 将clone的blueking-dbm转移到跟目录操作 + mv blueking-dbm/ / && cd /blueking-dbm && git checkout -f ${MEDIUM_BUILDER_BRANCH} && \ + # 更新lock文件 + cd /app && python main.py --type update_lock && \ # 将更新后的medium.lock文件放到clone的dbm仓库 - cd blueking-dbm/ && \ - git checkout -f ${MEDIUM_BUILDER_BRANCH} && \ - cp ../medium.lock ${MEDIUM_PATH} && \ + cp medium.lock /blueking-dbm/${MEDIUM_PATH} && \ # 判断有diff才提pr,否则会非正常结束。注意这里也需要删除.git - git add ${MEDIUM_PATH}/medium.lock && \ - git diff-index --quiet HEAD && rm -rf /app/blueking-dbm || \ + cd /blueking-dbm && git add ${MEDIUM_PATH}/medium.lock && \ + git diff-index --quiet HEAD && rm -rf /blueking-dbm || \ ( \ git commit -m "minor: [$(date +"%Y-%m-%d %H:%M:%S")]update medium.lock" && \ git push --set-upstream --force origin ${MEDIUM_BUILDER_BRANCH}:medicum_lock_${MEDIUM_BUILDER_BRANCH} && \ - rm -rf /app/blueking-dbm \ + rm -rf /blueking-dbm \ ) + + +FROM go-mod-builder as medium-builder + +WORKDIR / +## 安装jq依赖 +RUN set -ex && \ + apt-get update && apt-get install -y --no-install-recommends wget && \ + wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 && \ + chmod a+x /usr/local/bin/yq && \ + rm -rf /var/lib/apt/lists/* + +## 保存jq的脚本用于下一阶段用 +RUN set -ex && \ + echo 'yq e ".${1}[].${2} | .${3}" /medium.lock | grep -v null' >> lock.sh && \ + chmod 777 lock.sh + +## 获取上一阶段的lock文件 +COPY --from=base-app /app/medium.lock / + + +FROM medium-builder as mysql-medium-builder + +WORKDIR / +## 构建mysql介质 +RUN set -ex && \ + cd /blueking-dbm/dbm-services/mysql/db-tools/dbactuator && \ + make VERSION=$(/lock.sh mysql actuator version) GITHASH=$(/lock.sh mysql actuator commitId) -j4 && \ + cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-dbbackup && \ + sh build.sh -t txsql && \ + cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-table-checksum && \ + make release-bin VERSION=$(/lock.sh mysql mysql-checksum version) GITHASH=$(/lock.sh mysql mysql-checksum commitId) -j4 && \ + cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-crond && \ + make release-bin VERSION=$(/lock.sh mysql mysql-crond version) GITHASH=$(/lock.sh mysql mysql-crond commitId) -j4 && \ + cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-rotatebinlog && \ + make release VERSION=$(/lock.sh mysql rotate-binlog version) GITHASH=$(/lock.sh mysql rotate-binlog commitId) -j4 && \ + cd /blueking-dbm/dbm-services/mysql/db-tools/mysql-monitor && \ + make release-bin VERSION=$(/lock.sh mysql mysql-monitor version) GITHASH=$(/lock.sh mysql mysql-monitor commitId) -j4 + + +FROM medium-builder as redis-medium-builder + +## 构建redis介质 +RUN set -ex && \ + cd /blueking-dbm/dbm-services/redis/db-tools/dbactuator && \ + make VERSION=$(/lock.sh redis actuator version) GITHASH=$(/lock.sh redis actuator commitId) -j4 && \ + cd /blueking-dbm/dbm-services/redis/db-tools/dbmon && \ + bash package.sh + + +FROM medium-builder as bigdata-medium-builder + +## 构建大数据介质 +RUN set -ex && \ + cd /blueking-dbm/dbm-services/bigdata/db-tools/dbactuator && \ + make VERSION=$(/lock.sh es actuator version) GITHASH=$(/lock.sh es actuator commitId) -j4 + + +FROM base-app as medium-app + +WORKDIR /app + +COPY --from=mysql-medium-builder /blueking-dbm/dbm-services/mysql /blueking-dbm/dbm-services/mysql +COPY --from=redis-medium-builder /blueking-dbm/dbm-services/redis /blueking-dbm/dbm-services/redis +COPY --from=bigdata-medium-builder /blueking-dbm/dbm-services/bigdata /blueking-dbm/dbm-services/bigdata + +RUN set -ex && \ + python main.py --type build && rm -rf /blueking-dbm diff --git a/dbm-ui/backend/dbm_init/medium/handlers.py b/dbm-ui/backend/dbm_init/medium/handlers.py index 78a6443da8..946db7e2c6 100644 --- a/dbm-ui/backend/dbm_init/medium/handlers.py +++ b/dbm-ui/backend/dbm_init/medium/handlers.py @@ -188,8 +188,8 @@ def sync_from_bkrepo(self, db_type): http.post(url="apis/packages/update_or_create/", data=package_params) @classmethod - def build_medium(cls, bkrepo_tmp_dir): - """同步构建好的介质,并更新.lock文件""" + def update_lock(cls, bkrepo_tmp_dir): + """更新.lock文件""" def add_version(version): # TODO: 这里版本号叠加规则是怎样?默认只是小版本+1 @@ -220,6 +220,20 @@ def add_version(version): medium_info["version"] = add_version(medium_info["version"]) medium_info["commitId"] = dir_commit + # 更新lock文件 + with open(medium_lock_path, "w") as lock_file: + lock_file.write(yaml.safe_dump(lock_info)) + + @classmethod + def build_medium(cls, bkrepo_tmp_dir): + # 加载lock文件,获取介质的版本信息 + medium_lock_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "medium.lock") + with open(medium_lock_path, "r") as lock_file: + lock_info = yaml.safe_load(lock_file) + + for db_type, mediums in lock_info.items(): + for medium in mediums: + for medium_type, medium_info in medium.items(): # 将编译好的介质复制到指定目录 target_medium_path = f"{bkrepo_tmp_dir}/{db_type}/{medium_type}/{medium_info['version']}" result = subprocess.run( @@ -230,7 +244,3 @@ def add_version(version): ) if result.returncode: logger.error("Error: move medium fail! message: %s", result.stderr) - - # 更新lock文件 - with open(medium_lock_path, "w") as lock_file: - lock_file.write(yaml.safe_dump(lock_info)) diff --git a/dbm-ui/backend/dbm_init/medium/main.py b/dbm-ui/backend/dbm_init/medium/main.py index 59a093d7fe..9139cac550 100644 --- a/dbm-ui/backend/dbm_init/medium/main.py +++ b/dbm-ui/backend/dbm_init/medium/main.py @@ -31,7 +31,9 @@ """版本镜像脚本执行入口""" path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "medium") - if args.type == "build": + if args.type == "update_lock": + MediumHandler.update_lock(bkrepo_tmp_dir=path) + elif args.type == "build": MediumHandler.build_medium(bkrepo_tmp_dir=path) elif args.type == "upload": MediumHandler().upload_medium(path=args.db, bkrepo_tmp_dir=path) diff --git a/dbm-ui/backend/flow/plugins/components/collections/riak/get_riak_resource.py b/dbm-ui/backend/flow/plugins/components/collections/riak/get_riak_resource.py index 4718cd4c16..4e16255494 100644 --- a/dbm-ui/backend/flow/plugins/components/collections/riak/get_riak_resource.py +++ b/dbm-ui/backend/flow/plugins/components/collections/riak/get_riak_resource.py @@ -30,22 +30,19 @@ def _execute(self, data, parent_data) -> bool: global_data = data.get_one_of_inputs("global_data") trans_data = data.get_one_of_inputs("trans_data") - if global_data["ip_source"] == "manual_input": - ips = [node["ip"] for node in global_data["nodes"]] - if global_data["ticket_type"] == TicketType.RIAK_CLUSTER_APPLY and len(ips) >= 3: - trans_data.nodes = ips - trans_data.base_node = ips[0] - trans_data.operate_nodes = ips[1:] - elif ( - global_data["ticket_type"] == TicketType.RIAK_CLUSTER_SCALE_OUT - or global_data["ticket_type"] == TicketType.RIAK_CLUSTER_SCALE_IN - ) and len(ips) >= 1: - trans_data.operate_nodes = ips - else: - self.log_error(_("获取机器资源失败,新建集群至少选择3台机器,扩容或缩容至少选择1台机器")) - return False - elif self.data["ip_source"] == "resource_pool": - pass + ips = [node["ip"] for node in global_data["nodes"]] + if global_data["ticket_type"] == TicketType.RIAK_CLUSTER_APPLY and len(ips) >= 3: + trans_data.nodes = ips + trans_data.base_node = ips[0] + trans_data.operate_nodes = ips[1:] + elif ( + global_data["ticket_type"] == TicketType.RIAK_CLUSTER_SCALE_OUT + or global_data["ticket_type"] == TicketType.RIAK_CLUSTER_SCALE_IN + ) and len(ips) >= 1: + trans_data.operate_nodes = ips + else: + self.log_error(_("获取机器资源失败,新建集群至少选择3台机器,扩容或缩容至少选择1台机器")) + return False self.log_info(_("获取机器资源成功。 {}").format(trans_data)) data.outputs["trans_data"] = trans_data diff --git a/dbm-ui/backend/ticket/builders/mysql/base.py b/dbm-ui/backend/ticket/builders/mysql/base.py index 6c12e71cf7..cdfd91e7bb 100644 --- a/dbm-ui/backend/ticket/builders/mysql/base.py +++ b/dbm-ui/backend/ticket/builders/mysql/base.py @@ -97,7 +97,7 @@ def validate_cluster_can_access(self, attrs): for status_flag, whitelist in self.unavailable_whitelist__status_flag.items(): if cluster.status_flag & status_flag and ticket_type not in whitelist: raise serializers.ValidationError( - _("高可用实例状态异常:{},暂时无法执行该单据类型:{}").format(status_flag.flag_text(), ticket_type) + _("集群实例状态异常:{},暂时无法执行该单据类型:{}").format(status_flag.flag_text(), ticket_type) ) return attrs diff --git a/dbm-ui/backend/ticket/builders/riak/base.py b/dbm-ui/backend/ticket/builders/riak/base.py index 50d0c24ec2..3995546bdf 100644 --- a/dbm-ui/backend/ticket/builders/riak/base.py +++ b/dbm-ui/backend/ticket/builders/riak/base.py @@ -12,6 +12,9 @@ from backend.configuration.constants import DBType from backend.ticket.builders import TicketFlowBuilder +# 默认riak的版本为2.2 +RIAK_VERSION = "2.2" + class BaseRiakTicketFlowBuilder(TicketFlowBuilder): group = DBType.Riak.value diff --git a/dbm-ui/backend/ticket/builders/riak/riak_apply.py b/dbm-ui/backend/ticket/builders/riak/riak_apply.py index 5e94592614..eaeb425353 100644 --- a/dbm-ui/backend/ticket/builders/riak/riak_apply.py +++ b/dbm-ui/backend/ticket/builders/riak/riak_apply.py @@ -18,7 +18,7 @@ from backend.flow.engine.controller.riak import RiakController from backend.ticket import builders from backend.ticket.builders.common.base import CommonValidate -from backend.ticket.builders.riak.base import BaseRiakTicketFlowBuilder +from backend.ticket.builders.riak.base import RIAK_VERSION, BaseRiakTicketFlowBuilder from backend.ticket.constants import TicketType @@ -34,7 +34,7 @@ class RiakApplyDetailSerializer(serializers.Serializer): ip_source = serializers.ChoiceField( help_text=_("主机来源"), choices=IpSource.get_choices(), default=IpSource.RESOURCE_POOL.value ) - db_version = serializers.CharField(help_text=_("riak数据库版本")) + db_version = serializers.CharField(help_text=_("riak数据库版本"), required=False, default=RIAK_VERSION) resource_spec = serializers.JSONField(help_text=_("部署规格")) # display fields @@ -88,8 +88,6 @@ def patch_ticket_detail(self): details = self.ticket.details db_module_name = DBModule.objects.get(db_module_id=details["db_module_id"]).db_module_name riak_cluster_name = riak_domain = f"{details['cluster_name']}.{db_module_name}" - - # TODO: 可能需要补充version等信息 details.update( db_module_name=db_module_name, cluster_name=riak_cluster_name, diff --git a/dbm-ui/backend/ticket/builders/riak/riak_shrink.py b/dbm-ui/backend/ticket/builders/riak/riak_shrink.py index 0492dddcfe..7b56e57e35 100644 --- a/dbm-ui/backend/ticket/builders/riak/riak_shrink.py +++ b/dbm-ui/backend/ticket/builders/riak/riak_shrink.py @@ -38,7 +38,7 @@ def format_ticket_data(self): self.ticket_data["bk_cloud_id"] = cluster.bk_cloud_id -@builders.BuilderFactory.register(TicketType.RIAK_CLUSTER_SCALE_IN, phase=ClusterPhase.OFFLINE) +@builders.BuilderFactory.register(TicketType.RIAK_CLUSTER_SCALE_IN) class RiakShrinkFlowBuilder(BaseRiakTicketFlowBuilder): serializer = RiakShrinkDetailSerializer inner_flow_builder = RiakShrinkFlowParamBuilder diff --git a/dbm-ui/backend/ticket/exclusive_ticket.xlsx b/dbm-ui/backend/ticket/exclusive_ticket.xlsx index 4bd66fb73474885ee87e8d9c75dd32eeb0d472bb..7126df32874c7e4a7cd5972dd6e933bc96e2eda4 100644 GIT binary patch literal 28977 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 literal 26671 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 diff --git a/helm-charts/bk-dbm/Chart.lock b/helm-charts/bk-dbm/Chart.lock index 3edc47e208..a255e2baaa 100644 --- a/helm-charts/bk-dbm/Chart.lock +++ b/helm-charts/bk-dbm/Chart.lock @@ -4,7 +4,7 @@ dependencies: version: 1.13.0 - name: mysql repository: https://charts.bitnami.com/bitnami - version: 9.14.1 + version: 9.14.2 - name: redis repository: https://charts.bitnami.com/bitnami version: 16.13.2 @@ -56,5 +56,5 @@ dependencies: - name: backup-consumer repository: file://charts/backup-consumer version: 0.0.3 -digest: sha256:2980ed56f192ffd9fa531dc1668522eefacd827580a900509ba0e4a78a826946 -generated: "2023-11-01T15:09:09.075761+08:00" +digest: sha256:6a298ec313dd81bf8304ff4851852594333711addfc65f44aff1aeda34c7ed24 +generated: "2023-11-06T21:45:38.599672+08:00"