From 176cd4956031f78ff1bbeb7807932f0cca8023a1 Mon Sep 17 00:00:00 2001 From: ericwu <51363667+scplsy@users.noreply.github.com> Date: Thu, 1 Feb 2024 10:10:07 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BC=BA=E5=88=B6=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E6=BA=90=E4=BB=93=E5=BA=93=E6=97=B6=E6=9C=AA?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=8C=85=E6=95=B0=E6=8D=AE=20#1720?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../artifact/message/ArtifactMessageCode.kt | 2 +- .../common/artifact/pojo/RepositoryType.kt | 38 ++++++------- .../resources/i18n/messages_zh_CN.properties | 2 +- .../resources/i18n/messages_zh_TW.properties | 2 +- .../service/packages/PackageService.kt | 8 +++ .../packages/impl/PackageServiceImpl.kt | 10 ++++ .../repo/impl/RepositoryServiceImpl.kt | 57 +++++++++++++------ .../CommitEdgeCenterRepositoryServiceImpl.kt | 22 ++++--- 8 files changed, 90 insertions(+), 51 deletions(-) diff --git a/src/backend/common/common-artifact/artifact-api/src/main/kotlin/com/tencent/bkrepo/common/artifact/message/ArtifactMessageCode.kt b/src/backend/common/common-artifact/artifact-api/src/main/kotlin/com/tencent/bkrepo/common/artifact/message/ArtifactMessageCode.kt index 9081ce32ad..9f707ff6e1 100644 --- a/src/backend/common/common-artifact/artifact-api/src/main/kotlin/com/tencent/bkrepo/common/artifact/message/ArtifactMessageCode.kt +++ b/src/backend/common/common-artifact/artifact-api/src/main/kotlin/com/tencent/bkrepo/common/artifact/message/ArtifactMessageCode.kt @@ -44,7 +44,7 @@ enum class ArtifactMessageCode(private val key: String) : MessageCode { PROJECT_EXISTED("artifact.project.existed"), REPOSITORY_NOT_FOUND("artifact.repository.not-found"), REPOSITORY_EXISTED("artifact.repository.existed"), - REPOSITORY_CONTAINS_FILE("artifact.repository.not-empty"), + REPOSITORY_CONTAINS_ARTIFACT("artifact.repository.not-empty"), FOLDER_CONTAINS_FILE("artifact.folder.not-empty"), NODE_NOT_FOUND("artifact.node.not-found"), NODE_PATH_INVALID("artifact.node.path.invalid"), diff --git a/src/backend/common/common-artifact/artifact-api/src/main/kotlin/com/tencent/bkrepo/common/artifact/pojo/RepositoryType.kt b/src/backend/common/common-artifact/artifact-api/src/main/kotlin/com/tencent/bkrepo/common/artifact/pojo/RepositoryType.kt index 990d65d226..d099f606d2 100644 --- a/src/backend/common/common-artifact/artifact-api/src/main/kotlin/com/tencent/bkrepo/common/artifact/pojo/RepositoryType.kt +++ b/src/backend/common/common-artifact/artifact-api/src/main/kotlin/com/tencent/bkrepo/common/artifact/pojo/RepositoryType.kt @@ -34,25 +34,25 @@ package com.tencent.bkrepo.common.artifact.pojo /** * 仓库类型 */ -enum class RepositoryType { - NONE, - GENERIC, - DOCKER, - MAVEN, - PYPI, - NPM, - HELM, - RDS, - COMPOSER, - RPM, - NUGET, - GIT, - OCI, - CONAN, - LFS, - DDC, - SVN, - S3 +enum class RepositoryType(val supportPackage: Boolean) { + NONE(false), + GENERIC(false), + DOCKER(true), + MAVEN(true), + PYPI(true), + NPM(true), + HELM(true), + RDS(true), + COMPOSER(true), + RPM(true), + NUGET(true), + GIT(true), + OCI(true), + CONAN(true), + LFS(false), + DDC(false), + SVN(false), + S3(false) ; companion object { diff --git a/src/backend/common/common-artifact/artifact-api/src/main/resources/i18n/messages_zh_CN.properties b/src/backend/common/common-artifact/artifact-api/src/main/resources/i18n/messages_zh_CN.properties index c8ef3fb5c6..4f59c7fcb3 100644 --- a/src/backend/common/common-artifact/artifact-api/src/main/resources/i18n/messages_zh_CN.properties +++ b/src/backend/common/common-artifact/artifact-api/src/main/resources/i18n/messages_zh_CN.properties @@ -33,7 +33,7 @@ artifact.project.not-found=项目[{0}]不存在 artifact.project.existed=项目[{0}]已存在 artifact.repository.not-found=仓库[{0}]不存在 artifact.repository.existed=仓库[{0}]已存在 -artifact.repository.not-empty=仓库包含文件 +artifact.repository.not-empty=仓库包含制品 artifact.repository.over-quota=超出仓库[{0}]配额值[{1}] artifact.folder.not-empty=目录包含文件 artifact.node.not-found=节点[{0}]不存在 diff --git a/src/backend/common/common-artifact/artifact-api/src/main/resources/i18n/messages_zh_TW.properties b/src/backend/common/common-artifact/artifact-api/src/main/resources/i18n/messages_zh_TW.properties index f7b9598519..de66c7860d 100644 --- a/src/backend/common/common-artifact/artifact-api/src/main/resources/i18n/messages_zh_TW.properties +++ b/src/backend/common/common-artifact/artifact-api/src/main/resources/i18n/messages_zh_TW.properties @@ -33,7 +33,7 @@ artifact.project.not-found=項目[{0}]不存在 artifact.project.existed=項目[{0}]已存在 artifact.repository.not-found=倉庫[{0}]不存在 artifact.repository.existed=倉庫[{0}]已存在 -artifact.repository.not-empty=倉庫包含文件 +artifact.repository.not-empty=倉庫包含製品 artifact.repository.over-quota=超過倉庫[{0}]配額值[{1}] artifact.folder.not-empty=目录包含文件 artifact.node.not-found=節點[{0}]不存在 diff --git a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/packages/PackageService.kt b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/packages/PackageService.kt index 33d8aece3b..fdd4f4d12d 100644 --- a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/packages/PackageService.kt +++ b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/packages/PackageService.kt @@ -190,6 +190,14 @@ interface PackageService { realIpAddress: String? = null ) + /** + * 删除所有包 + * + * @param projectId 项目id + * @param repoName 仓库名称 + */ + fun deleteAllPackage(projectId: String, repoName: String) + /** * 更新包 * diff --git a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/packages/impl/PackageServiceImpl.kt b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/packages/impl/PackageServiceImpl.kt index 8fc6d82b2b..ed91753879 100644 --- a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/packages/impl/PackageServiceImpl.kt +++ b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/packages/impl/PackageServiceImpl.kt @@ -304,6 +304,16 @@ class PackageServiceImpl( logger.info("Delete package version[$projectId/$repoName/$packageKey-$versionName] success") } + override fun deleteAllPackage(projectId: String, repoName: String) { + val query = PackageQueryHelper.packageListQuery(projectId, repoName, null) + var pageNumber = 1 + do { + val packageList = packageDao.find(query.with(Pages.ofRequest(pageNumber, 1000))) + packageList.forEach { deletePackage(it.projectId, it.repoName, it.key) } + pageNumber++ + } while (packageList.isNotEmpty()) + } + override fun updatePackage(request: PackageUpdateRequest, realIpAddress: String?) { val projectId = request.projectId val repoName = request.repoName diff --git a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/repo/impl/RepositoryServiceImpl.kt b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/repo/impl/RepositoryServiceImpl.kt index 5a157d45ca..4288016985 100644 --- a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/repo/impl/RepositoryServiceImpl.kt +++ b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/repo/impl/RepositoryServiceImpl.kt @@ -75,6 +75,7 @@ import com.tencent.bkrepo.repository.pojo.repo.RepoUpdateRequest import com.tencent.bkrepo.repository.pojo.repo.RepositoryDetail import com.tencent.bkrepo.repository.pojo.repo.RepositoryInfo import com.tencent.bkrepo.repository.service.node.NodeService +import com.tencent.bkrepo.repository.service.packages.PackageService import com.tencent.bkrepo.repository.service.repo.ProjectService import com.tencent.bkrepo.repository.service.repo.ProxyChannelService import com.tencent.bkrepo.repository.service.repo.RepositoryService @@ -84,7 +85,9 @@ import com.tencent.bkrepo.repository.util.RepoEventFactory.buildDeletedEvent import com.tencent.bkrepo.repository.util.RepoEventFactory.buildUpdatedEvent import java.time.Duration import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Conditional +import org.springframework.context.annotation.Lazy import org.springframework.dao.DuplicateKeyException import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Sort @@ -118,6 +121,10 @@ class RepositoryServiceImpl( private val projectMetricsRepository: ProjectMetricsRepository, ) : RepositoryService { + @Autowired + @Lazy + lateinit var packageService: PackageService + init { Companion.repositoryProperties = repositoryProperties } @@ -336,24 +343,12 @@ class RepositoryServiceImpl( override fun deleteRepo(repoDeleteRequest: RepoDeleteRequest) { repoDeleteRequest.apply { val repository = checkRepository(projectId, name) - if (repoDeleteRequest.forced) { - nodeService.deleteByPath(projectId, name, ROOT, operator) - } else { - val artifactInfo = DefaultArtifactInfo(projectId, name, ROOT) - nodeService.countFileNode(artifactInfo).takeIf { it == 0L } ?: throw ErrorCodeException( - ArtifactMessageCode.REPOSITORY_CONTAINS_FILE, - ) - nodeService.deleteByPath(projectId, name, ROOT, operator) - } - + clearRepo(projectId, name, repository.type.supportPackage, forced, operator) // 为避免仓库被删除后节点无法被自动清理的问题,对仓库实行假删除 - if (!repository.id.isNullOrBlank()) { - repositoryDao.updateFirst( - Query(Criteria.where(ID).isEqualTo(repository.id)), - Update().set(TRepository::deleted.name, LocalDateTime.now()), - ) - } - + repositoryDao.updateFirst( + Query(Criteria.where(ID).isEqualTo(repository.id!!)), + Update().set(TRepository::deleted.name, LocalDateTime.now()) + ) // 删除关联的库 if (repository.category == RepositoryCategory.COMPOSITE) { val configuration = repository.configuration.readJsonString() @@ -385,6 +380,34 @@ class RepositoryServiceImpl( ) } + /** + * 删除仓库内容 + */ + protected fun clearRepo( + projectId: String, + repoName: String, + supportPackage: Boolean, + forced: Boolean, + operator: String + ) { + if (forced) { + logger.info("Force clear repository [$projectId/$repoName] by [$operator]") + if (supportPackage) { + packageService.deleteAllPackage(projectId, repoName) + } + } else { + // 当仓库类型支持包管理,仓库下没有包时视为空仓库,删除仓库下所有节点 + val isEmpty = if (supportPackage) { + packageService.getPackageCount(projectId, repoName) == 0L + } else { + val artifactInfo = DefaultArtifactInfo(projectId, repoName, ROOT) + nodeService.countFileNode(artifactInfo) == 0L + } + if (!isEmpty) throw ErrorCodeException(ArtifactMessageCode.REPOSITORY_CONTAINS_ARTIFACT) + } + nodeService.deleteByPath(projectId, repoName, ROOT, operator) + } + /** * 获取仓库下的代理地址信息 */ diff --git a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/repo/impl/center/CommitEdgeCenterRepositoryServiceImpl.kt b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/repo/impl/center/CommitEdgeCenterRepositoryServiceImpl.kt index 33da95ed43..a621123503 100644 --- a/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/repo/impl/center/CommitEdgeCenterRepositoryServiceImpl.kt +++ b/src/backend/repository/biz-repository/src/main/kotlin/com/tencent/bkrepo/repository/service/repo/impl/center/CommitEdgeCenterRepositoryServiceImpl.kt @@ -31,14 +31,13 @@ import com.tencent.bkrepo.auth.api.ServicePermissionClient import com.tencent.bkrepo.common.api.exception.ErrorCodeException import com.tencent.bkrepo.common.api.message.CommonMessageCode import com.tencent.bkrepo.common.api.util.readJsonString -import com.tencent.bkrepo.common.artifact.api.DefaultArtifactInfo import com.tencent.bkrepo.common.artifact.message.ArtifactMessageCode -import com.tencent.bkrepo.common.artifact.path.PathUtils import com.tencent.bkrepo.common.artifact.pojo.RepositoryCategory import com.tencent.bkrepo.common.artifact.pojo.RepositoryType import com.tencent.bkrepo.common.artifact.pojo.configuration.RepositoryConfiguration import com.tencent.bkrepo.common.artifact.pojo.configuration.composite.CompositeConfiguration import com.tencent.bkrepo.common.artifact.util.ClusterUtils +import com.tencent.bkrepo.common.mongo.dao.AbstractMongoDao import com.tencent.bkrepo.common.security.util.SecurityUtils import com.tencent.bkrepo.common.service.cluster.ClusterProperties import com.tencent.bkrepo.common.service.cluster.CommitEdgeCenterCondition @@ -59,8 +58,12 @@ import com.tencent.bkrepo.repository.service.repo.impl.RepositoryServiceImpl import com.tencent.bkrepo.repository.util.RepoEventFactory import org.slf4j.LoggerFactory import org.springframework.context.annotation.Conditional +import org.springframework.data.mongodb.core.query.Criteria +import org.springframework.data.mongodb.core.query.Query import org.springframework.data.mongodb.core.query.Update +import org.springframework.data.mongodb.core.query.isEqualTo import org.springframework.stereotype.Service +import java.time.LocalDateTime @Service @Conditional(CommitEdgeCenterCondition::class) @@ -142,19 +145,14 @@ class CommitEdgeCenterRepositoryServiceImpl( override fun deleteRepo(repoDeleteRequest: RepoDeleteRequest) { repoDeleteRequest.apply { val repository = checkRepository(projectId, name) - if (repoDeleteRequest.forced) { - nodeService.deleteByPath(projectId, name, PathUtils.ROOT, operator) - } else { - val artifactInfo = DefaultArtifactInfo(projectId, name, PathUtils.ROOT) - nodeService.countFileNode(artifactInfo).takeIf { it == 0L } ?: throw ErrorCodeException( - ArtifactMessageCode.REPOSITORY_CONTAINS_FILE - ) - nodeService.deleteByPath(projectId, name, PathUtils.ROOT, operator) - } + clearRepo(projectId, name, repository.type.supportPackage, forced, operator) val clusterNames = repository.clusterNames.orEmpty().toMutableSet() clusterNames.remove(SecurityUtils.getClusterName() ?: clusterProperties.self.name) if (clusterNames.isEmpty()) { - repositoryDao.deleteById(repository.id) + repositoryDao.updateFirst( + Query(Criteria.where(AbstractMongoDao.ID).isEqualTo(repository.id!!)), + Update().set(TRepository::deleted.name, LocalDateTime.now()), + ) } else { repository.clusterNames = clusterNames repositoryDao.save(repository)