* 合并devcontainer web相关的源文件,简化目录结构 * devcontainer、ssh_key_pair和devcontainer.cloud * fixed bug:创建容器时Host为localhost时创建失败的问题 * 删除了死代码,更新了一些命名(主要是去掉devstar字符串) * 常量名全大写 * devcontainer HOST改为用户设置的域名或IP * 安装时如没有配置devcontainer则默认设置为docker方式 * 直接使用kubernetes和docker简化代码提高可读性 * 去除services/devstar_devcontainer文件夹名中不必要的devstar字符串 * 去除services/devstar_devcontainer文件夹名中不必要的devstar字符串 * 文件名中去掉不必要的devstar字符串 * 变量名中删除不必要的Devstar字符串 * Merge branch 'dev' into feature-websshAndUpdateImage * change pages style * change Structure * fix bug * websshAndUpdateImage
85 lines
3.2 KiB
Go
85 lines
3.2 KiB
Go
package api_services
|
||
|
||
import (
|
||
"context"
|
||
"regexp"
|
||
|
||
"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/devcontainer"
|
||
devcontainer_service_errors "code.gitea.io/gitea/services/devcontainer/errors"
|
||
devcontainer_service_options "code.gitea.io/gitea/services/devcontainer/options"
|
||
)
|
||
|
||
// 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
|
||
}
|