diff --git a/plugins/resource/functions.go b/plugins/resource/functions.go new file mode 100644 index 000000000..8f2b9ef61 --- /dev/null +++ b/plugins/resource/functions.go @@ -0,0 +1,130 @@ +package resource + +import ( + "fmt" + + "github.com/dokku/dokku/plugins/common" +) + +func clearByResourceType(appName string, processType string, resourceType string) { + noun := "limits" + if resourceType == "reserve" { + noun = "reservation" + } + + message := fmt.Sprintf("clearing %v %v", appName, noun) + if processType != "_default_" && processType != "" { + message = fmt.Sprintf("%v (%v)", message, processType) + } + common.LogInfo2Quiet(message) + + if processType == "" { + resources, err := common.PropertyGetAll("resource", appName) + if err != nil { + return + } + for key := range resources { + common.PropertyDelete("resource", appName, key) + } + } else { + resources := []string{ + "cpu", + "memory", + "memory-swap", + "network", + "network-ingress", + "network-egress", + "nvidia-gpu", + } + + for _, key := range resources { + property := propertyKey(processType, resourceType, key) + common.PropertyDelete("resource", appName, property) + } + } +} + +func setResourceType(appName string, processType string, r Resource, resourceType string) error { + if len(processType) == 0 { + processType = "_default_" + } + + resources := map[string]string{ + "cpu": r.CPU, + "memory": r.Memory, + "memory-swap": r.MemorySwap, + "network": r.Network, + "network-ingress": r.NetworkIngress, + "network-egress": r.NetworkEgress, + "nvidia-gpu": r.NvidiaGPU, + } + + hasValues := false + for _, value := range resources { + if value != "" { + hasValues = true + } + } + + if !hasValues { + reportResourceType(appName, processType, resourceType) + return nil + } + + noun := "limits" + if resourceType == "reserve" { + noun = "reservation" + } + message := fmt.Sprintf("Setting resource %v for %v", noun, appName) + if processType != "_default_" { + message = fmt.Sprintf("%v (%v)", message, processType) + } + common.LogInfo2Quiet(message) + + for key, value := range resources { + if value == "" { + continue + } + + common.LogVerbose(fmt.Sprintf("%v: %v", key, value)) + property := propertyKey(processType, resourceType, key) + err := common.PropertyWrite("resource", appName, property, value) + if err != nil { + return err + } + } + + return nil +} + +func reportResourceType(appName string, processType string, resourceType string) { + noun := "limits" + if resourceType == "reserve" { + noun = "reservation" + } + + message := fmt.Sprintf("resource %v %v information", noun, appName) + if processType == "_default_" { + message = fmt.Sprintf("%v [defaults]", message) + } else { + message = fmt.Sprintf("%v (%v)", message, processType) + } + common.LogInfo2Quiet(message) + + resources := []string{ + "cpu", + "memory", + "memory-swap", + "network", + "network-ingress", + "network-egress", + "nvidia-gpu", + } + + for _, key := range resources { + property := propertyKey(processType, resourceType, key) + value := common.PropertyGet("resource", appName, property) + common.LogVerbose(fmt.Sprintf("%v: %v", key, value)) + } + return +} diff --git a/plugins/resource/src/subcommands/subcommands.go b/plugins/resource/src/subcommands/subcommands.go index 713fa04c9..b6fbf99ea 100644 --- a/plugins/resource/src/subcommands/subcommands.go +++ b/plugins/resource/src/subcommands/subcommands.go @@ -28,6 +28,7 @@ func main() { networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to limit processes by") nvidiaGpu := args.String("nvidia-gpu", "", "nvidia-gpu: The number of Nvidia GPUs to limit a process to") args.Parse(os.Args[2:]) + appName := args.Arg(0) resources := resource.Resource{ CPU: *cpu, @@ -39,17 +40,19 @@ func main() { NvidiaGPU: *nvidiaGpu, } - err = resource.CommandLimit(args.Args(), *processType, resources) + err = resource.CommandLimit(appName, *processType, resources) case "limit-clear": args := flag.NewFlagSet("resource:limit-clear", flag.ExitOnError) processType := args.String("process-type", "", "process-type: A process type to clear") args.Parse(os.Args[2:]) - err = resource.CommandLimitClear(args.Args(), *processType) + appName := args.Arg(0) + err = resource.CommandLimitClear(appName, *processType) case "report": - flag.Parse() - appName := flag.Arg(1) - infoFlag := flag.Arg(2) - resource.CommandReport(appName, infoFlag) + args := flag.NewFlagSet("resource:report", flag.ExitOnError) + args.Parse(os.Args[2:]) + appName := args.Arg(0) + infoFlag := args.Arg(1) + err = resource.CommandReport(appName, infoFlag) case "reserve": args := flag.NewFlagSet("resource:reserve", flag.ExitOnError) processType := args.String("process-type", "", "process-type: A process type to manage") @@ -61,6 +64,7 @@ func main() { networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to reserve for processes") nvidiaGpu := args.String("nvidia-gpu", "", "nvidia-gpu: The number of Nvidia GPUs to resource for a process") args.Parse(os.Args[2:]) + appName := args.Arg(0) resources := resource.Resource{ CPU: *cpu, @@ -72,12 +76,13 @@ func main() { NvidiaGPU: *nvidiaGpu, } - err = resource.CommandReserve(args.Args(), *processType, resources) + err = resource.CommandReserve(appName, *processType, resources) case "reserve-clear": args := flag.NewFlagSet("resource:reserve-clear", flag.ExitOnError) processType := args.String("process-type", "", "process-type: A process type to clear") args.Parse(os.Args[2:]) - err = resource.CommandReserveClear(args.Args(), *processType) + appName := args.Arg(0) + err = resource.CommandReserveClear(appName, *processType) default: common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand)) } diff --git a/plugins/resource/subcommands.go b/plugins/resource/subcommands.go index 8107dceaf..32cc9e055 100644 --- a/plugins/resource/subcommands.go +++ b/plugins/resource/subcommands.go @@ -1,27 +1,25 @@ package resource import ( - "fmt" + "errors" "strings" "github.com/dokku/dokku/plugins/common" ) // CommandLimit implements resource:limit -func CommandLimit(args []string, processType string, r Resource) error { - appName, err := getAppName(args) - if err != nil { - return err +func CommandLimit(appName string, processType string, r Resource) error { + if appName == "" { + return errors.New("Please specify an app to run the command on") } return setResourceType(appName, processType, r, "limit") } // CommandLimitClear implements resource:limit-clear -func CommandLimitClear(args []string, processType string) error { - appName, err := getAppName(args) - if err != nil { - return err +func CommandLimitClear(appName string, processType string) error { + if appName == "" { + return errors.New("Please specify an app to run the command on") } clearByResourceType(appName, processType, "limit") @@ -52,145 +50,20 @@ func CommandReport(appName string, infoFlag string) error { } // CommandReserve implements resource:reserve -func CommandReserve(args []string, processType string, r Resource) error { - appName, err := getAppName(args) - if err != nil { - return err +func CommandReserve(appName string, processType string, r Resource) error { + if appName == "" { + return errors.New("Please specify an app to run the command on") } return setResourceType(appName, processType, r, "reserve") } // CommandReserveClear implements resource:reserve-clear -func CommandReserveClear(args []string, processType string) error { - appName, err := getAppName(args) - if err != nil { - return err +func CommandReserveClear(appName string, processType string) error { + if appName == "" { + return errors.New("Please specify an app to run the command on") } clearByResourceType(appName, processType, "reserve") return nil } - -func clearByResourceType(appName string, processType string, resourceType string) { - noun := "limits" - if resourceType == "reserve" { - noun = "reservation" - } - - message := fmt.Sprintf("clearing %v %v", appName, noun) - if processType != "_default_" && processType != "" { - message = fmt.Sprintf("%v (%v)", message, processType) - } - common.LogInfo2Quiet(message) - - if processType == "" { - resources, err := common.PropertyGetAll("resource", appName) - if err != nil { - return - } - for key := range resources { - common.PropertyDelete("resource", appName, key) - } - } else { - resources := []string{ - "cpu", - "memory", - "memory-swap", - "network", - "network-ingress", - "network-egress", - "nvidia-gpu", - } - - for _, key := range resources { - property := propertyKey(processType, resourceType, key) - common.PropertyDelete("resource", appName, property) - } - } -} - -func setResourceType(appName string, processType string, r Resource, resourceType string) error { - if len(processType) == 0 { - processType = "_default_" - } - - resources := map[string]string{ - "cpu": r.CPU, - "memory": r.Memory, - "memory-swap": r.MemorySwap, - "network": r.Network, - "network-ingress": r.NetworkIngress, - "network-egress": r.NetworkEgress, - "nvidia-gpu": r.NvidiaGPU, - } - - hasValues := false - for _, value := range resources { - if value != "" { - hasValues = true - } - } - - if !hasValues { - reportResourceType(appName, processType, resourceType) - return nil - } - - noun := "limits" - if resourceType == "reserve" { - noun = "reservation" - } - message := fmt.Sprintf("Setting resource %v for %v", noun, appName) - if processType != "_default_" { - message = fmt.Sprintf("%v (%v)", message, processType) - } - common.LogInfo2Quiet(message) - - for key, value := range resources { - if value == "" { - continue - } - - common.LogVerbose(fmt.Sprintf("%v: %v", key, value)) - property := propertyKey(processType, resourceType, key) - err := common.PropertyWrite("resource", appName, property, value) - if err != nil { - return err - } - } - - return nil -} - -func reportResourceType(appName string, processType string, resourceType string) { - noun := "limits" - if resourceType == "reserve" { - noun = "reservation" - } - - message := fmt.Sprintf("resource %v %v information", noun, appName) - if processType == "_default_" { - message = fmt.Sprintf("%v [defaults]", message) - } else { - message = fmt.Sprintf("%v (%v)", message, processType) - } - common.LogInfo2Quiet(message) - - resources := []string{ - "cpu", - "memory", - "memory-swap", - "network", - "network-ingress", - "network-egress", - "nvidia-gpu", - } - - for _, key := range resources { - property := propertyKey(processType, resourceType, key) - value := common.PropertyGet("resource", appName, property) - common.LogVerbose(fmt.Sprintf("%v: %v", key, value)) - } - return -}