github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/command/v6/v3_scale_command.go (about) 1 package v6 2 3 import ( 4 "code.cloudfoundry.org/cli/actor/actionerror" 5 "code.cloudfoundry.org/cli/actor/sharedaction" 6 "code.cloudfoundry.org/cli/actor/v2action" 7 "code.cloudfoundry.org/cli/actor/v3action" 8 "code.cloudfoundry.org/cli/command" 9 "code.cloudfoundry.org/cli/command/flag" 10 "code.cloudfoundry.org/cli/command/translatableerror" 11 "code.cloudfoundry.org/cli/command/v6/shared" 12 ) 13 14 //go:generate counterfeiter . V3ScaleActor 15 16 type V3ScaleActor interface { 17 shared.V3AppSummaryActor 18 19 GetApplicationByNameAndSpace(appName string, spaceGUID string) (v3action.Application, v3action.Warnings, error) 20 ScaleProcessByApplication(appGUID string, process v3action.Process) (v3action.Warnings, error) 21 StopApplication(appGUID string) (v3action.Warnings, error) 22 StartApplication(appGUID string) (v3action.Warnings, error) 23 PollStart(appGUID string, warnings chan<- v3action.Warnings) error 24 } 25 26 type V3ScaleCommand struct { 27 RequiredArgs flag.AppName `positional-args:"yes"` 28 Force bool `short:"f" description:"Force restart of app without prompt"` 29 Instances flag.Instances `short:"i" required:"false" description:"Number of instances"` 30 DiskLimit flag.Megabytes `short:"k" required:"false" description:"Disk limit (e.g. 256M, 1024M, 1G)"` 31 MemoryLimit flag.Megabytes `short:"m" required:"false" description:"Memory limit (e.g. 256M, 1024M, 1G)"` 32 ProcessType string `long:"process" default:"web" description:"App process to scale"` 33 usage interface{} `usage:"CF_NAME v3-scale APP_NAME [--process PROCESS] [-i INSTANCES] [-k DISK] [-m MEMORY]"` 34 relatedCommands interface{} `related_commands:"v3-push"` 35 envCFStartupTimeout interface{} `environmentName:"CF_STARTUP_TIMEOUT" environmentDescription:"Max wait time for app instance startup, in minutes" environmentDefault:"5"` 36 37 UI command.UI 38 Config command.Config 39 Actor V3ScaleActor 40 SharedActor command.SharedActor 41 AppSummaryDisplayer shared.AppSummaryDisplayer 42 } 43 44 func (cmd *V3ScaleCommand) Setup(config command.Config, ui command.UI) error { 45 cmd.UI = ui 46 cmd.Config = config 47 cmd.SharedActor = sharedaction.NewActor(config) 48 49 ccClient, _, err := shared.NewV3BasedClients(config, ui, true) 50 if err != nil { 51 return err 52 } 53 cmd.Actor = v3action.NewActor(ccClient, config, nil, nil) 54 55 ccClientV2, uaaClientV2, err := shared.GetNewClientsAndConnectToCF(config, ui) 56 if err != nil { 57 return err 58 } 59 v2Actor := v2action.NewActor(ccClientV2, uaaClientV2, config) 60 61 cmd.AppSummaryDisplayer = shared.AppSummaryDisplayer{ 62 UI: ui, 63 Config: config, 64 Actor: cmd.Actor, 65 V2AppActor: v2Actor, 66 AppName: cmd.RequiredArgs.AppName, 67 } 68 69 return nil 70 } 71 72 func (cmd V3ScaleCommand) Execute(args []string) error { 73 cmd.UI.DisplayWarning(command.ExperimentalWarning) 74 75 err := cmd.SharedActor.CheckTarget(true, true) 76 if err != nil { 77 return err 78 } 79 80 user, err := cmd.Config.CurrentUser() 81 if err != nil { 82 return err 83 } 84 85 app, warnings, err := cmd.Actor.GetApplicationByNameAndSpace(cmd.RequiredArgs.AppName, cmd.Config.TargetedSpace().GUID) 86 cmd.UI.DisplayWarnings(warnings) 87 if err != nil { 88 return err 89 } 90 91 if !cmd.Instances.IsSet && !cmd.DiskLimit.IsSet && !cmd.MemoryLimit.IsSet { 92 return cmd.showCurrentScale(user.Name) 93 } 94 95 scalled, err := cmd.scaleProcess(app.GUID, user.Name) 96 if err != nil { 97 return err 98 } 99 if !scalled { 100 return nil 101 } 102 103 pollWarnings := make(chan v3action.Warnings) 104 done := make(chan bool) 105 go func() { 106 for { 107 select { 108 case message := <-pollWarnings: 109 cmd.UI.DisplayWarnings(message) 110 case <-done: 111 return 112 } 113 } 114 }() 115 116 err = cmd.Actor.PollStart(app.GUID, pollWarnings) 117 done <- true 118 119 if err != nil { 120 if _, ok := err.(actionerror.StartupTimeoutError); ok { 121 return translatableerror.StartupTimeoutError{ 122 AppName: cmd.RequiredArgs.AppName, 123 BinaryName: cmd.Config.BinaryName(), 124 } 125 } 126 127 return err 128 } 129 130 return cmd.showCurrentScale(user.Name) 131 } 132 133 func (cmd V3ScaleCommand) scaleProcess(appGUID string, username string) (bool, error) { 134 cmd.UI.DisplayTextWithFlavor("Scaling app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{ 135 "AppName": cmd.RequiredArgs.AppName, 136 "OrgName": cmd.Config.TargetedOrganization().Name, 137 "SpaceName": cmd.Config.TargetedSpace().Name, 138 "Username": username, 139 }) 140 cmd.UI.DisplayNewline() 141 142 shouldRestart := cmd.DiskLimit.IsSet || cmd.MemoryLimit.IsSet 143 if shouldRestart && !cmd.Force { 144 shouldScale, err := cmd.UI.DisplayBoolPrompt( 145 false, 146 "This will cause the app to restart. Are you sure you want to scale {{.AppName}}?", 147 map[string]interface{}{"AppName": cmd.RequiredArgs.AppName}) 148 if err != nil { 149 return false, err 150 } 151 152 if !shouldScale { 153 cmd.UI.DisplayText("Scaling cancelled") 154 return false, nil 155 } 156 cmd.UI.DisplayNewline() 157 } 158 159 warnings, err := cmd.Actor.ScaleProcessByApplication(appGUID, v3action.Process{ 160 Type: cmd.ProcessType, 161 Instances: cmd.Instances.NullInt, 162 MemoryInMB: cmd.MemoryLimit.NullUint64, 163 DiskInMB: cmd.DiskLimit.NullUint64, 164 }) 165 cmd.UI.DisplayWarnings(warnings) 166 if err != nil { 167 return false, err 168 } 169 170 if shouldRestart { 171 err := cmd.restartApplication(appGUID, username) 172 if err != nil { 173 return false, err 174 } 175 } 176 177 return true, nil 178 } 179 180 func (cmd V3ScaleCommand) restartApplication(appGUID string, username string) error { 181 cmd.UI.DisplayTextWithFlavor("Stopping app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{ 182 "AppName": cmd.RequiredArgs.AppName, 183 "OrgName": cmd.Config.TargetedOrganization().Name, 184 "SpaceName": cmd.Config.TargetedSpace().Name, 185 "Username": username, 186 }) 187 cmd.UI.DisplayNewline() 188 189 warnings, err := cmd.Actor.StopApplication(appGUID) 190 cmd.UI.DisplayWarnings(warnings) 191 if err != nil { 192 return err 193 } 194 195 cmd.UI.DisplayTextWithFlavor("Starting app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{ 196 "AppName": cmd.RequiredArgs.AppName, 197 "OrgName": cmd.Config.TargetedOrganization().Name, 198 "SpaceName": cmd.Config.TargetedSpace().Name, 199 "Username": username, 200 }) 201 cmd.UI.DisplayNewline() 202 203 warnings, err = cmd.Actor.StartApplication(appGUID) 204 cmd.UI.DisplayWarnings(warnings) 205 if err != nil { 206 return err 207 } 208 209 return nil 210 } 211 212 func (cmd V3ScaleCommand) showCurrentScale(userName string) error { 213 cmd.UI.DisplayTextWithFlavor("Showing current scale of app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{ 214 "AppName": cmd.RequiredArgs.AppName, 215 "OrgName": cmd.Config.TargetedOrganization().Name, 216 "SpaceName": cmd.Config.TargetedSpace().Name, 217 "Username": userName, 218 }) 219 220 return cmd.AppSummaryDisplayer.DisplayAppProcessInfo() 221 }