package resource import ( "fmt" "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 } 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 } clearByResourceType(appName, processType, "limit") return nil } // CommandReport displays a resource report for one or more apps func CommandReport(appName string, infoFlag string) error { if strings.HasPrefix(appName, "--") { infoFlag = appName appName = "" } if len(appName) == 0 { apps, err := common.DokkuApps() if err != nil { return err } for _, appName := range apps { if err := ReportSingleApp(appName, infoFlag); err != nil { return err } } return nil } return ReportSingleApp(appName, infoFlag) } // CommandReserve implements resource:reserve func CommandReserve(args []string, processType string, r Resource) error { appName, err := getAppName(args) if err != nil { return err } 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 } 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", } 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, } 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", } for _, key := range resources { property := propertyKey(processType, resourceType, key) value := common.PropertyGet("resource", appName, property) common.LogVerbose(fmt.Sprintf("%v: %v", key, value)) } return }