Files
devstar/routers/api/devcontainer/devcontainer.go
2025-05-29 11:13:22 +08:00

195 lines
6.1 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 devcontainer
import (
"strconv"
"code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/log"
web_module "code.gitea.io/gitea/modules/web"
Result "code.gitea.io/gitea/routers/entity"
context "code.gitea.io/gitea/services/context"
gitea_web_context "code.gitea.io/gitea/services/context"
devcontainer_service "code.gitea.io/gitea/services/devcontainer"
"code.gitea.io/gitea/services/forms"
)
// CreateRepoDevcontainer 创建 某用户在某仓库的 DevContainer
//
// POST /api/devcontainer
// 请求体参数:
// -- repoId: 需要为哪个仓库创建 DevContainer
// -- sshPublicKeyList: 列表填入用户希望临时使用的SSH会话加密公钥
// 注意:必须携带 用户登录凭证
func CreateRepoDevcontainer(ctx *context.Context) {
// 1. 检查用户登录状态,若未登录则返回未授权错误
if ctx == nil || ctx.Doer == nil {
Result.RespUnauthorizedFailure.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 2. 检查表单校验规则是否失败
if ctx.HasError() {
// POST Binding 表单正则表达式校验失败,返回 API 错误信息
failedToValidateFormData := &Result.ResultType{
Code: Result.RespFailedIllegalParams.Code,
Msg: Result.RespFailedIllegalParams.Msg,
Data: map[string]string{
"ErrorMsg": ctx.GetErrMsg(),
},
}
failedToValidateFormData.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 3. 解析 repoId
form := web_module.GetForm(ctx).(*forms.CreateRepoDevcontainerForm)
repoId, err := strconv.ParseInt(form.RepoId, 10, 64)
if err != nil || repoId <= 0 {
failedToParseRepoId := Result.ResultType{
Code: Result.RespFailedIllegalParams.Code,
Msg: Result.RespFailedIllegalParams.Msg,
Data: map[string]string{
// fix nullptr dereference of `err.Error()` when repoId == 0
"ErrorMsg": "repoId 必须是正数",
},
}
failedToParseRepoId.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 4. 调用 API Service 层创建 DevContainer
repo, err := repo.GetRepositoryByID(ctx, repoId)
if err != nil {
errCreateDevcontainer := Result.ResultType{
Code: Result.RespFailedCreateDevcontainer.Code,
Msg: Result.RespFailedCreateDevcontainer.Msg,
Data: map[string]string{
"ErrorMsg": "repo not found",
},
}
errCreateDevcontainer.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
devcontainer_service.CreateDevcontainerJSON(ctx, repo, ctx.Doer)
opts := &devcontainer_service.CreateDevcontainerOptions{
Actor: ctx.Doer,
RepoId: repoId,
SSHPublicKeyList: form.SSHPublicKeyList,
}
err = devcontainer_service.CreateDevcontainerAPIService(ctx, opts)
if err != nil {
errCreateDevcontainer := Result.ResultType{
Code: Result.RespFailedCreateDevcontainer.Code,
Msg: Result.RespFailedCreateDevcontainer.Msg,
Data: map[string]string{
"ErrorMsg": err.Error(),
},
}
errCreateDevcontainer.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 4. 创建 DevContainer 成功,直接返回
Result.RespSuccess.RespondJson2HttpResponseWriter(ctx.Resp)
}
// GetDevcontainer 查找某用户在某仓库的 DevContainer
//
// GET /api/devcontainer
// 请求体参数:
// -- repoId: 需要为哪个仓库创建 DevContainer
// -- wait: 是否等待 DevContainer 就绪(默认为 false 直接返回“未就绪”,否则阻塞等待)
// -- UserPublicKey
// 注意:必须携带 用户登录凭证
func GetDevcontainer(ctx *gitea_web_context.Context) {
// 1. 检查用户登录状态,若未登录则返回未授权错误
if ctx == nil || ctx.Doer == nil {
Result.RespUnauthorizedFailure.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 2. 取得参数
wait := ctx.FormBool("wait")
repoIdStr := ctx.FormString("repoId")
UserPublicKey := ctx.FormString("userPublicKey")
log.Info(UserPublicKey)
repoId, err := strconv.ParseInt(repoIdStr, 10, 64)
if err != nil || repoId <= 0 {
Result.RespFailedIllegalParams.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 3. 准备调用 API Service 层,获取 DevContainer 信息
optsAbstractOpenDevcontainer := &devcontainer_service.AbstractOpenDevcontainerOptions{
Wait: wait,
RepoId: repoId,
Actor: ctx.Doer,
UserPublicKey: UserPublicKey,
}
repoDevcontainerVO, err := devcontainer_service.OpenDevcontainerAPIService(ctx, optsAbstractOpenDevcontainer)
if err != nil {
failureGetDevcontainer := Result.ResultType{
Code: Result.RespFailedOpenDevcontainer.Code,
Msg: Result.RespFailedOpenDevcontainer.Msg,
Data: map[string]any{
"ErrorMsg": err.Error(),
},
}
failureGetDevcontainer.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 4. 封装返回成功信息
successGetDevContainer := Result.ResultType{
Code: Result.RespSuccess.Code,
Msg: Result.RespSuccess.Msg,
Data: repoDevcontainerVO,
}
successGetDevContainer.RespondJson2HttpResponseWriter(ctx.Resp)
}
// DeleteRepoDevcontainer 删除某仓库的 DevContainer
//
// DELETE /api/devcontainer
// 请求体参数:
// -- repoId: 需要为哪个仓库创建 DevContainer
// 注意:必须携带 用户登录凭证
func DeleteRepoDevcontainer(ctx *gitea_web_context.Context) {
// 1. 检查用户登录状态,若未登录则返回未授权错误
if ctx == nil || ctx.Doer == nil {
Result.RespUnauthorizedFailure.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 2. 取得参数 repoId
repoIdStr := ctx.FormString("repoId")
repoId, err := strconv.ParseInt(repoIdStr, 10, 64)
if err != nil || repoId <= 0 {
Result.RespFailedIllegalParams.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 3. 调用 API Service 层,删除 DevContainer
opts := &devcontainer_service.AbstractDeleteDevcontainerOptions{
Actor: ctx.Doer,
RepoId: repoId,
}
err = devcontainer_service.DeleteDevcontainerAPIService(ctx, opts)
if err != nil {
failureDeleteDevcontainer := Result.ResultType{
Code: Result.RespFailedDeleteDevcontainer.Code,
Msg: Result.RespFailedDeleteDevcontainer.Msg,
Data: map[string]any{
"ErrorMsg": err.Error(),
},
}
failureDeleteDevcontainer.RespondJson2HttpResponseWriter(ctx.Resp)
return
}
// 4. 删除成功,返回提示信息
Result.RespSuccess.RespondJson2HttpResponseWriter(ctx.Resp)
}