github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/step/step_wait_for_artifact.go (about) 1 package step 2 3 import ( 4 "fmt" 5 "net/http" 6 "strings" 7 "time" 8 9 "github.com/jenkins-x/jx/v2/pkg/cmd/opts/step" 10 11 "github.com/jenkins-x/jx/v2/pkg/cmd/helper" 12 13 "github.com/jenkins-x/jx-logging/pkg/log" 14 "github.com/jenkins-x/jx/v2/pkg/cmd/opts" 15 "github.com/jenkins-x/jx/v2/pkg/cmd/templates" 16 "github.com/jenkins-x/jx/v2/pkg/util" 17 "github.com/spf13/cobra" 18 ) 19 20 const ( 21 optionRepo = "repo" 22 optionGroup = "group" 23 optionArtifact = "artifact" 24 optionVersion = "version" 25 optionPollTime = "poll-time" 26 DefaultMavenCentralRepo = "https://repo1.maven.org/maven2/" 27 ) 28 29 // StepWaitForArtifactOptions contains the command line flags 30 type StepWaitForArtifactOptions struct { 31 step.StepOptions 32 33 ArtifactURL string 34 RepoURL string 35 GroupId string 36 ArtifactId string 37 Version string 38 Extension string 39 Timeout string 40 PollTime string 41 42 // calculated fields 43 TimeoutDuration time.Duration 44 PollDuration time.Duration 45 } 46 47 var ( 48 StepWaitForArtifactLong = templates.LongDesc(` 49 Waits for the given artifact to be available in a maven style repository 50 51 `) 52 53 StepWaitForArtifactExample = templates.Examples(` 54 # wait for a 55 jx step gpg credentials 56 57 # generate the git credentials to a output file 58 jx step gpg credentials -o /tmp/mycreds 59 60 `) 61 ) 62 63 func NewCmdStepWaitForArtifact(commonOpts *opts.CommonOptions) *cobra.Command { 64 options := StepWaitForArtifactOptions{ 65 StepOptions: step.StepOptions{ 66 CommonOptions: commonOpts, 67 }, 68 } 69 cmd := &cobra.Command{ 70 Use: "wait for artifact", 71 Short: "Waits for the given artifact to be available in a maven style repository", 72 Long: StepWaitForArtifactLong, 73 Example: StepWaitForArtifactExample, 74 Run: func(cmd *cobra.Command, args []string) { 75 options.Cmd = cmd 76 options.Args = args 77 err := options.Run() 78 helper.CheckErr(err) 79 }, 80 } 81 cmd.Flags().StringVarP(&options.ArtifactURL, "artifact-url", "", "", "The full URL of the artifact to wait for. If not specified it is calculated from the repository URL, group, artifact and version") 82 cmd.Flags().StringVarP(&options.RepoURL, optionRepo, "r", DefaultMavenCentralRepo, "The URL of the maven style repository to query for the artifact") 83 cmd.Flags().StringVarP(&options.GroupId, optionGroup, "g", "", "The group ID of the artifact to search for") 84 cmd.Flags().StringVarP(&options.ArtifactId, optionArtifact, "a", "", "The artifact ID of the artifact to search for") 85 cmd.Flags().StringVarP(&options.Version, optionVersion, "v", "", "The version of the artifact to search for") 86 cmd.Flags().StringVarP(&options.Extension, "ext", "x", "pom", "The file extension to search for") 87 cmd.Flags().StringVarP(&options.Timeout, opts.OptionTimeout, "t", "1h", "The duration before we consider this operation failed") 88 cmd.Flags().StringVarP(&options.PollTime, optionPollTime, "", "10s", "The amount of time between polls for the artifact URL being present") 89 return cmd 90 } 91 92 func (o *StepWaitForArtifactOptions) getUrlStatusOK(u string) error { 93 client := http.Client{} 94 req, err := http.NewRequest(http.MethodGet, u, nil) 95 if err != nil { 96 return err 97 } 98 res, err := client.Do(req) 99 if err != nil { 100 return err 101 } 102 if res.StatusCode < 200 || res.StatusCode >= 300 { 103 return fmt.Errorf("Failed in request for %s as got status %d %s", u, res.StatusCode, res.Status) 104 } 105 return nil 106 } 107 108 func (o *StepWaitForArtifactOptions) Run() error { 109 var err error 110 if o.PollTime != "" { 111 o.PollDuration, err = time.ParseDuration(o.PollTime) 112 if err != nil { 113 return fmt.Errorf("Invalid duration format %s for option --%s: %s", o.PollTime, optionPollTime, err) 114 } 115 } 116 if o.Timeout != "" { 117 o.TimeoutDuration, err = time.ParseDuration(o.Timeout) 118 if err != nil { 119 return fmt.Errorf("Invalid duration format %s for option --%s: %s", o.Timeout, opts.OptionTimeout, err) 120 } 121 } 122 123 if o.ArtifactURL == "" { 124 // lets create it from the various parts 125 if o.RepoURL == "" { 126 return util.MissingOption(optionRepo) 127 } 128 group := o.GroupId 129 if group == "" { 130 return util.MissingOption(optionGroup) 131 } 132 group = strings.Replace(group, ".", "/", -1) 133 artifact := o.ArtifactId 134 if artifact == "" { 135 return util.MissingOption(optionArtifact) 136 } 137 version := o.Version 138 if version == "" { 139 return util.MissingOption(optionVersion) 140 } 141 o.ArtifactURL = util.UrlJoin(o.RepoURL, group, artifact, version, artifact+"-"+version+"."+o.Extension) 142 } 143 log.Logger().Infof("Waiting for artifact at %s", util.ColorInfo(o.ArtifactURL)) 144 145 fn := func() error { 146 return o.getUrlStatusOK(o.ArtifactURL) 147 } 148 err = o.RetryQuietlyUntilTimeout(o.TimeoutDuration, o.PollDuration, fn) 149 if err == nil { 150 log.Logger().Infof("Found artifact at %s", util.ColorInfo(o.ArtifactURL)) 151 return nil 152 } 153 log.Logger().Warnf("Failed to find artifact at %s due to %s", o.ArtifactURL, err) 154 return err 155 }