From 5ba5ebb2d1b1efaf0a2cf5c7d2975fe306672ac3 Mon Sep 17 00:00:00 2001 From: lannoy0523 <46735290+lannoy0523@users.noreply.github.com> Date: Sun, 18 Feb 2024 11:17:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=90=8E=E5=8F=B0admin=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E7=BC=93=E5=AD=98=E6=97=B6?= =?UTF-8?q?=E9=97=B4=EF=BC=8C=E8=B7=AF=E5=BE=84=EF=BC=8C=E5=90=8E=E7=BC=80?= =?UTF-8?q?=20#1587?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 * feat:后台admin支持配置文件缓存时间,路径,后缀 #1587 --- .../common/common-api/build.gradle.kts | 1 + .../api/serializer/DataSizeSerializer.kt | 45 +++ .../bkrepo/common/api/util/JsonUtils.kt | 7 +- .../file/BasedRepositoryFileExpireResolver.kt | 84 ++++-- .../batch/file/ExpireFileResolverConfig.kt | 3 + .../controller/user/FileCacheController.kt | 145 ++++++++++ .../bkrepo/job/pojo/FileCacheCheckRequest.kt | 36 +++ .../bkrepo/job/pojo/FileCacheRequest.kt | 39 +++ .../com/tencent/bkrepo/job/pojo/TFileCache.kt | 52 ++++ .../job/repository/FileCacheRepository.kt | 44 +++ .../bkrepo/job/service/FileCacheService.kt | 46 ++++ .../job/service/impl/FileCacheServiceImp.kt | 87 ++++++ .../bkrepo/opdata/pojo/config/ConfigItem.kt | 6 +- .../opdata/pojo/config/GetConfigRequest.kt | 12 + .../opdata/config/client/ConfigClient.kt | 2 + .../client/consul/ConsulConfigClient.kt | 44 +++ .../opdata/controller/ConfigController.kt | 15 + src/frontend/devops-op/src/api/config.js | 12 + src/frontend/devops-op/src/api/fileCache.js | 40 +++ src/frontend/devops-op/src/router/index.js | 7 + src/frontend/devops-op/src/utils/file.js | 25 ++ .../devops-op/src/views/node/FileCache.vue | 256 ++++++++++++++++++ .../CreateOrUpdateFileCacheDialog.vue | 238 ++++++++++++++++ 23 files changed, 1223 insertions(+), 23 deletions(-) create mode 100644 src/backend/common/common-api/src/main/kotlin/com/tencent/bkrepo/common/api/serializer/DataSizeSerializer.kt create mode 100644 src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/controller/user/FileCacheController.kt create mode 100644 src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/FileCacheCheckRequest.kt create mode 100644 src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/FileCacheRequest.kt create mode 100644 src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/TFileCache.kt create mode 100644 src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/repository/FileCacheRepository.kt create mode 100644 src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/service/FileCacheService.kt create mode 100644 src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/service/impl/FileCacheServiceImp.kt create mode 100644 src/backend/opdata/api-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/pojo/config/GetConfigRequest.kt create mode 100644 src/frontend/devops-op/src/api/fileCache.js create mode 100644 src/frontend/devops-op/src/views/node/FileCache.vue create mode 100644 src/frontend/devops-op/src/views/node/components/CreateOrUpdateFileCacheDialog.vue diff --git a/src/backend/common/common-api/build.gradle.kts b/src/backend/common/common-api/build.gradle.kts index 31f47ab4d6..6efd36aa42 100644 --- a/src/backend/common/common-api/build.gradle.kts +++ b/src/backend/common/common-api/build.gradle.kts @@ -40,4 +40,5 @@ dependencies { api("com.fasterxml.jackson.module:jackson-module-parameter-names") api("org.apache.commons:commons-compress") api("com.google.guava:guava") + api("org.springframework.boot:spring-boot-starter-test") } diff --git a/src/backend/common/common-api/src/main/kotlin/com/tencent/bkrepo/common/api/serializer/DataSizeSerializer.kt b/src/backend/common/common-api/src/main/kotlin/com/tencent/bkrepo/common/api/serializer/DataSizeSerializer.kt new file mode 100644 index 0000000000..3844cb4aca --- /dev/null +++ b/src/backend/common/common-api/src/main/kotlin/com/tencent/bkrepo/common/api/serializer/DataSizeSerializer.kt @@ -0,0 +1,45 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.tencent.bkrepo.common.api.serializer + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.ser.std.StdSerializer +import org.springframework.util.unit.DataSize + +class DataSizeSerializer : StdSerializer(DataSize::class.java) { + override fun serialize(value: DataSize?, gen: JsonGenerator?, provider: SerializerProvider?) { + if (gen != null && value != null) { + gen.writeString(value.toMegabytes().toString() + "MB") + } + } +} diff --git a/src/backend/common/common-api/src/main/kotlin/com/tencent/bkrepo/common/api/util/JsonUtils.kt b/src/backend/common/common-api/src/main/kotlin/com/tencent/bkrepo/common/api/util/JsonUtils.kt index 77932159cb..da20b8ee38 100644 --- a/src/backend/common/common-api/src/main/kotlin/com/tencent/bkrepo/common/api/util/JsonUtils.kt +++ b/src/backend/common/common-api/src/main/kotlin/com/tencent/bkrepo/common/api/util/JsonUtils.kt @@ -33,6 +33,7 @@ package com.tencent.bkrepo.common.api.util import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.SerializationFeature +import com.fasterxml.jackson.databind.module.SimpleModule import com.fasterxml.jackson.datatype.jdk8.Jdk8Module import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer @@ -44,6 +45,8 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.fasterxml.jackson.module.paramnames.ParameterNamesModule +import com.tencent.bkrepo.common.api.serializer.DataSizeSerializer +import org.springframework.util.unit.DataSize import java.io.InputStream import java.time.LocalDate import java.time.LocalDateTime @@ -68,7 +71,9 @@ object JsonUtils { registerModule(javaTimeModule) registerModule(ParameterNamesModule()) registerModule(Jdk8Module()) - + var dateSizeModule = SimpleModule() + dateSizeModule.addSerializer(DataSize::class.java, DataSizeSerializer()) + registerModule(dateSizeModule) enable(SerializationFeature.INDENT_OUTPUT) disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/batch/file/BasedRepositoryFileExpireResolver.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/batch/file/BasedRepositoryFileExpireResolver.kt index e1e03b2a77..557663c792 100644 --- a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/batch/file/BasedRepositoryFileExpireResolver.kt +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/batch/file/BasedRepositoryFileExpireResolver.kt @@ -1,17 +1,22 @@ package com.tencent.bkrepo.job.batch.file +import com.tencent.bkrepo.common.api.pojo.Page +import com.tencent.bkrepo.common.api.pojo.Response import com.tencent.bkrepo.common.query.enums.OperationType import com.tencent.bkrepo.common.query.model.Rule import com.tencent.bkrepo.common.storage.filesystem.cleanup.FileExpireResolver import com.tencent.bkrepo.job.FULL_PATH import com.tencent.bkrepo.job.LAST_ACCESS_DATE import com.tencent.bkrepo.job.SHA256 +import com.tencent.bkrepo.job.pojo.TFileCache +import com.tencent.bkrepo.job.service.FileCacheService import com.tencent.bkrepo.repository.api.NodeClient import com.tencent.bkrepo.repository.pojo.search.NodeQueryBuilder -import java.io.File -import java.time.LocalDateTime import org.slf4j.LoggerFactory import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler +import org.springframework.util.unit.DataSize +import java.io.File +import java.time.LocalDateTime /** * 基于仓库配置判断文件是否过期 @@ -20,6 +25,7 @@ class BasedRepositoryFileExpireResolver( private val nodeClient: NodeClient, private val expireConfig: RepositoryExpireConfig, taskScheduler: ThreadPoolTaskScheduler, + private val fileCacheService: FileCacheService, ) : FileExpireResolver { private var retainNodes = mutableSetOf() @@ -34,35 +40,71 @@ class BasedRepositoryFileExpireResolver( private fun refreshRetainNode() { logger.info("Refresh retain nodes.") - val newRetainNodes = mutableSetOf() - expireConfig.repos.forEach { - // for each repo + retainNodes.clear() + getNodeFromConfig() + getNodeFromDataBase() + } + + private fun getNodeFromConfig() { + var temp = mutableSetOf() + expireConfig.repos.map{ convertRepoConfigToFileCache(it) }.forEach { val projectId = it.projectId val repoName = it.repoName - - val queryModel = NodeQueryBuilder() - .projectId(it.projectId) - .repoName(it.repoName) - .excludeFolder() - .size(expireConfig.size.toBytes(), OperationType.GT) - .rule(LAST_ACCESS_DATE, LocalDateTime.now().minusDays(it.days.toLong()), OperationType.AFTER) - .page(1, expireConfig.max) - .select(SHA256, FULL_PATH).build() - val fullPathRuleList = it.pathPrefix.map { prefix -> - Rule.QueryRule(FULL_PATH, prefix, OperationType.PREFIX) + val pages = getNodes(it) + pages.data?.records?.forEach { ret -> + // 获取每个的sha256 + val sha256 = ret[SHA256].toString() + val fullPath = ret[FULL_PATH].toString() + temp.add(sha256) + logger.info("Retain node $projectId/$repoName$fullPath, $sha256.") } - val rule = Rule.NestedRule(fullPathRuleList.toMutableList(), Rule.NestedRule.RelationType.OR) - (queryModel.rule as Rule.NestedRule).rules.add(rule) - val pages = nodeClient.queryWithoutCount(queryModel) + } + retainNodes.addAll(temp) + } + + private fun getNodeFromDataBase() { + var temp = mutableSetOf() + fileCacheService.list().forEach { + val projectId = it.projectId + val repoName = it.repoName + val pages = getNodes(it) pages.data?.records?.forEach { ret -> // 获取每个的sha256 val sha256 = ret[SHA256].toString() val fullPath = ret[FULL_PATH].toString() - newRetainNodes.add(sha256) + temp.add(sha256) logger.info("Retain node $projectId/$repoName$fullPath, $sha256.") } } - retainNodes = newRetainNodes + retainNodes.addAll(temp) + } + + private fun convertRepoConfigToFileCache(repoConfig: RepoConfig):TFileCache { + return TFileCache( + id = null, + projectId = repoConfig.projectId, + repoName = repoConfig.repoName, + pathPrefix = repoConfig.pathPrefix, + days = repoConfig.days, + size = expireConfig.size.toMegabytes() + ) + } + + private fun getNodes(tFileCache: TFileCache): Response>> { + val queryModel = NodeQueryBuilder() + .projectId(tFileCache.projectId) + .repoName(tFileCache.repoName) + .excludeFolder() + .size(DataSize.ofMegabytes(tFileCache.size).toBytes(), OperationType.GT) + .rule(LAST_ACCESS_DATE, LocalDateTime.now().minusDays(tFileCache.days.toLong()), OperationType.AFTER) + .page(1, expireConfig.max) + .select(SHA256, FULL_PATH).build() + val fullPathRuleList = tFileCache.pathPrefix.map { prefix -> + Rule.QueryRule(FULL_PATH, prefix, OperationType.PREFIX) + } + val rule = Rule.NestedRule(fullPathRuleList.toMutableList(), Rule.NestedRule.RelationType.OR) + (queryModel.rule as Rule.NestedRule).rules.add(rule) + return nodeClient.queryWithoutCount(queryModel) } companion object { diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/batch/file/ExpireFileResolverConfig.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/batch/file/ExpireFileResolverConfig.kt index 56d6e675f5..c45a14d51d 100644 --- a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/batch/file/ExpireFileResolverConfig.kt +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/batch/file/ExpireFileResolverConfig.kt @@ -2,6 +2,7 @@ package com.tencent.bkrepo.job.batch.file import com.tencent.bkrepo.common.storage.filesystem.cleanup.FileExpireResolver import com.tencent.bkrepo.job.config.properties.ExpiredCacheFileCleanupJobProperties +import com.tencent.bkrepo.job.service.FileCacheService import com.tencent.bkrepo.repository.api.NodeClient import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean @@ -20,11 +21,13 @@ class ExpireFileResolverConfig { fun fileExpireResolver( expiredCacheFileCleanupJobProperties: ExpiredCacheFileCleanupJobProperties, scheduler: ThreadPoolTaskScheduler, + fileCacheService: FileCacheService ): FileExpireResolver { return BasedRepositoryFileExpireResolver( nodeClient, expiredCacheFileCleanupJobProperties.repoConfig, scheduler, + fileCacheService ) } } diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/controller/user/FileCacheController.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/controller/user/FileCacheController.kt new file mode 100644 index 0000000000..69eebd3867 --- /dev/null +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/controller/user/FileCacheController.kt @@ -0,0 +1,145 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.bkrepo.job.controller.user + +import com.tencent.bkrepo.common.api.constant.HttpStatus +import com.tencent.bkrepo.common.api.pojo.Response +import com.tencent.bkrepo.common.api.util.toJsonString +import com.tencent.bkrepo.common.security.permission.Principal +import com.tencent.bkrepo.common.security.permission.PrincipalType +import com.tencent.bkrepo.common.service.util.ResponseBuilder +import com.tencent.bkrepo.job.config.properties.ExpiredCacheFileCleanupJobProperties +import com.tencent.bkrepo.job.pojo.FileCacheCheckRequest +import com.tencent.bkrepo.job.pojo.FileCacheRequest +import com.tencent.bkrepo.job.pojo.TFileCache +import com.tencent.bkrepo.job.service.FileCacheService +import org.springframework.web.bind.annotation.DeleteMapping +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/api/cache") +@Principal(PrincipalType.ADMIN) +class FileCacheController( + val fileCacheService: FileCacheService, + val properties: ExpiredCacheFileCleanupJobProperties, +) { + + @GetMapping("/list") + fun list(): Response> { + return ResponseBuilder.success(fileCacheService.list()) + } + + @PostMapping("/update") + fun update(@RequestBody request:FileCacheRequest):Response { + request.id?.let { + var checkStatus = updateCheck(request) + if (checkStatus.status) { + return ResponseBuilder.success() + } else { + return ResponseBuilder.fail(HttpStatus.BAD_REQUEST.value, checkStatus.msg) + } + } ?: let { + return ResponseBuilder.fail(HttpStatus.BAD_REQUEST.value, "id is null") + } + } + + fun updateCheck(request: FileCacheRequest):CheckStatus { + fileCacheService.getById(request.id!!)?.let { + var fileCacheCheckRequest = FileCacheCheckRequest( + projectId = request.projectId, + repoName = request.repoName, + days = request.days, + size = request.size + ) + fileCacheService.checkExist(fileCacheCheckRequest)?.let { + if( it.id != request.id) { + var checkStatus = CheckStatus( + status = false, + msg = "has same config" + ) + return checkStatus + } + } + fileCacheService.update(request) + var checkStatus = CheckStatus( + status = true, + msg = "" + ) + return checkStatus + } + var checkStatus = CheckStatus( + status = false, + msg = "id not existed" + ) + return checkStatus + } + + // 新增 + @PostMapping("/create") + fun create(@RequestBody request:FileCacheRequest):Response { + var fileCacheCheckRequest = FileCacheCheckRequest( + repoName = request.repoName, + projectId = request.projectId, + days = request.days, + size = request.size + ) + fileCacheService.checkExist(fileCacheCheckRequest)?.let { + return ResponseBuilder.fail(HttpStatus.BAD_REQUEST.value, "has same config") + } + fileCacheService.create(request) + return ResponseBuilder.success() + } + + // 删除 + @DeleteMapping("/delete/{id}") + fun delete(@PathVariable id:String): Response { + fileCacheService.getById(id)?.let { + fileCacheService.delete(id) + return ResponseBuilder.success() + } + return ResponseBuilder.fail(HttpStatus.BAD_REQUEST.value, "id not existed") + } + + // 获取配置中的属性 + @GetMapping("/config") + fun getConfig(): Response { + var config = properties + return ResponseBuilder.success(config.toJsonString()) + } + +} + +data class CheckStatus( + val status: Boolean, + val msg: String +) \ No newline at end of file diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/FileCacheCheckRequest.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/FileCacheCheckRequest.kt new file mode 100644 index 0000000000..dfa407a14c --- /dev/null +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/FileCacheCheckRequest.kt @@ -0,0 +1,36 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.bkrepo.job.pojo + +data class FileCacheCheckRequest( + var projectId: String, + var repoName: String, + // 保留最近多少天内访问 + var days: Int, + var size: Long, +) diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/FileCacheRequest.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/FileCacheRequest.kt new file mode 100644 index 0000000000..a47007c994 --- /dev/null +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/FileCacheRequest.kt @@ -0,0 +1,39 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.bkrepo.job.pojo + +data class FileCacheRequest( + var id: String?, + var projectId: String = "", + var repoName: String = "", + // 路径前缀匹配 + var pathPrefix: List = emptyList(), + // 保留最近多少天内访问 + var days: Int = 30, + var size: Long = 10, +) diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/TFileCache.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/TFileCache.kt new file mode 100644 index 0000000000..e3598cd9c3 --- /dev/null +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/pojo/TFileCache.kt @@ -0,0 +1,52 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.bkrepo.job.pojo + +import org.springframework.data.mongodb.core.index.CompoundIndex +import org.springframework.data.mongodb.core.index.CompoundIndexes +import org.springframework.data.mongodb.core.mapping.Document + +@Document(collection = "file_cache") +@CompoundIndexes( + CompoundIndex( + name = "file_cache_idx", + def = "{'projectId': 1,'repoName': 1, 'days': 1, 'size': 1}", + background = true, + unique = true + ) +) +data class TFileCache( + var id: String?, + var projectId: String, + var repoName: String, + // 路径前缀匹配 + var pathPrefix: List = emptyList(), + // 保留最近多少天内访问 + var days: Int = 30, + var size: Long = 10 +) diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/repository/FileCacheRepository.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/repository/FileCacheRepository.kt new file mode 100644 index 0000000000..cff65d76ea --- /dev/null +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/repository/FileCacheRepository.kt @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.tencent.bkrepo.job.repository + +import com.tencent.bkrepo.job.pojo.TFileCache +import org.springframework.data.mongodb.repository.MongoRepository +import org.springframework.stereotype.Repository + +@Repository +interface FileCacheRepository : MongoRepository { + fun findAllBy(): List + + fun findByRepoNameAndProjectIdAndDaysAndSize( + repoName: String, projectId: String,days: Int, size: Long ): TFileCache? +} diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/service/FileCacheService.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/service/FileCacheService.kt new file mode 100644 index 0000000000..75daf2b0e1 --- /dev/null +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/service/FileCacheService.kt @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.bkrepo.job.service + +import com.tencent.bkrepo.job.pojo.FileCacheCheckRequest +import com.tencent.bkrepo.job.pojo.FileCacheRequest +import com.tencent.bkrepo.job.pojo.TFileCache + +interface FileCacheService { + fun list(): List + + fun create(fileCacheRequest: FileCacheRequest) + + fun delete(id: String) + + fun getById(id: String): TFileCache? + + fun checkExist(request: FileCacheCheckRequest): TFileCache? + + fun update(fileCacheRequest: FileCacheRequest) +} diff --git a/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/service/impl/FileCacheServiceImp.kt b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/service/impl/FileCacheServiceImp.kt new file mode 100644 index 0000000000..bda8090f33 --- /dev/null +++ b/src/backend/job/biz-job/src/main/kotlin/com/tencent/bkrepo/job/service/impl/FileCacheServiceImp.kt @@ -0,0 +1,87 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.bkrepo.job.service.impl + +import com.tencent.bkrepo.job.pojo.FileCacheCheckRequest +import com.tencent.bkrepo.job.pojo.FileCacheRequest +import com.tencent.bkrepo.job.pojo.TFileCache +import com.tencent.bkrepo.job.repository.FileCacheRepository +import com.tencent.bkrepo.job.service.FileCacheService +import org.springframework.stereotype.Service + +@Service +class FileCacheServiceImp constructor( + private val fileCacheRepository: FileCacheRepository +) : FileCacheService { + override fun list(): List { + return fileCacheRepository.findAllBy() + } + + override fun create(fileCacheRequest: FileCacheRequest) { + val fileCache = TFileCache( + id = null, + projectId = fileCacheRequest.projectId, + repoName = fileCacheRequest.repoName, + pathPrefix = fileCacheRequest.pathPrefix, + size = fileCacheRequest.size, + days = fileCacheRequest.days + ) + fileCacheRepository.insert(fileCache) + } + + override fun delete(id: String) { + fileCacheRepository.deleteById(id) + } + + override fun getById(id: String): TFileCache? { + return fileCacheRepository.findById(id).orElseGet(null) + } + + override fun checkExist(request: FileCacheCheckRequest): TFileCache? { + return fileCacheRepository.findByRepoNameAndProjectIdAndDaysAndSize( + request.repoName, + request.projectId, + request.days, + request.size + ) + } + + override fun update(fileCacheRequest: FileCacheRequest) { + fileCacheRepository.deleteById(fileCacheRequest.id) + var newFileCache = TFileCache( + id = fileCacheRequest.id, + projectId = fileCacheRequest.projectId, + repoName = fileCacheRequest.repoName, + pathPrefix = fileCacheRequest.pathPrefix, + size = fileCacheRequest.size, + days = fileCacheRequest.days + ) + fileCacheRepository.insert(newFileCache) + } + +} diff --git a/src/backend/opdata/api-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/pojo/config/ConfigItem.kt b/src/backend/opdata/api-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/pojo/config/ConfigItem.kt index 29ad375c04..0f08b7a15c 100644 --- a/src/backend/opdata/api-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/pojo/config/ConfigItem.kt +++ b/src/backend/opdata/api-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/pojo/config/ConfigItem.kt @@ -48,10 +48,14 @@ data class ConfigItem( return } - if (value is String || value is Number || value is Boolean) { + if (isBaseType() || value is ArrayList<*>) { return } throw BadRequestException(OpDataMessageCode.ConfigValueTypeInvalid) } + + fun isBaseType():Boolean { + return value is String || value is Number || value is Boolean + } } diff --git a/src/backend/opdata/api-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/pojo/config/GetConfigRequest.kt b/src/backend/opdata/api-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/pojo/config/GetConfigRequest.kt new file mode 100644 index 0000000000..49d4aea7d3 --- /dev/null +++ b/src/backend/opdata/api-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/pojo/config/GetConfigRequest.kt @@ -0,0 +1,12 @@ +package com.tencent.bkrepo.opdata.pojo.config + +import io.swagger.annotations.ApiModelProperty + +data class GetConfigRequest( + @ApiModelProperty("查询的应用名") + val appName: String = "", + @ApiModelProperty("查询的profile") + val profile: String = "", + @ApiModelProperty("查询的key") + val key:String +) diff --git a/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/config/client/ConfigClient.kt b/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/config/client/ConfigClient.kt index d7b29d5b43..e9119fc345 100644 --- a/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/config/client/ConfigClient.kt +++ b/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/config/client/ConfigClient.kt @@ -51,4 +51,6 @@ interface ConfigClient { * @param targetProfile 要更新的profile,比如dev、prod,空字符串表示更新默认配置 */ fun put(values: List, appName: String = "", targetProfile: String = "") + + fun get(appName: String = "", profile: String = "", key: String):String } diff --git a/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/config/client/consul/ConsulConfigClient.kt b/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/config/client/consul/ConsulConfigClient.kt index ac47616e15..98f3752e0b 100644 --- a/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/config/client/consul/ConsulConfigClient.kt +++ b/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/config/client/consul/ConsulConfigClient.kt @@ -33,6 +33,7 @@ import com.ecwid.consul.v1.kv.model.PutParams import com.tencent.bkrepo.common.api.constant.StringPool.SLASH import com.tencent.bkrepo.common.api.exception.BadRequestException import com.tencent.bkrepo.common.api.exception.SystemErrorException +import com.tencent.bkrepo.common.api.util.toJsonString import com.tencent.bkrepo.opdata.config.client.ConfigClient import com.tencent.bkrepo.opdata.message.OpDataMessageCode import com.tencent.bkrepo.opdata.pojo.config.ConfigItem @@ -82,6 +83,31 @@ class ConsulConfigClient( client.setKVValue(consulConfigKey, yaml.dumpAsMap(config), properties.aclToken, putParams) } + override fun get(appName: String, targetProfile: String, key: String): String { + // 当前仅支持 + if (properties.format != ConsulConfigProperties.Format.YAML) { + logger.error("consul config format: ${properties.format} not support") + throw SystemErrorException() + } + + // 读取配置index,用于更新时执行cas校验,避免覆盖其他更新 + val consulConfigKey = getConsulConfigKey(appName, targetProfile) + val getConfigResponse = client.getKVValue(consulConfigKey, this.properties.aclToken, QueryParams.DEFAULT) + + // 解析YAML + val putParams = PutParams() + val yaml = Yaml() + val config = if (getConfigResponse.value == null) { + putParams.cas = 0 + HashMap() + } else { + putParams.cas = getConfigResponse.consulIndex + yaml.load(getConfigResponse.value.decodedValue) + } + + return getVal(config, key) + } + private fun putVal(map: MutableMap, key: String, value: Any?) { val keys = key.split(".") var currentMap = map @@ -99,6 +125,24 @@ class ConsulConfigClient( } } + private fun getVal(map: MutableMap, key: String):String { + val keys = key.split(".") + var currentMap = map + for (i in keys.indices) { + if (i == keys.size - 1) { + return currentMap[keys[i]]?.toJsonString() ?: ""; + } else { + val currentKey = keys[i] + val currentVal = currentMap.getOrPut(currentKey) { HashMap(1) } + if (currentVal != null && currentVal !is Map<*, *>) { + throw BadRequestException(OpDataMessageCode.ConfigValueTypeInvalid) + } + currentMap = currentVal as MutableMap + } + } + return "" + } + /** * 获取Consul配置的key */ diff --git a/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/controller/ConfigController.kt b/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/controller/ConfigController.kt index e0a0d38a7a..7668091e2a 100644 --- a/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/controller/ConfigController.kt +++ b/src/backend/opdata/biz-opdata/src/main/kotlin/com/tencent/bkrepo/opdata/controller/ConfigController.kt @@ -35,9 +35,11 @@ import com.tencent.bkrepo.common.security.permission.PrincipalType import com.tencent.bkrepo.common.service.util.ResponseBuilder import com.tencent.bkrepo.opdata.config.client.ConfigClient import com.tencent.bkrepo.opdata.message.OpDataMessageCode +import com.tencent.bkrepo.opdata.pojo.config.GetConfigRequest import com.tencent.bkrepo.opdata.pojo.config.UpdateConfigRequest import org.springframework.beans.factory.ObjectProvider import org.springframework.beans.factory.annotation.Autowired +import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PatchMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping @@ -66,4 +68,17 @@ class ConfigController @Autowired constructor( } return ResponseBuilder.success() } + + @GetMapping + fun getConfig(getConfigRequest: GetConfigRequest):Response { + val configClient = configClientProvider.firstOrNull() + ?: throw SystemErrorException(OpDataMessageCode.CONFIG_CLIENT_NOT_FOUND) + return ResponseBuilder.success( + configClient.get( + getConfigRequest.appName, + getConfigRequest.profile, + getConfigRequest.key + ) + ) + } } diff --git a/src/frontend/devops-op/src/api/config.js b/src/frontend/devops-op/src/api/config.js index b1f7f5462a..f2cff7fd36 100644 --- a/src/frontend/devops-op/src/api/config.js +++ b/src/frontend/devops-op/src/api/config.js @@ -14,3 +14,15 @@ export function updateConfig(values, appName = '', profile = '') { data }) } + +export function getConfig(key, appName = '', profile = '') { + return request({ + url: `${PREFIX}`, + method: 'get', + params: { + appName: appName, + profile: profile, + key: key + } + }) +} diff --git a/src/frontend/devops-op/src/api/fileCache.js b/src/frontend/devops-op/src/api/fileCache.js new file mode 100644 index 0000000000..eba03e2ff2 --- /dev/null +++ b/src/frontend/devops-op/src/api/fileCache.js @@ -0,0 +1,40 @@ +import request from '@/utils/request' + +const PREFIX_SERVICES = '/job/api/cache' + +export function queryFileCache() { + return request({ + url: `${PREFIX_SERVICES}/list/`, + method: 'get' + }) +} + +export function deleteFileCache(id) { + return request({ + url: `${PREFIX_SERVICES}/delete/${id}`, + method: 'delete' + }) +} + +export function createFileCache(data) { + return request({ + url: `${PREFIX_SERVICES}/create/`, + method: 'post', + data: data + }) +} + +export function updateFileCache(data) { + return request({ + url: `${PREFIX_SERVICES}/update/`, + method: 'post', + data: data + }) +} + +export function getNodeConfig() { + return request({ + url: `${PREFIX_SERVICES}/config/`, + method: 'get' + }) +} diff --git a/src/frontend/devops-op/src/router/index.js b/src/frontend/devops-op/src/router/index.js index 2960e381b5..48effb4de8 100644 --- a/src/frontend/devops-op/src/router/index.js +++ b/src/frontend/devops-op/src/router/index.js @@ -21,6 +21,7 @@ export const ROUTER_NAME_JOB = 'Job' export const ROUTER_NAME_SHED_LOCK = 'Shedlock' export const ROUTER_NAME_PROJECT_METRICS = 'ProjectMetrics' export const ROUTER_NAME_FILE_SYSTEM = 'FileSystem' +export const ROUTER_NAME_FILE_CACHE = 'FileCache' Vue.use(Router) @@ -134,6 +135,12 @@ export const asyncRoutes = [ meta: { title: '文件管理', icon: 'file' }, component: () => import('@/views/node/index') }, + { + path: 'fileCache', + name: ROUTER_NAME_FILE_CACHE, + meta: { title: '缓存管理', icon: 'file' }, + component: () => import('@/views/node/FileCache') + }, { path: 'fileSystem', name: ROUTER_NAME_FILE_SYSTEM, diff --git a/src/frontend/devops-op/src/utils/file.js b/src/frontend/devops-op/src/utils/file.js index 050ea62067..f096359acb 100644 --- a/src/frontend/devops-op/src/utils/file.js +++ b/src/frontend/devops-op/src/utils/file.js @@ -8,6 +8,31 @@ export function convertFileSize(size, unit = 'B') { } } +export function formatFileSize(size, unit = 'GB') { + const arrays = ['B', 'KB', 'MB', 'GB', 'TB'] + let index + for (let i = arrays.length - 1; i < arrays.length && i > -1; i--) { + if (size.indexOf(arrays[i]) !== -1) { + index = i + break + } + } + const sizeIndex = size.indexOf(arrays[index]) + const unitIndex = arrays.findIndex(i => i === unit) + let temp = Number(size.substr(0, sizeIndex)) + if (unitIndex - index > 0) { + for (let i = 0; i < unitIndex - index; i++) { + temp = temp / 1024 + } + } + if (unitIndex - index < 0) { + for (let i = 0; i < index - unitIndex; i++) { + temp = temp * 1024 + } + } + return temp +} + function preZero(num) { num = Number(num) if (num < 10) { diff --git a/src/frontend/devops-op/src/views/node/FileCache.vue b/src/frontend/devops-op/src/views/node/FileCache.vue new file mode 100644 index 0000000000..733801790d --- /dev/null +++ b/src/frontend/devops-op/src/views/node/FileCache.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/src/frontend/devops-op/src/views/node/components/CreateOrUpdateFileCacheDialog.vue b/src/frontend/devops-op/src/views/node/components/CreateOrUpdateFileCacheDialog.vue new file mode 100644 index 0000000000..9da0210990 --- /dev/null +++ b/src/frontend/devops-op/src/views/node/components/CreateOrUpdateFileCacheDialog.vue @@ -0,0 +1,238 @@ + + + + + +