github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/step/verify/step_verify_packages.go (about)

     1  package verify
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	options2 "github.com/olli-ai/jx/v2/pkg/cmd/create/options"
     8  
     9  	"github.com/jenkins-x/jx-logging/pkg/log"
    10  	"github.com/olli-ai/jx/v2/pkg/cmd/helper"
    11  	"github.com/olli-ai/jx/v2/pkg/cmd/opts"
    12  	"github.com/olli-ai/jx/v2/pkg/cmd/opts/step"
    13  	"github.com/olli-ai/jx/v2/pkg/cmd/templates"
    14  	"github.com/olli-ai/jx/v2/pkg/cmd/upgrade"
    15  	"github.com/olli-ai/jx/v2/pkg/config"
    16  	"github.com/olli-ai/jx/v2/pkg/util"
    17  	"github.com/olli-ai/jx/v2/pkg/version"
    18  	"github.com/olli-ai/jx/v2/pkg/versionstream"
    19  	"github.com/pkg/errors"
    20  	"github.com/spf13/cobra"
    21  )
    22  
    23  var (
    24  	verifyPackagesLong = templates.LongDesc(`
    25  		Verifies the versions of the required command line packages
    26  
    27  
    28  ` + helper.SeeAlsoText("jx create project"))
    29  
    30  	verifyPackagesExample = templates.Examples(`
    31  		Verifies the versions of the required command line packages
    32  
    33  		# verify packages and fail if any are not valid:
    34  		jx step verify packages
    35  
    36  		# override the error if the 'jx' binary is out of range (e.g. for development)
    37          export JX_DISABLE_VERIFY_JX="true"
    38  		jx step verify packages
    39  	`)
    40  )
    41  
    42  // StepVerifyPackagesOptions contains the command line flags
    43  type StepVerifyPackagesOptions struct {
    44  	step.StepOptions
    45  
    46  	Namespace string
    47  	HelmTLS   bool
    48  	Packages  []string
    49  	Dir       string
    50  }
    51  
    52  // NewCmdStepVerifyPackages creates the `jx step verify pod` command
    53  func NewCmdStepVerifyPackages(commonOpts *opts.CommonOptions) *cobra.Command {
    54  	options := &StepVerifyPackagesOptions{
    55  		StepOptions: step.StepOptions{
    56  			CommonOptions: commonOpts,
    57  		},
    58  	}
    59  
    60  	cmd := &cobra.Command{
    61  		Use:     "packages",
    62  		Aliases: []string{"package"},
    63  		Short:   "Verifies the versions of the required command line packages",
    64  		Long:    verifyPackagesLong,
    65  		Example: verifyPackagesExample,
    66  		Run: func(cmd *cobra.Command, args []string) {
    67  			options.Cmd = cmd
    68  			options.Args = args
    69  			err := options.Run()
    70  			helper.CheckErr(err)
    71  		},
    72  	}
    73  	cmd.Flags().BoolVarP(&options.HelmTLS, "helm-tls", "", false, "Whether to use TLS with helm")
    74  	cmd.Flags().StringVarP(&options.Namespace, "namespace", "n", "", "The namespace to use to look for helm's tiller")
    75  	cmd.Flags().StringArrayVarP(&options.Packages, "packages", "p", []string{"jx", "kubectl", "git", "helm", "kaniko"}, "The packages to verify")
    76  	cmd.Flags().StringVarP(&options.Dir, "dir", "d", ".", "the directory to recursively look upwards for any 'jx-requirements.yml' file to determine the version stream")
    77  	return cmd
    78  }
    79  
    80  // Run implements this command
    81  func (o *StepVerifyPackagesOptions) Run() error {
    82  	packages, table := o.GetPackageVersions(o.Namespace, o.HelmTLS)
    83  
    84  	verifyMap := map[string]string{}
    85  	for _, k := range o.Packages {
    86  		verifyMap[k] = packages[k]
    87  	}
    88  
    89  	requirements, _, err := config.LoadRequirementsConfig(o.Dir, config.DefaultFailOnValidationError)
    90  	if err != nil {
    91  		return errors.Wrapf(err, "failed to load boot requirements")
    92  	}
    93  	vs := requirements.VersionStream
    94  	u := vs.URL
    95  	ref := vs.Ref
    96  	log.Logger().Infof("Verifying the CLI packages using version stream URL: %s and git ref: %s\n", u, vs.Ref)
    97  
    98  	resolver, err := o.CreateVersionResolver(u, ref)
    99  	if err != nil {
   100  		return errors.Wrapf(err, "failed to create version resolver")
   101  	}
   102  
   103  	// lets verify jx separately
   104  	delete(packages, "jx")
   105  
   106  	err = resolver.VerifyPackages(verifyMap)
   107  	if err != nil {
   108  		return err
   109  	}
   110  	err = o.verifyJXVersion(resolver)
   111  	if err != nil {
   112  		return err
   113  	}
   114  
   115  	log.Logger().Infof("CLI packages %s seem to be setup correctly", util.ColorInfo(strings.Join(o.Packages, ", ")))
   116  	table.Render()
   117  
   118  	return nil
   119  }
   120  
   121  func (o *StepVerifyPackagesOptions) verifyJXVersion(resolver versionstream.Streamer) error {
   122  	currentVersion, err := version.GetSemverVersion()
   123  	if err != nil {
   124  		return errors.Wrap(err, "getting current jx version")
   125  	}
   126  	versionStreamVersion, err := o.GetLatestJXVersion(resolver)
   127  	if err != nil {
   128  		return errors.Wrap(err, "getting latest jx version")
   129  	}
   130  	info := util.ColorInfo
   131  	latestVersionText := versionStreamVersion.String()
   132  
   133  	if currentVersion.EQ(versionStreamVersion) {
   134  		log.Logger().Infof("using version %s of %s", info(latestVersionText), info("jx"))
   135  		return nil
   136  	}
   137  
   138  	// The case this happens is when we have a version stream ref which is outdated, should the version stream not get updated before the binary version is checked?
   139  	if currentVersion.GE(versionStreamVersion) {
   140  		log.Logger().Warnf("jx version specified in the version stream %s is %s. You are using %s. We highly recommend you upgrade versionstream ref", util.ColorInfo(resolver.GetVersionsDir()), util.ColorInfo(latestVersionText), util.ColorInfo(currentVersion.String()))
   141  		return nil
   142  	}
   143  
   144  	log.Logger().Info("\n")
   145  	log.Logger().Warnf("jx version specified in the version stream %s is %s. You are using %s. We highly recommend you upgrade to it.", util.ColorInfo(resolver.GetVersionsDir()), util.ColorInfo(latestVersionText), util.ColorInfo(currentVersion.String()))
   146  
   147  	if o.BatchMode {
   148  		log.Logger().Warnf("To upgrade to this new version use: %s then re-run %s", info("jx upgrade cli"), info("jx boot"))
   149  		return nil
   150  	}
   151  	// skip checks for dev version
   152  	if strings.Contains(currentVersion.String(), "-dev") {
   153  		log.Logger().Warn("Skipping version upgrade since a dev version is used")
   154  		return nil
   155  	}
   156  
   157  	// Todo: verify function should not upgrade, probably a different function is the right thing
   158  	log.Logger().Info("\n")
   159  	message := fmt.Sprintf("Would you like to upgrade to the %s version?", info("jx"))
   160  	answer, err := util.Confirm(message, true, "Please indicate if you would like to upgrade the binary version.", o.GetIOFileHandles())
   161  	if err != nil {
   162  		return err
   163  	}
   164  
   165  	if answer {
   166  		options := &upgrade.UpgradeCLIOptions{
   167  			CreateOptions: options2.CreateOptions{
   168  				CommonOptions: o.CommonOptions,
   169  			},
   170  		}
   171  		options.Version = latestVersionText
   172  		options.NoBrew = true
   173  		err = options.Run()
   174  		if err != nil {
   175  			return err
   176  		}
   177  		log.Logger().Info("\n")
   178  		log.Logger().Warnf("the version of %s has been updated to %s. Please re-run: %s", info("jx"), info(latestVersionText), info("jx boot"))
   179  		log.Logger().Info("\n")
   180  
   181  		return fmt.Errorf("the version of jx has been updated. Please re-run: jx boot")
   182  	}
   183  
   184  	return nil
   185  }