diff --git a/charts/fsm/components/scripts/ingress/config/main.json b/charts/fsm/components/scripts/ingress/config/main.json index 2a57eef2..07670634 100644 --- a/charts/fsm/components/scripts/ingress/config/main.json +++ b/charts/fsm/components/scripts/ingress/config/main.json @@ -35,5 +35,7 @@ "size": 1000, "separator": "\n" } - } + }, + + "version": 1 } \ No newline at end of file diff --git a/charts/fsm/templates/ingress-pipy-deployment.yaml b/charts/fsm/templates/ingress-pipy-deployment.yaml index 15e00bbb..94111a35 100644 --- a/charts/fsm/templates/ingress-pipy-deployment.yaml +++ b/charts/fsm/templates/ingress-pipy-deployment.yaml @@ -46,7 +46,7 @@ spec: - --connect-timeout - "2" - --retry - - "50" + - "100" - --retry-connrefused - --retry-delay - "5" diff --git a/charts/fsm/templates/mesh-config-configmap.yaml b/charts/fsm/templates/mesh-config-configmap.yaml index 94580065..7b0b04d6 100644 --- a/charts/fsm/templates/mesh-config-configmap.yaml +++ b/charts/fsm/templates/mesh-config-configmap.yaml @@ -18,7 +18,8 @@ data: }, "repo": { - "rootUrl": {{ include "fsm.repo-service.url" . | quote }} + "rootUrl": {{ include "fsm.repo-service.url" . | quote }}, + "recoverIntervalInSeconds": 30 }, "webhook": { diff --git a/charts/fsm/values.schema.json b/charts/fsm/values.schema.json index db98c8f2..c783a923 100644 --- a/charts/fsm/values.schema.json +++ b/charts/fsm/values.schema.json @@ -165,7 +165,7 @@ }, "tag": { "type": "string", - "default": "0.90.0-185", + "default": "0.90.1-157", "title": "The tag Schema" } } diff --git a/charts/fsm/values.yaml b/charts/fsm/values.yaml index 702a9d2c..9d93409b 100644 --- a/charts/fsm/values.yaml +++ b/charts/fsm/values.yaml @@ -53,7 +53,7 @@ fsm: pipy: imageName: pipy - tag: 0.90.1-10-nonroot + tag: 0.90.1-157-nonroot toolbox: imageName: toolbox diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 5aa167e0..3056603a 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -51,6 +51,7 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth" flomeshscheme "github.com/flomesh-io/fsm-classic/pkg/generated/clientset/versioned/scheme" + "github.com/go-co-op/gocron" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -143,7 +144,7 @@ func main() { //+kubebuilder:scaffold:builder // start the controller manager - startManager(mgr, mc) + startManager(mgr, mc, repoClient) } func processFlags() *startArgs { @@ -220,15 +221,27 @@ func addLivenessAndReadinessCheck(mgr manager.Manager) { } } -func startManager(mgr manager.Manager, mc *config.MeshConfig) { - //err := mgr.Add(manager.RunnableFunc(func(context.Context) error { - // aggregatorAddr := fmt.Sprintf(":%s", mc.AggregatorPort()) - // return aggregator.NewAggregator(aggregatorAddr, mc.RepoAddr()).Run() - //})) - //if err != nil { - // klog.Error(err, "unable add aggregator server to the manager") - // os.Exit(1) - //} +func startManager(mgr manager.Manager, mc *config.MeshConfig, repoClient *repo.PipyRepoClient) { + klog.V(5).Infof("===> RepoRecoverIntervalInSeconds: %d", mc.Repo.RecoverIntervalInSeconds) + s := gocron.NewScheduler(time.Local) + s.SingletonModeAll() + if _, err := s.Every(30).Seconds(). + Name("rebuild-repo"). + Do(rebuildRepoJob, repoClient, mgr.GetClient(), mc); err != nil { + klog.Errorf("Error happened while rebuilding repo: %s", err) + } + s.RegisterEventListeners( + gocron.AfterJobRuns(func(jobName string) { + klog.Infof(">>>>>> afterJobRuns: %s\n", jobName) + }), + gocron.BeforeJobRuns(func(jobName string) { + klog.Infof(">>>>>> beforeJobRuns: %s\n", jobName) + }), + gocron.WhenJobReturnsError(func(jobName string, err error) { + klog.Errorf(">>>>>> whenJobReturnsError: %s, %v\n", jobName, err) + }), + ) + s.StartAsync() klog.Info("starting manager") if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { diff --git a/cmd/manager/repo.go b/cmd/manager/repo.go index 9cf02ad9..0126428b 100644 --- a/cmd/manager/repo.go +++ b/cmd/manager/repo.go @@ -25,13 +25,21 @@ package main import ( + "context" "fmt" + nsigv1alpha1 "github.com/flomesh-io/fsm-classic/apis/namespacedingress/v1alpha1" + pfv1alpha1 "github.com/flomesh-io/fsm-classic/apis/proxyprofile/v1alpha1" + pfhelper "github.com/flomesh-io/fsm-classic/apis/proxyprofile/v1alpha1/helper" + "github.com/flomesh-io/fsm-classic/pkg/commons" + "github.com/flomesh-io/fsm-classic/pkg/config" + "github.com/flomesh-io/fsm-classic/pkg/config/utils" "github.com/flomesh-io/fsm-classic/pkg/repo" "io/ioutil" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/klog/v2" "os" "path/filepath" + "sigs.k8s.io/controller-runtime/pkg/client" "strings" "time" ) @@ -62,11 +70,11 @@ func initRepo(repoClient *repo.PipyRepoClient) { } func ingressBatch() repo.Batch { - return createBatch("/base/ingress", fmt.Sprintf("%s/ingress", ScriptsRoot)) + return createBatch(commons.DefaultIngressBasePath, fmt.Sprintf("%s/ingress", ScriptsRoot)) } func servicesBatch() repo.Batch { - return createBatch("/base/services", fmt.Sprintf("%s/services", ScriptsRoot)) + return createBatch(commons.DefaultServiceBasePath, fmt.Sprintf("%s/services", ScriptsRoot)) } func createBatch(repoPath, scriptsDir string) repo.Batch { @@ -116,3 +124,89 @@ func visit(files *[]string) filepath.WalkFunc { return nil } } + +func rebuildRepoJob(repoClient *repo.PipyRepoClient, client client.Client, mc *config.MeshConfig) error { + klog.Infof("<<<<<< rebuilding repo - start >>>>>> ") + + if !repoClient.IsRepoUp() { + klog.V(2).Info("Repo is not up, sleeping ...") + return nil + } + + // initialize the repo + batches := make([]repo.Batch, 0) + if !repoClient.CodebaseExists(commons.DefaultIngressBasePath) { + batches = append(batches, ingressBatch()) + } + if !repoClient.CodebaseExists(commons.DefaultServiceBasePath) { + batches = append(batches, servicesBatch()) + } + if len(batches) > 0 { + if err := repoClient.Batch(batches); err != nil { + klog.Errorf("Failed to write config to repo: %s", err) + return err + } + + defaultIngressPath := mc.GetDefaultIngressPath() + if _, err := repoClient.DeriveCodebase(defaultIngressPath, commons.DefaultIngressBasePath); err != nil { + klog.Errorf("%q failed to derive codebase %q: %s", defaultIngressPath, commons.DefaultIngressBasePath, err) + return err + } + + defaultServicesPath := mc.GetDefaultServicesPath() + if _, err := repoClient.DeriveCodebase(defaultServicesPath, commons.DefaultServiceBasePath); err != nil { + klog.Errorf("%q failed to derive codebase %q: %s", defaultServicesPath, commons.DefaultServiceBasePath, err) + return err + } + + if mc.Ingress.Enabled && mc.Ingress.Namespaced { + nsigList := &nsigv1alpha1.NamespacedIngressList{} + if err := client.List(context.TODO(), nsigList); err != nil { + return err + } + + for _, nsig := range nsigList.Items { + ingressPath := mc.NamespacedIngressCodebasePath(nsig.Namespace) + parentPath := mc.IngressCodebasePath() + if _, err := repoClient.DeriveCodebase(ingressPath, parentPath); err != nil { + klog.Errorf("Codebase of NamespaceIngress %q failed to derive codebase %q: %s", ingressPath, parentPath, err) + return err + } + } + } + + pfList := &pfv1alpha1.ProxyProfileList{} + if err := client.List(context.TODO(), pfList); err != nil { + return err + } + + for _, pf := range pfList.Items { + // ProxyProfile codebase derives service codebase + pfPath := pfhelper.GetProxyProfilePath(pf.Name, mc) + pfParentPath := pfhelper.GetProxyProfileParentPath(mc) + klog.V(5).Infof("Deriving service codebase of ProxyProfile %q", pf.Name) + if _, err := repoClient.DeriveCodebase(pfPath, pfParentPath); err != nil { + klog.Errorf("Deriving service codebase of ProxyProfile %q error: %#v", pf.Name, err) + return err + } + + // sidecar codebase derives ProxyProfile codebase + for _, sidecar := range pf.Spec.Sidecars { + sidecarPath := pfhelper.GetSidecarPath(pf.Name, sidecar.Name, mc) + klog.V(5).Infof("Deriving codebase of sidecar %q of ProxyProfile %q", sidecar.Name, pf.Name) + if _, err := repoClient.DeriveCodebase(sidecarPath, pfPath); err != nil { + klog.Errorf("Deriving codebase of sidecar %q of ProxyProfile %q error: %#v", sidecar.Name, pf.Name, err) + return err + } + } + } + + if err := utils.UpdateMainVersion(commons.DefaultIngressBasePath, repoClient, mc); err != nil { + klog.Errorf("Failed to update version of main.json: %s", err) + return err + } + } + + klog.Infof("<<<<<< rebuilding repo - end >>>>>> ") + return nil +} diff --git a/cmd/proxy-init/main.go b/cmd/proxy-init/main.go index 2bb51826..e7d19ced 100644 --- a/cmd/proxy-init/main.go +++ b/cmd/proxy-init/main.go @@ -157,7 +157,7 @@ func deriveCodebases(cfg config.ProxyInitEnvironmentConfiguration) { parentPath := cfg.ProxyParentPath for _, sidecarPath := range cfg.ProxyPaths { - if err := repoClient.DeriveCodebase(sidecarPath, parentPath); err != nil { + if _, err := repoClient.DeriveCodebase(sidecarPath, parentPath); err != nil { os.Exit(1) } } diff --git a/controllers/cluster/v1alpha1/cluster_controller.go b/controllers/cluster/v1alpha1/cluster_controller.go index fb61842b..f9fa1bde 100644 --- a/controllers/cluster/v1alpha1/cluster_controller.go +++ b/controllers/cluster/v1alpha1/cluster_controller.go @@ -164,12 +164,12 @@ func (r *ClusterReconciler) deriveCodebases(mc *config.MeshConfig) (ctrl.Result, repoClient := repo.NewRepoClient(mc.RepoRootURL()) defaultServicesPath := mc.GetDefaultServicesPath() - if err := repoClient.DeriveCodebase(defaultServicesPath, commons.DefaultServiceBasePath); err != nil { + if _, err := repoClient.DeriveCodebase(defaultServicesPath, commons.DefaultServiceBasePath); err != nil { return ctrl.Result{RequeueAfter: 1 * time.Second}, err } defaultIngressPath := mc.GetDefaultIngressPath() - if err := repoClient.DeriveCodebase(defaultIngressPath, commons.DefaultIngressBasePath); err != nil { + if _, err := repoClient.DeriveCodebase(defaultIngressPath, commons.DefaultIngressBasePath); err != nil { return ctrl.Result{RequeueAfter: 1 * time.Second}, err } diff --git a/controllers/namespacedingress/v1alpha1/namespacedingress_controller.go b/controllers/namespacedingress/v1alpha1/namespacedingress_controller.go index 47fb889e..a6a39101 100644 --- a/controllers/namespacedingress/v1alpha1/namespacedingress_controller.go +++ b/controllers/namespacedingress/v1alpha1/namespacedingress_controller.go @@ -161,7 +161,7 @@ func (r *NamespacedIngressReconciler) deriveCodebases(nsig *nsigv1alpha1.Namespa ingressPath := mc.NamespacedIngressCodebasePath(nsig.Namespace) parentPath := mc.IngressCodebasePath() - if err := repoClient.DeriveCodebase(ingressPath, parentPath); err != nil { + if _, err := repoClient.DeriveCodebase(ingressPath, parentPath); err != nil { return ctrl.Result{RequeueAfter: 1 * time.Second}, err } diff --git a/controllers/proxyprofile/v1alpha1/proxyprofile_controller.go b/controllers/proxyprofile/v1alpha1/proxyprofile_controller.go index 71882bb2..d16b9861 100644 --- a/controllers/proxyprofile/v1alpha1/proxyprofile_controller.go +++ b/controllers/proxyprofile/v1alpha1/proxyprofile_controller.go @@ -369,7 +369,7 @@ func (r *ProxyProfileReconciler) deriveCodebases(pf *pfv1alpha1.ProxyProfile, mc pfPath := pfhelper.GetProxyProfilePath(pf.Name, mc) pfParentPath := pfhelper.GetProxyProfileParentPath(mc) klog.V(5).Infof("Deriving service codebase of ProxyProfile %q", pf.Name) - if err := repoClient.DeriveCodebase(pfPath, pfParentPath); err != nil { + if _, err := repoClient.DeriveCodebase(pfPath, pfParentPath); err != nil { klog.Errorf("Deriving service codebase of ProxyProfile %q error: %#v", pf.Name, err) return ctrl.Result{RequeueAfter: 3 * time.Second}, err } @@ -378,7 +378,7 @@ func (r *ProxyProfileReconciler) deriveCodebases(pf *pfv1alpha1.ProxyProfile, mc for _, sidecar := range pf.Spec.Sidecars { sidecarPath := pfhelper.GetSidecarPath(pf.Name, sidecar.Name, mc) klog.V(5).Infof("Deriving codebase of sidecar %q of ProxyProfile %q", sidecar.Name, pf.Name) - if err := repoClient.DeriveCodebase(sidecarPath, pfPath); err != nil { + if _, err := repoClient.DeriveCodebase(sidecarPath, pfPath); err != nil { klog.Errorf("Deriving codebase of sidecar %q of ProxyProfile %q error: %#v", sidecar.Name, pf.Name, err) return ctrl.Result{RequeueAfter: 3 * time.Second}, err } diff --git a/dockerfiles/ingress-pipy/Dockerfile b/dockerfiles/ingress-pipy/Dockerfile index 4785f1dd..807b77d6 100644 --- a/dockerfiles/ingress-pipy/Dockerfile +++ b/dockerfiles/ingress-pipy/Dockerfile @@ -22,7 +22,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \ CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH make build/ingress-pipy # Build the final image -FROM flomesh/pipy:0.90.0-185-$DISTROLESS_TAG +FROM flomesh/pipy:0.90.1-157-$DISTROLESS_TAG WORKDIR / COPY --from=builder /workspace/bin/ingress-pipy . diff --git a/go.mod b/go.mod index 4f332a0b..9bd0e647 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/fatih/color v1.13.0 github.com/ghodss/yaml v1.0.0 github.com/gin-gonic/gin v1.7.7 + github.com/go-co-op/gocron v1.30.1 github.com/go-playground/validator/v10 v10.4.1 github.com/go-resty/resty/v2 v2.7.0 github.com/jetstack/cert-manager v1.7.3 @@ -132,6 +133,7 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rubenv/sql-migrate v1.1.2 // indirect github.com/russross/blackfriday v1.5.2 // indirect github.com/shopspring/decimal v1.2.0 // indirect @@ -147,7 +149,7 @@ require ( github.com/xlab/treeprint v1.1.0 // indirect go.etcd.io/etcd/api/v3 v3.5.4 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - go.uber.org/atomic v1.7.0 // indirect + go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.21.0 // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect diff --git a/go.sum b/go.sum index 9279e6d8..92571687 100644 --- a/go.sum +++ b/go.sum @@ -207,6 +207,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/go-co-op/gocron v1.30.1 h1:tjWUvJl5KrcwpkEkSXFSQFr4F9h5SfV/m4+RX0cV2fs= +github.com/go-co-op/gocron v1.30.1/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -435,6 +437,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -580,10 +583,14 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rubenv/sql-migrate v1.1.2 h1:9M6oj4e//owVVHYrFISmY9LBRw6gzkCNmD9MV36tZeQ= github.com/rubenv/sql-migrate v1.1.2/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= @@ -622,14 +629,19 @@ github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo= @@ -678,8 +690,9 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= diff --git a/pkg/cache/local_cache.go b/pkg/cache/local_cache.go index ea718216..15b9f6bc 100644 --- a/pkg/cache/local_cache.go +++ b/pkg/cache/local_cache.go @@ -228,7 +228,12 @@ func (c *LocalCache) syncRoutes() { serviceRoutes := c.buildServiceRoutes() klog.V(5).Infof("Service Routes:\n %#v", serviceRoutes) - if c.serviceRoutesVersion != serviceRoutes.Hash { + + exists := c.repoClient.CodebaseExists(mc.GetDefaultServicesPath()) + if !exists { + c.serviceRoutesVersion = fmt.Sprintf("%d", time.Now().UnixMilli()) + } + if c.serviceRoutesVersion != serviceRoutes.Hash && exists { klog.V(5).Infof("Service Routes changed, old hash=%q, new hash=%q", c.serviceRoutesVersion, serviceRoutes.Hash) batches := serviceBatches(serviceRoutes, mc) if batches != nil { @@ -249,7 +254,11 @@ func (c *LocalCache) syncRoutes() { ingressRoutes := c.buildIngressConfig() klog.V(5).Infof("Ingress Routes:\n %#v", ingressRoutes) - if c.ingressRoutesVersion != ingressRoutes.Hash { + exists = c.repoClient.CodebaseExists(mc.GetDefaultIngressPath()) + if !exists { + c.ingressRoutesVersion = fmt.Sprintf("%d", time.Now().UnixMilli()) + } + if c.ingressRoutesVersion != ingressRoutes.Hash && exists { klog.V(5).Infof("Ingress Routes changed, old hash=%q, new hash=%q", c.ingressRoutesVersion, ingressRoutes.Hash) batches := c.ingressBatches(ingressRoutes, mc) if batches != nil { diff --git a/pkg/cluster/local.go b/pkg/cluster/local.go index d5d190c4..c4df0a99 100644 --- a/pkg/cluster/local.go +++ b/pkg/cluster/local.go @@ -111,12 +111,12 @@ func (c *LocalConnector) ensureCodebaseDerivatives() error { repoClient := repo.NewRepoClient(mc.RepoRootURL()) defaultServicesPath := mc.GetDefaultServicesPath() - if err := repoClient.DeriveCodebase(defaultServicesPath, commons.DefaultServiceBasePath); err != nil { + if _, err := repoClient.DeriveCodebase(defaultServicesPath, commons.DefaultServiceBasePath); err != nil { return err } defaultIngressPath := mc.GetDefaultIngressPath() - if err := repoClient.DeriveCodebase(defaultIngressPath, commons.DefaultIngressBasePath); err != nil { + if _, err := repoClient.DeriveCodebase(defaultIngressPath, commons.DefaultIngressBasePath); err != nil { return err } diff --git a/pkg/config/mesh.go b/pkg/config/mesh.go index 7105bd7c..737f29eb 100644 --- a/pkg/config/mesh.go +++ b/pkg/config/mesh.go @@ -62,7 +62,8 @@ type MeshConfig struct { } type Repo struct { - RootURL string `json:"rootURL" validate:"required,url"` + RootURL string `json:"rootURL" validate:"required,url"` + RecoverIntervalInSeconds uint32 `json:"recoverIntervalInSeconds" validate:"gte=1,lte=3600"` } type Images struct { diff --git a/pkg/config/utils/version.go b/pkg/config/utils/version.go new file mode 100644 index 00000000..9bf28213 --- /dev/null +++ b/pkg/config/utils/version.go @@ -0,0 +1,24 @@ +package utils + +import ( + "github.com/flomesh-io/fsm-classic/pkg/config" + "github.com/flomesh-io/fsm-classic/pkg/repo" + "github.com/tidwall/sjson" + "k8s.io/klog/v2" + "time" +) + +func UpdateMainVersion(basepath string, repoClient *repo.PipyRepoClient, mc *config.MeshConfig) error { + json, err := getMainJson(basepath, repoClient) + if err != nil { + return err + } + + newJson, err := sjson.Set(json, "version", time.Now().UnixMilli()) + if err != nil { + klog.Errorf("Failed to update HTTP config: %s", err) + return err + } + + return updateMainJson(basepath, repoClient, newJson) +} diff --git a/pkg/repo/client.go b/pkg/repo/client.go index 78bac4be..c844eb0d 100644 --- a/pkg/repo/client.go +++ b/pkg/repo/client.go @@ -78,7 +78,7 @@ func newRepoClientWithRepoRootUrlAndTransport(repoRootUrl string, transport *htt return repo } -func (p *PipyRepoClient) isCodebaseExists(path string) (bool, *Codebase) { +func (p *PipyRepoClient) codebaseExists(path string) (bool, *Codebase) { resp, err := p.httpClient.R(). SetResult(&Codebase{}). Get(fullRepoApiPath(path)) @@ -133,7 +133,7 @@ func (p *PipyRepoClient) createCodebase(path string) (*Codebase, error) { } func (p *PipyRepoClient) deriveCodebase(path, base string) (*Codebase, error) { - exists, _ := p.isCodebaseExists(base) + exists, _ := p.codebaseExists(base) if !exists { return nil, fmt.Errorf("parent %q of codebase %q doesn't exists", base, path) } @@ -246,7 +246,7 @@ func (p *PipyRepoClient) Batch(batches []Batch) error { // 1. batch.Basepath, if not exists, create it klog.V(5).Infof("batch.Basepath = %q", batch.Basepath) var version = int64(-1) - exists, codebase := p.isCodebaseExists(batch.Basepath) + exists, codebase := p.codebaseExists(batch.Basepath) if exists { // just get the version of codebase version = codebase.Version @@ -292,30 +292,31 @@ func (p *PipyRepoClient) Batch(batches []Batch) error { return nil } -func (p *PipyRepoClient) DeriveCodebase(path, base string) error { +func (p *PipyRepoClient) DeriveCodebase(path, base string) (bool, error) { klog.V(5).Infof("Checking if exists, codebase %q", path) - exists, _ := p.isCodebaseExists(path) + exists, _ := p.codebaseExists(path) if exists { klog.V(5).Infof("Codebase %q already exists, ignore deriving ...", path) + return false, nil } else { klog.V(5).Infof("Codebase %q doesn't exist, deriving ...", path) result, err := p.deriveCodebase(path, base) if err != nil { klog.Errorf("Deriving codebase %q error: %#v", path, err) - return err + return false, err } klog.V(5).Infof("Successfully derived codebase %q", path) klog.V(5).Infof("Committing the changes of codebase %q", path) if err = p.commit(path, result.Version); err != nil { klog.Errorf("Committing codebase %q error: %#v", path, err) - return err + return false, err } klog.V(5).Infof("Successfully committed codebase %q", path) } - return nil + return true, nil } func (p *PipyRepoClient) IsRepoUp() bool { @@ -328,6 +329,12 @@ func (p *PipyRepoClient) IsRepoUp() bool { return true } +func (p *PipyRepoClient) CodebaseExists(path string) bool { + exists, _ := p.codebaseExists(path) + + return exists +} + func fullRepoApiPath(path string) string { return fmt.Sprintf("%s%s", commons.DefaultPipyRepoApiPath, path) } diff --git a/samples/ingress/001-routing.yaml b/samples/ingress/001-routing.yaml index 483be4f6..61e67516 100644 --- a/samples/ingress/001-routing.yaml +++ b/samples/ingress/001-routing.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: pipy-ok - image: flomesh/pipy:0.90.0-185 + image: flomesh/pipy:0.90.1-157 ports: - name: pipy containerPort: 8080 diff --git a/samples/ingress/300-ingress-tls.yaml b/samples/ingress/300-ingress-tls.yaml index dca4a1eb..0d1e4259 100644 --- a/samples/ingress/300-ingress-tls.yaml +++ b/samples/ingress/300-ingress-tls.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: pipy-ok-tls - image: flomesh/pipy:0.90.0-185 + image: flomesh/pipy:0.90.1-157 ports: - name: pipy containerPort: 8080 diff --git a/samples/multi-cluster/001-pipy-deployment.yaml b/samples/multi-cluster/001-pipy-deployment.yaml index 391e7561..e3b08628 100644 --- a/samples/multi-cluster/001-pipy-deployment.yaml +++ b/samples/multi-cluster/001-pipy-deployment.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: pipy-ok - image: flomesh/pipy:0.90.0-185 + image: flomesh/pipy:0.90.1-157 ports: - name: pipy containerPort: 8080 diff --git a/samples/session-sticky/001.yaml b/samples/session-sticky/001.yaml index e3f170d5..9d4d451d 100644 --- a/samples/session-sticky/001.yaml +++ b/samples/session-sticky/001.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: pipy-ok - image: flomesh/pipy:0.90.0-185-nonroot + image: flomesh/pipy:0.90.1-157-nonroot ports: - name: pipy containerPort: 8080 diff --git a/samples/session-sticky/pipy-nonroot.yaml b/samples/session-sticky/pipy-nonroot.yaml index cba0ef9d..19655a74 100644 --- a/samples/session-sticky/pipy-nonroot.yaml +++ b/samples/session-sticky/pipy-nonroot.yaml @@ -48,7 +48,7 @@ spec: topologyKey: kubernetes.io/hostname weight: 100 containers: - - image: flomesh/pipy:0.90.0-185-debug-nonroot + - image: flomesh/pipy:0.90.1-157-debug-nonroot imagePullPolicy: Always name: pipy-nonroot command: diff --git a/samples/session-sticky/pipy.yaml b/samples/session-sticky/pipy.yaml index 69f75720..3b55d419 100644 --- a/samples/session-sticky/pipy.yaml +++ b/samples/session-sticky/pipy.yaml @@ -46,7 +46,7 @@ spec: topologyKey: kubernetes.io/hostname weight: 100 containers: - - image: flomesh/pipy:0.90.0-185 + - image: flomesh/pipy:0.90.1-157 imagePullPolicy: Always name: pipy command: diff --git a/samples/session-sticky/values.yaml b/samples/session-sticky/values.yaml index 4e3b5fe0..5c983400 100644 --- a/samples/session-sticky/values.yaml +++ b/samples/session-sticky/values.yaml @@ -3,4 +3,4 @@ fsm: image: pullPolicy: Always pipy: - tag: 0.90.0-185-debug-nonroot \ No newline at end of file + tag: 0.90.1-157-debug-nonroot \ No newline at end of file diff --git a/samples/setup/k3d/cluster1.yaml b/samples/setup/k3d/cluster1.yaml index 2b92a81d..10cce935 100644 --- a/samples/setup/k3d/cluster1.yaml +++ b/samples/setup/k3d/cluster1.yaml @@ -1,5 +1,5 @@ # k3d configuration file, saved as e.g. /home/me/myk3dcluster.yaml -apiVersion: k3d.io/v1alpha4 # this will change in the future as we make everything more stable +apiVersion: k3d.io/v1alpha5 # this will change in the future as we make everything more stable kind: Simple # internally, we also have a Cluster config, which is not yet available externally metadata: name: cluster1 # name that you want to give to your cluster (will still be prefixed with `k3d-`) diff --git a/samples/setup/k3d/cluster2.yaml b/samples/setup/k3d/cluster2.yaml index 059ead91..0a4fed51 100644 --- a/samples/setup/k3d/cluster2.yaml +++ b/samples/setup/k3d/cluster2.yaml @@ -1,5 +1,5 @@ # k3d configuration file, saved as e.g. /home/me/myk3dcluster.yaml -apiVersion: k3d.io/v1alpha4 # this will change in the future as we make everything more stable +apiVersion: k3d.io/v1alpha5 # this will change in the future as we make everything more stable kind: Simple # internally, we also have a Cluster config, which is not yet available externally metadata: name: cluster2 # name that you want to give to your cluster (will still be prefixed with `k3d-`) diff --git a/samples/setup/k3d/control-plane.yaml b/samples/setup/k3d/control-plane.yaml index 820fd752..1ea9f936 100644 --- a/samples/setup/k3d/control-plane.yaml +++ b/samples/setup/k3d/control-plane.yaml @@ -1,5 +1,5 @@ # k3d configuration file, saved as e.g. /home/me/myk3dcluster.yaml -apiVersion: k3d.io/v1alpha4 # this will change in the future as we make everything more stable +apiVersion: k3d.io/v1alpha5 # this will change in the future as we make everything more stable kind: Simple # internally, we also have a Cluster config, which is not yet available externally metadata: name: control-plane # name that you want to give to your cluster (will still be prefixed with `k3d-`)