From aef63e920d29a91e2b788c29276b162456f38476 Mon Sep 17 00:00:00 2001 From: catttam Date: Fri, 26 May 2023 12:35:55 +0200 Subject: [PATCH 01/25] Image puller daemonset to cache images on working nodes --- pkg/backends/k8s.go | 7 ++ pkg/imagepuller/daemonset.go | 186 +++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 pkg/imagepuller/daemonset.go diff --git a/pkg/backends/k8s.go b/pkg/backends/k8s.go index ebbfb2bf..3cc7fcb6 100644 --- a/pkg/backends/k8s.go +++ b/pkg/backends/k8s.go @@ -22,6 +22,7 @@ import ( "log" "github.com/goccy/go-yaml" + "github.com/grycap/oscar/v2/pkg/imagepuller" "github.com/grycap/oscar/v2/pkg/types" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -112,6 +113,12 @@ func (k *KubeBackend) CreateService(service types.Service) error { return err } + //Create deaemonset to cache the service image on all the nodes + err = imagepuller.CreateDaemonset(k.config, service, k.kubeClientset) + if err != nil { + return err + } + return nil } diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go new file mode 100644 index 00000000..bbfeb361 --- /dev/null +++ b/pkg/imagepuller/daemonset.go @@ -0,0 +1,186 @@ +/* +Copyright (C) GRyCAP - I3M - UPV + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package imagepuller + +//TODO check error control + +import ( + //"k8s.io/apimachinery/pkg/watch" + "context" + "fmt" + "log" + "math/rand" + "sync" + "time" + + "github.com/grycap/oscar/v2/pkg/types" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/informers" + "k8s.io/client-go/informers/internalinterfaces" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" +) + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +const lengthStr = 5 + +var podGroup string +var daemonsetName string + +var workingNodes int + +type PodCounter struct { + wnCount int + mutex sync.Mutex +} + +var pc PodCounter +var stopper = make(chan struct{}) + +//Create daemonset +func CreateDaemonset(cfg *types.Config, service types.Service, kubeClientset kubernetes.Interface) error { + + //Set needed variables + setWorkingNodes(kubeClientset) + podGroup = generatePodGroupName() + daemonsetName = "image-puller-" + service.Image + + //Get daemonset definition + daemon := getDaemonset(cfg, service) + + //Create daemonset + _, err := kubeClientset.AppsV1().DaemonSets(cfg.Namespace).Create(context.TODO(), daemon, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("failed to create daemonset: %s", err.Error()) + } else { + log.Printf("Created daemonset") + } + + //Set watcher informer + watchPods(kubeClientset, cfg) + + return nil +} + +//Get daemonset definition +func getDaemonset(cfg *types.Config, service types.Service) *appsv1.DaemonSet { + return &appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: daemonsetName, + Namespace: cfg.Namespace, + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "oscar-resource": "daemonset", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "oscar-resource": "daemonset", + "pod-group": podGroup, + }, + Name: "podpuller", + }, + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{}, + ImagePullSecrets: types.SetImagePullSecrets(service.ImagePullSecrets), + Containers: []corev1.Container{ + { + Name: "imagePuller", + Image: service.Image, + Command: []string{"/bin/sh", "-c", "echo 'Image puller succeed'"}, + }, + }, + }, + }, + }, + } +} + +//Watch pods with a Kubernetes Informer +func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { + + defer close(stopper) + + pc = PodCounter{wnCount: 0} + + var optionsFunc internalinterfaces.TweakListOptionsFunc = func(options *metav1.ListOptions) { + labelSelector := labels.Set{ + "oscar-resoure": "daemonset", + "podGroup": podGroup, + }.AsSelector() + options.LabelSelector = labelSelector.String() + } + + sharedInformerOp := informers.WithTweakListOptions(optionsFunc) + + factory := informers.NewSharedInformerFactoryWithOptions(kubeClientset, 10*time.Second, informers.WithNamespace(cfg.Namespace), sharedInformerOp) + podInformer := factory.Core().V1().Pods().Informer() + factory.Start(stopper) + + cache.WaitForCacheSync(stopper, podInformer.HasSynced) + //Add event handler that gets all the pods status + podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + UpdateFunc: handlePodEvent, + }) + + //Delete daemonset when all pods are in state "Running" + err := kubeClientset.AppsV1().DaemonSets(cfg.Namespace).Delete(context.TODO(), daemonsetName, metav1.DeleteOptions{}) + if err != nil { + log.Fatalf("Failed to delete daemonset: %s", err.Error()) + } else { + log.Printf("Daemonset deleted") + } +} + +func handlePodEvent(oldObj interface{}, newObj interface{}) { + newPod := newObj.(*corev1.Pod) + if newPod.Status.Phase == corev1.PodRunning { + pc.mutex.Lock() + defer pc.mutex.Unlock() + pc.wnCount++ + //Check the running pods count and stop the informer + if pc.wnCount >= workingNodes { + <-stopper + } + } +} + +func setWorkingNodes(kubeClientset kubernetes.Interface) error { + nodes, err := kubeClientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{LabelSelector: "!node-role.kubernetes.io/control-plane,!node-role.kubernetes.io/master"}) + if err != nil { + return fmt.Errorf("error getting node list: %v", err) + } + + for range nodes.Items { + workingNodes++ + } + return nil +} + +func generatePodGroupName() string { + b := make([]byte, lengthStr) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return "pod-group-" + string(b) +} From fe8f94fd1dc180c75349cb1a30cc691bdb624402 Mon Sep 17 00:00:00 2001 From: SergioLangaritaBenitez Date: Mon, 29 May 2023 11:59:01 +0200 Subject: [PATCH 02/25] update oscar-ui reference --- ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui b/ui index 93bfee4e..29adf303 160000 --- a/ui +++ b/ui @@ -1 +1 @@ -Subproject commit 93bfee4ee6581bc6f863d853b98a43f5a6cce883 +Subproject commit 29adf3032660234f2985f9a90152d5f70a17582d From 4496d0dd353d76c348159648f3d07bc939de8a54 Mon Sep 17 00:00:00 2001 From: catttam Date: Mon, 29 May 2023 12:30:47 +0200 Subject: [PATCH 03/25] Minor fix --- pkg/types/service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/types/service.go b/pkg/types/service.go index a17494d6..219e4f29 100644 --- a/pkg/types/service.go +++ b/pkg/types/service.go @@ -231,7 +231,7 @@ func (service *Service) ToPodSpec(cfg *Config) (*v1.PodSpec, error) { } podSpec := &v1.PodSpec{ - ImagePullSecrets: setImagePullSecrets(service.ImagePullSecrets), + ImagePullSecrets: SetImagePullSecrets(service.ImagePullSecrets), Containers: []v1.Container{ { Name: ContainerName, @@ -306,7 +306,7 @@ func convertEnvVars(vars map[string]string) []v1.EnvVar { return envVars } -func setImagePullSecrets(secrets []string) []v1.LocalObjectReference { +func SetImagePullSecrets(secrets []string) []v1.LocalObjectReference { objects := []v1.LocalObjectReference{} for _, s := range secrets { objects = append(objects, v1.LocalObjectReference{ From 5c67d202ee8bc7a7a6f57356cd120f3ced6cc5c7 Mon Sep 17 00:00:00 2001 From: catttam Date: Mon, 29 May 2023 12:35:45 +0200 Subject: [PATCH 04/25] Minor fix on service test --- pkg/types/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/types/service_test.go b/pkg/types/service_test.go index 2c419a0c..4f380660 100644 --- a/pkg/types/service_test.go +++ b/pkg/types/service_test.go @@ -201,7 +201,7 @@ func TestSetImagePullSecrets(t *testing.T) { {Name: "testcred1"}, } - result := setImagePullSecrets(secrets) + result := SetImagePullSecrets(secrets) if result[0].Name != expected[0].Name { t.Errorf("invalid conversion of local object. Expected: %v, got %v", expected, result) } From 7df78c4c15795e71a813d14b87e1b9dfae7edce3 Mon Sep 17 00:00:00 2001 From: catttam Date: Mon, 29 May 2023 13:28:07 +0200 Subject: [PATCH 05/25] Added DaemonSet logs to debug --- pkg/backends/knative.go | 7 +++++++ pkg/imagepuller/daemonset.go | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pkg/backends/knative.go b/pkg/backends/knative.go index 25f7911f..a2d17ac6 100644 --- a/pkg/backends/knative.go +++ b/pkg/backends/knative.go @@ -23,6 +23,7 @@ import ( "net/http" "strconv" + "github.com/grycap/oscar/v2/pkg/imagepuller" "github.com/grycap/oscar/v2/pkg/types" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -118,6 +119,12 @@ func (kn *KnativeBackend) CreateService(service types.Service) error { return err } + //Create deaemonset to cache the service image on all the nodes + err = imagepuller.CreateDaemonset(kn.config, service, kn.kubeClientset) + if err != nil { + return err + } + return nil } diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index bbfeb361..98747f78 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -24,6 +24,7 @@ import ( "fmt" "log" "math/rand" + "os" "sync" "time" @@ -38,6 +39,8 @@ import ( "k8s.io/client-go/tools/cache" ) +var DaemonSetLoggerInfo = log.New(os.Stdout, "[DAEMONSET-INFO] ", log.Flags()) + const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" const lengthStr = 5 @@ -68,9 +71,10 @@ func CreateDaemonset(cfg *types.Config, service types.Service, kubeClientset kub //Create daemonset _, err := kubeClientset.AppsV1().DaemonSets(cfg.Namespace).Create(context.TODO(), daemon, metav1.CreateOptions{}) if err != nil { + DaemonSetLoggerInfo.Println(err) return fmt.Errorf("failed to create daemonset: %s", err.Error()) } else { - log.Printf("Created daemonset") + DaemonSetLoggerInfo.Println("Created daemonset for service: ", service.Name) } //Set watcher informer @@ -146,9 +150,11 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { //Delete daemonset when all pods are in state "Running" err := kubeClientset.AppsV1().DaemonSets(cfg.Namespace).Delete(context.TODO(), daemonsetName, metav1.DeleteOptions{}) if err != nil { + DaemonSetLoggerInfo.Println(err) log.Fatalf("Failed to delete daemonset: %s", err.Error()) } else { log.Printf("Daemonset deleted") + DaemonSetLoggerInfo.Println("Deleted daemonset") } } From 295f98ed7c2ba8b4c639fcea48c55335c639a075 Mon Sep 17 00:00:00 2001 From: catttam Date: Tue, 30 May 2023 10:49:27 +0200 Subject: [PATCH 06/25] Unabled TestKnativeCreateService --- pkg/backends/knative_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pkg/backends/knative_test.go b/pkg/backends/knative_test.go index b6ef367d..991d1088 100644 --- a/pkg/backends/knative_test.go +++ b/pkg/backends/knative_test.go @@ -200,7 +200,7 @@ func TestKnativeListServices(t *testing.T) { } } -func TestKnativeCreateService(t *testing.T) { +/* func TestKnativeCreateService(t *testing.T) { scenarios := []knativeBackendTestScenario{ { "Valid", @@ -232,6 +232,18 @@ func TestKnativeCreateService(t *testing.T) { }, true, }, + { + "Error creating daemonset", + []k8stesting.SimpleReactor{}, + []k8stesting.SimpleReactor{ + { + Verb: "create", + Resource: "daemonsets", + Reaction: errorReaction, + }, + }, + true, + }, { "Error creating knative service and deleting configMap", []k8stesting.SimpleReactor{ @@ -308,7 +320,7 @@ func TestKnativeCreateService(t *testing.T) { t.Error("expected error, got: nil") } }) -} +} */ func TestKnativeReadService(t *testing.T) { scenarios := []knativeBackendTestScenario{ From 5200a8d8e191539a79e2915cae2836cf41548431 Mon Sep 17 00:00:00 2001 From: catttam Date: Tue, 30 May 2023 16:37:00 +0200 Subject: [PATCH 07/25] Changed daemonset namespace --- pkg/imagepuller/daemonset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index 98747f78..05b649a5 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -88,7 +88,7 @@ func getDaemonset(cfg *types.Config, service types.Service) *appsv1.DaemonSet { return &appsv1.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ Name: daemonsetName, - Namespace: cfg.Namespace, + Namespace: cfg.ServicesNamespace, }, Spec: appsv1.DaemonSetSpec{ Selector: &metav1.LabelSelector{ From c7d2c4ed275ba19d5798a22f31fb66808a0b3cc4 Mon Sep 17 00:00:00 2001 From: catttam Date: Tue, 30 May 2023 18:07:14 +0200 Subject: [PATCH 08/25] Typo fix --- pkg/imagepuller/daemonset.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index 05b649a5..f5667449 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -69,7 +69,7 @@ func CreateDaemonset(cfg *types.Config, service types.Service, kubeClientset kub daemon := getDaemonset(cfg, service) //Create daemonset - _, err := kubeClientset.AppsV1().DaemonSets(cfg.Namespace).Create(context.TODO(), daemon, metav1.CreateOptions{}) + _, err := kubeClientset.AppsV1().DaemonSets(cfg.ServicesNamespace).Create(context.TODO(), daemon, metav1.CreateOptions{}) if err != nil { DaemonSetLoggerInfo.Println(err) return fmt.Errorf("failed to create daemonset: %s", err.Error()) @@ -137,7 +137,7 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { sharedInformerOp := informers.WithTweakListOptions(optionsFunc) - factory := informers.NewSharedInformerFactoryWithOptions(kubeClientset, 10*time.Second, informers.WithNamespace(cfg.Namespace), sharedInformerOp) + factory := informers.NewSharedInformerFactoryWithOptions(kubeClientset, 10*time.Second, informers.WithNamespace(cfg.ServicesNamespace), sharedInformerOp) podInformer := factory.Core().V1().Pods().Informer() factory.Start(stopper) @@ -148,7 +148,7 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { }) //Delete daemonset when all pods are in state "Running" - err := kubeClientset.AppsV1().DaemonSets(cfg.Namespace).Delete(context.TODO(), daemonsetName, metav1.DeleteOptions{}) + err := kubeClientset.AppsV1().DaemonSets(cfg.ServicesNamespace).Delete(context.TODO(), daemonsetName, metav1.DeleteOptions{}) if err != nil { DaemonSetLoggerInfo.Println(err) log.Fatalf("Failed to delete daemonset: %s", err.Error()) From 124bf2953d28e42f96a08d3d0c63bc713407a3b9 Mon Sep 17 00:00:00 2001 From: catttam Date: Wed, 31 May 2023 09:21:42 +0200 Subject: [PATCH 09/25] k8s naming format --- pkg/imagepuller/daemonset.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index f5667449..73c9c831 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -41,7 +41,7 @@ import ( var DaemonSetLoggerInfo = log.New(os.Stdout, "[DAEMONSET-INFO] ", log.Flags()) -const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +const letterBytes = "abcdefghijklmnopqrstuvwxyz" const lengthStr = 5 var podGroup string @@ -63,7 +63,7 @@ func CreateDaemonset(cfg *types.Config, service types.Service, kubeClientset kub //Set needed variables setWorkingNodes(kubeClientset) podGroup = generatePodGroupName() - daemonsetName = "image-puller-" + service.Image + daemonsetName = "image-puller-" + service.Name //Get daemonset definition daemon := getDaemonset(cfg, service) @@ -109,7 +109,7 @@ func getDaemonset(cfg *types.Config, service types.Service) *appsv1.DaemonSet { ImagePullSecrets: types.SetImagePullSecrets(service.ImagePullSecrets), Containers: []corev1.Container{ { - Name: "imagePuller", + Name: "image-puller", Image: service.Image, Command: []string{"/bin/sh", "-c", "echo 'Image puller succeed'"}, }, @@ -130,7 +130,7 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { var optionsFunc internalinterfaces.TweakListOptionsFunc = func(options *metav1.ListOptions) { labelSelector := labels.Set{ "oscar-resoure": "daemonset", - "podGroup": podGroup, + "pod-group": podGroup, }.AsSelector() options.LabelSelector = labelSelector.String() } From fdf887d356f8edcadb5f0a9265e1df2d6e9894bb Mon Sep 17 00:00:00 2001 From: catttam Date: Wed, 31 May 2023 10:07:37 +0200 Subject: [PATCH 10/25] Removed closing channel --- pkg/imagepuller/daemonset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index 73c9c831..805c2201 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -123,7 +123,7 @@ func getDaemonset(cfg *types.Config, service types.Service) *appsv1.DaemonSet { //Watch pods with a Kubernetes Informer func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { - defer close(stopper) + //defer close(stopper) pc = PodCounter{wnCount: 0} From 1d3a1d745906e69fc2dfd15a8470f476a6d9ec31 Mon Sep 17 00:00:00 2001 From: catttam Date: Wed, 31 May 2023 12:08:27 +0200 Subject: [PATCH 11/25] Image puller debug logs --- pkg/imagepuller/daemonset.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index 805c2201..e3aca461 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -55,7 +55,7 @@ type PodCounter struct { } var pc PodCounter -var stopper = make(chan struct{}) +var stopper chan struct{} //Create daemonset func CreateDaemonset(cfg *types.Config, service types.Service, kubeClientset kubernetes.Interface) error { @@ -123,7 +123,8 @@ func getDaemonset(cfg *types.Config, service types.Service) *appsv1.DaemonSet { //Watch pods with a Kubernetes Informer func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { - //defer close(stopper) + stopper = make(chan struct{}) + defer close(stopper) pc = PodCounter{wnCount: 0} @@ -141,12 +142,16 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { podInformer := factory.Core().V1().Pods().Informer() factory.Start(stopper) + //Wait for all the selected resources to be added to the cache cache.WaitForCacheSync(stopper, podInformer.HasSynced) + //Add event handler that gets all the pods status podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ UpdateFunc: handlePodEvent, }) + <-stopper + //Delete daemonset when all pods are in state "Running" err := kubeClientset.AppsV1().DaemonSets(cfg.ServicesNamespace).Delete(context.TODO(), daemonsetName, metav1.DeleteOptions{}) if err != nil { @@ -166,7 +171,7 @@ func handlePodEvent(oldObj interface{}, newObj interface{}) { pc.wnCount++ //Check the running pods count and stop the informer if pc.wnCount >= workingNodes { - <-stopper + DaemonSetLoggerInfo.Println("Closing channel") } } } From 41f1a2d8c721db6a95a7588ca73189088d9890b9 Mon Sep 17 00:00:00 2001 From: catttam Date: Wed, 31 May 2023 13:37:33 +0200 Subject: [PATCH 12/25] Channel stop signal on handler --- pkg/imagepuller/daemonset.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index e3aca461..a8d528b0 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -172,6 +172,7 @@ func handlePodEvent(oldObj interface{}, newObj interface{}) { //Check the running pods count and stop the informer if pc.wnCount >= workingNodes { DaemonSetLoggerInfo.Println("Closing channel") + stopper <- struct{}{} } } } From ff1e36f21a6510ff6ec294496ea9342591711a4c Mon Sep 17 00:00:00 2001 From: catttam Date: Thu, 1 Jun 2023 12:34:36 +0200 Subject: [PATCH 13/25] Changed pods command --- pkg/imagepuller/daemonset.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index a8d528b0..354fdde0 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -111,7 +111,7 @@ func getDaemonset(cfg *types.Config, service types.Service) *appsv1.DaemonSet { { Name: "image-puller", Image: service.Image, - Command: []string{"/bin/sh", "-c", "echo 'Image puller succeed'"}, + Command: []string{"/bin/sh", "-c", "sleep 1h"}, }, }, }, @@ -166,6 +166,7 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { func handlePodEvent(oldObj interface{}, newObj interface{}) { newPod := newObj.(*corev1.Pod) if newPod.Status.Phase == corev1.PodRunning { + DaemonSetLoggerInfo.Println("Pod status running") pc.mutex.Lock() defer pc.mutex.Unlock() pc.wnCount++ From 447762531b186924337c9145bf3cddb6179290fa Mon Sep 17 00:00:00 2001 From: catttam Date: Thu, 1 Jun 2023 13:34:27 +0200 Subject: [PATCH 14/25] New pod informer handler --- pkg/imagepuller/daemonset.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index 354fdde0..f1793874 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -147,7 +147,8 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { //Add event handler that gets all the pods status podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ - UpdateFunc: handlePodEvent, + AddFunc: handleAddPodEvent, + UpdateFunc: handleUpdatePodEvent, }) <-stopper @@ -158,12 +159,12 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { DaemonSetLoggerInfo.Println(err) log.Fatalf("Failed to delete daemonset: %s", err.Error()) } else { - log.Printf("Daemonset deleted") DaemonSetLoggerInfo.Println("Deleted daemonset") } } -func handlePodEvent(oldObj interface{}, newObj interface{}) { +func handleUpdatePodEvent(oldObj interface{}, newObj interface{}) { + DaemonSetLoggerInfo.Println("UPDATE EVENT FOUND") newPod := newObj.(*corev1.Pod) if newPod.Status.Phase == corev1.PodRunning { DaemonSetLoggerInfo.Println("Pod status running") @@ -178,6 +179,22 @@ func handlePodEvent(oldObj interface{}, newObj interface{}) { } } +func handleAddPodEvent(pod interface{}) { + DaemonSetLoggerInfo.Println("ADD EVENT FOUND") + p := pod.(*corev1.Pod) + if p.Status.Phase == corev1.PodRunning { + DaemonSetLoggerInfo.Println("Pod status running") + pc.mutex.Lock() + defer pc.mutex.Unlock() + pc.wnCount++ + //Check the running pods count and stop the informer + if pc.wnCount >= workingNodes { + DaemonSetLoggerInfo.Println("Closing channel") + stopper <- struct{}{} + } + } +} + func setWorkingNodes(kubeClientset kubernetes.Interface) error { nodes, err := kubeClientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{LabelSelector: "!node-role.kubernetes.io/control-plane,!node-role.kubernetes.io/master"}) if err != nil { From cff92ebe06c1e85ad5fce10f0e88c92c5b07cd47 Mon Sep 17 00:00:00 2001 From: catttam Date: Thu, 1 Jun 2023 19:42:34 +0200 Subject: [PATCH 15/25] Debug logs --- pkg/imagepuller/daemonset.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index f1793874..d7b3a635 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -74,7 +74,7 @@ func CreateDaemonset(cfg *types.Config, service types.Service, kubeClientset kub DaemonSetLoggerInfo.Println(err) return fmt.Errorf("failed to create daemonset: %s", err.Error()) } else { - DaemonSetLoggerInfo.Println("Created daemonset for service: ", service.Name) + DaemonSetLoggerInfo.Println("Created daemonset for service:", service.Name) } //Set watcher informer @@ -122,7 +122,7 @@ func getDaemonset(cfg *types.Config, service types.Service) *appsv1.DaemonSet { //Watch pods with a Kubernetes Informer func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { - + DaemonSetLoggerInfo.Println("Started pod watching") stopper = make(chan struct{}) defer close(stopper) @@ -138,21 +138,27 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { sharedInformerOp := informers.WithTweakListOptions(optionsFunc) - factory := informers.NewSharedInformerFactoryWithOptions(kubeClientset, 10*time.Second, informers.WithNamespace(cfg.ServicesNamespace), sharedInformerOp) + factory := informers.NewSharedInformerFactoryWithOptions(kubeClientset, 2*time.Second, informers.WithNamespace(cfg.ServicesNamespace), sharedInformerOp) podInformer := factory.Core().V1().Pods().Informer() factory.Start(stopper) - //Wait for all the selected resources to be added to the cache - cache.WaitForCacheSync(stopper, podInformer.HasSynced) + DaemonSetLoggerInfo.Println("Started factory") + //Wait for all the selected resources to be added to the cache + state := cache.WaitForCacheSync(stopper, podInformer.HasSynced) + if !state { + log.Fatalf("Failed to sync informer cache") + } + DaemonSetLoggerInfo.Println("Cache synced") //Add event handler that gets all the pods status podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: handleAddPodEvent, UpdateFunc: handleUpdatePodEvent, }) - + DaemonSetLoggerInfo.Println("Added handlers") <-stopper + DaemonSetLoggerInfo.Println("Channel stopped") //Delete daemonset when all pods are in state "Running" err := kubeClientset.AppsV1().DaemonSets(cfg.ServicesNamespace).Delete(context.TODO(), daemonsetName, metav1.DeleteOptions{}) if err != nil { From 3dbf67c6827150f0d106fdf1b2138c42ad9f8b30 Mon Sep 17 00:00:00 2001 From: catttam Date: Thu, 1 Jun 2023 22:17:21 +0200 Subject: [PATCH 16/25] Change starter order --- pkg/imagepuller/daemonset.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index d7b3a635..f85e96b2 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -140,22 +140,23 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { factory := informers.NewSharedInformerFactoryWithOptions(kubeClientset, 2*time.Second, informers.WithNamespace(cfg.ServicesNamespace), sharedInformerOp) podInformer := factory.Core().V1().Pods().Informer() - factory.Start(stopper) - - DaemonSetLoggerInfo.Println("Started factory") //Wait for all the selected resources to be added to the cache state := cache.WaitForCacheSync(stopper, podInformer.HasSynced) if !state { log.Fatalf("Failed to sync informer cache") } + DaemonSetLoggerInfo.Println("Cache synced") + //Add event handler that gets all the pods status podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: handleAddPodEvent, UpdateFunc: handleUpdatePodEvent, }) DaemonSetLoggerInfo.Println("Added handlers") + factory.Start(stopper) + DaemonSetLoggerInfo.Println("Started informer") <-stopper DaemonSetLoggerInfo.Println("Channel stopped") From dec3827ae759f2559bdf31fb87f808482e186119 Mon Sep 17 00:00:00 2001 From: catttam Date: Fri, 2 Jun 2023 12:25:43 +0200 Subject: [PATCH 17/25] Fixed informer --- pkg/imagepuller/daemonset.go | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/pkg/imagepuller/daemonset.go b/pkg/imagepuller/daemonset.go index f85e96b2..386e8b24 100644 --- a/pkg/imagepuller/daemonset.go +++ b/pkg/imagepuller/daemonset.go @@ -122,7 +122,6 @@ func getDaemonset(cfg *types.Config, service types.Service) *appsv1.DaemonSet { //Watch pods with a Kubernetes Informer func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { - DaemonSetLoggerInfo.Println("Started pod watching") stopper = make(chan struct{}) defer close(stopper) @@ -130,8 +129,7 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { var optionsFunc internalinterfaces.TweakListOptionsFunc = func(options *metav1.ListOptions) { labelSelector := labels.Set{ - "oscar-resoure": "daemonset", - "pod-group": podGroup, + "pod-group": podGroup, }.AsSelector() options.LabelSelector = labelSelector.String() } @@ -139,7 +137,10 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { sharedInformerOp := informers.WithTweakListOptions(optionsFunc) factory := informers.NewSharedInformerFactoryWithOptions(kubeClientset, 2*time.Second, informers.WithNamespace(cfg.ServicesNamespace), sharedInformerOp) + //factory := informers.NewSharedInformerFactory(kubeClientset, 2*time.Second) + podInformer := factory.Core().V1().Pods().Informer() + factory.Start(stopper) //Wait for all the selected resources to be added to the cache state := cache.WaitForCacheSync(stopper, podInformer.HasSynced) @@ -147,20 +148,15 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { log.Fatalf("Failed to sync informer cache") } - DaemonSetLoggerInfo.Println("Cache synced") - //Add event handler that gets all the pods status podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: handleAddPodEvent, UpdateFunc: handleUpdatePodEvent, }) - DaemonSetLoggerInfo.Println("Added handlers") - factory.Start(stopper) - DaemonSetLoggerInfo.Println("Started informer") + <-stopper - DaemonSetLoggerInfo.Println("Channel stopped") //Delete daemonset when all pods are in state "Running" + DaemonSetLoggerInfo.Println("Deleting daemonset...") err := kubeClientset.AppsV1().DaemonSets(cfg.ServicesNamespace).Delete(context.TODO(), daemonsetName, metav1.DeleteOptions{}) if err != nil { DaemonSetLoggerInfo.Println(err) @@ -171,32 +167,13 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) { } func handleUpdatePodEvent(oldObj interface{}, newObj interface{}) { - DaemonSetLoggerInfo.Println("UPDATE EVENT FOUND") newPod := newObj.(*corev1.Pod) if newPod.Status.Phase == corev1.PodRunning { - DaemonSetLoggerInfo.Println("Pod status running") - pc.mutex.Lock() - defer pc.mutex.Unlock() - pc.wnCount++ - //Check the running pods count and stop the informer - if pc.wnCount >= workingNodes { - DaemonSetLoggerInfo.Println("Closing channel") - stopper <- struct{}{} - } - } -} - -func handleAddPodEvent(pod interface{}) { - DaemonSetLoggerInfo.Println("ADD EVENT FOUND") - p := pod.(*corev1.Pod) - if p.Status.Phase == corev1.PodRunning { - DaemonSetLoggerInfo.Println("Pod status running") pc.mutex.Lock() defer pc.mutex.Unlock() pc.wnCount++ //Check the running pods count and stop the informer if pc.wnCount >= workingNodes { - DaemonSetLoggerInfo.Println("Closing channel") stopper <- struct{}{} } } From c8aa1d07b6d97b9a4011204059cc76456d8b0d5f Mon Sep 17 00:00:00 2001 From: catttam Date: Wed, 5 Jul 2023 13:25:34 +0200 Subject: [PATCH 18/25] Added enable_cache parameter to FDL --- docs/fdl.md | 1 + pkg/backends/k8s.go | 8 +++++--- pkg/backends/k8s_test.go | 2 ++ pkg/backends/knative.go | 8 +++++--- pkg/backends/knative_test.go | 16 ++-------------- pkg/types/service.go | 6 +++++- pkg/types/service_test.go | 1 + 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/fdl.md b/docs/fdl.md index 92c75356..44e29c91 100644 --- a/docs/fdl.md +++ b/docs/fdl.md @@ -74,6 +74,7 @@ storage_providers: | `memory`
*string* | Memory limit for the service following the [kubernetes format](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory). Optional (default: 256Mi) | | `cpu`
*string* | CPU limit for the service following the [kubernetes format](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu). Optional (default: 0.2) | | `enable_gpu`
*bool* | Parameter to enable the use of GPU for the service. Requires a device plugin deployed on the cluster (More info: [Kubernetes device plugins](https://kubernetes.io/docs/tasks/manage-gpus/scheduling-gpus/#using-device-plugins)). Optional (default: false) | +| `enable_cache`
*bool* | Parameter to enable the use of image caching. Optional (default: false) | | `total_memory`
*string* | Limit for the memory used by all the service's jobs running simultaneously. Apache YuniKorn scheduler is required to work. Same format as Memory, but internally translated to MB (integer). Optional (default: "") | | `total_cpu`
*string* | Limit for the virtual CPUs used by all the service's jobs running simultaneously. Apache YuniKorn scheduler is required to work. Same format as CPU, but internally translated to millicores (integer). Optional (default: "") | | `synchronous`
*[SynchronousSettings](#synchronoussettings)* | Struct to configure specific sync parameters. This settings are only applied on Knative ServerlessBackend. Optional. | diff --git a/pkg/backends/k8s.go b/pkg/backends/k8s.go index 3cc7fcb6..08f3954f 100644 --- a/pkg/backends/k8s.go +++ b/pkg/backends/k8s.go @@ -114,9 +114,11 @@ func (k *KubeBackend) CreateService(service types.Service) error { } //Create deaemonset to cache the service image on all the nodes - err = imagepuller.CreateDaemonset(k.config, service, k.kubeClientset) - if err != nil { - return err + if service.EnableCache { + err = imagepuller.CreateDaemonset(k.config, service, k.kubeClientset) + if err != nil { + return err + } } return nil diff --git a/pkg/backends/k8s_test.go b/pkg/backends/k8s_test.go index b8a11289..4039a2b4 100644 --- a/pkg/backends/k8s_test.go +++ b/pkg/backends/k8s_test.go @@ -212,6 +212,8 @@ func TestKubeListServices(t *testing.T) { }) } +// Test temporarily disabled to be able to use the image cache feature + func TestKubeCreateService(t *testing.T) { testService := types.Service{ Name: "test", diff --git a/pkg/backends/knative.go b/pkg/backends/knative.go index a2d17ac6..a2315d1e 100644 --- a/pkg/backends/knative.go +++ b/pkg/backends/knative.go @@ -120,9 +120,11 @@ func (kn *KnativeBackend) CreateService(service types.Service) error { } //Create deaemonset to cache the service image on all the nodes - err = imagepuller.CreateDaemonset(kn.config, service, kn.kubeClientset) - if err != nil { - return err + if service.EnableCache { + err = imagepuller.CreateDaemonset(kn.config, service, kn.kubeClientset) + if err != nil { + return err + } } return nil diff --git a/pkg/backends/knative_test.go b/pkg/backends/knative_test.go index 991d1088..b6ef367d 100644 --- a/pkg/backends/knative_test.go +++ b/pkg/backends/knative_test.go @@ -200,7 +200,7 @@ func TestKnativeListServices(t *testing.T) { } } -/* func TestKnativeCreateService(t *testing.T) { +func TestKnativeCreateService(t *testing.T) { scenarios := []knativeBackendTestScenario{ { "Valid", @@ -232,18 +232,6 @@ func TestKnativeListServices(t *testing.T) { }, true, }, - { - "Error creating daemonset", - []k8stesting.SimpleReactor{}, - []k8stesting.SimpleReactor{ - { - Verb: "create", - Resource: "daemonsets", - Reaction: errorReaction, - }, - }, - true, - }, { "Error creating knative service and deleting configMap", []k8stesting.SimpleReactor{ @@ -320,7 +308,7 @@ func TestKnativeListServices(t *testing.T) { t.Error("expected error, got: nil") } }) -} */ +} func TestKnativeReadService(t *testing.T) { scenarios := []knativeBackendTestScenario{ diff --git a/pkg/types/service.go b/pkg/types/service.go index 219e4f29..bfc89f7a 100644 --- a/pkg/types/service.go +++ b/pkg/types/service.go @@ -139,10 +139,14 @@ type Service struct { // Optional. (default: "") TotalCPU string `json:"total_cpu"` - // GPU parameter to request gpu usage in service's executions (synchronous and asynchronous) + // EnableGPU parameter to request gpu usage in service's executions (synchronous and asynchronous) // Optional. (default: false) EnableGPU bool `json:"enable_gpu"` + // EnableCache parameter to enable the image cache functionality + // Optional. (default: false) + EnableCache bool `json:"enable_cache"` + // Synchronous struct to configure specific sync parameters // Only Knative ServerlessBackend applies this settings // Optional. diff --git a/pkg/types/service_test.go b/pkg/types/service_test.go index 4f380660..ae4466d0 100644 --- a/pkg/types/service_test.go +++ b/pkg/types/service_test.go @@ -215,6 +215,7 @@ cpu: "1.0" total_memory: "" total_cpu: "" enable_gpu: false +enable_cache: false synchronous: min_scale: 0 max_scale: 0 From b7a7f1f8a65f5e495ad43d1b9d52718c5b35ee49 Mon Sep 17 00:00:00 2001 From: catttam Date: Thu, 6 Jul 2023 11:35:56 +0200 Subject: [PATCH 19/25] Updated rbac rules to manage daemonsets --- deploy/yaml/oscar-rbac.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/yaml/oscar-rbac.yaml b/deploy/yaml/oscar-rbac.yaml index 55958ab2..2f49e394 100644 --- a/deploy/yaml/oscar-rbac.yaml +++ b/deploy/yaml/oscar-rbac.yaml @@ -18,6 +18,7 @@ rules: - pods/log - podtemplates - configmaps + - daemonsets verbs: - get - list From ededf2d03dbace5c0d2b670194f9cd39dce6f9e7 Mon Sep 17 00:00:00 2001 From: catttam Date: Fri, 7 Jul 2023 09:39:09 +0200 Subject: [PATCH 20/25] Updated UI reference --- ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui b/ui index a7bc564a..764f12d9 160000 --- a/ui +++ b/ui @@ -1 +1 @@ -Subproject commit a7bc564a6b58d0063134bf70a5ae9a9fc1bef989 +Subproject commit 764f12d941d7d76d7da9ff9f9e05fc61f48261be From 89dacc6ae055350334e7c38c372cdd28450a1a30 Mon Sep 17 00:00:00 2001 From: catttam Date: Fri, 7 Jul 2023 12:17:16 +0200 Subject: [PATCH 21/25] Updated oscar-ui reference --- ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui b/ui index 764f12d9..a2e61188 160000 --- a/ui +++ b/ui @@ -1 +1 @@ -Subproject commit 764f12d941d7d76d7da9ff9f9e05fc61f48261be +Subproject commit a2e61188d202af6ce1fd0fee2bcd3e36bf1ad68c From 7fb876d66b2703c2b9c24e6bdb245b4af66887ce Mon Sep 17 00:00:00 2001 From: catttam Date: Fri, 7 Jul 2023 12:57:28 +0200 Subject: [PATCH 22/25] Updated rbac rules --- deploy/yaml/oscar-rbac.yaml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/deploy/yaml/oscar-rbac.yaml b/deploy/yaml/oscar-rbac.yaml index 2f49e394..b9a4ff1c 100644 --- a/deploy/yaml/oscar-rbac.yaml +++ b/deploy/yaml/oscar-rbac.yaml @@ -18,7 +18,6 @@ rules: - pods/log - podtemplates - configmaps - - daemonsets verbs: - get - list @@ -26,6 +25,17 @@ rules: - create - delete - update +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - get + - list + - watch + - create + - delete + - update - apiGroups: - batch resources: From 253877d2b3475abbe81f545177a4ebc8681308b9 Mon Sep 17 00:00:00 2001 From: catttam Date: Mon, 10 Jul 2023 10:04:51 +0200 Subject: [PATCH 23/25] Changed enable_cache parameter to image_prefetch --- docs/fdl.md | 2 +- pkg/handlers/run_test.go | 3 +++ pkg/types/service.go | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/fdl.md b/docs/fdl.md index 44e29c91..0d0b0132 100644 --- a/docs/fdl.md +++ b/docs/fdl.md @@ -74,7 +74,7 @@ storage_providers: | `memory`
*string* | Memory limit for the service following the [kubernetes format](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory). Optional (default: 256Mi) | | `cpu`
*string* | CPU limit for the service following the [kubernetes format](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu). Optional (default: 0.2) | | `enable_gpu`
*bool* | Parameter to enable the use of GPU for the service. Requires a device plugin deployed on the cluster (More info: [Kubernetes device plugins](https://kubernetes.io/docs/tasks/manage-gpus/scheduling-gpus/#using-device-plugins)). Optional (default: false) | -| `enable_cache`
*bool* | Parameter to enable the use of image caching. Optional (default: false) | +| `image_prefetch`
*bool* | Parameter to enable the use of image caching. Optional (default: false) | | `total_memory`
*string* | Limit for the memory used by all the service's jobs running simultaneously. Apache YuniKorn scheduler is required to work. Same format as Memory, but internally translated to MB (integer). Optional (default: "") | | `total_cpu`
*string* | Limit for the virtual CPUs used by all the service's jobs running simultaneously. Apache YuniKorn scheduler is required to work. Same format as CPU, but internally translated to millicores (integer). Optional (default: "") | | `synchronous`
*[SynchronousSettings](#synchronoussettings)* | Struct to configure specific sync parameters. This settings are only applied on Knative ServerlessBackend. Optional. | diff --git a/pkg/handlers/run_test.go b/pkg/handlers/run_test.go index 21f525cb..bf94fb48 100644 --- a/pkg/handlers/run_test.go +++ b/pkg/handlers/run_test.go @@ -5,6 +5,7 @@ import ( "net/http" "net/http/httptest" "testing" + "time" "github.com/gin-gonic/gin" "github.com/grycap/oscar/v2/pkg/backends" @@ -44,6 +45,7 @@ func (GinResponseRecorder) Flush() { func TestMakeRunHandler(t *testing.T) { back := backends.MakeFakeSyncBackend() + http.DefaultClient.Timeout = 400 * time.Second r := gin.Default() r.POST("/run/:serviceName", MakeRunHandler(&testConfigValidRun, back)) @@ -62,6 +64,7 @@ func TestMakeRunHandler(t *testing.T) { t.Run(s.name, func(t *testing.T) { w := httptest.NewRecorder() serviceName := "test" + req, _ := http.NewRequest("POST", "/run/"+serviceName, nil) req.Header.Set("Authorization", "Bearer AbCdEf123456") diff --git a/pkg/types/service.go b/pkg/types/service.go index bfc89f7a..6f9a7fb0 100644 --- a/pkg/types/service.go +++ b/pkg/types/service.go @@ -143,9 +143,9 @@ type Service struct { // Optional. (default: false) EnableGPU bool `json:"enable_gpu"` - // EnableCache parameter to enable the image cache functionality + // ImagePrefetch parameter to enable the image cache functionality // Optional. (default: false) - EnableCache bool `json:"enable_cache"` + ImagePrefetch bool `json:"image_prefetch"` // Synchronous struct to configure specific sync parameters // Only Knative ServerlessBackend applies this settings From 2917e962f69d321901707f10afd3281226cedb18 Mon Sep 17 00:00:00 2001 From: catttam Date: Mon, 10 Jul 2023 10:09:36 +0200 Subject: [PATCH 24/25] Fix service test --- pkg/types/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/types/service_test.go b/pkg/types/service_test.go index ae4466d0..8f7770b2 100644 --- a/pkg/types/service_test.go +++ b/pkg/types/service_test.go @@ -215,7 +215,7 @@ cpu: "1.0" total_memory: "" total_cpu: "" enable_gpu: false -enable_cache: false +image_prefetch: false synchronous: min_scale: 0 max_scale: 0 From 26e0490023d2bd8598651b4dc07d6ae4c54cd2d5 Mon Sep 17 00:00:00 2001 From: catttam Date: Mon, 10 Jul 2023 10:14:28 +0200 Subject: [PATCH 25/25] Typo fix --- pkg/backends/k8s.go | 2 +- pkg/backends/knative.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/backends/k8s.go b/pkg/backends/k8s.go index 08f3954f..ca578026 100644 --- a/pkg/backends/k8s.go +++ b/pkg/backends/k8s.go @@ -114,7 +114,7 @@ func (k *KubeBackend) CreateService(service types.Service) error { } //Create deaemonset to cache the service image on all the nodes - if service.EnableCache { + if service.ImagePrefetch { err = imagepuller.CreateDaemonset(k.config, service, k.kubeClientset) if err != nil { return err diff --git a/pkg/backends/knative.go b/pkg/backends/knative.go index a2315d1e..d445e47f 100644 --- a/pkg/backends/knative.go +++ b/pkg/backends/knative.go @@ -120,7 +120,7 @@ func (kn *KnativeBackend) CreateService(service types.Service) error { } //Create deaemonset to cache the service image on all the nodes - if service.EnableCache { + if service.ImagePrefetch { err = imagepuller.CreateDaemonset(kn.config, service, kn.kubeClientset) if err != nil { return err