diff --git a/api/types/environment.go b/api/types/environment.go index c1b4b63..026a35f 100644 --- a/api/types/environment.go +++ b/api/types/environment.go @@ -16,6 +16,7 @@ type ResourceSpec struct { CPU string `json:"cpu,omitempty"` Memory string `json:"memory,omitempty"` GPU string `json:"gpu,omitempty"` + Shm string `json:"shm,omitempty"` } type ObjectMeta struct { diff --git a/cmd/envd-server/main.go b/cmd/envd-server/main.go index 9cd935e..9a310a4 100644 --- a/cmd/envd-server/main.go +++ b/cmd/envd-server/main.go @@ -44,8 +44,8 @@ func handleErr(err error) { // @license.url https://mozilla.org/MPL/2.0/ // @securitydefinitions.apikey Authentication -// @in header -// @name JWT +// @in header +// @name JWT // @host localhost:8080 // @BasePath /api/v1 diff --git a/pkg/docs/docs.go b/pkg/docs/docs.go index 44a7c74..e6699c3 100644 --- a/pkg/docs/docs.go +++ b/pkg/docs/docs.go @@ -1035,6 +1035,9 @@ const docTemplate = `{ }, "memory": { "type": "string" + }, + "shm": { + "type": "string" } } } diff --git a/pkg/runtime/kubernetes/const.go b/pkg/runtime/kubernetes/const.go index 221068b..b0aa2e5 100644 --- a/pkg/runtime/kubernetes/const.go +++ b/pkg/runtime/kubernetes/const.go @@ -6,4 +6,6 @@ package kubernetes const ( ResourceNvidiaGPU = "nvidia.com/gpu" + ResourceShm = "shm" + ResourceShmPath = "/dev/shm" ) diff --git a/pkg/runtime/kubernetes/environment_create.go b/pkg/runtime/kubernetes/environment_create.go index 2c223d1..d8d456f 100644 --- a/pkg/runtime/kubernetes/environment_create.go +++ b/pkg/runtime/kubernetes/environment_create.go @@ -157,6 +157,27 @@ func (p generalProvisioner) EnvironmentCreate(ctx context.Context, }) } + if env.Resources.Shm != "" { + shm, err := resource.ParseQuantity(env.Resources.Shm) + if err != nil { + return nil, errors.Wrapf(err, "failed to parse shm resource: %s", env.Resources.Shm) + } + logrus.Debugf("configure shared memory to %s", env.Resources.Shm) + expectedPod.Spec.Volumes = append(expectedPod.Spec.Volumes, v1.Volume{ + Name: ResourceShm, + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{ + Medium: "Memory", + SizeLimit: &shm, + }, + }, + }) + expectedPod.Spec.Containers[0].VolumeMounts = append(expectedPod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ + Name: ResourceShm, + MountPath: ResourceShmPath, + }) + } + if p.imagePullSecretName != nil { expectedPod.Spec.ImagePullSecrets = []v1.LocalObjectReference{ { diff --git a/pkg/server/environment_create.go b/pkg/server/environment_create.go index efed933..87b12ff 100644 --- a/pkg/server/environment_create.go +++ b/pkg/server/environment_create.go @@ -19,9 +19,9 @@ import ( // @Tags environment // @Accept json // @Produce json -// @Param login_name path string true "login name" example("alice") -// @Param request body types.EnvironmentCreateRequest true "query params" -// @Success 201 {object} types.EnvironmentCreateResponse +// @Param login_name path string true "login name" example("alice") +// @Param request body types.EnvironmentCreateRequest true "query params" +// @Success 201 {object} types.EnvironmentCreateResponse // @Router /users/{login_name}/environments [post] func (s Server) environmentCreate(c *gin.Context) error { owner := c.GetString(ContextLoginName) diff --git a/pkg/server/environment_get.go b/pkg/server/environment_get.go index f90e078..39d279f 100644 --- a/pkg/server/environment_get.go +++ b/pkg/server/environment_get.go @@ -19,9 +19,9 @@ import ( // @Tags environment // @Accept json // @Produce json -// @Param login_name path string true "login name" example("alice") -// @Param name path string true "environment name" example("pytorch-example") -// @Success 200 {object} types.EnvironmentGetResponse +// @Param login_name path string true "login name" example("alice") +// @Param name path string true "environment name" example("pytorch-example") +// @Success 200 {object} types.EnvironmentGetResponse // @Router /users/{login_name}/environments/{name} [get] func (s Server) environmentGet(c *gin.Context) error { owner := c.GetString(ContextLoginName) diff --git a/pkg/server/environment_list.go b/pkg/server/environment_list.go index 10e34aa..f116122 100644 --- a/pkg/server/environment_list.go +++ b/pkg/server/environment_list.go @@ -20,8 +20,8 @@ import ( // @Tags environment // @Accept json // @Produce json -// @Param login_name path string true "login name" example("alice") -// @Success 200 {object} types.EnvironmentListResponse +// @Param login_name path string true "login name" example("alice") +// @Success 200 {object} types.EnvironmentListResponse // @Router /users/{login_name}/environments [get] func (s Server) environmentList(c *gin.Context) error { owner := c.GetString(ContextLoginName) diff --git a/pkg/server/environment_remove.go b/pkg/server/environment_remove.go index cff81c1..47d3cea 100644 --- a/pkg/server/environment_remove.go +++ b/pkg/server/environment_remove.go @@ -19,9 +19,9 @@ import ( // @Tags environment // @Accept json // @Produce json -// @Param login_name path string true "login name" example("alice") -// @Param name path string true "environment name" example("pytorch-example") -// @Success 200 {object} types.EnvironmentRemoveResponse +// @Param login_name path string true "login name" example("alice") +// @Param name path string true "environment name" example("pytorch-example") +// @Success 200 {object} types.EnvironmentRemoveResponse // @Router /users/{login_name}/environments/{name} [delete] func (s *Server) environmentRemove(c *gin.Context) error { owner := c.GetString(ContextLoginName) diff --git a/pkg/server/image_get.go b/pkg/server/image_get.go index f011a1b..984a30a 100644 --- a/pkg/server/image_get.go +++ b/pkg/server/image_get.go @@ -20,9 +20,9 @@ import ( // @Tags image // @Accept json // @Produce json -// @Param login_name path string true "login name" example("alice") -// @Param name path string true "digest" example("python-example") -// @Success 200 {object} types.ImageGetResponse +// @Param login_name path string true "login name" example("alice") +// @Param name path string true "digest" example("python-example") +// @Success 200 {object} types.ImageGetResponse // @Router /users/{login_name}/images/{name} [get] func (s *Server) imageGet(c *gin.Context) error { owner := c.GetString(ContextLoginName) diff --git a/pkg/server/image_list.go b/pkg/server/image_list.go index 89f709b..511f3bb 100644 --- a/pkg/server/image_list.go +++ b/pkg/server/image_list.go @@ -19,8 +19,8 @@ import ( // @Tags image // @Accept json // @Produce json -// @Param login_name path string true "login name" example("alice") -// @Success 200 {object} types.ImageListResponse +// @Param login_name path string true "login name" example("alice") +// @Success 200 {object} types.ImageListResponse // @Router /users/{login_name}/images [get] func (s *Server) imageList(c *gin.Context) error { owner := c.GetString(ContextLoginName) diff --git a/pkg/server/key_create.go b/pkg/server/key_create.go index 64bbfe1..fea7164 100644 --- a/pkg/server/key_create.go +++ b/pkg/server/key_create.go @@ -20,9 +20,9 @@ import ( // @Tags key // @Accept json // @Produce json -// @Param login_name path string true "login name" example("alice") -// @Param request body types.KeyCreateRequest true "query params" -// @Success 201 {object} types.KeyCreateResponse +// @Param login_name path string true "login name" example("alice") +// @Param request body types.KeyCreateRequest true "query params" +// @Success 201 {object} types.KeyCreateResponse // @Router /users/{login_name}/keys [post] func (s Server) keyCreate(c *gin.Context) error { owner := c.GetString(ContextLoginName)