Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push and scale app log rate limit #2301

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions actor/v7action/space_quota.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func (actor Actor) CreateSpaceQuota(spaceQuotaName string, orgGuid string, limit
TotalMemory: limits.TotalMemoryInMB,
InstanceMemory: limits.PerProcessMemoryInMB,
TotalAppInstances: limits.TotalInstances,
TotalLogVolume: limits.TotalLogVolume,
},
Services: resources.ServiceLimit{
TotalServiceInstances: limits.TotalServiceInstances,
Expand Down Expand Up @@ -137,6 +138,7 @@ func (actor Actor) UpdateSpaceQuota(currentName, orgGUID, newName string, limits
TotalMemory: limits.TotalMemoryInMB,
InstanceMemory: limits.PerProcessMemoryInMB,
TotalAppInstances: limits.TotalInstances,
TotalLogVolume: limits.TotalLogVolume,
},
Services: resources.ServiceLimit{
TotalServiceInstances: limits.TotalServiceInstances,
Expand Down
11 changes: 11 additions & 0 deletions actor/v7action/space_quota_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalServiceInstances: &types.NullInt{IsSet: true, Value: 6},
TotalRoutes: &types.NullInt{IsSet: true, Value: 8},
TotalReservedPorts: &types.NullInt{IsSet: true, Value: 9},
TotalLogVolume: &types.NullInt{IsSet: true, Value: 10},
}
})

