little improve

This commit is contained in:
starryskymeow
2025-07-05 06:04:40 +08:00
parent fa18edc20f
commit 49d90848d8
5 changed files with 74 additions and 67 deletions

View File

@@ -14,12 +14,15 @@ import (
)
const (
DefaultImage = "ghcr.io/dreamstarsky/educode:cpu-latest"
DefaultCPU = "500m"
DefaultMemory = "512Mi"
DefaultStorage = "5Gi"
DefaultImage = "ghcr.io/dreamstarsky/educode:cpu-latest"
)
var DefaultResourceLimits = ResourceLimits{
CPU: "500m",
Memory: "1Gi",
Storage: "5Gi",
}
type WorkspaceRequest struct {
Image string
Env map[string]string
@@ -30,8 +33,9 @@ type WorkspaceRequest struct {
}
type ResourceLimits struct {
CPU string
Memory string
CPU string `json:"cpu"`
Memory string `json:"memory"`
Storage string `json:"storage"`
}
func CreateWorkspace(req *WorkspaceRequest) error {
@@ -60,13 +64,13 @@ func CreateWorkspace(req *WorkspaceRequest) error {
Name: "code-server",
Image: req.Image,
Ports: []corev1.ContainerPort{
{ContainerPort: 8080}, // Default code-server port
{ContainerPort: 8080}, // code-server port
{ContainerPort: 22}, // SSH port
},
Env: getEnvVars(req.Env),
Resources: getResourceRequirements(req.ResourceLimits),
Env: getEnvVars(req.Env),
Resources: getResourceRequirements(req.ResourceLimits),
VolumeMounts: []corev1.VolumeMount{
{Name: "workspace-storage", MountPath: "/home/coder"},
{Name: "workspace-storage", MountPath: "/home/ubuntu/workspace"},
},
},
},
@@ -76,10 +80,10 @@ func CreateWorkspace(req *WorkspaceRequest) error {
{
ObjectMeta: metav1.ObjectMeta{Name: "workspace-storage"},
Spec: corev1.PersistentVolumeClaimSpec{
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce},
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteMany},
Resources: corev1.VolumeResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceStorage: resource.MustParse(DefaultStorage),
corev1.ResourceStorage: resource.MustParse(req.ResourceLimits.Storage),
},
},
},
@@ -88,32 +92,44 @@ func CreateWorkspace(req *WorkspaceRequest) error {
},
}
// Create resources
sts, err := req.Clientset.AppsV1().StatefulSets(req.Namespace).Create(context.TODO(), sts, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("failed to create statefulset: %w", err)
}
// Define Service
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: req.WorkspaceID,
Namespace: req.Namespace,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: "apps/v1",
Kind: "StatefulSet",
Name: req.WorkspaceID,
UID: sts.UID,
Controller: boolPrt(true),
},
},
},
Spec: corev1.ServiceSpec{
Selector: map[string]string{"app": req.WorkspaceID},
Ports: []corev1.ServicePort{
{Name: "http", Port: 8080, TargetPort: intstr.FromInt(8080)},
{Name: "code-server", Port: 8080, TargetPort: intstr.FromInt(8080)},
{Name: "ssh", Port: 22, TargetPort: intstr.FromInt(22)},
},
Type: corev1.ServiceTypeClusterIP,
},
}
// Create resources
_, err := req.Clientset.AppsV1().StatefulSets(req.Namespace).Create(context.TODO(), sts, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("failed to create statefulset: %w", err)
}
_, err = req.Clientset.CoreV1().Services(req.Namespace).Create(context.TODO(), svc, metav1.CreateOptions{})
if err != nil {
// Cleanup StatefulSet if Service creation fails
req.Clientset.AppsV1().StatefulSets(req.Namespace).Delete(context.TODO(), req.WorkspaceID, metav1.DeleteOptions{})
deletePolicy := metav1.DeletePropagationBackground
req.Clientset.AppsV1().StatefulSets(req.Namespace).Delete(context.TODO(), req.WorkspaceID, metav1.DeleteOptions{
PropagationPolicy: &deletePolicy,
})
return fmt.Errorf("failed to create service: %w", err)
}
@@ -122,20 +138,16 @@ func CreateWorkspace(req *WorkspaceRequest) error {
func DeleteWorkspace(clientset *kubernetes.Clientset, namespace, workspaceID string) error {
// Delete StatefulSet
err := clientset.AppsV1().StatefulSets(namespace).Delete(context.TODO(), workspaceID, metav1.DeleteOptions{})
deletePolicy := metav1.DeletePropagationBackground
// TODO
// Maybe not delete pvc?
err := clientset.AppsV1().StatefulSets(namespace).Delete(context.TODO(), workspaceID, metav1.DeleteOptions{
PropagationPolicy: &deletePolicy,
})
if err != nil {
return fmt.Errorf("failed to delete statefulset: %w", err)
}
// Delete Service
err = clientset.CoreV1().Services(namespace).Delete(context.TODO(), workspaceID, metav1.DeleteOptions{})
if err != nil {
return fmt.Errorf("failed to delete service: %w", err)
}
// PVC will be deleted automatically when the StatefulSet is deleted, if the reclaim policy is set to Delete.
// If not, it might need manual cleanup. For now, we assume it's handled.
return nil
}
@@ -150,22 +162,13 @@ func getEnvVars(env map[string]string) []corev1.EnvVar {
func getResourceRequirements(limits *ResourceLimits) corev1.ResourceRequirements {
req := corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse(DefaultCPU),
corev1.ResourceMemory: resource.MustParse(DefaultMemory),
corev1.ResourceCPU: resource.MustParse(limits.CPU),
corev1.ResourceMemory: resource.MustParse(limits.Memory),
},
}
if limits != nil {
req.Limits = corev1.ResourceList{}
if limits.CPU != "" {
req.Limits[corev1.ResourceCPU] = resource.MustParse(limits.CPU)
}
if limits.Memory != "" {
req.Limits[corev1.ResourceMemory] = resource.MustParse(limits.Memory)
}
}
return req
}
func int32Ptr(i int32) *int32 { return &i }
func boolPrt(b bool) *bool { return &b }