diff --git a/cmd/apiserver-watcher/run.go b/cmd/apiserver-watcher/run.go index f9205bb28b..dd06d98fc5 100644 --- a/cmd/apiserver-watcher/run.go +++ b/cmd/apiserver-watcher/run.go @@ -59,7 +59,7 @@ func runRunCmd(cmd *cobra.Command, args []string) error { uri, err := url.Parse(runOpts.healthCheckURL) if err != nil { - return fmt.Errorf("failed to parse health-check-url: %v", err) + return fmt.Errorf("failed to parse health-check-url: %w", err) } if !uri.IsAbs() { return fmt.Errorf("invalid URI %q (no scheme)", uri) @@ -82,7 +82,7 @@ func runRunCmd(cmd *cobra.Command, args []string) error { }}, }) if err != nil { - return fmt.Errorf("failed to create httpCheck: %v", err) + return fmt.Errorf("failed to create httpCheck: %w", err) } errCh := make(chan error) diff --git a/cmd/machine-config-controller/start.go b/cmd/machine-config-controller/start.go index 769df54f7a..9d56b8dbaa 100644 --- a/cmd/machine-config-controller/start.go +++ b/cmd/machine-config-controller/start.go @@ -3,6 +3,7 @@ package main import ( "context" "flag" + "fmt" "github.com/golang/glog" "github.com/openshift/machine-config-operator/cmd/common" @@ -14,7 +15,6 @@ import ( "github.com/openshift/machine-config-operator/pkg/controller/render" "github.com/openshift/machine-config-operator/pkg/controller/template" "github.com/openshift/machine-config-operator/pkg/version" - "github.com/pkg/errors" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/leaderelection" @@ -52,7 +52,7 @@ func runStartCmd(cmd *cobra.Command, args []string) { cb, err := clients.NewBuilder(startOpts.kubeconfig) if err != nil { - ctrlcommon.WriteTerminationError(errors.Wrapf(err, "Creating clients")) + ctrlcommon.WriteTerminationError(fmt.Errorf("creating clients: %w", err)) } run := func(ctx context.Context) { ctrlctx := ctrlcommon.CreateControllerContext(cb, ctx.Done(), componentName) diff --git a/cmd/machine-config-daemon/pivot.go b/cmd/machine-config-daemon/pivot.go index 42f5143762..b4163a613e 100644 --- a/cmd/machine-config-daemon/pivot.go +++ b/cmd/machine-config-daemon/pivot.go @@ -12,7 +12,6 @@ import ( "github.com/golang/glog" daemon "github.com/openshift/machine-config-operator/pkg/daemon" - errors "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -50,9 +49,9 @@ func run(_ *cobra.Command, args []string) (retErr error) { data, err := ioutil.ReadFile(etcPivotFile) if err != nil { if os.IsNotExist(err) { - return fmt.Errorf("No container specified") + return fmt.Errorf("no container specified") } - return errors.Wrapf(err, "failed to read from %s", etcPivotFile) + return fmt.Errorf("failed to read from %s: %w", etcPivotFile, err) } container = strings.TrimSpace(string(data)) } else { @@ -74,7 +73,7 @@ func run(_ *cobra.Command, args []string) (retErr error) { if fromEtcPullSpec { if err := os.Remove(etcPivotFile); err != nil { if !os.IsNotExist(err) { - return errors.Wrapf(err, "failed to delete %s", etcPivotFile) + return fmt.Errorf("failed to delete %s: %w", etcPivotFile, err) } } } diff --git a/cmd/machine-config-daemon/start.go b/cmd/machine-config-daemon/start.go index acbc2f9b6d..4b5a4cd34c 100644 --- a/cmd/machine-config-daemon/start.go +++ b/cmd/machine-config-daemon/start.go @@ -3,6 +3,7 @@ package main import ( "bufio" "flag" + "fmt" "io" "net/url" "os" @@ -19,7 +20,6 @@ import ( "github.com/openshift/machine-config-operator/pkg/daemon" daemonconsts "github.com/openshift/machine-config-operator/pkg/daemon/constants" "github.com/openshift/machine-config-operator/pkg/version" - errors "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -68,7 +68,7 @@ func bindPodMounts(rootMount string) error { // This will only affect our mount namespace, not the host output, err := exec.Command("mount", "--rbind", "/run/secrets", targetSecrets).CombinedOutput() if err != nil { - return errors.Wrapf(err, "failed to mount /run/secrets to %s: %s", targetSecrets, string(output)) + return fmt.Errorf("failed to mount /run/secrets to %s: %s: %w", targetSecrets, string(output), err) } return nil } @@ -76,7 +76,7 @@ func bindPodMounts(rootMount string) error { func selfCopyToHost() error { selfExecutableFd, err := os.Open("/proc/self/exe") if err != nil { - return errors.Wrapf(err, "Opening our binary") + return fmt.Errorf("opening our binary: %w", err) } defer selfExecutableFd.Close() if err := os.MkdirAll(filepath.Dir(daemonconsts.HostSelfBinary), 0755); err != nil { @@ -167,7 +167,7 @@ func runStartCmd(cmd *cobra.Command, args []string) { // In the cluster case, for now we copy our binary out to the host // for SELinux reasons, see https://bugzilla.redhat.com/show_bug.cgi?id=1839065 if err := selfCopyToHost(); err != nil { - glog.Fatalf("%v", errors.Wrapf(err, "copying self to host")) + glog.Fatalf("%v", fmt.Errorf("copying self to host: %w", err)) return } diff --git a/internal/kubeutils.go b/internal/kubeutils.go index 2d83734abd..957a49fcf2 100644 --- a/internal/kubeutils.go +++ b/internal/kubeutils.go @@ -41,14 +41,14 @@ func UpdateNodeRetry(client corev1client.NodeInterface, lister corev1lister.Node patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldNode, newNode, corev1.Node{}) if err != nil { - return fmt.Errorf("failed to create patch for node %q: %v", nodeName, err) + return fmt.Errorf("failed to create patch for node %q: %w", nodeName, err) } node, err = client.Patch(context.TODO(), nodeName, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) return err }); err != nil { // may be conflict if max retries were hit - return nil, fmt.Errorf("unable to update node %q: %v", node, err) + return nil, fmt.Errorf("unable to update node %q: %w", node, err) } return node, nil } diff --git a/lib/resourceread/machineconfig.go b/lib/resourceread/machineconfig.go index 1b7e7f3475..a50a5f2ba5 100644 --- a/lib/resourceread/machineconfig.go +++ b/lib/resourceread/machineconfig.go @@ -28,7 +28,7 @@ func ReadMachineConfigV1(objBytes []byte) (*mcfgv1.MachineConfig, error) { m, err := runtime.Decode(mcfgCodecs.UniversalDecoder(mcfgv1.SchemeGroupVersion), objBytes) if err != nil { - return nil, fmt.Errorf("failed to decode raw bytes to mcfgv1.SchemeGroupVersion: %v", err) + return nil, fmt.Errorf("failed to decode raw bytes to mcfgv1.SchemeGroupVersion: %w", err) } if m == nil { return nil, fmt.Errorf("expected mcfgv1.SchemeGroupVersion but got nil") diff --git a/pkg/controller/bootstrap/bootstrap.go b/pkg/controller/bootstrap/bootstrap.go index 5cbb6cd009..d616657600 100644 --- a/pkg/controller/bootstrap/bootstrap.go +++ b/pkg/controller/bootstrap/bootstrap.go @@ -87,13 +87,13 @@ func (b *Bootstrap) Run(destDir string) error { file, err := os.Open(filepath.Join(b.manifestDir, info.Name())) if err != nil { - return fmt.Errorf("error opening %s: %v", file.Name(), err) + return fmt.Errorf("error opening %s: %w", file.Name(), err) } defer file.Close() manifests, err := parseManifests(file.Name(), file) if err != nil { - return fmt.Errorf("error parsing manifests from %s: %v", file.Name(), err) + return fmt.Errorf("error parsing manifests from %s: %w", file.Name(), err) } for idx, m := range manifests { @@ -104,7 +104,7 @@ func (b *Bootstrap) Run(destDir string) error { glog.V(4).Infof("skipping path %q [%d] manifest because it is not part of expected api group: %v", file.Name(), idx+1, err) continue } - return fmt.Errorf("error parsing %q [%d] manifest: %v", file.Name(), idx+1, err) + return fmt.Errorf("error parsing %q [%d] manifest: %w", file.Name(), idx+1, err) } switch obj := obji.(type) { @@ -268,7 +268,7 @@ func parseManifests(filename string, r io.Reader) ([]manifest, error) { if err == io.EOF { return manifests, nil } - return manifests, fmt.Errorf("error parsing %q: %v", filename, err) + return manifests, fmt.Errorf("error parsing %q: %w", filename, err) } m.Raw = bytes.TrimSpace(m.Raw) if len(m.Raw) == 0 || bytes.Equal(m.Raw, []byte("null")) { diff --git a/pkg/controller/common/helpers.go b/pkg/controller/common/helpers.go index 99eebfee2c..5730b90723 100644 --- a/pkg/controller/common/helpers.go +++ b/pkg/controller/common/helpers.go @@ -36,7 +36,6 @@ import ( validate3 "github.com/coreos/ignition/v2/config/validate" "github.com/ghodss/yaml" "github.com/golang/glog" - "github.com/pkg/errors" "github.com/vincent-petithory/dataurl" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -210,17 +209,17 @@ func ConvertRawExtIgnitionToV3(inRawExtIgn *runtime.RawExtension) (runtime.RawEx } else { ignCfg, rpt, err := ign2.Parse(inRawExtIgn.Raw) if err != nil || rpt.IsFatal() { - return runtime.RawExtension{}, errors.Errorf("parsing Ignition config spec v2.2 failed with error: %v\nReport: %v", err, rpt) + return runtime.RawExtension{}, fmt.Errorf("parsing Ignition config spec v2.2 failed with error: %w\nReport: %v", err, rpt) } converted3, err = convertIgnition2to3(ignCfg) if err != nil { - return runtime.RawExtension{}, errors.Errorf("failed to convert config from spec v2.2 to v3.2: %v", err) + return runtime.RawExtension{}, fmt.Errorf("failed to convert config from spec v2.2 to v3.2: %w", err) } } outIgnV3, err := json.Marshal(converted3) if err != nil { - return runtime.RawExtension{}, errors.Errorf("failed to marshal converted config: %v", err) + return runtime.RawExtension{}, fmt.Errorf("failed to marshal converted config: %w", err) } outRawExt := runtime.RawExtension{} @@ -239,7 +238,7 @@ func ConvertRawExtIgnitionToV3_1(inRawExtIgn *runtime.RawExtension) (runtime.Raw ignCfgV3, rptV3, errV3 := ign3.Parse(rawExt.Raw) if errV3 != nil || rptV3.IsFatal() { - return runtime.RawExtension{}, errors.Errorf("parsing Ignition config failed with error: %v\nReport: %v", errV3, rptV3) + return runtime.RawExtension{}, fmt.Errorf("parsing Ignition config failed with error: %w\nReport: %v", errV3, rptV3) } ignCfgV31, err := convertIgnition32to31(ignCfgV3) @@ -249,7 +248,7 @@ func ConvertRawExtIgnitionToV3_1(inRawExtIgn *runtime.RawExtension) (runtime.Raw outIgnV31, err := json.Marshal(ignCfgV31) if err != nil { - return runtime.RawExtension{}, errors.Errorf("failed to marshal converted config: %v", err) + return runtime.RawExtension{}, fmt.Errorf("failed to marshal converted config: %w", err) } outRawExt := runtime.RawExtension{} @@ -263,17 +262,17 @@ func ConvertRawExtIgnitionToV3_1(inRawExtIgn *runtime.RawExtension) (runtime.Raw func ConvertRawExtIgnitionToV2(inRawExtIgn *runtime.RawExtension) (runtime.RawExtension, error) { ignCfg, rpt, err := ign3.Parse(inRawExtIgn.Raw) if err != nil || rpt.IsFatal() { - return runtime.RawExtension{}, errors.Errorf("parsing Ignition config spec v3.2 failed with error: %v\nReport: %v", err, rpt) + return runtime.RawExtension{}, fmt.Errorf("parsing Ignition config spec v3.2 failed with error: %w\nReport: %v", err, rpt) } converted2, err := convertIgnition3to2(ignCfg) if err != nil { - return runtime.RawExtension{}, errors.Errorf("failed to convert config from spec v3.2 to v2.2: %v", err) + return runtime.RawExtension{}, fmt.Errorf("failed to convert config from spec v3.2 to v2.2: %w", err) } outIgnV2, err := json.Marshal(converted2) if err != nil { - return runtime.RawExtension{}, errors.Errorf("failed to marshal converted config: %v", err) + return runtime.RawExtension{}, fmt.Errorf("failed to marshal converted config: %w", err) } outRawExt := runtime.RawExtension{} @@ -293,7 +292,7 @@ func convertIgnition2to3(ign2config ign2types.Config) (ign3types.Config, error) ign2_3config := ign2_3.Translate(ign2config) ign3_0config, err := v23tov30.Translate(ign2_3config, fsMap) if err != nil { - return ign3types.Config{}, errors.Errorf("unable to convert Ignition spec v2 config to v3: %v", err) + return ign3types.Config{}, fmt.Errorf("unable to convert Ignition spec v2 config to v3: %w", err) } // Workaround to get a v3.2 config as output converted3 := translate3.Translate(translate3_1.Translate(ign3_0config)) @@ -306,7 +305,7 @@ func convertIgnition2to3(ign2config ign2types.Config) (ign3types.Config, error) func convertIgnition3to2(ign3config ign3types.Config) (ign2types.Config, error) { converted2, err := v32tov22.Translate(ign3config) if err != nil { - return ign2types.Config{}, errors.Errorf("unable to convert Ignition spec v3 config to v2: %v", err) + return ign2types.Config{}, fmt.Errorf("unable to convert Ignition spec v3 config to v2: %w", err) } glog.V(4).Infof("Successfully translated Ignition spec v3 config to Ignition spec v2 config: %v", converted2) @@ -317,7 +316,7 @@ func convertIgnition3to2(ign3config ign3types.Config) (ign2types.Config, error) func convertIgnition32to31(ign3config ign3types.Config) (ign3_1types.Config, error) { converted31, err := v32tov31.Translate(ign3config) if err != nil { - return ign3_1types.Config{}, errors.Errorf("unable to convert Ignition spec v3_2 config to v3_1: %v", err) + return ign3_1types.Config{}, fmt.Errorf("unable to convert Ignition spec v3_2 config to v3_1: %w", err) } glog.V(4).Infof("Successfully translated Ignition spec v3_2 config to Ignition spec v3_1 config: %v", converted31) @@ -336,7 +335,7 @@ func ValidateIgnition(ignconfig interface{}) error { return nil } if report := validate2.ValidateWithoutSource(reflect.ValueOf(cfg)); report.IsFatal() { - return errors.Errorf("invalid ignition V2 config found: %v", report) + return fmt.Errorf("invalid ignition V2 config found: %v", report) } return validateIgn2FileModes(cfg) case ign3types.Config: @@ -344,11 +343,11 @@ func ValidateIgnition(ignconfig interface{}) error { return nil } if report := validate3.ValidateWithContext(cfg, nil); report.IsFatal() { - return errors.Errorf("invalid ignition V3 config found: %v", report) + return fmt.Errorf("invalid ignition V3 config found: %v", report) } return validateIgn3FileModes(cfg) default: - return errors.Errorf("unrecognized ignition type") + return fmt.Errorf("unrecognized ignition type") } } @@ -425,7 +424,7 @@ func InSlice(elem string, slice []string) bool { // ValidateMachineConfig validates that given MachineConfig Spec is valid. func ValidateMachineConfig(cfg mcfgv1.MachineConfigSpec) error { if !(cfg.KernelType == "" || cfg.KernelType == KernelTypeDefault || cfg.KernelType == KernelTypeRealtime) { - return errors.Errorf("kernelType=%s is invalid", cfg.KernelType) + return fmt.Errorf("kernelType=%s is invalid", cfg.KernelType) } if cfg.Config.Raw != nil { @@ -467,15 +466,15 @@ func IgnParseWrapper(rawIgn []byte) (interface{}, error) { // If the error is still UnknownVersion it's not a 3.2/3.1/3.0 or 2.x config, thus unsupported if errV2.Error() == ign2error.ErrUnknownVersion.Error() { - return ign3types.Config{}, errors.Errorf("parsing Ignition config failed: unknown version. Supported spec versions: 2.2, 3.0, 3.1, 3.2") + return ign3types.Config{}, fmt.Errorf("parsing Ignition config failed: unknown version. Supported spec versions: 2.2, 3.0, 3.1, 3.2") } - return ign3types.Config{}, errors.Errorf("parsing Ignition spec v2 failed with error: %v\nReport: %v", errV2, rptV2) + return ign3types.Config{}, fmt.Errorf("parsing Ignition spec v2 failed with error: %w\nReport: %v", errV2, rptV2) } - return ign3types.Config{}, errors.Errorf("parsing Ignition config spec v3.0 failed with error: %v\nReport: %v", errV3_0, rptV3_0) + return ign3types.Config{}, fmt.Errorf("parsing Ignition config spec v3.0 failed with error: %w\nReport: %v", errV3_0, rptV3_0) } - return ign3types.Config{}, errors.Errorf("parsing Ignition config spec v3.1 failed with error: %v\nReport: %v", errV3_1, rptV3_1) + return ign3types.Config{}, fmt.Errorf("parsing Ignition config spec v3.1 failed with error: %w\nReport: %v", errV3_1, rptV3_1) } - return ign3types.Config{}, errors.Errorf("parsing Ignition config spec v3.2 failed with error: %v\nReport: %v", errV3_2, rptV3_2) + return ign3types.Config{}, fmt.Errorf("parsing Ignition config spec v3.2 failed with error: %w\nReport: %v", errV3_2, rptV3_2) } // ParseAndConvertConfig parses rawIgn for both V2 and V3 ignition configs and returns @@ -483,7 +482,7 @@ func IgnParseWrapper(rawIgn []byte) (interface{}, error) { func ParseAndConvertConfig(rawIgn []byte) (ign3types.Config, error) { ignconfigi, err := IgnParseWrapper(rawIgn) if err != nil { - return ign3types.Config{}, errors.Wrapf(err, "failed to parse Ignition config") + return ign3types.Config{}, fmt.Errorf("failed to parse Ignition config: %w", err) } switch typedConfig := ignconfigi.(type) { @@ -496,11 +495,11 @@ func ParseAndConvertConfig(rawIgn []byte) (ign3types.Config, error) { } convertedIgnV3, err := convertIgnition2to3(ignconfv2) if err != nil { - return ign3types.Config{}, errors.Wrapf(err, "failed to convert Ignition config spec v2 to v3") + return ign3types.Config{}, fmt.Errorf("failed to convert Ignition config spec v2 to v3: %w", err) } return convertedIgnV3, nil default: - return ign3types.Config{}, errors.Errorf("unexpected type for ignition config: %v", typedConfig) + return ign3types.Config{}, fmt.Errorf("unexpected type for ignition config: %v", typedConfig) } } @@ -575,11 +574,11 @@ func removeIgnDuplicateFilesUnitsUsers(ignConfig ign2types.Config) (ign2types.Co if len(users) > 0 { outUser := users[len(users)-1] if outUser.Name != "core" { - return ignConfig, errors.Errorf("unexpected user with name: %v. Only core user is supported.", outUser.Name) + return ignConfig, fmt.Errorf("unexpected user with name: %v. Only core user is supported", outUser.Name) } for i := len(users) - 2; i >= 0; i-- { if users[i].Name != "core" { - return ignConfig, errors.Errorf("unexpected user with name: %v. Only core user is supported.", users[i].Name) + return ignConfig, fmt.Errorf("unexpected user with name: %v. Only core user is supported", users[i].Name) } for j := range users[i].SSHAuthorizedKeys { outUser.SSHAuthorizedKeys = append(outUser.SSHAuthorizedKeys, users[i].SSHAuthorizedKeys[j]) @@ -605,7 +604,7 @@ func TranspileCoreOSConfigToIgn(files, units []string) (*ign3types.Config, error for _, contents := range files { f := new(fcctbase.File) if err := yaml.Unmarshal([]byte(contents), f); err != nil { - return nil, fmt.Errorf("failed to unmarshal %q into struct: %v", contents, err) + return nil, fmt.Errorf("failed to unmarshal %q into struct: %w", contents, err) } f.Overwrite = &overwrite @@ -614,7 +613,7 @@ func TranspileCoreOSConfigToIgn(files, units []string) (*ign3types.Config, error ctCfg.Storage.Files = append(ctCfg.Storage.Files, *f) ign3_0config, tSet, err := ctCfg.ToIgn3_0() if err != nil { - return nil, fmt.Errorf("failed to transpile config to Ignition config %s\nTranslation set: %v", err, tSet) + return nil, fmt.Errorf("failed to transpile config to Ignition config %w\nTranslation set: %v", err, tSet) } ign3_2config := translate3.Translate(translate3_1.Translate(ign3_0config)) outConfig = ign3.Merge(outConfig, ign3_2config) @@ -623,7 +622,7 @@ func TranspileCoreOSConfigToIgn(files, units []string) (*ign3types.Config, error for _, contents := range units { u := new(fcctbase.Unit) if err := yaml.Unmarshal([]byte(contents), u); err != nil { - return nil, fmt.Errorf("failed to unmarshal systemd unit into struct: %v", err) + return nil, fmt.Errorf("failed to unmarshal systemd unit into struct: %w", err) } // Add the unit to the config @@ -631,7 +630,7 @@ func TranspileCoreOSConfigToIgn(files, units []string) (*ign3types.Config, error ctCfg.Systemd.Units = append(ctCfg.Systemd.Units, *u) ign3_0config, tSet, err := ctCfg.ToIgn3_0() if err != nil { - return nil, fmt.Errorf("failed to transpile config to Ignition config %s\nTranslation set: %v", err, tSet) + return nil, fmt.Errorf("failed to transpile config to Ignition config %w\nTranslation set: %v", err, tSet) } ign3_2config := translate3.Translate(translate3_1.Translate(ign3_0config)) outConfig = ign3.Merge(outConfig, ign3_2config) @@ -644,7 +643,7 @@ func TranspileCoreOSConfigToIgn(files, units []string) (*ign3types.Config, error func MachineConfigFromIgnConfig(role, name string, ignCfg interface{}) (*mcfgv1.MachineConfig, error) { rawIgnCfg, err := json.Marshal(ignCfg) if err != nil { - return nil, fmt.Errorf("error marshalling Ignition config: %v", err) + return nil, fmt.Errorf("error marshalling Ignition config: %w", err) } return MachineConfigFromRawIgnConfig(role, name, rawIgnCfg) } @@ -680,7 +679,7 @@ func GetManagedKey(pool *mcfgv1.MachineConfigPool, client mcfgclientset.Interfac } old, err := client.MachineconfigurationV1().MachineConfigs().Get(context.TODO(), deprecatedKey, metav1.GetOptions{}) if err != nil && !kerr.IsNotFound(err) { - return "", fmt.Errorf("could not get MachineConfig %q: %v", deprecatedKey, err) + return "", fmt.Errorf("could not get MachineConfig %q: %w", deprecatedKey, err) } // this means no previous CR config were here, so we can start fresh if kerr.IsNotFound(err) { diff --git a/pkg/controller/container-runtime-config/container_runtime_config_bootstrap.go b/pkg/controller/container-runtime-config/container_runtime_config_bootstrap.go index 5f70e3e581..bd66d7bf56 100644 --- a/pkg/controller/container-runtime-config/container_runtime_config_bootstrap.go +++ b/pkg/controller/container-runtime-config/container_runtime_config_bootstrap.go @@ -22,7 +22,7 @@ func RunContainerRuntimeBootstrap(templateDir string, crconfigs []*mcfgv1.Contai // use selector since label matching part of a ContaineRuntimeConfig is not handled during the bootstrap selector, err := metav1.LabelSelectorAsSelector(cfg.Spec.MachineConfigPoolSelector) if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) + return nil, fmt.Errorf("invalid label selector: %w", err) } for _, pool := range mcpPools { // If a pool with a nil or empty selector creeps in, it should match nothing, not everything. @@ -34,7 +34,7 @@ func RunContainerRuntimeBootstrap(templateDir string, crconfigs []*mcfgv1.Contai // Generate the original ContainerRuntimeConfig originalStorageIgn, _, _, err := generateOriginalContainerRuntimeConfigs(templateDir, controllerConfig, role) if err != nil { - return nil, fmt.Errorf("could not generate origin ContainerRuntime Configs: %v", err) + return nil, fmt.Errorf("could not generate origin ContainerRuntime Configs: %w", err) } var configFileList []generatedConfigFile @@ -55,15 +55,15 @@ func RunContainerRuntimeBootstrap(templateDir string, crconfigs []*mcfgv1.Contai ctrRuntimeConfigIgn := createNewIgnition(configFileList) if err != nil { - return nil, fmt.Errorf("could not marshal container runtime ignition: %v", err) + return nil, fmt.Errorf("could not marshal container runtime ignition: %w", err) } managedKey, err := generateBootstrapManagedKeyContainerConfig(pool, managedKeyExist) if err != nil { - return nil, fmt.Errorf("could not marshal container runtime ignition: %v", err) + return nil, fmt.Errorf("could not marshal container runtime ignition: %w", err) } mc, err := ctrlcommon.MachineConfigFromIgnConfig(role, managedKey, ctrRuntimeConfigIgn) if err != nil { - return nil, fmt.Errorf("could not create MachineConfig from new Ignition config: %v", err) + return nil, fmt.Errorf("could not create MachineConfig from new Ignition config: %w", err) } mc.SetAnnotations(map[string]string{ ctrlcommon.GeneratedByControllerVersionAnnotationKey: version.Hash, diff --git a/pkg/controller/container-runtime-config/container_runtime_config_controller.go b/pkg/controller/container-runtime-config/container_runtime_config_controller.go index 6edae9057b..39f478d6cf 100644 --- a/pkg/controller/container-runtime-config/container_runtime_config_controller.go +++ b/pkg/controller/container-runtime-config/container_runtime_config_controller.go @@ -24,6 +24,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" + kubeErrs "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/jsonmergepatch" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" @@ -258,7 +259,7 @@ func (ctrl *Controller) deleteContainerRuntimeConfig(obj interface{}) { } } if err := ctrl.cascadeDelete(cfg); err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't delete object %#v: %v", cfg, err)) + utilruntime.HandleError(fmt.Errorf("couldn't delete object %#v: %w", cfg, err)) } else { glog.V(4).Infof("Deleted ContainerRuntimeConfig %s and restored default config", cfg.Name) } @@ -282,7 +283,7 @@ func (ctrl *Controller) cascadeDelete(cfg *mcfgv1.ContainerRuntimeConfig) error func (ctrl *Controller) enqueue(cfg *mcfgv1.ContainerRuntimeConfig) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(cfg) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", cfg, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", cfg, err)) return } ctrl.queue.Add(key) @@ -291,7 +292,7 @@ func (ctrl *Controller) enqueue(cfg *mcfgv1.ContainerRuntimeConfig) { func (ctrl *Controller) enqueueRateLimited(cfg *mcfgv1.ContainerRuntimeConfig) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(cfg) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", cfg, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", cfg, err)) return } ctrl.queue.AddRateLimited(key) @@ -377,7 +378,7 @@ func generateOriginalContainerRuntimeConfigs(templateDir string, cc *mcfgv1.Cont rc := &mtmpl.RenderConfig{ControllerConfigSpec: &cc.Spec} generatedConfigs, err := mtmpl.GenerateMachineConfigsForRole(rc, role, templateDir) if err != nil { - return nil, nil, nil, fmt.Errorf("generateMachineConfigsforRole failed with error %s", err) + return nil, nil, nil, fmt.Errorf("generateMachineConfigsforRole failed with error %w", err) } // Find generated storage.conf, registries.conf, and policy.json var ( @@ -409,7 +410,8 @@ func generateOriginalContainerRuntimeConfigs(templateDir string, cc *mcfgv1.Cont } } if errStorage != nil || errRegistries != nil || errPolicy != nil { - return nil, nil, nil, fmt.Errorf("could not generate old container runtime configs: %v, %v, %v", errStorage, errRegistries, errPolicy) + errs := kubeErrs.NewAggregate([]error{errStorage, errRegistries, errPolicy}) + return nil, nil, nil, fmt.Errorf("could not generate old container runtime configs: %w", errs) } return gmcStorageConfig, gmcRegistriesConfig, gmcPolicyJSON, nil @@ -509,7 +511,7 @@ func (ctrl *Controller) syncContainerRuntimeConfig(key string) error { // Get ControllerConfig controllerConfig, err := ctrl.ccLister.Get(ctrlcommon.ControllerConfigName) if err != nil { - return fmt.Errorf("could not get ControllerConfig %v", err) + return fmt.Errorf("could not get ControllerConfig %w", err) } // Find all MachineConfigPools @@ -635,7 +637,7 @@ func (ctrl *Controller) cleanUpDuplicatedMC() error { // Get all machine configs mcList, err := ctrl.client.MachineconfigurationV1().MachineConfigs().List(context.TODO(), metav1.ListOptions{}) if err != nil { - return fmt.Errorf("error listing containerruntime machine configs: %v", err) + return fmt.Errorf("error listing containerruntime machine configs: %w", err) } for _, mc := range mcList.Items { if !strings.Contains(mc.Name, generatedCtrCfg) { @@ -644,7 +646,7 @@ func (ctrl *Controller) cleanUpDuplicatedMC() error { // delete the containerruntime mc if its degraded if mc.Annotations[ctrlcommon.GeneratedByControllerVersionAnnotationKey] != version.Hash { if err := ctrl.client.MachineconfigurationV1().MachineConfigs().Delete(context.TODO(), mc.Name, metav1.DeleteOptions{}); err != nil { - return fmt.Errorf("error deleting degraded containerruntime machine config %s: %v", mc.Name, err) + return fmt.Errorf("error deleting degraded containerruntime machine config %s: %w", mc.Name, err) } } @@ -660,11 +662,11 @@ func mergeConfigChanges(origFile *ign3types.File, cfg *mcfgv1.ContainerRuntimeCo } contents, err := ctrlcommon.DecodeIgnitionFileContents(origFile.Contents.Source, origFile.Contents.Compression) if err != nil { - return nil, fmt.Errorf("could not decode original Container Runtime config: %v", err) + return nil, fmt.Errorf("could not decode original Container Runtime config: %w", err) } cfgTOML, err := update(contents, cfg.Spec.ContainerRuntimeConfig) if err != nil { - return nil, fmt.Errorf("could not update container runtime config with new changes: %v", err) + return nil, fmt.Errorf("could not update container runtime config with new changes: %w", err) } return cfgTOML, nil } @@ -713,7 +715,7 @@ func (ctrl *Controller) syncImageConfig(key string) error { // Get ControllerConfig controllerConfig, err := ctrl.ccLister.Get(ctrlcommon.ControllerConfigName) if err != nil { - return fmt.Errorf("could not get ControllerConfig %v", err) + return fmt.Errorf("could not get ControllerConfig: %w", err) } // Find all ImageContentSourcePolicy objects @@ -751,11 +753,11 @@ func (ctrl *Controller) syncImageConfig(key string) error { } rawRegistriesIgn, err := json.Marshal(registriesIgn) if err != nil { - return fmt.Errorf("could not encode registries Ignition config: %v", err) + return fmt.Errorf("could not encode registries Ignition config: %w", err) } mc, err := ctrl.client.MachineconfigurationV1().MachineConfigs().Get(context.TODO(), managedKey, metav1.GetOptions{}) if err != nil && !errors.IsNotFound(err) { - return fmt.Errorf("could not find MachineConfig: %v", err) + return fmt.Errorf("could not find MachineConfig: %w", err) } isNotFound := errors.IsNotFound(err) if !isNotFound && equality.Semantic.DeepEqual(rawRegistriesIgn, mc.Spec.Config.Raw) { @@ -771,7 +773,7 @@ func (ctrl *Controller) syncImageConfig(key string) error { tempIgnCfg := ctrlcommon.NewIgnConfig() mc, err = ctrlcommon.MachineConfigFromIgnConfig(role, managedKey, tempIgnCfg) if err != nil { - return fmt.Errorf("could not create MachineConfig from new Ignition config: %v", err) + return fmt.Errorf("could not create MachineConfig from new Ignition config: %w", err) } } mc.Spec.Config.Raw = rawRegistriesIgn @@ -795,7 +797,7 @@ func (ctrl *Controller) syncImageConfig(key string) error { return err }); err != nil { - return fmt.Errorf("could not Create/Update MachineConfig: %v", err) + return fmt.Errorf("could not Create/Update MachineConfig: %w", err) } if applied { glog.Infof("Applied ImageConfig cluster on MachineConfigPool %v", pool.Name) @@ -816,7 +818,7 @@ func registriesConfigIgnition(templateDir string, controllerConfig *mcfgv1.Contr // Generate the original registries config _, originalRegistriesIgn, originalPolicyIgn, err := generateOriginalContainerRuntimeConfigs(templateDir, controllerConfig, role) if err != nil { - return nil, fmt.Errorf("could not generate origin ContainerRuntime Configs: %v", err) + return nil, fmt.Errorf("could not generate origin ContainerRuntime Configs: %w", err) } if insecureRegs != nil || blockedRegs != nil || len(icspRules) != 0 { @@ -825,11 +827,11 @@ func registriesConfigIgnition(templateDir string, controllerConfig *mcfgv1.Contr } contents, err := ctrlcommon.DecodeIgnitionFileContents(originalRegistriesIgn.Contents.Source, originalRegistriesIgn.Contents.Compression) if err != nil { - return nil, fmt.Errorf("could not decode original registries config: %v", err) + return nil, fmt.Errorf("could not decode original registries config: %w", err) } registriesTOML, err = updateRegistriesConfig(contents, insecureRegs, blockedRegs, icspRules) if err != nil { - return nil, fmt.Errorf("could not update registries config with new changes: %v", err) + return nil, fmt.Errorf("could not update registries config with new changes: %w", err) } } if blockedRegs != nil || allowedRegs != nil { @@ -838,11 +840,11 @@ func registriesConfigIgnition(templateDir string, controllerConfig *mcfgv1.Contr } contents, err := ctrlcommon.DecodeIgnitionFileContents(originalPolicyIgn.Contents.Source, originalPolicyIgn.Contents.Compression) if err != nil { - return nil, fmt.Errorf("could not decode original policy json: %v", err) + return nil, fmt.Errorf("could not decode original policy json: %w", err) } policyJSON, err = updatePolicyJSON(contents, blockedRegs, allowedRegs) if err != nil { - return nil, fmt.Errorf("could not update policy json with new changes: %v", err) + return nil, fmt.Errorf("could not update policy json with new changes: %w", err) } } generatedConfigFileList := []generatedConfigFile{ @@ -992,7 +994,7 @@ func (ctrl *Controller) getPoolsForContainerRuntimeConfig(config *mcfgv1.Contain selector, err := metav1.LabelSelectorAsSelector(config.Spec.MachineConfigPoolSelector) if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) + return nil, fmt.Errorf("invalid label selector: %w", err) } var pools []*mcfgv1.MachineConfigPool diff --git a/pkg/controller/container-runtime-config/helpers.go b/pkg/controller/container-runtime-config/helpers.go index 8a7becbd9e..b18b18e929 100644 --- a/pkg/controller/container-runtime-config/helpers.go +++ b/pkg/controller/container-runtime-config/helpers.go @@ -140,7 +140,7 @@ func createNewIgnition(configs []generatedConfigFile) ign3types.Config { func findStorageConfig(mc *mcfgv1.MachineConfig) (*ign3types.File, error) { ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing Storage Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing Storage Ignition config failed with error: %w", err) } for _, c := range ignCfg.Storage.Files { if c.Path == storageConfigPath { @@ -154,7 +154,7 @@ func findStorageConfig(mc *mcfgv1.MachineConfig) (*ign3types.File, error) { func findRegistriesConfig(mc *mcfgv1.MachineConfig) (*ign3types.File, error) { ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing Registries Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing Registries Ignition config failed with error: %w", err) } for _, c := range ignCfg.Storage.Files { if c.Path == registriesConfigPath { @@ -167,7 +167,7 @@ func findRegistriesConfig(mc *mcfgv1.MachineConfig) (*ign3types.File, error) { func findPolicyJSON(mc *mcfgv1.MachineConfig) (*ign3types.File, error) { ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing Policy JSON Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing Policy JSON Ignition config failed with error: %w", err) } for _, c := range ignCfg.Storage.Files { if c.Path == policyConfigPath { @@ -187,7 +187,7 @@ func getManagedKeyCtrCfg(pool *mcfgv1.MachineConfigPool, client mcfgclientset.In // Get all the ctrcfg CRs ctrcfgListAll, err := client.MachineconfigurationV1().ContainerRuntimeConfigs().List(context.TODO(), metav1.ListOptions{}) if err != nil { - return "", fmt.Errorf("error listing container runtime configs: %v", err) + return "", fmt.Errorf("error listing container runtime configs: %w", err) } // If there is no ctrcfg in the list, return the default MC name with no suffix if ctrcfgListAll == nil || len(ctrcfgListAll.Items) == 0 { @@ -198,7 +198,7 @@ func getManagedKeyCtrCfg(pool *mcfgv1.MachineConfigPool, client mcfgclientset.In for _, ctrcfg := range ctrcfgListAll.Items { selector, err := metav1.LabelSelectorAsSelector(ctrcfg.Spec.MachineConfigPoolSelector) if err != nil { - return "", fmt.Errorf("invalid label selector: %v", err) + return "", fmt.Errorf("invalid label selector: %w", err) } if selector.Empty() || !selector.Matches(labels.Set(pool.Labels)) { continue @@ -231,7 +231,7 @@ func getManagedKeyCtrCfg(pool *mcfgv1.MachineConfigPool, client mcfgclientset.In // Convert the suffix value to int so we can look through the list and grab the max suffix created so far intVal, err := strconv.Atoi(val) if err != nil { - return "", fmt.Errorf("error converting %s to int: %v", val, err) + return "", fmt.Errorf("error converting %s to int: %w", val, err) } if intVal > suffixNum { suffixNum = intVal @@ -288,7 +288,7 @@ func wrapErrorWithCondition(err error, args ...interface{}) mcfgv1.ContainerRunt func updateStorageConfig(data []byte, internal *mcfgv1.ContainerRuntimeConfiguration) ([]byte, error) { tomlConf := new(tomlConfigStorage) if _, err := toml.DecodeReader(bytes.NewBuffer(data), tomlConf); err != nil { - return nil, fmt.Errorf("error decoding crio config: %v", err) + return nil, fmt.Errorf("error decoding crio config: %w", err) } if internal.OverlaySize.Value() < 0 { @@ -312,7 +312,7 @@ func addTOMLgeneratedConfigFile(configFileList []generatedConfigFile, path strin var newData bytes.Buffer encoder := toml.NewEncoder(&newData) if err := encoder.Encode(tomlConf); err != nil { - return nil, fmt.Errorf("error encoding toml for CRIO drop-in files: %v", err) + return nil, fmt.Errorf("error encoding toml for CRIO drop-in files: %w", err) } configFileList = append(configFileList, generatedConfigFile{filePath: path, data: newData.Bytes()}) return configFileList, nil @@ -374,7 +374,7 @@ func updateSearchRegistriesConfig(searchRegs []string) []generatedConfigFile { func updateRegistriesConfig(data []byte, internalInsecure, internalBlocked []string, icspRules []*apioperatorsv1alpha1.ImageContentSourcePolicy) ([]byte, error) { tomlConf := sysregistriesv2.V2RegistriesConf{} if _, err := toml.Decode(string(data), &tomlConf); err != nil { - return nil, fmt.Errorf("error unmarshalling registries config: %v", err) + return nil, fmt.Errorf("error unmarshalling registries config: %w", err) } if err := validateRegistriesConfScopes(internalInsecure, internalBlocked, []string{}, icspRules); err != nil { @@ -417,7 +417,7 @@ func updatePolicyJSON(data []byte, internalBlocked, internalAllowed []string) ([ decoder := json.NewDecoder(bytes.NewBuffer(data)) err := decoder.Decode(policyObj) if err != nil { - return nil, fmt.Errorf("error decoding policy json: %v", err) + return nil, fmt.Errorf("error decoding policy json: %w", err) } transportScopes := make(signature.PolicyTransportScopes) if len(internalAllowed) > 0 { diff --git a/pkg/controller/kubelet-config/helpers.go b/pkg/controller/kubelet-config/helpers.go index a7f336bc3e..2974d2eb70 100644 --- a/pkg/controller/kubelet-config/helpers.go +++ b/pkg/controller/kubelet-config/helpers.go @@ -134,14 +134,14 @@ func createNewDefaultFeatureGate() *osev1.FeatureGate { func findKubeletConfig(mc *mcfgv1.MachineConfig) (*ign3types.File, error) { ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing Kubelet Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing Kubelet Ignition config failed with error: %w", err) } for _, c := range ignCfg.Storage.Files { if c.Path == "/etc/kubernetes/kubelet.conf" { return &c, nil } } - return nil, fmt.Errorf("Could not find Kubelet Config") + return nil, fmt.Errorf("could not find Kubelet Config") } // nolint: dupl @@ -149,7 +149,7 @@ func getManagedKubeletConfigKey(pool *mcfgv1.MachineConfigPool, client mcfgclien // Get all the kubelet config CRs kcListAll, err := client.MachineconfigurationV1().KubeletConfigs().List(context.TODO(), metav1.ListOptions{}) if err != nil { - return "", fmt.Errorf("error listing kubelet configs: %v", err) + return "", fmt.Errorf("error listing kubelet configs: %w", err) } // If there is no kubelet config in the list, return the default MC name with no suffix @@ -161,7 +161,7 @@ func getManagedKubeletConfigKey(pool *mcfgv1.MachineConfigPool, client mcfgclien for _, kc := range kcListAll.Items { selector, err := metav1.LabelSelectorAsSelector(kc.Spec.MachineConfigPoolSelector) if err != nil { - return "", fmt.Errorf("invalid label selector: %v", err) + return "", fmt.Errorf("invalid label selector: %w", err) } if selector.Empty() || !selector.Matches(labels.Set(pool.Labels)) { continue @@ -199,7 +199,7 @@ func getManagedKubeletConfigKey(pool *mcfgv1.MachineConfigPool, client mcfgclien // Convert the suffix value to int so we can look through the list and grab the max suffix created so far intVal, err := strconv.Atoi(val) if err != nil { - return "", fmt.Errorf("error converting %s to int: %v", val, err) + return "", fmt.Errorf("error converting %s to int: %w", val, err) } if intVal > suffixNum { suffixNum = intVal @@ -243,7 +243,7 @@ func validateUserKubeletConfig(cfg *mcfgv1.KubeletConfig) error { } kcDecoded, err := decodeKubeletConfig(cfg.Spec.KubeletConfig.Raw) if err != nil { - return fmt.Errorf("KubeletConfig could not be unmarshalled, err: %v", err) + return fmt.Errorf("KubeletConfig could not be unmarshalled, err: %w", err) } // Check all the fields a user cannot set within the KubeletConfig CR. @@ -333,7 +333,7 @@ func newKubeletconfigJSONEncoder(targetVersion schema.GroupVersion) (runtime.Enc func kubeletConfigToIgnFile(cfg *kubeletconfigv1beta1.KubeletConfiguration) (*ign3types.File, error) { cfgJSON, err := EncodeKubeletConfig(cfg, kubeletconfigv1beta1.SchemeGroupVersion) if err != nil { - return nil, fmt.Errorf("could not encode kubelet configuration: %v", err) + return nil, fmt.Errorf("could not encode kubelet configuration: %w", err) } cfgIgn := createNewKubeletIgnition(cfgJSON) return cfgIgn, nil @@ -351,7 +351,7 @@ func generateKubeletIgnFiles(kubeletConfig *mcfgv1.KubeletConfig, originalKubeCo if kubeletConfig.Spec.KubeletConfig != nil && kubeletConfig.Spec.KubeletConfig.Raw != nil { specKubeletConfig, err := decodeKubeletConfig(kubeletConfig.Spec.KubeletConfig.Raw) if err != nil { - return nil, nil, nil, fmt.Errorf("could not deserialize the new Kubelet config: %v", err) + return nil, nil, nil, fmt.Errorf("could not deserialize the new Kubelet config: %w", err) } if val, ok := specKubeletConfig.SystemReserved["memory"]; ok { @@ -371,14 +371,14 @@ func generateKubeletIgnFiles(kubeletConfig *mcfgv1.KubeletConfig, originalKubeCo // Merge the Old and New err = mergo.Merge(originalKubeConfig, specKubeletConfig, mergo.WithOverride) if err != nil { - return nil, nil, nil, fmt.Errorf("could not merge original config and new config: %v", err) + return nil, nil, nil, fmt.Errorf("could not merge original config and new config: %w", err) } } // Encode the new config into an Ignition File kubeletIgnition, err := kubeletConfigToIgnFile(originalKubeConfig) if err != nil { - return nil, nil, nil, fmt.Errorf("could not encode JSON: %v", err) + return nil, nil, nil, fmt.Errorf("could not encode JSON: %w", err) } if kubeletConfig.Spec.LogLevel != nil { diff --git a/pkg/controller/kubelet-config/kubelet_config_bootstrap.go b/pkg/controller/kubelet-config/kubelet_config_bootstrap.go index bd18c81dee..31c000a4f7 100644 --- a/pkg/controller/kubelet-config/kubelet_config_bootstrap.go +++ b/pkg/controller/kubelet-config/kubelet_config_bootstrap.go @@ -27,7 +27,7 @@ func RunKubeletBootstrap(templateDir string, kubeletConfigs []*mcfgv1.KubeletCon // use selector since label matching part of a KubeletConfig is not handled during the bootstrap selector, err := metav1.LabelSelectorAsSelector(kubeletConfig.Spec.MachineConfigPoolSelector) if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) + return nil, fmt.Errorf("invalid label selector: %w", err) } for _, pool := range mcpPools { @@ -76,7 +76,7 @@ func RunKubeletBootstrap(templateDir string, kubeletConfigs []*mcfgv1.KubeletCon ignConfig := ctrlcommon.NewIgnConfig() mc, err := ctrlcommon.MachineConfigFromIgnConfig(role, managedKey, ignConfig) if err != nil { - return nil, fmt.Errorf("could not create MachineConfig from new Ignition config: %v", err) + return nil, fmt.Errorf("could not create MachineConfig from new Ignition config: %w", err) } mc.Spec.Config.Raw = rawIgn mc.SetAnnotations(map[string]string{ diff --git a/pkg/controller/kubelet-config/kubelet_config_controller.go b/pkg/controller/kubelet-config/kubelet_config_controller.go index 45d55f6178..e949ee30d5 100644 --- a/pkg/controller/kubelet-config/kubelet_config_controller.go +++ b/pkg/controller/kubelet-config/kubelet_config_controller.go @@ -220,7 +220,7 @@ func (ctrl *Controller) deleteKubeletConfig(obj interface{}) { } } if err := ctrl.cascadeDelete(cfg); err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't delete object %#v: %v", cfg, err)) + utilruntime.HandleError(fmt.Errorf("couldn't delete object %#v: %w", cfg, err)) } else { glog.V(4).Infof("Deleted KubeletConfig %s and restored default config", cfg.Name) } @@ -253,7 +253,7 @@ func (ctrl *Controller) cascadeDelete(cfg *mcfgv1.KubeletConfig) error { func (ctrl *Controller) enqueue(cfg *mcfgv1.KubeletConfig) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(cfg) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", cfg, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", cfg, err)) return } ctrl.queue.Add(key) @@ -262,7 +262,7 @@ func (ctrl *Controller) enqueue(cfg *mcfgv1.KubeletConfig) { func (ctrl *Controller) enqueueRateLimited(cfg *mcfgv1.KubeletConfig) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(cfg) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", cfg, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", cfg, err)) return } ctrl.queue.AddRateLimited(key) @@ -334,29 +334,29 @@ func (ctrl *Controller) handleFeatureErr(err error, key interface{}) { func generateOriginalKubeletConfigWithFeatureGates(cc *mcfgv1.ControllerConfig, templatesDir, role string, features *configv1.FeatureGate) (*kubeletconfigv1beta1.KubeletConfiguration, error) { originalKubeletIgn, err := generateOriginalKubeletConfigIgn(cc, templatesDir, role, features) if err != nil { - return nil, fmt.Errorf("could not generate the original Kubelet config ignition: %v", err) + return nil, fmt.Errorf("could not generate the original Kubelet config ignition: %w", err) } if originalKubeletIgn.Contents.Source == nil { - return nil, fmt.Errorf("the original Kubelet source string is empty: %v", err) + return nil, fmt.Errorf("the original Kubelet source string is empty: %w", err) } contents, err := ctrlcommon.DecodeIgnitionFileContents(originalKubeletIgn.Contents.Source, originalKubeletIgn.Contents.Compression) if err != nil { - return nil, fmt.Errorf("could not decode the original Kubelet source string: %v", err) + return nil, fmt.Errorf("could not decode the original Kubelet source string: %w", err) } originalKubeConfig, err := decodeKubeletConfig(contents) if err != nil { - return nil, fmt.Errorf("could not deserialize the Kubelet source: %v", err) + return nil, fmt.Errorf("could not deserialize the Kubelet source: %w", err) } featureGates, err := generateFeatureMap(features, openshiftOnlyFeatureGates...) if err != nil { - return nil, fmt.Errorf("could not generate features map: %v", err) + return nil, fmt.Errorf("could not generate features map: %w", err) } // Merge in Feature Gates. // If they are the same, this will be a no-op if err := mergo.Merge(&originalKubeConfig.FeatureGates, featureGates, mergo.WithOverride); err != nil { - return nil, fmt.Errorf("could not merge feature gates: %v", err) + return nil, fmt.Errorf("could not merge feature gates: %w", err) } return originalKubeConfig, nil @@ -367,7 +367,7 @@ func generateOriginalKubeletConfigIgn(cc *mcfgv1.ControllerConfig, templatesDir, rc := &mtmpl.RenderConfig{ControllerConfigSpec: &cc.Spec, FeatureGate: featureGate} generatedConfigs, err := mtmpl.GenerateMachineConfigsForRole(rc, role, templatesDir) if err != nil { - return nil, fmt.Errorf("GenerateMachineConfigsforRole failed with error %s", err) + return nil, fmt.Errorf("GenerateMachineConfigsforRole failed with error: %w", err) } // Find generated kubelet.config for _, gmc := range generatedConfigs { @@ -503,7 +503,7 @@ func (ctrl *Controller) syncKubeletConfig(key string) error { features = createNewDefaultFeatureGate() } else if err != nil { glog.V(2).Infof("%v", err) - err := fmt.Errorf("could not fetch FeatureGates: %v", err) + err := fmt.Errorf("could not fetch FeatureGates: %w", err) return ctrl.syncStatusOnly(cfg, err) } @@ -531,7 +531,7 @@ func (ctrl *Controller) syncKubeletConfig(key string) error { // Generate the original KubeletConfig cc, err := ctrl.ccLister.Get(ctrlcommon.ControllerConfigName) if err != nil { - return fmt.Errorf("could not get ControllerConfig %v", err) + return fmt.Errorf("could not get ControllerConfig %w", err) } originalKubeConfig, err := generateOriginalKubeletConfigWithFeatureGates(cc, ctrl.templatesDir, role, features) @@ -645,7 +645,7 @@ func (ctrl *Controller) cleanUpDuplicatedMC() error { // Get all machine configs mcList, err := ctrl.client.MachineconfigurationV1().MachineConfigs().List(context.TODO(), metav1.ListOptions{}) if err != nil { - return fmt.Errorf("error listing kubelet machine configs: %v", err) + return fmt.Errorf("error listing kubelet machine configs: %w", err) } for _, mc := range mcList.Items { if !strings.Contains(mc.Name, generatedKubeletCfg) { @@ -654,7 +654,7 @@ func (ctrl *Controller) cleanUpDuplicatedMC() error { // delete the mc if its degraded if mc.Annotations[ctrlcommon.GeneratedByControllerVersionAnnotationKey] != version.Hash { if err := ctrl.client.MachineconfigurationV1().MachineConfigs().Delete(context.TODO(), mc.Name, metav1.DeleteOptions{}); err != nil { - return fmt.Errorf("error deleting degraded kubelet machine config %s: %v", mc.Name, err) + return fmt.Errorf("error deleting degraded kubelet machine config %s: %w", mc.Name, err) } } } @@ -751,7 +751,7 @@ func (ctrl *Controller) getPoolsForKubeletConfig(config *mcfgv1.KubeletConfig) ( selector, err := metav1.LabelSelectorAsSelector(config.Spec.MachineConfigPoolSelector) if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) + return nil, fmt.Errorf("invalid label selector: %w", err) } var pools []*mcfgv1.MachineConfigPool diff --git a/pkg/controller/kubelet-config/kubelet_config_features.go b/pkg/controller/kubelet-config/kubelet_config_features.go index af83c31868..2d2562f487 100644 --- a/pkg/controller/kubelet-config/kubelet_config_features.go +++ b/pkg/controller/kubelet-config/kubelet_config_features.go @@ -70,7 +70,7 @@ func (ctrl *Controller) syncFeatureHandler(key string) error { cc, err := ctrl.ccLister.Get(ctrlcommon.ControllerConfigName) if err != nil { - return fmt.Errorf("could not get ControllerConfig %v", err) + return fmt.Errorf("could not get ControllerConfig: %w", err) } // Find all MachineConfigPools @@ -122,7 +122,7 @@ func (ctrl *Controller) syncFeatureHandler(key string) error { } return err }); err != nil { - return fmt.Errorf("Could not Create/Update MachineConfig: %v", err) + return fmt.Errorf("Could not Create/Update MachineConfig: %w", err) } glog.Infof("Applied FeatureSet %v on MachineConfigPool %v", key, pool.Name) } @@ -133,7 +133,7 @@ func (ctrl *Controller) syncFeatureHandler(key string) error { func (ctrl *Controller) enqueueFeature(feat *osev1.FeatureGate) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(feat) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", feat, err)) + utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %w", feat, err)) return } ctrl.featureQueue.Add(key) diff --git a/pkg/controller/node/node_controller.go b/pkg/controller/node/node_controller.go index 7123208db4..51fa9ffc3e 100644 --- a/pkg/controller/node/node_controller.go +++ b/pkg/controller/node/node_controller.go @@ -24,13 +24,13 @@ import ( "github.com/openshift/machine-config-operator/pkg/generated/clientset/versioned/scheme" mcfginformersv1 "github.com/openshift/machine-config-operator/pkg/generated/informers/externalversions/machineconfiguration.openshift.io/v1" mcfglistersv1 "github.com/openshift/machine-config-operator/pkg/generated/listers/machineconfiguration.openshift.io/v1" - goerrs "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" + kubeErrs "k8s.io/apimachinery/pkg/util/errors" intstrutil "k8s.io/apimachinery/pkg/util/intstr" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/strategicpatch" @@ -178,7 +178,7 @@ func (ctrl *Controller) Run(workers int, stopCh <-chan struct{}) { func (ctrl *Controller) getCurrentMasters() ([]*corev1.Node, error) { nodeList, err := ctrl.nodeLister.List(labels.SelectorFromSet(labels.Set{ctrlcommon.MasterLabel: ""})) if err != nil { - return nil, fmt.Errorf("error while listing master nodes %v", err) + return nil, fmt.Errorf("error while listing master nodes %w", err) } return nodeList, nil } @@ -199,14 +199,16 @@ func (ctrl *Controller) checkMasterNodesOnDelete(obj interface{}) { } currentMasters, err := ctrl.getCurrentMasters() if err != nil { - goerrs.Wrap(err, "Reconciling to make master nodes schedulable/unschedulable failed") + err = fmt.Errorf("reconciling to make master nodes schedulable/unschedulable failed: %w", err) + glog.Error(err) return } // On deletion make all masters unschedulable to restore default behaviour errs := ctrl.makeMastersUnSchedulable(currentMasters) if len(errs) > 0 { err = v1helpers.NewMultiLineAggregate(errs) - goerrs.Wrap(err, "Reconciling to make nodes schedulable/unschedulable failed") + err = fmt.Errorf("reconciling to make nodes schedulable/unschedulable failed: %w", err) + glog.Error(err) return } return @@ -236,7 +238,7 @@ func (ctrl *Controller) makeMastersUnSchedulable(currentMasters []*corev1.Node) var errs []error for _, node := range currentMasters { if err := ctrl.makeMasterNodeUnSchedulable(node); err != nil { - errs = append(errs, fmt.Errorf("failed making node %v schedulable with error %v", node.Name, err)) + errs = append(errs, fmt.Errorf("failed making node %v schedulable with error %w", node.Name, err)) } } return errs @@ -318,12 +320,12 @@ func (ctrl *Controller) deleteMachineConfigPool(obj interface{}) { if !ok { tombstone, ok := obj.(cache.DeletedFinalStateUnknown) if !ok { - utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) return } pool, ok = tombstone.Obj.(*mcfgv1.MachineConfigPool) if !ok { - utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a MachineConfigPool %#v", obj)) + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a MachineConfigPool %#v", obj)) return } } @@ -335,7 +337,7 @@ func (ctrl *Controller) deleteMachineConfigPool(obj interface{}) { func (ctrl *Controller) getMastersSchedulable() (bool, error) { schedulerList, err := ctrl.schedulerList.List(labels.SelectorFromSet(nil)) if err != nil { - return false, fmt.Errorf("error while listing scheduler config %v", err) + return false, fmt.Errorf("error while listing scheduler config %w", err) } for _, sched := range schedulerList { if sched.Name == schedulerCRName { @@ -369,19 +371,22 @@ func isWindows(node *corev1.Node) bool { func (ctrl *Controller) reconcileMaster(node *corev1.Node) { mastersSchedulable, err := ctrl.getMastersSchedulable() if err != nil { - goerrs.Wrap(err, "Getting scheduler config failed") + err = fmt.Errorf("getting scheduler config failed: %w", err) + glog.Error(err) return } if mastersSchedulable { err = ctrl.makeMasterNodeSchedulable(node) if err != nil { - goerrs.Wrap(err, "Failed making master Node schedulable") + err = fmt.Errorf("failed making master Node schedulable: %w", err) + glog.Error(err) return } } else if !mastersSchedulable { err = ctrl.makeMasterNodeUnSchedulable(node) if err != nil { - goerrs.Wrap(err, "Failed making master Node unschedulable") + err = fmt.Errorf("failed making master Node unschedulable: %w", err) + glog.Error(err) return } } @@ -392,7 +397,8 @@ func (ctrl *Controller) reconcileMaster(node *corev1.Node) { func (ctrl *Controller) reconcileMasters() { currentMasters, err := ctrl.getCurrentMasters() if err != nil { - goerrs.Wrap(err, "Reconciling to make master nodes schedulable/unschedulable failed") + err = fmt.Errorf("reconciling to make master nodes schedulable/unschedulable failed: %w", err) + glog.Error(err) return } for _, node := range currentMasters { @@ -528,12 +534,12 @@ func (ctrl *Controller) deleteNode(obj interface{}) { if !ok { tombstone, ok := obj.(cache.DeletedFinalStateUnknown) if !ok { - utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) return } node, ok = tombstone.Obj.(*corev1.Node) if !ok { - utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a Node %#v", obj)) + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a Node %#v", obj)) return } } @@ -572,7 +578,7 @@ func (ctrl *Controller) getPoolsForNode(node *corev1.Node) ([]*mcfgv1.MachineCon for _, p := range pl { selector, err := metav1.LabelSelectorAsSelector(p.Spec.NodeSelector) if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) + return nil, fmt.Errorf("invalid label selector: %w", err) } // If a pool with a nil or empty selector creeps in, it should match nothing, not everything. @@ -639,7 +645,7 @@ func (ctrl *Controller) getPrimaryPoolForNode(node *corev1.Node) (*mcfgv1.Machin func (ctrl *Controller) enqueue(pool *mcfgv1.MachineConfigPool) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(pool) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", pool, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", pool, err)) return } @@ -649,7 +655,7 @@ func (ctrl *Controller) enqueue(pool *mcfgv1.MachineConfigPool) { func (ctrl *Controller) enqueueRateLimited(pool *mcfgv1.MachineConfigPool) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(pool) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", pool, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", pool, err)) return } @@ -660,7 +666,7 @@ func (ctrl *Controller) enqueueRateLimited(pool *mcfgv1.MachineConfigPool) { func (ctrl *Controller) enqueueAfter(pool *mcfgv1.MachineConfigPool, after time.Duration) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(pool) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", pool, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", pool, err)) return } @@ -773,7 +779,8 @@ func (ctrl *Controller) syncMachineConfigPool(key string) error { nodes, err := ctrl.getNodesForPool(pool) if err != nil { if syncErr := ctrl.syncStatusOnly(pool); syncErr != nil { - return goerrs.Wrapf(err, "error getting nodes for pool %q, sync error: %v", pool.Name, syncErr) + errs := kubeErrs.NewAggregate([]error{syncErr, err}) + return fmt.Errorf("error getting nodes for pool %q, sync error: %w", pool.Name, errs) } return err } @@ -781,13 +788,14 @@ func (ctrl *Controller) syncMachineConfigPool(key string) error { maxunavail, err := maxUnavailable(pool, nodes) if err != nil { if syncErr := ctrl.syncStatusOnly(pool); syncErr != nil { - return goerrs.Wrapf(err, "error getting max unavailable count for pool %q, sync error: %v", pool.Name, syncErr) + errs := kubeErrs.NewAggregate([]error{syncErr, err}) + return fmt.Errorf("error getting max unavailable count for pool %q, sync error: %w", pool.Name, errs) } return err } if err := ctrl.setClusterConfigAnnotation(nodes); err != nil { - return goerrs.Wrapf(err, "error setting clusterConfig Annotation for node in pool %q, error: %v", pool.Name, err) + return fmt.Errorf("error setting clusterConfig Annotation for node in pool %q, error: %w", pool.Name, err) } // Taint all the nodes in the node pool, irrespective of their upgrade status. ctx := context.TODO() @@ -799,13 +807,15 @@ func (ctrl *Controller) syncMachineConfigPool(key string) error { if node.Annotations[daemonconsts.DesiredMachineConfigAnnotationKey] == targetConfig { if hasInProgressTaint { if err := ctrl.removeUpdateInProgressTaint(ctx, node.Name); err != nil { - return goerrs.Wrapf(err, "failed removing %s taint for node %s", constants.NodeUpdateInProgressTaint.Key, node.Name) + err = fmt.Errorf("failed removing %s taint for node %s: %w", constants.NodeUpdateInProgressTaint.Key, node.Name, err) + glog.Error(err) } } } else { if !hasInProgressTaint { if err := ctrl.setUpdateInProgressTaint(ctx, node.Name); err != nil { - return goerrs.Wrapf(err, "failed applying %s taint for node %s", constants.NodeUpdateInProgressTaint.Key, node.Name) + err = fmt.Errorf("failed applying %s taint for node %s: %w", constants.NodeUpdateInProgressTaint.Key, node.Name, err) + glog.Error(err) } } } @@ -815,7 +825,8 @@ func (ctrl *Controller) syncMachineConfigPool(key string) error { ctrl.logPool(pool, "%d candidate nodes for update, capacity: %d", len(candidates), capacity) if err := ctrl.updateCandidateMachines(pool, candidates, capacity); err != nil { if syncErr := ctrl.syncStatusOnly(pool); syncErr != nil { - return goerrs.Wrapf(err, "error setting desired machine config annotation for pool %q, sync error: %v", pool.Name, syncErr) + errs := kubeErrs.NewAggregate([]error{syncErr, err}) + return fmt.Errorf("error setting desired machine config annotation for pool %q, sync error: %w", pool.Name, errs) } return err } @@ -836,7 +847,7 @@ func checkIfNodeHasInProgressTaint(node *corev1.Node) bool { func (ctrl *Controller) getNodesForPool(pool *mcfgv1.MachineConfigPool) ([]*corev1.Node, error) { selector, err := metav1.LabelSelectorAsSelector(pool.Spec.NodeSelector) if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) + return nil, fmt.Errorf("invalid label selector: %w", err) } initialNodes, err := ctrl.nodeLister.List(selector) @@ -913,7 +924,7 @@ func (ctrl *Controller) setDesiredMachineConfigAnnotation(nodeName, currentConfi patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, corev1.Node{}) if err != nil { - return fmt.Errorf("failed to create patch for node %q: %v", nodeName, err) + return fmt.Errorf("failed to create patch for node %q: %w", nodeName, err) } _, err = ctrl.kubeClient.CoreV1().Nodes().Patch(context.TODO(), nodeName, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) return err @@ -1013,7 +1024,7 @@ func (ctrl *Controller) updateCandidateMachines(pool *mcfgv1.MachineConfigPool, for _, node := range candidates { ctrl.logPool(pool, "Setting node %s target to %s", node.Name, targetConfig) if err := ctrl.setDesiredMachineConfigAnnotation(node.Name, targetConfig); err != nil { - return goerrs.Wrapf(err, "setting desired config for node %s", node.Name) + return fmt.Errorf("setting desired config for node %s: %w", node.Name, err) } } if len(candidates) == 1 { @@ -1114,7 +1125,7 @@ func (ctrl *Controller) removeUpdateInProgressTaint(ctx context.Context, nodeNam patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, corev1.Node{}) if err != nil { - return fmt.Errorf("failed to create patch for node %q: %v", nodeName, err) + return fmt.Errorf("failed to create patch for node %q: %w", nodeName, err) } _, err = ctrl.kubeClient.CoreV1().Nodes().Patch(ctx, nodeName, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) return err @@ -1238,7 +1249,7 @@ func (ctrl *Controller) getNewestAPIToKubeletSignerCertificate(statusIgnConfig * // We have other problems if this is empty, but it's possible if len(containedCertificates) == 0 { - return nil, fmt.Errorf("No certificates found in bundle") + return nil, fmt.Errorf("no certificates found in bundle") } // The *original* signer has a different name, the rotated ones have longer names @@ -1247,7 +1258,7 @@ func (ctrl *Controller) getNewestAPIToKubeletSignerCertificate(statusIgnConfig * // Shouldn't come back with nothing, but just in case we do if newestCertificate == nil { - return nil, fmt.Errorf("No matching kube-apiserver-to-kubelet-signer certificates found in bundle") + return nil, fmt.Errorf("no matching kube-apiserver-to-kubelet-signer certificates found in bundle") } return newestCertificate, nil diff --git a/pkg/controller/render/hash.go b/pkg/controller/render/hash.go index 36d857a0e8..bb09d40be3 100644 --- a/pkg/controller/render/hash.go +++ b/pkg/controller/render/hash.go @@ -44,10 +44,10 @@ func hashData(data []byte) ([]byte, error) { //nolint:gosec hasher := md5.New() if _, err := hasher.Write(salt); err != nil { - return nil, fmt.Errorf("error computing hash: %v", err) + return nil, fmt.Errorf("error computing hash: %w", err) } if _, err := hasher.Write(data); err != nil { - return nil, fmt.Errorf("error computing hash: %v", err) + return nil, fmt.Errorf("error computing hash: %w", err) } return hasher.Sum(nil), nil } diff --git a/pkg/controller/render/render_controller.go b/pkg/controller/render/render_controller.go index 4233c3e8b2..4fa5d6dc50 100644 --- a/pkg/controller/render/render_controller.go +++ b/pkg/controller/render/render_controller.go @@ -294,7 +294,7 @@ func (ctrl *Controller) getPoolsForMachineConfig(config *mcfgv1.MachineConfig) ( for _, p := range pList { selector, err := metav1.LabelSelectorAsSelector(p.Spec.MachineConfigSelector) if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) + return nil, fmt.Errorf("invalid label selector: %w", err) } // If a pool with a nil or empty selector creeps in, it should match nothing, not everything. @@ -314,7 +314,7 @@ func (ctrl *Controller) getPoolsForMachineConfig(config *mcfgv1.MachineConfig) ( func (ctrl *Controller) enqueue(pool *mcfgv1.MachineConfigPool) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(pool) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", pool, err)) + utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %w", pool, err)) return } @@ -324,7 +324,7 @@ func (ctrl *Controller) enqueue(pool *mcfgv1.MachineConfigPool) { func (ctrl *Controller) enqueueRateLimited(pool *mcfgv1.MachineConfigPool) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(pool) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", pool, err)) + utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %w", pool, err)) return } @@ -335,7 +335,7 @@ func (ctrl *Controller) enqueueRateLimited(pool *mcfgv1.MachineConfigPool) { func (ctrl *Controller) enqueueAfter(pool *mcfgv1.MachineConfigPool, after time.Duration) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(pool) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", pool, err)) + utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %w", pool, err)) return } @@ -611,7 +611,7 @@ func RunBootstrap(pools []*mcfgv1.MachineConfigPool, configs []*mcfgv1.MachineCo func getMachineConfigsForPool(pool *mcfgv1.MachineConfigPool, configs []*mcfgv1.MachineConfig) ([]*mcfgv1.MachineConfig, error) { selector, err := metav1.LabelSelectorAsSelector(pool.Spec.MachineConfigSelector) if err != nil { - return nil, fmt.Errorf("invalid label selector: %v", err) + return nil, fmt.Errorf("invalid label selector: %w", err) } var out []*mcfgv1.MachineConfig diff --git a/pkg/controller/template/render.go b/pkg/controller/template/render.go index 21cf498c82..d0b655d259 100644 --- a/pkg/controller/template/render.go +++ b/pkg/controller/template/render.go @@ -57,7 +57,7 @@ const ( func generateTemplateMachineConfigs(config *RenderConfig, templateDir string) ([]*mcfgv1.MachineConfig, error) { infos, err := ioutil.ReadDir(templateDir) if err != nil { - return nil, fmt.Errorf("failed to read dir %q: %v", templateDir, err) + return nil, fmt.Errorf("failed to read dir %q: %w", templateDir, err) } cfgs := []*mcfgv1.MachineConfig{} @@ -74,7 +74,7 @@ func generateTemplateMachineConfigs(config *RenderConfig, templateDir string) ([ roleConfigs, err := GenerateMachineConfigsForRole(config, role, templateDir) if err != nil { - return nil, fmt.Errorf("failed to create MachineConfig for role %s: %v", role, err) + return nil, fmt.Errorf("failed to create MachineConfig for role %s: %w", role, err) } cfgs = append(cfgs, roleConfigs...) } @@ -103,7 +103,7 @@ func GenerateMachineConfigsForRole(config *RenderConfig, role, templateDir strin path := filepath.Join(templateDir, rolePath) infos, err := ioutil.ReadDir(path) if err != nil { - return nil, fmt.Errorf("failed to read dir %q: %v", path, err) + return nil, fmt.Errorf("failed to read dir %q: %w", path, err) } cfgs := []*mcfgv1.MachineConfig{} @@ -176,7 +176,7 @@ func filterTemplates(toFilter map[string]string, path string, config *RenderConf filedata, err := ioutil.ReadFile(path) if err != nil { - return fmt.Errorf("failed to read file %q: %v", path, err) + return fmt.Errorf("failed to read file %q: %w", path, err) } // Render the template file @@ -287,11 +287,11 @@ func generateMachineConfigForName(config *RenderConfig, role, name, templateDir, ignCfg, err := ctrlcommon.TranspileCoreOSConfigToIgn(keySortVals(files), keySortVals(units)) if err != nil { - return nil, fmt.Errorf("error transpiling CoreOS config to Ignition config: %v", err) + return nil, fmt.Errorf("error transpiling CoreOS config to Ignition config: %w", err) } mcfg, err := ctrlcommon.MachineConfigFromIgnConfig(role, name, ignCfg) if err != nil { - return nil, fmt.Errorf("error creating MachineConfig from Ignition config: %v", err) + return nil, fmt.Errorf("error creating MachineConfig from Ignition config: %w", err) } // And inject the osimageurl here mcfg.Spec.OSImageURL = config.OSImageURL @@ -314,7 +314,7 @@ func renderTemplate(config RenderConfig, path string, b []byte) ([]byte, error) funcs["urlPort"] = urlPort tmpl, err := template.New(path).Funcs(funcs).Parse(string(b)) if err != nil { - return nil, fmt.Errorf("failed to parse template %s: %v", path, err) + return nil, fmt.Errorf("failed to parse template %s: %w", path, err) } if config.Constants == nil { @@ -323,7 +323,7 @@ func renderTemplate(config RenderConfig, path string, b []byte) ([]byte, error) buf := new(bytes.Buffer) if err := tmpl.Execute(buf, config); err != nil { - return nil, fmt.Errorf("failed to execute template: %v", err) + return nil, fmt.Errorf("failed to execute template: %w", err) } return buf.Bytes(), nil @@ -505,7 +505,7 @@ func existsDir(path string) (bool, error) { if os.IsNotExist(err) { return false, nil } - return false, fmt.Errorf("failed to open dir %q: %v", path, err) + return false, fmt.Errorf("failed to open dir %q: %w", path, err) } if !info.IsDir() { return false, fmt.Errorf("expected template directory, %q is not a directory", path) diff --git a/pkg/controller/template/render_test.go b/pkg/controller/template/render_test.go index b9f6be12f0..8a19162eff 100644 --- a/pkg/controller/template/render_test.go +++ b/pkg/controller/template/render_test.go @@ -453,7 +453,7 @@ func controllerConfigFromFile(path string) (*mcfgv1.ControllerConfig, error) { } cci, _, err := scheme.Codecs.UniversalDecoder().Decode(data, nil, &mcfgv1.ControllerConfig{}) if err != nil { - return nil, fmt.Errorf("unable to decode ControllerConfig manifest: %v", err) + return nil, fmt.Errorf("unable to decode ControllerConfig manifest: %w", err) } cc, ok := cci.(*mcfgv1.ControllerConfig) if !ok { @@ -489,7 +489,7 @@ func verifyIgn(actual [][]byte, dir string, t *testing.T) { } if info.IsDir() { if path != dir { - return fmt.Errorf("unexpected dir: %v", err) + return fmt.Errorf("unexpected dir: %w", err) } return nil } diff --git a/pkg/controller/template/template_controller.go b/pkg/controller/template/template_controller.go index 0628fea9b4..a474778ceb 100644 --- a/pkg/controller/template/template_controller.go +++ b/pkg/controller/template/template_controller.go @@ -161,12 +161,12 @@ func (ctrl *Controller) deleteSecret(obj interface{}) { if !ok { tombstone, ok := obj.(cache.DeletedFinalStateUnknown) if !ok { - utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) return } secret, ok = tombstone.Obj.(*corev1.Secret) if !ok { - utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a Secret %#v", obj)) + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a Secret %#v", obj)) return } } @@ -174,7 +174,7 @@ func (ctrl *Controller) deleteSecret(obj interface{}) { if secret.Name == "pull-secret" { cfg, err := ctrl.ccLister.Get(ctrlcommon.ControllerConfigName) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get ControllerConfig on secret callback %#v", err)) + utilruntime.HandleError(fmt.Errorf("couldn't get ControllerConfig on secret callback %#w", err)) return } glog.V(4).Infof("Re-syncing ControllerConfig %s due to secret deletion", cfg.Name) @@ -186,7 +186,7 @@ func (ctrl *Controller) deleteSecret(obj interface{}) { func (ctrl *Controller) enqueueController() { cfg, err := ctrl.ccLister.Get(ctrlcommon.ControllerConfigName) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get ControllerConfig on dependency callback %#v", err)) + utilruntime.HandleError(fmt.Errorf("couldn't get ControllerConfig on dependency callback %#w", err)) return } glog.V(4).Infof("Re-syncing ControllerConfig %s due to dependency change", cfg.Name) @@ -213,12 +213,12 @@ func (ctrl *Controller) deleteFeature(obj interface{}) { if !ok { tombstone, ok := obj.(cache.DeletedFinalStateUnknown) if !ok { - utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) return } features, ok = tombstone.Obj.(*osev1.FeatureGate) if !ok { - utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a FeatureGate %#v", obj)) + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a FeatureGate %#v", obj)) return } } @@ -263,12 +263,12 @@ func (ctrl *Controller) deleteControllerConfig(obj interface{}) { if !ok { tombstone, ok := obj.(cache.DeletedFinalStateUnknown) if !ok { - utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) return } cfg, ok = tombstone.Obj.(*mcfgv1.ControllerConfig) if !ok { - utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a ControllerConfig %#v", obj)) + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a ControllerConfig %#v", obj)) return } } @@ -318,12 +318,12 @@ func (ctrl *Controller) deleteMachineConfig(obj interface{}) { if !ok { tombstone, ok := obj.(cache.DeletedFinalStateUnknown) if !ok { - utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) return } mc, ok = tombstone.Obj.(*mcfgv1.MachineConfig) if !ok { - utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a MachineConfig %#v", obj)) + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a MachineConfig %#v", obj)) return } } @@ -363,7 +363,7 @@ func (ctrl *Controller) resolveControllerRef(controllerRef *metav1.OwnerReferenc func (ctrl *Controller) enqueue(config *mcfgv1.ControllerConfig) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(config) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", config, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", config, err)) return } @@ -373,7 +373,7 @@ func (ctrl *Controller) enqueue(config *mcfgv1.ControllerConfig) { func (ctrl *Controller) enqueueRateLimited(controllerconfig *mcfgv1.ControllerConfig) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(controllerconfig) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", controllerconfig, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", controllerconfig, err)) return } @@ -384,7 +384,7 @@ func (ctrl *Controller) enqueueRateLimited(controllerconfig *mcfgv1.ControllerCo func (ctrl *Controller) enqueueAfter(controllerconfig *mcfgv1.ControllerConfig, after time.Duration) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(controllerconfig) if err != nil { - utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", controllerconfig, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", controllerconfig, err)) return } @@ -476,7 +476,7 @@ func (ctrl *Controller) syncControllerConfig(key string) error { fg, err := ctrl.featLister.Get(ctrlcommon.ClusterFeatureInstanceName) if err != nil && !errors.IsNotFound(err) { - err := fmt.Errorf("could not fetch FeatureGate: %v", err) + err := fmt.Errorf("could not fetch FeatureGate: %w", err) glog.V(2).Infof("%v", err) return ctrl.syncFailingStatus(cfg, err) } @@ -501,7 +501,7 @@ func (ctrl *Controller) syncControllerConfig(key string) error { func getMachineConfigsForControllerConfig(templatesDir string, config *mcfgv1.ControllerConfig, pullSecretRaw []byte, featureGate *configv1.FeatureGate) ([]*mcfgv1.MachineConfig, error) { buf := &bytes.Buffer{} if err := json.Compact(buf, pullSecretRaw); err != nil { - return nil, fmt.Errorf("couldn't compact pullsecret %q: %v", string(pullSecretRaw), err) + return nil, fmt.Errorf("couldn't compact pullsecret %q: %w", string(pullSecretRaw), err) } rc := &RenderConfig{ ControllerConfigSpec: &config.Spec, diff --git a/pkg/daemon/config_drift_monitor.go b/pkg/daemon/config_drift_monitor.go index 915621d239..271775e9bd 100644 --- a/pkg/daemon/config_drift_monitor.go +++ b/pkg/daemon/config_drift_monitor.go @@ -17,13 +17,19 @@ import ( ) // Outermost error type for config drift errors -type configDriftErr error +type configDriftErr struct { + error +} // Error type for file config drifts -type fileConfigDriftErr error +type fileConfigDriftErr struct { + error +} // Error type for systemd unit config drifts -type unitConfigDriftErr error +type unitConfigDriftErr struct { + error +} type ConfigDriftMonitor interface { Start(ConfigDriftMonitorOpts) error @@ -258,7 +264,7 @@ func (c *configDriftWatcher) handleFileEvent(event fsnotify.Event) error { return nil } - var cdErr configDriftErr + var cdErr *configDriftErr if errors.As(err, &cdErr) { c.OnDrift(cdErr) // Don't bubble this error up further since it's handled by OnDrift. @@ -276,7 +282,7 @@ func (c *configDriftWatcher) checkMachineConfigForEvent(event fsnotify.Event) er } if err := validateOnDiskState(c.MachineConfig, c.SystemdPath); err != nil { - return configDriftErr(err) + return &configDriftErr{err} } return nil diff --git a/pkg/daemon/config_drift_monitor_test.go b/pkg/daemon/config_drift_monitor_test.go index 35d5062240..5cabf2a986 100644 --- a/pkg/daemon/config_drift_monitor_test.go +++ b/pkg/daemon/config_drift_monitor_test.go @@ -23,8 +23,8 @@ func TestConfigDriftMonitor(t *testing.T) { // Our errors. Their contents don't matter because we're not basing our // assertions off of their contents. Instead, we're more concerned about // their types. - fileErr := configDriftErr(fileConfigDriftErr(fmt.Errorf("file error"))) - unitErr := configDriftErr(unitConfigDriftErr(fmt.Errorf("unit error"))) + fileErr := &configDriftErr{&fileConfigDriftErr{fmt.Errorf("file error")}} + unitErr := &configDriftErr{&unitConfigDriftErr{fmt.Errorf("unit error")}} // Filesystem Mutators // These are closures to avoid namespace collisions and pollution since @@ -446,17 +446,17 @@ func (tc configDriftMonitorTestCase) onDriftFunc(t *testing.T, err error) { // Make sure that we get specific error types based upon the expected // values - var cdErr configDriftErr + var cdErr *configDriftErr assert.ErrorAs(t, err, &cdErr) // If the testcase asks for a fileConfigDriftErr, be sure we got one. - var fErr fileConfigDriftErr + var fErr *fileConfigDriftErr if errors.As(tc.expectedErr, &fErr) { assert.ErrorAs(t, err, &fErr) } // If the testcase asks for a unitConfigDriftErr, be sure we got one. - var uErr unitConfigDriftErr + var uErr *unitConfigDriftErr if errors.As(tc.expectedErr, &uErr) { assert.ErrorAs(t, err, &uErr) } diff --git a/pkg/daemon/controlplane.go b/pkg/daemon/controlplane.go index 5c365b09d1..9805fbfa1d 100644 --- a/pkg/daemon/controlplane.go +++ b/pkg/daemon/controlplane.go @@ -12,7 +12,6 @@ import ( "strings" "github.com/golang/glog" - "github.com/pkg/errors" ) // setRootDeviceSchedulerBFQ switches to the `bfq` I/O scheduler @@ -69,7 +68,7 @@ func setRootDeviceSchedulerBFQ() error { // latency spikes for etcd; see https://github.com/ostreedev/ostree/pull/2152 func updateOstreeObjectSync() error { if err := exec.Command("ostree", "--repo=/sysroot/ostree/repo", "config", "set", "core.per-object-fsync", "true").Run(); err != nil { - return errors.Wrapf(err, "Failed to set per-object-fsync for ostree") + return fmt.Errorf("failed to set per-object-fsync for ostree: %w", err) } return nil } diff --git a/pkg/daemon/coreos.go b/pkg/daemon/coreos.go index 6571344672..994b386d21 100644 --- a/pkg/daemon/coreos.go +++ b/pkg/daemon/coreos.go @@ -11,7 +11,6 @@ import ( "path/filepath" "github.com/golang/glog" - "github.com/pkg/errors" ) // alephPath contains information on the original bootimage; for more @@ -44,12 +43,12 @@ func byLabel(label string) string { func getParentDeviceSysfs(device string) (string, error) { target, err := os.Readlink(device) if err != nil { - return "", errors.Wrapf(err, "reading %s", device) + return "", fmt.Errorf("reading %s: %w", device, err) } sysfsDevLink := fmt.Sprintf("/sys/class/block/%s", filepath.Base(target)) sysfsDev, err := filepath.EvalSymlinks(sysfsDevLink) if err != nil { - return "", errors.Wrapf(err, "parsing %s", sysfsDevLink) + return "", fmt.Errorf("parsing %s: %w", sysfsDevLink, err) } if _, err := os.Stat(filepath.Join(sysfsDev, "partition")); err == nil { sysfsDev = filepath.Dir(sysfsDev) @@ -71,7 +70,7 @@ func getRootBlockDeviceSysfs() (string, error) { if _, err := os.Stat(root); err == nil { return getParentDeviceSysfs(root) } - return "", fmt.Errorf("Failed to find %s", root) + return "", fmt.Errorf("failed to find %s", root) } func logAlephInformation() error { diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index f136ba487e..75599c8ec6 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -4,6 +4,7 @@ import ( "bufio" "context" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -19,7 +20,6 @@ import ( ign3types "github.com/coreos/ignition/v2/config/v3_2/types" "github.com/golang/glog" - "github.com/pkg/errors" "golang.org/x/time/rate" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -230,7 +230,7 @@ func New( hostos, err = GetHostRunningOS() if err != nil { HostOS.WithLabelValues("unsupported", "").Set(1) - return nil, errors.Wrapf(err, "checking operating system") + return nil, fmt.Errorf("checking operating system: %w", err) } } @@ -238,11 +238,11 @@ func New( if hostos.IsCoreOSVariant() { err := nodeUpdaterClient.Initialize() if err != nil { - return nil, fmt.Errorf("error initializing rpm-ostree: %v", err) + return nil, fmt.Errorf("error initializing rpm-ostree: %w", err) } osImageURL, osVersion, err = nodeUpdaterClient.GetBootedOSImageURL() if err != nil { - return nil, fmt.Errorf("error reading osImageURL from rpm-ostree: %v", err) + return nil, fmt.Errorf("error reading osImageURL from rpm-ostree: %w", err) } glog.Infof("Booted osImageURL: %s (%s)", osImageURL, osVersion) } @@ -251,7 +251,7 @@ func New( if !mock { bootID, err = getBootID() if err != nil { - return nil, errors.Wrapf(err, "failed to read boot ID") + return nil, fmt.Errorf("failed to read boot ID: %w", err) } } @@ -261,7 +261,7 @@ func New( if hostos.IsLikeTraditionalRHEL7() { loggerOutput, err := exec.Command("logger", "--help").CombinedOutput() if err != nil { - return nil, errors.Wrapf(err, "running logger --help") + return nil, fmt.Errorf("running logger --help: %w", err) } loggerSupportsJournal = strings.Contains(string(loggerOutput), "--journald") } @@ -434,11 +434,15 @@ func (dn *Daemon) handleErr(err error, key interface{}) { dn.queue.AddRateLimited(key) } +type unreconcilableErr struct { + error +} + func (dn *Daemon) updateErrorState(err error) { - switch errors.Cause(err) { - case errUnreconcilable: + var uErr *unreconcilableErr + if errors.As(err, &uErr) { dn.nodeWriter.SetUnreconcilable(err, dn.kubeClient.CoreV1().Nodes(), dn.nodeLister, dn.name) - default: + } else { dn.nodeWriter.SetDegraded(err, dn.kubeClient.CoreV1().Nodes(), dn.nodeLister, dn.name) } } @@ -547,7 +551,7 @@ func (dn *Daemon) syncNode(key string) error { // Pass to the shared update prep method current, desired, err := dn.prepUpdateFromCluster() if err != nil { - return errors.Wrapf(err, "prepping update") + return fmt.Errorf("prepping update: %w", err) } if current != nil || desired != nil { // Only check for config drift if we need to update. @@ -583,7 +587,7 @@ func (dn *Daemon) runPreflightConfigDriftCheck() error { if err := dn.validateOnDiskState(currentOnDisk); err != nil { dn.recorder.Eventf(getNodeRef(dn.node), corev1.EventTypeWarning, "PreflightConfigDriftCheckFailed", err.Error()) glog.Errorf("Preflight config drift check failed: %v", err) - return configDriftErr(err) + return &configDriftErr{err} } glog.Infof("Preflight config drift check successful (took %s)", time.Since(start)) @@ -595,7 +599,7 @@ func (dn *Daemon) runPreflightConfigDriftCheck() error { func (dn *Daemon) enqueueDefault(node *corev1.Node) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(node) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", node, err)) + utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %w", node, err)) return } dn.queue.AddRateLimited(key) @@ -694,17 +698,17 @@ func (dn *Daemon) syncNodeHypershift(key string) error { if os.IsNotExist(err) { currentConfigBytes, err = ioutil.ReadFile(mcsServedConfigPath) if err != nil { - return errors.Wrapf(err, "Cannot find any existing configuration on disk") + return fmt.Errorf("cannot find any existing configuration on disk: %w", err) } } else { - return errors.Wrapf(err, "Failed to load local config") + return fmt.Errorf("failed to load local config: %w", err) } } var currentConfig mcfgv1.MachineConfig err = json.Unmarshal(currentConfigBytes, ¤tConfig) if err != nil { - return errors.Wrapf(err, "Cannot read on-disk state into MachineConfig") + return fmt.Errorf("cannot read on-disk state into MachineConfig: %w", err) } // Instead of reading from configmap directly, let's mount it in as a volumn, such that we don't have to give that @@ -712,30 +716,30 @@ func (dn *Daemon) syncNodeHypershift(key string) error { ignServedConfigPath := filepath.Join(dn.hypershiftConfigMap, configMapConfigKey) ignServedConfigBytes, err := ioutil.ReadFile(ignServedConfigPath) if err != nil { - return errors.Wrapf(err, "Failed to load desiredConfig") + return fmt.Errorf("failed to load desiredConfig: %w", err) } targetHashPath := filepath.Join(dn.hypershiftConfigMap, configMapHashKey) targetHashBytes, err := ioutil.ReadFile(targetHashPath) if err != nil { - return errors.Wrapf(err, "Failed to load desiredConfig hash") + return fmt.Errorf("failed to load desiredConfig hash: %w", err) } targetHash := string(targetHashBytes) // TODO probably have to compress this in the future ignConfig, err := ctrlcommon.ParseAndConvertConfig(ignServedConfigBytes) if err != nil { - return errors.Wrapf(err, "Failed to parse Ignition from configmap data.config") + return fmt.Errorf("failed to parse Ignition from configmap data.config: %w", err) } desiredConfigBytes, err := ctrlcommon.GetIgnitionFileDataByPath(&ignConfig, mcsServedConfigPath) if err != nil { - return errors.Wrapf(err, "Failed to find desiredConfig from configmap data") + return fmt.Errorf("failed to find desiredConfig from configmap data: %w", err) } var desiredConfig mcfgv1.MachineConfig err = json.Unmarshal(desiredConfigBytes, &desiredConfig) if err != nil { - return errors.Wrapf(err, "Cannot decode desiredConfig from configmap data") + return fmt.Errorf("cannot decode desiredConfig from configmap data: %w", err) } glog.Infof("Successfully read current/desired Config") @@ -743,13 +747,13 @@ func (dn *Daemon) syncNodeHypershift(key string) error { // check update reconcilability mcDiff, err := reconcilable(¤tConfig, &desiredConfig) if err != nil { - return errors.Wrapf(err, "The update is not reconcilable") + return fmt.Errorf("the update is not reconcilable: %w", err) } if mcDiff.isEmpty() { // No diff was detected. Check if we are in the right state. glog.Infof("No diff detected. Assuming a previous update was completed. Checking on-disk state.") if err := dn.validateOnDiskState(&desiredConfig); err != nil { - return errors.Wrapf(err, "Disk validation failed") + return fmt.Errorf("disk validation failed: %w", err) } if node.Annotations[constants.CurrentMachineConfigAnnotationKey] == targetHash && @@ -766,7 +770,7 @@ func (dn *Daemon) syncNodeHypershift(key string) error { constants.DesiredDrainerAnnotationKey: fmt.Sprintf("%s-%s", constants.DrainerStateUncordon, targetHash), } if err := dn.HypershiftSetAnnotation(annos); err != nil { - return errors.Wrapf(err, "Failed to set Done annotation on node") + return fmt.Errorf("failed to set Done annotation on node: %w", err) } glog.Infof("The pod has completed update. Awaiting removal.") // TODO os.Exit here @@ -788,7 +792,7 @@ func (dn *Daemon) syncNodeHypershift(key string) error { constants.DesiredDrainerAnnotationKey: targetDrainValue, } if err := dn.HypershiftSetAnnotation(annos); err != nil { - return errors.Wrapf(err, "Failed to set Done annotation on node") + return fmt.Errorf("failed to set Done annotation on node: %w", err) } // Wait for a future sync to perform post-drain actions glog.Info("Setting drain request via annotation to controller.") @@ -798,7 +802,7 @@ func (dn *Daemon) syncNodeHypershift(key string) error { // For us to be here, DesiredDrainerAnnotationKey == LastAppliedDrainerAnnotationKey == drain-targetHash // perform the actual update if err := dn.updateHypershift(¤tConfig, &desiredConfig, mcDiff); err != nil { - return errors.Wrapf(err, "Failed to update configuration") + return fmt.Errorf("failed to update configuration: %w", err) } // Finally, once we are successful, we perform the necessary post config change action (TODO) @@ -806,7 +810,7 @@ func (dn *Daemon) syncNodeHypershift(key string) error { // write new config to disk, used for future updates err = writeFileAtomicallyWithDefaults(hypershiftCurrentConfigPath, desiredConfigBytes) if err != nil { - return errors.Wrapf(err, "Cannot store new config to disk") + return fmt.Errorf("cannot store new config to disk: %w", err) } return dn.reboot(fmt.Sprintf("Node will reboot into config %s", desiredConfig.Name)) @@ -837,14 +841,14 @@ func (dn *Daemon) HypershiftSetAnnotation(annotations map[string]string) error { patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldNode, newNode, corev1.Node{}) if err != nil { - return fmt.Errorf("failed to create patch for node %q: %v", dn.name, err) + return fmt.Errorf("failed to create patch for node %q: %w", dn.name, err) } _, err = dn.kubeClient.CoreV1().Nodes().Patch(context.TODO(), dn.name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) return err }); err != nil { // may be conflict if max retries were hit - return fmt.Errorf("unable to update node %s: %v", dn.name, err) + return fmt.Errorf("unable to update node %s: %w", dn.name, err) } return nil } @@ -865,7 +869,7 @@ func (dn *Daemon) RunOnceFrom(onceFrom string, skipReboot bool) error { glog.V(2).Info("Daemon running directly from MachineConfig") return dn.runOnceFromMachineConfig(c, contentFrom) } - return errors.New("unsupported onceFrom type provided") + return fmt.Errorf("unsupported onceFrom type provided") } // RunFirstbootCompleteMachineconfig is run via systemd on the first boot @@ -878,7 +882,7 @@ func (dn *Daemon) RunFirstbootCompleteMachineconfig() error { var mc mcfgv1.MachineConfig err = json.Unmarshal(data, &mc) if err != nil { - return errors.Wrapf(err, "failed to parse MachineConfig") + return fmt.Errorf("failed to parse MachineConfig: %w", err) } // Start with an empty config, then add our *booted* osImageURL to @@ -890,12 +894,12 @@ func (dn *Daemon) RunFirstbootCompleteMachineconfig() error { // specified, then we don't need to do anything here. mcDiffNotEmpty, err := dn.compareMachineConfig(oldConfig, &mc) if err != nil { - return errors.Wrapf(err, "failed to compare MachineConfig") + return fmt.Errorf("failed to compare MachineConfig: %w", err) } if !mcDiffNotEmpty { // Removing this file signals completion of the initial MC processing. if err := os.Remove(constants.MachineConfigEncapsulatedPath); err != nil { - return errors.Wrapf(err, "failed to remove %s", constants.MachineConfigEncapsulatedPath) + return fmt.Errorf("failed to remove %s: %w", constants.MachineConfigEncapsulatedPath, err) } return nil } @@ -908,7 +912,7 @@ func (dn *Daemon) RunFirstbootCompleteMachineconfig() error { // Removing this file signals completion of the initial MC processing. if err := os.Rename(constants.MachineConfigEncapsulatedPath, constants.MachineConfigEncapsulatedBakPath); err != nil { - return errors.Wrap(err, "failed to rename encapsulated MachineConfig after processing on firstboot") + return fmt.Errorf("failed to rename encapsulated MachineConfig after processing on firstboot: %w", err) } dn.skipReboot = false @@ -964,7 +968,7 @@ func (dn *Daemon) Run(stopCh <-chan struct{}, exitCh <-chan error) error { defer dn.queue.ShutDown() if !cache.WaitForCacheSync(stopCh, dn.nodeListerSynced, dn.mcListerSynced) { - return errors.New("failed to sync initial listers cache") + return fmt.Errorf("failed to sync initial listers cache") } go wait.Until(dn.worker, time.Second, stopCh) @@ -1027,7 +1031,7 @@ func (dn *Daemon) runLoginMonitor(stopCh <-chan struct{}, exitCh chan<- error) { func (dn *Daemon) applySSHAccessedAnnotation() error { if err := dn.nodeWriter.SetSSHAccessed(dn.kubeClient.CoreV1().Nodes(), dn.nodeLister, dn.name); err != nil { - return fmt.Errorf("error: cannot apply annotation for SSH access due to: %v", err) + return fmt.Errorf("error: cannot apply annotation for SSH access due to: %w", err) } return nil } @@ -1109,7 +1113,7 @@ func (dn *Daemon) runKubeletHealthzMonitor(stopCh <-chan struct{}, exitCh chan<- err := dn.getHealth() if err != nil { failureCount++ - exitCh <- fmt.Errorf("kubelet health check has failed %d times: %v", failureCount, err) + exitCh <- fmt.Errorf("kubelet health check has failed %d times: %w", failureCount, err) } else { // reset failure count on success failureCount = 0 @@ -1315,13 +1319,13 @@ func (dn *Daemon) getPendingConfig() (*pendingConfigState, error) { s, err := ioutil.ReadFile("/etc/machine-config-daemon/state.json") if err != nil { if !os.IsNotExist(err) { - return nil, errors.Wrapf(err, "loading transient state") + return nil, fmt.Errorf("loading transient state: %w", err) } return nil, nil } var p pendingConfigState if err := json.Unmarshal(s, &p); err != nil { - return nil, errors.Wrapf(err, "parsing transient state") + return nil, fmt.Errorf("parsing transient state: %w", err) } return &p, nil @@ -1360,7 +1364,7 @@ func upgradeHackFor44AndBelow() error { glog.Warningf("Failed to complete machine-config-daemon-firstboot before joining cluster!") // Removing this file signals completion of the initial MC processing. if err := os.Rename(constants.MachineConfigEncapsulatedPath, constants.MachineConfigEncapsulatedBakPath); err != nil { - return errors.Wrap(err, "failed to rename encapsulated MachineConfig after processing on firstboot") + return fmt.Errorf("failed to rename encapsulated MachineConfig after processing on firstboot: %w", err) } } return nil @@ -1371,7 +1375,7 @@ func upgradeHackFor44AndBelow() error { // Currently removes the systemd preset file written by Ignition. func removeIgnitionArtifacts() error { if err := os.Remove(constants.IgnitionSystemdPresetFile); err != nil && !os.IsNotExist(err) { - return errors.Wrap(err, "failed to remove Ignition-written systemd preset file") + return fmt.Errorf("failed to remove Ignition-written systemd preset file: %w", err) } return nil } @@ -1434,7 +1438,7 @@ func (dn *Daemon) checkStateOnFirstRun() error { } if err := dn.detectEarlySSHAccessesFromBoot(); err != nil { - return fmt.Errorf("error detecting previous SSH accesses: %v", err) + return fmt.Errorf("error detecting previous SSH accesses: %w", err) } // Bootstrapping state is when we have the node annotations file @@ -1465,7 +1469,7 @@ func (dn *Daemon) checkStateOnFirstRun() error { // currentConfig's osImageURL should now be *truth*. // In other words if it drifts somehow, we go degraded. if err := os.Rename(constants.InitialNodeAnnotationsFilePath, constants.InitialNodeAnnotationsBakPath); err != nil { - return errors.Wrap(err, "renaming initial node annotation file") + return fmt.Errorf("renaming initial node annotation file: %w", err) } } @@ -1543,10 +1547,10 @@ func (dn *Daemon) updateConfigAndState(state *stateAndConfigs) (bool, error) { dn.recorder.Eventf(getNodeRef(dn.node), corev1.EventTypeNormal, "NodeDone", fmt.Sprintf("Setting node %s, currentConfig %s to Done", dn.node.Name, state.pendingConfig.GetName())) } if err := dn.nodeWriter.SetDone(dn.kubeClient.CoreV1().Nodes(), dn.nodeLister, dn.name, state.pendingConfig.GetName()); err != nil { - return true, errors.Wrap(err, "error setting node's state to Done") + return true, fmt.Errorf("error setting node's state to Done: %w", err) } if out, err := dn.storePendingState(state.pendingConfig, 0); err != nil { - return true, errors.Wrapf(err, "failed to reset pending config: %s", string(out)) + return true, fmt.Errorf("failed to reset pending config: %s: %w", string(out), err) } state.currentConfig = state.pendingConfig @@ -1578,7 +1582,7 @@ func (dn *Daemon) updateConfigAndState(state *stateAndConfigs) (bool, error) { if err := dn.nodeWriter.SetDone(dn.kubeClient.CoreV1().Nodes(), dn.nodeLister, dn.name, state.currentConfig.GetName()); err != nil { errLabelStr := fmt.Sprintf("error setting node's state to Done: %v", err) MCDUpdateState.WithLabelValues("", errLabelStr).SetToCurrentTime() - return inDesiredConfig, errors.Wrap(err, "error setting node's state to Done") + return inDesiredConfig, fmt.Errorf("error setting node's state to Done: %w", err) } } @@ -1638,7 +1642,7 @@ func (dn *Daemon) runOnceFromIgnition(ignConfig ign3types.Config) error { _, err := os.Stat(constants.MachineConfigEncapsulatedPath) if err == nil { if err := os.Remove(constants.MachineConfigEncapsulatedPath); err != nil { - return errors.Wrapf(err, "failed to remove %s", constants.MachineConfigEncapsulatedPath) + return fmt.Errorf("failed to remove %s: %w", constants.MachineConfigEncapsulatedPath, err) } } return dn.reboot("runOnceFromIgnition complete") @@ -1751,7 +1755,7 @@ func (dn *Daemon) validateOnDiskState(currentConfig *mcfgv1.MachineConfig) error // Be sure we're booted into the OS we expect osMatch := dn.checkOS(currentConfig.Spec.OSImageURL) if !osMatch { - return errors.Errorf("expected target osImageURL %q, have %q", currentConfig.Spec.OSImageURL, dn.bootedOSImageURL) + return fmt.Errorf("expected target osImageURL %q, have %q", currentConfig.Spec.OSImageURL, dn.bootedOSImageURL) } return validateOnDiskState(currentConfig, pathSystemd) @@ -1840,7 +1844,7 @@ func (dn *Daemon) senseAndLoadOnceFrom(onceFrom string) (interface{}, onceFromOr return *mc, contentFrom, nil } - return nil, onceFromUnknownConfig, fmt.Errorf("unable to decipher onceFrom config type: %v", err) + return nil, onceFromUnknownConfig, fmt.Errorf("unable to decipher onceFrom config type: %w", err) } func isSingleNodeTopology(topology configv1.TopologyMode) bool { diff --git a/pkg/daemon/drain.go b/pkg/daemon/drain.go index 1507e02a36..da92329cf2 100644 --- a/pkg/daemon/drain.go +++ b/pkg/daemon/drain.go @@ -11,8 +11,8 @@ import ( "github.com/golang/glog" ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common" "github.com/openshift/machine-config-operator/pkg/daemon/constants" - "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" + kubeErrs "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/kubectl/pkg/drain" ) @@ -67,9 +67,10 @@ func (dn *Daemon) cordonOrUncordonNode(desired bool) error { return true, nil }); err != nil { if err == wait.ErrWaitTimeout { - return errors.Wrapf(lastErr, "failed to %s node (%d tries): %v", verb, backoff.Steps, err) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + return fmt.Errorf("failed to %s node (%d tries): %w", verb, backoff.Steps, errs) } - return errors.Wrapf(err, "failed to %s node", verb) + return fmt.Errorf("failed to %s node: %w", verb, err) } return nil @@ -111,7 +112,7 @@ func (dn *Daemon) drain() error { failMsg := fmt.Sprintf("failed to drain node : %s after 1 hour", dn.node.Name) dn.recorder.Eventf(getNodeRef(dn.node), corev1.EventTypeWarning, "FailedToDrain", failMsg) MCDDrainErr.Set(1) - return errors.New(failMsg) + return fmt.Errorf(failMsg) case <-drainer(): return nil } @@ -188,22 +189,22 @@ func isSafeContainerRegistryConfChanges(oldIgnConfig, newIgnConfig ign3types.Con // /etc/containers/registries.conf contains config in toml format. Parse the file oldData, err := ctrlcommon.GetIgnitionFileDataByPath(&oldIgnConfig, constants.ContainerRegistryConfPath) if err != nil { - return false, fmt.Errorf("Failed decoding Data URL scheme string: %v", err) + return false, fmt.Errorf("failed decoding Data URL scheme string: %w", err) } newData, err := ctrlcommon.GetIgnitionFileDataByPath(&newIgnConfig, constants.ContainerRegistryConfPath) if err != nil { - return false, fmt.Errorf("Failed decoding Data URL scheme string %v", err) + return false, fmt.Errorf("failed decoding Data URL scheme string %w", err) } tomlConfOldReg := sysregistriesv2.V2RegistriesConf{} if _, err := toml.Decode(string(oldData), &tomlConfOldReg); err != nil { - return false, fmt.Errorf("Failed decoding TOML content from file %s: %v", constants.ContainerRegistryConfPath, err) + return false, fmt.Errorf("failed decoding TOML content from file %s: %w", constants.ContainerRegistryConfPath, err) } tomlConfNewReg := sysregistriesv2.V2RegistriesConf{} if _, err := toml.Decode(string(newData), &tomlConfNewReg); err != nil { - return false, fmt.Errorf("Failed decoding TOML content from file %s: %v", constants.ContainerRegistryConfPath, err) + return false, fmt.Errorf("failed decoding TOML content from file %s: %w", constants.ContainerRegistryConfPath, err) } // Ensure that any unqualified-search-registries has not been deleted diff --git a/pkg/daemon/image-inspect.go b/pkg/daemon/image-inspect.go index 7a372f1ca6..f39973771c 100644 --- a/pkg/daemon/image-inspect.go +++ b/pkg/daemon/image-inspect.go @@ -10,7 +10,6 @@ import ( "github.com/containers/image/v5/docker" "github.com/containers/image/v5/image" "github.com/containers/image/v5/types" - "github.com/pkg/errors" ) const ( @@ -67,14 +66,14 @@ func imageInspect(imageName string) (*types.ImageInspectInfo, error) { src, err = newDockerImageSource(ctx, sys, imageName) return err }); err != nil { - return nil, errors.Wrapf(err, "Error parsing image name %q", imageName) + return nil, fmt.Errorf("error parsing image name %q: %w", imageName, err) } defer src.Close() img, err := image.FromUnparsedImage(ctx, sys, image.UnparsedInstance(src, nil)) if err != nil { - return nil, fmt.Errorf("Error parsing manifest for image: %v", err) + return nil, fmt.Errorf("error parsing manifest for image: %w", err) } if err := retryIfNecessary(ctx, func() error { diff --git a/pkg/daemon/kernelargs.go b/pkg/daemon/kernelargs.go index de7134ef09..124c54666e 100644 --- a/pkg/daemon/kernelargs.go +++ b/pkg/daemon/kernelargs.go @@ -13,7 +13,6 @@ import ( "github.com/golang/glog" "github.com/openshift/machine-config-operator/pkg/daemon/pivot/types" - errors "github.com/pkg/errors" ) const ( @@ -39,7 +38,7 @@ var tuneableFCOSArgsAllowlist = map[string]bool{ func isArgTunable(arg string) (bool, error) { os, err := GetHostRunningOS() if err != nil { - return false, errors.Errorf("failed to get OS for determining whether kernel arg is tuneable: %v", err) + return false, fmt.Errorf("failed to get OS for determining whether kernel arg is tuneable: %w", err) } if os.IsRHCOS() { @@ -84,7 +83,7 @@ func parseTuningFile(tuningFilePath, cmdLinePath string) ([]types.TuneArgument, // It's ok if the file doesn't exist return addArguments, deleteArguments, nil } - return addArguments, deleteArguments, errors.Wrapf(err, "reading %s", tuningFilePath) + return addArguments, deleteArguments, fmt.Errorf("reading %s: %w", tuningFilePath, err) } // Clean up defer file.Close() diff --git a/pkg/daemon/node.go b/pkg/daemon/node.go index ac2823a33a..f701827c29 100644 --- a/pkg/daemon/node.go +++ b/pkg/daemon/node.go @@ -25,7 +25,7 @@ func (dn *Daemon) loadNodeAnnotations(node *corev1.Node) (*corev1.Node, error) { d, err := ioutil.ReadFile(constants.InitialNodeAnnotationsFilePath) if err != nil && !os.IsNotExist(err) { - return nil, fmt.Errorf("failed to read initial annotations from %q: %v", constants.InitialNodeAnnotationsFilePath, err) + return nil, fmt.Errorf("failed to read initial annotations from %q: %w", constants.InitialNodeAnnotationsFilePath, err) } if os.IsNotExist(err) { // try currentConfig if, for whatever reason we lost annotations? this is super best effort. @@ -39,13 +39,13 @@ func (dn *Daemon) loadNodeAnnotations(node *corev1.Node) (*corev1.Node, error) { var initial map[string]string if err := json.Unmarshal(d, &initial); err != nil { - return nil, fmt.Errorf("failed to unmarshal initial annotations: %v", err) + return nil, fmt.Errorf("failed to unmarshal initial annotations: %w", err) } glog.Infof("Setting initial node config: %s", initial[constants.CurrentMachineConfigAnnotationKey]) n, err := setNodeAnnotations(dn.kubeClient.CoreV1().Nodes(), dn.nodeLister, node.Name, initial) if err != nil { - return nil, fmt.Errorf("failed to set initial annotations: %v", err) + return nil, fmt.Errorf("failed to set initial annotations: %w", err) } return n, nil } diff --git a/pkg/daemon/on_disk_validation.go b/pkg/daemon/on_disk_validation.go index 8d8f6f330d..f65807a754 100644 --- a/pkg/daemon/on_disk_validation.go +++ b/pkg/daemon/on_disk_validation.go @@ -14,7 +14,6 @@ import ( "github.com/google/go-cmp/cmp" mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common" - "github.com/pkg/errors" ) // Validates that the on-disk state matches a given MachineConfig. @@ -24,28 +23,28 @@ func validateOnDiskState(currentConfig *mcfgv1.MachineConfig, systemdPath string // to remove possibilities of behaviour changes due to translation ignconfigi, err := ctrlcommon.IgnParseWrapper(currentConfig.Spec.Config.Raw) if err != nil { - return errors.Errorf("Failed to parse Ignition for validation: %s", err) + return fmt.Errorf("failed to parse Ignition for validation: %w", err) } switch typedConfig := ignconfigi.(type) { case ign3types.Config: if err := checkV3Files(ignconfigi.(ign3types.Config).Storage.Files); err != nil { - return fileConfigDriftErr(err) + return &fileConfigDriftErr{err} } if err := checkV3Units(ignconfigi.(ign3types.Config).Systemd.Units, systemdPath); err != nil { - return unitConfigDriftErr(err) + return &unitConfigDriftErr{err} } return nil case ign2types.Config: if err := checkV2Files(ignconfigi.(ign2types.Config).Storage.Files); err != nil { - return fileConfigDriftErr(err) + return &fileConfigDriftErr{err} } if err := checkV2Units(ignconfigi.(ign2types.Config).Systemd.Units, systemdPath); err != nil { - return unitConfigDriftErr(err) + return &unitConfigDriftErr{err} } return nil default: - return errors.Errorf("unexpected type for ignition config: %v", typedConfig) + return fmt.Errorf("unexpected type for ignition config: %v", typedConfig) } } @@ -91,10 +90,10 @@ func checkV3Units(units []ign3types.Unit, systemdPath string) error { if unit.Mask != nil && *unit.Mask { link, err := filepath.EvalSymlinks(path) if err != nil { - return errors.Wrapf(err, "state validation: error while evaluation symlink for path %q", path) + return fmt.Errorf("state validation: error while evaluation symlink for path %q: %w", path, err) } if strings.Compare(pathDevNull, link) != 0 { - return errors.Errorf("state validation: invalid unit masked setting. path: %q; expected: %v; received: %v", path, pathDevNull, link) + return fmt.Errorf("state validation: invalid unit masked setting. path: %q; expected: %v; received: %v", path, pathDevNull, link) } } if err := checkFileContentsAndMode(path, []byte(*unit.Contents), defaultFilePermissions); err != nil { @@ -124,10 +123,10 @@ func checkV2Units(units []ign2types.Unit, systemdPath string) error { if unit.Mask { link, err := filepath.EvalSymlinks(path) if err != nil { - return errors.Wrapf(err, "state validation: error while evaluation symlink for path %q", path) + return fmt.Errorf("state validation: error while evaluation symlink for path %q: %w", path, err) } if strings.Compare(pathDevNull, link) != 0 { - return errors.Errorf("state validation: invalid unit masked setting. path: %q; expected: %v; received: %v", path, pathDevNull, link) + return fmt.Errorf("state validation: invalid unit masked setting. path: %q; expected: %v; received: %v", path, pathDevNull, link) } } if err := checkFileContentsAndMode(path, []byte(unit.Contents), defaultFilePermissions); err != nil { @@ -196,18 +195,18 @@ func checkV2Files(files []ign2types.File) error { func checkFileContentsAndMode(filePath string, expectedContent []byte, mode os.FileMode) error { fi, err := os.Lstat(filePath) if err != nil { - return errors.Wrapf(err, "could not stat file %q", filePath) + return fmt.Errorf("could not stat file %q: %w", filePath, err) } if fi.Mode() != mode { - return errors.Errorf("mode mismatch for file: %q; expected: %[2]v/%[2]d/%#[2]o; received: %[3]v/%[3]d/%#[3]o", filePath, mode, fi.Mode()) + return fmt.Errorf("mode mismatch for file: %q; expected: %[2]v/%[2]d/%#[2]o; received: %[3]v/%[3]d/%#[3]o", filePath, mode, fi.Mode()) } contents, err := ioutil.ReadFile(filePath) if err != nil { - return errors.Wrapf(err, "could not read file %q", filePath) + return fmt.Errorf("could not read file %q: %w", filePath, err) } if !bytes.Equal(contents, expectedContent) { glog.Errorf("content mismatch for file %q (-want +got):\n%s", filePath, cmp.Diff(expectedContent, contents)) - return errors.Errorf("content mismatch for file %q", filePath) + return fmt.Errorf("content mismatch for file %q", filePath) } return nil } diff --git a/pkg/daemon/pivot/utils/run.go b/pkg/daemon/pivot/utils/run.go index 569ab39f59..65f8c326b6 100644 --- a/pkg/daemon/pivot/utils/run.go +++ b/pkg/daemon/pivot/utils/run.go @@ -2,6 +2,7 @@ package utils import ( "bytes" + "fmt" "io" "os" "os/exec" @@ -9,7 +10,7 @@ import ( "time" "github.com/golang/glog" - "github.com/pkg/errors" + kubeErrs "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/wait" ) @@ -26,7 +27,7 @@ func runImpl(command string, args ...string) ([]byte, error) { cmd.Stdout = stdout err := cmd.Run() if err != nil { - return nil, errors.Wrapf(err, "running %s %s failed: %s", command, strings.Join(args, " "), b.String()) + return nil, fmt.Errorf("running %s %s failed: %s: %w", command, strings.Join(args, " "), b.String(), err) } return b.Bytes(), nil } @@ -48,9 +49,10 @@ func runExtBackoff(backoff wait.Backoff, command string, args ...string) (string return true, nil }); err != nil { if err == wait.ErrWaitTimeout { - return "", errors.Wrapf(lastErr, "failed to run command %s (%d tries): %v", command, backoff.Steps, err) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + return "", fmt.Errorf("failed to run command %s (%d tries): %w", command, backoff.Steps, errs) } - return "", errors.Wrap(err, "failed to run command %s (%d tries): %v") + return "", fmt.Errorf("failed to run command %s (%d tries): %w", command, backoff.Steps, err) } return output, nil } diff --git a/pkg/daemon/rpm-ostree.go b/pkg/daemon/rpm-ostree.go index f35ecaccdd..023e1286c5 100644 --- a/pkg/daemon/rpm-ostree.go +++ b/pkg/daemon/rpm-ostree.go @@ -12,7 +12,6 @@ import ( "github.com/golang/glog" "github.com/opencontainers/go-digest" pivotutils "github.com/openshift/machine-config-operator/pkg/daemon/pivot/utils" - "github.com/pkg/errors" ) const ( @@ -94,7 +93,7 @@ func (r *RpmOstreeClient) loadStatus() (*rpmOstreeState, error) { } if err := json.Unmarshal(output, &rosState); err != nil { - return nil, errors.Wrapf(err, "failed to parse `rpm-ostree status --json` output (%s)", truncate(string(output), 30)) + return nil, fmt.Errorf("failed to parse `rpm-ostree status --json` output (%s): %w", truncate(string(output), 30), err) } return &rosState, nil @@ -207,7 +206,7 @@ func podmanInspect(imgURL string) (imgdata *imageInspection, err error) { var imagedataArray []imageInspection err = json.Unmarshal(output, &imagedataArray) if err != nil { - err = errors.Wrapf(err, "unmarshaling podman inspect") + err = fmt.Errorf("unmarshaling podman inspect: %w", err) return } imgdata = &imagedataArray[0] @@ -283,11 +282,11 @@ func (r *RpmOstreeClient) Rebase(imgURL, osImageContentDir string) (changed bool } ostreeCsum = strings.TrimSpace(string(ostreeCsumBytes)) } else if len(refs) > 1 { - err = errors.New("multiple refs found in repo") + err = fmt.Errorf("multiple refs found in repo") return } else { // XXX: in the future, possibly scan the repo to find a unique .commit object - err = errors.New("No refs found in repo") + err = fmt.Errorf("no refs found in repo") return } } diff --git a/pkg/daemon/update.go b/pkg/daemon/update.go index d234fc5c48..f358152356 100644 --- a/pkg/daemon/update.go +++ b/pkg/daemon/update.go @@ -3,6 +3,7 @@ package daemon import ( "bufio" "bytes" + "errors" "fmt" "io/ioutil" "os" @@ -19,10 +20,10 @@ import ( ign3types "github.com/coreos/ignition/v2/config/v3_2/types" "github.com/golang/glog" "github.com/google/renameio" - errors "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + kubeErrs "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/uuid" mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" @@ -72,7 +73,7 @@ func writeFileAtomicallyWithDefaults(fpath string, b []byte) error { func writeFileAtomically(fpath string, b []byte, dirMode, fileMode os.FileMode, uid, gid int) error { dir := filepath.Dir(fpath) if err := os.MkdirAll(dir, dirMode); err != nil { - return fmt.Errorf("failed to create directory %q: %v", dir, err) + return fmt.Errorf("failed to create directory %q: %w", dir, err) } t, err := renameio.TempFile(dir, fpath) if err != nil { @@ -134,7 +135,7 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string if dn.recorder != nil { dn.recorder.Eventf(getNodeRef(dn.node), corev1.EventTypeWarning, "FailedServiceReload", fmt.Sprintf("Reloading %s service failed. Error: %v", serviceName, err)) } - return fmt.Errorf("Could not apply update: reloading %s configuration failed. Error: %v", serviceName, err) + return fmt.Errorf("could not apply update: reloading %s configuration failed. Error: %w", serviceName, err) } if dn.recorder != nil { @@ -148,12 +149,12 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string // Get current state of node, in case of an error reboot state, err := dn.getStateAndConfigs(configName) if err != nil { - return fmt.Errorf("Could not apply update: error processing state and configs. Error: %v", err) + return fmt.Errorf("could not apply update: error processing state and configs. Error: %w", err) } var inDesiredConfig bool if inDesiredConfig, err = dn.updateConfigAndState(state); err != nil { - return fmt.Errorf("Could not apply update: setting node's state to Done failed. Error: %v", err) + return fmt.Errorf("could not apply update: setting node's state to Done failed. Error: %w", err) } if inDesiredConfig { // (re)start the config drift monitor since rebooting isn't needed. @@ -169,7 +170,7 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string // It can also be called as a special case for the "bootstrap pivot". func (dn *Daemon) finalizeBeforeReboot(newConfig *mcfgv1.MachineConfig) (retErr error) { if out, err := dn.storePendingState(newConfig, 1); err != nil { - return errors.Wrapf(err, "failed to log pending config: %s", string(out)) + return fmt.Errorf("failed to log pending config: %s: %w", string(out), err) } defer func() { if retErr != nil { @@ -177,7 +178,8 @@ func (dn *Daemon) finalizeBeforeReboot(newConfig *mcfgv1.MachineConfig) (retErr dn.recorder.Eventf(getNodeRef(dn.node), corev1.EventTypeNormal, "PendingConfigRollBack", fmt.Sprintf("Rolling back pending config %s: %v", newConfig.GetName(), retErr)) } if out, err := dn.storePendingState(newConfig, 0); err != nil { - retErr = errors.Wrapf(retErr, "error rolling back pending config %v: %s", err, string(out)) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back pending config %s: %w", string(out), errs) return } } @@ -189,8 +191,6 @@ func (dn *Daemon) finalizeBeforeReboot(newConfig *mcfgv1.MachineConfig) (retErr return nil } -var errUnreconcilable = errors.New("unreconcilable") - func canonicalizeEmptyMC(config *mcfgv1.MachineConfig) *mcfgv1.MachineConfig { if config != nil { return config @@ -218,7 +218,7 @@ func (dn *Daemon) compareMachineConfig(oldConfig, newConfig *mcfgv1.MachineConfi newConfigName := newConfig.GetName() mcDiff, err := newMachineConfigDiff(oldConfig, newConfig) if err != nil { - return true, errors.Wrapf(err, "error creating machineConfigDiff for comparison") + return true, fmt.Errorf("error creating machineConfigDiff for comparison: %w", err) } if mcDiff.isEmpty() { glog.Infof("No changes from %s to %s", oldConfigName, newConfigName) @@ -284,7 +284,7 @@ func podmanCopy(imgURL, osImageContentDir string) (err error) { args = []string{"-R", "-t", "var_run_t", osImageContentDir} err = runCmdSync("chcon", args...) if err != nil { - err = errors.Wrapf(err, "changing selinux context on path %s", osImageContentDir) + err = fmt.Errorf("changing selinux context on path %s: %w", osImageContentDir, err) return } return @@ -300,7 +300,7 @@ func ExtractOSImage(imgURL string) (osImageContentDir string, err error) { registryConfig = append(registryConfig, "--registry-config", kubeletAuthFile) } if err = os.MkdirAll(osImageContentBaseDir, 0755); err != nil { - err = fmt.Errorf("error creating directory %s: %v", osImageContentBaseDir, err) + err = fmt.Errorf("error creating directory %s: %w", osImageContentBaseDir, err) return } @@ -390,7 +390,8 @@ func (dn *CoreOSDaemon) applyOSChanges(mcDiff machineConfigDiff, oldConfig, newC // Print out the error now so that if we fail to cleanup -p, we don't lose it. glog.Infof("Rolling back applied changes to OS due to error: %v", retErr) if err := removePendingDeployment(); err != nil { - retErr = errors.Wrapf(retErr, "error removing staged deployment: %v", err) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error removing staged deployment: %w", errs) return } } @@ -451,7 +452,7 @@ func calculatePostConfigChangeAction(diff *machineConfigDiff, diffFileSet []stri // this case regardless of what MachineConfig diff is. if _, err := os.Stat(constants.MachineConfigDaemonForceFile); err == nil { if err := os.Remove(constants.MachineConfigDaemonForceFile); err != nil { - return []string{}, errors.Wrap(err, "failed to remove force validation file") + return []string{}, fmt.Errorf("failed to remove force validation file: %w", err) } glog.Infof("Setting post config change action to postConfigChangeActionReboot; %s present", constants.MachineConfigDaemonForceFile) return []string{postConfigChangeActionReboot}, nil @@ -477,7 +478,7 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err } if state != constants.MachineConfigDaemonStateDegraded && state != constants.MachineConfigDaemonStateUnreconcilable { if err := dn.nodeWriter.SetWorking(dn.kubeClient.CoreV1().Nodes(), dn.nodeLister, dn.name); err != nil { - return errors.Wrap(err, "error setting node's state to Working") + return fmt.Errorf("error setting node's state to Working: %w", err) } } } @@ -507,7 +508,7 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err diff, reconcilableError := reconcilable(oldConfig, newConfig) if reconcilableError != nil { - wrappedErr := fmt.Errorf("can't reconcile config %s with %s: %v", oldConfigName, newConfigName, reconcilableError) + wrappedErr := fmt.Errorf("can't reconcile config %s with %s: %w", oldConfigName, newConfigName, reconcilableError) if dn.recorder != nil { mcRef := &corev1.ObjectReference{ Kind: "MachineConfig", @@ -516,7 +517,7 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err } dn.recorder.Eventf(mcRef, corev1.EventTypeWarning, "FailedToReconcile", wrappedErr.Error()) } - return errors.Wrapf(errUnreconcilable, "%v", wrappedErr) + return &unreconcilableErr{wrappedErr} } dn.logSystem("Starting update from %s to %s: %+v", oldConfigName, newConfigName, diff) @@ -548,7 +549,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err defer func() { if retErr != nil { if err := dn.updateFiles(newIgnConfig, oldIgnConfig); err != nil { - retErr = errors.Wrapf(retErr, "error rolling back files writes %v", err) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back files writes: %w", errs) return } } @@ -561,7 +563,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err defer func() { if retErr != nil { if err := dn.updateSSHKeys(oldIgnConfig.Passwd.Users); err != nil { - retErr = errors.Wrapf(retErr, "error rolling back SSH keys updates %v", err) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back SSH keys updates: %w", errs) return } } @@ -576,7 +579,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err defer func() { if retErr != nil { if err := coreOSDaemon.applyOSChanges(*diff, newConfig, oldConfig); err != nil { - retErr = errors.Wrapf(retErr, "error rolling back changes to OS %v", err) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back changes to OS: %w", errs) return } } @@ -597,7 +601,8 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err defer func() { if retErr != nil { if err := dn.storeCurrentConfigOnDisk(oldConfig); err != nil { - retErr = errors.Wrapf(retErr, "error rolling back current config on disk %v", err) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back current config on disk: %w", errs) return } } @@ -630,7 +635,8 @@ func (dn *Daemon) updateHypershift(oldConfig, newConfig *mcfgv1.MachineConfig, d defer func() { if retErr != nil { if err := dn.updateFiles(newIgnConfig, oldIgnConfig); err != nil { - retErr = errors.Wrapf(retErr, "error rolling back files writes %v", err) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back files writes: %w", errs) return } } @@ -643,7 +649,8 @@ func (dn *Daemon) updateHypershift(oldConfig, newConfig *mcfgv1.MachineConfig, d defer func() { if retErr != nil { if err := dn.updateSSHKeys(oldIgnConfig.Passwd.Users); err != nil { - retErr = errors.Wrapf(retErr, "error rolling back SSH keys updates %v", err) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back SSH keys updates: %w", errs) return } } @@ -658,7 +665,8 @@ func (dn *Daemon) updateHypershift(oldConfig, newConfig *mcfgv1.MachineConfig, d defer func() { if retErr != nil { if err := coreOSDaemon.applyOSChanges(*diff, newConfig, oldConfig); err != nil { - retErr = errors.Wrapf(retErr, "error rolling back changes to OS %v", err) + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back changes to OS: %w", errs) return } } @@ -727,11 +735,11 @@ func canonicalizeKernelType(kernelType string) string { func newMachineConfigDiff(oldConfig, newConfig *mcfgv1.MachineConfig) (*machineConfigDiff, error) { oldIgn, err := ctrlcommon.ParseAndConvertConfig(oldConfig.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing old Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing old Ignition config failed with error: %w", err) } newIgn, err := ctrlcommon.ParseAndConvertConfig(newConfig.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing new Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing new Ignition config failed with error: %w", err) } // Both nil and empty slices are of zero length, @@ -764,11 +772,11 @@ func reconcilable(oldConfig, newConfig *mcfgv1.MachineConfig) (*machineConfigDif // The ignition output in case of success will always have maxVersion oldIgn, err := ctrlcommon.ParseAndConvertConfig(oldConfig.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing old Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing old Ignition config failed with error: %w", err) } newIgn, err := ctrlcommon.ParseAndConvertConfig(newConfig.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing new Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing new Ignition config failed with error: %w", err) } // Check if this is a generally valid Ignition Config @@ -784,17 +792,17 @@ func reconcilable(oldConfig, newConfig *mcfgv1.MachineConfig) (*machineConfigDif passwdChanged := !reflect.DeepEqual(oldIgn.Passwd, newIgn.Passwd) if passwdChanged { if !reflect.DeepEqual(oldIgn.Passwd.Groups, newIgn.Passwd.Groups) { - return nil, errors.New("ignition Passwd Groups section contains changes") + return nil, fmt.Errorf("ignition Passwd Groups section contains changes") } if !reflect.DeepEqual(oldIgn.Passwd.Users, newIgn.Passwd.Users) { if len(oldIgn.Passwd.Users) > 0 && len(newIgn.Passwd.Users) == 0 { - return nil, errors.New("ignition passwd user section contains unsupported changes: user core may not be deleted") + return nil, fmt.Errorf("ignition passwd user section contains unsupported changes: user core may not be deleted") } // there is an update to Users, we must verify that it is ONLY making an acceptable // change to the SSHAuthorizedKeys for the user "core" for _, user := range newIgn.Passwd.Users { if user.Name != constants.CoreUserName { - return nil, errors.New("ignition passwd user section contains unsupported changes: non-core user") + return nil, fmt.Errorf("ignition passwd user section contains unsupported changes: non-core user") } } glog.Infof("user data to be verified before ssh update: %v", newIgn.Passwd.Users[len(newIgn.Passwd.Users)-1]) @@ -809,23 +817,23 @@ func reconcilable(oldConfig, newConfig *mcfgv1.MachineConfig) (*machineConfigDif // we can only reconcile files right now. make sure the sections we can't // fix aren't changed. if !reflect.DeepEqual(oldIgn.Storage.Disks, newIgn.Storage.Disks) { - return nil, errors.New("ignition disks section contains changes") + return nil, fmt.Errorf("ignition disks section contains changes") } if !reflect.DeepEqual(oldIgn.Storage.Filesystems, newIgn.Storage.Filesystems) { - return nil, errors.New("ignition filesystems section contains changes") + return nil, fmt.Errorf("ignition filesystems section contains changes") } if !reflect.DeepEqual(oldIgn.Storage.Raid, newIgn.Storage.Raid) { - return nil, errors.New("ignition raid section contains changes") + return nil, fmt.Errorf("ignition raid section contains changes") } if !reflect.DeepEqual(oldIgn.Storage.Directories, newIgn.Storage.Directories) { - return nil, errors.New("ignition directories section contains changes") + return nil, fmt.Errorf("ignition directories section contains changes") } if !reflect.DeepEqual(oldIgn.Storage.Links, newIgn.Storage.Links) { // This means links have been added, as opposed as being removed as it happened with // https://bugzilla.redhat.com/show_bug.cgi?id=1677198. This doesn't really change behavior // since we still don't support links but we allow old MC to remove links when upgrading. if len(newIgn.Storage.Links) != 0 { - return nil, errors.New("ignition links section contains changes") + return nil, fmt.Errorf("ignition links section contains changes") } } @@ -851,7 +859,7 @@ func reconcilable(oldConfig, newConfig *mcfgv1.MachineConfig) (*machineConfigDif glog.V(2).Info("Configs are reconcilable") mcDiff, err := newMachineConfigDiff(oldConfig, newConfig) if err != nil { - return nil, errors.Wrapf(err, "error creating machineConfigDiff") + return nil, fmt.Errorf("error creating machineConfigDiff: %w", err) } return mcDiff, nil } @@ -868,11 +876,11 @@ func verifyUserFields(pwdUser ign3types.PasswdUser) error { tempUser.Name = "" tempUser.SSHAuthorizedKeys = nil if !reflect.DeepEqual(emptyUser, tempUser) { - return errors.New("ignition passwd user section contains unsupported changes: non-sshKey changes") + return fmt.Errorf("ignition passwd user section contains unsupported changes: non-sshKey changes") } glog.Info("SSH Keys reconcilable") } else { - return errors.New("ignition passwd user section contains unsupported changes: user must be core and have 1 or more sshKeys") + return fmt.Errorf("ignition passwd user section contains unsupported changes: user must be core and have 1 or more sshKeys") } return nil } @@ -892,11 +900,11 @@ func checkFIPS(current, desired *mcfgv1.MachineConfig) error { glog.Infof("no %s on this system, skipping FIPS check", fipsFile) return nil } - return errors.Wrapf(err, "Error reading FIPS file at %s: %s", fipsFile, string(content)) + return fmt.Errorf("error reading FIPS file at %s: %s: %w", fipsFile, string(content), err) } nodeFIPS, err := strconv.ParseBool(strings.TrimSuffix(string(content), "\n")) if err != nil { - return errors.Wrapf(err, "Error parsing FIPS file at %s", fipsFile) + return fmt.Errorf("error parsing FIPS file at %s: %w", fipsFile, err) } if desired.Spec.FIPS == nodeFIPS { if desired.Spec.FIPS { @@ -906,7 +914,7 @@ func checkFIPS(current, desired *mcfgv1.MachineConfig) error { current.Spec.FIPS = nodeFIPS return nil } - return errors.New("detected change to FIPS flag; refusing to modify FIPS on a running cluster") + return fmt.Errorf("detected change to FIPS flag; refusing to modify FIPS on a running cluster") } // checks for white-space characters in "C" and "POSIX" locales. @@ -1191,10 +1199,10 @@ func (dn *Daemon) updateFiles(oldIgnConfig, newIgnConfig ign3types.Config) error func restorePath(path string) error { if out, err := exec.Command("cp", "-a", "--reflink=auto", origFileName(path), path).CombinedOutput(); err != nil { - return errors.Wrapf(err, "restoring %q from orig file %q: %s", path, origFileName(path), string(out)) + return fmt.Errorf("restoring %q from orig file %q: %s: %w", path, origFileName(path), string(out), err) } if err := os.Remove(origFileName(path)); err != nil { - return errors.Wrapf(err, "deleting orig file %q: %v", origFileName(path), err) + return fmt.Errorf("deleting orig file %q: %w", origFileName(path), err) } return nil } @@ -1252,8 +1260,8 @@ func (dn *Daemon) deleteStaleData(oldIgnConfig, newIgnConfig ign3types.Config) e continue } if _, err := os.Stat(noOrigFileStampName(f.Path)); err == nil { - if err := os.Remove(noOrigFileStampName(f.Path)); err != nil { - return errors.Wrapf(err, "deleting noorig file stamp %q: %v", noOrigFileStampName(f.Path), err) + if delErr := os.Remove(noOrigFileStampName(f.Path)); delErr != nil { + return fmt.Errorf("deleting noorig file stamp %q: %w", noOrigFileStampName(f.Path), delErr) } glog.V(2).Infof("Removing file %q completely", f.Path) } else if _, err := os.Stat(origFileName(f.Path)); err == nil { @@ -1284,8 +1292,8 @@ func (dn *Daemon) deleteStaleData(oldIgnConfig, newIgnConfig ign3types.Config) e continue } - if err := os.Remove(origFileName(f.Path)); err != nil { - return errors.Wrapf(err, "deleting orig file %q: %v", origFileName(f.Path), err) + if delErr := os.Remove(origFileName(f.Path)); delErr != nil { + return fmt.Errorf("deleting orig file %q: %w", origFileName(f.Path), delErr) } } @@ -1297,7 +1305,7 @@ func (dn *Daemon) deleteStaleData(oldIgnConfig, newIgnConfig ign3types.Config) e glog.V(2).Infof("Deleting stale config file: %s", f.Path) if err := os.Remove(f.Path); err != nil { - newErr := fmt.Errorf("unable to delete %s: %s", f.Path, err) + newErr := fmt.Errorf("unable to delete %s: %w", f.Path, err) if !os.IsNotExist(err) { return newErr } @@ -1323,8 +1331,8 @@ func (dn *Daemon) deleteStaleData(oldIgnConfig, newIgnConfig ign3types.Config) e path := filepath.Join(pathSystemd, u.Name+".d", u.Dropins[j].Name) if _, ok := newDropinSet[path]; !ok { if _, err := os.Stat(noOrigFileStampName(path)); err == nil { - if err := os.Remove(noOrigFileStampName(path)); err != nil { - return errors.Wrapf(err, "deleting noorig file stamp %q: %v", noOrigFileStampName(path), err) + if delErr := os.Remove(noOrigFileStampName(path)); delErr != nil { + return fmt.Errorf("deleting noorig file stamp %q: %w", noOrigFileStampName(path), delErr) } glog.V(2).Infof("Removing file %q completely", path) } else if _, err := os.Stat(origFileName(path)); err == nil { @@ -1336,7 +1344,7 @@ func (dn *Daemon) deleteStaleData(oldIgnConfig, newIgnConfig ign3types.Config) e } glog.V(2).Infof("Deleting stale systemd dropin file: %s", path) if err := os.Remove(path); err != nil { - newErr := fmt.Errorf("unable to delete %s: %s", path, err) + newErr := fmt.Errorf("unable to delete %s: %w", path, err) if !os.IsNotExist(err) { return newErr } @@ -1356,8 +1364,8 @@ func (dn *Daemon) deleteStaleData(oldIgnConfig, newIgnConfig ign3types.Config) e glog.Infof("Did not restore preset for %s (may not exist): %s", u.Name, err) } if _, err := os.Stat(noOrigFileStampName(path)); err == nil { - if err := os.Remove(noOrigFileStampName(path)); err != nil { - return errors.Wrapf(err, "deleting noorig file stamp %q: %v", noOrigFileStampName(path), err) + if delErr := os.Remove(noOrigFileStampName(path)); delErr != nil { + return fmt.Errorf("deleting noorig file stamp %q: %w", noOrigFileStampName(path), delErr) } glog.V(2).Infof("Removing file %q completely", path) } else if _, err := os.Stat(origFileName(path)); err == nil { @@ -1369,7 +1377,7 @@ func (dn *Daemon) deleteStaleData(oldIgnConfig, newIgnConfig ign3types.Config) e } glog.V(2).Infof("Deleting stale systemd unit file: %s", path) if err := os.Remove(path); err != nil { - newErr := fmt.Errorf("unable to delete %s: %s", path, err) + newErr := fmt.Errorf("unable to delete %s: %w", path, err) if !os.IsNotExist(err) { return newErr } @@ -1476,7 +1484,7 @@ func (dn *Daemon) writeDropins(u ign3types.Unit) error { } } if err := writeFileAtomicallyWithDefaults(dpath, []byte(*u.Dropins[i].Contents)); err != nil { - return fmt.Errorf("failed to write systemd unit dropin %q: %v", u.Dropins[i].Name, err) + return fmt.Errorf("failed to write systemd unit dropin %q: %w", u.Dropins[i].Name, err) } glog.V(2).Infof("Wrote systemd unit dropin at %s", dpath) @@ -1500,12 +1508,12 @@ func (dn *Daemon) writeUnits(units []ign3types.Unit) error { glog.V(2).Info("Systemd unit masked") if err := os.RemoveAll(fpath); err != nil { - return fmt.Errorf("failed to remove unit %q: %v", u.Name, err) + return fmt.Errorf("failed to remove unit %q: %w", u.Name, err) } glog.V(2).Infof("Removed unit %q", u.Name) if err := renameio.Symlink(pathDevNull, fpath); err != nil { - return fmt.Errorf("failed to symlink unit %q to %s: %v", u.Name, pathDevNull, err) + return fmt.Errorf("failed to symlink unit %q to %s: %w", u.Name, pathDevNull, err) } glog.V(2).Infof("Created symlink unit %q to %s", u.Name, pathDevNull) @@ -1521,7 +1529,7 @@ func (dn *Daemon) writeUnits(units []ign3types.Unit) error { } } if err := writeFileAtomicallyWithDefaults(fpath, []byte(*u.Contents)); err != nil { - return fmt.Errorf("failed to write systemd unit %q: %v", u.Name, err) + return fmt.Errorf("failed to write systemd unit %q: %w", u.Name, err) } glog.V(2).Infof("Successfully wrote systemd unit %q: ", u.Name) @@ -1533,7 +1541,7 @@ func (dn *Daemon) writeUnits(units []ign3types.Unit) error { // of those edge cases rather than introducing more complexity. glog.V(2).Infof("Ensuring systemd unit %q has no mask at %q", u.Name, fpath) if err := os.RemoveAll(fpath); err != nil { - return fmt.Errorf("failed to cleanup %s: %v", fpath, err) + return fmt.Errorf("failed to cleanup %s: %w", fpath, err) } } @@ -1602,7 +1610,7 @@ func (dn *Daemon) writeFiles(files []ign3types.File) error { // set chown if file information is provided uid, gid, err := getFileOwnership(file) if err != nil { - return fmt.Errorf("failed to retrieve file ownership for file %q: %v", file.Path, err) + return fmt.Errorf("failed to retrieve file ownership for file %q: %w", file.Path, err) } if err := createOrigFile(file.Path, file.Path); err != nil { return err @@ -1646,8 +1654,8 @@ func createOrigFile(fromPath, fpath string) error { // create a noorig file that tells the MCD that the file wasn't present on disk before MCD // took over so it can just remove it when deleting stale data, as opposed as restoring a file // that was shipped _with_ the underlying OS (e.g. a default chrony config). - if err := os.MkdirAll(filepath.Dir(noOrigFileStampName(fpath)), 0755); err != nil { - return errors.Wrapf(err, "creating no orig parent dir: %v", err) + if makeErr := os.MkdirAll(filepath.Dir(noOrigFileStampName(fpath)), 0755); makeErr != nil { + return fmt.Errorf("creating no orig parent dir: %w", makeErr) } return writeFileAtomicallyWithDefaults(noOrigFileStampName(fpath), nil) } @@ -1664,10 +1672,10 @@ func createOrigFile(fromPath, fpath string) error { return nil } if err := os.MkdirAll(filepath.Dir(origFileName(fpath)), 0755); err != nil { - return errors.Wrapf(err, "creating orig parent dir: %v", err) + return fmt.Errorf("creating orig parent dir: %w", err) } if out, err := exec.Command("cp", "-a", "--reflink=auto", fromPath, origFileName(fpath)).CombinedOutput(); err != nil { - return errors.Wrapf(err, "creating orig file for %q: %s", fpath, string(out)) + return fmt.Errorf("creating orig file for %q: %s: %w", fpath, string(out), err) } return nil } @@ -1785,11 +1793,11 @@ func (dn *Daemon) updateSSHKeys(newUsers []ign3types.PasswdUser) error { if err == nil { err := os.RemoveAll(authKeyPath) if err != nil { - return fmt.Errorf("failed to remove path '%s': %v", authKeyPath, err) + return fmt.Errorf("failed to remove path '%s': %w", authKeyPath, err) } } else if !os.IsNotExist(err) { // This shouldn't ever happen - return fmt.Errorf("unexpectedly failed to get info for path '%s': %v", authKeyPath, err) + return fmt.Errorf("unexpectedly failed to get info for path '%s': %w", authKeyPath, err) } // Ensure authorized_keys.d/ignition is the only fragment that exists @@ -1800,13 +1808,13 @@ func (dn *Daemon) updateSSHKeys(newUsers []ign3types.PasswdUser) error { keyPath := filepath.Join(authKeyFragmentDirPath, fragment.Name()) err := os.RemoveAll(keyPath) if err != nil { - return fmt.Errorf("failed to remove path '%s': %v", keyPath, err) + return fmt.Errorf("failed to remove path '%s': %w", keyPath, err) } } } } else if !os.IsNotExist(err) { // This shouldn't ever happen - return fmt.Errorf("unexpectedly failed to get info for path '%s': %v", authKeyFragmentDirPath, err) + return fmt.Errorf("unexpectedly failed to get info for path '%s': %w", authKeyFragmentDirPath, err) } } @@ -1824,7 +1832,7 @@ func updateOS(config *mcfgv1.MachineConfig, osImageContentDir string) error { glog.Infof("Updating OS to %s", newURL) client := NewNodeUpdaterClient() if _, err := client.Rebase(newURL, osImageContentDir); err != nil { - return fmt.Errorf("failed to update OS to %s : %v", newURL, err) + return fmt.Errorf("failed to update OS to %s : %w", newURL, err) } return nil @@ -1839,7 +1847,7 @@ func (dn *Daemon) getPendingStateLegacyLogger() (*journalMsg, error) { cmd.Stdout = &combinedOutput cmd.Stderr = &combinedOutput if err := cmd.Start(); err != nil { - return nil, errors.Wrap(err, "failed shelling out to journalctl -o cat") + return nil, fmt.Errorf("failed shelling out to journalctl -o cat: %w", err) } if err := cmd.Wait(); err != nil { if exiterr, ok := err.(*exec.ExitError); ok { @@ -1852,11 +1860,12 @@ func (dn *Daemon) getPendingStateLegacyLogger() (*journalMsg, error) { return nil, nil } if status.ExitStatus() > 1 { - return nil, errors.Wrapf(fmt.Errorf("grep exited with %s", combinedOutput.Bytes()), "failed to grep on journal output: %v", exiterr) + errs := kubeErrs.NewAggregate([]error{exiterr, fmt.Errorf("grep exited with %s", combinedOutput.Bytes())}) + return nil, fmt.Errorf("failed to grep on journal output: %w", errs) } } } else { - return nil, errors.Wrap(err, "command wait error") + return nil, fmt.Errorf("command wait error: %w", err) } } journalOutput := combinedOutput.Bytes() @@ -1880,7 +1889,7 @@ func (dn *Daemon) processJournalOutput(journalOutput []byte) (*journalMsg, error entry := &journalMsg{} if err := json.Unmarshal([]byte(last), entry); err != nil { - return nil, errors.Wrap(err, "getting pending state from journal") + return nil, fmt.Errorf("getting pending state from journal: %w", err) } if entry.Pending == "0" { return nil, nil @@ -1899,7 +1908,7 @@ func (dn *Daemon) getPendingState() (*journalMsg, error) { } journalOutput, err := exec.Command("journalctl", "-o", "json", "_UID=0", fmt.Sprintf("MESSAGE_ID=%s", pendingStateMessageID)).CombinedOutput() if err != nil { - return nil, errors.Wrap(err, "error running journalctl -o json") + return nil, fmt.Errorf("error running journalctl -o json: %w", err) } if len(journalOutput) == 0 { return nil, nil @@ -1950,7 +1959,7 @@ func runCmdSync(cmdName string, args ...string) error { cmd.Stdout = os.Stdout cmd.Stderr = &stderr if err := cmd.Run(); err != nil { - return errors.Wrapf(err, "error running %s %s: %s", cmdName, strings.Join(args, " "), string(stderr.Bytes())) + return fmt.Errorf("error running %s %s: %s: %w", cmdName, strings.Join(args, " "), string(stderr.Bytes()), err) } return nil diff --git a/pkg/operator/bootstrap.go b/pkg/operator/bootstrap.go index cd482bcff7..7efe6f8690 100644 --- a/pkg/operator/bootstrap.go +++ b/pkg/operator/bootstrap.go @@ -120,7 +120,7 @@ func RenderBootstrap( if infra.Spec.CloudConfig.Name != "" { cloudConf, err := loadBootstrapCloudProviderConfig(infra, cloudConfigFile) if err != nil { - return fmt.Errorf("failed to load the cloud provider config: %v", err) + return fmt.Errorf("failed to load the cloud provider config: %w", err) } spec.CloudProviderConfig = cloudConf } diff --git a/pkg/operator/render.go b/pkg/operator/render.go index de5de5bd30..9dbb89dcf8 100644 --- a/pkg/operator/render.go +++ b/pkg/operator/render.go @@ -50,7 +50,7 @@ func newAssetRenderer(path string) *assetRenderer { func (a *assetRenderer) read() error { objBytes, err := manifests.ReadFile(a.Path) if err != nil { - return fmt.Errorf("error getting asset %s: %v", a.Path, err) + return fmt.Errorf("error getting asset %s: %w", a.Path, err) } a.templateData = string(objBytes) return nil @@ -70,12 +70,12 @@ func (a *assetRenderer) addTemplateFuncs() { func (a *assetRenderer) render(config interface{}) ([]byte, error) { tmpl, err := a.tmpl.Parse(a.templateData) if err != nil { - return nil, fmt.Errorf("failed to parse asset %s: %v", a.Path, err) + return nil, fmt.Errorf("failed to parse asset %s: %w", a.Path, err) } buf := new(bytes.Buffer) if err := tmpl.Execute(buf, config); err != nil { - return nil, fmt.Errorf("failed to execute template: %v", err) + return nil, fmt.Errorf("failed to execute template: %w", err) } return buf.Bytes(), nil diff --git a/pkg/operator/status.go b/pkg/operator/status.go index 92b2a55c6d..ca19af506f 100644 --- a/pkg/operator/status.go +++ b/pkg/operator/status.go @@ -391,7 +391,7 @@ func (optr *Operator) isKubeletSkewSupported(pools []*v1.MachineConfigPool) (ske ) nodes, err := optr.GetAllManagedNodes(pools) if err != nil { - err = fmt.Errorf("getting all managed nodes failed: %v", err) + err = fmt.Errorf("getting all managed nodes failed: %w", err) coStatus.Reason = skewUnchecked coStatus.Message = fmt.Sprintf("An error occurred when getting all the managed nodes: %v", err.Error()) } @@ -441,7 +441,7 @@ func (optr *Operator) GetAllManagedNodes(pools []*v1.MachineConfigPool) ([]*core } poolNodes, err := optr.nodeLister.List(selector) if err != nil { - return nil, fmt.Errorf("could not list nodes for pool %v with error %v", pool.Name, err) + return nil, fmt.Errorf("could not list nodes for pool %v with error %w", pool.Name, err) } nodes = append(nodes, poolNodes...) } diff --git a/pkg/operator/sync.go b/pkg/operator/sync.go index fc2946bea9..63f274987c 100644 --- a/pkg/operator/sync.go +++ b/pkg/operator/sync.go @@ -15,7 +15,6 @@ import ( "time" "github.com/golang/glog" - "github.com/pkg/errors" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -23,6 +22,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + kubeErrs "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/tools/cache" @@ -104,7 +104,7 @@ type syncError struct { func (optr *Operator) syncAll(syncFuncs []syncFunc) error { if err := optr.syncProgressingStatus(); err != nil { - return fmt.Errorf("error syncing progressing status: %v", err) + return fmt.Errorf("error syncing progressing status: %w", err) } var syncErr syncError @@ -121,28 +121,28 @@ func (optr *Operator) syncAll(syncFuncs []syncFunc) error { break } if err := optr.clearDegradedStatus(sf.name); err != nil { - return fmt.Errorf("error clearing degraded status: %v", err) + return fmt.Errorf("error clearing degraded status: %w", err) } } if err := optr.syncDegradedStatus(syncErr); err != nil { - return fmt.Errorf("error syncing degraded status: %v", err) + return fmt.Errorf("error syncing degraded status: %w", err) } if err := optr.syncAvailableStatus(syncErr); err != nil { - return fmt.Errorf("error syncing available status: %v", err) + return fmt.Errorf("error syncing available status: %w", err) } if err := optr.syncUpgradeableStatus(); err != nil { - return fmt.Errorf("error syncing upgradeble status: %v", err) + return fmt.Errorf("error syncing upgradeble status: %w", err) } if err := optr.syncVersion(); err != nil { - return fmt.Errorf("error syncing version: %v", err) + return fmt.Errorf("error syncing version: %w", err) } if err := optr.syncRelatedObjects(); err != nil { - return fmt.Errorf("error syncing relatedObjects: %v", err) + return fmt.Errorf("error syncing relatedObjects: %w", err) } if optr.inClusterBringup && syncErr.err == nil { @@ -173,7 +173,7 @@ func (optr *Operator) syncCloudConfig(spec *mcfgv1.ControllerConfigSpec, infra * if apierrors.IsNotFound(err) { if isKubeCloudConfigCMRequired(infra) { // Return error only if the kube-cloud-config ConfigMap is required, otherwise proceeds further. - return fmt.Errorf("%s/%s configmap is required on platform %s but not found: %v", + return fmt.Errorf("%s/%s configmap is required on platform %s but not found: %w", "openshift-config-managed", "kube-cloud-config", infra.Status.PlatformStatus.Type, err) } return nil @@ -209,7 +209,7 @@ func (optr *Operator) syncRenderConfig(_ *renderConfig) error { glog.V(4).Info("Starting inClusterBringup informers cache sync") // sync now our own informers after having installed the CRDs if !cache.WaitForCacheSync(optr.stopCh, optr.ccListerSynced) { - return errors.New("failed to sync caches for informers") + return fmt.Errorf("failed to sync caches for informers") } glog.V(4).Info("Finished inClusterBringup informers cache sync") } @@ -376,7 +376,7 @@ func (optr *Operator) syncCustomResourceDefinitions() error { for _, crd := range crds { crdBytes, err := manifests.ReadFile(crd) if err != nil { - return fmt.Errorf("error getting asset %s: %v", crd, err) + return fmt.Errorf("error getting asset %s: %w", crd, err) } c := resourceread.ReadCustomResourceDefinitionV1OrDie(crdBytes) _, updated, err := resourceapply.ApplyCustomResourceDefinitionV1(context.TODO(), optr.apiExtClient.ApiextensionsV1(), optr.libgoRecorder, c) @@ -653,7 +653,8 @@ func (optr *Operator) syncRequiredMachineConfigPools(_ *renderConfig) error { if lastErr != nil { co, err := optr.fetchClusterOperator() if err != nil { - lastErr = errors.Wrapf(lastErr, "failed to fetch clusteroperator: %v", err) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + lastErr = fmt.Errorf("failed to fetch clusteroperator: %w", errs) return false, nil } if co == nil { @@ -663,7 +664,8 @@ func (optr *Operator) syncRequiredMachineConfigPools(_ *renderConfig) error { optr.setOperatorStatusExtension(&co.Status, lastErr) _, err = optr.configClient.ConfigV1().ClusterOperators().UpdateStatus(context.TODO(), co, metav1.UpdateOptions{}) if err != nil { - lastErr = errors.Wrapf(lastErr, "failed to update clusteroperator: %v", err) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + lastErr = fmt.Errorf("failed to update clusteroperator: %w", errs) return false, nil } } @@ -695,7 +697,7 @@ func (optr *Operator) syncRequiredMachineConfigPools(_ *renderConfig) error { } releaseVersion, _ := optr.vStore.Get("operator") if err := isMachineConfigPoolConfigurationValid(pool, version.Hash, releaseVersion, opURL, optr.mcLister.Get); err != nil { - lastErr = fmt.Errorf("pool %s has not progressed to latest configuration: %v, retrying", pool.Name, err) + lastErr = fmt.Errorf("pool %s has not progressed to latest configuration: %w, retrying", pool.Name, err) syncerr := optr.syncUpgradeableStatus() if syncerr != nil { glog.Errorf("Error syncingUpgradeableStatus: %q", syncerr) @@ -719,7 +721,8 @@ func (optr *Operator) syncRequiredMachineConfigPools(_ *renderConfig) error { }); err != nil { if err == wait.ErrWaitTimeout { glog.Errorf("Error syncing Required MachineConfigPools: %q", lastErr) - return fmt.Errorf("%v during syncRequiredMachineConfigPools: %v", err, lastErr) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + return fmt.Errorf("error during syncRequiredMachineConfigPools: %w", errs) } return err } @@ -745,7 +748,7 @@ func (optr *Operator) waitForCustomResourceDefinition(resource *apiextv1.CustomR if err := wait.Poll(customResourceReadyInterval, customResourceReadyTimeout, func() (bool, error) { crd, err := optr.crdLister.Get(resource.Name) if err != nil { - lastErr = fmt.Errorf("error getting CustomResourceDefinition %s: %v", resource.Name, err) + lastErr = fmt.Errorf("error getting CustomResourceDefinition %s: %w", resource.Name, err) return false, nil } @@ -758,7 +761,8 @@ func (optr *Operator) waitForCustomResourceDefinition(resource *apiextv1.CustomR return false, nil }); err != nil { if err == wait.ErrWaitTimeout { - return fmt.Errorf("%v during syncCustomResourceDefinitions: %v", err, lastErr) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + return fmt.Errorf("error during syncCustomResourceDefinitions: %w", errs) } return err } @@ -777,22 +781,23 @@ func (optr *Operator) waitForDeploymentRollout(resource *appsv1.Deployment) erro if err != nil { // Do not return error here, as we could be updating the API Server itself, in which case we // want to continue waiting. - lastErr = fmt.Errorf("error getting Deployment %s during rollout: %v", resource.Name, err) + lastErr = fmt.Errorf("error getting Deployment %s during rollout: %w", resource.Name, err) return false, nil } if d.DeletionTimestamp != nil { - return false, fmt.Errorf("Deployment %s is being deleted", resource.Name) + return false, fmt.Errorf("deployment %s is being deleted", resource.Name) } if d.Generation <= d.Status.ObservedGeneration && d.Status.UpdatedReplicas == d.Status.Replicas && d.Status.UnavailableReplicas == 0 { return true, nil } - lastErr = fmt.Errorf("Deployment %s is not ready. status: (replicas: %d, updated: %d, ready: %d, unavailable: %d)", d.Name, d.Status.Replicas, d.Status.UpdatedReplicas, d.Status.ReadyReplicas, d.Status.UnavailableReplicas) + lastErr = fmt.Errorf("deployment %s is not ready. status: (replicas: %d, updated: %d, ready: %d, unavailable: %d)", d.Name, d.Status.Replicas, d.Status.UpdatedReplicas, d.Status.ReadyReplicas, d.Status.UnavailableReplicas) return false, nil }); err != nil { if err == wait.ErrWaitTimeout { - return fmt.Errorf("%v during waitForDeploymentRollout: %v", err, lastErr) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + return fmt.Errorf("error during waitForDeploymentRollout: %w", errs) } return err } @@ -811,22 +816,23 @@ func (optr *Operator) waitForDaemonsetRollout(resource *appsv1.DaemonSet) error if err != nil { // Do not return error here, as we could be updating the API Server itself, in which case we // want to continue waiting. - lastErr = fmt.Errorf("error getting Daemonset %s during rollout: %v", resource.Name, err) + lastErr = fmt.Errorf("error getting Daemonset %s during rollout: %w", resource.Name, err) return false, nil } if d.DeletionTimestamp != nil { - return false, fmt.Errorf("Deployment %s is being deleted", resource.Name) + return false, fmt.Errorf("deployment %s is being deleted", resource.Name) } if d.Generation <= d.Status.ObservedGeneration && d.Status.UpdatedNumberScheduled == d.Status.DesiredNumberScheduled && d.Status.NumberUnavailable == 0 { return true, nil } - lastErr = fmt.Errorf("Daemonset %s is not ready. status: (desired: %d, updated: %d, ready: %d, unavailable: %d)", d.Name, d.Status.DesiredNumberScheduled, d.Status.UpdatedNumberScheduled, d.Status.NumberReady, d.Status.NumberUnavailable) + lastErr = fmt.Errorf("daemonset %s is not ready. status: (desired: %d, updated: %d, ready: %d, unavailable: %d)", d.Name, d.Status.DesiredNumberScheduled, d.Status.UpdatedNumberScheduled, d.Status.NumberReady, d.Status.NumberUnavailable) return false, nil }); err != nil { if err == wait.ErrWaitTimeout { - return fmt.Errorf("%v during waitForDaemonsetRollout: %v", err, lastErr) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + return fmt.Errorf("error during waitForDaemonsetRollout: %w", errs) } return err } @@ -837,13 +843,14 @@ func (optr *Operator) waitForControllerConfigToBeCompleted(resource *mcfgv1.Cont var lastErr error if err := wait.Poll(controllerConfigCompletedInterval, controllerConfigCompletedTimeout, func() (bool, error) { if err := mcfgv1.IsControllerConfigCompleted(resource.GetName(), optr.ccLister.Get); err != nil { - lastErr = fmt.Errorf("controllerconfig is not completed: %v", err) + lastErr = fmt.Errorf("controllerconfig is not completed: %w", err) return false, nil } return true, nil }); err != nil { if err == wait.ErrWaitTimeout { - return fmt.Errorf("%v during waitForControllerConfigToBeCompleted: %v", err, lastErr) + errs := kubeErrs.NewAggregate([]error{err, lastErr}) + return fmt.Errorf("error during waitForControllerConfigToBeCompleted: %w", errs) } return err } diff --git a/pkg/server/api.go b/pkg/server/api.go index 4397ae85ea..d31440d9d3 100644 --- a/pkg/server/api.go +++ b/pkg/server/api.go @@ -12,7 +12,6 @@ import ( "github.com/clarketm/json" "github.com/coreos/go-semver/semver" "github.com/golang/glog" - "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common" @@ -253,7 +252,7 @@ func parseAcceptHeader(input string) ([]acceptHeaderValue, error) { } if len(header) == 0 { - return nil, errors.New("no valid accept header detected") + return nil, fmt.Errorf("no valid accept header detected") } // Sort headers by descending q factor value. @@ -294,7 +293,7 @@ func detectSpecVersionFromAcceptHeader(acceptHeader string) (*semver.Version, er } else if !header.SemVer.LessThan(*v2_2) && header.SemVer.LessThan(*semver.New("3.0.0")) { return v2_2, nil } - ignVersionError = errors.Errorf("unsupported Ignition version in Accept header: %s", acceptHeader) + ignVersionError = fmt.Errorf("unsupported Ignition version in Accept header: %s", acceptHeader) } } // return error if version of Ignition MIME subtype is not supported diff --git a/pkg/server/bootstrap_server.go b/pkg/server/bootstrap_server.go index 28ca688fbd..b0b878c126 100644 --- a/pkg/server/bootstrap_server.go +++ b/pkg/server/bootstrap_server.go @@ -70,13 +70,13 @@ func (bsc *bootstrapServer) GetConfig(cr poolRequest) (*runtime.RawExtension, er return nil, nil } if err != nil { - return nil, fmt.Errorf("server: could not read file %s, err: %v", fileName, err) + return nil, fmt.Errorf("server: could not read file %s, err: %w", fileName, err) } mp := new(mcfgv1.MachineConfigPool) err = yaml.Unmarshal(data, mp) if err != nil { - return nil, fmt.Errorf("server: could not unmarshal file %s, err: %v", fileName, err) + return nil, fmt.Errorf("server: could not unmarshal file %s, err: %w", fileName, err) } currConf := mp.Status.Configuration.Name @@ -90,17 +90,17 @@ func (bsc *bootstrapServer) GetConfig(cr poolRequest) (*runtime.RawExtension, er return nil, nil } if err != nil { - return nil, fmt.Errorf("server: could not read file %s, err: %v", fileName, err) + return nil, fmt.Errorf("server: could not read file %s, err: %w", fileName, err) } mc := new(mcfgv1.MachineConfig) err = yaml.Unmarshal(data, mc) if err != nil { - return nil, fmt.Errorf("server: could not unmarshal file %s, err: %v", fileName, err) + return nil, fmt.Errorf("server: could not unmarshal file %s, err: %w", fileName, err) } ignConf, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing Ignition config failed with error: %w", err) } appenders := getAppenders(currConf, nil, bsc.kubeconfigFunc) @@ -120,7 +120,7 @@ func (bsc *bootstrapServer) GetConfig(cr poolRequest) (*runtime.RawExtension, er func kubeconfigFromFile(path string) ([]byte, []byte, error) { kcData, err := ioutil.ReadFile(path) if err != nil { - return nil, nil, fmt.Errorf("error getting kubeconfig from disk: %v", err) + return nil, nil, fmt.Errorf("error getting kubeconfig from disk: %w", err) } kc := clientcmd.Config{} diff --git a/pkg/server/cluster_server.go b/pkg/server/cluster_server.go index 4c9e13bb20..d032d05d5c 100644 --- a/pkg/server/cluster_server.go +++ b/pkg/server/cluster_server.go @@ -49,7 +49,7 @@ type clusterServer struct { func NewClusterServer(kubeConfig, apiserverURL string) (Server, error) { restConfig, err := getClientConfig(kubeConfig) if err != nil { - return nil, fmt.Errorf("Failed to create Kubernetes rest client: %v", err) + return nil, fmt.Errorf("failed to create Kubernetes rest client: %w", err) } mc := v1.NewForConfigOrDie(restConfig) @@ -64,7 +64,7 @@ func NewClusterServer(kubeConfig, apiserverURL string) (Server, error) { func (cs *clusterServer) GetConfig(cr poolRequest) (*runtime.RawExtension, error) { mp, err := cs.machineClient.MachineConfigPools().Get(context.TODO(), cr.machineConfigPool, metav1.GetOptions{}) if err != nil { - return nil, fmt.Errorf("could not fetch pool. err: %v", err) + return nil, fmt.Errorf("could not fetch pool. err: %w", err) } // For new nodes, we roll out the latest if at least one node has successfully updated. @@ -80,11 +80,11 @@ func (cs *clusterServer) GetConfig(cr poolRequest) (*runtime.RawExtension, error mc, err := cs.machineClient.MachineConfigs().Get(context.TODO(), currConf, metav1.GetOptions{}) if err != nil { - return nil, fmt.Errorf("could not fetch config %s, err: %v", currConf, err) + return nil, fmt.Errorf("could not fetch config %s, err: %w", currConf, err) } ignConf, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw) if err != nil { - return nil, fmt.Errorf("parsing Ignition config failed with error: %v", err) + return nil, fmt.Errorf("parsing Ignition config failed with error: %w", err) } appenders := getAppenders(currConf, cr.version, cs.kubeconfigFunc) @@ -118,11 +118,11 @@ func kubeconfigFromSecret(secretDir, apiserverURL string) ([]byte, []byte, error tokenFile := filepath.Join(secretDir, corev1.ServiceAccountTokenKey) caData, err := ioutil.ReadFile(caFile) if err != nil { - return nil, nil, fmt.Errorf("Failed to read %s: %v", caFile, err) + return nil, nil, fmt.Errorf("failed to read %s: %w", caFile, err) } token, err := ioutil.ReadFile(tokenFile) if err != nil { - return nil, nil, fmt.Errorf("Failed to read %s: %v", tokenFile, err) + return nil, nil, fmt.Errorf("failed to read %s: %w", tokenFile, err) } kubeconfig := clientcmdv1.Config{ diff --git a/pkg/server/server.go b/pkg/server/server.go index 08b8823bd0..a0492a433d 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -78,7 +78,7 @@ func appendEncapsulated(conf *igntypes.Config, mc *mcfgv1.MachineConfig, version tmpIgnCfg := ctrlcommon.NewIgnConfig() rawTmpIgnCfg, err = json.Marshal(tmpIgnCfg) if err != nil { - return fmt.Errorf("error marshalling Ignition config: %v", err) + return fmt.Errorf("error marshalling Ignition config: %w", err) } } else { tmpIgnCfg := ign2types.Config{ @@ -88,7 +88,7 @@ func appendEncapsulated(conf *igntypes.Config, mc *mcfgv1.MachineConfig, version } rawTmpIgnCfg, err = json.Marshal(tmpIgnCfg) if err != nil { - return fmt.Errorf("error marshalling Ignition config: %v", err) + return fmt.Errorf("error marshalling Ignition config: %w", err) } } @@ -96,11 +96,11 @@ func appendEncapsulated(conf *igntypes.Config, mc *mcfgv1.MachineConfig, version tmpcfg.Spec.Config.Raw = rawTmpIgnCfg serialized, err := json.Marshal(tmpcfg) if err != nil { - return fmt.Errorf("error marshalling MachineConfig: %v", err) + return fmt.Errorf("error marshalling MachineConfig: %w", err) } err = appendFileToIgnition(conf, daemonconsts.MachineConfigEncapsulatedPath, string(serialized)) if err != nil { - return fmt.Errorf("error appending file to raw Ignition config: %v", err) + return fmt.Errorf("error appending file to raw Ignition config: %w", err) } return nil } @@ -150,7 +150,7 @@ func getNodeAnnotation(conf string) (string, error) { } contents, err := json.Marshal(nodeAnnotations) if err != nil { - return "", fmt.Errorf("could not marshal node annotations, err: %v", err) + return "", fmt.Errorf("could not marshal node annotations, err: %w", err) } return string(contents), nil } diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 5ad05a2046..0bdaf00087 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -386,12 +386,12 @@ func getTestMachineConfigPool() (*mcfgv1.MachineConfigPool, error) { mpPath := path.Join(testDir, "machine-pools", testPool+".yaml") mpData, err := ioutil.ReadFile(mpPath) if err != nil { - return nil, fmt.Errorf("unexpected error while reading machine-pool: %s, err: %v", mpPath, err) + return nil, fmt.Errorf("unexpected error while reading machine-pool: %s, err: %w", mpPath, err) } mp := new(mcfgv1.MachineConfigPool) err = yaml.Unmarshal(mpData, mp) if err != nil { - return nil, fmt.Errorf("unexpected error while unmarshaling machine-pool: %s, err: %v", mpPath, err) + return nil, fmt.Errorf("unexpected error while unmarshaling machine-pool: %s, err: %w", mpPath, err) } return mp, nil } diff --git a/test/e2e-single-node/sno_mcd_test.go b/test/e2e-single-node/sno_mcd_test.go index 5b4045c065..f3e5fc12b7 100644 --- a/test/e2e-single-node/sno_mcd_test.go +++ b/test/e2e-single-node/sno_mcd_test.go @@ -12,11 +12,11 @@ import ( e2eShared "github.com/openshift/machine-config-operator/test/e2e-shared-tests" "github.com/openshift/machine-config-operator/test/framework" "github.com/openshift/machine-config-operator/test/helpers" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" + kubeErrs "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" @@ -405,10 +405,11 @@ func waitForSingleNodePoolComplete(t *testing.T, cs *framework.ClientSet, pool, } return true, nil }); err != nil { + errs := kubeErrs.NewAggregate([]error{lastErr, err}) if err == wait.ErrWaitTimeout { - errors.Wrapf(err, "pool %s is still not updated, waited %v: %v", pool, time.Since(startTime), lastErr) + return fmt.Errorf("pool %s is still not updated, waited %v: %w", pool, time.Since(startTime), errs) } else { - return errors.Wrapf(err, "unkown error occured %v", lastErr) + return fmt.Errorf("unknown error occurred: %w", errs) } } diff --git a/test/e2e/ctrcfg_test.go b/test/e2e/ctrcfg_test.go index 74f8c73c2a..587ca554af 100644 --- a/test/e2e/ctrcfg_test.go +++ b/test/e2e/ctrcfg_test.go @@ -14,7 +14,6 @@ import ( ctrcfg "github.com/openshift/machine-config-operator/pkg/controller/container-runtime-config" "github.com/openshift/machine-config-operator/test/framework" "github.com/openshift/machine-config-operator/test/helpers" - "github.com/pkg/errors" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -147,7 +146,7 @@ func runTestWithCtrcfg(t *testing.T, testName, regexKey, expectedConfVal1, expec arr := strings.Split(ctrcfg.CRIODropInFilePathLogLevel, "/") overrideFileName := arr[len(arr)-1] if fileExists(t, cs, node, overrideFileName) { - err := errors.New("override file still exists in crio.conf.d") + err := fmt.Errorf("override file still exists in crio.conf.d") require.Nil(t, err) } } @@ -204,7 +203,7 @@ func getMCFromCtrcfg(t *testing.T, cs *framework.ClientSet, ctrcfgName string) ( } return false, nil }); err != nil { - return "", errors.Wrapf(err, "can't find machine config created by ctrcfg %s", ctrcfgName) + return "", fmt.Errorf("can't find machine config created by ctrcfg %s: %w", ctrcfgName, err) } return mcName, nil } diff --git a/test/e2e/kubeletcfg_test.go b/test/e2e/kubeletcfg_test.go index 6556277d05..c428b67a53 100644 --- a/test/e2e/kubeletcfg_test.go +++ b/test/e2e/kubeletcfg_test.go @@ -13,7 +13,6 @@ import ( kcfg "github.com/openshift/machine-config-operator/pkg/controller/kubelet-config" "github.com/openshift/machine-config-operator/test/framework" "github.com/openshift/machine-config-operator/test/helpers" - "github.com/pkg/errors" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -214,7 +213,7 @@ func getMCFromKubeletCfg(t *testing.T, cs *framework.ClientSet, kcName string) ( } return false, nil }); err != nil { - return "", errors.Wrapf(err, "can't find machine config created by kubelet config %s", kcName) + return "", fmt.Errorf("can't find machine config created by kubelet config %s: %w", kcName, err) } return mcName, nil } diff --git a/test/helpers/utils.go b/test/helpers/utils.go index eb0caed3d7..1bd64a7a13 100644 --- a/test/helpers/utils.go +++ b/test/helpers/utils.go @@ -16,7 +16,6 @@ import ( mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" "github.com/openshift/machine-config-operator/pkg/daemon/constants" "github.com/openshift/machine-config-operator/test/framework" - "github.com/pkg/errors" "github.com/stretchr/testify/require" "github.com/vincent-petithory/dataurl" corev1 "k8s.io/api/core/v1" @@ -162,7 +161,7 @@ func WaitForRenderedConfigs(t *testing.T, cs *framework.ClientSet, pool string, renderedConfig = mcp.Spec.Configuration.Name return true, nil }); err != nil { - return "", errors.Wrapf(err, "machine configs %v hasn't been picked by pool %s (waited %s)", notFoundNames(found), pool, time.Since(startTime)) + return "", fmt.Errorf("machine configs %v hasn't been picked by pool %s (waited %s): %w", notFoundNames(found), pool, time.Since(startTime), err) } t.Logf("Pool %s has rendered configs %v with %s (waited %v)", pool, mcNames, renderedConfig, time.Since(startTime)) return renderedConfig, nil @@ -194,7 +193,7 @@ func WaitForPoolComplete(t *testing.T, cs *framework.ClientSet, pool, target str } return false, nil }); err != nil { - return errors.Wrapf(err, "pool %s didn't report %s to updated (waited %s)", pool, target, time.Since(startTime)) + return fmt.Errorf("pool %s didn't report %s to updated (waited %s): %w", pool, target, time.Since(startTime), err) } t.Logf("Pool %s has completed %s (waited %v)", pool, target, time.Since(startTime)) return nil @@ -267,13 +266,13 @@ func WaitForPausedConfig(t *testing.T, cs *framework.ClientSet, pool string) err func GetMonitoringToken(t *testing.T, cs *framework.ClientSet) (string, error) { sa, err := cs.ServiceAccounts("openshift-monitoring").Get(context.TODO(), "prometheus-k8s", metav1.GetOptions{}) if err != nil { - return "", fmt.Errorf("Failed to retrieve service account: %v", err) + return "", fmt.Errorf("failed to retrieve service account: %w", err) } for _, secret := range sa.Secrets { if strings.HasPrefix(secret.Name, "prometheus-k8s-token") { sec, err := cs.Secrets("openshift-monitoring").Get(context.TODO(), secret.Name, metav1.GetOptions{}) if err != nil { - return "", fmt.Errorf("Failed to retrieve monitoring secret: %v", err) + return "", fmt.Errorf("failed to retrieve monitoring secret: %w", err) } if token, ok := sec.Data["token"]; ok { return string(token), nil