From 5245d4281c03effaf408e95aacb4d8f0f3435ed6 Mon Sep 17 00:00:00 2001 From: Leonardo Cecchi Date: Thu, 15 Feb 2024 12:52:52 +0100 Subject: [PATCH] feat: use cnpg-i machinery (#8) Signed-off-by: Armando Ruocco Signed-off-by: Marco Nenciarini Co-authored-by: Armando Ruocco Co-authored-by: Marco Nenciarini --- go.mod | 15 +- go.sum | 2 + internal/backup/backup.go | 4 +- internal/backup/executor/controldata.go | 3 +- internal/backup/executor/executor.go | 3 +- internal/backup/executor/repository.go | 3 +- internal/operator/mutations.go | 2 +- internal/operator/validation.go | 2 +- internal/wal/status.go | 4 +- internal/wal/wal.go | 4 +- main.go | 2 +- pkg/logging/doc.go | 18 --- pkg/logging/logging.go | 64 -------- pkg/pluginhelper/doc.go | 19 --- pkg/pluginhelper/helper.go | 200 ------------------------ pkg/pluginhelper/server.go | 197 ----------------------- 16 files changed, 23 insertions(+), 519 deletions(-) delete mode 100644 pkg/logging/doc.go delete mode 100644 pkg/logging/logging.go delete mode 100644 pkg/pluginhelper/doc.go delete mode 100644 pkg/pluginhelper/helper.go delete mode 100644 pkg/pluginhelper/server.go diff --git a/go.mod b/go.mod index 3442548..6761a98 100644 --- a/go.mod +++ b/go.mod @@ -7,13 +7,7 @@ toolchain go1.21.6 require ( github.com/cloudnative-pg/cloudnative-pg v1.22.1-0.20240123130737-a22a155b9eb8 github.com/cloudnative-pg/cnpg-i v0.0.0-20240202130713-14050b29b7a2 - github.com/evanphx/json-patch/v5 v5.8.1 - github.com/go-logr/logr v1.3.0 - github.com/go-logr/zapr v1.2.4 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 - github.com/spf13/cobra v1.8.0 - github.com/spf13/viper v1.14.0 - go.uber.org/zap v1.26.0 + github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20240215100236-082604edc33a google.golang.org/grpc v1.60.1 k8s.io/api v0.28.4 k8s.io/apimachinery v0.28.4 @@ -26,7 +20,10 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/evanphx/json-patch/v5 v5.8.1 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/zapr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -38,6 +35,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/uuid v1.5.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -70,11 +68,14 @@ require ( github.com/robfig/cron v1.2.0 // indirect github.com/spf13/afero v1.9.2 // indirect github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.14.0 // indirect github.com/subosito/gotenv v1.4.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.18.0 // indirect golang.org/x/exp v0.0.0-20231219160207-73b9e39aefca // indirect golang.org/x/net v0.20.0 // indirect diff --git a/go.sum b/go.sum index 55989db..c218e44 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,8 @@ github.com/cloudnative-pg/cloudnative-pg v1.22.1-0.20240123130737-a22a155b9eb8 h github.com/cloudnative-pg/cloudnative-pg v1.22.1-0.20240123130737-a22a155b9eb8/go.mod h1:r6blheO2ihiuqKbk6rqPN5//PPJnYtKCGT2OxpXtk2o= github.com/cloudnative-pg/cnpg-i v0.0.0-20240202130713-14050b29b7a2 h1:7Cow1BF5rM3k7q+QYjJsPiYGZTK8w+uTGa4VZ3IbBpk= github.com/cloudnative-pg/cnpg-i v0.0.0-20240202130713-14050b29b7a2/go.mod h1:0G5GXQVj09KvONIcYURyroL74zOFGjv4eI5OXz7/G/0= +github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20240215100236-082604edc33a h1:ccAuhOYdWRuPXNDOq4OuLOInfJAKPTvxmVd/FINiET4= +github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20240215100236-082604edc33a/go.mod h1:A2Zx68zGuz6N/mv/1Jxgn9D6fV9Uc+wA58knRrEHwfo= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= diff --git a/internal/backup/backup.go b/internal/backup/backup.go index 6046d88..1630344 100644 --- a/internal/backup/backup.go +++ b/internal/backup/backup.go @@ -4,13 +4,13 @@ import ( "context" "time" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/logging" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper" "github.com/cloudnative-pg/cnpg-i/pkg/backup" "github.com/cloudnative-pg/plugin-pvc-backup/internal/backup/executor" "github.com/cloudnative-pg/plugin-pvc-backup/internal/backup/storage" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/logging" "github.com/cloudnative-pg/plugin-pvc-backup/pkg/metadata" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/pluginhelper" ) // Implementation is the implementation of the identity service diff --git a/internal/backup/executor/controldata.go b/internal/backup/executor/controldata.go index 3cd5289..037d9d6 100644 --- a/internal/backup/executor/controldata.go +++ b/internal/backup/executor/controldata.go @@ -11,8 +11,7 @@ import ( "github.com/cloudnative-pg/cloudnative-pg/pkg/management/url" "github.com/cloudnative-pg/cloudnative-pg/pkg/utils" - - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/logging" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/logging" ) // getPgControlData obtains the pg_controldata from the instance HTTP endpoint diff --git a/internal/backup/executor/executor.go b/internal/backup/executor/executor.go index e4bf2a6..0de87a0 100644 --- a/internal/backup/executor/executor.go +++ b/internal/backup/executor/executor.go @@ -10,10 +10,9 @@ import ( apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" "github.com/cloudnative-pg/cloudnative-pg/pkg/management/postgres/webserver" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/logging" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/util/retry" - - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/logging" ) var ( diff --git a/internal/backup/executor/repository.go b/internal/backup/executor/repository.go index 0080e0f..093bf21 100644 --- a/internal/backup/executor/repository.go +++ b/internal/backup/executor/repository.go @@ -6,8 +6,9 @@ import ( "os/exec" "path" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/logging" + "github.com/cloudnative-pg/plugin-pvc-backup/internal/fileutils" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/logging" ) const ( diff --git a/internal/operator/mutations.go b/internal/operator/mutations.go index 125f340..d9c607e 100644 --- a/internal/operator/mutations.go +++ b/internal/operator/mutations.go @@ -19,11 +19,11 @@ package operator import ( "context" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper" "github.com/cloudnative-pg/cnpg-i/pkg/operator" corev1 "k8s.io/api/core/v1" "github.com/cloudnative-pg/plugin-pvc-backup/pkg/metadata" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/pluginhelper" ) // MutateCluster is called to mutate a cluster with the defaulting webhook. diff --git a/internal/operator/validation.go b/internal/operator/validation.go index aa1b64e..98ead39 100644 --- a/internal/operator/validation.go +++ b/internal/operator/validation.go @@ -20,10 +20,10 @@ import ( "context" "fmt" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper" "github.com/cloudnative-pg/cnpg-i/pkg/operator" "github.com/cloudnative-pg/plugin-pvc-backup/pkg/metadata" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/pluginhelper" ) const ( diff --git a/internal/wal/status.go b/internal/wal/status.go index cdf62be..a600e0e 100644 --- a/internal/wal/status.go +++ b/internal/wal/status.go @@ -23,12 +23,12 @@ import ( "os" "path" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/logging" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper" "github.com/cloudnative-pg/cnpg-i/pkg/wal" "github.com/cloudnative-pg/plugin-pvc-backup/internal/backup/storage" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/logging" "github.com/cloudnative-pg/plugin-pvc-backup/pkg/metadata" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/pluginhelper" ) type walStatMode string diff --git a/internal/wal/wal.go b/internal/wal/wal.go index da3fefa..9fe9998 100644 --- a/internal/wal/wal.go +++ b/internal/wal/wal.go @@ -20,13 +20,13 @@ import ( "context" "path" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/logging" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper" "github.com/cloudnative-pg/cnpg-i/pkg/wal" "github.com/cloudnative-pg/plugin-pvc-backup/internal/backup/storage" "github.com/cloudnative-pg/plugin-pvc-backup/internal/fileutils" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/logging" "github.com/cloudnative-pg/plugin-pvc-backup/pkg/metadata" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/pluginhelper" ) // Archive copies one WAL file into the archive diff --git a/main.go b/main.go index 8ac3e5e..e0a5dad 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,7 @@ import ( "fmt" "os" + "github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper" "github.com/cloudnative-pg/cnpg-i/pkg/backup" "github.com/cloudnative-pg/cnpg-i/pkg/operator" "github.com/cloudnative-pg/cnpg-i/pkg/wal" @@ -30,7 +31,6 @@ import ( "github.com/cloudnative-pg/plugin-pvc-backup/internal/identity" operatorImpl "github.com/cloudnative-pg/plugin-pvc-backup/internal/operator" walImpl "github.com/cloudnative-pg/plugin-pvc-backup/internal/wal" - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/pluginhelper" ) func main() { diff --git a/pkg/logging/doc.go b/pkg/logging/doc.go deleted file mode 100644 index b346242..0000000 --- a/pkg/logging/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright The CloudNativePG Contributors - -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 logging is the logging infrastructure -package logging diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go deleted file mode 100644 index ce68774..0000000 --- a/pkg/logging/logging.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright The CloudNativePG Contributors - -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 logging - -import ( - "context" - "fmt" - - "github.com/go-logr/logr" - "github.com/go-logr/zapr" - "go.uber.org/zap" -) - -type loggerKeyType string - -const loggerKey = loggerKeyType("logger") - -func newLogger(debug bool) logr.Logger { - var zapLog *zap.Logger - var err error - - if debug { - zapLog, err = zap.NewDevelopment() - } else { - zapLog, err = zap.NewProduction() - } - if err != nil { - panic(fmt.Sprintf("who watches the watchmen (%v)?", err)) - } - - result := zapr.NewLogger(zapLog) - return result -} - -// IntoContext injects the logger into this context, returning -// a context having the logger embedded. The logger can be recovered -// with FromContext -func IntoContext(ctx context.Context, debug bool) context.Context { - return context.WithValue(ctx, loggerKey, newLogger(debug)) -} - -// FromContext get the logger from thecontext -func FromContext(ctx context.Context) logr.Logger { - preValue := ctx.Value(loggerKey) - if preValue == nil { - return newLogger(false) - } - - return preValue.(logr.Logger) -} diff --git a/pkg/pluginhelper/doc.go b/pkg/pluginhelper/doc.go deleted file mode 100644 index bda5081..0000000 --- a/pkg/pluginhelper/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright The CloudNativePG Contributors - -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 pluginhelper contains some helper functions to quickly -// implement CNPG-I plugins -package pluginhelper diff --git a/pkg/pluginhelper/helper.go b/pkg/pluginhelper/helper.go deleted file mode 100644 index eaa3287..0000000 --- a/pkg/pluginhelper/helper.go +++ /dev/null @@ -1,200 +0,0 @@ -/* -Copyright The CloudNativePG Contributors - -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 pluginhelper - -import ( - "encoding/json" - "strconv" - - apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" - "github.com/cloudnative-pg/cnpg-i/pkg/operator" - jsonpatch "github.com/evanphx/json-patch/v5" - corev1 "k8s.io/api/core/v1" -) - -const ( - pluginVolumeName = "plugins" - pluginMountPath = "/plugins" -) - -// Data is an helper structure to be used by -// plugins wanting to enhance the CNPG validating webhooks -type Data struct { - // Parameters are the configuration parameters of this plugin - Parameters map[string]string - - cluster apiv1.Cluster - pod corev1.Pod - pluginIndex int -} - -// DataBuilder a fluent constructor for the Data struct -type DataBuilder struct { - pluginName string - clusterJSON []byte - podJSON []byte -} - -// NewDataBuilder initializes a basic DataBuilder -func NewDataBuilder(pluginName string, clusterJSON []byte) *DataBuilder { - d := DataBuilder{clusterJSON: clusterJSON, pluginName: pluginName} - d.clusterJSON = clusterJSON - return &d -} - -// WithPod adds Pod data to the DataBuilder -func (d *DataBuilder) WithPod(podJSON []byte) *DataBuilder { - d.podJSON = podJSON - return d -} - -// Build returns the constructed Data object and any errors encountered -func (d *DataBuilder) Build() (*Data, error) { - result := &Data{} - - if err := json.Unmarshal(d.clusterJSON, &result.cluster); err != nil { - return nil, err - } - - if len(d.podJSON) > 0 { - if err := json.Unmarshal(d.podJSON, &result.pod); err != nil { - return nil, err - } - } - - result.pluginIndex = -1 - for idx, cfg := range result.cluster.Spec.Plugins { - if cfg.Name == d.pluginName { - result.pluginIndex = idx - result.Parameters = cfg.Parameters - } - } - - return result, nil -} - -// GetCluster gets the decoded cluster object -func (helper *Data) GetCluster() *apiv1.Cluster { - return &helper.cluster -} - -// GetPod gets the decoded pod object -func (helper *Data) GetPod() *corev1.Pod { - return &helper.pod -} - -// CreateClusterJSONPatch creates a JSON patch changing the cluster -// that was loaded into this helper into the -func (helper *Data) CreateClusterJSONPatch(newCluster apiv1.Cluster) ([]byte, error) { - originalCluster, err := json.Marshal(helper.cluster) - if err != nil { - return nil, err - } - - currentCluster, err := json.Marshal(newCluster) - if err != nil { - return nil, err - } - - return jsonpatch.CreateMergePatch(originalCluster, currentCluster) -} - -// CreatePodJSONPatch creates a JSON patch changing the cluster -// that was loaded into this helper into the -func (helper *Data) CreatePodJSONPatch(newPod corev1.Pod) ([]byte, error) { - originalPod, err := json.Marshal(helper.pod) - if err != nil { - return nil, err - } - - currentPod, err := json.Marshal(newPod) - if err != nil { - return nil, err - } - - return jsonpatch.CreateMergePatch(originalPod, currentPod) -} - -// ValidationErrorForParameter creates a validation error for a certain plugin -// parameter -func (helper *Data) ValidationErrorForParameter(name, message string) *operator.ValidationError { - if helper.pluginIndex == -1 { - return &operator.ValidationError{ - PathComponents: []string{ - "spec", - "plugins", - name, - }, - Message: message, - } - } - - return &operator.ValidationError{ - PathComponents: []string{ - "spec", - "plugins", - strconv.Itoa(helper.pluginIndex), - name, - }, - Message: message, - Value: helper.Parameters[name], - } -} - -// InjectPluginVolume injects the plugin volume into a CNPG Pod -func (*Data) InjectPluginVolume(pod *corev1.Pod) { - foundPluginVolume := false - for i := range pod.Spec.Volumes { - if pod.Spec.Volumes[i].Name == pluginVolumeName { - foundPluginVolume = true - } - } - - if foundPluginVolume { - return - } - - pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ - Name: pluginVolumeName, - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }) - - for i := range pod.Spec.Containers { - if pod.Spec.Containers[i].Name == "postgres" { - pod.Spec.Containers[i].VolumeMounts = append( - pod.Spec.Containers[i].VolumeMounts, - corev1.VolumeMount{ - Name: pluginVolumeName, - MountPath: pluginMountPath, - }, - ) - } - } -} - -// DecodeBackup decodes a JSON representation of a backup -func (*Data) DecodeBackup(backupDefinition []byte) (*apiv1.Backup, error) { - var backup apiv1.Backup - - if err := json.Unmarshal(backupDefinition, &backup); err != nil { - return nil, err - } - - return &backup, nil -} diff --git a/pkg/pluginhelper/server.go b/pkg/pluginhelper/server.go deleted file mode 100644 index 087416e..0000000 --- a/pkg/pluginhelper/server.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright The CloudNativePG Contributors - -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 pluginhelper - -import ( - "context" - "errors" - "net" - "os" - "os/signal" - "path" - "syscall" - - "github.com/cloudnative-pg/cnpg-i/pkg/identity" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "google.golang.org/grpc" - - "github.com/cloudnative-pg/plugin-pvc-backup/pkg/logging" -) - -const unixNetwork = "unix" - -// ServerEnricher is the type of functions that can add register -// service implementations in a GRPC server -type ServerEnricher func(*grpc.Server) - -// CreateMainCmd creates a command to be used as the server side -// for the CNPG-I infrastructure -func CreateMainCmd(identityImpl identity.IdentityServer, enrichers ...ServerEnricher) *cobra.Command { - cmd := &cobra.Command{ - Use: "pvc-backup", - PersistentPreRun: func(cmd *cobra.Command, _ []string) { - ctx := logging.IntoContext( - cmd.Context(), - viper.GetBool("debug")) - cmd.SetContext(ctx) - }, - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { - return run(cmd.Context(), identityImpl, enrichers...) - }, - } - - cmd.PersistentFlags().Bool( - "debug", - true, - "Enable debugging mode", - ) - _ = viper.BindPFlag("debug", cmd.PersistentFlags().Lookup("debug")) - - cmd.Flags().String( - "plugin-path", - "/plugins", - "The plugins socket path", - ) - _ = viper.BindPFlag("plugin-path", cmd.Flags().Lookup("plugin-path")) - - return cmd -} - -// run starts listining for GRPC requests -func run(ctx context.Context, identityImpl identity.IdentityServer, enrichers ...ServerEnricher) error { - logger := logging.FromContext(ctx) - - identityResponse, err := identityImpl.GetPluginMetadata( - ctx, - &identity.GetPluginMetadataRequest{}) - if err != nil { - logger.Error(err, "Error while querying the identity service") - return err - } - - pluginPath := viper.GetString("plugin-path") - pluginName := identityResponse.Name - pluginDisplayName := identityResponse.DisplayName - pluginVersion := identityResponse.Version - socketName := path.Join(pluginPath, identityResponse.Name) - - // Remove stale unix socket it still existent - if err := removeStaleSocket(ctx, socketName); err != nil { - logger.Error(err, "While removing old unix socket") - return err - } - - // Start accepting connections on the socket - listener, err := net.Listen( - unixNetwork, - socketName, - ) - if err != nil { - logger.Error(err, "While starting server") - return err - } - - // Handle quit-like signal - handleSignals(ctx, listener) - - // Create GRPC server - grpcServer := grpc.NewServer( - grpc.ChainUnaryInterceptor( - recovery.UnaryServerInterceptor(recovery.WithRecoveryHandlerContext(panicRecoveryHandler(listener))), - ), - grpc.ChainStreamInterceptor( - recovery.StreamServerInterceptor(recovery.WithRecoveryHandlerContext(panicRecoveryHandler(listener))), - ), - ) - identity.RegisterIdentityServer( - grpcServer, - identityImpl) - for _, enrich := range enrichers { - enrich(grpcServer) - } - - logger.Info( - "Starting plugin", - "path", pluginPath, - "name", pluginName, - "displayName", pluginDisplayName, - "version", pluginVersion, - "socketName", socketName, - ) - - if err = grpcServer.Serve(listener); !errors.Is(err, net.ErrClosed) { - logger.Error(err, "While terminating server") - } - - return nil -} - -// removeStaleSocket removes a stale unix domain socket -func removeStaleSocket(ctx context.Context, pluginPath string) error { - logger := logging.FromContext(ctx) - _, err := os.Stat(pluginPath) - - switch { - case err == nil: - logger.Info("Removing stale socket", "pluginPath", pluginPath) - return os.Remove(pluginPath) - - case errors.Is(err, os.ErrNotExist): - return nil - - default: - return err - } -} - -// handleSignals makes sure that we close the listening socket -// when we receive a quit-like signal -func handleSignals(ctx context.Context, listener net.Listener) { - logger := logging.FromContext(ctx) - - sigc := make(chan os.Signal, 1) - signal.Notify(sigc, syscall.SIGTERM, syscall.SIGABRT, syscall.SIGINT) - go func(c chan os.Signal) { - sig := <-c - logger.Info( - "Caught signal, shutting down.", - "signal", sig.String()) - - if err := listener.Close(); err != nil { - logger.Error(err, "While stopping server") - } - - os.Exit(1) - }(sigc) -} - -func panicRecoveryHandler(listener net.Listener) recovery.RecoveryHandlerFuncContext { - return func(ctx context.Context, err any) error { - logger := logging.FromContext(ctx) - logger.Info("Panic occurred", "error", err) - - if closeError := listener.Close(); closeError != nil { - logger.Error(closeError, "While stopping server") - } - - os.Exit(1) - return nil - } -}