From d58375ebd643599dbee95cd3669dbb3260244b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Fri, 30 Aug 2024 11:39:54 +0800 Subject: [PATCH] add devbox restart pod (#5010) * add devbox restart pod --- .../internal/controller/devbox_controller.go | 13 +++- .../internal/controller/helper/devbox.go | 60 ++++++++++++++----- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/controllers/devbox/internal/controller/devbox_controller.go b/controllers/devbox/internal/controller/devbox_controller.go index 5c1ea31d6a6..7e6af0821a9 100644 --- a/controllers/devbox/internal/controller/devbox_controller.go +++ b/controllers/devbox/internal/controller/devbox_controller.go @@ -222,9 +222,14 @@ func (r *DevboxReconciler) syncPod(ctx context.Context, devbox *devboxv1alpha1.D if removeFlag { return r.updateDevboxCommitHistory(ctx, devbox, &podList.Items[0]) } + if !helper.CheckPodConsistency(devbox, &podList.Items[0]) { + _ = r.Delete(ctx, &podList.Items[0]) + } case corev1.PodRunning: - // we do not recreate pod if it is running, even if pod does not have expected values - // update commit history status to success by pod name + //if pod is running,check pod need restart + if !helper.CheckPodConsistency(devbox, &podList.Items[0]) { + _ = r.Delete(ctx, &podList.Items[0]) + } return r.updateDevboxCommitHistory(ctx, devbox, &podList.Items[0]) case corev1.PodSucceeded: if controllerutil.RemoveFinalizer(&podList.Items[0], FinalizerName) { @@ -317,6 +322,10 @@ func (r *DevboxReconciler) generateDevboxPod(ctx context.Context, devbox *devbox Name: "SEALOS_COMMIT_IMAGE_SQUASH", Value: fmt.Sprintf("%v", devbox.Spec.Squash), }, + { + Name: "SEALOS_DEVBOX_NAME", + Value: devbox.ObjectMeta.Namespace + devbox.ObjectMeta.Name, + }, { Name: "SEALOS_DEVBOX_PASSWORD", ValueFrom: &corev1.EnvVarSource{ diff --git a/controllers/devbox/internal/controller/helper/devbox.go b/controllers/devbox/internal/controller/helper/devbox.go index 6c00cf2da36..9ea0c379f6e 100644 --- a/controllers/devbox/internal/controller/helper/devbox.go +++ b/controllers/devbox/internal/controller/helper/devbox.go @@ -15,14 +15,15 @@ package helper import ( - "crypto/ecdsa" - "crypto/elliptic" + "crypto/ed25519" cryptorand "crypto/rand" - "crypto/x509" + + "golang.org/x/crypto/ssh" "encoding/pem" + "fmt" - "golang.org/x/crypto/ssh" + corev1 "k8s.io/api/core/v1" devboxv1alpha1 "github.com/labring/sealos/controllers/devbox/api/v1alpha1" ) @@ -40,23 +41,50 @@ func GetLastSuccessCommitHistory(devbox *devboxv1alpha1.Devbox) *devboxv1alpha1. } func GenerateSSHKeyPair() ([]byte, []byte, error) { - privateKey, err := ecdsa.GenerateKey(elliptic.P256(), cryptorand.Reader) + pubKey, privKey, err := ed25519.GenerateKey(cryptorand.Reader) if err != nil { - return []byte(""), []byte(""), err + return nil, nil, err } - public := &privateKey.PublicKey - derPrivateKey, err := x509.MarshalECPrivateKey(privateKey) + pemKey, err := ssh.MarshalPrivateKey(privKey, "") if err != nil { - return []byte(""), []byte(""), err + return nil, nil, err } - privateKeyPem := pem.EncodeToMemory(&pem.Block{ - Type: "PRIVATE KEY", - Bytes: derPrivateKey, - }) - publicKey, err := ssh.NewPublicKey(public) + privateKey := pem.EncodeToMemory(pemKey) + publicKey, err := ssh.NewPublicKey(pubKey) if err != nil { - return []byte(""), []byte(""), err + return nil, nil, err } sshPublicKey := ssh.MarshalAuthorizedKey(publicKey) - return sshPublicKey, privateKeyPem, nil + return sshPublicKey, privateKey, nil +} + +func CheckPodConsistency(devbox *devboxv1alpha1.Devbox, pod *corev1.Pod) bool { + container := pod.Spec.Containers[0] + //check cpu and memory + if !container.Resources.Limits.Cpu().Equal(devbox.Spec.Resource["cpu"]) { + return false + } + if !container.Resources.Limits.Memory().Equal(devbox.Spec.Resource["memory"]) { + return false + } + //check ports + if len(container.Ports) != len(devbox.Spec.NetworkSpec.ExtraPorts)+1 { + return false + } + portMap := make(map[string]int) + for _, podPort := range container.Ports { + key := fmt.Sprintf("%d-%s", podPort.ContainerPort, podPort.Protocol) + portMap[key]++ + } + for _, devboxPort := range devbox.Spec.NetworkSpec.ExtraPorts { + key := fmt.Sprintf("%d-%s", devboxPort.ContainerPort, devboxPort.Protocol) + if _, found := portMap[key]; !found { + return false + } + portMap[key]-- + if portMap[key] == 0 { + delete(portMap, key) + } + } + return len(portMap) == 1 }