From 90d35e3c2779a2849f7a8b6fbce9a26e8bb7cc9b Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Wed, 25 Jun 2025 09:07:17 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecloud=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/api/cloud.go | 2 ++ client/router/cloud.go | 10 +++++++++- cloud/go.mod | 3 +++ cloud/platform/interface.go | 7 +++++++ cloud/platform/platform.go | 15 +++++++++++++++ cloud/service/service.go | 16 ++++++++++++++++ go.work.sum | 10 ++++++++++ 7 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 cloud/go.mod create mode 100644 cloud/platform/interface.go create mode 100644 cloud/platform/platform.go create mode 100644 cloud/service/service.go diff --git a/client/api/cloud.go b/client/api/cloud.go index 82832c4..abb095c 100644 --- a/client/api/cloud.go +++ b/client/api/cloud.go @@ -2,10 +2,12 @@ package api import ( "github.com/gin-gonic/gin" + "gitlink.org.cn/JointCloud/pcm-participant-ai/service" ) type cloudApi struct { *Api + *service.Service } var CloudApi = cloudApi{ diff --git a/client/router/cloud.go b/client/router/cloud.go index 9cc1ad6..7da1ded 100644 --- a/client/router/cloud.go +++ b/client/router/cloud.go @@ -1,6 +1,14 @@ package router -import "github.com/gin-gonic/gin" +import ( + "github.com/gin-gonic/gin" + "gitlink.org.cn/JointCloud/pcm-participant-client/api" +) func CloudRoutes(server *gin.Engine) { + cloud := server.Group("/cloud") + cloudApi := api.CloudApi + { + cloud.GET("/algorithm/get", cloud.TrainAlgorithmsHandler) + } } diff --git a/cloud/go.mod b/cloud/go.mod new file mode 100644 index 0000000..7aadc9c --- /dev/null +++ b/cloud/go.mod @@ -0,0 +1,3 @@ +module gitlink.org.cn/JointCloud/pcm-participant-cloud + +go 1.23.0 diff --git a/cloud/platform/interface.go b/cloud/platform/interface.go new file mode 100644 index 0000000..e9df05a --- /dev/null +++ b/cloud/platform/interface.go @@ -0,0 +1,7 @@ +package platform + +type IPlatform interface { + Type() Type + Name() string + Id() Id +} diff --git a/cloud/platform/platform.go b/cloud/platform/platform.go new file mode 100644 index 0000000..c5b8076 --- /dev/null +++ b/cloud/platform/platform.go @@ -0,0 +1,15 @@ +package platform + +const ( + Kubernetes Type = "Kubernetes" + Kubesphere Type = "Kubesphere" +) + +type Platform struct { + Name string `json:"name,omitempty"` + Id Id `json:"id,omitempty"` + Type Type `json:"type,omitempty"` +} + +type Type string +type Id int64 diff --git a/cloud/service/service.go b/cloud/service/service.go new file mode 100644 index 0000000..7011d57 --- /dev/null +++ b/cloud/service/service.go @@ -0,0 +1,16 @@ +package service + +import ( + "sync" +) + +type Service struct { + rlock sync.Mutex + dlock sync.Mutex + tlock sync.Mutex +} + +func NewService() (*Service, error) { + + return &Service{}, nil +} diff --git a/go.work.sum b/go.work.sum index f881e28..aab3fc9 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,6 +1,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= +github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -33,6 +35,7 @@ github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e h1:iWVPgObh6F4UDtjBLK51zsy5UHTPLQwCmsNjCsbKhQ0= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= @@ -41,18 +44,25 @@ golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= From 1e7046f44c80948a698e2276b5b324149ad482dd Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Fri, 27 Jun 2025 18:04:44 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecloud=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/api/cloud.go | 34 ++++++++++++++++++--- client/router/cloud.go | 7 ++++- cloud/go.mod | 66 +++++++++++++++++++++++++++++++++++++++- cloud/kubernetes.go | 56 ++++++++++++++++++++++++++++++++++ cloud/model/resp.go | 15 +++++++++ cloud/service/param.go | 17 +++++++++++ cloud/service/pod.go | 19 ++++++++++++ cloud/service/service.go | 18 ++++++++--- go.work | 1 + go.work.sum | 25 ++++++++++++--- 10 files changed, 243 insertions(+), 15 deletions(-) create mode 100644 cloud/kubernetes.go create mode 100644 cloud/model/resp.go create mode 100644 cloud/service/param.go create mode 100644 cloud/service/pod.go diff --git a/client/api/cloud.go b/client/api/cloud.go index abb095c..9240283 100644 --- a/client/api/cloud.go +++ b/client/api/cloud.go @@ -2,7 +2,10 @@ package api import ( "github.com/gin-gonic/gin" - "gitlink.org.cn/JointCloud/pcm-participant-ai/service" + cloud "gitlink.org.cn/JointCloud/pcm-participant-cloud" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/model" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/service" + "net/http" ) type cloudApi struct { @@ -11,20 +14,41 @@ type cloudApi struct { } var CloudApi = cloudApi{ - Api: BaseApi, + Api: BaseApi, + Service: initCloudSvc(), +} + +func initCloudSvc() *service.Service { + kubernetes := cloud.New("bearerToken", "https://192.168.1.1:6443") + svc, _ := service.NewService(kubernetes) + return svc } // SubmitHandler 统一作业提交接口 -func (h *cloudApi) SubmitHandler(c *gin.Context) { +func (cloud *cloudApi) SubmitHandler(c *gin.Context) { } // StatusHandler 统一状态查询接口 -func (h *cloudApi) StatusHandler(c *gin.Context) { +func (cloud *cloudApi) StatusHandler(c *gin.Context) { } // DetailHandler 查询作业详情接口 -func (h *cloudApi) DetailHandler(c *gin.Context) { +func (cloud *cloudApi) DetailHandler(c *gin.Context) { } + +func (cloud *cloudApi) ListPod(c *gin.Context) { + cloud.ListPod(c) + model.Response(c, http.StatusOK, "success", nil) +} + +func (cloud *cloudApi) CreateDeployment(c *gin.Context) { + var param service.CreateDeploymentParam + if err := c.ShouldBindJSON(¶m); err != nil { + model.Response(c, http.StatusBadRequest, "invalid request body", nil) + return + } + cloud.CreateDeployment(c, ¶m) +} diff --git a/client/router/cloud.go b/client/router/cloud.go index 7da1ded..b48eb0e 100644 --- a/client/router/cloud.go +++ b/client/router/cloud.go @@ -9,6 +9,11 @@ func CloudRoutes(server *gin.Engine) { cloud := server.Group("/cloud") cloudApi := api.CloudApi { - cloud.GET("/algorithm/get", cloud.TrainAlgorithmsHandler) + pod := cloud.Group("pod") + pod.GET("/list", cloudApi.ListPod) + } + { + deployment := cloud.Group("deployment") + deployment.POST("/create", cloudApi.CreateDeployment) } } diff --git a/cloud/go.mod b/cloud/go.mod index 7aadc9c..ee3108d 100644 --- a/cloud/go.mod +++ b/cloud/go.mod @@ -1,3 +1,67 @@ module gitlink.org.cn/JointCloud/pcm-participant-cloud -go 1.23.0 +go 1.24.0 + +require ( + github.com/gin-gonic/gin v1.10.1 + k8s.io/client-go v0.33.2 +) + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/time v0.9.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.33.2 // indirect + k8s.io/apimachinery v0.33.2 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) diff --git a/cloud/kubernetes.go b/cloud/kubernetes.go new file mode 100644 index 0000000..7694911 --- /dev/null +++ b/cloud/kubernetes.go @@ -0,0 +1,56 @@ +package cloud + +import ( + "fmt" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "time" +) + +type Option struct { + username string + token string + platform *platform.Platform +} +type Kubernetes struct { + opt *Option + DynamicClient *dynamic.DynamicClient + ClientSet *kubernetes.Clientset +} + +func New(bearerToken, url string) *Kubernetes { + restConfig := &rest.Config{ + Timeout: 10 * time.Second, + Host: url, + BearerToken: bearerToken, + TLSClientConfig: rest.TLSClientConfig{ + Insecure: true, + }, + } + dynamicClient, err := dynamic.NewForConfig(restConfig) + if err != nil { + fmt.Println(err.Error()) + } + clientSet, err := kubernetes.NewForConfig(restConfig) + if err != nil { + fmt.Println(err.Error()) + } + return &Kubernetes{ + DynamicClient: dynamicClient, + ClientSet: clientSet, + } +} + +func (k *Kubernetes) Type() platform.Type { + return k.opt.platform.Type +} + +func (k *Kubernetes) Id() platform.Id { + return k.opt.platform.Id +} + +func (k *Kubernetes) Name() string { + return k.opt.platform.Name +} diff --git a/cloud/model/resp.go b/cloud/model/resp.go new file mode 100644 index 0000000..ca40e29 --- /dev/null +++ b/cloud/model/resp.go @@ -0,0 +1,15 @@ +package model + +import ( + "github.com/gin-gonic/gin" + "net/http" +) + +func Response(c *gin.Context, code int, msg interface{}, data interface{}) { + c.JSON(http.StatusOK, map[string]interface{}{ + "code": code, + "msg": msg, + "data": data, + }) + return +} diff --git a/cloud/service/param.go b/cloud/service/param.go new file mode 100644 index 0000000..1a5cccd --- /dev/null +++ b/cloud/service/param.go @@ -0,0 +1,17 @@ +package service + +import ( + "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + v1 "k8s.io/api/apps/v1" + v2 "k8s.io/api/core/v1" +) + +type CreateDeploymentParam struct { + Id *platform.Id `json:"id" form:"id"` + Deployment v1.Deployment `json:"deployment" form:"deployment"` +} + +type CreatePodParam struct { + Id *platform.Id `json:"id" form:"id"` + Pod v2.Pod `json:"pod" form:"pod"` +} diff --git a/cloud/service/pod.go b/cloud/service/pod.go new file mode 100644 index 0000000..56224e4 --- /dev/null +++ b/cloud/service/pod.go @@ -0,0 +1,19 @@ +package service + +import ( + "context" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +type Pod struct { +} + +func ListPod(clientSet *kubernetes.Clientset, options metav1.ListOptions) (*v1.PodList, error) { + podList, err := clientSet.CoreV1().Pods("").List(context.Background(), options) + if err != nil { + return nil, err + } + return podList, nil +} diff --git a/cloud/service/service.go b/cloud/service/service.go index 7011d57..6dd7567 100644 --- a/cloud/service/service.go +++ b/cloud/service/service.go @@ -1,16 +1,26 @@ package service import ( + "context" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" "sync" ) type Service struct { - rlock sync.Mutex - dlock sync.Mutex - tlock sync.Mutex + podMap map[platform.Id]*platform.Pod + rlock sync.Mutex + dlock sync.Mutex + tlock sync.Mutex } -func NewService() (*Service, error) { +func NewService(platform platform.IPlatform) (*Service, error) { return &Service{}, nil } +func (s *Service) ListPod(ctx context.Context) { + s.ListPod(ctx) +} + +func (s *Service) CreateDeployment(ctx context.Context) { + +} diff --git a/go.work b/go.work index 1c9ae5d..af7f360 100644 --- a/go.work +++ b/go.work @@ -10,6 +10,7 @@ use ( ./participant/openI ./platform hpc + ./cloud ) replace gitlink.org.cn/JointCloud/pcm-participant-common v0.0.0 => ./common diff --git a/go.work.sum b/go.work.sum index aab3fc9..0826978 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,21 +1,33 @@ +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86 h1:D6paGObi5Wud7xg83MaEFyjxQB1W5bz5d0IFppr+ymk= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c h1:bY6ktFuJkt+ZXkX0RChQch2FtHpWQLVS8Qo1YasiIVk= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= @@ -27,34 +39,38 @@ github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvq github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e h1:iWVPgObh6F4UDtjBLK51zsy5UHTPLQwCmsNjCsbKhQ0= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= @@ -65,9 +81,10 @@ golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= nullprogram.com/x/optparse v1.0.0 h1:xGFgVi5ZaWOnYdac2foDT3vg0ZZC9ErXFV57mr4OHrI= rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= From 0a88eb74aeab1192815c349066235b451a49ff54 Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Wed, 2 Jul 2025 10:20:34 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecloud=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/api/cloud.go | 9 ++++----- client/router/cloud.go | 5 +++-- cloud/go.mod | 4 ++-- cloud/pod/interface.go | 18 ++++++++++++++++++ cloud/pod/pod.go | 13 +++++++++++++ cloud/{ => service}/kubernetes.go | 11 ++++++++++- cloud/service/param.go | 4 ++-- cloud/service/pod.go | 19 ------------------- cloud/service/service.go | 30 ++++++++++++++++++------------ go.work.sum | 26 ++++++++++++++++++++------ 10 files changed, 90 insertions(+), 49 deletions(-) create mode 100644 cloud/pod/interface.go create mode 100644 cloud/pod/pod.go rename cloud/{ => service}/kubernetes.go (79%) delete mode 100644 cloud/service/pod.go diff --git a/client/api/cloud.go b/client/api/cloud.go index 9240283..a21c576 100644 --- a/client/api/cloud.go +++ b/client/api/cloud.go @@ -2,7 +2,6 @@ package api import ( "github.com/gin-gonic/gin" - cloud "gitlink.org.cn/JointCloud/pcm-participant-cloud" "gitlink.org.cn/JointCloud/pcm-participant-cloud/model" "gitlink.org.cn/JointCloud/pcm-participant-cloud/service" "net/http" @@ -19,7 +18,7 @@ var CloudApi = cloudApi{ } func initCloudSvc() *service.Service { - kubernetes := cloud.New("bearerToken", "https://192.168.1.1:6443") + kubernetes := service.New("bearerToken", "https://192.168.1.1:6443") svc, _ := service.NewService(kubernetes) return svc } @@ -44,11 +43,11 @@ func (cloud *cloudApi) ListPod(c *gin.Context) { model.Response(c, http.StatusOK, "success", nil) } -func (cloud *cloudApi) CreateDeployment(c *gin.Context) { - var param service.CreateDeploymentParam +func (cloud *cloudApi) CreatePodHandler(c *gin.Context) { + var param service.CreatePodParam if err := c.ShouldBindJSON(¶m); err != nil { model.Response(c, http.StatusBadRequest, "invalid request body", nil) return } - cloud.CreateDeployment(c, ¶m) + cloud.CreatePod(c, ¶m) } diff --git a/client/router/cloud.go b/client/router/cloud.go index b48eb0e..3f5202e 100644 --- a/client/router/cloud.go +++ b/client/router/cloud.go @@ -11,9 +11,10 @@ func CloudRoutes(server *gin.Engine) { { pod := cloud.Group("pod") pod.GET("/list", cloudApi.ListPod) + pod.POST("/create", cloudApi.CreatePodHandler) } { - deployment := cloud.Group("deployment") - deployment.POST("/create", cloudApi.CreateDeployment) + //deployment := cloud.Group("deployment") + //deployment.POST("/create", cloudApi.CreateDeployment) } } diff --git a/cloud/go.mod b/cloud/go.mod index ee3108d..e6888ec 100644 --- a/cloud/go.mod +++ b/cloud/go.mod @@ -4,6 +4,8 @@ go 1.24.0 require ( github.com/gin-gonic/gin v1.10.1 + k8s.io/api v0.33.2 + k8s.io/apimachinery v0.33.2 k8s.io/client-go v0.33.2 ) @@ -55,8 +57,6 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.33.2 // indirect - k8s.io/apimachinery v0.33.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect diff --git a/cloud/pod/interface.go b/cloud/pod/interface.go new file mode 100644 index 0000000..e1ebe2f --- /dev/null +++ b/cloud/pod/interface.go @@ -0,0 +1,18 @@ +package pod + +import ( + "context" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/service" + v1 "k8s.io/api/core/v1" +) + +type IPod interface { + List(ctx context.Context) (*v1.PodList, error) + Detail(ctx context.Context) (*v1.Pod, error) + Create(ctx context.Context, param *service.CreatePodParam) +} + +type ISpec interface { + Spec() (*Pod, error) + Detail() (interface{}, error) +} diff --git a/cloud/pod/pod.go b/cloud/pod/pod.go new file mode 100644 index 0000000..e76c8c0 --- /dev/null +++ b/cloud/pod/pod.go @@ -0,0 +1,13 @@ +package pod + +import ( + "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + v1 "k8s.io/api/core/v1" +) + +type Pods []ISpec + +type Pod struct { + Platform *platform.Platform `json:"platform,omitempty"` + Pod *v1.Pod `json:"pod,omitempty"` +} diff --git a/cloud/kubernetes.go b/cloud/service/kubernetes.go similarity index 79% rename from cloud/kubernetes.go rename to cloud/service/kubernetes.go index 7694911..ffa4a99 100644 --- a/cloud/kubernetes.go +++ b/cloud/service/kubernetes.go @@ -1,8 +1,10 @@ -package cloud +package service import ( + "context" "fmt" "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -42,6 +44,13 @@ func New(bearerToken, url string) *Kubernetes { ClientSet: clientSet, } } +func (k *Kubernetes) CreatePod(ctx context.Context, param *CreatePodParam) error { + _, err := k.ClientSet.CoreV1().Pods("").Create(ctx, param.Pod, metav1.CreateOptions{}) + if err != nil { + return err + } + return nil +} func (k *Kubernetes) Type() platform.Type { return k.opt.platform.Type diff --git a/cloud/service/param.go b/cloud/service/param.go index 1a5cccd..bd3dec4 100644 --- a/cloud/service/param.go +++ b/cloud/service/param.go @@ -12,6 +12,6 @@ type CreateDeploymentParam struct { } type CreatePodParam struct { - Id *platform.Id `json:"id" form:"id"` - Pod v2.Pod `json:"pod" form:"pod"` + Id platform.Id `json:"id" form:"id"` + Pod *v2.Pod `json:"pod" form:"pod"` } diff --git a/cloud/service/pod.go b/cloud/service/pod.go deleted file mode 100644 index 56224e4..0000000 --- a/cloud/service/pod.go +++ /dev/null @@ -1,19 +0,0 @@ -package service - -import ( - "context" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" -) - -type Pod struct { -} - -func ListPod(clientSet *kubernetes.Clientset, options metav1.ListOptions) (*v1.PodList, error) { - podList, err := clientSet.CoreV1().Pods("").List(context.Background(), options) - if err != nil { - return nil, err - } - return podList, nil -} diff --git a/cloud/service/service.go b/cloud/service/service.go index 6dd7567..82b6e04 100644 --- a/cloud/service/service.go +++ b/cloud/service/service.go @@ -3,24 +3,30 @@ package service import ( "context" "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + "sync" ) type Service struct { - podMap map[platform.Id]*platform.Pod - rlock sync.Mutex - dlock sync.Mutex - tlock sync.Mutex + clientMap map[platform.Id]*Kubernetes + rlock sync.Mutex + dlock sync.Mutex + tlock sync.Mutex } -func NewService(platform platform.IPlatform) (*Service, error) { +func NewService(platforms ...platform.IPlatform) (*Service, error) { + clientMap := map[platform.Id]*Kubernetes{} + for _, platform := range platforms { + kubernetes, ok := platform.(*Kubernetes) + if !ok { - return &Service{}, nil + } + clientMap[platform.Id()] = kubernetes + } + return &Service{ + clientMap: clientMap, + }, nil } -func (s *Service) ListPod(ctx context.Context) { - s.ListPod(ctx) -} - -func (s *Service) CreateDeployment(ctx context.Context) { - +func (s *Service) CreatePod(ctx context.Context, param *CreatePodParam) { + s.clientMap[param.Id].CreatePod(ctx, param) } diff --git a/go.work.sum b/go.work.sum index 0826978..47f6637 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,33 +1,43 @@ +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86 h1:D6paGObi5Wud7xg83MaEFyjxQB1W5bz5d0IFppr+ymk= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c h1:bY6ktFuJkt+ZXkX0RChQch2FtHpWQLVS8Qo1YasiIVk= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= @@ -45,13 +55,14 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e h1:iWVPgObh6F4UDtjBLK51zsy5UHTPLQwCmsNjCsbKhQ0= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= @@ -64,12 +75,14 @@ golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= @@ -84,7 +97,8 @@ golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7 h1:cErOOTkQ3JW19o4lo91fFurouhP8NcoBvb7CkvhZZpk= +k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= nullprogram.com/x/optparse v1.0.0 h1:xGFgVi5ZaWOnYdac2foDT3vg0ZZC9ErXFV57mr4OHrI= rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= From 04961dc67ad4689d8deb449a0009c3faec6a8838 Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Wed, 2 Jul 2025 18:27:24 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecloud=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/api/cloud.go | 53 ------- client/router/cloud.go | 2 +- cloud/cloud.go | 77 ++++++++++ cloud/{pod/pod.go => container/container.go} | 4 +- cloud/{pod => container}/interface.go | 2 +- cloud/go.mod | 4 + cloud/service/param.go | 2 +- cloud/task/interface.go | 20 +++ cloud/task/task.go | 25 ++++ go.work | 8 +- go.work.sum | 150 ++++++++++++++++++- 11 files changed, 280 insertions(+), 67 deletions(-) delete mode 100644 client/api/cloud.go create mode 100644 cloud/cloud.go rename cloud/{pod/pod.go => container/container.go} (71%) rename cloud/{pod => container}/interface.go (95%) create mode 100644 cloud/task/interface.go create mode 100644 cloud/task/task.go diff --git a/client/api/cloud.go b/client/api/cloud.go deleted file mode 100644 index a21c576..0000000 --- a/client/api/cloud.go +++ /dev/null @@ -1,53 +0,0 @@ -package api - -import ( - "github.com/gin-gonic/gin" - "gitlink.org.cn/JointCloud/pcm-participant-cloud/model" - "gitlink.org.cn/JointCloud/pcm-participant-cloud/service" - "net/http" -) - -type cloudApi struct { - *Api - *service.Service -} - -var CloudApi = cloudApi{ - Api: BaseApi, - Service: initCloudSvc(), -} - -func initCloudSvc() *service.Service { - kubernetes := service.New("bearerToken", "https://192.168.1.1:6443") - svc, _ := service.NewService(kubernetes) - return svc -} - -// SubmitHandler 统一作业提交接口 -func (cloud *cloudApi) SubmitHandler(c *gin.Context) { - -} - -// StatusHandler 统一状态查询接口 -func (cloud *cloudApi) StatusHandler(c *gin.Context) { - -} - -// DetailHandler 查询作业详情接口 -func (cloud *cloudApi) DetailHandler(c *gin.Context) { - -} - -func (cloud *cloudApi) ListPod(c *gin.Context) { - cloud.ListPod(c) - model.Response(c, http.StatusOK, "success", nil) -} - -func (cloud *cloudApi) CreatePodHandler(c *gin.Context) { - var param service.CreatePodParam - if err := c.ShouldBindJSON(¶m); err != nil { - model.Response(c, http.StatusBadRequest, "invalid request body", nil) - return - } - cloud.CreatePod(c, ¶m) -} diff --git a/client/router/cloud.go b/client/router/cloud.go index 3f5202e..2be6807 100644 --- a/client/router/cloud.go +++ b/client/router/cloud.go @@ -9,7 +9,7 @@ func CloudRoutes(server *gin.Engine) { cloud := server.Group("/cloud") cloudApi := api.CloudApi { - pod := cloud.Group("pod") + pod := cloud.Group("container") pod.GET("/list", cloudApi.ListPod) pod.POST("/create", cloudApi.CreatePodHandler) } diff --git a/cloud/cloud.go b/cloud/cloud.go new file mode 100644 index 0000000..0e382de --- /dev/null +++ b/cloud/cloud.go @@ -0,0 +1,77 @@ +package ai + +import ( + "github.com/hashicorp/yamux" + "log" + "net" + "net/http" +) + +func startYamuxClient(serverAddr string) { + // 连接到A服务器 + conn, err := net.Dial("tcp", serverAddr) + if err != nil { + log.Fatal("连接A服务器失败:", err) + } + log.Printf("已成功连接到A服务器: %s", serverAddr) + + // 建立yamux会话 + session, err := yamux.Client(conn, nil) + if err != nil { + log.Fatal(err) + } + + // 保持连接并处理请求 + for { + stream, err := session.Accept() + if err != nil { + log.Println("accept error:", err) + continue + } + go handleRequest(stream) + } + +} + +func handleRequest(stream net.Conn) { + log.Printf("收到新连接: 来自 %s", stream.RemoteAddr()) + + mux := http.NewServeMux() + + mux.HandleFunc("/api/test", func(w http.ResponseWriter, r *http.Request) { + log.Printf("请求头: %v", r.Header) + log.Printf("处理测试接口请求") + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"status":"success","message":"测试接口响应"}`)) + }) + + // 添加默认404处理 + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotFound) + w.Write([]byte("404 - 接口不存在")) + }) + + http.Serve(&singleConnListener{conn: stream}, mux) +} + +type singleConnListener struct { + conn net.Conn +} + +func (l *singleConnListener) Accept() (net.Conn, error) { + return l.conn, nil +} + +func (l *singleConnListener) Close() error { + return nil +} + +func (l *singleConnListener) Addr() net.Addr { + return l.conn.LocalAddr() +} + +func main() { + // 这里可以添加命令行参数解析 + serverAddr := "client_url:1234" // P端Client服务地址 + startYamuxClient(serverAddr) +} diff --git a/cloud/pod/pod.go b/cloud/container/container.go similarity index 71% rename from cloud/pod/pod.go rename to cloud/container/container.go index e76c8c0..bb3d204 100644 --- a/cloud/pod/pod.go +++ b/cloud/container/container.go @@ -1,4 +1,4 @@ -package pod +package container import ( "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" @@ -9,5 +9,5 @@ type Pods []ISpec type Pod struct { Platform *platform.Platform `json:"platform,omitempty"` - Pod *v1.Pod `json:"pod,omitempty"` + Pod *v1.Pod `json:"container,omitempty"` } diff --git a/cloud/pod/interface.go b/cloud/container/interface.go similarity index 95% rename from cloud/pod/interface.go rename to cloud/container/interface.go index e1ebe2f..31e6ba7 100644 --- a/cloud/pod/interface.go +++ b/cloud/container/interface.go @@ -1,4 +1,4 @@ -package pod +package container import ( "context" diff --git a/cloud/go.mod b/cloud/go.mod index e6888ec..40b0369 100644 --- a/cloud/go.mod +++ b/cloud/go.mod @@ -10,6 +10,7 @@ require ( ) require ( + github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect @@ -31,6 +32,7 @@ require ( github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect @@ -40,6 +42,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect @@ -56,6 +59,7 @@ require ( google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect diff --git a/cloud/service/param.go b/cloud/service/param.go index bd3dec4..dd91ed8 100644 --- a/cloud/service/param.go +++ b/cloud/service/param.go @@ -13,5 +13,5 @@ type CreateDeploymentParam struct { type CreatePodParam struct { Id platform.Id `json:"id" form:"id"` - Pod *v2.Pod `json:"pod" form:"pod"` + Pod *v2.Pod `json:"container" form:"container"` } diff --git a/cloud/task/interface.go b/cloud/task/interface.go new file mode 100644 index 0000000..ba68bd3 --- /dev/null +++ b/cloud/task/interface.go @@ -0,0 +1,20 @@ +package task + +import "context" + +type Task interface { + Infer + Train +} + +type Infer interface { + Infer(ctx context.Context, params *InferParams) (Result, error) +} + +type Train interface { + Train(ctx context.Context, params *TrainParams) (Result, error) +} + +type Result interface { + Get(ctx context.Context, id string) error +} diff --git a/cloud/task/task.go b/cloud/task/task.go new file mode 100644 index 0000000..448fd3a --- /dev/null +++ b/cloud/task/task.go @@ -0,0 +1,25 @@ +package task + +import ( + "gitlink.org.cn/JointCloud/pcm-participant-ai/algorithm" + "gitlink.org.cn/JointCloud/pcm-participant-ai/dataset" + "gitlink.org.cn/JointCloud/pcm-participant-ai/image" + "gitlink.org.cn/JointCloud/pcm-participant-ai/resource" +) + +type ContainerParams struct { + TaskName string + Desc string + Resource resource.TrainParameter + Image image.TrainParameter + Dataset dataset.TrainParameter + Algorithm algorithm.TrainParameter +} + +type InferParams struct { + TaskName string + Desc string + Resource resource.TrainParameter + Image image.TrainParameter + Algorithm algorithm.TrainParameter +} diff --git a/go.work b/go.work index 5ab0723..87e2fb9 100644 --- a/go.work +++ b/go.work @@ -1,17 +1,15 @@ -go 1.23.0 - -toolchain go1.24.0 +go 1.24.0 use ( ./ai ./client + ./cloud ./common + ./jcs ./participant ./participant/openI ./platform - ./jcs hpc - ./cloud ) replace gitlink.org.cn/JointCloud/pcm-participant-common v0.0.0 => ./common diff --git a/go.work.sum b/go.work.sum index aab3fc9..8790c0b 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,73 +1,215 @@ +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= +github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= +github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= +github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90 h1:WXb3TSNmHp2vHoCroCIB1foO/yQ36swABL8aOVeDpgg= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= +github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= +github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= +github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= +github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= +github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8= +github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d h1:lBXNCxVENCipq4D1Is42JVOP4eQjlB8TQ6H69Yx5J9Q= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5 h1:PJr+ZMXIecYc1Ey2zucXdR73SMBtgjPgwa31099IMv0= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86 h1:D6paGObi5Wud7xg83MaEFyjxQB1W5bz5d0IFppr+ymk= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c h1:bY6ktFuJkt+ZXkX0RChQch2FtHpWQLVS8Qo1YasiIVk= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= +github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636 h1:aSISeOcal5irEhJd1M+IrApc0PdcN7e7Aj4yuEnOrfQ= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= +golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e h1:iWVPgObh6F4UDtjBLK51zsy5UHTPLQwCmsNjCsbKhQ0= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b h1:Qh4dB5D/WpoUUp3lSod7qgoyEHbDGPUWjIbnqdqqe1k= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7 h1:cErOOTkQ3JW19o4lo91fFurouhP8NcoBvb7CkvhZZpk= +k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= nullprogram.com/x/optparse v1.0.0 h1:xGFgVi5ZaWOnYdac2foDT3vg0ZZC9ErXFV57mr4OHrI= rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= From 27052db278700251eabf4d3efbe63acc2494097d Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Fri, 4 Jul 2025 16:10:23 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecloud=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.work | 3 + participant/eci/apis/container.go | 39 ++++++++ participant/eci/app.go | 13 +++ participant/eci/common/client.go | 80 +++++++++++++++++ participant/eci/common/const.go | 75 ++++++++++++++++ participant/eci/common/types.go | 12 +++ participant/eci/common/util.go | 88 ++++++++++++++++++ participant/eci/go.mod | 3 + participant/eci/initialize/common.go | 9 ++ participant/eci/model/container.go | 20 +++++ participant/eci/model/error.go | 29 ++++++ participant/eci/model/response.go | 15 ++++ participant/eci/router/router.go | 58 ++++++++++++ participant/eci/service/container.go | 30 +++++++ participant/eci/service/service.go | 3 + participant/k8s/apis/container.go | 17 ++++ participant/k8s/app.go | 13 +++ participant/k8s/common/client.go | 80 +++++++++++++++++ participant/k8s/common/const.go | 74 +++++++++++++++ participant/k8s/common/types.go | 12 +++ participant/k8s/common/util.go | 92 +++++++++++++++++++ participant/k8s/go.mod | 7 ++ participant/k8s/initialize/common.go | 9 ++ participant/k8s/model/container.go | 11 +++ participant/k8s/model/error.go | 29 ++++++ participant/k8s/router/router.go | 59 ++++++++++++ participant/serverless/apis/container.go | 7 ++ participant/serverless/common/client.go | 80 +++++++++++++++++ participant/serverless/common/const.go | 74 +++++++++++++++ participant/serverless/common/types.go | 12 +++ participant/serverless/common/util.go | 88 ++++++++++++++++++ participant/serverless/go.mod | 37 ++++++++ participant/serverless/model/container.go | 105 ++++++++++++++++++++++ participant/serverless/model/error.go | 29 ++++++ participant/serverless/model/response.go | 15 ++++ participant/serverless/router/router.go | 59 ++++++++++++ 36 files changed, 1386 insertions(+) create mode 100644 participant/eci/apis/container.go create mode 100644 participant/eci/app.go create mode 100644 participant/eci/common/client.go create mode 100644 participant/eci/common/const.go create mode 100644 participant/eci/common/types.go create mode 100644 participant/eci/common/util.go create mode 100644 participant/eci/go.mod create mode 100644 participant/eci/initialize/common.go create mode 100644 participant/eci/model/container.go create mode 100644 participant/eci/model/error.go create mode 100644 participant/eci/model/response.go create mode 100644 participant/eci/router/router.go create mode 100644 participant/eci/service/container.go create mode 100644 participant/eci/service/service.go create mode 100644 participant/k8s/apis/container.go create mode 100644 participant/k8s/app.go create mode 100644 participant/k8s/common/client.go create mode 100644 participant/k8s/common/const.go create mode 100644 participant/k8s/common/types.go create mode 100644 participant/k8s/common/util.go create mode 100644 participant/k8s/go.mod create mode 100644 participant/k8s/initialize/common.go create mode 100644 participant/k8s/model/container.go create mode 100644 participant/k8s/model/error.go create mode 100644 participant/k8s/router/router.go create mode 100644 participant/serverless/apis/container.go create mode 100644 participant/serverless/common/client.go create mode 100644 participant/serverless/common/const.go create mode 100644 participant/serverless/common/types.go create mode 100644 participant/serverless/common/util.go create mode 100644 participant/serverless/go.mod create mode 100644 participant/serverless/model/container.go create mode 100644 participant/serverless/model/error.go create mode 100644 participant/serverless/model/response.go create mode 100644 participant/serverless/router/router.go diff --git a/go.work b/go.work index 87e2fb9..bb4e9d3 100644 --- a/go.work +++ b/go.work @@ -7,7 +7,10 @@ use ( ./common ./jcs ./participant + ./participant/eci + ./participant/k8s ./participant/openI + ./participant/serverless ./platform hpc ) diff --git a/participant/eci/apis/container.go b/participant/eci/apis/container.go new file mode 100644 index 0000000..efdfb40 --- /dev/null +++ b/participant/eci/apis/container.go @@ -0,0 +1,39 @@ +package apis + +import ( + "github.com/gin-gonic/gin" + "gitlink.org.cn/JointCloud/pcm-participant-eci/common" + "gitlink.org.cn/JointCloud/pcm-participant-eci/model" + "gitlink.org.cn/JointCloud/pcm-participant-eci/service" + "net/http" +) + +func CreateContainer(ctx *gin.Context) { + var param model.CreateContainerParam + if err := ctx.BindJSON(¶m); err != nil { + model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, err) + return + } + ip := ctx.Query(common.IPADDR) + if ip == "" { + model.Response(ctx, 401, "addr为必填字段", nil) + return + } + token := ctx.Query(common.ACCESSTOKEN) + if token == "" { + model.Response(ctx, 401, "token为必填字段", nil) + return + } + resp, err := service.CreateContainer(ip, token, ¶m) + if err != nil { + return + } + if !resp.Success { + if resp.Error != nil { + model.Response(ctx, 500, common.INVOKEERROR, resp.Error) + return + } + } + + model.Response(ctx, http.StatusOK, common.SUCCESS, resp.Payload) +} diff --git a/participant/eci/app.go b/participant/eci/app.go new file mode 100644 index 0000000..359cdeb --- /dev/null +++ b/participant/eci/app.go @@ -0,0 +1,13 @@ +package openI + +import ( + "gitlink.org.cn/JointCloud/pcm-participant-eci/initialize" + "gitlink.org.cn/JointCloud/pcm-participant-eci/router" +) + +func main() { + //初始化公共配置 + initialize.InitConfig() + rt, _ := router.Create(nil) + _ = rt.Run(":2028") +} diff --git a/participant/eci/common/client.go b/participant/eci/common/client.go new file mode 100644 index 0000000..c315031 --- /dev/null +++ b/participant/eci/common/client.go @@ -0,0 +1,80 @@ +package common + +import ( + "crypto/tls" + "errors" + "fmt" + "gitlink.org.cn/JointCloud/pcm-participant-eci/model" + "net/http" + "time" + + "github.com/go-resty/resty/v2" +) + +var ( + NoRedirectClient *resty.Client + RestyClient *resty.Client + HttpClient *http.Client +) +var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" +var DefaultTimeout = time.Second * 300 + +func InitClient() { + NoRedirectClient = resty.New().SetRedirectPolicy( + resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }), + ).SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) + NoRedirectClient.SetHeader("user-agent", UserAgent) + + RestyClient = NewRestyClient() + HttpClient = NewHttpClient() +} + +func NewRestyClient() *resty.Client { + client := resty.New(). + SetHeader("user-agent", UserAgent). + SetRetryCount(3). + SetRetryResetReaders(true). + SetTimeout(DefaultTimeout). + SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) + return client +} + +func NewHttpClient() *http.Client { + return &http.Client{ + Timeout: time.Hour * 48, + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } +} + +func Request(url string, method string, callback ReqCallback) ([]byte, error) { + respErr := &model.RespErr{} + req := RestyClient.R(). + SetHeaders(map[string]string{ + "Content-Type": "application/json", + }). + SetError(&respErr) + + if callback != nil { + callback(req) + } + + res, err := req.Execute(method, OPENIPREFIX+url) + + if err != nil { + return nil, err + } + if respErr.Message != "" { + return nil, errors.New(respErr.Message) + } + + if res.StatusCode() != http.StatusOK && res.StatusCode() != http.StatusCreated { + return nil, errors.New(fmt.Sprintf("msg: %s, status: %d", res.String(), res.StatusCode())) + } + + return res.Body(), nil +} diff --git a/participant/eci/common/const.go b/participant/eci/common/const.go new file mode 100644 index 0000000..0bbe831 --- /dev/null +++ b/participant/eci/common/const.go @@ -0,0 +1,75 @@ +package common + +const ( + MaxChunkSize int64 = 1024 * 1024 * 64 //64MB + + QUESTION_MARK = "?" + TIMEOUT = 10 + OPENIPREFIX = "https://openi.pcl.ac.cn" + ACCESSTOKEN = "access_token" + IPADDR = "addr" + // user + USERINFO = "/api/v1/user" + Forward_Slash = "/" + // repo + REPO = "/api/v1/user/repos" + RepoFile = "/api/v1/repos/{username}/{reponame}/contents/{filepath}" //上传文件到项目中、修改项目中的文件内容 + + // image + IMAGERECOMMENDED = "/api/v1/images/recommend" + IMAGECUSTOM = "/api/v1/images/custom" + IMAGESTARED = "/api/v1/images/star" + + // datasets + DATASETCURRENT = "/api/v1/datasets/{username}/{reponame}/current_repo" //查询当前项目的数据集接口 + DATASETMINE = "/api/v1/datasets/{username}/{reponame}/my_datasets" //我上传的数据集 + DATASETPUBLIC = "/api/v1/datasets/{username}/{reponame}/public_datasets" //查询公开数据集 + DATASETFAVORITE = "/api/v1/datasets/{username}/{reponame}/my_favorite" //查询我收藏的数据集 + DATASETEXISTEXPORT = "/api/v1/datasets/{username}/{reponame}/model/export_exist_dataset" //将用户选择的文件从训练任务结果中导出到数据集中 POST请求 + DATASETCREATE = "/api/v1/datasets/{username}/{reponame}/create" // + BaseDatasetsUrl = "/api/v1/datasets/{username}/{reponame}" //数据集列表 //数据集基本接口 + CreateContainer = "" + // datasets upload + GetChunksUrl = "/api/v1/attachments/get_chunks" //获取当前需要上传文件的chunk信息 + NewMultipartUrl = "/api/v1/attachments/new_multipart" //获取文件上传的需要的信息 + GetMultipartUrl = "/api/v1/attachments/get_multipart_url" //获取文件上传的地址 + CompleteMultipartUrl = "/api/v1/attachments/complete_multipart" //完成上传接口 //上传文件到数据集 + + // task + TASKCREATIONREQUIRED = "/api/v1/{username}/{reponame}/ai_task/creation/required" // 查询创建任务所需资源接口 + TASKCREATIONIMAGEBYSPEC = "/api/v1/{username}/{reponame}/ai_task/creation/image_by_spec" // 根据选择的规格获取镜像(计算资源是NPU时使用) + TASKCREATE = "/api/v1/{username}/{reponame}/ai_task/create" // 创建任务 + TASKLIST = "/api/v1/{username}/{reponame}/ai_task/list" // 任务列表 + TASKDETAIL = "/api/v1/{username}/{reponame}/ai_task" // 查询任务详情 + TASKSTOP = "/api/v1/{username}/{reponame}/ai_task/stop" // 停止任务接口 + TASKOUTPUT = "/api/v1/{username}/{reponame}/ai_task/output" // 查询结果列表接口 + TASKRESULTDOWNLOAD = "/api/v1/{username}/{reponame}/ai_task/output/download/all" // 所有结果下载接口 + TASKLOGDOWNLOAD = "/api/v1/{username}/{reponame}/ai_task/log/download" //日志下载 + SelfEndpointUrl = "/api/v1/{username}/{reponame}/ai_task/self_endpoint_url" //在线推理接口 + + // model + MODELCREATE = "/api/v1/repos/{username}/{reponame}/modelmanage/create_new_model" //模型新增接口 + MODELGETBYID = "/api/v1/repos/{username}/{reponame}/modelmanage/query_model_byId" //根据模型ID查询模型信息接口 + MODELDOWNLOADBYID = "/api/v1/repos/{username}/{reponame}/modelmanage/downloadall" + QUERYMODELBYNAME = "/api/v1/repos/{username}/{reponame}/modelmanage/query_model_byName" //根据模型名称查询模型 + PageModel = "/api/v1/repos/{username}/{reponame}/modelmanage/show_model_api" //分页查询模型 + QueryAllModelFile = "/api/v1/all_model_data" //查询所有模型文件 + + // model local create + MODELLOCALCREATE = "/api/v1/repos/{username}/{reponame}/modelmanage/create_local_model" //创建一条本地模型记录 + MODELLOCALGETUPLOADEDCHUNKS = "/api/v1/attachments/model/get_chunks" //获取该文件已经上传的分片接口 + MODELLOCALNEWMULTIPART = "/api/v1/attachments/model/new_multipart" //开启一个本地模型上传 + MODELLOCALGETMULTIPARTURL = "/api/v1/attachments/model/get_multipart_url" //获取模型分片传输链接,并进行上传 + MODELLOCALCOMPLETEMULTIPART = "/api/v1/attachments/model/complete_multipart" //完成模型文件上传 +) + +const ( + SUCCESS = "success" +) + +// error +const ( + INVOKEERROR = "failed to invoke" + INVALIDPARAMS = "invalid Request params" + NOTFOUND = "not found" +) diff --git a/participant/eci/common/types.go b/participant/eci/common/types.go new file mode 100644 index 0000000..b8dffad --- /dev/null +++ b/participant/eci/common/types.go @@ -0,0 +1,12 @@ +package common + +import "github.com/go-resty/resty/v2" + +type Json map[string]interface{} + +type TokenResp struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` +} + +type ReqCallback func(req *resty.Request) diff --git a/participant/eci/common/util.go b/participant/eci/common/util.go new file mode 100644 index 0000000..b0eaeed --- /dev/null +++ b/participant/eci/common/util.go @@ -0,0 +1,88 @@ +package common + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "github.com/go-resty/resty/v2" + "io" + "mime/multipart" + "reflect" + "strconv" + "time" +) + +func GetRestyRequest(timeoutSeconds int64) *resty.Request { + client := resty.New().SetTimeout(time.Duration(timeoutSeconds) * time.Second) + request := client.R() + return request +} + +func GetFileMd5(file multipart.File) (string, error) { + hash := md5.New() + if _, err := io.Copy(hash, file); err != nil { + return "", err + } + + // 计算MD5并转换为16进制字符串 + md5Bytes := hash.Sum(nil) + md5Str := hex.EncodeToString(md5Bytes) + return md5Str, nil +} + +func Bool2String(b bool) string { + return strconv.FormatBool(b) +} + +// StructToMapWithTag 将结构体转换为 map[string]string,key 使用指定标签的值 +func StructToMapWithTag(obj interface{}, tagName string) (map[string]string, error) { + result := make(map[string]string) + + // 获取值的反射对象 + val := reflect.ValueOf(obj) + if val.Kind() == reflect.Ptr { + val = val.Elem() // 解引用指针 + } + + if val.Kind() != reflect.Struct { + return nil, fmt.Errorf("input is not a struct or pointer to struct") + } + + // 获取类型信息 + typ := val.Type() + + // 遍历结构体字段 + for i := 0; i < val.NumField(); i++ { + field := val.Field(i) + fieldType := typ.Field(i) + + // 获取字段的标签值 + tagValue := fieldType.Tag.Get(tagName) + if tagValue == "" { + continue // 如果标签不存在,跳过该字段 + } + + // 获取字段值并转换为字符串 + var fieldValue string + switch field.Kind() { + case reflect.String: + fieldValue = field.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fieldValue = strconv.FormatInt(field.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + fieldValue = strconv.FormatUint(field.Uint(), 10) + case reflect.Float32, reflect.Float64: + fieldValue = strconv.FormatFloat(field.Float(), 'f', -1, 64) + case reflect.Bool: + fieldValue = strconv.FormatBool(field.Bool()) + default: + // 如果字段类型不支持,跳过 + continue + } + + // 将标签值和字段值存入 map + result[tagValue] = fieldValue + } + + return result, nil +} diff --git a/participant/eci/go.mod b/participant/eci/go.mod new file mode 100644 index 0000000..54ebdf8 --- /dev/null +++ b/participant/eci/go.mod @@ -0,0 +1,3 @@ +module gitlink.org.cn/JointCloud/pcm-participant-eci + +go 1.22.0 diff --git a/participant/eci/initialize/common.go b/participant/eci/initialize/common.go new file mode 100644 index 0000000..fb9f665 --- /dev/null +++ b/participant/eci/initialize/common.go @@ -0,0 +1,9 @@ +package initialize + +import ( + "gitlink.org.cn/JointCloud/pcm-participant-eci/common" +) + +func InitConfig() { + common.InitClient() +} diff --git a/participant/eci/model/container.go b/participant/eci/model/container.go new file mode 100644 index 0000000..6fc05d5 --- /dev/null +++ b/participant/eci/model/container.go @@ -0,0 +1,20 @@ +package model + +type CreateContainerParam struct { + RegionId string `json:"regionId"` + ContainerGroupName string `json:"containerGroupName"` + Container []Container `json:"container"` +} +type Container struct { + Name string `json:"name"` + Image string `json:"image"` +} + +type CreateContainerRemote struct { + Success bool `json:"success"` + Payload struct { + RequestId string `json:"requestId"` + ContainerGroupId string `json:"containerGroupId"` + } `json:"payload"` + Error interface{} `json:"error"` +} diff --git a/participant/eci/model/error.go b/participant/eci/model/error.go new file mode 100644 index 0000000..f3d4e70 --- /dev/null +++ b/participant/eci/model/error.go @@ -0,0 +1,29 @@ +package model + +// Error Model +// +// The Error contains error relevant information. +// +// swagger:model Error +type Error struct { + // The general error message + // + // required: true + // example: Unauthorized + Error string `json:"error"` + // The http error code. + // + // required: true + // example: 401 + ErrorCode int `json:"errorCode"` + // The http error code. + // + // required: true + // example: you need to provide a valid access token or user credentials to access this api + ErrorDescription string `json:"errorDescription"` +} + +type RespErr struct { + Code string `json:"code"` + Message string `json:"message"` +} diff --git a/participant/eci/model/response.go b/participant/eci/model/response.go new file mode 100644 index 0000000..ca40e29 --- /dev/null +++ b/participant/eci/model/response.go @@ -0,0 +1,15 @@ +package model + +import ( + "github.com/gin-gonic/gin" + "net/http" +) + +func Response(c *gin.Context, code int, msg interface{}, data interface{}) { + c.JSON(http.StatusOK, map[string]interface{}{ + "code": code, + "msg": msg, + "data": data, + }) + return +} diff --git a/participant/eci/router/router.go b/participant/eci/router/router.go new file mode 100644 index 0000000..6ca3028 --- /dev/null +++ b/participant/eci/router/router.go @@ -0,0 +1,58 @@ +package router + +import ( + "fmt" + "github.com/gin-gonic/gin" + "gitlink.org.cn/JointCloud/pcm-participant/eci/apis" + "regexp" + "time" +) + +func Create() (*gin.Engine, error) { + g := gin.New() + + g.Use(gin.LoggerWithFormatter(logFormatter), gin.Recovery()) + g.Use(gin.Logger()) + g.Use(gin.Recovery()) + + api := g.Group("/api") + v1 := api.Group("/v1") + { + + // container + container := v1.Group("container") + container.POST("/create", apis.CreateContainer) + + } + + return g, nil +} + +var tokenRegexp = regexp.MustCompile("token=[^&]+") + +func logFormatter(param gin.LogFormatterParams) string { + if (param.ClientIP == "127.0.0.1" || param.ClientIP == "::1") && param.Path == "/health" { + return "" + } + + var statusColor, methodColor, resetColor string + if param.IsOutputColor() { + statusColor = param.StatusCodeColor() + methodColor = param.MethodColor() + resetColor = param.ResetColor() + } + + if param.Latency > time.Minute { + param.Latency = param.Latency - param.Latency%time.Second + } + path := tokenRegexp.ReplaceAllString(param.Path, "token=[masked]") + return fmt.Sprintf("%v |%s %3d %s| %13v | %15s |%s %-7s %s %#v\n%s", + param.TimeStamp.Format(time.RFC3339), + statusColor, param.StatusCode, resetColor, + param.Latency, + param.ClientIP, + methodColor, param.Method, resetColor, + path, + param.ErrorMessage, + ) +} diff --git a/participant/eci/service/container.go b/participant/eci/service/container.go new file mode 100644 index 0000000..691ae37 --- /dev/null +++ b/participant/eci/service/container.go @@ -0,0 +1,30 @@ +package service + +import ( + "gitlink.org.cn/JointCloud/pcm-participant-eci/common" + "gitlink.org.cn/JointCloud/pcm-participant-eci/model" +) + +type ContainerService struct { +} + +func NewDatasetService() *ContainerService { + return &ContainerService{} +} +func CreateContainer(ip, token string, param *model.CreateContainerParam) (*model.CreateContainerRemote, error) { + resp := &model.CreateContainerRemote{} + + var reqUrl = ip + common.Forward_Slash + common.CreateContainer + + req := common.GetRestyRequest(common.TIMEOUT) + _, err := req. + SetHeader("Authorization", "Bearer "+token). + SetBody(param). + SetResult(resp). + Post(reqUrl) + + if err != nil { + return nil, err + } + return resp, nil +} diff --git a/participant/eci/service/service.go b/participant/eci/service/service.go new file mode 100644 index 0000000..f188694 --- /dev/null +++ b/participant/eci/service/service.go @@ -0,0 +1,3 @@ +package service + +import () diff --git a/participant/k8s/apis/container.go b/participant/k8s/apis/container.go new file mode 100644 index 0000000..13ab2cf --- /dev/null +++ b/participant/k8s/apis/container.go @@ -0,0 +1,17 @@ +package apis + +import "github.com/gin-gonic/gin" + +type containerApi struct { + *Api + *service.DatasetService +} + +var DatasetApi = datasetApi{ + Api: BaseApi, + DatasetService: service.NewDatasetService(), +} + +func CreateContainer(ctx *gin.Context) { + +} diff --git a/participant/k8s/app.go b/participant/k8s/app.go new file mode 100644 index 0000000..8d42926 --- /dev/null +++ b/participant/k8s/app.go @@ -0,0 +1,13 @@ +package openI + +import ( + "gitlink.org.cn/JointCloud/pcm-participant-k8s/initialize" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/router" +) + +func main() { + //初始化公共配置 + initialize.InitConfig() + rt, _ := router.Create(nil) + _ = rt.Run(":2028") +} diff --git a/participant/k8s/common/client.go b/participant/k8s/common/client.go new file mode 100644 index 0000000..c315031 --- /dev/null +++ b/participant/k8s/common/client.go @@ -0,0 +1,80 @@ +package common + +import ( + "crypto/tls" + "errors" + "fmt" + "gitlink.org.cn/JointCloud/pcm-participant-eci/model" + "net/http" + "time" + + "github.com/go-resty/resty/v2" +) + +var ( + NoRedirectClient *resty.Client + RestyClient *resty.Client + HttpClient *http.Client +) +var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" +var DefaultTimeout = time.Second * 300 + +func InitClient() { + NoRedirectClient = resty.New().SetRedirectPolicy( + resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }), + ).SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) + NoRedirectClient.SetHeader("user-agent", UserAgent) + + RestyClient = NewRestyClient() + HttpClient = NewHttpClient() +} + +func NewRestyClient() *resty.Client { + client := resty.New(). + SetHeader("user-agent", UserAgent). + SetRetryCount(3). + SetRetryResetReaders(true). + SetTimeout(DefaultTimeout). + SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) + return client +} + +func NewHttpClient() *http.Client { + return &http.Client{ + Timeout: time.Hour * 48, + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } +} + +func Request(url string, method string, callback ReqCallback) ([]byte, error) { + respErr := &model.RespErr{} + req := RestyClient.R(). + SetHeaders(map[string]string{ + "Content-Type": "application/json", + }). + SetError(&respErr) + + if callback != nil { + callback(req) + } + + res, err := req.Execute(method, OPENIPREFIX+url) + + if err != nil { + return nil, err + } + if respErr.Message != "" { + return nil, errors.New(respErr.Message) + } + + if res.StatusCode() != http.StatusOK && res.StatusCode() != http.StatusCreated { + return nil, errors.New(fmt.Sprintf("msg: %s, status: %d", res.String(), res.StatusCode())) + } + + return res.Body(), nil +} diff --git a/participant/k8s/common/const.go b/participant/k8s/common/const.go new file mode 100644 index 0000000..8c49303 --- /dev/null +++ b/participant/k8s/common/const.go @@ -0,0 +1,74 @@ +package common + +const ( + MaxChunkSize int64 = 1024 * 1024 * 64 //64MB + + QUESTION_MARK = "?" + TIMEOUT = 10 + OPENIPREFIX = "https://openi.pcl.ac.cn" + ACCESSTOKEN = "access_token" + // user + USERINFO = "/api/v1/user" + IPADDR = "addr" + // repo + REPO = "/api/v1/user/repos" + RepoFile = "/api/v1/repos/{username}/{reponame}/contents/{filepath}" //上传文件到项目中、修改项目中的文件内容 + + // image + IMAGERECOMMENDED = "/api/v1/images/recommend" + IMAGECUSTOM = "/api/v1/images/custom" + IMAGESTARED = "/api/v1/images/star" + + // datasets + DATASETCURRENT = "/api/v1/datasets/{username}/{reponame}/current_repo" //查询当前项目的数据集接口 + DATASETMINE = "/api/v1/datasets/{username}/{reponame}/my_datasets" //我上传的数据集 + DATASETPUBLIC = "/api/v1/datasets/{username}/{reponame}/public_datasets" //查询公开数据集 + DATASETFAVORITE = "/api/v1/datasets/{username}/{reponame}/my_favorite" //查询我收藏的数据集 + DATASETEXISTEXPORT = "/api/v1/datasets/{username}/{reponame}/model/export_exist_dataset" //将用户选择的文件从训练任务结果中导出到数据集中 POST请求 + DATASETCREATE = "/api/v1/datasets/{username}/{reponame}/create" // + BaseDatasetsUrl = "/api/v1/datasets/{username}/{reponame}" //数据集列表 //数据集基本接口 + + // datasets upload + GetChunksUrl = "/api/v1/attachments/get_chunks" //获取当前需要上传文件的chunk信息 + NewMultipartUrl = "/api/v1/attachments/new_multipart" //获取文件上传的需要的信息 + GetMultipartUrl = "/api/v1/attachments/get_multipart_url" //获取文件上传的地址 + CompleteMultipartUrl = "/api/v1/attachments/complete_multipart" //完成上传接口 //上传文件到数据集 + + // task + TASKCREATIONREQUIRED = "/api/v1/{username}/{reponame}/ai_task/creation/required" // 查询创建任务所需资源接口 + TASKCREATIONIMAGEBYSPEC = "/api/v1/{username}/{reponame}/ai_task/creation/image_by_spec" // 根据选择的规格获取镜像(计算资源是NPU时使用) + TASKCREATE = "/api/v1/{username}/{reponame}/ai_task/create" // 创建任务 + TASKLIST = "/api/v1/{username}/{reponame}/ai_task/list" // 任务列表 + TASKDETAIL = "/api/v1/{username}/{reponame}/ai_task" // 查询任务详情 + TASKSTOP = "/api/v1/{username}/{reponame}/ai_task/stop" // 停止任务接口 + TASKOUTPUT = "/api/v1/{username}/{reponame}/ai_task/output" // 查询结果列表接口 + TASKRESULTDOWNLOAD = "/api/v1/{username}/{reponame}/ai_task/output/download/all" // 所有结果下载接口 + TASKLOGDOWNLOAD = "/api/v1/{username}/{reponame}/ai_task/log/download" //日志下载 + SelfEndpointUrl = "/api/v1/{username}/{reponame}/ai_task/self_endpoint_url" //在线推理接口 + + // model + MODELCREATE = "/api/v1/repos/{username}/{reponame}/modelmanage/create_new_model" //模型新增接口 + MODELGETBYID = "/api/v1/repos/{username}/{reponame}/modelmanage/query_model_byId" //根据模型ID查询模型信息接口 + MODELDOWNLOADBYID = "/api/v1/repos/{username}/{reponame}/modelmanage/downloadall" + QUERYMODELBYNAME = "/api/v1/repos/{username}/{reponame}/modelmanage/query_model_byName" //根据模型名称查询模型 + PageModel = "/api/v1/repos/{username}/{reponame}/modelmanage/show_model_api" //分页查询模型 + QueryAllModelFile = "/api/v1/all_model_data" //查询所有模型文件 + + // model local create + MODELLOCALCREATE = "/api/v1/repos/{username}/{reponame}/modelmanage/create_local_model" //创建一条本地模型记录 + MODELLOCALGETUPLOADEDCHUNKS = "/api/v1/attachments/model/get_chunks" //获取该文件已经上传的分片接口 + MODELLOCALNEWMULTIPART = "/api/v1/attachments/model/new_multipart" //开启一个本地模型上传 + MODELLOCALGETMULTIPARTURL = "/api/v1/attachments/model/get_multipart_url" //获取模型分片传输链接,并进行上传 + MODELLOCALCOMPLETEMULTIPART = "/api/v1/attachments/model/complete_multipart" //完成模型文件上传 +) + +const ( + SUCCESS = "success" +) + +// error +const ( + INVOKEERROR = "failed to invoke" + INVALIDPARAMS = "invalid Request params" + NOTFOUND = "not found" +) diff --git a/participant/k8s/common/types.go b/participant/k8s/common/types.go new file mode 100644 index 0000000..b8dffad --- /dev/null +++ b/participant/k8s/common/types.go @@ -0,0 +1,12 @@ +package common + +import "github.com/go-resty/resty/v2" + +type Json map[string]interface{} + +type TokenResp struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` +} + +type ReqCallback func(req *resty.Request) diff --git a/participant/k8s/common/util.go b/participant/k8s/common/util.go new file mode 100644 index 0000000..ea19722 --- /dev/null +++ b/participant/k8s/common/util.go @@ -0,0 +1,92 @@ +package common + +import ( + "crypto/md5" + "crypto/tls" + "encoding/hex" + "fmt" + "github.com/go-resty/resty/v2" + "io" + "mime/multipart" + "reflect" + "strconv" + "time" +) + +func GetRestyRequest() *resty.Request { + client := resty.New().SetTimeout(time.Duration(5) * time.Second) + client.SetTLSClientConfig(&tls.Config{ + InsecureSkipVerify: true, // Only for development/testing + }) + request := client.R() + return request +} + +func GetFileMd5(file multipart.File) (string, error) { + hash := md5.New() + if _, err := io.Copy(hash, file); err != nil { + return "", err + } + + // 计算MD5并转换为16进制字符串 + md5Bytes := hash.Sum(nil) + md5Str := hex.EncodeToString(md5Bytes) + return md5Str, nil +} + +func Bool2String(b bool) string { + return strconv.FormatBool(b) +} + +// StructToMapWithTag 将结构体转换为 map[string]string,key 使用指定标签的值 +func StructToMapWithTag(obj interface{}, tagName string) (map[string]string, error) { + result := make(map[string]string) + + // 获取值的反射对象 + val := reflect.ValueOf(obj) + if val.Kind() == reflect.Ptr { + val = val.Elem() // 解引用指针 + } + + if val.Kind() != reflect.Struct { + return nil, fmt.Errorf("input is not a struct or pointer to struct") + } + + // 获取类型信息 + typ := val.Type() + + // 遍历结构体字段 + for i := 0; i < val.NumField(); i++ { + field := val.Field(i) + fieldType := typ.Field(i) + + // 获取字段的标签值 + tagValue := fieldType.Tag.Get(tagName) + if tagValue == "" { + continue // 如果标签不存在,跳过该字段 + } + + // 获取字段值并转换为字符串 + var fieldValue string + switch field.Kind() { + case reflect.String: + fieldValue = field.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fieldValue = strconv.FormatInt(field.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + fieldValue = strconv.FormatUint(field.Uint(), 10) + case reflect.Float32, reflect.Float64: + fieldValue = strconv.FormatFloat(field.Float(), 'f', -1, 64) + case reflect.Bool: + fieldValue = strconv.FormatBool(field.Bool()) + default: + // 如果字段类型不支持,跳过 + continue + } + + // 将标签值和字段值存入 map + result[tagValue] = fieldValue + } + + return result, nil +} diff --git a/participant/k8s/go.mod b/participant/k8s/go.mod new file mode 100644 index 0000000..26f286e --- /dev/null +++ b/participant/k8s/go.mod @@ -0,0 +1,7 @@ +module gitlink.org.cn/JointCloud/pcm-participant-k8s + +go 1.22.0 + +require github.com/go-resty/resty/v2 v2.16.5 + +require golang.org/x/net v0.33.0 // indirect diff --git a/participant/k8s/initialize/common.go b/participant/k8s/initialize/common.go new file mode 100644 index 0000000..2c54b8f --- /dev/null +++ b/participant/k8s/initialize/common.go @@ -0,0 +1,9 @@ +package initialize + +import ( + "gitlink.org.cn/JointCloud/pcm-participant-k8s/common" +) + +func InitConfig() { + common.InitClient() +} diff --git a/participant/k8s/model/container.go b/participant/k8s/model/container.go new file mode 100644 index 0000000..79491b6 --- /dev/null +++ b/participant/k8s/model/container.go @@ -0,0 +1,11 @@ +package model + +type ECICreateRequest struct { + RegionId string `json:"regionId"` + ContainerGroupName string `json:"containerGroupName"` + Container []Container `json:"container"` +} +type Container struct { + Name string `json:"name"` + Image string `json:"image"` +} diff --git a/participant/k8s/model/error.go b/participant/k8s/model/error.go new file mode 100644 index 0000000..f3d4e70 --- /dev/null +++ b/participant/k8s/model/error.go @@ -0,0 +1,29 @@ +package model + +// Error Model +// +// The Error contains error relevant information. +// +// swagger:model Error +type Error struct { + // The general error message + // + // required: true + // example: Unauthorized + Error string `json:"error"` + // The http error code. + // + // required: true + // example: 401 + ErrorCode int `json:"errorCode"` + // The http error code. + // + // required: true + // example: you need to provide a valid access token or user credentials to access this api + ErrorDescription string `json:"errorDescription"` +} + +type RespErr struct { + Code string `json:"code"` + Message string `json:"message"` +} diff --git a/participant/k8s/router/router.go b/participant/k8s/router/router.go new file mode 100644 index 0000000..784ff9a --- /dev/null +++ b/participant/k8s/router/router.go @@ -0,0 +1,59 @@ +package router + +import ( + "fmt" + "github.com/gin-gonic/gin" + "gitlink.org.cn/JointCloud/pcm-participant/k8s/apis" + "regexp" + "time" +) + +func Create() (*gin.Engine, error) { + g := gin.New() + + g.Use(gin.LoggerWithFormatter(logFormatter), gin.Recovery()) + g.Use(gin.Logger()) + g.Use(gin.Recovery()) + //g.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + + api := g.Group("/api") + v1 := api.Group("/v1") + { + + // container + container := v1.Group("container") + container.POST("/create", apis.CreateContainer) + + } + + return g, nil +} + +var tokenRegexp = regexp.MustCompile("token=[^&]+") + +func logFormatter(param gin.LogFormatterParams) string { + if (param.ClientIP == "127.0.0.1" || param.ClientIP == "::1") && param.Path == "/health" { + return "" + } + + var statusColor, methodColor, resetColor string + if param.IsOutputColor() { + statusColor = param.StatusCodeColor() + methodColor = param.MethodColor() + resetColor = param.ResetColor() + } + + if param.Latency > time.Minute { + param.Latency = param.Latency - param.Latency%time.Second + } + path := tokenRegexp.ReplaceAllString(param.Path, "token=[masked]") + return fmt.Sprintf("%v |%s %3d %s| %13v | %15s |%s %-7s %s %#v\n%s", + param.TimeStamp.Format(time.RFC3339), + statusColor, param.StatusCode, resetColor, + param.Latency, + param.ClientIP, + methodColor, param.Method, resetColor, + path, + param.ErrorMessage, + ) +} diff --git a/participant/serverless/apis/container.go b/participant/serverless/apis/container.go new file mode 100644 index 0000000..6d413ce --- /dev/null +++ b/participant/serverless/apis/container.go @@ -0,0 +1,7 @@ +package apis + +import "github.com/gin-gonic/gin" + +func CreateContainer(ctx *gin.Context) { + +} diff --git a/participant/serverless/common/client.go b/participant/serverless/common/client.go new file mode 100644 index 0000000..cb6cade --- /dev/null +++ b/participant/serverless/common/client.go @@ -0,0 +1,80 @@ +package common + +import ( + "crypto/tls" + "errors" + "fmt" + "gitlink.org.cn/JointCloud/pcm-participant-serverless/model" + "net/http" + "time" + + "github.com/go-resty/resty/v2" +) + +var ( + NoRedirectClient *resty.Client + RestyClient *resty.Client + HttpClient *http.Client +) +var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" +var DefaultTimeout = time.Second * 300 + +func InitClient() { + NoRedirectClient = resty.New().SetRedirectPolicy( + resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }), + ).SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) + NoRedirectClient.SetHeader("user-agent", UserAgent) + + RestyClient = NewRestyClient() + HttpClient = NewHttpClient() +} + +func NewRestyClient() *resty.Client { + client := resty.New(). + SetHeader("user-agent", UserAgent). + SetRetryCount(3). + SetRetryResetReaders(true). + SetTimeout(DefaultTimeout). + SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) + return client +} + +func NewHttpClient() *http.Client { + return &http.Client{ + Timeout: time.Hour * 48, + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } +} + +func Request(url string, method string, callback ReqCallback) ([]byte, error) { + respErr := &model.RespErr{} + req := RestyClient.R(). + SetHeaders(map[string]string{ + "Content-Type": "application/json", + }). + SetError(&respErr) + + if callback != nil { + callback(req) + } + + res, err := req.Execute(method, OPENIPREFIX+url) + + if err != nil { + return nil, err + } + if respErr.Message != "" { + return nil, errors.New(respErr.Message) + } + + if res.StatusCode() != http.StatusOK && res.StatusCode() != http.StatusCreated { + return nil, errors.New(fmt.Sprintf("msg: %s, status: %d", res.String(), res.StatusCode())) + } + + return res.Body(), nil +} diff --git a/participant/serverless/common/const.go b/participant/serverless/common/const.go new file mode 100644 index 0000000..b1af028 --- /dev/null +++ b/participant/serverless/common/const.go @@ -0,0 +1,74 @@ +package common + +const ( + MaxChunkSize int64 = 1024 * 1024 * 64 //64MB + + QUESTION_MARK = "?" + TIMEOUT = 10 + OPENIPREFIX = "https://openi.pcl.ac.cn" + ACCESSTOKEN = "access_token" + // user + USERINFO = "/api/v1/user" + + // repo + REPO = "/api/v1/user/repos" + RepoFile = "/api/v1/repos/{username}/{reponame}/contents/{filepath}" //上传文件到项目中、修改项目中的文件内容 + + // image + IMAGERECOMMENDED = "/api/v1/images/recommend" + IMAGECUSTOM = "/api/v1/images/custom" + IMAGESTARED = "/api/v1/images/star" + + // datasets + DATASETCURRENT = "/api/v1/datasets/{username}/{reponame}/current_repo" //查询当前项目的数据集接口 + DATASETMINE = "/api/v1/datasets/{username}/{reponame}/my_datasets" //我上传的数据集 + DATASETPUBLIC = "/api/v1/datasets/{username}/{reponame}/public_datasets" //查询公开数据集 + DATASETFAVORITE = "/api/v1/datasets/{username}/{reponame}/my_favorite" //查询我收藏的数据集 + DATASETEXISTEXPORT = "/api/v1/datasets/{username}/{reponame}/model/export_exist_dataset" //将用户选择的文件从训练任务结果中导出到数据集中 POST请求 + DATASETCREATE = "/api/v1/datasets/{username}/{reponame}/create" // + BaseDatasetsUrl = "/api/v1/datasets/{username}/{reponame}" //数据集列表 //数据集基本接口 + + // datasets upload + GetChunksUrl = "/api/v1/attachments/get_chunks" //获取当前需要上传文件的chunk信息 + NewMultipartUrl = "/api/v1/attachments/new_multipart" //获取文件上传的需要的信息 + GetMultipartUrl = "/api/v1/attachments/get_multipart_url" //获取文件上传的地址 + CompleteMultipartUrl = "/api/v1/attachments/complete_multipart" //完成上传接口 //上传文件到数据集 + + // task + TASKCREATIONREQUIRED = "/api/v1/{username}/{reponame}/ai_task/creation/required" // 查询创建任务所需资源接口 + TASKCREATIONIMAGEBYSPEC = "/api/v1/{username}/{reponame}/ai_task/creation/image_by_spec" // 根据选择的规格获取镜像(计算资源是NPU时使用) + TASKCREATE = "/api/v1/{username}/{reponame}/ai_task/create" // 创建任务 + TASKLIST = "/api/v1/{username}/{reponame}/ai_task/list" // 任务列表 + TASKDETAIL = "/api/v1/{username}/{reponame}/ai_task" // 查询任务详情 + TASKSTOP = "/api/v1/{username}/{reponame}/ai_task/stop" // 停止任务接口 + TASKOUTPUT = "/api/v1/{username}/{reponame}/ai_task/output" // 查询结果列表接口 + TASKRESULTDOWNLOAD = "/api/v1/{username}/{reponame}/ai_task/output/download/all" // 所有结果下载接口 + TASKLOGDOWNLOAD = "/api/v1/{username}/{reponame}/ai_task/log/download" //日志下载 + SelfEndpointUrl = "/api/v1/{username}/{reponame}/ai_task/self_endpoint_url" //在线推理接口 + + // model + MODELCREATE = "/api/v1/repos/{username}/{reponame}/modelmanage/create_new_model" //模型新增接口 + MODELGETBYID = "/api/v1/repos/{username}/{reponame}/modelmanage/query_model_byId" //根据模型ID查询模型信息接口 + MODELDOWNLOADBYID = "/api/v1/repos/{username}/{reponame}/modelmanage/downloadall" + QUERYMODELBYNAME = "/api/v1/repos/{username}/{reponame}/modelmanage/query_model_byName" //根据模型名称查询模型 + PageModel = "/api/v1/repos/{username}/{reponame}/modelmanage/show_model_api" //分页查询模型 + QueryAllModelFile = "/api/v1/all_model_data" //查询所有模型文件 + + // model local create + MODELLOCALCREATE = "/api/v1/repos/{username}/{reponame}/modelmanage/create_local_model" //创建一条本地模型记录 + MODELLOCALGETUPLOADEDCHUNKS = "/api/v1/attachments/model/get_chunks" //获取该文件已经上传的分片接口 + MODELLOCALNEWMULTIPART = "/api/v1/attachments/model/new_multipart" //开启一个本地模型上传 + MODELLOCALGETMULTIPARTURL = "/api/v1/attachments/model/get_multipart_url" //获取模型分片传输链接,并进行上传 + MODELLOCALCOMPLETEMULTIPART = "/api/v1/attachments/model/complete_multipart" //完成模型文件上传 +) + +const ( + SUCCESS = "success" +) + +// error +const ( + INVOKEERROR = "failed to invoke" + INVALIDPARAMS = "invalid Request params" + NOTFOUND = "not found" +) diff --git a/participant/serverless/common/types.go b/participant/serverless/common/types.go new file mode 100644 index 0000000..b8dffad --- /dev/null +++ b/participant/serverless/common/types.go @@ -0,0 +1,12 @@ +package common + +import "github.com/go-resty/resty/v2" + +type Json map[string]interface{} + +type TokenResp struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` +} + +type ReqCallback func(req *resty.Request) diff --git a/participant/serverless/common/util.go b/participant/serverless/common/util.go new file mode 100644 index 0000000..b0eaeed --- /dev/null +++ b/participant/serverless/common/util.go @@ -0,0 +1,88 @@ +package common + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "github.com/go-resty/resty/v2" + "io" + "mime/multipart" + "reflect" + "strconv" + "time" +) + +func GetRestyRequest(timeoutSeconds int64) *resty.Request { + client := resty.New().SetTimeout(time.Duration(timeoutSeconds) * time.Second) + request := client.R() + return request +} + +func GetFileMd5(file multipart.File) (string, error) { + hash := md5.New() + if _, err := io.Copy(hash, file); err != nil { + return "", err + } + + // 计算MD5并转换为16进制字符串 + md5Bytes := hash.Sum(nil) + md5Str := hex.EncodeToString(md5Bytes) + return md5Str, nil +} + +func Bool2String(b bool) string { + return strconv.FormatBool(b) +} + +// StructToMapWithTag 将结构体转换为 map[string]string,key 使用指定标签的值 +func StructToMapWithTag(obj interface{}, tagName string) (map[string]string, error) { + result := make(map[string]string) + + // 获取值的反射对象 + val := reflect.ValueOf(obj) + if val.Kind() == reflect.Ptr { + val = val.Elem() // 解引用指针 + } + + if val.Kind() != reflect.Struct { + return nil, fmt.Errorf("input is not a struct or pointer to struct") + } + + // 获取类型信息 + typ := val.Type() + + // 遍历结构体字段 + for i := 0; i < val.NumField(); i++ { + field := val.Field(i) + fieldType := typ.Field(i) + + // 获取字段的标签值 + tagValue := fieldType.Tag.Get(tagName) + if tagValue == "" { + continue // 如果标签不存在,跳过该字段 + } + + // 获取字段值并转换为字符串 + var fieldValue string + switch field.Kind() { + case reflect.String: + fieldValue = field.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fieldValue = strconv.FormatInt(field.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + fieldValue = strconv.FormatUint(field.Uint(), 10) + case reflect.Float32, reflect.Float64: + fieldValue = strconv.FormatFloat(field.Float(), 'f', -1, 64) + case reflect.Bool: + fieldValue = strconv.FormatBool(field.Bool()) + default: + // 如果字段类型不支持,跳过 + continue + } + + // 将标签值和字段值存入 map + result[tagValue] = fieldValue + } + + return result, nil +} diff --git a/participant/serverless/go.mod b/participant/serverless/go.mod new file mode 100644 index 0000000..c353830 --- /dev/null +++ b/participant/serverless/go.mod @@ -0,0 +1,37 @@ +module gitlink.org.cn/JointCloud/pcm-participant-serverless + +go 1.22.0 + +require ( + github.com/gin-gonic/gin v1.10.1 + github.com/go-resty/resty/v2 v2.16.5 +) + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/participant/serverless/model/container.go b/participant/serverless/model/container.go new file mode 100644 index 0000000..d548556 --- /dev/null +++ b/participant/serverless/model/container.go @@ -0,0 +1,105 @@ +package model + +import "time" + +// ContainerGroup 表示容器组配置 +type ContainerGroup struct { + Containers []Container `json:"Containers,omitempty"` + EksCiName *string `json:"EksCiName,omitempty"` + SecurityGroupIds []*string `json:"SecurityGroupIds,omitempty"` + SubnetId *string `json:"SubnetId,omitempty"` + VpcId *string `json:"VpcId,omitempty"` + Memory *float64 `json:"Memory,omitempty"` + Cpu *float64 `json:"Cpu,omitempty"` +} + +// Container 表示容器配置 +type Container struct { + Image *string `json:"Image,omitempty"` + Name *string `json:"Name,omitempty"` + Args []*string `json:"Args,omitempty"` + Commands []*string `json:"Commands,omitempty"` + Cpu *float64 `json:"Cpu,omitempty"` + CurrentState *ContainerState `json:"CurrentState,omitempty"` + EnvironmentVars []*EnvironmentVar `json:"EnvironmentVars,omitempty"` + GpuLimit *int `json:"GpuLimit,omitempty"` + LivenessProbe *ProbeConfig `json:"LivenessProbe,omitempty"` + Memory *float64 `json:"Memory,omitempty"` + ReadinessProbe *ProbeConfig `json:"ReadinessProbe,omitempty"` + RestartCount *int `json:"RestartCount,omitempty"` + SecurityContext *SecurityContext `json:"SecurityContext,omitempty"` + VolumeMounts []*VolumeMount `json:"VolumeMounts,omitempty"` + WorkingDir *string `json:"WorkingDir,omitempty"` +} + +// ContainerState 表示容器的当前状态 +type ContainerState struct { + ExitCode *int `json:"ExitCode,omitempty"` + FinishTime *time.Time `json:"FinishTime,omitempty"` + Message *string `json:"Message,omitempty"` + Reason *string `json:"Reason,omitempty"` + RestartCount *int `json:"RestartCount,omitempty"` + StartTime *time.Time `json:"StartTime,omitempty"` + State *string `json:"State,omitempty"` +} + +// EnvironmentVar 表示容器环境变量 +type EnvironmentVar struct { + Name *string `json:"Name,omitempty"` + Value *string `json:"Value,omitempty"` +} + +// ProbeConfig 表示容器健康检查探针配置 +type ProbeConfig struct { + Probe *Probe `json:"Probe,omitempty"` + Exec *ExecProbe `json:"Exec,omitempty"` + HttpGet *HTTPGetProbe `json:"HttpGet,omitempty"` + TcpSocket *TCPSocketProbe `json:"TcpSocket,omitempty"` +} + +// Probe 表示通用探针配置 +type Probe struct { + FailureThreshold *int `json:"FailureThreshold,omitempty"` + InitialDelaySeconds *int `json:"InitialDelaySeconds,omitempty"` + PeriodSeconds *int `json:"PeriodSeconds,omitempty"` + SuccessThreshold *int `json:"SuccessThreshold,omitempty"` + TimeoutSeconds *int `json:"TimeoutSeconds,omitempty"` +} + +// ExecProbe 表示执行命令类型的探针 +type ExecProbe struct { + Commands []*string `json:"Commands,omitempty"` +} + +// HTTPGetProbe 表示HTTP请求类型的探针 +type HTTPGetProbe struct { + Path *string `json:"Path,omitempty"` + Port *int `json:"Port,omitempty"` + Scheme *string `json:"Scheme,omitempty"` +} + +// TCPSocketProbe 表示TCP连接类型的探针 +type TCPSocketProbe struct { + Port *int `json:"Port,omitempty"` +} + +// SecurityContext 表示容器安全上下文 +type SecurityContext struct { + Capabilities *Capabilities `json:"Capabilities,omitempty"` +} + +// Capabilities 表示容器权限配置 +type Capabilities struct { + Add []*string `json:"Add,omitempty"` + Drop []*string `json:"Drop,omitempty"` +} + +// VolumeMount 表示容器卷挂载配置 +type VolumeMount struct { + MountPath *string `json:"MountPath,omitempty"` + Name *string `json:"Name,omitempty"` + MountPropagation *string `json:"MountPropagation,omitempty"` + ReadOnly *bool `json:"ReadOnly,omitempty"` + SubPath *string `json:"SubPath,omitempty"` + SubPathExpr *string `json:"SubPathExpr,omitempty"` +} diff --git a/participant/serverless/model/error.go b/participant/serverless/model/error.go new file mode 100644 index 0000000..f3d4e70 --- /dev/null +++ b/participant/serverless/model/error.go @@ -0,0 +1,29 @@ +package model + +// Error Model +// +// The Error contains error relevant information. +// +// swagger:model Error +type Error struct { + // The general error message + // + // required: true + // example: Unauthorized + Error string `json:"error"` + // The http error code. + // + // required: true + // example: 401 + ErrorCode int `json:"errorCode"` + // The http error code. + // + // required: true + // example: you need to provide a valid access token or user credentials to access this api + ErrorDescription string `json:"errorDescription"` +} + +type RespErr struct { + Code string `json:"code"` + Message string `json:"message"` +} diff --git a/participant/serverless/model/response.go b/participant/serverless/model/response.go new file mode 100644 index 0000000..ca40e29 --- /dev/null +++ b/participant/serverless/model/response.go @@ -0,0 +1,15 @@ +package model + +import ( + "github.com/gin-gonic/gin" + "net/http" +) + +func Response(c *gin.Context, code int, msg interface{}, data interface{}) { + c.JSON(http.StatusOK, map[string]interface{}{ + "code": code, + "msg": msg, + "data": data, + }) + return +} diff --git a/participant/serverless/router/router.go b/participant/serverless/router/router.go new file mode 100644 index 0000000..8e00738 --- /dev/null +++ b/participant/serverless/router/router.go @@ -0,0 +1,59 @@ +package router + +import ( + "fmt" + "github.com/gin-gonic/gin" + "gitlink.org.cn/JointCloud/pcm-participant/serverless/apis" + "regexp" + "time" +) + +func Create() (*gin.Engine, error) { + g := gin.New() + + g.Use(gin.LoggerWithFormatter(logFormatter), gin.Recovery()) + g.Use(gin.Logger()) + g.Use(gin.Recovery()) + //g.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + + api := g.Group("/api") + v1 := api.Group("/v1") + { + + // container + container := v1.Group("container") + container.POST("/create", apis.CreateContainer) + + } + + return g, nil +} + +var tokenRegexp = regexp.MustCompile("token=[^&]+") + +func logFormatter(param gin.LogFormatterParams) string { + if (param.ClientIP == "127.0.0.1" || param.ClientIP == "::1") && param.Path == "/health" { + return "" + } + + var statusColor, methodColor, resetColor string + if param.IsOutputColor() { + statusColor = param.StatusCodeColor() + methodColor = param.MethodColor() + resetColor = param.ResetColor() + } + + if param.Latency > time.Minute { + param.Latency = param.Latency - param.Latency%time.Second + } + path := tokenRegexp.ReplaceAllString(param.Path, "token=[masked]") + return fmt.Sprintf("%v |%s %3d %s| %13v | %15s |%s %-7s %s %#v\n%s", + param.TimeStamp.Format(time.RFC3339), + statusColor, param.StatusCode, resetColor, + param.Latency, + param.ClientIP, + methodColor, param.Method, resetColor, + path, + param.ErrorMessage, + ) +} From 6c498656af8791d1b1475904491650f0161cc40e Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Fri, 4 Jul 2025 21:24:16 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Eserverless=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.work | 4 +- go.work.sum | 39 +++-------------- participant/eci/apis/container.go | 25 ++++------- participant/eci/common/const.go | 23 +++------- participant/eci/common/token.go | 22 ++++++++++ participant/eci/common/util.go | 8 ---- participant/eci/go.mod | 38 ++++++++++++++++ participant/eci/model/container.go | 8 ++-- participant/eci/model/token.go | 15 +++++++ participant/eci/router/router.go | 2 +- participant/eci/service/container.go | 25 +++++------ participant/eci/service/container_test.go | 43 +++++++++++++++++++ participant/openI/service/image_test.go | 2 +- participant/serverless/common/token.go | 24 +++++++++++ participant/serverless/go.mod | 5 +++ participant/serverless/router/router.go | 2 +- .../serverless/service/container_test.go | 37 ++++++++++++++++ 17 files changed, 223 insertions(+), 99 deletions(-) create mode 100644 participant/eci/common/token.go create mode 100644 participant/eci/model/token.go create mode 100644 participant/eci/service/container_test.go create mode 100644 participant/serverless/common/token.go create mode 100644 participant/serverless/service/container_test.go diff --git a/go.work b/go.work index 5f922e6..bb4e9d3 100644 --- a/go.work +++ b/go.work @@ -1,6 +1,4 @@ -go 1.23.0 - -toolchain go1.24.0 +go 1.24.0 use ( ./ai diff --git a/go.work.sum b/go.work.sum index 8790c0b..c1f69e2 100644 --- a/go.work.sum +++ b/go.work.sum @@ -19,14 +19,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= -github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= -github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= -github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= -github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= @@ -38,10 +32,6 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90 h1:WXb3TSNmHp2vHoCroCIB1foO/yQ36swABL8aOVeDpgg= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= -github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= -github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -53,12 +43,6 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= -github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8= -github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= -github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= -github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= -github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= -github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d h1:lBXNCxVENCipq4D1Is42JVOP4eQjlB8TQ6H69Yx5J9Q= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -68,8 +52,6 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= @@ -90,8 +72,6 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4 github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= @@ -104,12 +84,11 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c h1:bY6ktFuJkt+ZXkX0RChQch2FtHpWQLVS8Qo1YasiIVk= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= @@ -135,13 +114,10 @@ github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= -golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e h1:iWVPgObh6F4UDtjBLK51zsy5UHTPLQwCmsNjCsbKhQ0= golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= @@ -153,6 +129,7 @@ golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= @@ -160,10 +137,7 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= @@ -176,9 +150,10 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= @@ -189,20 +164,16 @@ golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b h1:Qh4dB5D/WpoUUp3lSod7qgoyEHbDGPUWjIbnqdqqe1k= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= diff --git a/participant/eci/apis/container.go b/participant/eci/apis/container.go index efdfb40..95d47f6 100644 --- a/participant/eci/apis/container.go +++ b/participant/eci/apis/container.go @@ -14,26 +14,17 @@ func CreateContainer(ctx *gin.Context) { model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, err) return } - ip := ctx.Query(common.IPADDR) - if ip == "" { - model.Response(ctx, 401, "addr为必填字段", nil) - return - } - token := ctx.Query(common.ACCESSTOKEN) - if token == "" { - model.Response(ctx, 401, "token为必填字段", nil) - return - } - resp, err := service.CreateContainer(ip, token, ¶m) + client := common.GetEciClient() + resp, err := service.CreateContainer(client, ¶m) if err != nil { return } - if !resp.Success { - if resp.Error != nil { - model.Response(ctx, 500, common.INVOKEERROR, resp.Error) - return - } + if !resp.IsSuccess() { + + model.Response(ctx, 500, common.INVOKEERROR, resp.String()) + return + } - model.Response(ctx, http.StatusOK, common.SUCCESS, resp.Payload) + model.Response(ctx, http.StatusOK, common.SUCCESS, resp.ContainerGroupId) } diff --git a/participant/eci/common/const.go b/participant/eci/common/const.go index 0bbe831..34732ac 100644 --- a/participant/eci/common/const.go +++ b/participant/eci/common/const.go @@ -3,6 +3,10 @@ package common const ( MaxChunkSize int64 = 1024 * 1024 * 64 //64MB + Ip = "https://api.aliyun.com" + User = "c2net@pcl.ac.cn" + Pwd = "c2net123" + QUESTION_MARK = "?" TIMEOUT = 10 OPENIPREFIX = "https://openi.pcl.ac.cn" @@ -11,24 +15,9 @@ const ( // user USERINFO = "/api/v1/user" Forward_Slash = "/" - // repo - REPO = "/api/v1/user/repos" - RepoFile = "/api/v1/repos/{username}/{reponame}/contents/{filepath}" //上传文件到项目中、修改项目中的文件内容 + GetToken = "openaiserver/v1/authmanage/token" - // image - IMAGERECOMMENDED = "/api/v1/images/recommend" - IMAGECUSTOM = "/api/v1/images/custom" - IMAGESTARED = "/api/v1/images/star" - - // datasets - DATASETCURRENT = "/api/v1/datasets/{username}/{reponame}/current_repo" //查询当前项目的数据集接口 - DATASETMINE = "/api/v1/datasets/{username}/{reponame}/my_datasets" //我上传的数据集 - DATASETPUBLIC = "/api/v1/datasets/{username}/{reponame}/public_datasets" //查询公开数据集 - DATASETFAVORITE = "/api/v1/datasets/{username}/{reponame}/my_favorite" //查询我收藏的数据集 - DATASETEXISTEXPORT = "/api/v1/datasets/{username}/{reponame}/model/export_exist_dataset" //将用户选择的文件从训练任务结果中导出到数据集中 POST请求 - DATASETCREATE = "/api/v1/datasets/{username}/{reponame}/create" // - BaseDatasetsUrl = "/api/v1/datasets/{username}/{reponame}" //数据集列表 //数据集基本接口 - CreateContainer = "" + CreateContainer = "/api/Eci/2018-08-08/CreateContainerGroup" // datasets upload GetChunksUrl = "/api/v1/attachments/get_chunks" //获取当前需要上传文件的chunk信息 NewMultipartUrl = "/api/v1/attachments/new_multipart" //获取文件上传的需要的信息 diff --git a/participant/eci/common/token.go b/participant/eci/common/token.go new file mode 100644 index 0000000..3c1515c --- /dev/null +++ b/participant/eci/common/token.go @@ -0,0 +1,22 @@ +package common + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" +) + +const ( + accessKeyId = "" + accessKeySecret = "" +) + +func GetEciClient() *eci.Client { + config := sdk.NewConfig() + credential := credentials.NewAccessKeyCredential(accessKeyId, accessKeySecret) + client, err := eci.NewClientWithOptions("cn-hangzhou", config, credential) + if err != nil { + panic(err) + } + return client +} diff --git a/participant/eci/common/util.go b/participant/eci/common/util.go index b0eaeed..c09d8af 100644 --- a/participant/eci/common/util.go +++ b/participant/eci/common/util.go @@ -4,20 +4,12 @@ import ( "crypto/md5" "encoding/hex" "fmt" - "github.com/go-resty/resty/v2" "io" "mime/multipart" "reflect" "strconv" - "time" ) -func GetRestyRequest(timeoutSeconds int64) *resty.Request { - client := resty.New().SetTimeout(time.Duration(timeoutSeconds) * time.Second) - request := client.R() - return request -} - func GetFileMd5(file multipart.File) (string, error) { hash := md5.New() if _, err := io.Copy(hash, file); err != nil { diff --git a/participant/eci/go.mod b/participant/eci/go.mod index 54ebdf8..c246dce 100644 --- a/participant/eci/go.mod +++ b/participant/eci/go.mod @@ -1,3 +1,41 @@ module gitlink.org.cn/JointCloud/pcm-participant-eci go 1.22.0 + +require ( + github.com/gin-gonic/gin v1.10.1 + github.com/go-resty/resty/v2 v2.16.5 + github.com/smartystreets/goconvey v1.8.1 +) + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/gopherjs/gopherjs v1.17.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/jtolds/gls v4.20.0+incompatible // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/smarty/assertions v1.15.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/participant/eci/model/container.go b/participant/eci/model/container.go index 6fc05d5..f7adef3 100644 --- a/participant/eci/model/container.go +++ b/participant/eci/model/container.go @@ -1,9 +1,11 @@ package model +import "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" + type CreateContainerParam struct { - RegionId string `json:"regionId"` - ContainerGroupName string `json:"containerGroupName"` - Container []Container `json:"container"` + RegionId string `json:"regionId"` + ContainerGroupName string `json:"containerGroupName"` + Container *[]eci.CreateContainerGroupContainer `json:"container"` } type Container struct { Name string `json:"name"` diff --git a/participant/eci/model/token.go b/participant/eci/model/token.go new file mode 100644 index 0000000..6a9037a --- /dev/null +++ b/participant/eci/model/token.go @@ -0,0 +1,15 @@ +package model + +type Token struct { + Success bool `json:"success"` + Payload struct { + Token string `json:"token"` + Expiration int `json:"expiration"` + } `json:"payload"` + Error interface{} `json:"error"` +} + +type TokenParam struct { + User string `json:"user"` + Pwd string `json:"pwd"` +} diff --git a/participant/eci/router/router.go b/participant/eci/router/router.go index 6ca3028..01b25eb 100644 --- a/participant/eci/router/router.go +++ b/participant/eci/router/router.go @@ -3,7 +3,7 @@ package router import ( "fmt" "github.com/gin-gonic/gin" - "gitlink.org.cn/JointCloud/pcm-participant/eci/apis" + "gitlink.org.cn/JointCloud/pcm-participant-eci/apis" "regexp" "time" ) diff --git a/participant/eci/service/container.go b/participant/eci/service/container.go index 691ae37..b44c16b 100644 --- a/participant/eci/service/container.go +++ b/participant/eci/service/container.go @@ -1,7 +1,8 @@ package service import ( - "gitlink.org.cn/JointCloud/pcm-participant-eci/common" + "fmt" + "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" "gitlink.org.cn/JointCloud/pcm-participant-eci/model" ) @@ -11,20 +12,16 @@ type ContainerService struct { func NewDatasetService() *ContainerService { return &ContainerService{} } -func CreateContainer(ip, token string, param *model.CreateContainerParam) (*model.CreateContainerRemote, error) { - resp := &model.CreateContainerRemote{} - - var reqUrl = ip + common.Forward_Slash + common.CreateContainer - - req := common.GetRestyRequest(common.TIMEOUT) - _, err := req. - SetHeader("Authorization", "Bearer "+token). - SetBody(param). - SetResult(resp). - Post(reqUrl) - +func CreateContainer(client *eci.Client, param *model.CreateContainerParam) (*eci.CreateContainerGroupResponse, error) { + request := eci.CreateCreateContainerGroupRequest() + request.RegionId = param.RegionId + request.Container = param.Container + request.ContainerGroupName = param.ContainerGroupName + // 发送请求 + response, err := client.CreateContainerGroup(request) if err != nil { + fmt.Printf("Error: %v\n", err) return nil, err } - return resp, nil + return response, nil } diff --git a/participant/eci/service/container_test.go b/participant/eci/service/container_test.go new file mode 100644 index 0000000..0e670a5 --- /dev/null +++ b/participant/eci/service/container_test.go @@ -0,0 +1,43 @@ +package service + +import ( + "fmt" + "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" + "github.com/smartystreets/goconvey/convey" + "gitlink.org.cn/JointCloud/pcm-participant-eci/common" + "gitlink.org.cn/JointCloud/pcm-participant-eci/model" + "testing" +) + +var ( + requestId string + containerGroupId string +) + +func TestCreateContainer(t *testing.T) { + convey.Convey("Test Service", t, func() { + client := common.GetClient() + convey.Convey("CreateContainer", func() { + param := &model.CreateContainerParam{ + RegionId: "cn-hangzhou", + ContainerGroupName: "minimal-hello", + Container: &[]eci.CreateContainerGroupContainer{ + eci.CreateContainerGroupContainer{ + Image: "minimal-hello", + Name: "minimal-hello", + }, + }, + } + resp, err := CreateContainer(client, param) + if err != nil { + fmt.Println(err.Error()) + } + if !resp.IsSuccess() { + fmt.Println(resp.GetHttpContentString()) + } + convey.So(err, convey.ShouldBeNil) + convey.So(resp.ContainerGroupId, convey.ShouldNotBeNil) + }) + + }) +} diff --git a/participant/openI/service/image_test.go b/participant/openI/service/image_test.go index 604d4cd..b72f6bf 100644 --- a/participant/openI/service/image_test.go +++ b/participant/openI/service/image_test.go @@ -9,7 +9,7 @@ import ( ) func TestImage(t *testing.T) { - convey.Convey("Test Image Service", t, func() { + convey.Convey("Test Container Service", t, func() { common.InitClient() token := "8cff1d2db9171462c02901d086d13221389fd082" diff --git a/participant/serverless/common/token.go b/participant/serverless/common/token.go new file mode 100644 index 0000000..abd1bbb --- /dev/null +++ b/participant/serverless/common/token.go @@ -0,0 +1,24 @@ +package common + +import ( + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" + tke "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke/v20180525" +) + +const ( + secretId = "" + secretKey = "" +) + +func GetTkeClient() *tke.Client { + credential := common.NewCredential(secretId, secretKey) + cpf := profile.NewClientProfile() + cpf.HttpProfile.Endpoint = "tke.tencentcloudapi.com" + // 实例化要请求产品的client对象,clientProfile是可选的 + client, err := tke.NewClient(credential, "", cpf) + if err != nil { + panic(err) + } + return client +} diff --git a/participant/serverless/go.mod b/participant/serverless/go.mod index c353830..e284326 100644 --- a/participant/serverless/go.mod +++ b/participant/serverless/go.mod @@ -5,6 +5,8 @@ go 1.22.0 require ( github.com/gin-gonic/gin v1.10.1 github.com/go-resty/resty/v2 v2.16.5 + github.com/smartystreets/goconvey v1.8.1 + github.com/tencentcloud/tencentcloud-sdk-go v3.0.233+incompatible ) require ( @@ -18,13 +20,16 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/smarty/assertions v1.15.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect golang.org/x/arch v0.8.0 // indirect diff --git a/participant/serverless/router/router.go b/participant/serverless/router/router.go index 8e00738..acc829e 100644 --- a/participant/serverless/router/router.go +++ b/participant/serverless/router/router.go @@ -3,7 +3,7 @@ package router import ( "fmt" "github.com/gin-gonic/gin" - "gitlink.org.cn/JointCloud/pcm-participant/serverless/apis" + "gitlink.org.cn/JointCloud/pcm-participant-serverless/apis" "regexp" "time" ) diff --git a/participant/serverless/service/container_test.go b/participant/serverless/service/container_test.go new file mode 100644 index 0000000..2e0227d --- /dev/null +++ b/participant/serverless/service/container_test.go @@ -0,0 +1,37 @@ +package service + +import ( + "fmt" + "github.com/smartystreets/goconvey/convey" + "gitlink.org.cn/JointCloud/pcm-participant-serverless/common" + "gitlink.org.cn/JointCloud/pcm-participant-serverless/model" + "testing" +) + +var ( + requestId string + containerGroupId string +) + +func TestCreateContainer(t *testing.T) { + convey.Convey("Test Service", t, func() { + client := common.GetTkeClient() + convey.Convey("CreateContainer", func() { + param := &model.CreateContainerParam{ + RegionId: "cn-hangzhou", + ContainerGroupName: "minimal-hello", + } + resp, err := CreateContainer(client, param) + if err != nil { + fmt.Println(err.Error()) + } + if !resp.IsSuccess() { + fmt.Println(resp.GetHttpContentString()) + } + + convey.So(err, convey.ShouldBeNil) + convey.So(resp.ContainerGroupId, convey.ShouldNotBeNil) + }) + + }) +} From 5b135a8f8ffaecda40dff2e1d00f656c17c14d7d Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Fri, 11 Jul 2025 18:39:40 +0800 Subject: [PATCH 07/11] =?UTF-8?q?k8s=E5=88=9B=E5=BB=BApod=E5=92=8C?= =?UTF-8?q?=E5=88=9B=E5=BB=BApvc=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/go.mod | 2 +- go.work | 2 + jcs/go.mod | 1 - participant/eci/go.mod | 6 +- participant/eci/model/container.go | 2 +- participant/eci/service/container.go | 5 +- participant/eci/service/container_test.go | 4 +- participant/go.mod | 2 +- participant/k8s/apis/container.go | 30 +++--- participant/k8s/app.go | 2 +- participant/k8s/common/client.go | 2 +- participant/k8s/common/token.go | 30 ++++++ participant/k8s/go.mod | 75 ++++++++++++++- participant/k8s/model/container.go | 26 +++-- participant/k8s/model/response.go | 15 +++ participant/k8s/router/router.go | 2 +- participant/k8s/service/container.go | 94 +++++++++++++++++++ participant/k8s/service/container_test.go | 41 ++++++++ participant/k8s/service/pvc.go | 45 +++++++++ participant/serverless/go.mod | 2 +- .../serverless/service/container_test.go | 37 -------- 21 files changed, 353 insertions(+), 72 deletions(-) create mode 100644 participant/k8s/common/token.go create mode 100644 participant/k8s/model/response.go create mode 100644 participant/k8s/service/container.go create mode 100644 participant/k8s/service/container_test.go create mode 100644 participant/k8s/service/pvc.go delete mode 100644 participant/serverless/service/container_test.go diff --git a/cloud/go.mod b/cloud/go.mod index 40b0369..6788ab8 100644 --- a/cloud/go.mod +++ b/cloud/go.mod @@ -1,6 +1,6 @@ module gitlink.org.cn/JointCloud/pcm-participant-cloud -go 1.24.0 +go 1.23.0 require ( github.com/gin-gonic/gin v1.10.1 diff --git a/go.work b/go.work index bb4e9d3..c1070f0 100644 --- a/go.work +++ b/go.work @@ -1,5 +1,7 @@ go 1.24.0 +toolchain go1.24 + use ( ./ai ./client diff --git a/jcs/go.mod b/jcs/go.mod index 5e74636..0e2bde0 100644 --- a/jcs/go.mod +++ b/jcs/go.mod @@ -2,7 +2,6 @@ module gitlink.org.cn/JointCloud/jcs go 1.23.0 -toolchain go1.24.1 require ( github.com/go-git/go-git/v5 v5.13.2 diff --git a/participant/eci/go.mod b/participant/eci/go.mod index c246dce..dc0ec3e 100644 --- a/participant/eci/go.mod +++ b/participant/eci/go.mod @@ -1,8 +1,9 @@ module gitlink.org.cn/JointCloud/pcm-participant-eci -go 1.22.0 +go 1.23.10 require ( + github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 github.com/gin-gonic/gin v1.10.1 github.com/go-resty/resty/v2 v2.16.5 github.com/smartystreets/goconvey v1.8.1 @@ -20,6 +21,7 @@ require ( github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect @@ -27,6 +29,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/smarty/assertions v1.15.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect @@ -37,5 +40,6 @@ require ( golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/participant/eci/model/container.go b/participant/eci/model/container.go index f7adef3..d7897a2 100644 --- a/participant/eci/model/container.go +++ b/participant/eci/model/container.go @@ -5,7 +5,7 @@ import "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" type CreateContainerParam struct { RegionId string `json:"regionId"` ContainerGroupName string `json:"containerGroupName"` - Container *[]eci.CreateContainerGroupContainer `json:"container"` + Containers *[]eci.CreateContainerGroupContainer `json:"containers"` } type Container struct { Name string `json:"name"` diff --git a/participant/eci/service/container.go b/participant/eci/service/container.go index b44c16b..603dff1 100644 --- a/participant/eci/service/container.go +++ b/participant/eci/service/container.go @@ -9,13 +9,10 @@ import ( type ContainerService struct { } -func NewDatasetService() *ContainerService { - return &ContainerService{} -} func CreateContainer(client *eci.Client, param *model.CreateContainerParam) (*eci.CreateContainerGroupResponse, error) { request := eci.CreateCreateContainerGroupRequest() request.RegionId = param.RegionId - request.Container = param.Container + request.Container = param.Containers request.ContainerGroupName = param.ContainerGroupName // 发送请求 response, err := client.CreateContainerGroup(request) diff --git a/participant/eci/service/container_test.go b/participant/eci/service/container_test.go index 0e670a5..350d518 100644 --- a/participant/eci/service/container_test.go +++ b/participant/eci/service/container_test.go @@ -16,12 +16,12 @@ var ( func TestCreateContainer(t *testing.T) { convey.Convey("Test Service", t, func() { - client := common.GetClient() + client := common.GetEciClient() convey.Convey("CreateContainer", func() { param := &model.CreateContainerParam{ RegionId: "cn-hangzhou", ContainerGroupName: "minimal-hello", - Container: &[]eci.CreateContainerGroupContainer{ + Containers: &[]eci.CreateContainerGroupContainer{ eci.CreateContainerGroupContainer{ Image: "minimal-hello", Name: "minimal-hello", diff --git a/participant/go.mod b/participant/go.mod index 114a914..36509e9 100644 --- a/participant/go.mod +++ b/participant/go.mod @@ -1,3 +1,3 @@ module gitlink.org.cn/JointCloud/pcm-participant -go 1.22.0 +go 1.23.10 diff --git a/participant/k8s/apis/container.go b/participant/k8s/apis/container.go index 13ab2cf..04667f4 100644 --- a/participant/k8s/apis/container.go +++ b/participant/k8s/apis/container.go @@ -1,17 +1,25 @@ package apis -import "github.com/gin-gonic/gin" - -type containerApi struct { - *Api - *service.DatasetService -} - -var DatasetApi = datasetApi{ - Api: BaseApi, - DatasetService: service.NewDatasetService(), -} +import ( + "github.com/gin-gonic/gin" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/common" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/service" + "net/http" +) func CreateContainer(ctx *gin.Context) { + var param model.CreateContainerParam + if err := ctx.BindJSON(¶m); err != nil { + model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, err) + return + } + client := common.GetK8sClient() + err := service.CreateContainer(client, ¶m) + if err != nil { + model.Response(ctx, 500, common.INVOKEERROR, err) + return + } + model.Response(ctx, http.StatusOK, common.SUCCESS, err) } diff --git a/participant/k8s/app.go b/participant/k8s/app.go index 8d42926..166c7f5 100644 --- a/participant/k8s/app.go +++ b/participant/k8s/app.go @@ -8,6 +8,6 @@ import ( func main() { //初始化公共配置 initialize.InitConfig() - rt, _ := router.Create(nil) + rt, _ := router.Create() _ = rt.Run(":2028") } diff --git a/participant/k8s/common/client.go b/participant/k8s/common/client.go index c315031..53e2b02 100644 --- a/participant/k8s/common/client.go +++ b/participant/k8s/common/client.go @@ -4,7 +4,7 @@ import ( "crypto/tls" "errors" "fmt" - "gitlink.org.cn/JointCloud/pcm-participant-eci/model" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" "net/http" "time" diff --git a/participant/k8s/common/token.go b/participant/k8s/common/token.go new file mode 100644 index 0000000..833ef00 --- /dev/null +++ b/participant/k8s/common/token.go @@ -0,0 +1,30 @@ +package common + +import ( + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "time" +) + +const ( + host = "https://119.45.100.73:6443" + bearerToken = "eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA" +) + +func GetK8sClient() *kubernetes.Clientset { + // 1. 加载 kubeconfig 配置(本地开发用) + restConfig := &rest.Config{ + Timeout: 10 * time.Second, + Host: host, + BearerToken: bearerToken, + TLSClientConfig: rest.TLSClientConfig{ + Insecure: true, + }, + } + // 2. 创建 clientset + client, err := kubernetes.NewForConfig(restConfig) + if err != nil { + panic(err) + } + return client +} diff --git a/participant/k8s/go.mod b/participant/k8s/go.mod index 26f286e..d04ea2c 100644 --- a/participant/k8s/go.mod +++ b/participant/k8s/go.mod @@ -1,7 +1,76 @@ module gitlink.org.cn/JointCloud/pcm-participant-k8s -go 1.22.0 +go 1.24.0 -require github.com/go-resty/resty/v2 v2.16.5 +require ( + github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 + github.com/gin-gonic/gin v1.10.1 + github.com/go-resty/resty/v2 v2.16.5 + github.com/smartystreets/goconvey v1.8.1 + k8s.io/api v0.33.2 + k8s.io/apimachinery v0.33.2 + k8s.io/client-go v0.33.2 +) -require golang.org/x/net v0.33.0 // indirect +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gopherjs/gopherjs v1.17.2 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/jtolds/gls v4.20.0+incompatible // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/smarty/assertions v1.15.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/time v0.9.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) diff --git a/participant/k8s/model/container.go b/participant/k8s/model/container.go index 79491b6..5a4dd05 100644 --- a/participant/k8s/model/container.go +++ b/participant/k8s/model/container.go @@ -1,11 +1,25 @@ package model -type ECICreateRequest struct { - RegionId string `json:"regionId"` - ContainerGroupName string `json:"containerGroupName"` - Container []Container `json:"container"` +type CreateContainerParam struct { + ContainerGroupName string `json:"containerGroupName"` + Container Container `json:"Container"` + MountPath string `json:"mountPath,omitempty"` + PvcName string `json:"pvcName,omitempty"` } type Container struct { - Name string `json:"name"` - Image string `json:"image"` + Name string `json:"name"` + Image string `json:"image"` + Limits struct { + Cpu string `json:"cpu,omitempty"` + Memory string `json:"memory,omitempty"` + } `json:"limits,omitempty"` + ContainerPort struct { + Port int32 `json:"port,omitempty"` + HostPort int32 `json:"hostPort,omitempty"` + } `json:"containerPorts,omitempty"` + Envs []struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` + } `json:"envs,omitempty"` + Command []string } diff --git a/participant/k8s/model/response.go b/participant/k8s/model/response.go new file mode 100644 index 0000000..ca40e29 --- /dev/null +++ b/participant/k8s/model/response.go @@ -0,0 +1,15 @@ +package model + +import ( + "github.com/gin-gonic/gin" + "net/http" +) + +func Response(c *gin.Context, code int, msg interface{}, data interface{}) { + c.JSON(http.StatusOK, map[string]interface{}{ + "code": code, + "msg": msg, + "data": data, + }) + return +} diff --git a/participant/k8s/router/router.go b/participant/k8s/router/router.go index 784ff9a..9106c49 100644 --- a/participant/k8s/router/router.go +++ b/participant/k8s/router/router.go @@ -3,7 +3,7 @@ package router import ( "fmt" "github.com/gin-gonic/gin" - "gitlink.org.cn/JointCloud/pcm-participant/k8s/apis" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/apis" "regexp" "time" ) diff --git a/participant/k8s/service/container.go b/participant/k8s/service/container.go new file mode 100644 index 0000000..ca85949 --- /dev/null +++ b/participant/k8s/service/container.go @@ -0,0 +1,94 @@ +package service + +import ( + "context" + "fmt" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +type ContainerService struct { +} + +func NewDatasetService() *ContainerService { + return &ContainerService{} +} + +func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerParam) error { + + if param.MountPath != "" { + // 创建pvc + pvcName, err := CreatePvc(client) + if err != nil { + return err + } + param.PvcName = pvcName + } + // 创建 Pod 对象 + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: param.ContainerGroupName, // Pod 名称(必选) + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ // 至少一个容器(必选) + { + Name: param.Container.Name, + Image: param.Container.Image, + Resources: v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse(param.Container.Limits.Cpu), + v1.ResourceMemory: resource.MustParse(param.Container.Limits.Memory), + }, + }, + Ports: []v1.ContainerPort{ + { + ContainerPort: param.Container.ContainerPort.Port, + HostPort: param.Container.ContainerPort.HostPort, + }, + }, + Env: make([]v1.EnvVar, len(param.Container.Envs)), + Command: param.Container.Command, + VolumeMounts: []v1.VolumeMount{ + { + Name: "minio-volume", + MountPath: param.MountPath, + }, + }, + }, + }, + Volumes: []v1.Volume{ + { + Name: "minio-volume", + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ + ClaimName: param.PvcName, + }, + }, + }, + }, + }, + } + + // 设置环境变量 + for i := range param.Container.Envs { + pod.Spec.Containers[0].Env[i] = v1.EnvVar{ + Name: param.Container.Envs[i].Name, + Value: param.Container.Envs[i].Value, + } + } + + // 发送请求 + response, err := client.CoreV1().Pods("default").Create( + context.TODO(), + pod, + metav1.CreateOptions{}) + if err != nil { + return err + } + + fmt.Printf("Pod created successfully. Name: %s\n", response.Name) + return nil +} diff --git a/participant/k8s/service/container_test.go b/participant/k8s/service/container_test.go new file mode 100644 index 0000000..22b388c --- /dev/null +++ b/participant/k8s/service/container_test.go @@ -0,0 +1,41 @@ +package service + +import ( + "fmt" + "github.com/smartystreets/goconvey/convey" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/common" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" + "testing" +) + +var ( + requestId string + containerGroupId string +) + +func TestCreateContainer(t *testing.T) { + convey.Convey("Test Service", t, func() { + client := common.GetK8sClient() + convey.Convey("CreateContainer", func() { + param := &model.CreateContainerParam{ + ContainerGroupName: "hello-world", + Container: model.Container{ + Image: "nginx:1.25.3", + Name: "hello-world", + }, + } + param.Container.Limits.Cpu = "100m" + param.Container.Limits.Memory = "256Mi" + param.Container.ContainerPort.Port = 80 + param.Container.ContainerPort.HostPort = 8080 + err := CreateContainer(client, param) + if err != nil { + fmt.Println(err.Error()) + } + + convey.So(err, convey.ShouldBeNil) + convey.So("success", convey.ShouldNotBeNil) + }) + + }) +} diff --git a/participant/k8s/service/pvc.go b/participant/k8s/service/pvc.go new file mode 100644 index 0000000..238dfcd --- /dev/null +++ b/participant/k8s/service/pvc.go @@ -0,0 +1,45 @@ +package service + +import ( + "context" + "encoding/base64" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +func CreatePvc(client *kubernetes.Clientset) (string, error) { + randStr := generateUniqueID() + pvc := v1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: randStr + "-pvc", + }, + } + _, err := client.CoreV1().PersistentVolumeClaims("").Create(context.Background(), &pvc, metav1.CreateOptions{}) + if err != nil { + return "", err + } + return pvc.Name, nil + +} + +func generateUniqueID() string { + // 生成足够的随机字节 + bytes := make([]byte, 12) + + // 编码为Base64URL格式 + encoded := base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(bytes) + + // 过滤并保留字母数字字符 + alphanumeric := make([]rune, 0, 6) + for _, r := range encoded { + if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') { + alphanumeric = append(alphanumeric, r) + if len(alphanumeric) == 6 { + break + } + } + } + + return string(alphanumeric) +} diff --git a/participant/serverless/go.mod b/participant/serverless/go.mod index e284326..eb1bfae 100644 --- a/participant/serverless/go.mod +++ b/participant/serverless/go.mod @@ -1,6 +1,6 @@ module gitlink.org.cn/JointCloud/pcm-participant-serverless -go 1.22.0 +go 1.23.10 require ( github.com/gin-gonic/gin v1.10.1 diff --git a/participant/serverless/service/container_test.go b/participant/serverless/service/container_test.go deleted file mode 100644 index 2e0227d..0000000 --- a/participant/serverless/service/container_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package service - -import ( - "fmt" - "github.com/smartystreets/goconvey/convey" - "gitlink.org.cn/JointCloud/pcm-participant-serverless/common" - "gitlink.org.cn/JointCloud/pcm-participant-serverless/model" - "testing" -) - -var ( - requestId string - containerGroupId string -) - -func TestCreateContainer(t *testing.T) { - convey.Convey("Test Service", t, func() { - client := common.GetTkeClient() - convey.Convey("CreateContainer", func() { - param := &model.CreateContainerParam{ - RegionId: "cn-hangzhou", - ContainerGroupName: "minimal-hello", - } - resp, err := CreateContainer(client, param) - if err != nil { - fmt.Println(err.Error()) - } - if !resp.IsSuccess() { - fmt.Println(resp.GetHttpContentString()) - } - - convey.So(err, convey.ShouldBeNil) - convey.So(resp.ContainerGroupId, convey.ShouldNotBeNil) - }) - - }) -} From c5ddc685c5c62b9398da9b8a2d5c0fbb12a8ce15 Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Mon, 14 Jul 2025 16:53:03 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- participant/k8s/model/container.go | 4 ++ participant/k8s/service/container.go | 67 ++++++++++++++++------- participant/k8s/service/container_test.go | 28 +++++++++- participant/k8s/service/pvc.go | 54 +++++++++++------- 4 files changed, 111 insertions(+), 42 deletions(-) diff --git a/participant/k8s/model/container.go b/participant/k8s/model/container.go index 5a4dd05..bd7fa66 100644 --- a/participant/k8s/model/container.go +++ b/participant/k8s/model/container.go @@ -23,3 +23,7 @@ type Container struct { } `json:"envs,omitempty"` Command []string } + +type DeleteContainerParam struct { + ContainerName string `json:"containerGroupName"` +} diff --git a/participant/k8s/service/container.go b/participant/k8s/service/container.go index ca85949..f969967 100644 --- a/participant/k8s/service/container.go +++ b/participant/k8s/service/container.go @@ -5,6 +5,7 @@ import ( "fmt" "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -18,9 +19,16 @@ func NewDatasetService() *ContainerService { } func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerParam) error { - + // 查询pod是否存在 + _, err := client.CoreV1().Pods("default").Get(context.TODO(), param.ContainerGroupName, metav1.GetOptions{}) + if err == nil { + return fmt.Errorf("Pod already exists") + } + if !errors.IsNotFound(err) { + return err + } + // 创建pvc if param.MountPath != "" { - // 创建pvc pvcName, err := CreatePvc(client) if err != nil { return err @@ -35,8 +43,9 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP Spec: v1.PodSpec{ Containers: []v1.Container{ // 至少一个容器(必选) { - Name: param.Container.Name, - Image: param.Container.Image, + ImagePullPolicy: "Never", + Name: param.Container.Name, + Image: param.Container.Image, Resources: v1.ResourceRequirements{ Limits: v1.ResourceList{ v1.ResourceCPU: resource.MustParse(param.Container.Limits.Cpu), @@ -51,26 +60,26 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP }, Env: make([]v1.EnvVar, len(param.Container.Envs)), Command: param.Container.Command, - VolumeMounts: []v1.VolumeMount{ - { - Name: "minio-volume", - MountPath: param.MountPath, - }, - }, - }, - }, - Volumes: []v1.Volume{ - { - Name: "minio-volume", - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: param.PvcName, - }, - }, }, }, }, } + // 挂载pvc + if param.MountPath != "" { + pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ + Name: param.PvcName, + MountPath: param.MountPath, + }) + pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{ + Name: param.PvcName, + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ + ClaimName: param.PvcName, + ReadOnly: false, + }, + }, + }) + } // 设置环境变量 for i := range param.Container.Envs { @@ -86,9 +95,27 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP pod, metav1.CreateOptions{}) if err != nil { + // 删除pvc + client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) return err } fmt.Printf("Pod created successfully. Name: %s\n", response.Name) return nil } + +func DeleteContainer(client *kubernetes.Clientset, param *model.DeleteContainerParam) error { + // 查询pod + pod, err := client.CoreV1().Pods("default").Get(context.TODO(), param.ContainerName, metav1.GetOptions{}) + if err != nil { + return err + } + // 删除pod + err = client.CoreV1().Pods("default").Delete(context.TODO(), pod.Name, metav1.DeleteOptions{}) + if err != nil { + return err + } + // 删除pvc + client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) + return nil +} diff --git a/participant/k8s/service/container_test.go b/participant/k8s/service/container_test.go index 22b388c..181af72 100644 --- a/participant/k8s/service/container_test.go +++ b/participant/k8s/service/container_test.go @@ -18,16 +18,17 @@ func TestCreateContainer(t *testing.T) { client := common.GetK8sClient() convey.Convey("CreateContainer", func() { param := &model.CreateContainerParam{ - ContainerGroupName: "hello-world", + ContainerGroupName: "hello-nginx", Container: model.Container{ - Image: "nginx:1.25.3", - Name: "hello-world", + Image: "nginx:latest", + Name: "hello-nginx", }, } param.Container.Limits.Cpu = "100m" param.Container.Limits.Memory = "256Mi" param.Container.ContainerPort.Port = 80 param.Container.ContainerPort.HostPort = 8080 + param.MountPath = "/data" err := CreateContainer(client, param) if err != nil { fmt.Println(err.Error()) @@ -39,3 +40,24 @@ func TestCreateContainer(t *testing.T) { }) } + +func TestDeleteContainer(t *testing.T) { + convey.Convey("Test Service", t, func() { + client := common.GetK8sClient() + convey.Convey("DeleteContainer", func() { + param := &model.DeleteContainerParam{ + ContainerName: "hello-nginx", + } + err := DeleteContainer(client, param) + if err != nil { + fmt.Println(err.Error()) + } + + convey.So(err, convey.ShouldBeNil) + convey.So("success", convey.ShouldNotBeNil) + }) + + }) +} + +// 删除容器 diff --git a/participant/k8s/service/pvc.go b/participant/k8s/service/pvc.go index 238dfcd..d3cfc0c 100644 --- a/participant/k8s/service/pvc.go +++ b/participant/k8s/service/pvc.go @@ -2,20 +2,42 @@ package service import ( "context" - "encoding/base64" + "crypto/rand" + "encoding/binary" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) +const ( + charSet = "abcdefghijklmnopqrstuvwxyz0123456789" // 36个字符 + base = 36 + length = 9 + maxTries = 1000 // 最大尝试次数 +) + +var sc = "csi-s3" + func CreatePvc(client *kubernetes.Clientset) (string, error) { - randStr := generateUniqueID() + randStr := generateRandomString() pvc := v1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ Name: randStr + "-pvc", }, + Spec: v1.PersistentVolumeClaimSpec{ + AccessModes: []v1.PersistentVolumeAccessMode{ + v1.ReadWriteMany, + }, + Resources: v1.VolumeResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceStorage: resource.MustParse("10Gi"), + }, + }, + StorageClassName: &sc, + }, } - _, err := client.CoreV1().PersistentVolumeClaims("").Create(context.Background(), &pvc, metav1.CreateOptions{}) + _, err := client.CoreV1().PersistentVolumeClaims("default").Create(context.Background(), &pvc, metav1.CreateOptions{}) if err != nil { return "", err } @@ -23,23 +45,17 @@ func CreatePvc(client *kubernetes.Clientset) (string, error) { } -func generateUniqueID() string { - // 生成足够的随机字节 - bytes := make([]byte, 12) +// 生成随机字符串 +func generateRandomString() string { + var builder [length]byte + randomBuf := make([]byte, 8) - // 编码为Base64URL格式 - encoded := base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(bytes) - - // 过滤并保留字母数字字符 - alphanumeric := make([]rune, 0, 6) - for _, r := range encoded { - if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') { - alphanumeric = append(alphanumeric, r) - if len(alphanumeric) == 6 { - break - } + for i := 0; i < length; i++ { + if _, err := rand.Read(randomBuf); err != nil { + return "" } + randomValue := binary.BigEndian.Uint64(randomBuf) + builder[i] = charSet[randomValue%base] } - - return string(alphanumeric) + return string(builder[:]) } From 2fb71a7b7a8c1d72e580edfda0b98f2eb05de76c Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Sat, 19 Jul 2025 15:40:10 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E5=A2=9E=E5=88=A0=E6=9F=A5=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/api/cloud.go | 54 ++++++++ client/go.mod | 3 +- client/go.sum | 34 +++++ cloud/container/container.go | 33 ++++- cloud/container/feature.go | 7 + cloud/container/interface.go | 28 ++-- cloud/container/option.go | 67 ++++++++++ cloud/go.mod | 9 +- cloud/platform/platform.go | 5 +- cloud/service/container.go | 55 ++++++++ cloud/service/kubernetes.go | 65 --------- cloud/service/param.go | 16 +-- cloud/service/service.go | 63 +++++++-- cloud/service/service_test.go | 128 ++++++++++++++++++ cloud/task/interface.go | 17 +-- cloud/task/option.go | 1 + cloud/task/task.go | 22 +--- go.work | 4 +- jcs/go.mod | 21 --- participant/eci/app.go | 4 +- participant/eci/eci.go | 110 ++++++++++++++++ participant/eci/model/container.go | 20 ++- participant/eci/service/container.go | 23 ++++ participant/eci/service/container_test.go | 43 ------ participant/k8s/app.go | 2 +- participant/k8s/k8s.go | 153 ++++++++++++++++++++++ participant/k8s/model/container.go | 4 + participant/k8s/service/container.go | 33 ++++- participant/k8s/service/container_test.go | 63 --------- 29 files changed, 801 insertions(+), 286 deletions(-) create mode 100644 client/api/cloud.go create mode 100644 cloud/container/feature.go create mode 100644 cloud/container/option.go create mode 100644 cloud/service/container.go delete mode 100644 cloud/service/kubernetes.go create mode 100644 cloud/service/service_test.go create mode 100644 cloud/task/option.go create mode 100644 participant/eci/eci.go delete mode 100644 participant/eci/service/container_test.go create mode 100644 participant/k8s/k8s.go delete mode 100644 participant/k8s/service/container_test.go diff --git a/client/api/cloud.go b/client/api/cloud.go new file mode 100644 index 0000000..762f43c --- /dev/null +++ b/client/api/cloud.go @@ -0,0 +1,54 @@ +package api + +import ( + "fmt" + "github.com/gin-gonic/gin" + "github.com/go-playground/validator/v10" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/service" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" + "net/http" + "strconv" + "strings" + "sync" +) + +type cloudApi struct { + *Api + svcLock sync.RWMutex + service *service.Service +} + +var CloudApi = cloudApi{ + Api: BaseApi, +} + +func (a *cloudApi) RegisterSvc(svc *service.Service) { + a.svcLock.Lock() + defer a.svcLock.Unlock() + + a.service = svc +} + +func (c *cloudApi) CreateContainerHandler(ctx *gin.Context) { + pfIdStr := ctx.Query("pfId") + _, err := strconv.ParseInt(pfIdStr, 10, 64) + if err != nil { + model.Response(ctx, http.StatusBadRequest, "invalid pfId", nil) + return + } + var param container.CreateParam + if err := ctx.ShouldBindJSON(¶m); err != nil { + if ve, ok := err.(validator.ValidationErrors); ok { + var errorMsg []string + for _, e := range ve { + errorMsg = append(errorMsg, fmt.Sprintf("字段 %s 验证失败: %s", e.Field(), e.Tag())) + } + model.Response(ctx, http.StatusBadRequest, "请求体格式错误: "+strings.Join(errorMsg, "; "), nil) + } else { + model.Response(ctx, http.StatusBadRequest, "请求体解析失败: "+err.Error(), nil) + } + return + } + //c.service.CreatePod(ctx.Request.Context(), pfId, ¶m) +} diff --git a/client/go.mod b/client/go.mod index 740d90f..5a15fe2 100644 --- a/client/go.mod +++ b/client/go.mod @@ -7,6 +7,7 @@ replace gitlink.org.cn/JointCloud/pcm-participant-common v0.0.0 => ../common require ( github.com/gin-gonic/gin v1.10.0 github.com/hashicorp/yamux v0.1.2 + gitlink.org.cn/JointCloud/pcm-participant-common v0.0.0 ) @@ -39,4 +40,4 @@ require ( golang.org/x/text v0.15.0 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect -) +) \ No newline at end of file diff --git a/client/go.sum b/client/go.sum index af93d9c..bbe93c2 100644 --- a/client/go.sum +++ b/client/go.sum @@ -2,10 +2,16 @@ github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UME github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -13,10 +19,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= +github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -25,8 +37,12 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -41,6 +57,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= @@ -53,6 +71,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -77,24 +97,38 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.19.0 h1:LmbDQUodHThXE+htjrnmVD73M//D9GTH6wFZjyDkjyU= +golang.org/x/arch v0.19.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cloud/container/container.go b/cloud/container/container.go index bb3d204..2bda7b9 100644 --- a/cloud/container/container.go +++ b/cloud/container/container.go @@ -2,12 +2,35 @@ package container import ( "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" - v1 "k8s.io/api/core/v1" ) -type Pods []ISpec +type Containers []ISpec + +func NewContainer(container IContainer) *Container { + return &Container{container: container} +} + +type Container struct { + Platform *platform.Platform `json:"platform,omitempty"` + Name string `json:"name,omitempty"` + Image string `json:"image,omitempty"` + Cpu string `json:"cpu,omitempty"` + Memory string `json:"memory,omitempty"` + container IContainer `json:"container,omitempty"` +} + +func (containers *Containers) Containers() ([]*Container, error) { + res := make([]*Container, len(*containers)) + for _, container := range *containers { + spec, err := container.Spec() + if err != nil { + return nil, err + } + res = append(res, spec) + } + return res, nil +} + +func (c *Container) ContainerCreateParameter() { -type Pod struct { - Platform *platform.Platform `json:"platform,omitempty"` - Pod *v1.Pod `json:"container,omitempty"` } diff --git a/cloud/container/feature.go b/cloud/container/feature.go new file mode 100644 index 0000000..52c9369 --- /dev/null +++ b/cloud/container/feature.go @@ -0,0 +1,7 @@ +package container + +type Features struct { +} + +type FeatureSpec struct { +} diff --git a/cloud/container/interface.go b/cloud/container/interface.go index 31e6ba7..640c40f 100644 --- a/cloud/container/interface.go +++ b/cloud/container/interface.go @@ -2,17 +2,29 @@ package container import ( "context" - "gitlink.org.cn/JointCloud/pcm-participant-cloud/service" - v1 "k8s.io/api/core/v1" ) -type IPod interface { - List(ctx context.Context) (*v1.PodList, error) - Detail(ctx context.Context) (*v1.Pod, error) - Create(ctx context.Context, param *service.CreatePodParam) +type IContainer interface { + Create(ctx context.Context, param *CreateParam) (interface{}, error) + Delete(ctx context.Context, param *DeleteParam) error + Get(ctx context.Context, param *GetParam) (interface{}, error) + Features() *Features } type ISpec interface { - Spec() (*Pod, error) - Detail() (interface{}, error) + Spec() (*Container, error) // 自定义参数 + Detail() (interface{}, error) //官方的参数 + Features() *FeatureSpec // 不同平台差异化出参 +} + +type CreateParameter interface { + ContainerCreateParameter() +} + +type DeleteParameter interface { + ContainerDeleteParameter() +} + +type GetParameter interface { + ContainerGetParameter() } diff --git a/cloud/container/option.go b/cloud/container/option.go new file mode 100644 index 0000000..d3c28df --- /dev/null +++ b/cloud/container/option.go @@ -0,0 +1,67 @@ +package container + +type CreateParam struct { + ContainerGroupName string `json:"containerGroupName"` + Name string `json:"name"` + Image string `json:"image"` + Cpu string `json:"cpu,omitempty"` + Memory string `json:"memory,omitempty"` + Port int32 `json:"port,omitempty"` + HostPort int32 `json:"hostPort,omitempty"` + MountPath string `json:"mountPath,omitempty"` + Envs []struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` + } `json:"envs,omitempty"` + CreateParameter CreateParameter `json:"createParameter,omitempty"` +} + +type K8sCreateParam struct { +} + +type EciCreateParam struct { +} + +func (k K8sCreateParam) ContainerCreateParameter() { +} + +func (e EciCreateParam) ContainerCreateParameter() { +} + +// 删除容器参数 +type DeleteParam struct { + Name string `json:"name,omitempty"` + DeleteParameter DeleteParameter `json:"deleteParameter,omitempty"` +} + +func (k K8sDeleteParam) ContainerDeleteParameter() { +} +func (e EciDeleteParam) ContainerDeleteParameter() { +} + +type K8sDeleteParam struct { +} + +type EciDeleteParam struct { + RegionId string `json:"regionId,omitempty"` + ContainerGroupId string `json:"containerGroupId,omitempty"` +} + +// 获取容器信息 +type GetParam struct { + Name string `json:"name,omitempty"` + GetParameter GetParameter `json:"getParameter,omitempty"` +} + +func (g K8sGetParam) ContainerGetParameter() { +} +func (g EciGetParam) ContainerGetParameter() { +} + +type K8sGetParam struct { +} + +type EciGetParam struct { + RegionId string `json:"regionId,omitempty"` + ContainerGroupName string `json:"containerGroupName,omitempty"` +} diff --git a/cloud/go.mod b/cloud/go.mod index 6788ab8..c827553 100644 --- a/cloud/go.mod +++ b/cloud/go.mod @@ -1,16 +1,18 @@ module gitlink.org.cn/JointCloud/pcm-participant-cloud -go 1.23.0 +go 1.24.0 + +toolchain go1.24.4 require ( github.com/gin-gonic/gin v1.10.1 + github.com/hashicorp/yamux v0.1.2 k8s.io/api v0.33.2 k8s.io/apimachinery v0.33.2 k8s.io/client-go v0.33.2 ) require ( - github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect @@ -32,7 +34,6 @@ require ( github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect @@ -42,7 +43,6 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect @@ -59,7 +59,6 @@ require ( google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect diff --git a/cloud/platform/platform.go b/cloud/platform/platform.go index c5b8076..a9bfda7 100644 --- a/cloud/platform/platform.go +++ b/cloud/platform/platform.go @@ -1,8 +1,9 @@ package platform const ( - Kubernetes Type = "Kubernetes" - Kubesphere Type = "Kubesphere" + K8s Type = "k8s" + Eci Type = "eci" + Serverless Type = "serverless" ) type Platform struct { diff --git a/cloud/service/container.go b/cloud/service/container.go new file mode 100644 index 0000000..f2ef323 --- /dev/null +++ b/cloud/service/container.go @@ -0,0 +1,55 @@ +package service + +import ( + "context" + "errors" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" +) + +type Container struct { + container container.IContainer +} + +func NewContainer(container container.IContainer) *Container { + return &Container{container: container} +} + +func (c *Container) Create(ctx context.Context, param *container.CreateParam) (interface{}, error) { + if param.Name == "" { + return nil, errors.New("Name is required") + } + if param.Image == "" { + return nil, errors.New("Image is required") + } + if param.ContainerGroupName == "" { + return nil, errors.New("ContainerGroupName is required") + } + if param == nil { + return nil, nil + } + ctn, err := c.container.Create(ctx, param) + if err != nil { + return nil, err + } + return ctn, nil +} +func (c *Container) Delete(ctx context.Context, param *container.DeleteParam) error { + if param == nil { + return nil + } + err := c.container.Delete(ctx, param) + if err != nil { + return err + } + return nil +} +func (c *Container) Get(ctx context.Context, param *container.GetParam) (interface{}, error) { + if param == nil { + return nil, errors.New("param is required") + } + resp, err := c.container.Get(ctx, param) + if err != nil { + return nil, err + } + return resp, err +} diff --git a/cloud/service/kubernetes.go b/cloud/service/kubernetes.go deleted file mode 100644 index ffa4a99..0000000 --- a/cloud/service/kubernetes.go +++ /dev/null @@ -1,65 +0,0 @@ -package service - -import ( - "context" - "fmt" - "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "time" -) - -type Option struct { - username string - token string - platform *platform.Platform -} -type Kubernetes struct { - opt *Option - DynamicClient *dynamic.DynamicClient - ClientSet *kubernetes.Clientset -} - -func New(bearerToken, url string) *Kubernetes { - restConfig := &rest.Config{ - Timeout: 10 * time.Second, - Host: url, - BearerToken: bearerToken, - TLSClientConfig: rest.TLSClientConfig{ - Insecure: true, - }, - } - dynamicClient, err := dynamic.NewForConfig(restConfig) - if err != nil { - fmt.Println(err.Error()) - } - clientSet, err := kubernetes.NewForConfig(restConfig) - if err != nil { - fmt.Println(err.Error()) - } - return &Kubernetes{ - DynamicClient: dynamicClient, - ClientSet: clientSet, - } -} -func (k *Kubernetes) CreatePod(ctx context.Context, param *CreatePodParam) error { - _, err := k.ClientSet.CoreV1().Pods("").Create(ctx, param.Pod, metav1.CreateOptions{}) - if err != nil { - return err - } - return nil -} - -func (k *Kubernetes) Type() platform.Type { - return k.opt.platform.Type -} - -func (k *Kubernetes) Id() platform.Id { - return k.opt.platform.Id -} - -func (k *Kubernetes) Name() string { - return k.opt.platform.Name -} diff --git a/cloud/service/param.go b/cloud/service/param.go index dd91ed8..ba62a24 100644 --- a/cloud/service/param.go +++ b/cloud/service/param.go @@ -1,17 +1,5 @@ package service -import ( - "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" - v1 "k8s.io/api/apps/v1" - v2 "k8s.io/api/core/v1" -) - -type CreateDeploymentParam struct { - Id *platform.Id `json:"id" form:"id"` - Deployment v1.Deployment `json:"deployment" form:"deployment"` -} - -type CreatePodParam struct { - Id platform.Id `json:"id" form:"id"` - Pod *v2.Pod `json:"container" form:"container"` +type ContainerParam struct { + Name string `json:"name,omitempty" form:"name"` } diff --git a/cloud/service/service.go b/cloud/service/service.go index 82b6e04..5cd137c 100644 --- a/cloud/service/service.go +++ b/cloud/service/service.go @@ -2,31 +2,66 @@ package service import ( "context" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + eci "gitlink.org.cn/JointCloud/pcm-participant-eci" + k8s "gitlink.org.cn/JointCloud/pcm-participant-k8s" "sync" ) type Service struct { - clientMap map[platform.Id]*Kubernetes - rlock sync.Mutex - dlock sync.Mutex - tlock sync.Mutex + containerMap map[platform.Id]*Container + rlock sync.Mutex + dlock sync.Mutex + tlock sync.Mutex } func NewService(platforms ...platform.IPlatform) (*Service, error) { - clientMap := map[platform.Id]*Kubernetes{} - for _, platform := range platforms { - kubernetes, ok := platform.(*Kubernetes) - if !ok { + containerMap := make(map[platform.Id]*Container) + for _, pf := range platforms { + switch pf.Type() { + case platform.K8s: + k8s, ok := pf.(*k8s.Kubernetes) + if !ok { + } + containerMap[pf.Id()] = NewContainer(k8s.Container) + case platform.Eci: + eci, ok := pf.(*eci.Eci) + if !ok { + + } + containerMap[pf.Id()] = NewContainer(eci.Container) } - clientMap[platform.Id()] = kubernetes } - return &Service{ - clientMap: clientMap, - }, nil + + return &Service{containerMap: containerMap}, nil } -func (s *Service) CreatePod(ctx context.Context, param *CreatePodParam) { - s.clientMap[param.Id].CreatePod(ctx, param) + +func (s *Service) CreateContainer(ctx context.Context, pid int64, param *container.CreateParam) (interface{}, error) { + svc := s.containerMap[platform.Id(pid)] + resp, err := svc.Create(ctx, param) + if err != nil { + return nil, err + } + + return resp, nil +} +func (s *Service) DeleteContainer(ctx context.Context, pid int64, param *container.DeleteParam) error { + svc := s.containerMap[platform.Id(pid)] + err := svc.Delete(ctx, param) + if err != nil { + return err + } + return nil +} + +func (s *Service) GetContainer(ctx context.Context, pid int64, param *container.GetParam) (interface{}, error) { + svc := s.containerMap[platform.Id(pid)] + resp, err := svc.Get(ctx, param) + if err != nil { + return nil, err + } + return resp, nil } diff --git a/cloud/service/service_test.go b/cloud/service/service_test.go new file mode 100644 index 0000000..02503a5 --- /dev/null +++ b/cloud/service/service_test.go @@ -0,0 +1,128 @@ +package service + +import ( + "context" + "fmt" + "github.com/smartystreets/goconvey/convey" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" + eci "gitlink.org.cn/JointCloud/pcm-participant-eci" + k8s "gitlink.org.cn/JointCloud/pcm-participant-k8s" + "testing" + "time" +) + +func TestCreateService(t *testing.T) { + convey.Convey("Test Service", t, func() { + k8s, err := k8s.New("eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA", "https://119.45.100.73:6443", 123) + if err != nil { + t.Fatalf("failed to create k8s client: %v", err) + } + eci, err := eci.New("LTAI5tLdKjnos44aLvN1XWJk", "FIF0zpGpA8Q0dEraw28VAUTKg7sVLR", "cn-hangzhou", 456) + if err != nil { + t.Fatalf("failed to create eci client: %v", err) + } + + svc, err := NewService(k8s, eci) + if err != nil { + t.Fatalf("failed to create service: %v", err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + convey.Convey("all train algorithms", func() { + param := container.CreateParam{ + ContainerGroupName: "hello-nginx", + Image: "nginx:latest", + Name: "hello-nginx", + Cpu: "1.0", + Memory: "1.0", + } + ctn, err := svc.CreateContainer(ctx, 456, ¶m) + if err != nil { + fmt.Println(err) + } + + convey.So(err, convey.ShouldBeNil) + convey.So(ctn, convey.ShouldNotBeEmpty) + + }) + + }) +} + +func TestDeleteService(t *testing.T) { + convey.Convey("Test Service", t, func() { + k8s, err := k8s.New("eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA", "https://119.45.100.73:6443", 123) + if err != nil { + t.Fatalf("failed to create k8s client: %v", err) + } + eci, err := eci.New("LTAI5tLdKjnos44aLvN1XWJk", "FIF0zpGpA8Q0dEraw28VAUTKg7sVLR", "cn-hangzhou", 456) + if err != nil { + t.Fatalf("failed to create eci client: %v", err) + } + + svc, err := NewService(k8s, eci) + if err != nil { + t.Fatalf("failed to create service: %v", err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + convey.Convey("all train algorithms", func() { + param := container.DeleteParam{ + DeleteParameter: &container.EciDeleteParam{ + RegionId: "cn-hangzhou", + ContainerGroupId: "eci-bp1f6qix5wkkeqhzoc77", + }, + } + err := svc.DeleteContainer(ctx, 456, ¶m) + if err != nil { + fmt.Println(err) + } + + convey.So(err, convey.ShouldBeNil) + convey.So(nil, convey.ShouldNotBeEmpty) + + }) + + }) +} + +func TestGetService(t *testing.T) { + convey.Convey("Test Service", t, func() { + k8s, err := k8s.New("eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA", "https://119.45.100.73:6443", 123) + if err != nil { + t.Fatalf("failed to create k8s client: %v", err) + } + eci, err := eci.New("LTAI5tLdKjnos44aLvN1XWJk", "FIF0zpGpA8Q0dEraw28VAUTKg7sVLR", "cn-hangzhou", 456) + if err != nil { + t.Fatalf("failed to create eci client: %v", err) + } + + svc, err := NewService(k8s, eci) + if err != nil { + t.Fatalf("failed to create service: %v", err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + convey.Convey("all train algorithms", func() { + param := container.GetParam{ + Name: "hello-nginx", + GetParameter: &container.EciGetParam{}, + } + resp, err := svc.GetContainer(ctx, 456, ¶m) + if err != nil { + fmt.Println(err) + } + fmt.Println(resp) + convey.So(err, convey.ShouldBeNil) + convey.So(resp, convey.ShouldNotBeEmpty) + + }) + + }) +} diff --git a/cloud/task/interface.go b/cloud/task/interface.go index ba68bd3..94f30b8 100644 --- a/cloud/task/interface.go +++ b/cloud/task/interface.go @@ -3,18 +3,11 @@ package task import "context" type Task interface { - Infer - Train + Container } -type Infer interface { - Infer(ctx context.Context, params *InferParams) (Result, error) -} - -type Train interface { - Train(ctx context.Context, params *TrainParams) (Result, error) -} - -type Result interface { - Get(ctx context.Context, id string) error +type Container interface { + CreateContainer(ctx context.Context, params *TaskParams) (interface{}, error) + GetContainer(ctx context.Context, id string) (interface{}, error) + DeleteContainer(ctx context.Context, id string) error } diff --git a/cloud/task/option.go b/cloud/task/option.go new file mode 100644 index 0000000..b028dfd --- /dev/null +++ b/cloud/task/option.go @@ -0,0 +1 @@ +package task diff --git a/cloud/task/task.go b/cloud/task/task.go index 448fd3a..918abf8 100644 --- a/cloud/task/task.go +++ b/cloud/task/task.go @@ -1,25 +1,9 @@ package task import ( - "gitlink.org.cn/JointCloud/pcm-participant-ai/algorithm" - "gitlink.org.cn/JointCloud/pcm-participant-ai/dataset" - "gitlink.org.cn/JointCloud/pcm-participant-ai/image" - "gitlink.org.cn/JointCloud/pcm-participant-ai/resource" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" ) -type ContainerParams struct { - TaskName string - Desc string - Resource resource.TrainParameter - Image image.TrainParameter - Dataset dataset.TrainParameter - Algorithm algorithm.TrainParameter -} - -type InferParams struct { - TaskName string - Desc string - Resource resource.TrainParameter - Image image.TrainParameter - Algorithm algorithm.TrainParameter +type TaskParams struct { + Container container.CreateParameter } diff --git a/go.work b/go.work index 8ac783c..39f7396 100644 --- a/go.work +++ b/go.work @@ -11,11 +11,11 @@ use ( ./participant ./participant/eci ./participant/k8s + ./participant/octopus ./participant/openI ./participant/serverless ./platform hpc - participant/octopus ) replace gitlink.org.cn/JointCloud/pcm-participant-common v0.0.0 => ./common @@ -23,3 +23,5 @@ replace gitlink.org.cn/JointCloud/pcm-participant-common v0.0.0 => ./common replace gitlink.org.cn/JointCloud/pcm-participant-ai v0.0.0 => ./ai replace gitlink.org.cn/JointCloud/pcm-participant-openi v0.0.0 => ./participant/openI + +replace gitlink.org.cn/JointCloud/pcm-participant-octopus v0.0.0 => ./participant/octopus diff --git a/jcs/go.mod b/jcs/go.mod index 0e2bde0..239c2da 100644 --- a/jcs/go.mod +++ b/jcs/go.mod @@ -2,7 +2,6 @@ module gitlink.org.cn/JointCloud/jcs go 1.23.0 - require ( github.com/go-git/go-git/v5 v5.13.2 github.com/go-resty/resty/v2 v2.16.5 @@ -10,7 +9,6 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/json-iterator/go v1.1.12 github.com/pkg/errors v0.9.1 - gitlink.org.cn/JointCloud/pcm-openi v0.0.0-20250321070427-b3addd77a29d gopkg.in/yaml.v3 v3.0.1 ) @@ -18,45 +16,26 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ProtonMail/go-crypto v1.1.5 // indirect - github.com/bytedance/sonic v1.13.2 // indirect - github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cloudflare/circl v1.3.7 // indirect - github.com/cloudwego/base64x v0.1.5 // indirect github.com/cyphar/filepath-securejoin v0.3.6 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/gin-contrib/sse v1.0.0 // indirect - github.com/gin-gonic/gin v1.10.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.25.0 // indirect - github.com/goccy/go-json v0.10.5 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect - github.com/leodido/go-urn v1.4.0 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.0 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/arch v0.15.0 // indirect golang.org/x/crypto v0.36.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.37.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/protobuf v1.36.6 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/participant/eci/app.go b/participant/eci/app.go index 359cdeb..110dac6 100644 --- a/participant/eci/app.go +++ b/participant/eci/app.go @@ -1,4 +1,4 @@ -package openI +package eci import ( "gitlink.org.cn/JointCloud/pcm-participant-eci/initialize" @@ -8,6 +8,6 @@ import ( func main() { //初始化公共配置 initialize.InitConfig() - rt, _ := router.Create(nil) + rt, _ := router.Create() _ = rt.Run(":2028") } diff --git a/participant/eci/eci.go b/participant/eci/eci.go new file mode 100644 index 0000000..f5e5bda --- /dev/null +++ b/participant/eci/eci.go @@ -0,0 +1,110 @@ +package eci + +import ( + "context" + "errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + "gitlink.org.cn/JointCloud/pcm-participant-eci/model" + "gitlink.org.cn/JointCloud/pcm-participant-eci/service" +) + +type Eci struct { + Container *Container + opt *Option +} + +type Container struct { + opt *Option + ft *container.Features +} + +type Option struct { + platform *platform.Platform + client *eci.Client +} + +func New(accessKeyId, accessKeySecret, regionId string, id platform.Id) (*Eci, error) { + config := sdk.NewConfig() + credential := credentials.NewAccessKeyCredential(accessKeyId, accessKeySecret) + client, err := eci.NewClientWithOptions(regionId, config, credential) + if err != nil { + panic(err) + } + opt := &Option{ + client: client, + platform: &platform.Platform{ + Id: id, + Type: platform.Eci, + }, + } + container := &Container{ + opt: opt, + } + return &Eci{opt: opt, Container: container}, nil +} +func (e *Eci) Name() string { + return e.opt.platform.Name +} +func (e *Eci) Type() platform.Type { + return e.opt.platform.Type +} +func (e *Eci) Id() platform.Id { + return e.opt.platform.Id +} +func (c *Container) Create(ctx context.Context, param *container.CreateParam) (interface{}, error) { + if param.Name == "" { + return nil, errors.New("Name is required") + } + if param.Image == "" { + return nil, errors.New("Image is required") + } + if param.ContainerGroupName == "" { + return nil, errors.New("ContainerGroupName is required") + } + cParam := model.CreateContainerParam{ + Containers: &[]eci.CreateContainerGroupContainer{ + { + Image: param.Image, + Name: param.Name, + Cpu: requests.Float(param.Cpu), + Memory: requests.Float(param.Memory), + }, + }, + ContainerGroupName: param.ContainerGroupName, + } + resp, err := service.CreateContainer(c.opt.client, &cParam) + if err != nil { + return nil, err + } + return resp, nil +} +func (c *Container) Delete(ctx context.Context, param *container.DeleteParam) error { + deleteParam := param.DeleteParameter.(*container.EciDeleteParam) + err := service.DeleteContainer(c.opt.client, &model.DeleteContainerParam{ + RegionId: deleteParam.RegionId, + ContainerGroupId: deleteParam.ContainerGroupId, + }) + if err != nil { + return err + } + return nil +} +func (c *Container) Features() *container.Features { + return nil +} +func (c *Container) Get(ctx context.Context, param *container.GetParam) (interface{}, error) { + getParam := param.GetParameter.(*container.EciGetParam) + resp, err := service.GetContainer(c.opt.client, &model.GetContainerParam{ + RegionId: getParam.RegionId, + ContainerGroupName: getParam.ContainerGroupName, + }) + if err != nil { + return nil, err + } + return resp, nil +} diff --git a/participant/eci/model/container.go b/participant/eci/model/container.go index d7897a2..da0e9a1 100644 --- a/participant/eci/model/container.go +++ b/participant/eci/model/container.go @@ -1,6 +1,9 @@ package model -import "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" +) type CreateContainerParam struct { RegionId string `json:"regionId"` @@ -8,8 +11,10 @@ type CreateContainerParam struct { Containers *[]eci.CreateContainerGroupContainer `json:"containers"` } type Container struct { - Name string `json:"name"` - Image string `json:"image"` + Name string `json:"name"` + Image string `json:"image"` + Memory requests.Float `json:"memory"` + Cpu requests.Float `json:"cpu"` } type CreateContainerRemote struct { @@ -20,3 +25,12 @@ type CreateContainerRemote struct { } `json:"payload"` Error interface{} `json:"error"` } +type DeleteContainerParam struct { + RegionId string `json:"regionId"` + ContainerGroupId string `json:"containerGroupId"` +} + +type GetContainerParam struct { + RegionId string `json:"regionId"` + ContainerGroupName string `json:"containerGroupName"` +} diff --git a/participant/eci/service/container.go b/participant/eci/service/container.go index 603dff1..06510ba 100644 --- a/participant/eci/service/container.go +++ b/participant/eci/service/container.go @@ -10,6 +10,7 @@ type ContainerService struct { } func CreateContainer(client *eci.Client, param *model.CreateContainerParam) (*eci.CreateContainerGroupResponse, error) { + request := eci.CreateCreateContainerGroupRequest() request.RegionId = param.RegionId request.Container = param.Containers @@ -22,3 +23,25 @@ func CreateContainer(client *eci.Client, param *model.CreateContainerParam) (*ec } return response, nil } + +func DeleteContainer(client *eci.Client, param *model.DeleteContainerParam) error { + request := eci.CreateDeleteContainerGroupRequest() + request.RegionId = param.RegionId + request.ContainerGroupId = param.ContainerGroupId + _, err := client.DeleteContainerGroup(request) + if err != nil { + return err + } + return nil +} + +func GetContainer(client *eci.Client, param *model.GetContainerParam) (interface{}, error) { + request := eci.CreateDescribeContainerGroupsRequest() + request.RegionId = param.RegionId + request.ContainerGroupName = param.ContainerGroupName + resp, err := client.DescribeContainerGroups(request) + if err != nil { + return nil, err + } + return resp, nil +} diff --git a/participant/eci/service/container_test.go b/participant/eci/service/container_test.go deleted file mode 100644 index 350d518..0000000 --- a/participant/eci/service/container_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package service - -import ( - "fmt" - "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" - "github.com/smartystreets/goconvey/convey" - "gitlink.org.cn/JointCloud/pcm-participant-eci/common" - "gitlink.org.cn/JointCloud/pcm-participant-eci/model" - "testing" -) - -var ( - requestId string - containerGroupId string -) - -func TestCreateContainer(t *testing.T) { - convey.Convey("Test Service", t, func() { - client := common.GetEciClient() - convey.Convey("CreateContainer", func() { - param := &model.CreateContainerParam{ - RegionId: "cn-hangzhou", - ContainerGroupName: "minimal-hello", - Containers: &[]eci.CreateContainerGroupContainer{ - eci.CreateContainerGroupContainer{ - Image: "minimal-hello", - Name: "minimal-hello", - }, - }, - } - resp, err := CreateContainer(client, param) - if err != nil { - fmt.Println(err.Error()) - } - if !resp.IsSuccess() { - fmt.Println(resp.GetHttpContentString()) - } - convey.So(err, convey.ShouldBeNil) - convey.So(resp.ContainerGroupId, convey.ShouldNotBeNil) - }) - - }) -} diff --git a/participant/k8s/app.go b/participant/k8s/app.go index 166c7f5..e126885 100644 --- a/participant/k8s/app.go +++ b/participant/k8s/app.go @@ -1,4 +1,4 @@ -package openI +package k8s import ( "gitlink.org.cn/JointCloud/pcm-participant-k8s/initialize" diff --git a/participant/k8s/k8s.go b/participant/k8s/k8s.go new file mode 100644 index 0000000..55afb00 --- /dev/null +++ b/participant/k8s/k8s.go @@ -0,0 +1,153 @@ +package k8s + +import ( + "context" + "errors" + "fmt" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/service" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "time" +) + +type Container struct { + opt *Option + ft *container.Features +} +type ContainerSpec struct { + opt *Option + fSpec *container.FeatureSpec + container *model.Container +} +type Option struct { + platform *platform.Platform + DynamicClient *dynamic.DynamicClient + ClientSet *kubernetes.Clientset +} +type Kubernetes struct { + Container *Container + opt *Option +} + +func New(bearerToken, url string, id platform.Id) (*Kubernetes, error) { + + restConfig := &rest.Config{ + Timeout: 10 * time.Second, + Host: url, + BearerToken: bearerToken, + TLSClientConfig: rest.TLSClientConfig{ + Insecure: true, + }, + } + dynamicClient, err := dynamic.NewForConfig(restConfig) + if err != nil { + fmt.Println(err.Error()) + } + clientSet, err := kubernetes.NewForConfig(restConfig) + if err != nil { + fmt.Println(err.Error()) + } + opt := &Option{ + DynamicClient: dynamicClient, + ClientSet: clientSet, + platform: &platform.Platform{ + Id: id, + Type: platform.K8s, + }, + } + container := &Container{ + opt: opt, + } + return &Kubernetes{ + opt: opt, + Container: container, + }, nil +} + +func (ic *ContainerSpec) Detail() (interface{}, error) { + return ic.container, nil +} +func (ic *ContainerSpec) Spec() (*container.Container, error) { + return nil, nil +} + +func (ic *ContainerSpec) Features() *container.FeatureSpec { + return ic.fSpec +} + +func (c *Container) Create(ctx context.Context, param *container.CreateParam) (interface{}, error) { + if param.Name == "" { + return nil, errors.New("Name is required") + } + if param.Image == "" { + return nil, errors.New("Image is required") + } + if param.ContainerGroupName == "" { + return nil, errors.New("ContainerGroupName is required") + } + cParam := model.CreateContainerParam{ + Container: model.Container{ + Name: param.Name, + Image: param.Image, + Limits: struct { + Cpu string `json:"cpu,omitempty"` + Memory string `json:"memory,omitempty"` + }{ + Cpu: param.Cpu, + Memory: param.Memory, + }, + ContainerPort: struct { + Port int32 `json:"port,omitempty"` + HostPort int32 `json:"hostPort,omitempty"` + }{}, + Envs: nil, + Command: nil, + }, + ContainerGroupName: param.ContainerGroupName, + } + err := service.CreateContainer(c.opt.ClientSet, &cParam) + if err != nil { + return nil, err + } + // 返回创建的容器信息 + return cParam.Container, nil +} +func (c *Container) Delete(ctx context.Context, param *container.DeleteParam) error { + if param.Name == "" { + return errors.New("Name is required") + } + err := service.DeleteContainer(c.opt.ClientSet, &model.DeleteContainerParam{ + ContainerName: param.Name, + }) + if err != nil { + return err + } + return nil +} + +func (c *Container) Features() *container.Features { + return nil +} +func (k *Kubernetes) Name() string { + return k.opt.platform.Name +} +func (k *Kubernetes) Type() platform.Type { + return k.opt.platform.Type +} +func (k *Kubernetes) Id() platform.Id { + return k.opt.platform.Id +} + +func (c *Container) Get(ctx context.Context, param *container.GetParam) (interface{}, error) { + pod, err := service.GetContainer(c.opt.ClientSet, &model.GetContainerParam{ + Name: param.Name, + }) + if err != nil { + return nil, err + } + return pod, nil +} diff --git a/participant/k8s/model/container.go b/participant/k8s/model/container.go index bd7fa66..43252b9 100644 --- a/participant/k8s/model/container.go +++ b/participant/k8s/model/container.go @@ -27,3 +27,7 @@ type Container struct { type DeleteContainerParam struct { ContainerName string `json:"containerGroupName"` } + +type GetContainerParam struct { + Name string `json:"name"` +} diff --git a/participant/k8s/service/container.go b/participant/k8s/service/container.go index f969967..8c9d628 100644 --- a/participant/k8s/service/container.go +++ b/participant/k8s/service/container.go @@ -52,12 +52,6 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP v1.ResourceMemory: resource.MustParse(param.Container.Limits.Memory), }, }, - Ports: []v1.ContainerPort{ - { - ContainerPort: param.Container.ContainerPort.Port, - HostPort: param.Container.ContainerPort.HostPort, - }, - }, Env: make([]v1.EnvVar, len(param.Container.Envs)), Command: param.Container.Command, }, @@ -81,6 +75,14 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP }) } + // 设置端口 + for i := range param.Container.ContainerPort.Port { + pod.Spec.Containers[0].Ports[i] = v1.ContainerPort{ + ContainerPort: param.Container.ContainerPort.Port, + HostPort: param.Container.ContainerPort.HostPort, + } + } + // 设置环境变量 for i := range param.Container.Envs { pod.Spec.Containers[0].Env[i] = v1.EnvVar{ @@ -95,6 +97,7 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP pod, metav1.CreateOptions{}) if err != nil { + fmt.Printf(err.Error()) // 删除pvc client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) return err @@ -116,6 +119,22 @@ func DeleteContainer(client *kubernetes.Clientset, param *model.DeleteContainerP return err } // 删除pvc - client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) + if pod.Spec.Volumes[0].PersistentVolumeClaim != nil { + err = client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) + if err != nil { + return err + } + } + return nil } + +func GetContainer(client *kubernetes.Clientset, param *model.GetContainerParam) (interface{}, error) { + // 查询pod + pod, err := client.CoreV1().Pods("default").Get(context.TODO(), param.Name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + return pod, nil +} diff --git a/participant/k8s/service/container_test.go b/participant/k8s/service/container_test.go deleted file mode 100644 index 181af72..0000000 --- a/participant/k8s/service/container_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package service - -import ( - "fmt" - "github.com/smartystreets/goconvey/convey" - "gitlink.org.cn/JointCloud/pcm-participant-k8s/common" - "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" - "testing" -) - -var ( - requestId string - containerGroupId string -) - -func TestCreateContainer(t *testing.T) { - convey.Convey("Test Service", t, func() { - client := common.GetK8sClient() - convey.Convey("CreateContainer", func() { - param := &model.CreateContainerParam{ - ContainerGroupName: "hello-nginx", - Container: model.Container{ - Image: "nginx:latest", - Name: "hello-nginx", - }, - } - param.Container.Limits.Cpu = "100m" - param.Container.Limits.Memory = "256Mi" - param.Container.ContainerPort.Port = 80 - param.Container.ContainerPort.HostPort = 8080 - param.MountPath = "/data" - err := CreateContainer(client, param) - if err != nil { - fmt.Println(err.Error()) - } - - convey.So(err, convey.ShouldBeNil) - convey.So("success", convey.ShouldNotBeNil) - }) - - }) -} - -func TestDeleteContainer(t *testing.T) { - convey.Convey("Test Service", t, func() { - client := common.GetK8sClient() - convey.Convey("DeleteContainer", func() { - param := &model.DeleteContainerParam{ - ContainerName: "hello-nginx", - } - err := DeleteContainer(client, param) - if err != nil { - fmt.Println(err.Error()) - } - - convey.So(err, convey.ShouldBeNil) - convey.So("success", convey.ShouldNotBeNil) - }) - - }) -} - -// 删除容器 From ceae117b21803bb5193eb3f77647e0505b647372 Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Wed, 23 Jul 2025 08:39:10 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E6=8E=A8=E7=90=86=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/container/option.go | 17 +++++------ cloud/service/service_test.go | 28 +++++++++++------- participant/k8s/k8s.go | 9 ++++-- participant/k8s/model/container.go | 8 +++--- participant/k8s/service/container.go | 41 ++++++++++++-------------- participant/k8s/service/pvc.go | 2 +- participant/k8s/service/svc.go | 43 ++++++++++++++++++++++++++++ 7 files changed, 100 insertions(+), 48 deletions(-) create mode 100644 participant/k8s/service/svc.go diff --git a/cloud/container/option.go b/cloud/container/option.go index d3c28df..ef430f6 100644 --- a/cloud/container/option.go +++ b/cloud/container/option.go @@ -1,14 +1,15 @@ package container type CreateParam struct { - ContainerGroupName string `json:"containerGroupName"` - Name string `json:"name"` - Image string `json:"image"` - Cpu string `json:"cpu,omitempty"` - Memory string `json:"memory,omitempty"` - Port int32 `json:"port,omitempty"` - HostPort int32 `json:"hostPort,omitempty"` - MountPath string `json:"mountPath,omitempty"` + ContainerGroupName string `json:"containerGroupName"` + Name string `json:"name"` + Image string `json:"image"` + Cpu string `json:"cpu,omitempty"` + Memory string `json:"memory,omitempty"` + Port int32 `json:"port,omitempty"` + NodePort int32 `json:"nodePort,omitempty"` + MountPath string `json:"mountPath,omitempty"` + Args []string `json:"args,omitempty"` Envs []struct { Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` diff --git a/cloud/service/service_test.go b/cloud/service/service_test.go index 02503a5..9ace0a8 100644 --- a/cloud/service/service_test.go +++ b/cloud/service/service_test.go @@ -32,13 +32,18 @@ func TestCreateService(t *testing.T) { convey.Convey("all train algorithms", func() { param := container.CreateParam{ - ContainerGroupName: "hello-nginx", - Image: "nginx:latest", - Name: "hello-nginx", - Cpu: "1.0", - Memory: "1.0", + ContainerGroupName: "hello-llama", + Image: "ghcr.io/ggml-org/llama.cpp:server", + //Image: "nginx:latest", + Name: "hello-llama", + Args: []string{"-m", "/models/ERNIE-4.5-0.3B-PT-GGUF/ernie-4.5-0.3b-pt-q4_k_m.gguf", "--port", "8000", "--host", "0.0.0.0", "-n", "512"}, + MountPath: "/models", + Port: 8000, + NodePort: 30000, + Cpu: "100m", + Memory: "256Mi", } - ctn, err := svc.CreateContainer(ctx, 456, ¶m) + ctn, err := svc.CreateContainer(ctx, 123, ¶m) if err != nil { fmt.Println(err) } @@ -72,12 +77,13 @@ func TestDeleteService(t *testing.T) { convey.Convey("all train algorithms", func() { param := container.DeleteParam{ - DeleteParameter: &container.EciDeleteParam{ - RegionId: "cn-hangzhou", - ContainerGroupId: "eci-bp1f6qix5wkkeqhzoc77", - }, + //DeleteParameter: &container.EciDeleteParam{ + //RegionId: "cn-hangzhou", + //ContainerGroupId: "eci-bp1f6qix5wkkeqhzoc77", + //}, + Name: "hello-llama", } - err := svc.DeleteContainer(ctx, 456, ¶m) + err := svc.DeleteContainer(ctx, 123, ¶m) if err != nil { fmt.Println(err) } diff --git a/participant/k8s/k8s.go b/participant/k8s/k8s.go index 55afb00..25977ab 100644 --- a/participant/k8s/k8s.go +++ b/participant/k8s/k8s.go @@ -93,6 +93,7 @@ func (c *Container) Create(ctx context.Context, param *container.CreateParam) (i Container: model.Container{ Name: param.Name, Image: param.Image, + Args: param.Args, Limits: struct { Cpu string `json:"cpu,omitempty"` Memory string `json:"memory,omitempty"` @@ -102,12 +103,16 @@ func (c *Container) Create(ctx context.Context, param *container.CreateParam) (i }, ContainerPort: struct { Port int32 `json:"port,omitempty"` - HostPort int32 `json:"hostPort,omitempty"` - }{}, + NodePort int32 `json:"nodePort,omitempty"` + }{ + Port: param.Port, + NodePort: param.NodePort, + }, Envs: nil, Command: nil, }, ContainerGroupName: param.ContainerGroupName, + MountPath: param.MountPath, } err := service.CreateContainer(c.opt.ClientSet, &cParam) if err != nil { diff --git a/participant/k8s/model/container.go b/participant/k8s/model/container.go index 43252b9..2e3dfa7 100644 --- a/participant/k8s/model/container.go +++ b/participant/k8s/model/container.go @@ -4,18 +4,18 @@ type CreateContainerParam struct { ContainerGroupName string `json:"containerGroupName"` Container Container `json:"Container"` MountPath string `json:"mountPath,omitempty"` - PvcName string `json:"pvcName,omitempty"` } type Container struct { - Name string `json:"name"` - Image string `json:"image"` + Name string `json:"name"` + Image string `json:"image"` + Args []string `json:"args,omitempty"` Limits struct { Cpu string `json:"cpu,omitempty"` Memory string `json:"memory,omitempty"` } `json:"limits,omitempty"` ContainerPort struct { Port int32 `json:"port,omitempty"` - HostPort int32 `json:"hostPort,omitempty"` + NodePort int32 `json:"nodePort,omitempty"` } `json:"containerPorts,omitempty"` Envs []struct { Name string `json:"name,omitempty"` diff --git a/participant/k8s/service/container.go b/participant/k8s/service/container.go index 8c9d628..74a4095 100644 --- a/participant/k8s/service/container.go +++ b/participant/k8s/service/container.go @@ -27,25 +27,30 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP if !errors.IsNotFound(err) { return err } - // 创建pvc - if param.MountPath != "" { - pvcName, err := CreatePvc(client) + // 创建svc + if param.Container.ContainerPort.Port != 0 { + _, err := CreateSvc(client, param) if err != nil { return err } - param.PvcName = pvcName } // 创建 Pod 对象 pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: param.ContainerGroupName, // Pod 名称(必选) + Labels: map[string]string{ + "app": param.ContainerGroupName, + }, }, + Spec: v1.PodSpec{ + HostNetwork: true, Containers: []v1.Container{ // 至少一个容器(必选) { ImagePullPolicy: "Never", Name: param.Container.Name, Image: param.Container.Image, + Args: param.Container.Args, Resources: v1.ResourceRequirements{ Limits: v1.ResourceList{ v1.ResourceCPU: resource.MustParse(param.Container.Limits.Cpu), @@ -61,28 +66,20 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP // 挂载pvc if param.MountPath != "" { pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ - Name: param.PvcName, + Name: "11mvgt1jh-pvc", MountPath: param.MountPath, }) pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{ - Name: param.PvcName, + Name: "11mvgt1jh-pvc", VolumeSource: v1.VolumeSource{ PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: param.PvcName, + ClaimName: "11mvgt1jh-pvc", ReadOnly: false, }, }, }) } - // 设置端口 - for i := range param.Container.ContainerPort.Port { - pod.Spec.Containers[0].Ports[i] = v1.ContainerPort{ - ContainerPort: param.Container.ContainerPort.Port, - HostPort: param.Container.ContainerPort.HostPort, - } - } - // 设置环境变量 for i := range param.Container.Envs { pod.Spec.Containers[0].Env[i] = v1.EnvVar{ @@ -99,7 +96,7 @@ func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerP if err != nil { fmt.Printf(err.Error()) // 删除pvc - client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) + //client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) return err } @@ -119,12 +116,12 @@ func DeleteContainer(client *kubernetes.Clientset, param *model.DeleteContainerP return err } // 删除pvc - if pod.Spec.Volumes[0].PersistentVolumeClaim != nil { - err = client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) - if err != nil { - return err - } - } + //if pod.Spec.Volumes[0].PersistentVolumeClaim != nil { + // err = client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) + // if err != nil { + // return err + // } + //} return nil } diff --git a/participant/k8s/service/pvc.go b/participant/k8s/service/pvc.go index d3cfc0c..0e45d82 100644 --- a/participant/k8s/service/pvc.go +++ b/participant/k8s/service/pvc.go @@ -31,7 +31,7 @@ func CreatePvc(client *kubernetes.Clientset) (string, error) { }, Resources: v1.VolumeResourceRequirements{ Requests: v1.ResourceList{ - v1.ResourceStorage: resource.MustParse("10Gi"), + v1.ResourceStorage: resource.MustParse("1Gi"), }, }, StorageClassName: &sc, diff --git a/participant/k8s/service/svc.go b/participant/k8s/service/svc.go new file mode 100644 index 0000000..e61dc45 --- /dev/null +++ b/participant/k8s/service/svc.go @@ -0,0 +1,43 @@ +package service + +import ( + "context" + "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/kubernetes" +) + +func CreateSvc(client *kubernetes.Clientset, param *model.CreateContainerParam) (string, error) { + + svc := v1.Service{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: param.ContainerGroupName + "-service", + }, + + Spec: v1.ServiceSpec{ + Type: "NodePort", + Selector: map[string]string{ + "app": param.ContainerGroupName, + }, + Ports: []v1.ServicePort{ + { + Port: param.Container.ContainerPort.Port, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: param.Container.ContainerPort.Port, + }, + NodePort: param.Container.ContainerPort.NodePort, + }, + }, + }, + } + _, err := client.CoreV1().Services("default").Create(context.Background(), &svc, metav1.CreateOptions{}) + if err != nil { + return "", err + } + return svc.Name, nil + +} From cd1b06bb9e6a03c3b1d8692e3b95a6b47d7ecadd Mon Sep 17 00:00:00 2001 From: zhangwei <894646498@qq.com> Date: Thu, 24 Jul 2025 15:46:18 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E5=88=9B=E5=BB=BA=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=20=E6=9F=A5=E8=AF=A2=E5=AE=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/api/cloud.go | 56 ++++++++-- client/config/config.yaml | 3 +- client/config/pcm_core.go | 11 +- client/initialize/cloudCluster.go | 152 +++++++++++++++++++++++++++ client/main.go | 14 ++- client/router/cloud.go | 7 +- cloud/platform/platform.go | 4 +- cloud/service/service.go | 12 ++- cloud/service/service_test.go | 19 ++-- participant/k8s/service/container.go | 23 ++-- 10 files changed, 251 insertions(+), 50 deletions(-) create mode 100644 client/initialize/cloudCluster.go diff --git a/client/api/cloud.go b/client/api/cloud.go index 762f43c..665dadf 100644 --- a/client/api/cloud.go +++ b/client/api/cloud.go @@ -8,7 +8,6 @@ import ( "gitlink.org.cn/JointCloud/pcm-participant-cloud/service" "gitlink.org.cn/JointCloud/pcm-participant-k8s/model" "net/http" - "strconv" "strings" "sync" ) @@ -31,12 +30,8 @@ func (a *cloudApi) RegisterSvc(svc *service.Service) { } func (c *cloudApi) CreateContainerHandler(ctx *gin.Context) { - pfIdStr := ctx.Query("pfId") - _, err := strconv.ParseInt(pfIdStr, 10, 64) - if err != nil { - model.Response(ctx, http.StatusBadRequest, "invalid pfId", nil) - return - } + pfId := ctx.Query("pfId") + var param container.CreateParam if err := ctx.ShouldBindJSON(¶m); err != nil { if ve, ok := err.(validator.ValidationErrors); ok { @@ -50,5 +45,50 @@ func (c *cloudApi) CreateContainerHandler(ctx *gin.Context) { } return } - //c.service.CreatePod(ctx.Request.Context(), pfId, ¶m) + fmt.Println(c.service) + createContainer, err := c.service.CreateContainer(ctx.Request.Context(), pfId, ¶m) + if err != nil { + model.Response(ctx, http.StatusInternalServerError, err, nil) + return + } + model.Response(ctx, http.StatusOK, "success", createContainer) +} + +func (c *cloudApi) DeleteContainerHandler(ctx *gin.Context) { + pfId := ctx.Query("pfId") + + var param container.DeleteParam + if err := ctx.ShouldBindJSON(¶m); err != nil { + if ve, ok := err.(validator.ValidationErrors); ok { + var errorMsg []string + for _, e := range ve { + errorMsg = append(errorMsg, fmt.Sprintf("字段 %s 验证失败: %s", e.Field(), e.Tag())) + } + model.Response(ctx, http.StatusBadRequest, "请求体格式错误: "+strings.Join(errorMsg, "; "), nil) + } else { + model.Response(ctx, http.StatusBadRequest, "请求体解析失败: "+err.Error(), nil) + } + return + } + err := c.service.DeleteContainer(ctx.Request.Context(), pfId, ¶m) + if err != nil { + model.Response(ctx, http.StatusInternalServerError, err, nil) + return + } + model.Response(ctx, http.StatusOK, "success", nil) +} + +func (c *cloudApi) GetContainerHandler(ctx *gin.Context) { + pfId := ctx.Query("pfId") + name := ctx.Query("name") + param := container.GetParam{ + Name: name, + } + + getContainer, err := c.service.GetContainer(ctx.Request.Context(), pfId, ¶m) + if err != nil { + model.Response(ctx, http.StatusInternalServerError, err, nil) + return + } + model.Response(ctx, http.StatusOK, "success", getContainer) } diff --git a/client/config/config.yaml b/client/config/config.yaml index fca8ef7..818938f 100644 --- a/client/config/config.yaml +++ b/client/config/config.yaml @@ -8,4 +8,5 @@ pcm-core: coordinator-host: http://127.0.0.1:8999 participant-host: http://localhost:8080 hpc-cluster-list: /pcm/v1/adapter/cluster/list?type=2&pageNum=1&pageSize=10&storageSchedule=1 - ai-cluster-list: /pcm/v1/adapter/cluster/list?adapterId=1777144940456666666&type=1&pageNum=1&pageSize=10&storageSchedule=1 \ No newline at end of file + ai-cluster-list: /pcm/v1/adapter/cluster/list?adapterId=1777144940456666666&type=1&pageNum=1&pageSize=10&storageSchedule=1 + cloud-cluster-list: /pcm/v1/adapter/cluster/list?adapterId=1770658294298316800&type=0&pageNum=1&pageSize=10 \ No newline at end of file diff --git a/client/config/pcm_core.go b/client/config/pcm_core.go index a570a94..f5658f6 100644 --- a/client/config/pcm_core.go +++ b/client/config/pcm_core.go @@ -1,9 +1,10 @@ package config type PcmCore struct { - CoordinatorHost string `mapstructure:"coordinator-host" json:"coordinator-host" yaml:"coordinator-host"` // C端主机地址 - ParticipantHost string `mapstructure:"participant-host" json:"participant-host" yaml:"participant-host"` // 本P端服务主机地址 - HPCClusterList string `mapstructure:"hpc-cluster-list" json:"hpc-cluster-list" yaml:"hpc-cluster-list"` // 集群列表接口 - AIClusterList string `mapstructure:"ai-cluster-list" json:"ai-cluster-list" yaml:"ai-cluster-list"` // 集群列表接口 - Token string `mapstructure:"token" json:"token" yaml:"token"` + CoordinatorHost string `mapstructure:"coordinator-host" json:"coordinator-host" yaml:"coordinator-host"` // C端主机地址 + ParticipantHost string `mapstructure:"participant-host" json:"participant-host" yaml:"participant-host"` // 本P端服务主机地址 + HPCClusterList string `mapstructure:"hpc-cluster-list" json:"hpc-cluster-list" yaml:"hpc-cluster-list"` // 集群列表接口 + AIClusterList string `mapstructure:"ai-cluster-list" json:"ai-cluster-list" yaml:"ai-cluster-list"` // 集群列表接口 + CloudClusterList string `mapstructure:"cloud-cluster-list" json:"cloud-cluster-list" yaml:"cloud-cluster-list"` + Token string `mapstructure:"token" json:"token" yaml:"token"` } diff --git a/client/initialize/cloudCluster.go b/client/initialize/cloudCluster.go new file mode 100644 index 0000000..1af7fde --- /dev/null +++ b/client/initialize/cloudCluster.go @@ -0,0 +1,152 @@ +package initialize + +import ( + "fmt" + "github.com/go-resty/resty/v2" + "gitlink.org.cn/JointCloud/pcm-participant-client/common/types" + "gitlink.org.cn/JointCloud/pcm-participant-client/common/utils" + "gitlink.org.cn/JointCloud/pcm-participant-client/config" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/service" + eci "gitlink.org.cn/JointCloud/pcm-participant-eci" + k8s "gitlink.org.cn/JointCloud/pcm-participant-k8s" + "strconv" + + "go.uber.org/zap" +) + +// 获取所有集群信息 +func GetAllCloudClusterInfos() map[string]types.ClusterInfo { + result := make(map[string]types.ClusterInfo) + clusterInfos.Range(func(key, value interface{}) bool { + result[key.(string)] = value.(types.ClusterInfo) + return true + }) + return result +} + +func InitCloudCluster(cfg *config.Server) (*service.Service, error) { + client := utils.InitClient(cfg.PcmCore.CoordinatorHost, "") + return initCloudSvc(client, cfg.PcmCore) +} + +// 初始化智算集群连接池 +func initCloudSvc(client *utils.RestyClient, core config.PcmCore) (*service.Service, error) { + resp := types.ResultResp{} + token := "Bearer " + core.Token + _, err := client.Request(core.CoordinatorHost+core.CloudClusterList, "GET", func(req *resty.Request) { + req.SetHeader("Authorization", token).SetResult(&resp) + }) + if err != nil { + return nil, fmt.Errorf("获取集群列表失败: %w", err) + } + + if resp.Code != 200 { + return nil, fmt.Errorf("API返回错误: %d, 消息: %s", resp.Code, resp.Msg) + } + + var platforms []platform.IPlatform + var svc *service.Service + //var octopus octopus.Octopus + + for _, cluster := range resp.Data.List { + if cluster.Status == "offline" { + + // 修改集群的server地址为本服务的地址,修改状态为在线 + cluster.Server = core.ParticipantHost + cluster.Status = "online" + + updateClusterReq := types.ClusterCreateReq{ + Id: cluster.Id, + AdapterId: strconv.FormatInt(cluster.AdapterId, 10), + Name: cluster.Name, + Nickname: cluster.Nickname, + Description: cluster.Description, + Server: cluster.Server, + MonitorServer: cluster.MonitorServer, + Username: cluster.Username, + Password: cluster.Password, + Token: cluster.Token, + Ak: cluster.Ak, + Sk: cluster.Sk, + RegionName: cluster.Region, + ProjectId: cluster.ProjectId, + Version: cluster.Version, + Label: cluster.Label, + OwnerId: cluster.OwnerId, + AuthType: cluster.AuthType, + ProducerDict: cluster.ProducerDict, + RegionDict: cluster.RegionDict, + Status: cluster.Status, + } + + updateResp := types.ResultResp{} + _, err := client.Request(core.CoordinatorHost+"/pcm/v1/adapter/cluster/update", "PUT", func(req *resty.Request) { + req.SetBody(updateClusterReq).SetResult(&updateResp) // 添加请求体 + }) + + if err != nil { + zap.L().Error("更新集群状态失败", zap.Error(err)) + continue + } + if updateResp.Code != 200 { + zap.L().Error("更新集群状态API返回错误", + zap.Int("code", updateResp.Code), + zap.String("message", updateResp.Msg)) + continue + } + + } else if cluster.Status == "online" { + if cluster.Server != core.ParticipantHost { + zap.L().Warn("集群已被其他服务代理", + zap.String("cluster_id", cluster.Id), + zap.String("当前服务地址", core.ParticipantHost), + zap.String("集群记录地址", cluster.Server)) + continue + } else { + // 更新集群信息的修改时间 + _, err := client.Request(core.CoordinatorHost+"/pcm/v1/adapter/cluster/update", "PUT", func(req *resty.Request) { + req.SetBody(cluster) + }) + if err != nil { + zap.L().Error("刷新集群时间失败", zap.Error(err)) + } + } + } + + if cluster.Id == "" { + zap.L().Warn("跳过无效集群条目: 缺少集群ID") + continue + } + switch cluster.Label { + case "kubernetes": + k8s, err := k8s.New(cluster.Token, cluster.Address, platform.Id(cluster.Id)) + if err != nil { + Error("初始化失败", zap.Error(err)) + continue + } + platforms = append(platforms, k8s) + //更新C端集群状态 + case "eci": + eci, err := eci.New(cluster.Ak, cluster.Sk, cluster.Password, platform.Id(cluster.Id)) + if err != nil { + Error("初始化失败", zap.Error(err)) + continue + } + platforms = append(platforms, eci) + + } + } + if len(platforms) == 0 { + return nil, fmt.Errorf("注册集群列表为空") + } + + for _, p := range platforms { + Info("注册集群列表:", zap.Any("id", p.Id()), zap.Any("type", p.Type()), zap.Any("name", p.Name())) + } + svc, err = service.NewService(platforms...) + if err != nil { + return nil, err + } + return svc, nil +} diff --git a/client/main.go b/client/main.go index 2334f2b..130f55f 100644 --- a/client/main.go +++ b/client/main.go @@ -40,14 +40,20 @@ func main() { //if err := initialize.InitHPCCluster(cfg); err != nil { // zap.L().Fatal("集群初始化失败", zap.Error(err)) //} - // 初始化集群连接 - svc, err := initialize.InitAICluster(cfg) + // 初始化智算集群连接 + aiSvc, err := initialize.InitAICluster(cfg) if err != nil { initialize.Panic("Server started failed: %s", err) return } - api.AiApi.RegisterSvc(svc) - + api.AiApi.RegisterSvc(aiSvc) + // 初始化通算集群连接 + cloudSvc, err := initialize.InitCloudCluster(cfg) + if err != nil { + initialize.Panic("Server started failed: %s", err) + return + } + api.CloudApi.RegisterSvc(cloudSvc) defer initialize.CloseAllPools() // 设置退出处理 setupGracefulShutdown() diff --git a/client/router/cloud.go b/client/router/cloud.go index 2be6807..0cc63ab 100644 --- a/client/router/cloud.go +++ b/client/router/cloud.go @@ -9,9 +9,10 @@ func CloudRoutes(server *gin.Engine) { cloud := server.Group("/cloud") cloudApi := api.CloudApi { - pod := cloud.Group("container") - pod.GET("/list", cloudApi.ListPod) - pod.POST("/create", cloudApi.CreatePodHandler) + cloud := cloud.Group("container") + cloud.POST("/create", cloudApi.CreateContainerHandler) + cloud.DELETE("/delete", cloudApi.DeleteContainerHandler) + cloud.GET("/get", cloudApi.GetContainerHandler) } { //deployment := cloud.Group("deployment") diff --git a/cloud/platform/platform.go b/cloud/platform/platform.go index a9bfda7..427b0bd 100644 --- a/cloud/platform/platform.go +++ b/cloud/platform/platform.go @@ -1,7 +1,7 @@ package platform const ( - K8s Type = "k8s" + K8s Type = "kubernetes" Eci Type = "eci" Serverless Type = "serverless" ) @@ -13,4 +13,4 @@ type Platform struct { } type Type string -type Id int64 +type Id string diff --git a/cloud/service/service.go b/cloud/service/service.go index 5cd137c..85378d0 100644 --- a/cloud/service/service.go +++ b/cloud/service/service.go @@ -2,6 +2,7 @@ package service import ( "context" + "fmt" "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" eci "gitlink.org.cn/JointCloud/pcm-participant-eci" @@ -39,8 +40,13 @@ func NewService(platforms ...platform.IPlatform) (*Service, error) { return &Service{containerMap: containerMap}, nil } -func (s *Service) CreateContainer(ctx context.Context, pid int64, param *container.CreateParam) (interface{}, error) { +func (s *Service) CreateContainer(ctx context.Context, pid string, param *container.CreateParam) (interface{}, error) { + fmt.Println(s.containerMap) + for id := range s.containerMap { + fmt.Println(s.containerMap[id]) + } svc := s.containerMap[platform.Id(pid)] + fmt.Println(svc) resp, err := svc.Create(ctx, param) if err != nil { return nil, err @@ -48,7 +54,7 @@ func (s *Service) CreateContainer(ctx context.Context, pid int64, param *contain return resp, nil } -func (s *Service) DeleteContainer(ctx context.Context, pid int64, param *container.DeleteParam) error { +func (s *Service) DeleteContainer(ctx context.Context, pid string, param *container.DeleteParam) error { svc := s.containerMap[platform.Id(pid)] err := svc.Delete(ctx, param) if err != nil { @@ -57,7 +63,7 @@ func (s *Service) DeleteContainer(ctx context.Context, pid int64, param *contain return nil } -func (s *Service) GetContainer(ctx context.Context, pid int64, param *container.GetParam) (interface{}, error) { +func (s *Service) GetContainer(ctx context.Context, pid string, param *container.GetParam) (interface{}, error) { svc := s.containerMap[platform.Id(pid)] resp, err := svc.Get(ctx, param) if err != nil { diff --git a/cloud/service/service_test.go b/cloud/service/service_test.go index 9ace0a8..25b31d8 100644 --- a/cloud/service/service_test.go +++ b/cloud/service/service_test.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/smartystreets/goconvey/convey" "gitlink.org.cn/JointCloud/pcm-participant-cloud/container" + "gitlink.org.cn/JointCloud/pcm-participant-cloud/platform" eci "gitlink.org.cn/JointCloud/pcm-participant-eci" k8s "gitlink.org.cn/JointCloud/pcm-participant-k8s" "testing" @@ -13,11 +14,11 @@ import ( func TestCreateService(t *testing.T) { convey.Convey("Test Service", t, func() { - k8s, err := k8s.New("eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA", "https://119.45.100.73:6443", 123) + k8s, err := k8s.New("", "", platform.Id(123)) if err != nil { t.Fatalf("failed to create k8s client: %v", err) } - eci, err := eci.New("LTAI5tLdKjnos44aLvN1XWJk", "FIF0zpGpA8Q0dEraw28VAUTKg7sVLR", "cn-hangzhou", 456) + eci, err := eci.New("", "", "cn-hangzhou", platform.Id(456)) if err != nil { t.Fatalf("failed to create eci client: %v", err) } @@ -43,7 +44,7 @@ func TestCreateService(t *testing.T) { Cpu: "100m", Memory: "256Mi", } - ctn, err := svc.CreateContainer(ctx, 123, ¶m) + ctn, err := svc.CreateContainer(ctx, "123", ¶m) if err != nil { fmt.Println(err) } @@ -58,11 +59,11 @@ func TestCreateService(t *testing.T) { func TestDeleteService(t *testing.T) { convey.Convey("Test Service", t, func() { - k8s, err := k8s.New("eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA", "https://119.45.100.73:6443", 123) + k8s, err := k8s.New("eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA", "https://119.45.100.73:6443", platform.Id(123)) if err != nil { t.Fatalf("failed to create k8s client: %v", err) } - eci, err := eci.New("LTAI5tLdKjnos44aLvN1XWJk", "FIF0zpGpA8Q0dEraw28VAUTKg7sVLR", "cn-hangzhou", 456) + eci, err := eci.New("LTAI5tLdKjnos44aLvN1XWJk", "FIF0zpGpA8Q0dEraw28VAUTKg7sVLR", "cn-hangzhou", platform.Id(456)) if err != nil { t.Fatalf("failed to create eci client: %v", err) } @@ -83,7 +84,7 @@ func TestDeleteService(t *testing.T) { //}, Name: "hello-llama", } - err := svc.DeleteContainer(ctx, 123, ¶m) + err := svc.DeleteContainer(ctx, "123", ¶m) if err != nil { fmt.Println(err) } @@ -98,11 +99,11 @@ func TestDeleteService(t *testing.T) { func TestGetService(t *testing.T) { convey.Convey("Test Service", t, func() { - k8s, err := k8s.New("eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA", "https://119.45.100.73:6443", 123) + k8s, err := k8s.New("eyJhbGciOiJSUzI1NiIsImtpZCI6IkNzNXRMOE5VdWdiVHJ2U2JtU3ZKWk5razRwZlJHWWZmV3M0aVNHLUJJOHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTg0bW5sIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjOWU1NjU1OC1lZTRhLTQ1MGUtYTljNy03NGNhNDU4NzEyNGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.IxXITCqR8Yv-C3mkC3ItwkDLhNueFk_HMF7QhFtjch8miVhUYH3g2Uh70EB5M_3F8vZIF3CoYd3TLG_1acg2JR9Tf7Ipiwzol3npXIqG27QQJ-px3q2i3CMqwjogKjCSEMWTxHS03CDOCJUFLL2qKIa4U-QmEUYnbOFnNsoXDr7zkgRyREi5QUqlEB1ODMlEy8wb6n1g8E9AqNxnYBeHywAAS8ZMkTiKlEdhi-7Jgblkcssmb_P_5xbWelIy6HfBZuumJICzd8b5JRrkX7m7MaIx4TgNETa17kCFi1JnC6MvC1u3UGQQ7MKiXrud06cN9Sphgnu5nIkFjF5TWpSuaA", "https://119.45.100.73:6443", platform.Id(123)) if err != nil { t.Fatalf("failed to create k8s client: %v", err) } - eci, err := eci.New("LTAI5tLdKjnos44aLvN1XWJk", "FIF0zpGpA8Q0dEraw28VAUTKg7sVLR", "cn-hangzhou", 456) + eci, err := eci.New("LTAI5tLdKjnos44aLvN1XWJk", "FIF0zpGpA8Q0dEraw28VAUTKg7sVLR", "cn-hangzhou", platform.Id(456)) if err != nil { t.Fatalf("failed to create eci client: %v", err) } @@ -120,7 +121,7 @@ func TestGetService(t *testing.T) { Name: "hello-nginx", GetParameter: &container.EciGetParam{}, } - resp, err := svc.GetContainer(ctx, 456, ¶m) + resp, err := svc.GetContainer(ctx, "456", ¶m) if err != nil { fmt.Println(err) } diff --git a/participant/k8s/service/container.go b/participant/k8s/service/container.go index 74a4095..d7b1202 100644 --- a/participant/k8s/service/container.go +++ b/participant/k8s/service/container.go @@ -11,18 +11,11 @@ import ( "k8s.io/client-go/kubernetes" ) -type ContainerService struct { -} - -func NewDatasetService() *ContainerService { - return &ContainerService{} -} - func CreateContainer(client *kubernetes.Clientset, param *model.CreateContainerParam) error { // 查询pod是否存在 _, err := client.CoreV1().Pods("default").Get(context.TODO(), param.ContainerGroupName, metav1.GetOptions{}) if err == nil { - return fmt.Errorf("Pod already exists") + return err } if !errors.IsNotFound(err) { return err @@ -115,13 +108,13 @@ func DeleteContainer(client *kubernetes.Clientset, param *model.DeleteContainerP if err != nil { return err } - // 删除pvc - //if pod.Spec.Volumes[0].PersistentVolumeClaim != nil { - // err = client.CoreV1().PersistentVolumeClaims("default").Delete(context.TODO(), pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.DeleteOptions{}) - // if err != nil { - // return err - // } - //} + // 删除svc + if pod.Spec.Containers[0].Ports != nil { + err = client.CoreV1().Services("default").Delete(context.TODO(), pod.Name+"-service", metav1.DeleteOptions{}) + if err != nil { + return err + } + } return nil }