github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/cf/commands/application/scale.go (about) 1 package application 2 3 import ( 4 "errors" 5 "fmt" 6 7 "code.cloudfoundry.org/cli/cf/api/applications" 8 "code.cloudfoundry.org/cli/cf/commandregistry" 9 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 10 "code.cloudfoundry.org/cli/cf/flags" 11 "code.cloudfoundry.org/cli/cf/formatters" 12 . "code.cloudfoundry.org/cli/cf/i18n" 13 "code.cloudfoundry.org/cli/cf/models" 14 "code.cloudfoundry.org/cli/cf/requirements" 15 "code.cloudfoundry.org/cli/cf/terminal" 16 ) 17 18 type Scale struct { 19 ui terminal.UI 20 config coreconfig.Reader 21 restarter Restarter 22 appReq requirements.ApplicationRequirement 23 appRepo applications.Repository 24 } 25 26 func init() { 27 commandregistry.Register(&Scale{}) 28 } 29 30 func (cmd *Scale) MetaData() commandregistry.CommandMetadata { 31 fs := make(map[string]flags.FlagSet) 32 fs["i"] = &flags.IntFlag{ShortName: "i", Usage: T("Number of instances")} 33 fs["k"] = &flags.StringFlag{ShortName: "k", Usage: T("Disk limit (e.g. 256M, 1024M, 1G)")} 34 fs["m"] = &flags.StringFlag{ShortName: "m", Usage: T("Memory limit (e.g. 256M, 1024M, 1G)")} 35 fs["f"] = &flags.BoolFlag{ShortName: "f", Usage: T("Force restart of app without prompt")} 36 37 return commandregistry.CommandMetadata{ 38 Name: "scale", 39 Description: T("Change or view the instance count, disk space limit, and memory limit for an app"), 40 Usage: []string{ 41 T("CF_NAME scale APP_NAME [-i INSTANCES] [-k DISK] [-m MEMORY] [-f]"), 42 }, 43 Flags: fs, 44 } 45 } 46 47 func (cmd *Scale) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) { 48 if len(fc.Args()) != 1 { 49 cmd.ui.Failed(T("Incorrect Usage. Requires an argument\n\n") + commandregistry.Commands.CommandUsage("scale")) 50 return nil, fmt.Errorf("Incorrect usage: %d arguments of %d required", len(fc.Args()), 1) 51 } 52 53 cmd.appReq = requirementsFactory.NewApplicationRequirement(fc.Args()[0]) 54 55 reqs := []requirements.Requirement{ 56 requirementsFactory.NewLoginRequirement(), 57 requirementsFactory.NewTargetedSpaceRequirement(), 58 cmd.appReq, 59 } 60 61 return reqs, nil 62 } 63 64 func (cmd *Scale) SetDependency(deps commandregistry.Dependency, pluginCall bool) commandregistry.Command { 65 cmd.ui = deps.UI 66 cmd.config = deps.Config 67 cmd.appRepo = deps.RepoLocator.GetApplicationRepository() 68 69 //get command from registry for dependency 70 commandDep := commandregistry.Commands.FindCommand("restart") 71 commandDep = commandDep.SetDependency(deps, false) 72 cmd.restarter = commandDep.(Restarter) 73 74 return cmd 75 } 76 77 var bytesInAMegabyte int64 = 1024 * 1024 78 79 func (cmd *Scale) Execute(c flags.FlagContext) error { 80 currentApp := cmd.appReq.GetApplication() 81 if !anyFlagsSet(c) { 82 cmd.ui.Say(T("Showing current scale of app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...", 83 map[string]interface{}{ 84 "AppName": terminal.EntityNameColor(currentApp.Name), 85 "OrgName": terminal.EntityNameColor(cmd.config.OrganizationFields().Name), 86 "SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name), 87 "CurrentUser": terminal.EntityNameColor(cmd.config.Username()), 88 })) 89 cmd.ui.Ok() 90 cmd.ui.Say("") 91 92 cmd.ui.Say("%s %s", terminal.HeaderColor(T("memory:")), formatters.ByteSize(currentApp.Memory*bytesInAMegabyte)) 93 cmd.ui.Say("%s %s", terminal.HeaderColor(T("disk:")), formatters.ByteSize(currentApp.DiskQuota*bytesInAMegabyte)) 94 cmd.ui.Say("%s %d", terminal.HeaderColor(T("instances:")), currentApp.InstanceCount) 95 96 return nil 97 } 98 99 params := models.AppParams{} 100 shouldRestart := false 101 102 if c.String("m") != "" { 103 memory, err := formatters.ToMegabytes(c.String("m")) 104 if err != nil { 105 return errors.New(T("Invalid memory limit: {{.Memory}}\n{{.ErrorDescription}}", 106 map[string]interface{}{ 107 "Memory": c.String("m"), 108 "ErrorDescription": err, 109 })) 110 } 111 params.Memory = &memory 112 shouldRestart = true 113 } 114 115 if c.String("k") != "" { 116 diskQuota, err := formatters.ToMegabytes(c.String("k")) 117 if err != nil { 118 return errors.New(T("Invalid disk quota: {{.DiskQuota}}\n{{.ErrorDescription}}", 119 map[string]interface{}{ 120 "DiskQuota": c.String("k"), 121 "ErrorDescription": err, 122 })) 123 } 124 params.DiskQuota = &diskQuota 125 shouldRestart = true 126 } 127 128 if c.IsSet("i") { 129 instances := c.Int("i") 130 params.InstanceCount = &instances 131 } 132 133 if shouldRestart && !cmd.confirmRestart(c, currentApp.Name) { 134 return nil 135 } 136 137 cmd.ui.Say(T("Scaling app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...", 138 map[string]interface{}{ 139 "AppName": terminal.EntityNameColor(currentApp.Name), 140 "OrgName": terminal.EntityNameColor(cmd.config.OrganizationFields().Name), 141 "SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name), 142 "CurrentUser": terminal.EntityNameColor(cmd.config.Username()), 143 })) 144 145 updatedApp, err := cmd.appRepo.Update(currentApp.GUID, params) 146 if err != nil { 147 return err 148 } 149 150 cmd.ui.Ok() 151 152 if shouldRestart { 153 err = cmd.restarter.ApplicationRestart(updatedApp, cmd.config.OrganizationFields().Name, cmd.config.SpaceFields().Name) 154 if err != nil { 155 return err 156 } 157 } 158 return nil 159 } 160 161 func (cmd *Scale) confirmRestart(context flags.FlagContext, appName string) bool { 162 if context.Bool("f") { 163 return true 164 } 165 166 result := cmd.ui.Confirm(T("This will cause the app to restart. Are you sure you want to scale {{.AppName}}?", 167 map[string]interface{}{"AppName": terminal.EntityNameColor(appName)})) 168 cmd.ui.Say("") 169 return result 170 } 171 172 func anyFlagsSet(context flags.FlagContext) bool { 173 return context.IsSet("m") || context.IsSet("k") || context.IsSet("i") 174 }