github.com/arunkumar7540/cli@v6.45.0+incompatible/command/v7/update_buildpack_command.go (about) 1 package v7 2 3 import ( 4 "io/ioutil" 5 "os" 6 "time" 7 8 "code.cloudfoundry.org/cli/actor/sharedaction" 9 "code.cloudfoundry.org/cli/actor/v7action" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 11 "code.cloudfoundry.org/cli/command" 12 "code.cloudfoundry.org/cli/command/flag" 13 "code.cloudfoundry.org/cli/command/translatableerror" 14 "code.cloudfoundry.org/cli/command/v7/shared" 15 "code.cloudfoundry.org/cli/types" 16 "code.cloudfoundry.org/cli/util/configv3" 17 "code.cloudfoundry.org/cli/util/download" 18 ) 19 20 //go:generate counterfeiter . UpdateBuildpackActor 21 22 type UpdateBuildpackActor interface { 23 UpdateBuildpackByNameAndStack(buildpackName string, buildpackStack string, buildpack v7action.Buildpack) (v7action.Buildpack, v7action.Warnings, error) 24 UploadBuildpack(guid string, pathToBuildpackBits string, progressBar v7action.SimpleProgressBar) (ccv3.JobURL, v7action.Warnings, error) 25 PrepareBuildpackBits(inputPath string, tmpDirPath string, downloader v7action.Downloader) (string, error) 26 PollUploadBuildpackJob(jobURL ccv3.JobURL) (v7action.Warnings, error) 27 } 28 29 type UpdateBuildpackCommand struct { 30 RequiredArgs flag.BuildpackName `positional-args:"Yes"` 31 usage interface{} `usage:"CF_NAME update-buildpack BUILDPACK [-p PATH | -s STACK | --assign-stack NEW_STACK] [-i POSITION] [--enable|--disable] [--lock|--unlock] [--rename]\n\nTIP:\nPath should be a zip file, a url to a zip file, or a local directory. Position is a positive integer, sets priority, and is sorted from lowest to highest.\n\nUse '--assign-stack' with caution. Associating a buildpack with a stack that it does not support may result in undefined behavior. Additionally, changing this association once made may require a local copy of the buildpack.\n\n"` 32 relatedCommands interface{} `related_commands:"buildpacks, create-buildpack, delete-buildpack"` 33 NewStack string `long:"assign-stack" description:"Assign a stack to a buildpack that does not have a stack association"` 34 Disable bool `long:"disable" description:"Disable the buildpack from being used for staging"` 35 Enable bool `long:"enable" description:"Enable the buildpack to be used for staging"` 36 Lock bool `long:"lock" description:"Lock the buildpack to prevent updates"` 37 Path flag.PathWithExistenceCheckOrURL `long:"path" short:"p" description:"Path to directory or zip file"` 38 Position types.NullInt `long:"position" short:"i" description:"The order in which the buildpacks are checked during buildpack auto-detection"` 39 NewName string `long:"rename" description:"Rename an existing buildpack"` 40 CurrentStack string `long:"stack" short:"s" description:"Specify stack to disambiguate buildpacks with the same name"` 41 Unlock bool `long:"unlock" description:"Unlock the buildpack to enable updates"` 42 43 UI command.UI 44 Config command.Config 45 ProgressBar v7action.SimpleProgressBar 46 SharedActor command.SharedActor 47 Actor UpdateBuildpackActor 48 } 49 50 func (cmd *UpdateBuildpackCommand) Setup(config command.Config, ui command.UI) error { 51 cmd.UI = ui 52 cmd.Config = config 53 sharedActor := sharedaction.NewActor(config) 54 cmd.SharedActor = sharedActor 55 56 ccClient, uaaClient, err := shared.NewClients(config, ui, true, "") 57 if err != nil { 58 return err 59 } 60 cmd.Actor = v7action.NewActor(ccClient, config, sharedActor, uaaClient) 61 cmd.ProgressBar = v7action.NewProgressBar() 62 63 return nil 64 } 65 66 func (cmd UpdateBuildpackCommand) Execute(args []string) error { 67 var buildpackBitsPath, tmpDirPath string 68 69 user, err := cmd.validateSetup() 70 if err != nil { 71 return err 72 } 73 74 cmd.printInitialText(user.Name) 75 76 if cmd.Path != "" { 77 buildpackBitsPath, tmpDirPath, err = cmd.prepareBuildpackBits() 78 if err != nil { 79 return err 80 } 81 defer os.RemoveAll(tmpDirPath) 82 } 83 84 updatedBuildpack, err := cmd.updateBuildpack() 85 if err != nil { 86 return err 87 } 88 89 if buildpackBitsPath != "" { 90 return cmd.uploadBits(user, updatedBuildpack, buildpackBitsPath) 91 } 92 93 return nil 94 } 95 96 func (cmd UpdateBuildpackCommand) validateSetup() (configv3.User, error) { 97 var user configv3.User 98 99 err := cmd.validateFlagCombinations() 100 if err != nil { 101 return user, err 102 } 103 104 err = cmd.SharedActor.CheckTarget(false, false) 105 if err != nil { 106 return user, err 107 } 108 109 return cmd.Config.CurrentUser() 110 } 111 112 func (cmd UpdateBuildpackCommand) prepareBuildpackBits() (string, string, error) { 113 downloader := download.NewDownloader(time.Second * 30) 114 tmpDirPath, err := ioutil.TempDir("", "buildpack-dir-") 115 if err != nil { 116 return "", "", err 117 } 118 119 buildpackBits, err := cmd.Actor.PrepareBuildpackBits(string(cmd.Path), tmpDirPath, downloader) 120 return buildpackBits, tmpDirPath, err 121 } 122 123 func (cmd UpdateBuildpackCommand) updateBuildpack() (v7action.Buildpack, error) { 124 var desiredBuildpack v7action.Buildpack 125 126 desiredBuildpack.Enabled = types.NullBool{IsSet: cmd.Enable || cmd.Disable, Value: cmd.Enable} 127 desiredBuildpack.Locked = types.NullBool{IsSet: cmd.Lock || cmd.Unlock, Value: cmd.Lock} 128 desiredBuildpack.Position = cmd.Position 129 130 if cmd.NewStack != "" { 131 desiredBuildpack.Stack = cmd.NewStack 132 } 133 134 if cmd.NewName != "" { 135 desiredBuildpack.Name = cmd.NewName 136 } 137 138 updatedBuildpack, warnings, err := cmd.Actor.UpdateBuildpackByNameAndStack( 139 cmd.RequiredArgs.Buildpack, 140 cmd.CurrentStack, 141 desiredBuildpack, 142 ) 143 cmd.UI.DisplayWarnings(warnings) 144 if err != nil { 145 return updatedBuildpack, err 146 } 147 cmd.UI.DisplayOK() 148 149 return updatedBuildpack, nil 150 } 151 152 func (cmd UpdateBuildpackCommand) uploadBits(user configv3.User, updatedBuildpack v7action.Buildpack, buildpackBitsPath string) error { 153 cmd.UI.DisplayTextWithFlavor("Uploading buildpack {{.Buildpack}} as {{.Username}}...", map[string]interface{}{ 154 "Buildpack": cmd.RequiredArgs.Buildpack, 155 "Username": user.Name, 156 }) 157 158 jobURL, warnings, err := cmd.Actor.UploadBuildpack( 159 updatedBuildpack.GUID, 160 buildpackBitsPath, 161 cmd.ProgressBar, 162 ) 163 cmd.UI.DisplayWarnings(warnings) 164 if err != nil { 165 return err 166 } 167 cmd.UI.DisplayOK() 168 169 cmd.UI.DisplayTextWithFlavor("Processing uploaded buildpack {{.BuildpackName}}...", map[string]interface{}{ 170 "BuildpackName": cmd.RequiredArgs.Buildpack, 171 }) 172 173 warnings, err = cmd.Actor.PollUploadBuildpackJob(jobURL) 174 cmd.UI.DisplayWarnings(warnings) 175 if err != nil { 176 return err 177 } 178 179 cmd.UI.DisplayOK() 180 return nil 181 } 182 183 func (cmd UpdateBuildpackCommand) printInitialText(userName string) { 184 var originalBuildpackName = cmd.RequiredArgs.Buildpack 185 var buildpackName = originalBuildpackName 186 187 if cmd.NewName != "" { 188 buildpackName = cmd.NewName 189 cmd.UI.DisplayTextWithFlavor("Renaming buildpack {{.Buildpack}} to {{.DesiredBuildpackName}} as {{.CurrentUser}}...\n", map[string]interface{}{ 190 "Buildpack": originalBuildpackName, 191 "CurrentUser": userName, 192 "DesiredBuildpackName": cmd.NewName, 193 }) 194 } 195 196 switch { 197 case cmd.NewStack != "": 198 cmd.UI.DisplayTextWithFlavor("Assigning stack {{.Stack}} to {{.Buildpack}} as {{.CurrentUser}}...", map[string]interface{}{ 199 "Buildpack": buildpackName, 200 "CurrentUser": userName, 201 "Stack": cmd.NewStack, 202 }) 203 if cmd.Position.IsSet || cmd.Lock || cmd.Unlock || cmd.Enable || cmd.Disable { 204 cmd.UI.DisplayTextWithFlavor("\nUpdating buildpack {{.Buildpack}} with stack {{.Stack}} as {{.CurrentUser}}...", map[string]interface{}{ 205 "Buildpack": buildpackName, 206 "CurrentUser": userName, 207 "Stack": cmd.NewStack, 208 }) 209 } 210 case cmd.CurrentStack == "": 211 cmd.UI.DisplayTextWithFlavor("Updating buildpack {{.Buildpack}} as {{.CurrentUser}}...", map[string]interface{}{ 212 "Buildpack": buildpackName, 213 "CurrentUser": userName, 214 }) 215 default: 216 cmd.UI.DisplayTextWithFlavor("Updating buildpack {{.Buildpack}} with stack {{.Stack}} as {{.CurrentUser}}...", map[string]interface{}{ 217 "Buildpack": buildpackName, 218 "CurrentUser": userName, 219 "Stack": cmd.CurrentStack, 220 }) 221 } 222 } 223 224 func (cmd UpdateBuildpackCommand) validateFlagCombinations() error { 225 if cmd.Lock && cmd.Unlock { 226 return translatableerror.ArgumentCombinationError{ 227 Args: []string{"--lock", "--unlock"}, 228 } 229 } 230 231 if cmd.Enable && cmd.Disable { 232 return translatableerror.ArgumentCombinationError{ 233 Args: []string{"--enable", "--disable"}, 234 } 235 } 236 237 if cmd.Path != "" && cmd.Lock { 238 return translatableerror.ArgumentCombinationError{ 239 Args: []string{"--path", "--lock"}, 240 } 241 } 242 243 if cmd.Path != "" && cmd.NewStack != "" { 244 return translatableerror.ArgumentCombinationError{ 245 Args: []string{"--path", "--assign-stack"}, 246 } 247 } 248 249 if cmd.CurrentStack != "" && cmd.NewStack != "" { 250 return translatableerror.ArgumentCombinationError{ 251 Args: []string{"--stack", "--assign-stack"}, 252 } 253 } 254 return nil 255 }