Expand All @@ -167,6 +168,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalMemory: &types.NullInt{IsSet: true, Value: 2},
InstanceMemory: &types.NullInt{IsSet: true, Value: 3},
TotalAppInstances: &types.NullInt{IsSet: true, Value: 4},
TotalLogVolume: &types.NullInt{IsSet: true, Value: 10},
},
Services: resources.ServiceLimit{
TotalServiceInstances: &types.NullInt{IsSet: true, Value: 6},
Expand Down Expand Up @@ -201,6 +203,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalMemory: &types.NullInt{Value: 0, IsSet: true},
InstanceMemory: nil,
TotalAppInstances: nil,
TotalLogVolume: nil,
},
Services: resources.ServiceLimit{
TotalServiceInstances: &types.NullInt{Value: 0, IsSet: true},
Expand Down Expand Up @@ -244,6 +247,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalServiceInstances: &types.NullInt{Value: -1, IsSet: true},
TotalRoutes: &types.NullInt{Value: -1, IsSet: true},
TotalReservedPorts: &types.NullInt{Value: -1, IsSet: true},
TotalLogVolume: &types.NullInt{Value: -1, IsSet: true},
}
ccv3Quota = resources.SpaceQuota{
Quota: resources.Quota{
Expand All @@ -252,6 +256,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalMemory: &types.NullInt{Value: 0, IsSet: false},
InstanceMemory: &types.NullInt{Value: 0, IsSet: false},
TotalAppInstances: &types.NullInt{Value: 0, IsSet: false},
TotalLogVolume: &types.NullInt{Value: 0, IsSet: false},
},
Services: resources.ServiceLimit{
TotalServiceInstances: &types.NullInt{Value: 0, IsSet: false},
Expand Down Expand Up @@ -607,6 +612,7 @@ var _ = Describe("Space Quota Actions", func() {
PaidServicesAllowed: &trueValue,
TotalRoutes: &types.NullInt{Value: 6, IsSet: true},
TotalReservedPorts: &types.NullInt{Value: 5, IsSet: true},
TotalLogVolume: &types.NullInt{Value: 512, IsSet: true},
}

fakeCloudControllerClient.GetSpaceQuotasReturns(
Expand Down Expand Up @@ -652,6 +658,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalMemory: nil,
InstanceMemory: nil,
TotalAppInstances: nil,
TotalLogVolume: nil,
},
Services: resources.ServiceLimit{
TotalServiceInstances: nil,
Expand Down Expand Up @@ -699,6 +706,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalServiceInstances: &types.NullInt{Value: -1, IsSet: true},
TotalRoutes: &types.NullInt{Value: -1, IsSet: true},
TotalReservedPorts: &types.NullInt{Value: -1, IsSet: true},
TotalLogVolume: &types.NullInt{Value: -1, IsSet: true},
}

ccv3Quota = resources.SpaceQuota{
Expand All @@ -708,6 +716,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalMemory: &types.NullInt{Value: 0, IsSet: false},
InstanceMemory: &types.NullInt{Value: 0, IsSet: false},
TotalAppInstances: &types.NullInt{Value: 0, IsSet: false},
TotalLogVolume: &types.NullInt{Value: 0, IsSet: false},
},
Services: resources.ServiceLimit{
TotalServiceInstances: &types.NullInt{Value: 0, IsSet: false},
Expand Down Expand Up @@ -754,6 +763,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalMemory: &types.NullInt{Value: 2048, IsSet: true},
InstanceMemory: &types.NullInt{Value: 1024, IsSet: true},
TotalAppInstances: &types.NullInt{Value: 0, IsSet: false},
TotalLogVolume: &types.NullInt{Value: 512, IsSet: true},
},
Services: resources.ServiceLimit{
TotalServiceInstances: &types.NullInt{Value: 0, IsSet: true},
Expand Down Expand Up @@ -802,6 +812,7 @@ var _ = Describe("Space Quota Actions", func() {
TotalMemory: &types.NullInt{Value: 2048, IsSet: true},
InstanceMemory: &types.NullInt{Value: 1024, IsSet: true},
TotalAppInstances: &types.NullInt{Value: 0, IsSet: false},
TotalLogVolume: &types.NullInt{Value: 512, IsSet: true},
},
Services: resources.ServiceLimit{
TotalServiceInstances: &types.NullInt{Value: 0, IsSet: true},
Expand Down
1 change: 1 addition & 0 deletions actor/v7pushaction/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func NewActor(v3Actor V7Actor, sharedActor SharedActor) *Actor {
HandleHealthCheckTimeoutOverride,
HandleMemoryOverride,
HandleDiskOverride,
HandleLogRateLimitOverride,
HandleNoRouteOverride,
HandleRandomRouteOverride,
HandleTaskOverride,
Expand Down
24 changes: 24 additions & 0 deletions actor/v7pushaction/handle_log_rate_limit_override.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package v7pushaction

import (
"code.cloudfoundry.org/cli/command/translatableerror"
"code.cloudfoundry.org/cli/util/manifestparser"
)

func HandleLogRateLimitOverride(manifest manifestparser.Manifest, overrides FlagOverrides) (manifestparser.Manifest, error) {
if overrides.LogRateLimit != "" {
if manifest.ContainsMultipleApps() {
return manifest, translatableerror.CommandLineArgsWithMultipleAppsError{}
}

webProcess := manifest.GetFirstAppWebProcess()
if webProcess != nil {
webProcess.LogRateLimit = overrides.LogRateLimit
} else {
app := manifest.GetFirstApp()
app.LogRateLimit = overrides.LogRateLimit
}
}

return manifest, nil
}
149 changes: 149 additions & 0 deletions actor/v7pushaction/handle_log_rate_limit_override_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package v7pushaction_test

import (
"code.cloudfoundry.org/cli/command/translatableerror"
"code.cloudfoundry.org/cli/util/manifestparser"

. "code.cloudfoundry.org/cli/actor/v7pushaction"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("HandleLogRateLimitOverride", func() {
var (
originalManifest manifestparser.Manifest
transformedManifest manifestparser.Manifest
overrides FlagOverrides
executeErr error
)

BeforeEach(func() {
originalManifest = manifestparser.Manifest{}
overrides = FlagOverrides{}
})

JustBeforeEach(func() {
transformedManifest, executeErr = HandleLogRateLimitOverride(originalManifest, overrides)
})

When("log rate limit is not set on a flag override", func() {
BeforeEach(func() {
originalManifest.Applications = []manifestparser.Application{
{
Processes: []manifestparser.Process{
{Type: "web"},
{Type: "worker", LogRateLimit: "1B"},
},
},
}
})

It("does not change the manifest", func() {
Expect(executeErr).ToNot(HaveOccurred())
Expect(transformedManifest.Applications).To(ConsistOf(
manifestparser.Application{
Processes: []manifestparser.Process{
{Type: "web"},
{Type: "worker", LogRateLimit: "1B"},
},
},
))
})
})

When("manifest web process does not specify log rate limit", func() {
BeforeEach(func() {
overrides.LogRateLimit = "64K"

originalManifest.Applications = []manifestparser.Application{
{
Processes: []manifestparser.Process{
{Type: "web"},
},
},
}
})

It("changes the log rate limit of the web process in the manifest", func() {
Expect(executeErr).ToNot(HaveOccurred())
Expect(transformedManifest.Applications).To(ConsistOf(
manifestparser.Application{
Processes: []manifestparser.Process{
{Type: "web", LogRateLimit: "64K"},
},
},
))
})
})

When("manifest app has only non-web processes", func() {
BeforeEach(func() {
overrides.LogRateLimit = "32B"

originalManifest.Applications = []manifestparser.Application{
{
Processes: []manifestparser.Process{
{Type: "worker"},
},
},
}
})

It("changes the log rate limit of the app in the manifest", func() {
Expect(executeErr).ToNot(HaveOccurred())
Expect(transformedManifest.Applications).To(ConsistOf(
manifestparser.Application{
LogRateLimit: "32B",
Processes: []manifestparser.Process{
{Type: "worker"},
},
},
))
})
})

When("manifest app has web and non-web processes", func() {
BeforeEach(func() {
overrides.LogRateLimit = "4MB"

originalManifest.Applications = []manifestparser.Application{
{
Processes: []manifestparser.Process{
{Type: "worker"},
{Type: "web"},
},
LogRateLimit: "1GB",
},
}
})

It("changes the log rate limit of the web process in the manifest", func() {
Expect(executeErr).ToNot(HaveOccurred())
Expect(transformedManifest.Applications).To(ConsistOf(
manifestparser.Application{
Processes: []manifestparser.Process{
{Type: "worker"},
{Type: "web", LogRateLimit: "4MB"},
},
LogRateLimit: "1GB",
},
))
})
})

When("there are multiple apps in the manifest", func() {
BeforeEach(func() {
overrides.LogRateLimit = "64M"

originalManifest.Applications = []manifestparser.Application{
{},
{},
}
})

It("returns an error", func() {
Expect(executeErr).To(MatchError(translatableerror.CommandLineArgsWithMultipleAppsError{}))
})
})
})
1 change: 0 additions & 1 deletion actor/v7pushaction/handle_memory_override.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package v7pushaction

import (
//"code.cloudfoundry.org/cli/command/translatableerror"
"code.cloudfoundry.org/cli/command/translatableerror"
"code.cloudfoundry.org/cli/util/manifestparser"
)
Expand Down
1 change: 1 addition & 0 deletions actor/v7pushaction/push_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type FlagOverrides struct {
Vars []template.VarKV
NoManifest bool
Task bool
LogRateLimit string
}

func (state PushPlan) String() string {
Expand Down
7 changes: 5 additions & 2 deletions command/v7/create_space_quota_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ type CreateSpaceQuotaCommand struct {
TotalRoutes flag.IntegerLimit `short:"r" description:"Total number of routes. -1 represents an unlimited amount. (Default: 0)."`
TotalReservedPorts flag.IntegerLimit `long:"reserved-route-ports" description:"Maximum number of routes that may be created with ports. -1 represents an unlimited amount. (Default: 0)."`
TotalServiceInstances flag.IntegerLimit `short:"s" description:"Total number of service instances. -1 represents an unlimited amount. (Default: 0)."`
usage interface{} `usage:"CF_NAME create-space-quota QUOTA [-m TOTAL_MEMORY] [-i INSTANCE_MEMORY] [-r ROUTES] [-s SERVICE_INSTANCES] [-a APP_INSTANCES] [--allow-paid-service-plans] [--reserved-route-ports RESERVED_ROUTE_PORTS]"`
relatedCommands interface{} `related_commands:"create-space, space-quotas, set-space-quota"`
TotalLogVolume flag.BytesWithUnlimited `short:"l" description:"Total log volume per second all processes can have, in bytes (e.g. 128B, 4K, 1M). -1 represents an unlimited amount. (Default: -1)."`

usage interface{} `usage:"CF_NAME create-space-quota QUOTA [-m TOTAL_MEMORY] [-i INSTANCE_MEMORY] [-r ROUTES] [-s SERVICE_INSTANCES] [-a APP_INSTANCES] [--allow-paid-service-plans] [--reserved-route-ports RESERVED_ROUTE_PORTS] [-l LOG_VOLUME]"`
relatedCommands interface{} `related_commands:"create-space, space-quotas, set-space-quota"`
}

func (cmd CreateSpaceQuotaCommand) Execute([]string) error {
Expand Down Expand Up @@ -49,6 +51,7 @@ func (cmd CreateSpaceQuotaCommand) Execute([]string) error {
TotalServiceInstances: convertIntegerLimitFlagToNullInt(cmd.TotalServiceInstances),
TotalRoutes: convertIntegerLimitFlagToNullInt(cmd.TotalRoutes),
TotalReservedPorts: convertIntegerLimitFlagToNullInt(cmd.TotalReservedPorts),
TotalLogVolume: convertBytesFlagToNullInt(cmd.TotalLogVolume),
},
)

Expand Down
2 changes: 2 additions & 0 deletions command/v7/create_space_quota_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ var _ = Describe("create-space-quota Command", func() {
cmd.TotalServiceInstances = flag.IntegerLimit{IsSet: true, Value: 9}
cmd.TotalRoutes = flag.IntegerLimit{IsSet: true, Value: 1}
cmd.TotalReservedPorts = flag.IntegerLimit{IsSet: true, Value: 7}
cmd.TotalLogVolume = flag.BytesWithUnlimited{IsSet: true, Value: 512}

fakeActor.CreateSpaceQuotaReturns(
v7action.Warnings{"warnings-1", "warnings-2"},
Expand All @@ -163,6 +164,7 @@ var _ = Describe("create-space-quota Command", func() {
TotalServiceInstances: &types.NullInt{IsSet: true, Value: 9},
TotalRoutes: &types.NullInt{IsSet: true, Value: 1},
TotalReservedPorts: &types.NullInt{IsSet: true, Value: 7},
TotalLogVolume: &types.NullInt{IsSet: true, Value: 512},
}))
})

Expand Down
4 changes: 3 additions & 1 deletion command/v7/push_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ type PushCommand struct {
StartCommand flag.Command `long:"start-command" short:"c" description:"Startup command, set to null to reset to default start command"`
Strategy flag.DeploymentStrategy `long:"strategy" description:"Deployment strategy, either rolling or null."`
Task bool `long:"task" description:"Push an app that is used only to execute tasks. The app will be staged, but not started and will have no route assigned."`
LogRateLimit string `long:"log-rate-limit" short:"l" description:"Log rate limit per second, in bytes (e.g. 128B, 4K, 1M). -1 represents unlimited."`
Vars []template.VarKV `long:"var" description:"Variable key value pair for variable substitution, (e.g., name=app1); can specify multiple times"`
PathsToVarsFiles []flag.PathWithExistenceCheck `long:"vars-file" description:"Path to a variable substitution file for manifest; can specify multiple times"`
dockerPassword interface{} `environmentName:"CF_DOCKER_PASSWORD" environmentDescription:"Password used for private docker repository"`
usage interface{} `usage:"CF_NAME push APP_NAME [-b BUILDPACK_NAME]\n [-c COMMAND] [-f MANIFEST_PATH | --no-manifest] [--no-start] [--no-wait] [-i NUM_INSTANCES]\n [-k DISK] [-m MEMORY] [-p PATH] [-s STACK] [-t HEALTH_TIMEOUT] [--task TASK]\n [-u (process | port | http)] [--no-route | --random-route]\n [--var KEY=VALUE] [--vars-file VARS_FILE_PATH]...\n \n CF_NAME push APP_NAME --docker-image [REGISTRY_HOST:PORT/]IMAGE[:TAG] [--docker-username USERNAME]\n [-c COMMAND] [-f MANIFEST_PATH | --no-manifest] [--no-start] [--no-wait] [-i NUM_INSTANCES]\n [-k DISK] [-m MEMORY] [-p PATH] [-s STACK] [-t HEALTH_TIMEOUT] [--task TASK]\n [-u (process | port | http)] [--no-route | --random-route ]\n [--var KEY=VALUE] [--vars-file VARS_FILE_PATH]..."`
usage interface{} `usage:"CF_NAME push APP_NAME [-b BUILDPACK_NAME]\n [-c COMMAND] [-f MANIFEST_PATH | --no-manifest] [--no-start] [--no-wait] [-i NUM_INSTANCES]\n [-k DISK] [-m MEMORY] [-p PATH] [-s STACK] [-t HEALTH_TIMEOUT] [--task TASK]\n [-u (process | port | http)] [--no-route | --random-route] [-l LOG_RATE_LIMIT]\n [--var KEY=VALUE] [--vars-file VARS_FILE_PATH]...\n \n CF_NAME push APP_NAME --docker-image [REGISTRY_HOST:PORT/]IMAGE[:TAG] [--docker-username USERNAME]\n [-c COMMAND] [-f MANIFEST_PATH | --no-manifest] [--no-start] [--no-wait] [-i NUM_INSTANCES]\n [-k DISK] [-m MEMORY] [-p PATH] [-s STACK] [-t HEALTH_TIMEOUT] [--task TASK]\n [-u (process | port | http)] [--no-route | --random-route ] [-l LOG_RATE_LIMIT]\n [--var KEY=VALUE] [--vars-file VARS_FILE_PATH]..."`
envCFStagingTimeout interface{} `environmentName:"CF_STAGING_TIMEOUT" environmentDescription:"Max wait time for staging, in minutes" environmentDefault:"15"`
envCFStartupTimeout interface{} `environmentName:"CF_STARTUP_TIMEOUT" environmentDescription:"Max wait time for app instance startup, in minutes" environmentDefault:"5"`

Expand Down Expand Up @@ -358,6 +359,7 @@ func (cmd PushCommand) GetFlagOverrides() (v7pushaction.FlagOverrides, error) {
Vars: cmd.Vars,
NoManifest: cmd.NoManifest,
Task: cmd.Task,
LogRateLimit: cmd.LogRateLimit,
}, nil
}

Expand Down
4 changes: 3 additions & 1 deletion command/v7/push_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ var _ = Describe("push Command", func() {
})
})

When("marsahlling the manifest succeeds", func() {
When("marshalling the manifest succeeds", func() {
BeforeEach(func() {
fakeManifestParser.MarshalManifestReturns([]byte("our-manifest"), nil)
})
Expand Down Expand Up @@ -1078,6 +1078,7 @@ var _ = Describe("push Command", func() {
cmd.PathsToVarsFiles = []flag.PathWithExistenceCheck{"/vars1", "/vars2"}
cmd.Vars = []template.VarKV{{Name: "key", Value: "val"}}
cmd.Task = true
cmd.LogRateLimit = "512M"
})

JustBeforeEach(func() {
Expand Down Expand Up @@ -1106,6 +1107,7 @@ var _ = Describe("push Command", func() {
Expect(overrides.PathsToVarsFiles).To(Equal([]string{"/vars1", "/vars2"}))
Expect(overrides.Vars).To(Equal([]template.VarKV{{Name: "key", Value: "val"}}))
Expect(overrides.Task).To(BeTrue())
Expect(overrides.LogRateLimit).To(Equal("512M"))
})

When("a docker image is provided", func() {
Expand Down
Loading