Files
devstar/services/devstar_devcontainer/api_services/CreateDevcontainerAPIService.go
戴明辰 c1ea93e233 !10 [Feature][Fix][Doc] Tencent NAT Auto-Portforwarding
* [Fix] Relocate User Permanent SSH Public Key queries to DevcontainerService Layer
* [Fix] Add Unix Timestamps in DB table `devstar_devcontainer`
* [Feature] Tencent NAT port forwarding
* [Doc] k8s Operator RBAC: ServiceAccount, ClusterRole, ClusterRoleBinding, etc.
* [fix] k8s Operator Reconciler error while converting YAML to JSON
* [Doc] Added DevStar API Doc
* [fix] detailed errors while listing user devcontainers
* [fix] Invalid metadata.labels: value must be no more than 63 characters
2024-10-23 03:05:44 +00:00

84 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package api_services
import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/repo"
DevcontainersVO "code.gitea.io/gitea/routers/api/devcontainer/vo"
gitea_web_context "code.gitea.io/gitea/services/context"
DevcontainersService "code.gitea.io/gitea/services/devstar_devcontainer"
devcontainer_service_errors "code.gitea.io/gitea/services/devstar_devcontainer/errors"
devcontainer_service_options "code.gitea.io/gitea/services/devstar_devcontainer/options"
"context"
"regexp"
)
// CreateDevcontainerAPIService API专用创建 DevContainer Service
func CreateDevcontainerAPIService(ctx *gitea_web_context.Context, opts *devcontainer_service_options.CreateDevcontainerOptions) error {
// 0. 检查用户传入参数
if ctx == nil || opts == nil || opts.Actor == nil || opts.RepoId <= 0 {
return devcontainer_service_errors.ErrIllegalParams{
FieldNameList: []string{"ctx", "opts", "opts.Actor", "opts.RepoId"},
}
}
// sanitize user-input SSH Public Key List
regexpInvalidSSHPublicKey := regexp.MustCompile(`[\r]`)
for _, publicKey := range opts.SSHPublicKeyList {
if len(publicKey) <= 4 || publicKey[0:4] != "ssh-" || regexpInvalidSSHPublicKey.MatchString(publicKey) {
// 遇到可能无效的 SSH Public Key或者导致 k8s Operator YAML 解码失败的字符: `\r`,报错返回
// ERROR Reconciler error:
// {
// "controller": "devcontainerapp",
// "controllerGroup": "devcontainer.devstar.cn",
// "controllerKind": "DevcontainerApp",
// "DevcontainerApp": {
// "name": "leviyanx-16-4834a4c88c4511ef9c1a4e1bce2a7080",
// "namespace": "devstar-studio-ns"
// },
// "namespace": "devstar-studio-ns",
// "name": "leviyanx-16-4834a4c88c4511ef9c1a4e1bce2a7080",
// "reconcileID": "6af51347-7aae-4542-a5cf-2f9b57a202e6",
// "error": "panic: error converting YAML to JSON: yaml: line 46: could not find expected ':' [recovered]"
// }
return devcontainer_service_errors.ErrIllegalParams{
FieldNameList: []string{"SSHPublicKeyList"},
}
}
}
// 1. 开启事务
errTxn := db.WithTx(ctx, func(ctx context.Context) error {
// 1.1 调用 model层查询数据库将 repoId 变换为 Repository 对象
repositoryInDB, err := repo.GetRepositoryByID(ctx, opts.RepoId)
if err != nil || repositoryInDB == nil {
return devcontainer_service_errors.ErrIllegalParams{
FieldNameList: []string{"opts.RepoId"},
}
}
// 1.2 检查该用户在该仓库 是否已经创建过 DevContainer
optsRepoDevcontainer := &DevcontainersVO.RepoDevcontainerOptions{
Actor: opts.Actor,
Repository: repositoryInDB,
}
devcontainerDetails, err := DevcontainersService.GetRepoDevcontainerDetails(ctx, optsRepoDevcontainer)
if err != nil || devcontainerDetails.DevContainerId > 0 {
return devcontainer_service_errors.ErrDevcontainerAlreadyCreated{
Actor: opts.Actor,
Repository: repositoryInDB,
}
}
// 1.3 调用 DevContainer Service 创建 DevContainer
optsCreateDevcontainer := &DevcontainersVO.CreateRepoDevcontainerOptions{
Actor: opts.Actor,
Repository: repositoryInDB,
SSHPublicKeyList: opts.SSHPublicKeyList,
}
return DevcontainersService.CreateRepoDevcontainer(ctx, optsCreateDevcontainer)
})
return errTxn
}