mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
feat(llm): allow disabling pod/container cgroup CPU and memory limits (#25577)
Inference SKUs default to off; SKU and CLI expose enable flags so hosts can skip CFS quota and memory hard limits when needed.
This commit is contained in:
@@ -84,6 +84,10 @@ type PodCreateInput struct {
|
||||
HostIPC bool `json:"host_ipc"`
|
||||
//PortMappings []*PodPortMapping `json:"port_mappings"`
|
||||
SecurityContext *PodSecurityContext `json:"security_context,omitempty"`
|
||||
// DisableCgroupCpuLimit skips setting CPU CFS quota on the pod sandbox and containers.
|
||||
DisableCgroupCpuLimit bool `json:"disable_cgroup_cpu_limit"`
|
||||
// DisableCgroupMemoryLimit skips setting memory hard limit on the pod sandbox and containers.
|
||||
DisableCgroupMemoryLimit bool `json:"disable_cgroup_memory_limit"`
|
||||
}
|
||||
|
||||
type PodStartResponse struct {
|
||||
|
||||
@@ -136,17 +136,21 @@ type ContainerSpec struct {
|
||||
// List of environment variable to set in the container.
|
||||
Envs []*ContainerKeyValue `json:"envs"`
|
||||
// Enable lxcfs
|
||||
EnableLxcfs bool `json:"enable_lxcfs"`
|
||||
Capabilities *ContainerCapability `json:"capabilities"`
|
||||
Privileged bool `json:"privileged"`
|
||||
DisableNoNewPrivs bool `json:"disable_no_new_privs"`
|
||||
Lifecyle *ContainerLifecyle `json:"lifecyle"`
|
||||
CgroupDevicesAllow []string `json:"cgroup_devices_allow"`
|
||||
CgroupPidsMax int `json:"cgroup_pids_max"`
|
||||
ResourcesLimit *ContainerResources `json:"resources_limit"`
|
||||
SimulateCpu bool `json:"simulate_cpu"`
|
||||
ShmSizeMB int `json:"shm_size_mb"`
|
||||
SecurityContext *ContainerSecurityContext `json:"security_context,omitempty"`
|
||||
EnableLxcfs bool `json:"enable_lxcfs"`
|
||||
Capabilities *ContainerCapability `json:"capabilities"`
|
||||
Privileged bool `json:"privileged"`
|
||||
DisableNoNewPrivs bool `json:"disable_no_new_privs"`
|
||||
Lifecyle *ContainerLifecyle `json:"lifecyle"`
|
||||
CgroupDevicesAllow []string `json:"cgroup_devices_allow"`
|
||||
CgroupPidsMax int `json:"cgroup_pids_max"`
|
||||
ResourcesLimit *ContainerResources `json:"resources_limit"`
|
||||
// DisableCgroupCpuLimit skips setting CPU CFS quota for this container.
|
||||
DisableCgroupCpuLimit bool `json:"disable_cgroup_cpu_limit"`
|
||||
// DisableCgroupMemoryLimit skips setting memory hard limit for this container.
|
||||
DisableCgroupMemoryLimit bool `json:"disable_cgroup_memory_limit"`
|
||||
SimulateCpu bool `json:"simulate_cpu"`
|
||||
ShmSizeMB int `json:"shm_size_mb"`
|
||||
SecurityContext *ContainerSecurityContext `json:"security_context,omitempty"`
|
||||
// Periodic probe of container liveness.
|
||||
// Container will be restarted if the probe fails.
|
||||
// Cannot be updated.
|
||||
|
||||
@@ -37,6 +37,11 @@ var (
|
||||
string(LLM_CONTAINER_COMFYUI),
|
||||
string(LLM_CONTAINER_OPENCLAW),
|
||||
)
|
||||
LLM_INFERENCE_TYPES = sets.NewString(
|
||||
string(LLM_CONTAINER_OLLAMA),
|
||||
string(LLM_CONTAINER_VLLM),
|
||||
string(LLM_CONTAINER_SGLANG),
|
||||
)
|
||||
)
|
||||
|
||||
func IsLLMContainerType(t string) bool {
|
||||
@@ -47,6 +52,10 @@ func IsLLMInstantModelType(t string) bool {
|
||||
return LLM_INSTANT_MODEL_TYPES.Has(t)
|
||||
}
|
||||
|
||||
func IsLLMInferenceType(t string) bool {
|
||||
return LLM_INFERENCE_TYPES.Has(t)
|
||||
}
|
||||
|
||||
func GetLLMInstantModelContainerType(t LLMContainerType) LLMContainerType {
|
||||
return t
|
||||
}
|
||||
|
||||
@@ -162,6 +162,11 @@ type LLMSKuBaseCreateInput struct {
|
||||
Memory int `json:"memory"`
|
||||
Bandwidth int `json:"bandwidth"`
|
||||
|
||||
// EnableCgroupCpu enables CPU CFS quota on the pod/container. Inference SKUs default to false.
|
||||
EnableCgroupCpu *bool `json:"enable_cgroup_cpu"`
|
||||
// EnableCgroupMemory enables memory hard limit on the pod/container. Inference SKUs default to false.
|
||||
EnableCgroupMemory *bool `json:"enable_cgroup_memory"`
|
||||
|
||||
Volumes *Volumes `json:"volumes"`
|
||||
HostPaths *HostPaths `json:"host_paths"`
|
||||
PortMappings *PortMappings `json:"port_mappings"`
|
||||
@@ -176,6 +181,9 @@ type LLMSkuBaseUpdateInput struct {
|
||||
Cpu *int `json:"cpu"`
|
||||
Memory *int `json:"memory"`
|
||||
|
||||
EnableCgroupCpu *bool `json:"enable_cgroup_cpu"`
|
||||
EnableCgroupMemory *bool `json:"enable_cgroup_memory"`
|
||||
|
||||
// RequstSyncImage *bool `json:"request_sync_image"`
|
||||
|
||||
DiskSize *int `json:"disk_size" yunion-deprecated-by:"disk_size_mb"`
|
||||
|
||||
@@ -1170,7 +1170,7 @@ func (s *sPodGuestInstance) _startPod(ctx context.Context, userCred mcclient.Tok
|
||||
return nil, errors.Wrap(err, "setCRIId")
|
||||
}
|
||||
// set pod cgroup resources
|
||||
if err := s.setPodCgroupResources(criId, s.GetDesc().Mem, s.GetDesc().Cpu); err != nil {
|
||||
if err := s.setPodCgroupResources(criId, s.GetDesc().Mem, s.GetDesc().Cpu, podInput); err != nil {
|
||||
return nil, errors.Wrapf(err, "set pod %s cgroup memMB %d, cpu %d", criId, s.GetDesc().Mem, s.GetDesc().Cpu)
|
||||
}
|
||||
|
||||
@@ -1184,12 +1184,16 @@ func (s *sPodGuestInstance) _startPod(ctx context.Context, userCred mcclient.Tok
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *sPodGuestInstance) setPodCgroupResources(criId string, memMB int64, cpuCnt int64) error {
|
||||
if err := s.getCGUtil().SetMemoryLimitBytes(criId, memMB*1024*1024); err != nil {
|
||||
return errors.Wrap(err, "set cgroup memory limit")
|
||||
func (s *sPodGuestInstance) setPodCgroupResources(criId string, memMB int64, cpuCnt int64, podInput *computeapi.PodCreateInput) error {
|
||||
if podInput == nil || !podInput.DisableCgroupMemoryLimit {
|
||||
if err := s.getCGUtil().SetMemoryLimitBytes(criId, memMB*1024*1024); err != nil {
|
||||
return errors.Wrap(err, "set cgroup memory limit")
|
||||
}
|
||||
}
|
||||
if err := s.getCGUtil().SetCPUCfs(criId, cpuCnt*s.getDefaultCPUPeriod(), s.getDefaultCPUPeriod()); err != nil {
|
||||
return errors.Wrap(err, "set cgroup cfs")
|
||||
if podInput == nil || !podInput.DisableCgroupCpuLimit {
|
||||
if err := s.getCGUtil().SetCPUCfs(criId, cpuCnt*s.getDefaultCPUPeriod(), s.getDefaultCPUPeriod()); err != nil {
|
||||
return errors.Wrap(err, "set cgroup cfs")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -2051,6 +2055,21 @@ func (s *sPodGuestInstance) createContainer(ctx context.Context, userCred mcclie
|
||||
procMountType = apis.ContainerUnmaskedProcMount
|
||||
}
|
||||
|
||||
cpuQuota := (s.GetDesc().Cpu + int64(extraCpuCount)) * s.getDefaultCPUPeriod()
|
||||
memoryLimitInBytes := s.GetDesc().Mem * 1024 * 1024
|
||||
disableCgroupCpuLimit := spec.DisableCgroupCpuLimit
|
||||
disableCgroupMemoryLimit := spec.DisableCgroupMemoryLimit
|
||||
if podCreateInput, err := s.getPodCreateParams(); err == nil && podCreateInput != nil {
|
||||
disableCgroupCpuLimit = disableCgroupCpuLimit || podCreateInput.DisableCgroupCpuLimit
|
||||
disableCgroupMemoryLimit = disableCgroupMemoryLimit || podCreateInput.DisableCgroupMemoryLimit
|
||||
}
|
||||
if disableCgroupCpuLimit {
|
||||
cpuQuota = 0
|
||||
}
|
||||
if disableCgroupMemoryLimit {
|
||||
memoryLimitInBytes = 0
|
||||
}
|
||||
|
||||
ctrCfg := &runtimeapi.ContainerConfig{
|
||||
Metadata: &runtimeapi.ContainerMetadata{
|
||||
Name: input.Name,
|
||||
@@ -2072,9 +2091,9 @@ func (s *sPodGuestInstance) createContainer(ctx context.Context, userCred mcclie
|
||||
Resources: &runtimeapi.LinuxContainerResources{
|
||||
// REF: https://docs.docker.com/config/containers/resource_constraints/#configure-the-default-cfs-scheduler
|
||||
CpuPeriod: s.getDefaultCPUPeriod(),
|
||||
CpuQuota: (s.GetDesc().Cpu + int64(extraCpuCount)) * s.getDefaultCPUPeriod(),
|
||||
CpuQuota: cpuQuota,
|
||||
//CpuShares: defaultCPUPeriod,
|
||||
MemoryLimitInBytes: s.GetDesc().Mem * 1024 * 1024,
|
||||
MemoryLimitInBytes: memoryLimitInBytes,
|
||||
OomScoreAdj: 0,
|
||||
CpusetCpus: cpuSetCpus,
|
||||
CpusetMems: cpuSetMems,
|
||||
|
||||
@@ -154,6 +154,20 @@ func runtimeHasExplicitTokenLimit(sku *SLLMSku) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// skuHasExplicitGpuMemoryUtilization reports whether the SKU already sets the
|
||||
// backend GPU memory fraction (vLLM gpu-memory-utilization / SGLang mem-fraction-static)
|
||||
// via backend_parameters or type-specific customized args.
|
||||
func skuHasExplicitGpuMemoryUtilization(sku *SLLMSku) bool {
|
||||
if sku == nil {
|
||||
return false
|
||||
}
|
||||
key, ok := gpuMemoryUtilizationRuntimeArgKey(sku.LLMType)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return runtimeHasExplicitArg(sku, []string{key})
|
||||
}
|
||||
|
||||
func runtimeHasExplicitArg(sku *SLLMSku, keys []string) bool {
|
||||
if sku == nil {
|
||||
return false
|
||||
@@ -563,6 +577,11 @@ func BuildDeploymentResolvedGpuMemoryLLMSpec(ctx context.Context, userCred mccli
|
||||
if deploy.GpuMemoryUtilization != nil {
|
||||
return buildDeploymentGpuMemoryLLMSpec(deploy, sku)
|
||||
}
|
||||
if skuHasExplicitGpuMemoryUtilization(sku) {
|
||||
key, _ := gpuMemoryUtilizationRuntimeArgKey(sku.LLMType)
|
||||
log.Infof("skip auto gpu_memory_utilization: sku=%s already has explicit %s", sku.Id, key)
|
||||
return nil, nil
|
||||
}
|
||||
if !skuCanAutoGpuMemoryUtilization(sku) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
63
pkg/llm/models/llm_deployment_gpu_explicit_util_test.go
Normal file
63
pkg/llm/models/llm_deployment_gpu_explicit_util_test.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/llm"
|
||||
)
|
||||
|
||||
func TestSkuHasExplicitGpuMemoryUtilization(t *testing.T) {
|
||||
if skuHasExplicitGpuMemoryUtilization(nil) {
|
||||
t.Fatal("nil sku should not have explicit GPU util")
|
||||
}
|
||||
|
||||
plain := &SLLMSku{LLMType: string(api.LLM_CONTAINER_VLLM)}
|
||||
if skuHasExplicitGpuMemoryUtilization(plain) {
|
||||
t.Fatal("SKU without backend args should not have explicit GPU util")
|
||||
}
|
||||
|
||||
byBackend := &SLLMSku{
|
||||
LLMType: string(api.LLM_CONTAINER_VLLM),
|
||||
BackendParameters: []string{"--max-model-len=4096", "--gpu-memory-utilization=0.9"},
|
||||
}
|
||||
if !skuHasExplicitGpuMemoryUtilization(byBackend) {
|
||||
t.Fatal("backend_parameters gpu-memory-utilization should count as explicit")
|
||||
}
|
||||
|
||||
bySpec := &SLLMSku{
|
||||
LLMType: string(api.LLM_CONTAINER_VLLM),
|
||||
LLMSpec: &api.LLMSpec{
|
||||
Vllm: &api.LLMSpecVllm{
|
||||
CustomizedArgs: []*api.VllmCustomizedArg{{Key: "gpu-memory-utilization", Value: "0.85"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
if !skuHasExplicitGpuMemoryUtilization(bySpec) {
|
||||
t.Fatal("vllm customized_args gpu-memory-utilization should count as explicit")
|
||||
}
|
||||
|
||||
sglang := &SLLMSku{
|
||||
LLMType: string(api.LLM_CONTAINER_SGLANG),
|
||||
BackendParameters: []string{"--mem-fraction-static=0.8"},
|
||||
}
|
||||
if !skuHasExplicitGpuMemoryUtilization(sglang) {
|
||||
t.Fatal("sglang mem-fraction-static should count as explicit")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDeploymentResolvedGpuMemoryLLMSpecSkipsExplicitSkuArg(t *testing.T) {
|
||||
auto := true
|
||||
deploy := &SLLMDeployment{AutoGpuMemoryUtilization: &auto}
|
||||
sku := &SLLMSku{
|
||||
LLMType: string(api.LLM_CONTAINER_VLLM),
|
||||
BackendParameters: []string{"--gpu-memory-utilization=0.9"},
|
||||
}
|
||||
spec, err := BuildDeploymentResolvedGpuMemoryLLMSpec(context.Background(), nil, deploy, sku)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if spec != nil {
|
||||
t.Fatalf("expected nil spec when SKU already sets gpu-memory-utilization, got %#v", spec)
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,10 @@ func GetLLMPodCreateInput(
|
||||
containers := GetDriverPodContainers(ctx, lcd, llm, llmImage, sku, nil, nil, "")
|
||||
|
||||
data.Pod = &computeapi.PodCreateInput{
|
||||
HostIPC: true,
|
||||
Containers: containers,
|
||||
HostIPC: true,
|
||||
Containers: containers,
|
||||
DisableCgroupCpuLimit: sku == nil || !skuCgroupLimitEnabled(sku.EnableCgroupCpu),
|
||||
DisableCgroupMemoryLimit: sku == nil || !skuCgroupLimitEnabled(sku.EnableCgroupMemory),
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
||||
@@ -230,6 +230,30 @@ func (manager *SLLMSkuManager) FetchCustomizeColumns(
|
||||
return res
|
||||
}
|
||||
|
||||
func boolPtr(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
func skuCgroupLimitEnabled(enabled *bool) bool {
|
||||
if enabled == nil {
|
||||
return true
|
||||
}
|
||||
return *enabled
|
||||
}
|
||||
|
||||
func applySkuCgroupLimitDefaults(input *api.LLMSkuCreateInput) {
|
||||
if input == nil {
|
||||
return
|
||||
}
|
||||
def := !api.IsLLMInferenceType(input.LLMType)
|
||||
if input.EnableCgroupCpu == nil {
|
||||
input.EnableCgroupCpu = boolPtr(def)
|
||||
}
|
||||
if input.EnableCgroupMemory == nil {
|
||||
input.EnableCgroupMemory = boolPtr(def)
|
||||
}
|
||||
}
|
||||
|
||||
func (man *SLLMSkuManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input *api.LLMSkuCreateInput) (*api.LLMSkuCreateInput, error) {
|
||||
var err error
|
||||
input.LLMSKuBaseCreateInput, err = man.SLLMSkuBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.LLMSKuBaseCreateInput)
|
||||
@@ -239,6 +263,7 @@ func (man *SLLMSkuManager) ValidateCreateData(ctx context.Context, userCred mccl
|
||||
if !api.IsLLMContainerType(input.LLMType) && input.LLMType != string(api.LLM_CONTAINER_DIFY) {
|
||||
return input, errors.Wrap(httperrors.ErrInputParameter, "llm_type must be one of "+strings.Join(api.LLM_CONTAINER_TYPES.List(), ","))
|
||||
}
|
||||
applySkuCgroupLimitDefaults(input)
|
||||
|
||||
drv, err := GetLLMContainerDriverWithError(api.LLMContainerType(input.LLMType))
|
||||
if err != nil {
|
||||
|
||||
71
pkg/llm/models/llm_sku_cgroup_test.go
Normal file
71
pkg/llm/models/llm_sku_cgroup_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/llm"
|
||||
)
|
||||
|
||||
func TestApplySkuCgroupLimitDefaultsInference(t *testing.T) {
|
||||
for _, llmType := range []string{
|
||||
string(api.LLM_CONTAINER_VLLM),
|
||||
string(api.LLM_CONTAINER_SGLANG),
|
||||
string(api.LLM_CONTAINER_OLLAMA),
|
||||
} {
|
||||
input := &api.LLMSkuCreateInput{LLMType: llmType}
|
||||
applySkuCgroupLimitDefaults(input)
|
||||
if input.EnableCgroupCpu == nil || *input.EnableCgroupCpu {
|
||||
t.Fatalf("%s: expected enable_cgroup_cpu=false, got %v", llmType, input.EnableCgroupCpu)
|
||||
}
|
||||
if input.EnableCgroupMemory == nil || *input.EnableCgroupMemory {
|
||||
t.Fatalf("%s: expected enable_cgroup_memory=false, got %v", llmType, input.EnableCgroupMemory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplySkuCgroupLimitDefaultsInferenceExplicitTrue(t *testing.T) {
|
||||
enabled := true
|
||||
input := &api.LLMSkuCreateInput{
|
||||
LLMType: string(api.LLM_CONTAINER_VLLM),
|
||||
LLMSKuBaseCreateInput: api.LLMSKuBaseCreateInput{
|
||||
EnableCgroupCpu: &enabled,
|
||||
EnableCgroupMemory: &enabled,
|
||||
},
|
||||
}
|
||||
applySkuCgroupLimitDefaults(input)
|
||||
if input.EnableCgroupCpu == nil || !*input.EnableCgroupCpu {
|
||||
t.Fatalf("expected explicit enable_cgroup_cpu=true, got %v", input.EnableCgroupCpu)
|
||||
}
|
||||
if input.EnableCgroupMemory == nil || !*input.EnableCgroupMemory {
|
||||
t.Fatalf("expected explicit enable_cgroup_memory=true, got %v", input.EnableCgroupMemory)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplySkuCgroupLimitDefaultsNonInference(t *testing.T) {
|
||||
for _, llmType := range []string{
|
||||
string(api.LLM_CONTAINER_DIFY),
|
||||
string(api.LLM_CONTAINER_DESKTOP),
|
||||
string(api.LLM_CONTAINER_COMFYUI),
|
||||
} {
|
||||
input := &api.LLMSkuCreateInput{LLMType: llmType}
|
||||
applySkuCgroupLimitDefaults(input)
|
||||
if input.EnableCgroupCpu == nil || !*input.EnableCgroupCpu {
|
||||
t.Fatalf("%s: expected enable_cgroup_cpu=true, got %v", llmType, input.EnableCgroupCpu)
|
||||
}
|
||||
if input.EnableCgroupMemory == nil || !*input.EnableCgroupMemory {
|
||||
t.Fatalf("%s: expected enable_cgroup_memory=true, got %v", llmType, input.EnableCgroupMemory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSkuCgroupLimitEnabled(t *testing.T) {
|
||||
if !skuCgroupLimitEnabled(nil) {
|
||||
t.Fatal("nil should default to enabled (legacy SKU behavior)")
|
||||
}
|
||||
if !skuCgroupLimitEnabled(boolPtr(true)) {
|
||||
t.Fatal("true should be enabled")
|
||||
}
|
||||
if skuCgroupLimitEnabled(boolPtr(false)) {
|
||||
t.Fatal("false should be disabled")
|
||||
}
|
||||
}
|
||||
@@ -34,14 +34,16 @@ type SLLMSkuBaseManager struct {
|
||||
type SLLMSkuBase struct {
|
||||
db.SSharableVirtualResourceBase
|
||||
|
||||
Bandwidth int `nullable:"false" default:"0" create:"optional" list:"user" update:"user"`
|
||||
Cpu int `nullable:"false" default:"1" create:"optional" list:"user" update:"user"`
|
||||
Memory int `nullable:"false" default:"512" create:"optional" list:"user" update:"user"`
|
||||
Volumes *api.Volumes `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
HostPaths *api.HostPaths `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
PortMappings *api.PortMappings `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
Devices *api.Devices `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
Envs *api.Envs `charset:"utf8" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
Bandwidth int `nullable:"false" default:"0" create:"optional" list:"user" update:"user"`
|
||||
Cpu int `nullable:"false" default:"1" create:"optional" list:"user" update:"user"`
|
||||
Memory int `nullable:"false" default:"512" create:"optional" list:"user" update:"user"`
|
||||
EnableCgroupCpu *bool `default:"true" create:"optional" list:"user" update:"user"`
|
||||
EnableCgroupMemory *bool `default:"true" create:"optional" list:"user" update:"user"`
|
||||
Volumes *api.Volumes `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
HostPaths *api.HostPaths `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
PortMappings *api.PortMappings `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
Devices *api.Devices `charset:"utf8" length:"medium" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
Envs *api.Envs `charset:"utf8" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
// Properties
|
||||
Properties map[string]string `charset:"utf8" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
}
|
||||
|
||||
@@ -48,43 +48,47 @@ type ContainerDeleteOptions struct {
|
||||
}
|
||||
|
||||
type ContainerCreateCommonOptions struct {
|
||||
IMAGE string `help:"Image of container" json:"image"`
|
||||
ImageCredentialId string `help:"Image credential id" json:"image_credential_id"`
|
||||
Command []string `help:"Command to execute (i.e., entrypoint for docker)" json:"command"`
|
||||
Args []string `help:"Args for the Command (i.e. command for docker)" json:"args"`
|
||||
WorkingDir string `help:"Current working directory of the command" json:"working_dir"`
|
||||
Env []string `help:"List of environment variable to set in the container and the format is: <key>=<value>"`
|
||||
RootFs string `help:"Root filesystem of the container, e.g.: disk_index=<disk_number>,disk_id=<disk_id>"`
|
||||
VolumeMount []string `help:"Volume mount of the container and the format is: name=<val>,mount_path=<container_path>,readonly=<true_or_false>,case_insensitive_paths=p1,p2,disk_index=<disk_number>,disk_id=<disk_id>"`
|
||||
Device []string `help:"Host device: <host_path>:<container_path>:<permissions>, e.g.: /dev/snd:/dev/snd:rwm"`
|
||||
Privileged bool `help:"Privileged mode"`
|
||||
Caps string `help:"Container capabilities, e.g.: SETPCAP,AUDIT_WRITE,SYS_CHROOT,CHOWN,DAC_OVERRIDE,FOWNER,SETGID,SETUID,SYSLOG,SYS_ADMIN,WAKE_ALARM,SYS_PTRACE,BLOCK_SUSPEND,MKNOD,KILL,SYS_RESOURCE,NET_RAW,NET_ADMIN,NET_BIND_SERVICE,SYS_NICE"`
|
||||
DropCaps string `help:"Container dropped capabilities, split by ','"`
|
||||
EnableLxcfs bool `help:"Enable lxcfs"`
|
||||
PostStartExec string `help:"Post started execution command"`
|
||||
CgroupDeviceAllow []string `help:"Cgroup devices.allow, e.g.: 'c 13:* rwm'"`
|
||||
SimulateCpu bool `help:"Simulating /sys/devices/system/cpu files"`
|
||||
ShmSizeMb int `help:"Shm size MB"`
|
||||
Uid int64 `help:"UID of container" default:"0"`
|
||||
Gid int64 `help:"GID of container" default:"0"`
|
||||
DisableNoNewPrivs bool `help:"Disable no_new_privs flag of the container"`
|
||||
Apparmor string `help:"Apparmor profile for container"`
|
||||
IMAGE string `help:"Image of container" json:"image"`
|
||||
ImageCredentialId string `help:"Image credential id" json:"image_credential_id"`
|
||||
Command []string `help:"Command to execute (i.e., entrypoint for docker)" json:"command"`
|
||||
Args []string `help:"Args for the Command (i.e. command for docker)" json:"args"`
|
||||
WorkingDir string `help:"Current working directory of the command" json:"working_dir"`
|
||||
Env []string `help:"List of environment variable to set in the container and the format is: <key>=<value>"`
|
||||
RootFs string `help:"Root filesystem of the container, e.g.: disk_index=<disk_number>,disk_id=<disk_id>"`
|
||||
VolumeMount []string `help:"Volume mount of the container and the format is: name=<val>,mount_path=<container_path>,readonly=<true_or_false>,case_insensitive_paths=p1,p2,disk_index=<disk_number>,disk_id=<disk_id>"`
|
||||
Device []string `help:"Host device: <host_path>:<container_path>:<permissions>, e.g.: /dev/snd:/dev/snd:rwm"`
|
||||
Privileged bool `help:"Privileged mode"`
|
||||
Caps string `help:"Container capabilities, e.g.: SETPCAP,AUDIT_WRITE,SYS_CHROOT,CHOWN,DAC_OVERRIDE,FOWNER,SETGID,SETUID,SYSLOG,SYS_ADMIN,WAKE_ALARM,SYS_PTRACE,BLOCK_SUSPEND,MKNOD,KILL,SYS_RESOURCE,NET_RAW,NET_ADMIN,NET_BIND_SERVICE,SYS_NICE"`
|
||||
DropCaps string `help:"Container dropped capabilities, split by ','"`
|
||||
EnableLxcfs bool `help:"Enable lxcfs"`
|
||||
PostStartExec string `help:"Post started execution command"`
|
||||
CgroupDeviceAllow []string `help:"Cgroup devices.allow, e.g.: 'c 13:* rwm'"`
|
||||
DisableCgroupCpuLimit bool `help:"Do not set CPU cgroup CFS quota"`
|
||||
DisableCgroupMemoryLimit bool `help:"Do not set memory cgroup hard limit"`
|
||||
SimulateCpu bool `help:"Simulating /sys/devices/system/cpu files"`
|
||||
ShmSizeMb int `help:"Shm size MB"`
|
||||
Uid int64 `help:"UID of container" default:"0"`
|
||||
Gid int64 `help:"GID of container" default:"0"`
|
||||
DisableNoNewPrivs bool `help:"Disable no_new_privs flag of the container"`
|
||||
Apparmor string `help:"Apparmor profile for container"`
|
||||
}
|
||||
|
||||
func (o ContainerCreateCommonOptions) getCreateSpec() (*computeapi.ContainerSpec, error) {
|
||||
req := &computeapi.ContainerSpec{
|
||||
ContainerSpec: apis.ContainerSpec{
|
||||
Image: o.IMAGE,
|
||||
ImageCredentialId: o.ImageCredentialId,
|
||||
Command: o.Command,
|
||||
Args: o.Args,
|
||||
WorkingDir: o.WorkingDir,
|
||||
EnableLxcfs: o.EnableLxcfs,
|
||||
Privileged: o.Privileged,
|
||||
Capabilities: &apis.ContainerCapability{},
|
||||
CgroupDevicesAllow: o.CgroupDeviceAllow,
|
||||
SimulateCpu: o.SimulateCpu,
|
||||
DisableNoNewPrivs: o.DisableNoNewPrivs,
|
||||
Image: o.IMAGE,
|
||||
ImageCredentialId: o.ImageCredentialId,
|
||||
Command: o.Command,
|
||||
Args: o.Args,
|
||||
WorkingDir: o.WorkingDir,
|
||||
EnableLxcfs: o.EnableLxcfs,
|
||||
Privileged: o.Privileged,
|
||||
Capabilities: &apis.ContainerCapability{},
|
||||
CgroupDevicesAllow: o.CgroupDeviceAllow,
|
||||
DisableCgroupCpuLimit: o.DisableCgroupCpuLimit,
|
||||
DisableCgroupMemoryLimit: o.DisableCgroupMemoryLimit,
|
||||
SimulateCpu: o.SimulateCpu,
|
||||
DisableNoNewPrivs: o.DisableNoNewPrivs,
|
||||
SecurityContext: &apis.ContainerSecurityContext{
|
||||
RunAsUser: nil,
|
||||
RunAsGroup: nil,
|
||||
|
||||
@@ -19,6 +19,9 @@ type LLMSkuBaseCreateOptions struct {
|
||||
MEMORY int `help:"memory size MB"`
|
||||
DISK_SIZE int `help:"disk size MB"`
|
||||
|
||||
EnableCgroupCpu *bool `help:"enable CPU cgroup CFS quota; inference SKUs default false" json:"enable_cgroup_cpu" token:"enable-cgroup-cpu"`
|
||||
EnableCgroupMemory *bool `help:"enable memory cgroup hard limit; inference SKUs default false" json:"enable_cgroup_memory" token:"enable-cgroup-memory"`
|
||||
|
||||
Bandwidth int
|
||||
StorageType string
|
||||
// DiskOverlay string `help:"disk overlay, e.g. /opt/steam-data/base:/opt/steam-data/games"`
|
||||
@@ -59,13 +62,15 @@ type LLMSkuBaseUpdateOptions struct {
|
||||
|
||||
ID string
|
||||
|
||||
Cpu *int
|
||||
Memory *int `help:"memory size MB"`
|
||||
DiskSize *int `help:"disk size MB"`
|
||||
StorageType string
|
||||
TemplateId string
|
||||
NoTemplate bool `json:"-" help:"remove template"`
|
||||
Bandwidth *int
|
||||
Cpu *int
|
||||
Memory *int `help:"memory size MB"`
|
||||
EnableCgroupCpu *bool `help:"enable CPU cgroup CFS quota" json:"enable_cgroup_cpu" token:"enable-cgroup-cpu"`
|
||||
EnableCgroupMemory *bool `help:"enable memory cgroup hard limit" json:"enable_cgroup_memory" token:"enable-cgroup-memory"`
|
||||
DiskSize *int `help:"disk size MB"`
|
||||
StorageType string
|
||||
TemplateId string
|
||||
NoTemplate bool `json:"-" help:"remove template"`
|
||||
Bandwidth *int
|
||||
// Dpi *int
|
||||
// Fps *int
|
||||
PortMappings []string `help:"port mapping in the format of protocol:port[:prefix][:first_port_offset], e.g. tcp:5555:192.168.0.0/16,10.10.0.0/16:1000"`
|
||||
|
||||
Reference in New Issue
Block a user