diff --git a/docker/postgres-kanister-tools/requirements.txt b/docker/postgres-kanister-tools/requirements.txt index 9887c7d51b..e1e713f440 100644 --- a/docker/postgres-kanister-tools/requirements.txt +++ b/docker/postgres-kanister-tools/requirements.txt @@ -1,4 +1,4 @@ -awscli==1.35.20 +awscli==1.36.10 pip==24.3.1 -setuptools==75.3.0 -wheel==0.44.0 +setuptools==75.6.0 +wheel==0.45.1 diff --git a/docker/postgresql/requirements.txt b/docker/postgresql/requirements.txt index 5bfbb11d44..fdc1cfa954 100644 --- a/docker/postgresql/requirements.txt +++ b/docker/postgresql/requirements.txt @@ -1,5 +1,5 @@ -awscli==1.35.20 +awscli==1.36.10 wal-e==1.1.1 pip==24.3.1 -setuptools==75.3.0 -wheel==0.44.0 +setuptools==75.6.0 +wheel==0.45.1 diff --git a/go.mod b/go.mod index e1f59430b5..eb769139b6 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/jpillora/backoff v1.0.0 github.com/json-iterator/go v1.1.12 github.com/kanisterio/errkit v0.0.2 - github.com/kanisterio/safecli v0.0.8 + github.com/kanisterio/safecli v0.0.9 github.com/kopia/kopia v0.17.1-0.20240927044625-1bceb7155ede github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0 github.com/lib/pq v1.10.9 diff --git a/go.sum b/go.sum index 7512c046b2..efe981418e 100644 --- a/go.sum +++ b/go.sum @@ -375,8 +375,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kanisterio/errkit v0.0.2 h1:3v3HGz9lHIbZR6Jr9qIJpRjaqUX0rsJSLMEQGsMHiUk= github.com/kanisterio/errkit v0.0.2/go.mod h1:ViQ6kPJ2gTJDEvRytmwde7pzG9/sndObF9BPZoEZixc= -github.com/kanisterio/safecli v0.0.8 h1:flvTiGksy/a0+zvqjaBSJwxESu/nFcG65yttmR0XwiA= -github.com/kanisterio/safecli v0.0.8/go.mod h1:KBraqj8mdv2cwAr9wecknGUb8jztTzUik0r7uE6yRA8= +github.com/kanisterio/safecli v0.0.9 h1:MBjXbS82fWhGUaOX1MP+xGyTcouh1GRzzu4EzqQV0rY= +github.com/kanisterio/safecli v0.0.9/go.mod h1:y1oYVoT2eqsmySCIS5yOzrxaYVywlMSEdWEKfLhBjgs= github.com/kastenhq/check v0.0.0-20180626002341-0264cfcea734 h1:qulsCaCv+O2y9/sQ9nd5KChnAgFOWakTHQ9ZADjs6DQ= github.com/kastenhq/check v0.0.0-20180626002341-0264cfcea734/go.mod h1:rdqSnvOJuKCPFW/h2rVLuXOAkRnHHdp9PZcKx4HCoDM= github.com/kastenhq/stow v0.2.6-kasten.1.0.20231101232131-9321daa23aae h1:2cl4yuAJpdmLCx7G8eIsfNlQBLEfw0JDj6mTTyqc5qg= diff --git a/pkg/apis/cr/v1alpha1/repositoryserver_types_test.go b/pkg/apis/cr/v1alpha1/repositoryserver_types_test.go index 0e051742f1..524d8328c5 100644 --- a/pkg/apis/cr/v1alpha1/repositoryserver_types_test.go +++ b/pkg/apis/cr/v1alpha1/repositoryserver_types_test.go @@ -17,7 +17,7 @@ package v1alpha1 import ( "testing" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -86,7 +86,7 @@ func getRepositoryServerFromSpec(spec []byte) (*RepositoryServer, error) { repositoryServer := &RepositoryServer{} d := serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer() if _, _, err := d.Decode([]byte(spec), nil, repositoryServer); err != nil { - return nil, errors.Wrap(err, "Failed to decode RepositoryServer") + return nil, errkit.Wrap(err, "Failed to decode RepositoryServer") } return repositoryServer, nil } diff --git a/pkg/apis/cr/v1alpha1/types_test.go b/pkg/apis/cr/v1alpha1/types_test.go index 6da1bc3d7d..6518183101 100644 --- a/pkg/apis/cr/v1alpha1/types_test.go +++ b/pkg/apis/cr/v1alpha1/types_test.go @@ -18,7 +18,7 @@ import ( "reflect" "testing" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -73,7 +73,7 @@ func getBlueprintFromSpec(spec []byte) (*Blueprint, error) { blueprint := &Blueprint{} d := serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer() if _, _, err := d.Decode([]byte(spec), nil, blueprint); err != nil { - return nil, errors.Wrap(err, "Failed to decode spec into object") + return nil, errkit.Wrap(err, "Failed to decode spec into object") } return blueprint, nil } diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index 24ffe5cb09..e67d6ef07a 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -549,12 +549,12 @@ func (s *AdStorage) SnapshotsList(ctx context.Context, tags map[string]string) ( return nil, errkit.Wrap(err, "SnapshotsClient.List in SnapshotsList") } for _, snap := range page.Value { - k10Snap, err := s.SnapshotParse(ctx, *snap) + parsedSnap, err := s.SnapshotParse(ctx, *snap) if err != nil { log.WithError(err).Print("Incorrect Snaphost type", field.M{"SnapshotID": snap.ID}) continue } - snaps = append(snaps, k10Snap) + snaps = append(snaps, parsedSnap) } } snaps = blockstorage.FilterSnapshotsWithTags(snaps, blockstorage.SanitizeTags(tags)) diff --git a/pkg/blockstorage/tags/tags.go b/pkg/blockstorage/tags/tags.go index ae99e2eec0..95dbb3faea 100644 --- a/pkg/blockstorage/tags/tags.go +++ b/pkg/blockstorage/tags/tags.go @@ -27,7 +27,7 @@ import ( const ( // ClusterTagKey is used to tag resources with the cluster name ClusterTagKey = "kanister.io/clustername" - // VersionTagKey is used to tag resources with the K10 version + // VersionTagKey is used to tag resources with a version VersionTagKey = "kanister.io/version" // AppNameTag is used to tag volumes with the app they belong to AppNameTag = "kanister.io/appname" diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 4e3c7f69a0..c1f5362d43 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -27,8 +27,8 @@ import ( "strings" "sync" + "github.com/kanisterio/errkit" osversioned "github.com/openshift/client-go/apps/clientset/versioned" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "gopkg.in/tomb.v2" corev1 "k8s.io/api/core/v1" @@ -86,23 +86,23 @@ func New(c *rest.Config, reg prometheus.Registerer) *Controller { func (c *Controller) StartWatch(ctx context.Context, namespace string) error { crClient, err := versioned.NewForConfig(c.config) if err != nil { - return errors.Wrap(err, "failed to get a CustomResource client") + return errkit.Wrap(err, "failed to get a CustomResource client") } if err := checkCRAccess(ctx, crClient, namespace); err != nil { return err } clientset, err := kubernetes.NewForConfig(c.config) if err != nil { - return errors.Wrap(err, "failed to get a k8s client") + return errkit.Wrap(err, "failed to get a k8s client") } dynClient, err := dynamic.NewForConfig(c.config) if err != nil { - return errors.Wrap(err, "failed to get a k8s dynamic client") + return errkit.Wrap(err, "failed to get a k8s dynamic client") } osClient, err := osversioned.NewForConfig(c.config) if err != nil { - return errors.Wrap(err, "failed to get a openshift client") + return errkit.Wrap(err, "failed to get a openshift client") } c.crClient = crClient @@ -134,13 +134,13 @@ func (c *Controller) StartWatch(ctx context.Context, namespace string) error { func checkCRAccess(ctx context.Context, cli versioned.Interface, ns string) error { if _, err := cli.CrV1alpha1().ActionSets(ns).List(ctx, metav1.ListOptions{}); err != nil { - return errors.Wrap(err, "Could not list ActionSets") + return errkit.Wrap(err, "Could not list ActionSets") } if _, err := cli.CrV1alpha1().Blueprints(ns).List(ctx, metav1.ListOptions{}); err != nil { - return errors.Wrap(err, "Could not list Blueprints") + return errkit.Wrap(err, "Could not list Blueprints") } if _, err := cli.CrV1alpha1().Profiles(ns).List(ctx, metav1.ListOptions{}); err != nil { - return errors.Wrap(err, "Could not list Profiles") + return errkit.Wrap(err, "Could not list Profiles") } return nil } @@ -220,7 +220,7 @@ func (c *Controller) onAddActionSet(ctx context.Context, t *tomb.Tomb, as *crv1a } as, err := c.crClient.CrV1alpha1().ActionSets(as.GetNamespace()).Get(ctx, as.GetName(), metav1.GetOptions{}) if err != nil { - return errors.WithStack(err) + return errkit.WithStack(err) } if err = validate.ActionSet(as); err != nil { return err @@ -313,13 +313,13 @@ func (c *Controller) initActionSetStatus(ctx context.Context, as *crv1alpha1.Act for _, a := range as.Spec.Actions { if a.Blueprint == "" { // TODO: If no blueprint is specified, we should consider a default. - err = errors.New("Blueprint is not specified for action") + err = errkit.New("Blueprint is not specified for action") c.logAndErrorEvent(ctx, "Could not get blueprint:", "Blueprint not specified", err, as) break } var bp *crv1alpha1.Blueprint if bp, err = c.crClient.CrV1alpha1().Blueprints(as.GetNamespace()).Get(ctx, a.Blueprint, metav1.GetOptions{}); err != nil { - err = errors.Wrap(err, "Failed to query blueprint") + err = errkit.Wrap(err, "Failed to query blueprint") c.logAndErrorEvent(ctx, "Could not get blueprint:", "Error", err, as) break } @@ -349,7 +349,7 @@ func (c *Controller) initActionSetStatus(ctx context.Context, as *crv1alpha1.Act func (c *Controller) initialActionStatus(a crv1alpha1.ActionSpec, bp *crv1alpha1.Blueprint) (*crv1alpha1.ActionStatus, error) { bpa, ok := bp.Actions[a.Name] if !ok { - return nil, errors.Errorf("Action %s for object kind %s not found in blueprint %s", a.Name, a.Object.Kind, a.Blueprint) + return nil, errkit.New(fmt.Sprintf("Action %s for object kind %s not found in blueprint %s", a.Name, a.Object.Kind, a.Blueprint)) } phases := make([]crv1alpha1.Phase, 0, len(bpa.Phases)) for _, p := range bpa.Phases { @@ -379,14 +379,14 @@ func (c *Controller) initialActionStatus(a crv1alpha1.ActionSpec, bp *crv1alpha1 func (c *Controller) handleActionSet(ctx context.Context, t *tomb.Tomb, as *crv1alpha1.ActionSet) (err error) { if as.Status == nil { - return errors.New("ActionSet was not initialized") + return errkit.New("ActionSet was not initialized") } if as.Status.State != crv1alpha1.StatePending { return nil } as.Status.State = crv1alpha1.StateRunning if as, err = c.crClient.CrV1alpha1().ActionSets(as.GetNamespace()).Update(ctx, as, metav1.UpdateOptions{}); err != nil { - return errors.WithStack(err) + return errkit.WithStack(err) } ctx = field.Context(ctx, consts.ActionsetNameKey, as.GetName()) // adding labels with prefix "kanister.io/" in the context as field for better logging @@ -399,7 +399,7 @@ func (c *Controller) handleActionSet(ctx context.Context, t *tomb.Tomb, as *crv1 for i, a := range as.Status.Actions { var bp *crv1alpha1.Blueprint if bp, err = c.crClient.CrV1alpha1().Blueprints(as.GetNamespace()).Get(ctx, a.Blueprint, metav1.GetOptions{}); err != nil { - err = errors.Wrap(err, "Failed to query blueprint") + err = errkit.Wrap(err, "Failed to query blueprint") c.logAndErrorEvent(ctx, "Could not get blueprint:", "Error", err, as) break } @@ -419,7 +419,7 @@ func (c *Controller) handleActionSet(ctx context.Context, t *tomb.Tomb, as *crv1 Message: err.Error(), } _, err = c.crClient.CrV1alpha1().ActionSets(as.GetNamespace()).Update(ctx, as, metav1.UpdateOptions{}) - return errors.WithStack(err) + return errkit.WithStack(err) } log.WithContext(ctx).Print("Created actionset and started executing actions", field.M{"NewActionSetName": as.GetName()}) return nil diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 6f5b8604a0..f5b4210025 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -21,7 +21,7 @@ import ( "testing" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "github.com/prometheus/client_golang/prometheus" promgomodel "github.com/prometheus/client_model/go" "gopkg.in/check.v1" @@ -171,12 +171,12 @@ func (s *ControllerSuite) waitOnActionSetState(as *crv1alpha1.ActionSet, state c if as.Status.State == crv1alpha1.StatePending || as.Status.State == crv1alpha1.StateRunning { return false, nil } - return false, errors.New(fmt.Sprintf("Unexpected state: %s", as.Status.State)) + return false, errkit.New(fmt.Sprintf("Unexpected state: %s", as.Status.State)) }) if err == nil { return nil } - return errors.Wrapf(err, "State '%s' never reached", state) + return errkit.Wrap(err, fmt.Sprintf("State '%s' never reached", state)) } func (s *ControllerSuite) waitOnDeferPhaseState(as *crv1alpha1.ActionSet, state crv1alpha1.State) error { @@ -201,7 +201,7 @@ func (s *ControllerSuite) waitOnDeferPhaseState(as *crv1alpha1.ActionSet, state if err == nil { return nil } - return errors.Wrapf(err, "State '%s' never reached", state) + return errkit.Wrap(err, fmt.Sprintf("State '%s' never reached", state)) } func (s *ControllerSuite) waitOnActionSetCompleteWithRunningPhases(as *crv1alpha1.ActionSet, rp *sets.Set[string]) error { @@ -229,12 +229,12 @@ func (s *ControllerSuite) waitOnActionSetCompleteWithRunningPhases(as *crv1alpha } return false, nil } - return false, errors.New(fmt.Sprintf("Unexpected state: %s", as.Status.State)) + return false, errkit.New(fmt.Sprintf("Unexpected state: %s", as.Status.State)) }) if err == nil { return nil } - return errors.Wrapf(err, "ActionSet did not reach '%s' state", crv1alpha1.StateComplete) + return errkit.Wrap(err, fmt.Sprintf("ActionSet did not reach '%s' state", crv1alpha1.StateComplete)) } func newBPWithOutputArtifact() *crv1alpha1.Blueprint { @@ -731,7 +731,7 @@ func (s *ControllerSuite) TestRuntimeObjEventLogs(c *check.C) { config, err := kube.LoadConfig() c.Assert(err, check.IsNil) ctlr := New(config, nil) - ctlr.logAndErrorEvent(ctx, msg, reason, errors.New("Testing Event Logs"), as, nilAs, bp) + ctlr.logAndErrorEvent(ctx, msg, reason, errkit.New("Testing Event Logs"), as, nilAs, bp) // Test ActionSet error event logging events, err := s.cli.CoreV1().Events(as.Namespace).Search(scheme.Scheme, as) @@ -754,7 +754,7 @@ func (s *ControllerSuite) TestRuntimeObjEventLogs(c *check.C) { // Testing empty Blueprint testbp := &crv1alpha1.Blueprint{} - ctlr.logAndErrorEvent(ctx, msg, reason, errors.New("Testing Event Logs"), testbp) + ctlr.logAndErrorEvent(ctx, msg, reason, errkit.New("Testing Event Logs"), testbp) events, err = s.cli.CoreV1().Events(bp.Namespace).Search(scheme.Scheme, testbp) c.Assert(err, check.NotNil) c.Assert(len(events.Items), check.Equals, 0) diff --git a/pkg/controllers/repositoryserver/handler.go b/pkg/controllers/repositoryserver/handler.go index 29677628de..d7325f0c27 100644 --- a/pkg/controllers/repositoryserver/handler.go +++ b/pkg/controllers/repositoryserver/handler.go @@ -22,7 +22,7 @@ import ( "github.com/go-logr/logr" "github.com/jpillora/backoff" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" @@ -50,20 +50,20 @@ type RepoServerHandler struct { func (h *RepoServerHandler) CreateOrUpdateOwnedResources(ctx context.Context) error { if err := h.getSecretsFromCR(ctx); err != nil { - return errors.Wrap(err, "Failed to get Kopia API server secrets") + return errkit.Wrap(err, "Failed to get Kopia API server secrets") } svc, err := h.reconcileService(ctx) if err != nil { - return errors.Wrap(err, "Failed to reconcile service") + return errkit.Wrap(err, "Failed to reconcile service") } envVars, pod, err := h.reconcilePod(ctx, svc) if err != nil { - return errors.Wrap(err, "Failed to reconcile Kopia API server pod") + return errkit.Wrap(err, "Failed to reconcile Kopia API server pod") } if err := h.waitForPodReady(ctx, pod); err != nil { - return errors.Wrap(err, "Kopia API server pod not in ready state") + return errkit.Wrap(err, "Kopia API server pod not in ready state") } // envVars are set only when credentials are of type AWS/Azure. @@ -95,7 +95,7 @@ func (h *RepoServerHandler) reconcileService(ctx context.Context) (*corev1.Servi return nil, err } if err := h.updateServerInfoInCRStatus(ctx, h.RepositoryServer.Status.ServerInfo.PodName, svc.Name); err != nil { - return nil, errors.Wrap(err, "Failed to update service name in RepositoryServer /status") + return nil, errkit.Wrap(err, "Failed to update service name in RepositoryServer /status") } return svc, err } @@ -131,7 +131,7 @@ func (h *RepoServerHandler) createService(ctx context.Context, repoServerNamespa } err := h.Reconciler.Create(ctx, &svc) if err != nil { - return nil, errors.Wrap(err, "Failed to create RepositoryServer service") + return nil, errkit.Wrap(err, "Failed to create RepositoryServer service") } err = poll.WaitWithBackoff(ctx, backoff.Backoff{ @@ -184,7 +184,7 @@ func (h *RepoServerHandler) createPodAndUpdateStatus(ctx context.Context, repoSe return nil, nil, err } if err := h.updateServerInfoInCRStatus(ctx, pod.Name, h.RepositoryServer.Status.ServerInfo.ServiceName); err != nil { - return nil, nil, errors.Wrap(err, "Failed to update pod name in RepositoryServer /status") + return nil, nil, errkit.Wrap(err, "Failed to update pod name in RepositoryServer /status") } return envVars, pod, nil } @@ -236,7 +236,7 @@ func (h *RepoServerHandler) createPod(ctx context.Context, repoServerNamespace s return nil, nil, err } if err := h.Reconciler.Create(ctx, pod); err != nil { - return nil, nil, errors.Wrap(err, "Failed to create RepositoryServer pod") + return nil, nil, errkit.Wrap(err, "Failed to create RepositoryServer pod") } return pod, envVars, err } @@ -284,7 +284,7 @@ func (h *RepoServerHandler) preparePodOverride(ctx context.Context, po *kube.Pod h.RepositoryServerSecrets.serverTLS.Name, po, ); err != nil { - return nil, errors.Wrap(err, "Failed to attach TLS Certificate configuration") + return nil, errkit.Wrap(err, "Failed to attach TLS Certificate configuration") } return podOverride, nil } @@ -315,7 +315,7 @@ func (h *RepoServerHandler) updateServerInfoInCRStatus(ctx context.Context, podN func (h *RepoServerHandler) waitForPodReady(ctx context.Context, pod *corev1.Pod) error { if err := kube.WaitForPodReady(ctx, h.KubeCli, pod.Namespace, pod.Name); err != nil { - return errors.Wrap(err, fmt.Sprintf("Failed while waiting for pod %s to be ready", pod.Name)) + return errkit.Wrap(err, fmt.Sprintf("Failed while waiting for pod %s to be ready", pod.Name)) } return nil } diff --git a/pkg/controllers/repositoryserver/repositoryserver_controller.go b/pkg/controllers/repositoryserver/repositoryserver_controller.go index 8616921b95..7e52febac0 100644 --- a/pkg/controllers/repositoryserver/repositoryserver_controller.go +++ b/pkg/controllers/repositoryserver/repositoryserver_controller.go @@ -18,7 +18,7 @@ import ( "context" "github.com/go-logr/logr" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -69,11 +69,11 @@ func (r *RepositoryServerReconciler) Reconcile(ctx context.Context, req ctrl.Req logger = logger.V(1) cnf, err := ctrl.GetConfig() if err != nil { - return ctrl.Result{}, errors.Wrap(err, "Failed to get k8s config") + return ctrl.Result{}, errkit.Wrap(err, "Failed to get k8s config") } kubeCli, err := kubernetes.NewForConfig(cnf) if err != nil { - return ctrl.Result{}, errors.Wrap(err, "Failed to get a k8s client") + return ctrl.Result{}, errkit.Wrap(err, "Failed to get a k8s client") } repositoryServer := &crv1alpha1.RepositoryServer{} diff --git a/pkg/controllers/repositoryserver/repositoryserver_controller_test.go b/pkg/controllers/repositoryserver/repositoryserver_controller_test.go index 90b6e9f5fa..b84557e468 100644 --- a/pkg/controllers/repositoryserver/repositoryserver_controller_test.go +++ b/pkg/controllers/repositoryserver/repositoryserver_controller_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" corev1 "k8s.io/api/core/v1" k8sresource "k8s.io/apimachinery/pkg/api/resource" @@ -477,11 +477,11 @@ func (s *RepoServerControllerSuite) waitForRepoServerInfoUpdateInCR(repoServerNa }) if !serverInfoUpdated && err == nil { - err = errors.New("pod name or service name is not set on repository server CR") + err = errkit.New("pod name or service name is not set on repository server CR") } if err != nil { - return errors.Wrapf(err, "failed waiting for RepoServer Info updates in the CR") + return errkit.Wrap(err, "failed waiting for RepoServer Info updates in the CR") } return err } @@ -502,12 +502,12 @@ func (s *RepoServerControllerSuite) waitOnRepositoryServerState(reposerverName s return false, nil } if repoServerCR.Status.Progress == crv1alpha1.Failed { - return false, errors.New(fmt.Sprintf(" There is failure in staring the repository server, server is in %s state, please check logs", repoServerCR.Status.Progress)) + return false, errkit.New(fmt.Sprintf("There is failure in staring the repository server, server is in %s state, please check logs", repoServerCR.Status.Progress)) } if repoServerCR.Status.Progress == crv1alpha1.Ready { return true, nil } - return false, errors.New(fmt.Sprintf("Unexpected Repository server state: %s", repoServerCR.Status.Progress)) + return false, errkit.New(fmt.Sprintf("Unexpected Repository server state: %s", repoServerCR.Status.Progress)) }) return repoServerState, err } diff --git a/pkg/controllers/repositoryserver/secrets_manager.go b/pkg/controllers/repositoryserver/secrets_manager.go index 9272eeafb3..fb66923ea2 100644 --- a/pkg/controllers/repositoryserver/secrets_manager.go +++ b/pkg/controllers/repositoryserver/secrets_manager.go @@ -18,7 +18,7 @@ import ( "context" "fmt" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ) @@ -76,14 +76,14 @@ func (h *RepoServerHandler) getSecretsFromCR(ctx context.Context) error { func (h *RepoServerHandler) fetchSecret(ctx context.Context, ref *corev1.SecretReference) (*corev1.Secret, error) { if ref == nil { - return nil, errors.New("repository server CR does not have a secret reference set") + return nil, errkit.New("repository server CR does not have a secret reference set") } h.Logger.Info(fmt.Sprintf("Fetching secret %s from namespace %s", ref.Name, ref.Namespace)) secret := corev1.Secret{} err := h.Reconciler.Get(ctx, types.NamespacedName{Name: ref.Name, Namespace: ref.Namespace}, &secret) if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf("Error fetching secret %s from namespace %s", ref.Name, ref.Namespace)) + return nil, errkit.Wrap(err, fmt.Sprintf("Error fetching secret %s from namespace %s", ref.Name, ref.Namespace)) } return &secret, nil } diff --git a/pkg/controllers/repositoryserver/server.go b/pkg/controllers/repositoryserver/server.go index 16ce3d4a08..9d03c0ea33 100644 --- a/pkg/controllers/repositoryserver/server.go +++ b/pkg/controllers/repositoryserver/server.go @@ -21,7 +21,7 @@ import ( "os" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "k8s.io/kube-openapi/pkg/util/sets" "github.com/kanisterio/kanister/pkg/format" @@ -69,12 +69,12 @@ func (h *RepoServerHandler) startRepoProxyServer(ctx context.Context) (err error format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stdout) format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stderr) if err != nil { - return errors.Wrap(err, "Failed to start Kopia API server") + return errkit.Wrap(err, "Failed to start Kopia API server") } err = h.waitForServerReady(ctx, repoServerAddress, serverAdminUserName, serverAdminPassword) if err != nil { - return errors.Wrap(err, "Failed to check Kopia API server status") + return errkit.Wrap(err, "Failed to check Kopia API server status") } return nil } @@ -87,10 +87,10 @@ func (h *RepoServerHandler) getServerDetails(ctx context.Context) (string, strin var serverAdminUsername, serverAdminPassword []byte var ok bool if serverAdminUsername, ok = h.RepositoryServerSecrets.serverAdmin.Data[reposerver.AdminUsernameKey]; !ok { - return "", "", "", errors.New("Server admin username is not specified") + return "", "", "", errkit.New("Server admin username is not specified") } if serverAdminPassword, ok = h.RepositoryServerSecrets.serverAdmin.Data[reposerver.AdminPasswordKey]; !ok { - return "", "", "", errors.New("Server admin password is not specified") + return "", "", "", errkit.New("Server admin password is not specified") } return repoServerAddress, string(serverAdminUsername), string(serverAdminPassword), nil } @@ -98,7 +98,7 @@ func (h *RepoServerHandler) getServerDetails(ctx context.Context) (string, strin func (h *RepoServerHandler) checkServerStatus(ctx context.Context, serverAddress, username, password string) error { cmd, err := h.getServerStatusCommand(ctx, serverAddress, username, password) if err != nil { - return errors.Wrap(err, "Failed to extract fingerprint from Kopia API server certificate secret data") + return errkit.Wrap(err, "Failed to extract fingerprint from Kopia API server certificate secret data") } stdout, stderr, exErr := kube.Exec(ctx, h.KubeCli, h.RepositoryServer.Namespace, h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, cmd, nil) format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stdout) @@ -109,7 +109,7 @@ func (h *RepoServerHandler) checkServerStatus(ctx context.Context, serverAddress func (h *RepoServerHandler) waitForServerReady(ctx context.Context, serverAddress, username, password string) error { cmd, err := h.getServerStatusCommand(ctx, serverAddress, username, password) if err != nil { - return errors.Wrap(err, "Failed to extract fingerprint from Kopia API server certificate secret data") + return errkit.Wrap(err, "Failed to extract fingerprint from Kopia API server certificate secret data") } serverStartTimeOut := h.getRepositoryServerStartTimeout() ctx, cancel := context.WithTimeout(ctx, serverStartTimeOut) @@ -132,14 +132,14 @@ func (h *RepoServerHandler) createOrUpdateClientUsers(ctx context.Context) error format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stdout) format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stderr) if err != nil { - return errors.Wrap(err, "Failed to list users from the Kopia repository") + return errkit.Wrap(err, "Failed to list users from the Kopia repository") } userProfiles := []maintenance.KopiaUserProfile{} err = json.Unmarshal([]byte(stdout), &userProfiles) if err != nil { - return errors.Wrap(err, "Failed to unmarshal user list") + return errkit.Wrap(err, "Failed to unmarshal user list") } // Get list of usernames from ServerListUserCommand output to update the existing data with updated password @@ -169,7 +169,7 @@ func (h *RepoServerHandler) createOrUpdateClientUsers(ctx context.Context) error format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stdout) format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stderr) if err != nil { - return errors.Wrap(err, "Failed to update existing user passphrase from the Kopia API server") + return errkit.Wrap(err, "Failed to update existing user passphrase from the Kopia API server") } continue } @@ -187,7 +187,7 @@ func (h *RepoServerHandler) createOrUpdateClientUsers(ctx context.Context) error format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stdout) format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stderr) if err != nil { - return errors.Wrap(err, "Failed to add new user to the Kopia API server") + return errkit.Wrap(err, "Failed to add new user to the Kopia API server") } } return nil @@ -201,7 +201,7 @@ func (h *RepoServerHandler) refreshServer(ctx context.Context) error { repoPassword := string(h.RepositoryServerSecrets.repositoryPassword.Data[reposerver.RepoPasswordKey]) fingerprint, err := kopia.ExtractFingerprintFromCertSecret(ctx, h.KubeCli, h.RepositoryServerSecrets.serverTLS.Name, h.RepositoryServer.Namespace) if err != nil { - return errors.Wrap(err, "Failed to extract fingerprint from Kopia API server certificate secret data") + return errkit.Wrap(err, "Failed to extract fingerprint from Kopia API server certificate secret data") } cmd := command.ServerRefresh( @@ -220,7 +220,7 @@ func (h *RepoServerHandler) refreshServer(ctx context.Context) error { format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stdout) format.Log(h.RepositoryServer.Status.ServerInfo.PodName, repoServerPodContainerName, stderr) if err != nil { - return errors.Wrap(err, "Failed to refresh Kopia API server") + return errkit.Wrap(err, "Failed to refresh Kopia API server") } return nil } @@ -241,7 +241,7 @@ func (h *RepoServerHandler) getRepositoryServerStartTimeout() time.Duration { func (h *RepoServerHandler) getServerStatusCommand(ctx context.Context, serverAddress, username, password string) ([]string, error) { fingerprint, err := kopia.ExtractFingerprintFromCertSecret(ctx, h.KubeCli, h.RepositoryServerSecrets.serverTLS.Name, h.RepositoryServer.Namespace) if err != nil { - return nil, errors.Wrap(err, "Failed to extract fingerprint from Kopia API server certificate secret data") + return nil, errkit.Wrap(err, "Failed to extract fingerprint from Kopia API server certificate secret data") } cmd := command.ServerStatus( command.ServerStatusCommandArgs{ diff --git a/pkg/controllers/repositoryserver/utils.go b/pkg/controllers/repositoryserver/utils.go index 928dc984bb..0fdcd5af69 100644 --- a/pkg/controllers/repositoryserver/utils.go +++ b/pkg/controllers/repositoryserver/utils.go @@ -22,7 +22,7 @@ import ( "time" "github.com/jpillora/backoff" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -164,12 +164,12 @@ func volumeSpecForName(podSpec corev1.PodSpec, podOverride map[string]interface{ func addTLSCertConfigurationInPodOverride(podOverride *map[string]interface{}, tlsCertSecretName string, po *kube.PodOptions) error { podSpecBytes, err := json.Marshal(*podOverride) if err != nil { - return errors.Wrap(err, "Failed to marshal Pod Override") + return errkit.Wrap(err, "Failed to marshal Pod Override") } var podOverrideSpec corev1.PodSpec if err := json.Unmarshal(podSpecBytes, &podOverrideSpec); err != nil { - return errors.Wrap(err, "Failed to unmarshal Pod Override Spec") + return errkit.Wrap(err, "Failed to unmarshal Pod Override Spec") } podOverrideSpec.Volumes = append(podOverrideSpec.Volumes, corev1.Volume{ @@ -199,11 +199,11 @@ func addTLSCertConfigurationInPodOverride(podOverride *map[string]interface{}, t podSpecBytes, err = json.Marshal(podOverrideSpec) if err != nil { - return errors.Wrap(err, "Failed to marshal Pod Override Spec") + return errkit.Wrap(err, "Failed to marshal Pod Override Spec") } if err := json.Unmarshal(podSpecBytes, podOverride); err != nil { - return errors.Wrap(err, "Failed to unmarshal Pod Override") + return errkit.Wrap(err, "Failed to unmarshal Pod Override") } return nil @@ -235,7 +235,7 @@ func getPodOptions(namespace string, svc *corev1.Service, vols map[string]kube.V func getPodAddress(ctx context.Context, cli kubernetes.Interface, namespace, podName string) (string, error) { p, err := cli.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{}) if err != nil { - return "", errors.Wrap(err, "Failed to get pod") + return "", errkit.Wrap(err, "Failed to get pod") } return fmt.Sprintf(repoServerAddressFormat, p.Status.PodIP, repoServerServicePort), nil } @@ -277,17 +277,17 @@ func getVolumes( vols := make(map[string]kube.VolumeMountOptions, 0) var claimName []byte if len(secret.Data) == 0 { - return nil, errors.Errorf(secerrors.EmptySecretErrorMessage, secret.Namespace, secret.Name) + return nil, errkit.New(fmt.Sprintf(secerrors.EmptySecretErrorMessage, secret.Namespace, secret.Name)) } if locationType, ok := (secret.Data[reposerver.TypeKey]); ok && reposerver.LocType(string(locationType)) == reposerver.LocTypeFilestore { if claimName, ok = secret.Data[reposerver.ClaimNameKey]; !ok { - return nil, errors.New("Claim name not set for file store location secret, failed to retrieve PVC") + return nil, errkit.New("Claim name not set for file store location secret, failed to retrieve PVC") } claimNameString := string(claimName) pvc, err := cli.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, claimNameString, metav1.GetOptions{}) if err != nil { - return nil, errors.Wrapf(err, "Failed to validate if PVC %s:%s exists", namespace, claimName) + return nil, errkit.Wrap(err, "Failed to validate if PVC exists", "namespace", namespace, "claimName", claimName) } vols[claimNameString] = kube.VolumeMountOptions{ diff --git a/pkg/errorchecker/errorchecker_test.go b/pkg/errorchecker/errorchecker_test.go index 3a12e5a5ef..f8466a3c14 100644 --- a/pkg/errorchecker/errorchecker_test.go +++ b/pkg/errorchecker/errorchecker_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/kanisterio/errkit" - "github.com/pkg/errors" "gopkg.in/check.v1" ) @@ -18,11 +17,11 @@ var _ = check.Suite(&ErrorsTestSuite{}) func (ts *ErrorsTestSuite) TestWrappingAndMatching(c *check.C) { errkitErr := errkit.New("Errkit error") errkitWrappedErr := errkit.Wrap(errkitErr, "errkit wrapped") - errorsWrappedErr := errors.Wrap(errkitWrappedErr, "errors wrapped") - errorsWrappedErr1 := errors.Wrap(errorsWrappedErr, "errors wrapped 1") + errorsWrappedErr := errkit.Wrap(errkitWrappedErr, "errors wrapped") + errorsWrappedErr1 := errkit.Wrap(errorsWrappedErr, "errors wrapped 1") // Ensure that errors from 'errkit' wrapped by the older 'errors' package remain matchable. - c.Assert(errors.Is(errorsWrappedErr, errkitErr), check.Equals, true) + c.Assert(errkit.Is(errorsWrappedErr, errkitErr), check.Equals, true) // Ensure that transformation to string still works c.Assert(errorsWrappedErr1.Error(), check.Equals, "errors wrapped 1: errors wrapped: errkit wrapped: Errkit error") // Ensure that error message matching does work as expected diff --git a/pkg/function/export_rds_snapshot_location.go b/pkg/function/export_rds_snapshot_location.go index c2df143550..ca32c18251 100644 --- a/pkg/function/export_rds_snapshot_location.go +++ b/pkg/function/export_rds_snapshot_location.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "fmt" + "strconv" "strings" "time" @@ -435,6 +436,8 @@ func postgresBackupCommand(dbEndpoint, username, password string, dbList []strin return nil, errkit.New("No database found to backup") } + profileQuoted := strconv.Quote(string(profile)) + command := []string{ "bash", "-o", @@ -452,9 +455,9 @@ func postgresBackupCommand(dbEndpoint, username, password string, dbList []strin for db in "${dblist[@]}"; do echo "backing up $db db" && pg_dump $db -C --inserts > /backup/$db.sql; done - tar -zc backup | kando location push --profile '%s' --path "${BACKUP_PREFIX}/${BACKUP_ID}" - + tar -zc backup | kando location push --profile %s --path "${BACKUP_PREFIX}/${BACKUP_ID}" - kando output %s ${BACKUP_ID}`, - dbEndpoint, backupPrefix, backupID, strings.Join(dbList, " "), profile, ExportRDSSnapshotToLocBackupID), + dbEndpoint, backupPrefix, backupID, strings.Join(dbList, " "), profileQuoted, ExportRDSSnapshotToLocBackupID), } return command, nil } diff --git a/pkg/function/rds_functions_test.go b/pkg/function/rds_functions_test.go index fc037e6749..f278369a05 100644 --- a/pkg/function/rds_functions_test.go +++ b/pkg/function/rds_functions_test.go @@ -60,10 +60,32 @@ func (s *RDSFunctionsTest) TestPrepareCommand(c *check.C) { command: []string{"bash", "-o", "errexit", "-o", "pipefail", "-c", fmt.Sprintf(` export PGHOST=%s - kando location pull --profile '%s' --path "%s" - | gunzip -c -f | sed 's/"LOCALE"/"LC_COLLATE"/' | psql -q -U "${PGUSER}" %s + kando location pull --profile "%s" --path "%s" - | gunzip -c -f | sed 's/"LOCALE"/"LC_COLLATE"/' | psql -q -U "${PGUSER}" %s `, "db-endpoint", "null", fmt.Sprintf("%s/%s", "/backup/postgres-backup", "backup-id"), postgres.DefaultConnectDatabase), }, }, + { + name: "PostgreS restore command with profile", + dbEngine: PostgrSQLEngine, + action: RestoreAction, + dbEndpoint: "db-endpoint", + username: "test-user", + password: "secret-pass", + backupPrefix: "/backup/postgres-backup", + backupID: "backup-id", + dbEngineVersion: "12.7", + errChecker: check.IsNil, + dbList: []string{"template1"}, + command: []string{"bash", "-o", "errexit", "-o", "pipefail", "-c", + fmt.Sprintf(` + export PGHOST=%s + kando location pull --profile "{\"Location\":{\"type\":\"\",\"bucket\":\"\",\"endpoint\":\"\",\"prefix\":\"\",\"region\":\"\"},\"Credential\":{\"Type\":\"\",\"KeyPair\":null,\"Secret\":null,\"KopiaServerSecret\":null},\"SkipSSLVerify\":false}" --path "%s" - | gunzip -c -f | sed 's/"LOCALE"/"LC_COLLATE"/' | psql -q -U "${PGUSER}" %s + `, "db-endpoint", fmt.Sprintf("%s/%s", "/backup/postgres-backup", "backup-id"), postgres.DefaultConnectDatabase), + }, + tp: param.TemplateParams{ + Profile: ¶m.Profile{}, + }, + }, { name: "PostgreS restore command", dbEngine: PostgrSQLEngine, @@ -79,7 +101,7 @@ func (s *RDSFunctionsTest) TestPrepareCommand(c *check.C) { command: []string{"bash", "-o", "errexit", "-o", "pipefail", "-c", fmt.Sprintf(` export PGHOST=%s - kando location pull --profile '%s' --path "%s" - | gunzip -c -f | psql -q -U "${PGUSER}" %s + kando location pull --profile "%s" --path "%s" - | gunzip -c -f | psql -q -U "${PGUSER}" %s `, "db-endpoint", "null", fmt.Sprintf("%s/%s", "/backup/postgres-backup", "backup-id"), postgres.DefaultConnectDatabase), }, }, @@ -106,7 +128,7 @@ func (s *RDSFunctionsTest) TestPrepareCommand(c *check.C) { for db in "${dblist[@]}"; do echo "backing up $db db" && pg_dump $db -C --inserts > /backup/$db.sql; done - tar -zc backup | kando location push --profile '%s' --path "${BACKUP_PREFIX}/${BACKUP_ID}" - + tar -zc backup | kando location push --profile "%s" --path "${BACKUP_PREFIX}/${BACKUP_ID}" - kando output %s ${BACKUP_ID}`, "db-endpoint", "/backup/postgres-backup", "backup-id", strings.Join([]string{"template1"}, " "), "null", ExportRDSSnapshotToLocBackupID), }, diff --git a/pkg/function/restore_rds_snapshot.go b/pkg/function/restore_rds_snapshot.go index df5dd16957..76f482bfdd 100644 --- a/pkg/function/restore_rds_snapshot.go +++ b/pkg/function/restore_rds_snapshot.go @@ -17,6 +17,7 @@ package function import ( "context" "fmt" + "strconv" "time" "github.com/aws/aws-sdk-go/aws" @@ -335,6 +336,8 @@ func postgresRestoreCommand(pgHost, username, password string, backupArtifactPre replaceCommand = ` sed 's/"LOCALE"/"LC_COLLATE"/' |` } + profileQuoted := strconv.Quote(string(profile)) + return []string{ "bash", "-o", @@ -344,8 +347,8 @@ func postgresRestoreCommand(pgHost, username, password string, backupArtifactPre "-c", fmt.Sprintf(` export PGHOST=%s - kando location pull --profile '%s' --path "%s" - | gunzip -c -f |%s psql -q -U "${PGUSER}" %s - `, pgHost, profile, fmt.Sprintf("%s/%s", backupArtifactPrefix, backupID), replaceCommand, postgres.DefaultConnectDatabase), + kando location pull --profile %s --path "%s" - | gunzip -c -f |%s psql -q -U "${PGUSER}" %s + `, pgHost, profileQuoted, fmt.Sprintf("%s/%s", backupArtifactPrefix, backupID), replaceCommand, postgres.DefaultConnectDatabase), }, nil } diff --git a/pkg/kopia/cli/errors.go b/pkg/kopia/cli/errors.go index 68153212d5..4d08eb48cc 100644 --- a/pkg/kopia/cli/errors.go +++ b/pkg/kopia/cli/errors.go @@ -15,29 +15,29 @@ package cli import ( - "github.com/pkg/errors" + "github.com/kanisterio/errkit" ) // Common errors var ( // ErrInvalidID is returned when the ID is empty. - ErrInvalidID = errors.New("invalid ID") + ErrInvalidID = errkit.NewSentinelErr("invalid ID") ) // storage errors var ( // ErrUnsupportedStorage is returned when the storage is not supported. - ErrUnsupportedStorage = errors.New("unsupported storage") + ErrUnsupportedStorage = errkit.NewSentinelErr("unsupported storage") // ErrInvalidRepoPath is returned when the repoPath is empty. - ErrInvalidRepoPath = errors.New("repository path cannot be empty") + ErrInvalidRepoPath = errkit.NewSentinelErr("repository path cannot be empty") // ErrInvalidPrefix is returned when the prefix is empty. - ErrInvalidPrefix = errors.New("prefix cannot be empty") + ErrInvalidPrefix = errkit.NewSentinelErr("prefix cannot be empty") // ErrInvalidBucketName is returned when the bucketName is empty. - ErrInvalidBucketName = errors.New("bucket name cannot be empty") + ErrInvalidBucketName = errkit.NewSentinelErr("bucket name cannot be empty") // ErrInvalidCredentialsFile is returned when the credentials file is empty. - ErrInvalidCredentialsFile = errors.New("credentials file cannot be empty") + ErrInvalidCredentialsFile = errkit.NewSentinelErr("credentials file cannot be empty") // ErrInvalidContainerName is returned when the containerName is empty. - ErrInvalidContainerName = errors.New("container name cannot be empty") + ErrInvalidContainerName = errkit.NewSentinelErr("container name cannot be empty") // ErrInvalidServerURL is returned when the serverURL is empty. - ErrInvalidServerURL = errors.New("server URL cannot be empty") + ErrInvalidServerURL = errkit.NewSentinelErr("server URL cannot be empty") ) diff --git a/pkg/kopia/cli/internal/test/command_suite.go b/pkg/kopia/cli/internal/test/command_suite.go index 57a8c2f96d..660909dc6d 100644 --- a/pkg/kopia/cli/internal/test/command_suite.go +++ b/pkg/kopia/cli/internal/test/command_suite.go @@ -15,9 +15,9 @@ package test import ( + "github.com/kanisterio/errkit" "github.com/kanisterio/safecli" "github.com/kanisterio/safecli/test" - "github.com/pkg/errors" "gopkg.in/check.v1" ) @@ -62,8 +62,7 @@ func (t *CommandTest) assertNoError(c *check.C, err error) { // assertError checks the error against ExpectedErr. func (t *CommandTest) assertError(c *check.C, err error) { - actualErr := errors.Cause(err) - c.Assert(actualErr, check.Equals, t.ExpectedErr) + c.Assert(errkit.Is(err, t.ExpectedErr), check.Equals, true) } // assertCLI asserts the builder's CLI output against ExpectedCLI. diff --git a/pkg/kopia/cli/repository/opts.go b/pkg/kopia/cli/repository/opts.go index 31c92ab0e5..fd05a901ca 100644 --- a/pkg/kopia/cli/repository/opts.go +++ b/pkg/kopia/cli/repository/opts.go @@ -15,11 +15,12 @@ package repository import ( + "fmt" "time" "github.com/go-openapi/strfmt" + "github.com/kanisterio/errkit" "github.com/kanisterio/safecli/command" - "github.com/pkg/errors" "github.com/kanisterio/kanister/pkg/kopia/cli" "github.com/kanisterio/kanister/pkg/kopia/cli/internal" @@ -91,7 +92,7 @@ func optStorage(l internal.Location, repoPathPrefix string, logger log.Logger) c } func errUnsupportedStorageType(t rs.LocType) command.Applier { - err := errors.Wrapf(cli.ErrUnsupportedStorage, "storage location: %v", t) + err := errkit.Wrap(cli.ErrUnsupportedStorage, fmt.Sprintf("storage location: %v", t)) return command.NewErrorArgument(err) } diff --git a/pkg/kopia/errors/utils_test.go b/pkg/kopia/errors/utils_test.go index e4370f0406..7ef1debfd9 100644 --- a/pkg/kopia/errors/utils_test.go +++ b/pkg/kopia/errors/utils_test.go @@ -18,7 +18,6 @@ import ( "testing" "github.com/kanisterio/errkit" - "github.com/pkg/errors" "gopkg.in/check.v1" ) @@ -31,17 +30,14 @@ var _ = check.Suite(&KopiaErrorsTestSuite{}) // TestErrCheck verifies that error types are properly detected after wrapping them func (s *KopiaErrorsTestSuite) TestErrCheck(c *check.C) { - origErr := errors.New("Some error") + origErr := errkit.New("Some error") - errWithMessage := errors.WithMessage(origErr, ErrInvalidPasswordStr) errWrapped := errkit.Wrap(origErr, ErrInvalidPasswordStr) - c.Assert(IsInvalidPasswordError(errWithMessage), check.Equals, true) c.Assert(IsInvalidPasswordError(errWrapped), check.Equals, true) c.Assert(IsRepoNotFoundError(errWrapped), check.Equals, false) permittedErrors := []ErrorType{ErrorInvalidPassword, ErrorRepoNotFound} - c.Assert(CheckKopiaErrors(errWithMessage, permittedErrors), check.Equals, true) c.Assert(CheckKopiaErrors(errWrapped, permittedErrors), check.Equals, true) wrongErrors := []ErrorType{ErrorRepoNotFound} diff --git a/pkg/kube/exec_test.go b/pkg/kube/exec_test.go index 9242abb4ec..2475a54fad 100644 --- a/pkg/kube/exec_test.go +++ b/pkg/kube/exec_test.go @@ -20,10 +20,10 @@ package kube import ( "bytes" "context" - "errors" "strings" "time" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -191,7 +191,7 @@ func (s *ExecSuite) TestErrorInExecWithOptions(c *check.C) { c.Assert(err1, check.Not(check.IsNil)) var ee1 *ExecError - ok := errors.As(err1, &ee1) + ok := errkit.As(err1, &ee1) c.Assert(ok, check.Equals, true) c.Assert(ee1.Stdout(), check.Not(check.Equals), testCase.expectedOut) c.Assert(ee1.Stderr(), check.Not(check.Equals), testCase.expectedErr) @@ -208,7 +208,7 @@ func (s *ExecSuite) TestErrorInExecWithOptions(c *check.C) { c.Assert(err2, check.Not(check.IsNil)) var ee2 *ExecError - ok = errors.As(err2, &ee2) + ok = errkit.As(err2, &ee2) c.Assert(ok, check.Equals, true) // When error happens, stdout/stderr buffers should contain all lines produced by an app diff --git a/pkg/kube/log_reader_test.go b/pkg/kube/log_reader_test.go index b83a89ea29..55fed677c7 100644 --- a/pkg/kube/log_reader_test.go +++ b/pkg/kube/log_reader_test.go @@ -3,9 +3,9 @@ package kube import ( "bytes" "context" - "errors" "io" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" "k8s.io/client-go/rest" ) @@ -39,7 +39,7 @@ func (frw *fakeResponseWrapper) Stream(context.Context) (io.ReadCloser, error) { } func (s *LogReaderSuite) TestLogReader(c *check.C) { - err := errors.New("TEST") + err := errkit.New("TEST") for _, tc := range []struct { rw *fakeResponseWrapper err error diff --git a/pkg/kube/pod.go b/pkg/kube/pod.go index 8baf644565..09be10c94c 100644 --- a/pkg/kube/pod.go +++ b/pkg/kube/pod.go @@ -27,7 +27,6 @@ import ( "github.com/gofrs/uuid" json "github.com/json-iterator/go" "github.com/kanisterio/errkit" - "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -451,7 +450,7 @@ func checkPVCAndPVStatus(ctx context.Context, vol corev1.Volume, p *corev1.Pod, pvcName := vol.VolumeSource.PersistentVolumeClaim.ClaimName pvc, err := cli.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, pvcName, metav1.GetOptions{}) if err != nil { - if apierrors.IsNotFound(errors.Cause(err)) { + if apierrors.IsNotFound(err) { // Do not return err, wait for timeout, since sometimes in case of statefulsets, they trigger creation of a volume return nil } @@ -470,7 +469,7 @@ func checkPVCAndPVStatus(ctx context.Context, vol corev1.Volume, p *corev1.Pod, } pv, err := cli.CoreV1().PersistentVolumes().Get(ctx, pvName, metav1.GetOptions{}) if err != nil { - if apierrors.IsNotFound(errors.Cause(err)) { + if apierrors.IsNotFound(err) { // wait for timeout return nil } diff --git a/pkg/kube/pod_command_executor_test.go b/pkg/kube/pod_command_executor_test.go index bc037dad47..064e6b35c0 100644 --- a/pkg/kube/pod_command_executor_test.go +++ b/pkg/kube/pod_command_executor_test.go @@ -17,11 +17,11 @@ package kube import ( "bytes" "context" - "errors" "os" "sync" "time" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" "k8s.io/client-go/kubernetes/fake" ) @@ -129,7 +129,7 @@ func (s *PodCommandExecutorTestSuite) TestPodRunnerExec(c *check.C) { prp.execWithOptionsSyncEnd.Sync() c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, context.DeadlineExceeded), check.Equals, true) + c.Assert(errkit.Is(err, context.DeadlineExceeded), check.Equals, true) }, "Cancelled": func(ctx context.Context, pr PodCommandExecutor, prp *fakePodCommandExecutorProcessor) { var err error @@ -151,7 +151,7 @@ func (s *PodCommandExecutorTestSuite) TestPodRunnerExec(c *check.C) { prp.execWithOptionsSyncEnd.Sync() // Release ExecWithOptions c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, context.Canceled), check.Equals, true) + c.Assert(errkit.Is(err, context.Canceled), check.Equals, true) }, "Successful execution": func(ctx context.Context, pr PodCommandExecutor, prp *fakePodCommandExecutorProcessor) { var err error diff --git a/pkg/kube/pod_controller_test.go b/pkg/kube/pod_controller_test.go index b2172ca21c..1555070569 100644 --- a/pkg/kube/pod_controller_test.go +++ b/pkg/kube/pod_controller_test.go @@ -16,7 +16,6 @@ package kube import ( "context" - "errors" "fmt" "os" "time" @@ -46,14 +45,14 @@ func (s *PodControllerTestSuite) TestPodControllerStartPod(c *check.C) { ctx := context.Background() cli := fake.NewSimpleClientset() - simulatedError := errors.New("SimulatedError") + simulatedError := errkit.New("SimulatedError") cases := map[string]func(prp *FakePodControllerProcessor, pr PodController){ "Pod creation failure": func(pcp *FakePodControllerProcessor, pc PodController) { pcp.CreatePodErr = simulatedError err := pc.StartPod(ctx) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, simulatedError), check.Equals, true) + c.Assert(errkit.Is(err, simulatedError), check.Equals, true) c.Assert(pcp.InCreatePodOptions, check.DeepEquals, &PodOptions{ Namespace: podControllerNS, Name: podControllerPodName, @@ -81,11 +80,11 @@ func (s *PodControllerTestSuite) TestPodControllerStartPod(c *check.C) { prp.InCreatePodOptions = nil prp.CreatePodRet = nil - prp.CreatePodErr = errors.New("CreatePod should not be invoked") + prp.CreatePodErr = errkit.New("CreatePod should not be invoked") err = pr.StartPod(ctx) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, ErrPodControllerPodAlreadyStarted), check.Equals, true) + c.Assert(errkit.Is(err, ErrPodControllerPodAlreadyStarted), check.Equals, true) c.Assert(prp.InCreatePodOptions, check.IsNil) }, } @@ -108,13 +107,13 @@ func (s *PodControllerTestSuite) TestPodControllerWaitPod(c *check.C) { ctx := context.Background() cli := fake.NewSimpleClientset() - simulatedError := errkit.Wrap(errors.New("SimulatedError"), "Wrapped") + simulatedError := errkit.Wrap(errkit.New("SimulatedError"), "Wrapped") cases := map[string]func(pcp *FakePodControllerProcessor, pc PodController){ "Waiting failed because pod not started yet": func(pcp *FakePodControllerProcessor, pc PodController) { err := pc.WaitForPodReady(ctx) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, ErrPodControllerPodNotStarted), check.Equals, true) + c.Assert(errkit.Is(err, ErrPodControllerPodNotStarted), check.Equals, true) c.Assert(pcp.InCreatePodOptions, check.IsNil) }, "Waiting failed due to timeout": func(pcp *FakePodControllerProcessor, pc PodController) { @@ -132,7 +131,7 @@ func (s *PodControllerTestSuite) TestPodControllerWaitPod(c *check.C) { c.Assert(err, check.Not(check.IsNil)) c.Assert(pcp.InWaitForPodReadyPodName, check.Equals, podControllerPodName) c.Assert(pcp.InWaitForPodReadyNamespace, check.Equals, podControllerNS) - c.Assert(errors.Is(err, pcp.WaitForPodReadyErr), check.Equals, true) + c.Assert(errkit.Is(err, pcp.WaitForPodReadyErr), check.Equals, true) c.Assert(err.Error(), check.Equals, fmt.Sprintf("Pod failed to become ready in time: %s", simulatedError.Error())) // Check that POD deletion was also invoked with expected arguments @@ -169,13 +168,13 @@ func (s *PodControllerTestSuite) TestPodControllerStopPod(c *check.C) { cli := fake.NewSimpleClientset() untouchedStr := "DEADBEEF" - simulatedError := errors.New("SimulatedError") + simulatedError := errkit.New("SimulatedError") cases := map[string]func(pcp *FakePodControllerProcessor, pc PodController){ "Pod not started yet": func(pcp *FakePodControllerProcessor, pc PodController) { err := pc.StopPod(ctx, 30*time.Second, int64(0)) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, ErrPodControllerPodNotStarted), check.Equals, true) + c.Assert(errkit.Is(err, ErrPodControllerPodNotStarted), check.Equals, true) c.Assert(pcp.InDeletePodPodName, check.Equals, untouchedStr) c.Assert(pcp.InDeletePodNamespace, check.Equals, untouchedStr) }, @@ -192,7 +191,7 @@ func (s *PodControllerTestSuite) TestPodControllerStopPod(c *check.C) { pcp.DeletePodErr = simulatedError err = pc.StopPod(ctx, 30*time.Second, int64(0)) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, simulatedError), check.Equals, true) + c.Assert(errkit.Is(err, simulatedError), check.Equals, true) }, "Pod successfully deleted": func(pcp *FakePodControllerProcessor, pc PodController) { pcp.CreatePodRet = &corev1.Pod{ @@ -239,12 +238,12 @@ func (s *PodControllerTestSuite) TestPodControllerGetCommandExecutorAndFileWrite pce, err := pc.GetCommandExecutor() c.Assert(pce, check.IsNil) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, ErrPodControllerPodNotStarted), check.Equals, true) + c.Assert(errkit.Is(err, ErrPodControllerPodNotStarted), check.Equals, true) pfw, err := pc.GetFileWriter() c.Assert(pfw, check.IsNil) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, ErrPodControllerPodNotStarted), check.Equals, true) + c.Assert(errkit.Is(err, ErrPodControllerPodNotStarted), check.Equals, true) }, "Pod not ready yet": func(pcp *FakePodControllerProcessor, pc PodController) { pcp.CreatePodRet = &corev1.Pod{ @@ -258,12 +257,12 @@ func (s *PodControllerTestSuite) TestPodControllerGetCommandExecutorAndFileWrite pce, err := pc.GetCommandExecutor() c.Assert(pce, check.IsNil) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, ErrPodControllerPodNotReady), check.Equals, true) + c.Assert(errkit.Is(err, ErrPodControllerPodNotReady), check.Equals, true) pfw, err := pc.GetFileWriter() c.Assert(pfw, check.IsNil) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, ErrPodControllerPodNotReady), check.Equals, true) + c.Assert(errkit.Is(err, ErrPodControllerPodNotReady), check.Equals, true) }, "CommandExecutor successfully returned": func(pcp *FakePodControllerProcessor, pc PodController) { pcp.CreatePodRet = &corev1.Pod{ diff --git a/pkg/kube/pod_file_writer_test.go b/pkg/kube/pod_file_writer_test.go index c9c45636b1..85e6a95e4b 100644 --- a/pkg/kube/pod_file_writer_test.go +++ b/pkg/kube/pod_file_writer_test.go @@ -17,7 +17,6 @@ package kube import ( "bytes" "context" - "errors" "io" "os" @@ -90,7 +89,7 @@ func (s *PodFileWriterTestSuite) TestPodRunnerWriteFile(c *check.C) { buf := bytes.NewBuffer([]byte("some file content")) remover, err := pfw.Write(ctx, "/path/to/file", buf) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, simulatedError), check.Equals, true) + c.Assert(errkit.Is(err, simulatedError), check.Equals, true) c.Assert(remover, check.IsNil) c.Assert(pfwp.podWriter.inWriteNamespace, check.Equals, podFileWriterNS) @@ -130,7 +129,7 @@ func (s *PodFileWriterTestSuite) TestPodRunnerWriteFile(c *check.C) { err = remover.Remove(ctx) c.Assert(err, check.Not(check.IsNil)) - c.Assert(errors.Is(err, simulatedError), check.Equals, true) + c.Assert(errkit.Is(err, simulatedError), check.Equals, true) c.Assert(pfwp.podWriter.inRemoveNamespace, check.Equals, podFileWriterNS) c.Assert(pfwp.podWriter.inRemovePodName, check.Equals, podFileWriterPodName) c.Assert(pfwp.podWriter.inRemoveContainerName, check.Equals, podFileWriterContainerName) diff --git a/pkg/kube/pod_runner_test.go b/pkg/kube/pod_runner_test.go index a3b8c21d61..20a312b1c8 100644 --- a/pkg/kube/pod_runner_test.go +++ b/pkg/kube/pod_runner_test.go @@ -19,7 +19,7 @@ import ( "os" "path" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" @@ -191,10 +191,10 @@ func afterPodRunTestKeyPresentFunc(labelKey, expectedLabelValue string, isLabelE <-ch labelValue, found := pc.Pod().Labels[labelKey] if found != isLabelExpected { - return nil, errors.New("Got different label than expected") + return nil, errkit.New("Got different label than expected") } if isLabelExpected && labelValue != expectedLabelValue { - return nil, errors.New("Found label doesn't match with expected label") + return nil, errkit.New("Found label doesn't match with expected label") } return nil, nil } diff --git a/pkg/kube/pod_test.go b/pkg/kube/pod_test.go index 852dd29f10..e14878821b 100644 --- a/pkg/kube/pod_test.go +++ b/pkg/kube/pod_test.go @@ -19,14 +19,15 @@ package kube import ( "context" - "errors" "fmt" "os" "strings" "time" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -315,7 +316,7 @@ func (s *PodSuite) TestPodWithFilesystemModeVolumes(c *check.C) { ca := action.(testing.CreateAction) p = ca.GetObject().(*corev1.Pod) if len(p.Spec.Volumes[0].Name) > 63 { - return true, nil, errors.New("spec.volumes[0].name must be no more than 63 characters") + return true, nil, errkit.New("spec.volumes[0].name must be no more than 63 characters") } return false, nil, nil }) @@ -364,7 +365,7 @@ func (s *PodSuite) TestPodWithFilesystemModeReadOnlyVolumes(c *check.C) { ca := action.(testing.CreateAction) p = ca.GetObject().(*corev1.Pod) if len(p.Spec.Volumes[0].Name) > 63 { - return true, nil, errors.New("spec.volumes[0].name must be no more than 63 characters") + return true, nil, errkit.New("spec.volumes[0].name must be no more than 63 characters") } return false, nil, nil }) @@ -415,7 +416,7 @@ func (s *PodSuite) TestPodWithBlockModeVolumes(c *check.C) { ca := action.(testing.CreateAction) p = ca.GetObject().(*corev1.Pod) if len(p.Spec.Volumes[0].Name) > 63 { - return true, nil, errors.New("spec.volumes[0].name must be no more than 63 characters") + return true, nil, errkit.New("spec.volumes[0].name must be no more than 63 characters") } return false, nil, nil }) @@ -1244,3 +1245,19 @@ func (s *PodSuite) TestAddAnnotations(c *check.C) { c.Assert(tc.podOptions, check.DeepEquals, tc.expectedPodOptions) } } + +// TestErrkitApiErrorsWrapping verifies that apierrors wrapped with errkit.Wrap are still matchable using apierrors matchers +func (s *PodSuite) TestErrkitApiErrorsWrapping(c *check.C) { + // Create the fake client + fakeClient := fake.NewSimpleClientset() + + // Add a reactor to simulate an error when trying to get a PVC + fakeClient.PrependReactor("get", "persistentvolumeclaims", func(action testing.Action) (handled bool, ret runtime.Object, err error) { + return true, nil, errkit.Wrap(apierrors.NewNotFound(action.GetResource().GroupResource(), action.GetSubresource()), "Some context") + }) + + _, err := fakeClient.CoreV1().PersistentVolumeClaims("abc").Get(context.TODO(), "def", metav1.GetOptions{}) + if err != nil { + c.Assert(apierrors.IsNotFound(err), check.Equals, true) + } +} diff --git a/pkg/log/fluentbit.go b/pkg/log/fluentbit.go index 36a03397a3..2c2d11cf22 100644 --- a/pkg/log/fluentbit.go +++ b/pkg/log/fluentbit.go @@ -7,7 +7,7 @@ import ( "os" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "github.com/sirupsen/logrus" ) @@ -64,7 +64,7 @@ func NewFluentbitHook(endpoint string) *FluentbitHook { func dial(endpoint string) (net.Conn, error) { conn, err := net.DialTimeout("tcp", endpoint, defaultConnTimeout) if err != nil { - return nil, errors.Wrap(err, "Fluentbit connection problem") + return nil, errkit.Wrap(err, "Fluentbit connection problem") } return conn, nil } @@ -73,12 +73,12 @@ func dial(endpoint string) (net.Conn, error) { func handle(msgs []byte, endpoint string) error { conn, err := dial(endpoint) if err != nil { - return errors.Wrap(err, "Fluentbit connection error") + return errkit.Wrap(err, "Fluentbit connection error") } defer conn.Close() //nolint:errcheck _, err = conn.Write(msgs) if err != nil { - return errors.Wrap(err, "Fluentbit write error") + return errkit.Wrap(err, "Fluentbit write error") } return nil } diff --git a/pkg/log/log.go b/pkg/log/log.go index fcd1932cb0..a5363fbc16 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "github.com/sirupsen/logrus" "github.com/kanisterio/kanister/pkg/caller" @@ -34,9 +34,9 @@ const ( ) var ( - ErrEndpointNotSet = errors.New("fluentbit endpoint not set") - ErrNonTCPEndpoint = errors.New("fluentbit endpoint scheme must be tcp") - ErrPathSet = errors.New("fluentbit endpoint path is set") + ErrEndpointNotSet = errkit.NewSentinelErr("fluentbit endpoint not set") + ErrNonTCPEndpoint = errkit.NewSentinelErr("fluentbit endpoint scheme must be tcp") + ErrPathSet = errkit.NewSentinelErr("fluentbit endpoint path is set") ) // OutputSink describes the current output sink. @@ -72,17 +72,17 @@ func SetOutput(sink OutputSink) error { case FluentbitSink: fbitAddr, ok := os.LookupEnv(LoggingServiceHostEnv) if !ok { - return errors.New("Unable to find Fluentbit host address") + return errkit.New("Unable to find Fluentbit host address") } fbitPort, ok := os.LookupEnv(LoggingServicePortEnv) if !ok { - return errors.New("Unable to find Fluentbit logging port") + return errkit.New("Unable to find Fluentbit logging port") } hook := NewFluentbitHook(fbitAddr + ":" + fbitPort) log.AddHook(hook) return nil default: - return errors.New("not implemented") + return errkit.New("not implemented") } } diff --git a/pkg/log/log_test.go b/pkg/log/log_test.go index 838942d7eb..2cb20b1e76 100644 --- a/pkg/log/log_test.go +++ b/pkg/log/log_test.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "net/url" "os" @@ -12,6 +11,7 @@ import ( "testing" "time" + "github.com/kanisterio/errkit" "github.com/sirupsen/logrus" "gopkg.in/check.v1" @@ -59,7 +59,7 @@ func (s *LogSuite) TestLogWithFields(c *check.C) { func (s *LogSuite) TestLogWithError(c *check.C) { const text = "My error message" - err := errors.New("test error") + err := errkit.New("test error") entry := testLogMessage(c, text, WithError(err).Print) c.Assert(entry["error"], check.Equals, err.Error()) c.Assert(entry["level"], check.Equals, infoLevelStr) @@ -88,7 +88,7 @@ func (s *LogSuite) TestLogWithContextFields(c *check.C) { func (s *LogSuite) TestLogWithContextFieldsAndError(c *check.C) { const text = "My error message" ctx := field.Context(context.Background(), "key", "value") - err := errors.New("test error") + err := errkit.New("test error") entry := testLogMessage(c, text, WithError(err).WithContext(ctx).Print) c.Assert(entry["level"], check.Equals, infoLevelStr) // Error should be included in the log entry diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 7831683a47..011d1debf3 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -15,9 +15,9 @@ package metrics import ( - "errors" "fmt" + "github.com/kanisterio/errkit" "github.com/prometheus/client_golang/prometheus" "gonum.org/v1/gonum/stat/combin" @@ -73,7 +73,7 @@ func getLabelCombinations(bl []BoundedLabel) ([]prometheus.Labels, error) { {"operation_type": "restore", "action_set_resolution": "failure"}] */ if !verifyBoundedLabels(bl) { - return nil, errors.New("invalid BoundedLabel list") + return nil, errkit.New("invalid BoundedLabel list") } labelLens := make([]int, len(bl)) for idx, l := range bl { @@ -241,7 +241,7 @@ func registerGauge(r prometheus.Registerer, g prometheus.Gauge) prometheus.Gauge func registerMetricOrDie(r prometheus.Registerer, c prometheus.Collector) prometheus.Collector { if err := r.Register(c); err != nil { are := prometheus.AlreadyRegisteredError{} - if !errors.As(err, &are) { + if !errkit.As(err, &are) { panic(fmt.Sprintf("failed to register metric. error: %v", err)) } // Use already registered metric diff --git a/pkg/objectstore/directory.go b/pkg/objectstore/directory.go index f184c29449..d228230cc1 100644 --- a/pkg/objectstore/directory.go +++ b/pkg/objectstore/directory.go @@ -234,7 +234,7 @@ func (d *directory) Put(ctx context.Context, name string, r io.Reader, size int6 if d.path == "" { return errors.New("invalid entry") } - // K10 tags include '/'. Remove them, at least for S3 + // Replace any '/' in tags with '-'. sTags := sanitizeTags(tags) objName := d.absPathName(name) diff --git a/pkg/testing/e2e_test.go b/pkg/testing/e2e_test.go index 17ef519cd3..3e3ffd41e0 100644 --- a/pkg/testing/e2e_test.go +++ b/pkg/testing/e2e_test.go @@ -23,7 +23,7 @@ import ( "log" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -166,7 +166,7 @@ func (s *E2ESuite) TestKubeExec(c *check.C) { case err != nil, as.Status == nil: return false, err case as.Status.State == crv1alpha1.StateFailed: - return true, errors.Errorf("Actionset failed: %#v", as.Status) + return true, errkit.New(fmt.Sprintf("Actionset failed: %#v", as.Status)) case as.Status.State == crv1alpha1.StateComplete: return true, nil } @@ -290,7 +290,7 @@ func (s *E2ESuite) TestKubeTask(c *check.C) { case err != nil, as.Status == nil: return false, err case as.Status.State == crv1alpha1.StateFailed: - return true, errors.Errorf("Actionset failed: %#v", as.Status) + return true, errkit.New(fmt.Sprintf("Actionset failed: %#v", as.Status)) case as.Status.State == crv1alpha1.StateComplete: return true, nil } @@ -524,7 +524,7 @@ func (s *E2ESuite) waitForActionSetComplete(asName string) error { case err != nil, as.Status == nil: return false, err case as.Status.State == crv1alpha1.StateFailed: - return true, errors.Errorf("Actionset failed: %#v", as.Status) + return true, errkit.New(fmt.Sprintf("Actionset failed: %#v", as.Status)) case as.Status.State == crv1alpha1.StateComplete: return true, nil } @@ -553,7 +553,7 @@ func (s *E2ESuite) waitForFunctionPodReady() error { } if len(pods.Items) > 1 { - return false, errors.New("more than one kanister-job pod found") + return false, errkit.New("more than one kanister-job pod found") } return true, nil @@ -564,7 +564,7 @@ func verifyAnnotationsInFunctionPod(funcPodAnnotations, expectedAnnotations map[ for k, v := range expectedAnnotations { val, ok := funcPodAnnotations[k] if !ok || v != val { - return errors.New(fmt.Sprintf("Either key %s, is not found in pod annotations or, its values (%s and %s) don't match", k, v, val)) + return errkit.New(fmt.Sprintf("Either key %s, is not found in pod annotations or, its values (%s and %s) don't match", k, v, val)) } } return nil @@ -574,7 +574,7 @@ func verifyLabelsInFunctionPod(funcPodLabels, expectedLabels map[string]string) for k, v := range expectedLabels { val, ok := funcPodLabels[k] if !ok || v != val { - return errors.New(fmt.Sprintf("Either key %s, is not found in pod labels or, its values (%s and %s) don't match", k, v, val)) + return errkit.New(fmt.Sprintf("Either key %s, is not found in pod labels or, its values (%s and %s) don't match", k, v, val)) } } return nil diff --git a/pkg/testing/integration_test.go b/pkg/testing/integration_test.go index 80bce4d248..baf3ca8fc7 100644 --- a/pkg/testing/integration_test.go +++ b/pkg/testing/integration_test.go @@ -18,12 +18,13 @@ package testing import ( - context "context" + "context" + "fmt" "os" test "testing" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -425,7 +426,7 @@ func (s *IntegrationSuite) createActionset(ctx context.Context, c *check.C, as * case err != nil, as.Status == nil: return false, err case as.Status.State == crv1alpha1.StateFailed: - return true, errors.Errorf("Actionset failed: %#v", as.Status) + return true, errkit.New(fmt.Sprintf("Actionset failed: %#v", as.Status)) case as.Status.State == crv1alpha1.StateComplete: return true, nil } diff --git a/pkg/testutil/func.go b/pkg/testutil/func.go index 8e5beabdf6..bb45370478 100644 --- a/pkg/testutil/func.go +++ b/pkg/testutil/func.go @@ -18,7 +18,7 @@ import ( "context" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kanister "github.com/kanisterio/kanister/pkg" @@ -48,7 +48,7 @@ var ( ) func failFunc(context.Context, param.TemplateParams, map[string]interface{}) (map[string]interface{}, error) { - err := errors.New("Kanister function failed") + err := errkit.New("Kanister function failed") failFuncCh <- err return nil, err } diff --git a/pkg/testutil/mockblockstorage/mockblockstorage.go b/pkg/testutil/mockblockstorage/mockblockstorage.go index d36e38e565..9275cf4a60 100644 --- a/pkg/testutil/mockblockstorage/mockblockstorage.go +++ b/pkg/testutil/mockblockstorage/mockblockstorage.go @@ -20,7 +20,7 @@ import ( "time" uuid "github.com/gofrs/uuid" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "github.com/kanisterio/kanister/pkg/blockstorage" "github.com/kanisterio/kanister/pkg/blockstorage/getter" @@ -57,7 +57,7 @@ func (*mockGetter) Get(storageType blockstorage.Type, config map[string]string) case blockstorage.TypeGPD: return Get(storageType) default: - return nil, errors.New("Get failed") + return nil, errkit.New("Get failed") } } @@ -65,7 +65,7 @@ func (*mockGetter) Get(storageType blockstorage.Type, config map[string]string) func Get(storageType blockstorage.Type) (*Provider, error) { volumeUUID, err := uuid.NewV1() if err != nil { - return nil, errors.Wrap(err, "Failed to create UUID") + return nil, errkit.Wrap(err, "Failed to create UUID") } volume := blockstorage.Volume{ Type: storageType, @@ -84,7 +84,7 @@ func Get(storageType blockstorage.Type) (*Provider, error) { snapVol := volume snapUUID, err := uuid.NewV1() if err != nil { - return nil, errors.Wrap(err, "Failed to create UUID") + return nil, errkit.Wrap(err, "Failed to create UUID") } snapshot := blockstorage.Snapshot{ Type: storageType, @@ -122,7 +122,7 @@ func (p *Provider) VolumeCreate(context.Context, blockstorage.Volume) (*blocksto func (p *Provider) VolumeCreateFromSnapshot(ctx context.Context, snapshot blockstorage.Snapshot, tags map[string]string) (*blockstorage.Volume, error) { volUUID, err := uuid.NewV1() if err != nil { - return nil, errors.Wrap(err, "Failed to create UUID") + return nil, errkit.Wrap(err, "Failed to create UUID") } vol := blockstorage.Volume{ Type: snapshot.Type, @@ -197,7 +197,7 @@ func (p *Provider) SetTags(ctx context.Context, resource interface{}, tags map[s case *blockstorage.Snapshot: return nil default: - return errors.Errorf("Unsupported resource type %v(%T)", res, res) + return errkit.New(fmt.Sprintf("Unsupported resource type %v(%T)", res, res)) } } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 55aff0c8dc..396472f324 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -23,7 +23,7 @@ import ( "strings" "time" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -56,7 +56,7 @@ func PrintStage(description string, i indicator) { func GetNamespaceUID(ctx context.Context, cli kubernetes.Interface, namespace string) (string, error) { ns, err := cli.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}) if err != nil { - return "", errors.Wrapf(err, "Failed to get namespace %s", namespace) + return "", errkit.Wrap(err, "Failed to get namespace", "namespace", namespace) } return string(ns.GetUID()), nil } @@ -85,7 +85,7 @@ func GetIntOrDefault(value string, defaultValue int) (int, error) { v, err := strconv.Atoi(value) if err != nil { v = defaultValue - return v, errors.New("conversion to integer failed, using default value for the field") + return v, errkit.New("conversion to integer failed, using default value for the field") } return v, nil } @@ -121,7 +121,7 @@ func RoundUpDuration(t time.Duration) time.Duration { func CheckRequiredArgs(reqArgs []string, args map[string]interface{}) error { for _, a := range reqArgs { if _, ok := args[a]; !ok { - return errors.Errorf("Required arg missing: %s", a) + return errkit.New(fmt.Sprintf("Required arg missing: %s", a)) } } return nil @@ -132,7 +132,7 @@ func CheckRequiredArgs(reqArgs []string, args map[string]interface{}) error { func CheckSupportedArgs(supportedArgs []string, args map[string]interface{}) error { for a := range args { if !slices.Contains(supportedArgs, a) { - return errors.Errorf("argument %s is not supported", a) + return errkit.New(fmt.Sprintf("argument %s is not supported", a)) } } return nil diff --git a/pkg/validate/error.go b/pkg/validate/error.go index 5011e94a25..50c4c591a4 100644 --- a/pkg/validate/error.go +++ b/pkg/validate/error.go @@ -15,18 +15,16 @@ package validate import ( - "fmt" - - "github.com/pkg/errors" + "github.com/kanisterio/errkit" ) -var errValidate = fmt.Errorf("Validation Failed") +var errValidate = errkit.NewSentinelErr("Validation Failed") func errorf(err error, format string, args ...interface{}) error { - return errors.Wrapf(err, format, args...) + return errkit.Wrap(err, format, args...) } -// IsError returns true iff the underlying cause was a validation error. +// IsError returns true if the underlying cause was a validation error. func IsError(err error) bool { - return errors.Cause(err) == errValidate + return errkit.Is(err, errValidate) } diff --git a/pkg/validate/error_test.go b/pkg/validate/error_test.go index 05b9cba995..cf86806870 100644 --- a/pkg/validate/error_test.go +++ b/pkg/validate/error_test.go @@ -17,7 +17,7 @@ package validate import ( "fmt" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "gopkg.in/check.v1" ) @@ -43,23 +43,23 @@ func (s *ErrorSuite) TestIsError(c *check.C) { is: true, }, { - err: errors.Wrap(nil, "test"), + err: errkit.Wrap(nil, "test"), is: false, }, { - err: errors.WithStack(nil), + err: errkit.WithStack(nil), is: false, }, { - err: errors.Wrap(errValidate, "test"), + err: errkit.Wrap(errValidate, "test"), is: true, }, { - err: errors.WithStack(errValidate), + err: errkit.WithStack(errValidate), is: true, }, { - err: errors.New("test"), + err: errkit.New("test"), is: false, }, } { diff --git a/pkg/validatingwebhook/repositoryserver_handler.go b/pkg/validatingwebhook/repositoryserver_handler.go index b3b9c3509e..b401050c99 100644 --- a/pkg/validatingwebhook/repositoryserver_handler.go +++ b/pkg/validatingwebhook/repositoryserver_handler.go @@ -18,7 +18,7 @@ import ( "context" "fmt" - "github.com/pkg/errors" + "github.com/kanisterio/errkit" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -43,11 +43,11 @@ func (r *RepositoryServerValidator) ValidateUpdate(ctx context.Context, old runt oldrs, ook := old.(*crv1alpha1.RepositoryServer) newrs, nok := new.(*crv1alpha1.RepositoryServer) if !ook || !nok { - return nil, errors.New("Either updated object or the old object is not of type RepositoryServer.cr.kanister.io") + return nil, errkit.New("Either updated object or the old object is not of type RepositoryServer.cr.kanister.io") } errMsg := fmt.Sprintf("RepositoryServer.cr.kanister.io \"%s\" is invalid: spec.repository.rootPath: Invalid value, Value is immutable", newrs.Name) if oldrs.Spec.Repository.RootPath != newrs.Spec.Repository.RootPath { - return nil, errors.New(errMsg) + return nil, errkit.New(errMsg) } return nil, nil }