diff --git a/cmd/openshift-install/main.go b/cmd/openshift-install/main.go index c14d57095d3..8093ec46022 100644 --- a/cmd/openshift-install/main.go +++ b/cmd/openshift-install/main.go @@ -82,7 +82,7 @@ func main() { for _, asset := range targetAssets { st, err := assetStore.Fetch(asset) if err != nil { - logrus.Fatalf("Failed to generate asset: %v", err) + logrus.Fatalf("Failed to generate %s: %v", asset.Name(), err) } if err := st.PersistToFile(*dirFlag); err != nil { diff --git a/pkg/asset/asset.go b/pkg/asset/asset.go index ec6884912fb..c3f3fe02c0d 100644 --- a/pkg/asset/asset.go +++ b/pkg/asset/asset.go @@ -1,8 +1,9 @@ package asset import ( - "fmt" "path/filepath" + + "github.com/pkg/errors" ) // Asset used to install OpenShift. @@ -22,7 +23,7 @@ type Asset interface { func GetDataByFilename(a Asset, parents map[Asset]*State, filename string) ([]byte, error) { st, ok := parents[a] if !ok { - return nil, fmt.Errorf("failed to find %T in parents", a) + return nil, errors.Errorf("failed to find %T in parents", a) } for _, c := range st.Contents { @@ -30,5 +31,5 @@ func GetDataByFilename(a Asset, parents map[Asset]*State, filename string) ([]by return c.Data, nil } } - return nil, fmt.Errorf("failed to find data in %v with filename == %q", st, filename) + return nil, errors.Errorf("failed to find data in %v with filename == %q", st, filename) } diff --git a/pkg/asset/cluster/cluster.go b/pkg/asset/cluster/cluster.go index 348d2b8e6fc..2222db57cde 100644 --- a/pkg/asset/cluster/cluster.go +++ b/pkg/asset/cluster/cluster.go @@ -2,11 +2,11 @@ package cluster import ( "encoding/json" - "fmt" "io/ioutil" "os" "path/filepath" + "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/openshift/installer/data" @@ -45,23 +45,23 @@ func (c *Cluster) Dependencies() []asset.Asset { func (c *Cluster) Generate(parents map[asset.Asset]*asset.State) (*asset.State, error) { state, ok := parents[c.tfvars] if !ok { - return nil, fmt.Errorf("failed to get terraform.tfvar state in the parent asset states") + return nil, errors.Errorf("failed to get terraform.tfvars from parent") } // Copy the terraform.tfvars to a temp directory where the terraform will be invoked within. tmpDir, err := ioutil.TempDir(os.TempDir(), "openshift-install-") if err != nil { - return nil, fmt.Errorf("failed to create temp dir: %v", err) + return nil, errors.Wrap(err, "failed to create temp dir for terraform execution") } defer os.RemoveAll(tmpDir) if err := ioutil.WriteFile(filepath.Join(tmpDir, state.Contents[0].Name), state.Contents[0].Data, 0600); err != nil { - return nil, fmt.Errorf("failed to write terraform.tfvars file: %v", err) + return nil, errors.Wrap(err, "failed to write terraform.tfvars file") } var tfvars config.Cluster if err := json.Unmarshal(state.Contents[0].Data, &tfvars); err != nil { - return nil, fmt.Errorf("failed to unmarshal terraform tfvars file: %v", err) + return nil, errors.Wrap(err, "failed to Unmarshal terraform.tfvars file") } platform := string(tfvars.Platform) @@ -78,12 +78,12 @@ func (c *Cluster) Generate(parents map[asset.Asset]*asset.State) (*asset.State, // This runs the terraform in a temp directory, the tfstate file will be returned // to the asset store to persist it on the disk. if err := terraform.Init(tmpDir); err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to initialize terraform") } stateFile, err := terraform.Apply(tmpDir) if err != nil { - err = fmt.Errorf("terraform failed: %v", err) + err = errors.Wrap(err, "failed to run terraform") } data, err2 := ioutil.ReadFile(stateFile) diff --git a/pkg/asset/cluster/tfvars.go b/pkg/asset/cluster/tfvars.go index a0709896ae1..5baf6a5582e 100644 --- a/pkg/asset/cluster/tfvars.go +++ b/pkg/asset/cluster/tfvars.go @@ -1,11 +1,10 @@ package cluster import ( - "fmt" - "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/types/config" + "github.com/pkg/errors" ) const ( @@ -39,7 +38,7 @@ func (t *TerraformVariables) Dependencies() []asset.Asset { func (t *TerraformVariables) Generate(parents map[asset.Asset]*asset.State) (*asset.State, error) { installCfg, err := installconfig.GetInstallConfig(t.installConfig, parents) if err != nil { - return nil, fmt.Errorf("failed to get install config state in the parent asset states") + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } contents := map[asset.Asset][]string{} @@ -51,7 +50,7 @@ func (t *TerraformVariables) Generate(parents map[asset.Asset]*asset.State) (*as } { state, ok := parents[ign] if !ok { - return nil, fmt.Errorf("failed to get the ignition state for %v in the parent asset states", ign) + return nil, errors.Errorf("failed to get the ignition state for %v in the parent asset states", ign) } for _, content := range state.Contents { @@ -72,7 +71,7 @@ func (t *TerraformVariables) Generate(parents map[asset.Asset]*asset.State) (*as data, err := cluster.TFVars() if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get Tfvars") } return &asset.State{ diff --git a/pkg/asset/ignition/bootstrap/bootstrap.go b/pkg/asset/ignition/bootstrap/bootstrap.go index 51e6fc9bad7..1ce9f5c8718 100644 --- a/pkg/asset/ignition/bootstrap/bootstrap.go +++ b/pkg/asset/ignition/bootstrap/bootstrap.go @@ -10,6 +10,7 @@ import ( "github.com/coreos/ignition/config/util" igntypes "github.com/coreos/ignition/config/v2_2/types" + "github.com/pkg/errors" log "github.com/sirupsen/logrus" "github.com/openshift/installer/pkg/asset" @@ -133,12 +134,12 @@ func (a *bootstrap) Dependencies() []asset.Asset { func (a *bootstrap) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { installConfig, err := installconfig.GetInstallConfig(a.installConfig, dependencies) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } templateData, err := a.getTemplateData(installConfig) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get bootstrap templates") } config := igntypes.Config{ @@ -166,7 +167,7 @@ func (a *bootstrap) Generate(dependencies map[asset.Asset]*asset.State) (*asset. data, err := json.Marshal(config) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to Marshal Ignition config") } return &asset.State{ @@ -186,7 +187,7 @@ func (a *bootstrap) Name() string { func (a *bootstrap) getTemplateData(installConfig *types.InstallConfig) (*bootstrapTemplateData, error) { clusterDNSIP, err := installconfig.ClusterDNSIP(installConfig) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get ClusterDNSIP from InstallConfig") } etcdEndpoints := make([]string, installConfig.MasterCount()) for i := range etcdEndpoints { diff --git a/pkg/asset/ignition/machine/master.go b/pkg/asset/ignition/machine/master.go index b7e19dfbf4a..31c668d1080 100644 --- a/pkg/asset/ignition/machine/master.go +++ b/pkg/asset/ignition/machine/master.go @@ -3,6 +3,8 @@ package machine import ( "fmt" + "github.com/pkg/errors" + "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/asset/tls" @@ -39,7 +41,7 @@ func (a *master) Dependencies() []asset.Asset { func (a *master) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { installConfig, err := installconfig.GetInstallConfig(a.installConfig, dependencies) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } state := &asset.State{ diff --git a/pkg/asset/ignition/machine/worker.go b/pkg/asset/ignition/machine/worker.go index 15b37c85385..2b92ffa6648 100644 --- a/pkg/asset/ignition/machine/worker.go +++ b/pkg/asset/ignition/machine/worker.go @@ -1,6 +1,8 @@ package machine import ( + "github.com/pkg/errors" + "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/asset/tls" @@ -37,7 +39,7 @@ func (a *worker) Dependencies() []asset.Asset { func (a *worker) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { installConfig, err := installconfig.GetInstallConfig(a.installConfig, dependencies) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } return &asset.State{ diff --git a/pkg/asset/installconfig/installconfig.go b/pkg/asset/installconfig/installconfig.go index 79b7e769015..33a7833d86f 100644 --- a/pkg/asset/installconfig/installconfig.go +++ b/pkg/asset/installconfig/installconfig.go @@ -7,7 +7,7 @@ import ( "github.com/apparentlymart/go-cidr/cidr" "github.com/ghodss/yaml" - + "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/openshift/installer/pkg/asset" @@ -131,7 +131,7 @@ func (a *installConfig) Generate(dependencies map[asset.Asset]*asset.State) (*as data, err := yaml.Marshal(installConfig) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to Marshal InstallConfig") } return &asset.State{ @@ -155,13 +155,12 @@ func GetInstallConfig(installConfig asset.Asset, parents map[asset.Asset]*asset. st, ok := parents[installConfig] if !ok { - return nil, fmt.Errorf("failed to find %T in parents", installConfig) + return nil, errors.Errorf("%T does not exist in parents", installConfig) } if err := yaml.Unmarshal(st.Contents[0].Data, &cfg); err != nil { - return nil, fmt.Errorf("failed to unmarshal the installconfig: %v", err) + return nil, errors.Wrap(err, "failed to Unmarshal the installconfig") } - return &cfg, nil } diff --git a/pkg/asset/installconfig/platform.go b/pkg/asset/installconfig/platform.go index fcdbb68c4cc..c4bbebb81a2 100644 --- a/pkg/asset/installconfig/platform.go +++ b/pkg/asset/installconfig/platform.go @@ -8,6 +8,7 @@ import ( "sort" "strings" + "github.com/pkg/errors" survey "gopkg.in/AlecAivazis/survey.v1" "github.com/openshift/installer/pkg/asset" @@ -100,6 +101,7 @@ func (a *Platform) Name() string { func (a *Platform) queryUserForPlatform() (string, error) { sort.Strings(validPlatforms) prompt := asset.UserProvided{ + AssetName: "Platform", Question: &survey.Question{ Prompt: &survey.Select{ Message: "Platform", @@ -109,7 +111,7 @@ func (a *Platform) queryUserForPlatform() (string, error) { choice := ans.(string) i := sort.SearchStrings(validPlatforms, choice) if i == len(validPlatforms) || validPlatforms[i] != choice { - return fmt.Errorf("invalid platform %q", choice) + return errors.Errorf("invalid platform %q", choice) } return nil }), @@ -142,6 +144,7 @@ func (a *Platform) awsPlatform() (*asset.State, error) { sort.Strings(longRegions) sort.Strings(shortRegions) prompt := asset.UserProvided{ + AssetName: "AWS Region", Question: &survey.Question{ Prompt: &survey.Select{ Message: "Region", @@ -153,7 +156,7 @@ func (a *Platform) awsPlatform() (*asset.State, error) { choice := regionTransform(ans).(string) i := sort.SearchStrings(shortRegions, choice) if i == len(shortRegions) || shortRegions[i] != choice { - return fmt.Errorf("invalid region %q", choice) + return errors.Errorf("invalid region %q", choice) } return nil }), @@ -169,13 +172,13 @@ func (a *Platform) awsPlatform() (*asset.State, error) { if value, ok := os.LookupEnv("_CI_ONLY_STAY_AWAY_OPENSHIFT_INSTALL_AWS_USER_TAGS"); ok { if err := json.Unmarshal([]byte(value), &platform.UserTags); err != nil { - return nil, fmt.Errorf("_CI_ONLY_STAY_AWAY_OPENSHIFT_INSTALL_AWS_USER_TAGS contains invalid JSON: %s (%v)", value, err) + return nil, errors.Wrapf(err, "_CI_ONLY_STAY_AWAY_OPENSHIFT_INSTALL_AWS_USER_TAGS contains invalid JSON: %s", value) } } data, err := json.Marshal(platform) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to Marshal %s platform", AWSPlatformType) } return &asset.State{ @@ -197,6 +200,7 @@ func (a *Platform) openstackPlatform() (*asset.State, error) { NetworkCIDRBlock: defaultVPCCIDR, } prompt := asset.UserProvided{ + AssetName: "OpenStack Region", Question: &survey.Question{ Prompt: &survey.Select{ Message: "Region", @@ -217,6 +221,7 @@ func (a *Platform) openstackPlatform() (*asset.State, error) { } platform.Region = string(region.Contents[0].Data) prompt2 := asset.UserProvided{ + AssetName: "OpenStack Image", Question: &survey.Question{ Prompt: &survey.Select{ Message: "Image", @@ -237,6 +242,7 @@ func (a *Platform) openstackPlatform() (*asset.State, error) { } platform.BaseImage = string(image.Contents[0].Data) prompt3 := asset.UserProvided{ + AssetName: "OpenStack Cloud", Question: &survey.Question{ Prompt: &survey.Select{ Message: "Cloud", @@ -256,6 +262,7 @@ func (a *Platform) openstackPlatform() (*asset.State, error) { } platform.Cloud = string(cloud.Contents[0].Data) prompt4 := asset.UserProvided{ + AssetName: "OpenStack External Network", Question: &survey.Question{ Prompt: &survey.Select{ Message: "ExternalNetwork", @@ -277,7 +284,7 @@ func (a *Platform) openstackPlatform() (*asset.State, error) { data, err := json.Marshal(platform) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to Marshal %s platform", OpenStackPlatformType) } return &asset.State{ @@ -307,6 +314,7 @@ func (a *Platform) libvirtPlatform() (*asset.State, error) { } uriPrompt := asset.UserProvided{ + AssetName: "Libvirt Connection URI", Question: &survey.Question{ Prompt: &survey.Input{ Message: "Libvirt Connection URI", @@ -323,6 +331,7 @@ func (a *Platform) libvirtPlatform() (*asset.State, error) { } imagePrompt := asset.UserProvided{ + AssetName: "Libvirt Image", Question: &survey.Question{ Prompt: &survey.Input{ Message: "Image", @@ -342,7 +351,7 @@ func (a *Platform) libvirtPlatform() (*asset.State, error) { data, err := json.Marshal(platform) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to Marshal %s platform", LibvirtPlatformType) } return &asset.State{ diff --git a/pkg/asset/installconfig/ssh.go b/pkg/asset/installconfig/ssh.go index 73ef5d24ab8..13c2a31cd2b 100644 --- a/pkg/asset/installconfig/ssh.go +++ b/pkg/asset/installconfig/ssh.go @@ -1,7 +1,6 @@ package installconfig import ( - "errors" "fmt" "io/ioutil" "os" @@ -10,6 +9,7 @@ import ( "sort" "strings" + "github.com/pkg/errors" survey "gopkg.in/AlecAivazis/survey.v1" "github.com/openshift/installer/pkg/asset" @@ -45,7 +45,7 @@ func (a *sshPublicKey) Generate(map[asset.Asset]*asset.State) (state *asset.Stat if value, ok := os.LookupEnv("OPENSHIFT_INSTALL_SSH_PUB_KEY"); ok { if value != "" { if err := validateOpenSSHPublicKey(value); err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to validate public key") } } return &asset.State{ @@ -59,7 +59,7 @@ func (a *sshPublicKey) Generate(map[asset.Asset]*asset.State) (state *asset.Stat if path, ok := os.LookupEnv("OPENSHIFT_INSTALL_SSH_PUB_KEY_PATH"); ok { key, err := readSSHKey(path) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to read public key file") } pubKeys[path] = key } else { @@ -68,7 +68,7 @@ func (a *sshPublicKey) Generate(map[asset.Asset]*asset.State) (state *asset.Stat if home != "" { paths, err := filepath.Glob(filepath.Join(home, ".ssh", "*.pub")) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to glob for public key files") } for _, path := range paths { key, err := readSSHKey(path) @@ -111,7 +111,7 @@ func (a *sshPublicKey) Generate(map[asset.Asset]*asset.State) (state *asset.Stat return nil }) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed UserInput for SSH public key") } return &asset.State{ diff --git a/pkg/asset/kubeconfig/kubeconfig.go b/pkg/asset/kubeconfig/kubeconfig.go index 4e44a25ee26..be645290861 100644 --- a/pkg/asset/kubeconfig/kubeconfig.go +++ b/pkg/asset/kubeconfig/kubeconfig.go @@ -5,10 +5,12 @@ import ( "path/filepath" "github.com/ghodss/yaml" + "github.com/pkg/errors" + clientcmd "k8s.io/client-go/tools/clientcmd/api/v1" + "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/asset/tls" - clientcmd "k8s.io/client-go/tools/clientcmd/api/v1" ) const ( @@ -40,11 +42,9 @@ func (k *Kubeconfig) Dependencies() []asset.Asset { // Generate generates the kubeconfig. func (k *Kubeconfig) Generate(parents map[asset.Asset]*asset.State) (*asset.State, error) { - var err error - caCertData, err := asset.GetDataByFilename(k.rootCA, parents, tls.RootCACertName) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get RootCA from parents") } var keyFilename, certFilename, kubeconfigSuffix string @@ -57,15 +57,15 @@ func (k *Kubeconfig) Generate(parents map[asset.Asset]*asset.State) (*asset.Stat } clientKeyData, err := asset.GetDataByFilename(k.certKey, parents, keyFilename) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get client certificate from parents") } clientCertData, err := asset.GetDataByFilename(k.certKey, parents, certFilename) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get client key from parents") } installConfig, err := installconfig.GetInstallConfig(k.installConfig, parents) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } kubeconfig := clientcmd.Config{ @@ -101,7 +101,7 @@ func (k *Kubeconfig) Generate(parents map[asset.Asset]*asset.State) (*asset.Stat data, err := yaml.Marshal(kubeconfig) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to Marshal kubeconfig") } return &asset.State{ diff --git a/pkg/asset/kubeconfig/kubeconfig_test.go b/pkg/asset/kubeconfig/kubeconfig_test.go index e2b3afe9063..85bff2dddf9 100644 --- a/pkg/asset/kubeconfig/kubeconfig_test.go +++ b/pkg/asset/kubeconfig/kubeconfig_test.go @@ -153,7 +153,7 @@ users: adminCertKey: adminCertState, installConfig: installConfigState, }, - errString: "failed to find kubeconfig.fakeAsset in parents", + errString: "failed to get RootCA from parents: failed to find kubeconfig.fakeAsset in parents", expectedData: nil, }, { @@ -165,7 +165,7 @@ users: kubeletCertKey: kubeletCertState, installConfig: installConfigState, }, - errString: "failed to find kubeconfig.fakeAsset in parents", + errString: "failed to get client certificate from parents: failed to find kubeconfig.fakeAsset in parents", expectedData: nil, }, { @@ -177,7 +177,7 @@ users: adminCertKey: adminCertState, installConfig: installConfigState, }, - errString: "failed to find kubeconfig.fakeAsset in parents", + errString: "failed to get client certificate from parents: failed to find kubeconfig.fakeAsset in parents", expectedData: nil, }, { @@ -188,7 +188,7 @@ users: rootCA: rootCAState, adminCertKey: adminCertState, }, - errString: "failed to find kubeconfig.fakeAsset in parents", + errString: "failed to get InstallConfig from parents: kubeconfig.fakeAsset does not exist in parents", expectedData: nil, }, } diff --git a/pkg/asset/manifests/kube-addon-operator.go b/pkg/asset/manifests/kube-addon-operator.go index 03282b3e645..684d421f209 100644 --- a/pkg/asset/manifests/kube-addon-operator.go +++ b/pkg/asset/manifests/kube-addon-operator.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/ghodss/yaml" + "github.com/pkg/errors" kubeaddon "github.com/coreos/tectonic-config/config/kube-addon" "github.com/openshift/installer/pkg/asset" @@ -38,14 +39,14 @@ func (kao *kubeAddonOperator) Dependencies() []asset.Asset { func (kao *kubeAddonOperator) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { ic, err := installconfig.GetInstallConfig(kao.installConfigAsset, dependencies) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } kao.installConfig = ic // installconfig is ready, we can create the addon config from it now addonConfig, err := kao.addonConfig() if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to create %s config from InstallConfig", kao.Name()) } state := &asset.State{ diff --git a/pkg/asset/manifests/kube-core-operator.go b/pkg/asset/manifests/kube-core-operator.go index ccaff3983b0..006cf38f32a 100644 --- a/pkg/asset/manifests/kube-core-operator.go +++ b/pkg/asset/manifests/kube-core-operator.go @@ -4,14 +4,15 @@ import ( "fmt" "strings" - "github.com/ghodss/yaml" - "github.com/apparentlymart/go-cidr/cidr" kubecore "github.com/coreos/tectonic-config/config/kube-core" + "github.com/ghodss/yaml" + "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/types" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -46,32 +47,28 @@ func (kco *kubeCoreOperator) Dependencies() []asset.Asset { func (kco *kubeCoreOperator) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { ic, err := installconfig.GetInstallConfig(kco.installConfigAsset, dependencies) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } kco.installConfig = ic // installconfig is ready, we can create the core config from it now coreConfig, err := kco.coreConfig() if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to create %s config from InstallConfig", kco.Name()) } - data, err := yaml.Marshal(coreConfig) - if err != nil { - return nil, fmt.Errorf("failed to marshal core config: %v", err) - } state := &asset.State{ Contents: []asset.Content{ { Name: "kco-config.yaml", - Data: data, + Data: coreConfig, }, }, } return state, nil } -func (kco *kubeCoreOperator) coreConfig() (*kubecore.OperatorConfig, error) { +func (kco *kubeCoreOperator) coreConfig() ([]byte, error) { coreConfig := kubecore.OperatorConfig{ TypeMeta: metav1.TypeMeta{ APIVersion: kubecore.APIVersion, @@ -99,8 +96,7 @@ func (kco *kubeCoreOperator) coreConfig() (*kubecore.OperatorConfig, error) { coreConfig.NetworkConfig.ServiceCIDR = kco.installConfig.Networking.ServiceCIDR.String() coreConfig.NetworkConfig.AdvertiseAddress = networkConfigAdvertiseAddress coreConfig.NetworkConfig.EtcdServers = strings.Join(kco.getEtcdServersURLs(), ",") - - return &coreConfig, nil + return yaml.Marshal(coreConfig) } func (kco *kubeCoreOperator) getAPIServerURL() string { diff --git a/pkg/asset/manifests/machine-api-operator.go b/pkg/asset/manifests/machine-api-operator.go index daf2a080eab..f839caef9ca 100644 --- a/pkg/asset/manifests/machine-api-operator.go +++ b/pkg/asset/manifests/machine-api-operator.go @@ -2,12 +2,12 @@ package manifests import ( "context" - "fmt" "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/rhcos" "github.com/openshift/installer/pkg/types" + "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -80,14 +80,14 @@ func (mao *machineAPIOperator) Dependencies() []asset.Asset { func (mao *machineAPIOperator) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { ic, err := installconfig.GetInstallConfig(mao.installConfigAsset, dependencies) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } mao.installConfig = ic // installconfig is ready, we can create the mao config from it now maoConfig, err := mao.maoConfig(dependencies) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to create %s config from InstallConfig", mao.Name()) } state := &asset.State{ @@ -120,7 +120,7 @@ func (mao *machineAPIOperator) maoConfig(dependencies map[asset.Asset]*asset.Sta ami, err := rhcos.AMI(context.TODO(), DefaultChannel, mao.installConfig.Platform.AWS.Region) if err != nil { - return "", fmt.Errorf("failed to lookup RHCOS AMI: %v", err) + return "", errors.Wrapf(err, "failed to get AMI for %s config", mao.Name()) } cfg.AWS = &awsConfig{ @@ -147,7 +147,7 @@ func (mao *machineAPIOperator) maoConfig(dependencies map[asset.Asset]*asset.Sta Replicas: int(*mao.installConfig.Machines[1].Replicas), } } else { - return "", fmt.Errorf("unknown provider for machine-api-operator") + return "", errors.Errorf("unknown provider for machine-api-operator") } return marshalYAML(cfg) diff --git a/pkg/asset/manifests/network-operator.go b/pkg/asset/manifests/network-operator.go index ee7cd0e8f24..e0297cf99be 100644 --- a/pkg/asset/manifests/network-operator.go +++ b/pkg/asset/manifests/network-operator.go @@ -2,6 +2,7 @@ package manifests import ( "github.com/ghodss/yaml" + "github.com/pkg/errors" "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" @@ -40,19 +41,19 @@ func (no *networkOperator) Dependencies() []asset.Asset { func (no *networkOperator) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { ic, err := installconfig.GetInstallConfig(no.installConfigAsset, dependencies) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } no.installConfig = ic // installconfig is ready, we can create the core config from it now netConfig, err := no.netConfig() if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to create %s config from InstallConfig", no.Name()) } netManifest, err := no.manifest() if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to create %s manifests from InstallConfig", no.Name()) } state := &asset.State{ Contents: []asset.Content{ diff --git a/pkg/asset/manifests/operators.go b/pkg/asset/manifests/operators.go index 138552efc21..5064658e15e 100644 --- a/pkg/asset/manifests/operators.go +++ b/pkg/asset/manifests/operators.go @@ -7,6 +7,8 @@ import ( "path/filepath" "text/template" + "github.com/pkg/errors" + "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/asset/manifests/content/bootkube" @@ -95,7 +97,7 @@ func (m *manifests) Generate(dependencies map[asset.Asset]*asset.State) (*asset. "mao-config": string(mao.Data), }) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to create kube-system/cluster-config-v1 configmap") } // addon goes to openshift system @@ -103,7 +105,7 @@ func (m *manifests) Generate(dependencies map[asset.Asset]*asset.State) (*asset. "addon-config": string(addon.Data), }) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to create tectonic-system/cluster-config-v1 configmap") } state := &asset.State{ diff --git a/pkg/asset/manifests/tectonic.go b/pkg/asset/manifests/tectonic.go index bfe5778a3b4..c8d4e5bc9d4 100644 --- a/pkg/asset/manifests/tectonic.go +++ b/pkg/asset/manifests/tectonic.go @@ -5,6 +5,8 @@ import ( "encoding/base64" "path/filepath" + "github.com/pkg/errors" + "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" content "github.com/openshift/installer/pkg/asset/manifests/content/tectonic" @@ -38,7 +40,7 @@ func (t *tectonic) Dependencies() []asset.Asset { func (t *tectonic) Generate(dependencies map[asset.Asset]*asset.State) (*asset.State, error) { ic, err := installconfig.GetInstallConfig(t.installConfig, dependencies) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } ingressContents := dependencies[t.ingressCertKey].Contents templateData := &tectonicTemplateData{ diff --git a/pkg/asset/metadata/metadata.go b/pkg/asset/metadata/metadata.go index 14cbaeb54be..115d63c24ab 100644 --- a/pkg/asset/metadata/metadata.go +++ b/pkg/asset/metadata/metadata.go @@ -4,6 +4,8 @@ import ( "encoding/json" "fmt" + "github.com/pkg/errors" + "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/types" @@ -37,7 +39,7 @@ func (m *Metadata) Dependencies() []asset.Asset { func (m *Metadata) Generate(parents map[asset.Asset]*asset.State) (*asset.State, error) { installCfg, err := installconfig.GetInstallConfig(m.installConfig, parents) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } cm := &types.ClusterMetadata{ @@ -68,7 +70,7 @@ func (m *Metadata) Generate(parents map[asset.Asset]*asset.State) (*asset.State, data, err := json.Marshal(cm) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to Marshal ClusterMetadata") } return &asset.State{ Contents: []asset.Content{ diff --git a/pkg/asset/state.go b/pkg/asset/state.go index f94c9cb4762..bd92151627c 100644 --- a/pkg/asset/state.go +++ b/pkg/asset/state.go @@ -4,6 +4,8 @@ import ( "io/ioutil" "os" "path/filepath" + + "github.com/pkg/errors" ) // State is the state of an Asset. @@ -20,16 +22,20 @@ type Content struct { // PersistToFile persists the data in the State to files. Each Content entry that // has a non-empty Name will be persisted to a file with that name. func (s *State) PersistToFile(directory string) error { + if s == nil { + return nil + } + for _, c := range s.Contents { if c.Name == "" { continue } path := filepath.Join(directory, c.Name) if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { - return err + return errors.Wrap(err, "failed to create dir") } if err := ioutil.WriteFile(path, c.Data, 0644); err != nil { - return err + return errors.Wrap(err, "failed to write file") } } return nil diff --git a/pkg/asset/store.go b/pkg/asset/store.go index 0137ed1f520..eaf159306e2 100644 --- a/pkg/asset/store.go +++ b/pkg/asset/store.go @@ -1,8 +1,7 @@ package asset import ( - "fmt" - + "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -40,7 +39,7 @@ func (s *StoreImpl) fetch(asset Asset, indent string) (*State, error) { for _, d := range dependencies { ds, err := s.fetch(d, indent+" ") if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to fetch dependency for %s", asset.Name()) } dependenciesStates[d] = ds } @@ -48,7 +47,7 @@ func (s *StoreImpl) fetch(asset Asset, indent string) (*State, error) { logrus.Debugf("%sGenerating %s...", indent, asset.Name()) state, err := asset.Generate(dependenciesStates) if err != nil { - return nil, fmt.Errorf("failed to generate asset %q: %v", asset.Name(), err) + return nil, errors.Wrapf(err, "failed to generate asset %s", asset.Name()) } if s.assets == nil { s.assets = make(map[Asset]*State) diff --git a/pkg/asset/tls/certkey.go b/pkg/asset/tls/certkey.go index bd83a77acf3..58e0ff14124 100644 --- a/pkg/asset/tls/certkey.go +++ b/pkg/asset/tls/certkey.go @@ -9,9 +9,10 @@ import ( "path/filepath" "time" - "github.com/ghodss/yaml" "github.com/openshift/installer/pkg/asset" + "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/types" + "github.com/pkg/errors" ) const ( @@ -74,33 +75,27 @@ func (c *CertKey) Generate(parents map[asset.Asset]*asset.State) (*asset.State, } if c.GenSubject != nil || c.GenDNSNames != nil || c.GenIPAddresses != nil { - state, ok := parents[c.installConfig] - if !ok { - return nil, fmt.Errorf("failed to get install config state in the parent asset states") + installConfig, err := installconfig.GetInstallConfig(c.installConfig, parents) + if err != nil { + return nil, errors.Wrap(err, "failed to get InstallConfig from parents") } - var installConfig types.InstallConfig - if err := yaml.Unmarshal(state.Contents[0].Data, &installConfig); err != nil { - return nil, fmt.Errorf("failed to unmarshal install config: %v", err) - } - - var err error if c.GenSubject != nil { - cfg.Subject, err = c.GenSubject(&installConfig) + cfg.Subject, err = c.GenSubject(installConfig) if err != nil { - return nil, fmt.Errorf("failed to generate Subject: %v", err) + return nil, errors.Wrap(err, "failed to generate Subject") } } if c.GenDNSNames != nil { - cfg.DNSNames, err = c.GenDNSNames(&installConfig) + cfg.DNSNames, err = c.GenDNSNames(installConfig) if err != nil { - return nil, fmt.Errorf("failed to generate DNSNames: %v", err) + return nil, errors.Wrap(err, "failed to generate DNSNames") } } if c.GenIPAddresses != nil { - cfg.IPAddresses, err = c.GenIPAddresses(&installConfig) + cfg.IPAddresses, err = c.GenIPAddresses(installConfig) if err != nil { - return nil, fmt.Errorf("failed to generate IPAddresses: %v", err) + return nil, errors.Wrap(err, "failed to generate IPAddresses") } } } @@ -111,17 +106,17 @@ func (c *CertKey) Generate(parents map[asset.Asset]*asset.State) (*asset.State, state, ok := parents[c.ParentCA] if !ok { - return nil, fmt.Errorf("failed to get parent CA %v in the parent asset states", c.ParentCA) + return nil, errors.Errorf("failed to get parent CA %v in the parent asset states", c.ParentCA) } caKey, caCert, err := parseCAFromAssetState(state) if err != nil { - return nil, fmt.Errorf("failed to parse CA from asset: %v", err) + return nil, errors.Wrap(err, "failed to parse CA from asset") } key, crt, err = GenerateCert(caKey, caCert, cfg) if err != nil { - return nil, fmt.Errorf("failed to generate cert/key pair: %v", err) + return nil, errors.Wrap(err, "failed to generate cert/key pair") } keyData := []byte(PrivateKeyToPem(key)) @@ -156,7 +151,7 @@ func parseCAFromAssetState(ca *asset.State) (*rsa.PrivateKey, *x509.Certificate, var err error if len(ca.Contents) != 2 { - return nil, nil, fmt.Errorf("expect key and cert in the contents of CA, got: %v", ca) + return nil, nil, errors.Errorf("expected key and cert in the contents of CA, got: %v", ca) } for _, c := range ca.Contents { @@ -164,15 +159,15 @@ func parseCAFromAssetState(ca *asset.State) (*rsa.PrivateKey, *x509.Certificate, case ".key": key, err = PemToPrivateKey(c.Data) if err != nil { - return nil, nil, fmt.Errorf("failed to parse rsa private key: %v", err) + return nil, nil, errors.Wrap(err, "failed to parse rsa private key") } case ".crt": cert, err = PemToCertificate(c.Data) if err != nil { - return nil, nil, fmt.Errorf("failed to parse x509 certificate: %v", err) + return nil, nil, errors.Wrap(err, "failed to parse x509 certificate") } default: - return nil, nil, fmt.Errorf("unexpected content name: %v", c.Name) + return nil, nil, errors.Errorf("unexpected content name: %v", c.Name) } } diff --git a/pkg/asset/tls/certkey_test.go b/pkg/asset/tls/certkey_test.go index 68d26714dfd..b68c59c8deb 100644 --- a/pkg/asset/tls/certkey_test.go +++ b/pkg/asset/tls/certkey_test.go @@ -118,7 +118,7 @@ func TestCertKeyGenerate(t *testing.T) { GenDNSNames: testGenDNSNames, GenIPAddresses: testGenIPAddresses, }, - errString: "failed to get install config state in the parent asset states", + errString: "failed to get InstallConfig from parents: tls.fakeInstallConfig does not exist in parents", parents: nil, }, } diff --git a/pkg/asset/tls/keypair.go b/pkg/asset/tls/keypair.go index 6f485df84ae..40ea9351ef0 100644 --- a/pkg/asset/tls/keypair.go +++ b/pkg/asset/tls/keypair.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/openshift/installer/pkg/asset" + "github.com/pkg/errors" ) // KeyPair implements the Asset interface and @@ -24,12 +25,12 @@ func (k *KeyPair) Dependencies() []asset.Asset { func (k *KeyPair) Generate(map[asset.Asset]*asset.State) (*asset.State, error) { key, err := PrivateKey() if err != nil { - return nil, fmt.Errorf("failed to generate private key: %v", err) + return nil, errors.Wrap(err, "failed to generate private key") } pubkeyData, err := PublicKeyToPem(&key.PublicKey) if err != nil { - return nil, fmt.Errorf("failed to get public key data: %v", err) + return nil, errors.Wrap(err, "failed to get public key data from private key") } return &asset.State{ diff --git a/pkg/asset/tls/root.go b/pkg/asset/tls/root.go index 67df4c5540e..29696745f42 100644 --- a/pkg/asset/tls/root.go +++ b/pkg/asset/tls/root.go @@ -3,9 +3,9 @@ package tls import ( "crypto/x509" "crypto/x509/pkix" - "fmt" "github.com/openshift/installer/pkg/asset" + "github.com/pkg/errors" ) // RootCA contains the private key and the cert that's @@ -30,7 +30,7 @@ func (c *RootCA) Generate(parents map[asset.Asset]*asset.State) (*asset.State, e key, crt, err := GenerateRootCertKey(cfg) if err != nil { - return nil, fmt.Errorf("failed to generate RootCA %v", err) + return nil, errors.Wrap(err, "failed to generate RootCA") } return &asset.State{ diff --git a/pkg/asset/tls/tls.go b/pkg/asset/tls/tls.go index 7990a6545d3..75957f38559 100644 --- a/pkg/asset/tls/tls.go +++ b/pkg/asset/tls/tls.go @@ -10,12 +10,12 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/asn1" - "errors" - "fmt" "math" "math/big" "net" "time" + + "github.com/pkg/errors" ) const ( @@ -50,7 +50,7 @@ type rsaPublicKey struct { func PrivateKey() (*rsa.PrivateKey, error) { rsaKey, err := rsa.GenerateKey(rand.Reader, keySize) if err != nil { - return nil, fmt.Errorf("error generating RSA private key: %v", err) + return nil, errors.Wrap(err, "error generating RSA private key") } return rsaKey, nil @@ -71,16 +71,16 @@ func SelfSignedCACert(cfg *CertCfg, key *rsa.PrivateKey) (*x509.Certificate, err } // verifies that the CN and/or OU for the cert is set if len(cfg.Subject.CommonName) == 0 || len(cfg.Subject.OrganizationalUnit) == 0 { - return nil, fmt.Errorf("certification's subject is not set, or invalid") + return nil, errors.Errorf("certification's subject is not set, or invalid") } pub := key.Public() cert.SubjectKeyId, err = generateSubjectKeyID(pub) if err != nil { - return nil, fmt.Errorf("failed to set subject key identifier: %v", err) + return nil, errors.Wrap(err, "failed to set subject key identifier") } certBytes, err := x509.CreateCertificate(rand.Reader, &cert, &cert, key.Public(), key) if err != nil { - return nil, fmt.Errorf("error creating certificate: %v", err) + return nil, errors.Wrap(err, "failed to create certificate") } return x509.ParseCertificate(certBytes) } @@ -114,11 +114,11 @@ func SignedCertificate( pub := caCert.PublicKey.(*rsa.PublicKey) certTmpl.SubjectKeyId, err = generateSubjectKeyID(pub) if err != nil { - return nil, fmt.Errorf("failed to set subject key identifier: %v", err) + return nil, errors.Wrap(err, "failed to set subject key identifier") } certBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey) if err != nil { - return nil, fmt.Errorf("error creating signed certificate: %v", err) + return nil, errors.Wrap(err, "failed to create x509 certificate") } return x509.ParseCertificate(certBytes) } @@ -132,7 +132,7 @@ func generateSubjectKeyID(pub crypto.PublicKey) ([]byte, error) { case *rsa.PublicKey: publicKeyBytes, err = asn1.Marshal(rsaPublicKey{N: pub.N, E: pub.E}) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to Marshal ans1 public key") } case *ecdsa.PublicKey: publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) @@ -154,24 +154,24 @@ func GenerateCert(caKey *rsa.PrivateKey, // create a private key key, err := PrivateKey() if err != nil { - return nil, nil, fmt.Errorf("failed to generate private key: %v", err) + return nil, nil, errors.Wrap(err, "failed to generate private key") } // create a CSR csrTmpl := x509.CertificateRequest{Subject: cfg.Subject, DNSNames: cfg.DNSNames, IPAddresses: cfg.IPAddresses} csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csrTmpl, key) if err != nil { - return nil, nil, fmt.Errorf("error creating certificate request: %v", err) + return nil, nil, errors.Wrap(err, "failed to create certificate request") } csr, err := x509.ParseCertificateRequest(csrBytes) if err != nil { - return nil, nil, fmt.Errorf("error parsing certificate request: %v", err) + return nil, nil, errors.Wrap(err, "error parsing x509 certificate request") } // create a cert cert, err := GenerateSignedCert(cfg, csr, key, caKey, caCert) if err != nil { - return nil, nil, fmt.Errorf("failed to create a certificate: %v", err) + return nil, nil, errors.Wrap(err, "failed to create a signed certificate") } return key, cert, nil } @@ -180,7 +180,7 @@ func GenerateCert(caKey *rsa.PrivateKey, func GenerateRootCA(key *rsa.PrivateKey, cfg *CertCfg) (*x509.Certificate, error) { cert, err := SelfSignedCACert(cfg, key) if err != nil { - return nil, fmt.Errorf("error generating self signed certificate: %v", err) + return nil, errors.Wrap(err, "failed to generate self signed certificate") } return cert, nil } @@ -193,7 +193,7 @@ func GenerateSignedCert(cfg *CertCfg, caCert *x509.Certificate) (*x509.Certificate, error) { cert, err := SignedCertificate(cfg, csr, key, caCert, caKey) if err != nil { - return nil, fmt.Errorf("error signing certificate: %v", err) + return nil, errors.Wrap(err, "failed to create a signed certificate") } return cert, nil } @@ -202,13 +202,12 @@ func GenerateSignedCert(cfg *CertCfg, func GenerateRootCertKey(cfg *CertCfg) (*rsa.PrivateKey, *x509.Certificate, error) { key, err := PrivateKey() if err != nil { - return nil, nil, fmt.Errorf("failed to generate private key: %v", err) + return nil, nil, errors.Wrap(err, "failed to generate private key") } crt, err := GenerateRootCA(key, cfg) if err != nil { - return nil, nil, fmt.Errorf("failed to create a certificate: %v", err) + return nil, nil, errors.Wrap(err, "failed to create root CA certificate") } - return key, crt, nil } diff --git a/pkg/asset/tls/utils.go b/pkg/asset/tls/utils.go index e972476d12e..c0414d8e90a 100644 --- a/pkg/asset/tls/utils.go +++ b/pkg/asset/tls/utils.go @@ -4,6 +4,8 @@ import ( "crypto/rsa" "crypto/x509" "encoding/pem" + + "github.com/pkg/errors" ) // PrivateKeyToPem converts an rsa.PrivateKey object to pem string @@ -44,7 +46,7 @@ func CSRToPem(cert *x509.CertificateRequest) string { func PublicKeyToPem(key *rsa.PublicKey) (string, error) { keyInBytes, err := x509.MarshalPKIXPublicKey(key) if err != nil { - return "", err + return "", errors.Wrap(err, "failed to MarshalPKIXPublicKey") } keyinPem := pem.EncodeToMemory( &pem.Block{ diff --git a/pkg/asset/userprovided.go b/pkg/asset/userprovided.go index 611dba2df03..c6093e2ffb5 100644 --- a/pkg/asset/userprovided.go +++ b/pkg/asset/userprovided.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "os" + "github.com/pkg/errors" survey "gopkg.in/AlecAivazis/survey.v1" ) @@ -23,7 +24,13 @@ func (a *UserProvided) Dependencies() []Asset { } // Generate queries for input from the user. -func (a *UserProvided) Generate(map[Asset]*State) (*State, error) { +func (a *UserProvided) Generate(map[Asset]*State) (state *State, err error) { + defer func() { + if err != nil { + err = errors.Wrapf(err, "failed to acquire user-provided input %s", a.AssetName) + } + }() + var response string if value, ok := os.LookupEnv(a.EnvVarName); ok { @@ -31,18 +38,18 @@ func (a *UserProvided) Generate(map[Asset]*State) (*State, error) { } else if path, ok := os.LookupEnv(a.PathEnvVarName); ok { value, err := ioutil.ReadFile(path) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to read file from %s", a.PathEnvVarName) } response = string(value) } if response == "" { if err := survey.Ask([]*survey.Question{a.Question}, &response); err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to Ask") } } else if a.Question.Validate != nil { if err := a.Question.Validate(response); err != nil { - return nil, err + return nil, errors.Wrap(err, "validation failed") } } diff --git a/pkg/destroy/destroyer.go b/pkg/destroy/destroyer.go index 20e0493ecec..00e82badbf4 100644 --- a/pkg/destroy/destroyer.go +++ b/pkg/destroy/destroyer.go @@ -2,10 +2,10 @@ package destroy import ( "encoding/json" - "fmt" "io/ioutil" "path/filepath" + "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/openshift/installer/pkg/asset/metadata" @@ -29,22 +29,22 @@ func New(logger logrus.FieldLogger, rootDir string) (Destroyer, error) { path := filepath.Join(rootDir, metadata.MetadataFilename) raw, err := ioutil.ReadFile(filepath.Join(rootDir, metadata.MetadataFilename)) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to read %s file", metadata.MetadataFilename) } var cmetadata *types.ClusterMetadata if err := json.Unmarshal(raw, &cmetadata); err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to Unmarshal data from %s file to types.ClusterMetadata", metadata.MetadataFilename) } platform := cmetadata.Platform() if platform == "" { - return nil, fmt.Errorf("no platform configured in %q", path) + return nil, errors.Errorf("no platform configured in %q", path) } creator, ok := Registry[platform] if !ok { - return nil, fmt.Errorf("no destroyers registered for %q", platform) + return nil, errors.Errorf("no destroyers registered for %q", platform) } return creator(logger, cmetadata) } diff --git a/pkg/destroy/libvirt/libvirt_prefix_deprovision.go b/pkg/destroy/libvirt/libvirt_prefix_deprovision.go index 3891fbc7889..3ebf6b1e692 100644 --- a/pkg/destroy/libvirt/libvirt_prefix_deprovision.go +++ b/pkg/destroy/libvirt/libvirt_prefix_deprovision.go @@ -8,10 +8,12 @@ import ( "time" libvirt "github.com/libvirt/libvirt-go" - "github.com/openshift/installer/pkg/destroy" - "github.com/openshift/installer/pkg/types" + "github.com/pkg/errors" "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/util/wait" + + "github.com/openshift/installer/pkg/destroy" + "github.com/openshift/installer/pkg/types" ) // filterFunc allows filtering based on names. @@ -61,7 +63,7 @@ func (o *ClusterUninstaller) Run() error { conn, err := libvirt.NewConnect(o.LibvirtURI) if err != nil { - return err + return errors.Wrap(err, "failed to connect to Libvirt daemon") } // launch goroutines diff --git a/pkg/ipnet/ipnet.go b/pkg/ipnet/ipnet.go index 59c20d976a6..eff16ee0c8f 100644 --- a/pkg/ipnet/ipnet.go +++ b/pkg/ipnet/ipnet.go @@ -5,6 +5,8 @@ import ( "encoding/json" "net" "reflect" + + "github.com/pkg/errors" ) var nullString = "null" @@ -45,12 +47,12 @@ func (ipnet *IPNet) UnmarshalJSON(b []byte) (err error) { var cidr string err = json.Unmarshal(b, &cidr) if err != nil { - return err + return errors.Wrap(err, "failed to Unmarshal string") } ip, net, err := net.ParseCIDR(cidr) if err != nil { - return err + return errors.Wrap(err, "failed to Parse cidr string to net.IPNet") } // This check is needed in order to work around a strange quirk in the Go diff --git a/pkg/rhcos/ami.go b/pkg/rhcos/ami.go index ba382769d60..462d59026d1 100644 --- a/pkg/rhcos/ami.go +++ b/pkg/rhcos/ami.go @@ -2,12 +2,12 @@ package rhcos import ( "context" - "fmt" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/pkg/errors" ) const ( @@ -18,7 +18,7 @@ const ( // AMI calculates a Red Hat CoreOS AMI. func AMI(ctx context.Context, channel, region string) (ami string, err error) { if channel != DefaultChannel { - return "", fmt.Errorf("channel %q is not yet supported", channel) + return "", errors.Errorf("channel %q is not yet supported", channel) } ssn := session.Must(session.NewSessionWithOptions(session.Options{ @@ -59,7 +59,7 @@ func AMI(ctx context.Context, channel, region string) (ami string, err error) { }, }) if err != nil { - return "", err + return "", errors.Wrap(err, "failed to describe AMIs") } var image *ec2.Image @@ -70,7 +70,7 @@ func AMI(ctx context.Context, channel, region string) (ami string, err error) { } nextCreated, err := time.Parse(time.RFC3339, *nextImage.CreationDate) if err != nil { - return "", err + return "", errors.Wrap(err, "failed to parse AMIs CreationDate to time.RFC3339") } if image == nil || nextCreated.After(created) { @@ -80,7 +80,7 @@ func AMI(ctx context.Context, channel, region string) (ami string, err error) { } if image == nil { - return "", fmt.Errorf("no RHCOS AMIs found in %s", region) + return "", errors.Errorf("no RHCOS AMIs found in %s", region) } return *image.ImageId, nil diff --git a/pkg/terraform/executor.go b/pkg/terraform/executor.go index 3c526b8101c..d55b4afb182 100644 --- a/pkg/terraform/executor.go +++ b/pkg/terraform/executor.go @@ -1,13 +1,12 @@ package terraform import ( - "errors" - "fmt" "os" "os/exec" "path/filepath" "runtime" + "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -40,7 +39,7 @@ func newExecutor() (*executor, error) { // Find the Terraform binary. binPath, err := tfBinaryPath() if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to get Terraform binary's path") } ex.binaryPath = binPath @@ -56,7 +55,7 @@ func (ex *executor) execute(clusterDir string, args ...string) error { // Prepare Terraform command by setting up the command, configuration, // and the working directory if clusterDir == "" { - return fmt.Errorf("clusterDir is unset. Quitting") + return errors.Errorf("clusterDir is unset. Quitting") } cmd := exec.Command(ex.binaryPath, args...) diff --git a/pkg/terraform/terraform.go b/pkg/terraform/terraform.go index 9bdd1171afb..3b39f8a73f3 100644 --- a/pkg/terraform/terraform.go +++ b/pkg/terraform/terraform.go @@ -3,18 +3,20 @@ package terraform import ( "fmt" "path" + + "github.com/pkg/errors" ) func terraformExec(clusterDir string, args ...string) error { // Create an executor ex, err := newExecutor() if err != nil { - return fmt.Errorf("could not create Terraform executor: %s", err) + return errors.Wrap(err, "failed to create Terraform executor") } err = ex.execute(clusterDir, args...) if err != nil { - return fmt.Errorf("failed to run Terraform: %s", err) + return errors.Wrap(err, "failed to execute Terraform") } return nil } diff --git a/pkg/types/config/cluster.go b/pkg/types/config/cluster.go index 10b6d4e15b3..70c42d50dd7 100644 --- a/pkg/types/config/cluster.go +++ b/pkg/types/config/cluster.go @@ -3,10 +3,10 @@ package config import ( "context" "encoding/json" - "fmt" "time" "github.com/coreos/tectonic-config/config/tectonic-network" + "github.com/pkg/errors" "gopkg.in/yaml.v2" "github.com/openshift/installer/pkg/rhcos" @@ -39,7 +39,7 @@ func (p *Platform) UnmarshalYAML(unmarshal func(interface{}) error) error { switch platform { case PlatformAWS, PlatformLibvirt, PlatformOpenStack: default: - return fmt.Errorf("invalid platform specified (%s); must be one of %s", platform, []Platform{PlatformAWS, PlatformLibvirt, PlatformOpenStack}) + return errors.Errorf("invalid platform specified (%s); must be one of %s", platform, []Platform{PlatformAWS, PlatformLibvirt, PlatformOpenStack}) } *p = platform @@ -116,13 +116,13 @@ func (c *Cluster) TFVars() (string, error) { // Fill in master ips if c.Platform == PlatformLibvirt { if err := c.Libvirt.TFVars(c.Master.Count, c.Worker.Count); err != nil { - return "", err + return "", errors.Wrap(err, "failed to create TFVars for libvirt platfrom") } } data, err := json.MarshalIndent(&c, "", " ") if err != nil { - return "", err + return "", errors.Wrap(err, "failed to marshal TFVars") } return string(data), nil @@ -144,7 +144,7 @@ func (c *Cluster) YAML() (string, error) { yaml, err := yaml.Marshal(c) if err != nil { - return "", err + return "", errors.Wrap(err, "failed to marshal config.Cluster") } return string(yaml), nil @@ -186,7 +186,7 @@ func ConvertInstallConfigToTFVars(cfg *types.InstallConfig, bootstrapIgn string, defer cancel() ami, err := rhcos.AMI(ctx, rhcos.DefaultChannel, cfg.Platform.AWS.Region) if err != nil { - return nil, fmt.Errorf("failed to determine default AMI: %v", err) + return nil, errors.Wrap(err, "failed to determine default AMI") } cluster.Platform = PlatformAWS @@ -268,14 +268,14 @@ func ConvertInstallConfigToTFVars(cfg *types.InstallConfig, bootstrapIgn string, } } default: - return nil, fmt.Errorf("unrecognized machine pool %q", m.Name) + return nil, errors.Errorf("unrecognized machine pool %q", m.Name) } } // Validate the TFVars. if err := cluster.ValidateAndLog(); err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to validate TFVars") } return cluster, nil diff --git a/pkg/types/config/parser.go b/pkg/types/config/parser.go index 050b9c94485..cb8116b0970 100644 --- a/pkg/types/config/parser.go +++ b/pkg/types/config/parser.go @@ -2,11 +2,10 @@ package config import ( "context" - "errors" - "fmt" "io/ioutil" "time" + "github.com/pkg/errors" "gopkg.in/yaml.v2" "github.com/openshift/installer/pkg/rhcos" @@ -17,7 +16,7 @@ func ParseConfig(data []byte) (*Cluster, error) { cluster := defaultCluster if err := yaml.Unmarshal(data, &cluster); err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to unmarshal to config.Cluster") } // Deprecated: remove after openshift/release is ported to pullSecret @@ -28,7 +27,7 @@ func ParseConfig(data []byte) (*Cluster, error) { data, err := ioutil.ReadFile(cluster.PullSecretPath) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to read PullSecretPath") } cluster.PullSecret = string(data) cluster.PullSecretPath = "" @@ -40,7 +39,7 @@ func ParseConfig(data []byte) (*Cluster, error) { ami, err := rhcos.AMI(ctx, rhcos.DefaultChannel, cluster.AWS.Region) if err != nil { - return nil, fmt.Errorf("failed to determine default AMI: %v", err) + return nil, errors.Wrap(err, "failed to determine default AMI") } cluster.EC2AMIOverride = ami } @@ -52,7 +51,7 @@ func ParseConfig(data []byte) (*Cluster, error) { func ParseConfigFile(path string) (*Cluster, error) { data, err := ioutil.ReadFile(path) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to read file") } return ParseConfig(data) @@ -63,7 +62,7 @@ func ParseInternal(data []byte) (*Internal, error) { internal := &Internal{} if err := yaml.Unmarshal(data, internal); err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to unmarshal to config.Internal") } return internal, nil @@ -73,7 +72,7 @@ func ParseInternal(data []byte) (*Internal, error) { func ParseInternalFile(path string) (*Internal, error) { data, err := ioutil.ReadFile(path) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to read file") } return ParseInternal(data)