mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
Rework of resource consumer.
Major rework of resource consumer: added controller running as a pod that spreads requests around consumers. This should fix #21664 and #23536.
This commit is contained in:
parent
2976e892a4
commit
967a7c95d2
@ -70,6 +70,9 @@ configure-cbr0
|
|||||||
configure-cloud-routes
|
configure-cloud-routes
|
||||||
conntrack-max
|
conntrack-max
|
||||||
conntrack-tcp-timeout-established
|
conntrack-tcp-timeout-established
|
||||||
|
consumer-port
|
||||||
|
consumer-service-name
|
||||||
|
consumer-service-namespace
|
||||||
contain-pod-resources
|
contain-pod-resources
|
||||||
container-port
|
container-port
|
||||||
container-runtime
|
container-runtime
|
||||||
@ -463,3 +466,4 @@ watch-only
|
|||||||
whitelist-override-label
|
whitelist-override-label
|
||||||
windows-line-endings
|
windows-line-endings
|
||||||
www-prefix
|
www-prefix
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ const (
|
|||||||
timeoutRC = 120 * time.Second
|
timeoutRC = 120 * time.Second
|
||||||
startServiceTimeout = time.Minute
|
startServiceTimeout = time.Minute
|
||||||
startServiceInterval = 5 * time.Second
|
startServiceInterval = 5 * time.Second
|
||||||
resourceConsumerImage = "gcr.io/google_containers/resource_consumer:beta2"
|
resourceConsumerImage = "gcr.io/google_containers/resource_consumer:beta4"
|
||||||
|
resourceConsumerControllerImage = "gcr.io/google_containers/resource_consumer/controller:beta4"
|
||||||
rcIsNil = "ERROR: replicationController = nil"
|
rcIsNil = "ERROR: replicationController = nil"
|
||||||
deploymentIsNil = "ERROR: deployment = nil"
|
deploymentIsNil = "ERROR: deployment = nil"
|
||||||
rsIsNil = "ERROR: replicaset = nil"
|
rsIsNil = "ERROR: replicaset = nil"
|
||||||
@ -58,6 +59,7 @@ rc.ConsumeCPU(300)
|
|||||||
*/
|
*/
|
||||||
type ResourceConsumer struct {
|
type ResourceConsumer struct {
|
||||||
name string
|
name string
|
||||||
|
controllerName string
|
||||||
kind string
|
kind string
|
||||||
framework *framework.Framework
|
framework *framework.Framework
|
||||||
cpu chan int
|
cpu chan int
|
||||||
@ -97,6 +99,7 @@ func newResourceConsumer(name, kind string, replicas, initCPUTotal, initMemoryTo
|
|||||||
runServiceAndWorkloadForResourceConsumer(f.Client, f.Namespace.Name, name, kind, replicas, cpuLimit, memLimit)
|
runServiceAndWorkloadForResourceConsumer(f.Client, f.Namespace.Name, name, kind, replicas, cpuLimit, memLimit)
|
||||||
rc := &ResourceConsumer{
|
rc := &ResourceConsumer{
|
||||||
name: name,
|
name: name,
|
||||||
|
controllerName: name + "-controller",
|
||||||
kind: kind,
|
kind: kind,
|
||||||
framework: f,
|
framework: f,
|
||||||
cpu: make(chan int),
|
cpu: make(chan int),
|
||||||
@ -111,8 +114,10 @@ func newResourceConsumer(name, kind string, replicas, initCPUTotal, initMemoryTo
|
|||||||
requestSizeInMegabytes: requestSizeInMegabytes,
|
requestSizeInMegabytes: requestSizeInMegabytes,
|
||||||
requestSizeCustomMetric: requestSizeCustomMetric,
|
requestSizeCustomMetric: requestSizeCustomMetric,
|
||||||
}
|
}
|
||||||
|
|
||||||
go rc.makeConsumeCPURequests()
|
go rc.makeConsumeCPURequests()
|
||||||
rc.ConsumeCPU(initCPUTotal)
|
rc.ConsumeCPU(initCPUTotal)
|
||||||
|
|
||||||
go rc.makeConsumeMemRequests()
|
go rc.makeConsumeMemRequests()
|
||||||
rc.ConsumeMem(initMemoryTotal)
|
rc.ConsumeMem(initMemoryTotal)
|
||||||
go rc.makeConsumeCustomMetric()
|
go rc.makeConsumeCustomMetric()
|
||||||
@ -140,25 +145,15 @@ func (rc *ResourceConsumer) ConsumeCustomMetric(amount int) {
|
|||||||
|
|
||||||
func (rc *ResourceConsumer) makeConsumeCPURequests() {
|
func (rc *ResourceConsumer) makeConsumeCPURequests() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
var count int
|
|
||||||
var rest int
|
|
||||||
sleepTime := time.Duration(0)
|
sleepTime := time.Duration(0)
|
||||||
|
millicores := 0
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case millicores := <-rc.cpu:
|
case millicores = <-rc.cpu:
|
||||||
framework.Logf("RC %s: consume %v millicores in total", rc.name, millicores)
|
framework.Logf("RC %s: setting consumption to %v millicores in total", rc.name, millicores)
|
||||||
if rc.requestSizeInMillicores != 0 {
|
|
||||||
count = millicores / rc.requestSizeInMillicores
|
|
||||||
}
|
|
||||||
rest = millicores - count*rc.requestSizeInMillicores
|
|
||||||
case <-time.After(sleepTime):
|
case <-time.After(sleepTime):
|
||||||
framework.Logf("RC %s: sending %v requests to consume %v millicores each and 1 request to consume %v millicores", rc.name, count, rc.requestSizeInMillicores, rest)
|
framework.Logf("RC %s: sending request to consume %d millicores", rc.name, millicores)
|
||||||
if count > 0 {
|
rc.sendConsumeCPURequest(millicores)
|
||||||
rc.sendConsumeCPURequests(count, rc.requestSizeInMillicores, rc.consumptionTimeInSeconds)
|
|
||||||
}
|
|
||||||
if rest > 0 {
|
|
||||||
go rc.sendOneConsumeCPURequest(rest, rc.consumptionTimeInSeconds)
|
|
||||||
}
|
|
||||||
sleepTime = rc.sleepTime
|
sleepTime = rc.sleepTime
|
||||||
case <-rc.stopCPU:
|
case <-rc.stopCPU:
|
||||||
return
|
return
|
||||||
@ -168,25 +163,15 @@ func (rc *ResourceConsumer) makeConsumeCPURequests() {
|
|||||||
|
|
||||||
func (rc *ResourceConsumer) makeConsumeMemRequests() {
|
func (rc *ResourceConsumer) makeConsumeMemRequests() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
var count int
|
|
||||||
var rest int
|
|
||||||
sleepTime := time.Duration(0)
|
sleepTime := time.Duration(0)
|
||||||
|
megabytes := 0
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case megabytes := <-rc.mem:
|
case megabytes = <-rc.mem:
|
||||||
framework.Logf("RC %s: consume %v MB in total", rc.name, megabytes)
|
framework.Logf("RC %s: setting consumption to %v MB in total", rc.name, megabytes)
|
||||||
if rc.requestSizeInMegabytes != 0 {
|
|
||||||
count = megabytes / rc.requestSizeInMegabytes
|
|
||||||
}
|
|
||||||
rest = megabytes - count*rc.requestSizeInMegabytes
|
|
||||||
case <-time.After(sleepTime):
|
case <-time.After(sleepTime):
|
||||||
framework.Logf("RC %s: sending %v requests to consume %v MB each and 1 request to consume %v MB", rc.name, count, rc.requestSizeInMegabytes, rest)
|
framework.Logf("RC %s: sending request to consume %d MB", rc.name, megabytes)
|
||||||
if count > 0 {
|
rc.sendConsumeMemRequest(megabytes)
|
||||||
rc.sendConsumeMemRequests(count, rc.requestSizeInMegabytes, rc.consumptionTimeInSeconds)
|
|
||||||
}
|
|
||||||
if rest > 0 {
|
|
||||||
go rc.sendOneConsumeMemRequest(rest, rc.consumptionTimeInSeconds)
|
|
||||||
}
|
|
||||||
sleepTime = rc.sleepTime
|
sleepTime = rc.sleepTime
|
||||||
case <-rc.stopMem:
|
case <-rc.stopMem:
|
||||||
return
|
return
|
||||||
@ -196,26 +181,15 @@ func (rc *ResourceConsumer) makeConsumeMemRequests() {
|
|||||||
|
|
||||||
func (rc *ResourceConsumer) makeConsumeCustomMetric() {
|
func (rc *ResourceConsumer) makeConsumeCustomMetric() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
var count int
|
|
||||||
var rest int
|
|
||||||
sleepTime := time.Duration(0)
|
sleepTime := time.Duration(0)
|
||||||
|
delta := 0
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case total := <-rc.customMetric:
|
case delta := <-rc.customMetric:
|
||||||
framework.Logf("RC %s: consume custom metric %v in total", rc.name, total)
|
framework.Logf("RC %s: setting bump of metric %s to %d in total", rc.name, customMetricName, delta)
|
||||||
if rc.requestSizeInMegabytes != 0 {
|
|
||||||
count = total / rc.requestSizeCustomMetric
|
|
||||||
}
|
|
||||||
rest = total - count*rc.requestSizeCustomMetric
|
|
||||||
case <-time.After(sleepTime):
|
case <-time.After(sleepTime):
|
||||||
framework.Logf("RC %s: sending %v requests to consume %v custom metric each and 1 request to consume %v",
|
framework.Logf("RC %s: sending request to consume %d of custom metric %s", rc.name, delta, customMetricName)
|
||||||
rc.name, count, rc.requestSizeCustomMetric, rest)
|
rc.sendConsumeCustomMetric(delta)
|
||||||
if count > 0 {
|
|
||||||
rc.sendConsumeCustomMetric(count, rc.requestSizeCustomMetric, rc.consumptionTimeInSeconds)
|
|
||||||
}
|
|
||||||
if rest > 0 {
|
|
||||||
go rc.sendOneConsumeCustomMetric(rest, rc.consumptionTimeInSeconds)
|
|
||||||
}
|
|
||||||
sleepTime = rc.sleepTime
|
sleepTime = rc.sleepTime
|
||||||
case <-rc.stopCustomMetric:
|
case <-rc.stopCustomMetric:
|
||||||
return
|
return
|
||||||
@ -223,64 +197,48 @@ func (rc *ResourceConsumer) makeConsumeCustomMetric() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *ResourceConsumer) sendConsumeCPURequests(requests, millicores, durationSec int) {
|
func (rc *ResourceConsumer) sendConsumeCPURequest(millicores int) {
|
||||||
for i := 0; i < requests; i++ {
|
|
||||||
go rc.sendOneConsumeCPURequest(millicores, durationSec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *ResourceConsumer) sendConsumeMemRequests(requests, megabytes, durationSec int) {
|
|
||||||
for i := 0; i < requests; i++ {
|
|
||||||
go rc.sendOneConsumeMemRequest(megabytes, durationSec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *ResourceConsumer) sendConsumeCustomMetric(requests, delta, durationSec int) {
|
|
||||||
for i := 0; i < requests; i++ {
|
|
||||||
go rc.sendOneConsumeCustomMetric(delta, durationSec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sendOneConsumeCPURequest sends POST request for cpu consumption
|
|
||||||
func (rc *ResourceConsumer) sendOneConsumeCPURequest(millicores int, durationSec int) {
|
|
||||||
defer GinkgoRecover()
|
|
||||||
proxyRequest, err := framework.GetServicesProxyRequest(rc.framework.Client, rc.framework.Client.Post())
|
proxyRequest, err := framework.GetServicesProxyRequest(rc.framework.Client, rc.framework.Client.Post())
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
_, err = proxyRequest.Namespace(rc.framework.Namespace.Name).
|
req := proxyRequest.Namespace(rc.framework.Namespace.Name).
|
||||||
Name(rc.name).
|
Name(rc.controllerName).
|
||||||
Suffix("ConsumeCPU").
|
Suffix("ConsumeCPU").
|
||||||
Param("millicores", strconv.Itoa(millicores)).
|
Param("millicores", strconv.Itoa(millicores)).
|
||||||
Param("durationSec", strconv.Itoa(durationSec)).
|
Param("durationSec", strconv.Itoa(rc.consumptionTimeInSeconds)).
|
||||||
DoRaw()
|
Param("requestSizeMillicores", strconv.Itoa(rc.requestSizeInMillicores))
|
||||||
|
framework.Logf("URL: %v", *req.URL())
|
||||||
|
_, err = req.DoRaw()
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendOneConsumeMemRequest sends POST request for memory consumption
|
// sendConsumeMemRequest sends POST request for memory consumption
|
||||||
func (rc *ResourceConsumer) sendOneConsumeMemRequest(megabytes int, durationSec int) {
|
func (rc *ResourceConsumer) sendConsumeMemRequest(megabytes int) {
|
||||||
defer GinkgoRecover()
|
|
||||||
proxyRequest, err := framework.GetServicesProxyRequest(rc.framework.Client, rc.framework.Client.Post())
|
proxyRequest, err := framework.GetServicesProxyRequest(rc.framework.Client, rc.framework.Client.Post())
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
_, err = proxyRequest.Namespace(rc.framework.Namespace.Name).
|
req := proxyRequest.Namespace(rc.framework.Namespace.Name).
|
||||||
Name(rc.name).
|
Name(rc.controllerName).
|
||||||
Suffix("ConsumeMem").
|
Suffix("ConsumeMem").
|
||||||
Param("megabytes", strconv.Itoa(megabytes)).
|
Param("megabytes", strconv.Itoa(megabytes)).
|
||||||
Param("durationSec", strconv.Itoa(durationSec)).
|
Param("durationSec", strconv.Itoa(rc.consumptionTimeInSeconds)).
|
||||||
DoRaw()
|
Param("requestSizeMegabytes", strconv.Itoa(rc.requestSizeInMegabytes))
|
||||||
|
framework.Logf("URL: %v", *req.URL())
|
||||||
|
_, err = req.DoRaw()
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendOneConsumeCustomMetric sends POST request for custom metric consumption
|
// sendConsumeCustomMetric sends POST request for custom metric consumption
|
||||||
func (rc *ResourceConsumer) sendOneConsumeCustomMetric(delta int, durationSec int) {
|
func (rc *ResourceConsumer) sendConsumeCustomMetric(delta int) {
|
||||||
defer GinkgoRecover()
|
|
||||||
proxyRequest, err := framework.GetServicesProxyRequest(rc.framework.Client, rc.framework.Client.Post())
|
proxyRequest, err := framework.GetServicesProxyRequest(rc.framework.Client, rc.framework.Client.Post())
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
_, err = proxyRequest.Namespace(rc.framework.Namespace.Name).
|
req := proxyRequest.Namespace(rc.framework.Namespace.Name).
|
||||||
Name(rc.name).
|
Name(rc.controllerName).
|
||||||
Suffix("BumpMetric").
|
Suffix("BumpMetric").
|
||||||
Param("metric", customMetricName).
|
Param("metric", customMetricName).
|
||||||
Param("delta", strconv.Itoa(delta)).
|
Param("delta", strconv.Itoa(delta)).
|
||||||
Param("durationSec", strconv.Itoa(durationSec)).
|
Param("durationSec", strconv.Itoa(rc.consumptionTimeInSeconds)).
|
||||||
DoRaw()
|
Param("requestSizeMetrics", strconv.Itoa(rc.requestSizeCustomMetric))
|
||||||
|
framework.Logf("URL: %v", *req.URL())
|
||||||
|
_, err = req.DoRaw()
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,6 +304,8 @@ func (rc *ResourceConsumer) CleanUp() {
|
|||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
framework.ExpectNoError(framework.DeleteRC(rc.framework.Client, rc.framework.Namespace.Name, rc.name))
|
framework.ExpectNoError(framework.DeleteRC(rc.framework.Client, rc.framework.Namespace.Name, rc.name))
|
||||||
framework.ExpectNoError(rc.framework.Client.Services(rc.framework.Namespace.Name).Delete(rc.name))
|
framework.ExpectNoError(rc.framework.Client.Services(rc.framework.Namespace.Name).Delete(rc.name))
|
||||||
|
framework.ExpectNoError(framework.DeleteRC(rc.framework.Client, rc.framework.Namespace.Name, rc.controllerName))
|
||||||
|
framework.ExpectNoError(rc.framework.Client.Services(rc.framework.Namespace.Name).Delete(rc.controllerName))
|
||||||
}
|
}
|
||||||
|
|
||||||
func runServiceAndWorkloadForResourceConsumer(c *client.Client, ns, name, kind string, replicas int, cpuLimitMillis, memLimitMb int64) {
|
func runServiceAndWorkloadForResourceConsumer(c *client.Client, ns, name, kind string, replicas int, cpuLimitMillis, memLimitMb int64) {
|
||||||
@ -400,6 +360,38 @@ func runServiceAndWorkloadForResourceConsumer(c *client.Client, ns, name, kind s
|
|||||||
framework.Failf(invalidKind)
|
framework.Failf(invalidKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
By(fmt.Sprintf("Running controller"))
|
||||||
|
controllerName := name + "-controller"
|
||||||
|
_, err = c.Services(ns).Create(&api.Service{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: controllerName,
|
||||||
|
},
|
||||||
|
Spec: api.ServiceSpec{
|
||||||
|
Ports: []api.ServicePort{{
|
||||||
|
Port: port,
|
||||||
|
TargetPort: intstr.FromInt(targetPort),
|
||||||
|
}},
|
||||||
|
|
||||||
|
Selector: map[string]string{
|
||||||
|
"name": controllerName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
dnsClusterFirst := api.DNSClusterFirst
|
||||||
|
controllerRcConfig := framework.RCConfig{
|
||||||
|
Client: c,
|
||||||
|
Image: resourceConsumerControllerImage,
|
||||||
|
Name: controllerName,
|
||||||
|
Namespace: ns,
|
||||||
|
Timeout: timeoutRC,
|
||||||
|
Replicas: 1,
|
||||||
|
Command: []string{"/controller", "--consumer-service-name=" + name, "--consumer-service-namespace=" + ns, "--consumer-port=80"},
|
||||||
|
DNSPolicy: &dnsClusterFirst,
|
||||||
|
}
|
||||||
|
framework.ExpectNoError(framework.RunRC(controllerRcConfig))
|
||||||
|
|
||||||
// Make sure endpoints are propagated.
|
// Make sure endpoints are propagated.
|
||||||
// TODO(piosz): replace sleep with endpoints watch.
|
// TODO(piosz): replace sleep with endpoints watch.
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
|
@ -271,6 +271,7 @@ type RCConfig struct {
|
|||||||
MemRequest int64 // bytes
|
MemRequest int64 // bytes
|
||||||
MemLimit int64 // bytes
|
MemLimit int64 // bytes
|
||||||
ReadinessProbe *api.Probe
|
ReadinessProbe *api.Probe
|
||||||
|
DNSPolicy *api.DNSPolicy
|
||||||
|
|
||||||
// Env vars, set the same for every pod.
|
// Env vars, set the same for every pod.
|
||||||
Env map[string]string
|
Env map[string]string
|
||||||
@ -2181,6 +2182,10 @@ func RunRC(config RCConfig) error {
|
|||||||
|
|
||||||
func (config *RCConfig) create() error {
|
func (config *RCConfig) create() error {
|
||||||
By(fmt.Sprintf("creating replication controller %s in namespace %s", config.Name, config.Namespace))
|
By(fmt.Sprintf("creating replication controller %s in namespace %s", config.Name, config.Namespace))
|
||||||
|
dnsDefault := api.DNSDefault
|
||||||
|
if config.DNSPolicy == nil {
|
||||||
|
config.DNSPolicy = &dnsDefault
|
||||||
|
}
|
||||||
rc := &api.ReplicationController{
|
rc := &api.ReplicationController{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: config.Name,
|
Name: config.Name,
|
||||||
@ -2204,7 +2209,7 @@ func (config *RCConfig) create() error {
|
|||||||
ReadinessProbe: config.ReadinessProbe,
|
ReadinessProbe: config.ReadinessProbe,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
DNSPolicy: api.DNSDefault,
|
DNSPolicy: *config.DNSPolicy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
TAG = beta2
|
TAG = beta4
|
||||||
PREFIX = gcr.io/google_containers
|
PREFIX = gcr.io/google_containers
|
||||||
|
|
||||||
all: clean consumer
|
all: clean consumer
|
||||||
@ -20,18 +20,22 @@ all: clean consumer
|
|||||||
consumer:
|
consumer:
|
||||||
CGO_ENABLED=0 go build -a -installsuffix cgo --ldflags '-w' -o consume-cpu/consume-cpu ./consume-cpu/consume_cpu.go
|
CGO_ENABLED=0 go build -a -installsuffix cgo --ldflags '-w' -o consume-cpu/consume-cpu ./consume-cpu/consume_cpu.go
|
||||||
CGO_ENABLED=0 go build -a -installsuffix cgo --ldflags '-w' -o consumer .
|
CGO_ENABLED=0 go build -a -installsuffix cgo --ldflags '-w' -o consumer .
|
||||||
|
CGO_ENABLED=0 go build -a -installsuffix cgo --ldflags '-w' -o controller/controller ./controller/controller.go
|
||||||
|
|
||||||
container: image
|
container: image
|
||||||
|
|
||||||
image:
|
image:
|
||||||
sudo docker build -t $(PREFIX)/resource_consumer:$(TAG) .
|
sudo docker build -t $(PREFIX)/resource_consumer:$(TAG) .
|
||||||
|
sudo docker build -t $(PREFIX)/resource_consumer/controller:$(TAG) controller
|
||||||
|
|
||||||
run_container:
|
run_container:
|
||||||
docker run --publish=8080:8080 $(PREFIX)/resource_consumer:$(TAG)
|
docker run --publish=8080:8080 $(PREFIX)/resource_consumer:$(TAG)
|
||||||
|
|
||||||
push:
|
push:
|
||||||
@echo "This image is not meant to be pushed."
|
gcloud docker push ${PREFIX}/resource_consumer:${TAG}
|
||||||
|
gcloud docker push ${PREFIX}/resource_consumer/controller:${TAG}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f consumer
|
rm -f consumer
|
||||||
rm -f consume-cpu/consume-cpu
|
rm -f consume-cpu/consume-cpu
|
||||||
|
rm -f controller/controller
|
||||||
|
41
test/images/resource-consumer/common/common.go
Normal file
41
test/images/resource-consumer/common/common.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
const (
|
||||||
|
ConsumeCPUAddress = "/ConsumeCPU"
|
||||||
|
ConsumeMemAddress = "/ConsumeMem"
|
||||||
|
BumpMetricAddress = "/BumpMetric"
|
||||||
|
GetCurrentStatusAddress = "/GetCurrentStatus"
|
||||||
|
MetricsAddress = "/Metrics"
|
||||||
|
|
||||||
|
MillicoresQuery = "millicores"
|
||||||
|
MegabytesQuery = "megabytes"
|
||||||
|
MetricNameQuery = "metric"
|
||||||
|
DeltaQuery = "delta"
|
||||||
|
DurationSecQuery = "durationSec"
|
||||||
|
RequestSizeInMillicoresQuery = "requestSizeMillicores"
|
||||||
|
RequestSizeInMegabytesQuery = "requestSizeMegabytes"
|
||||||
|
RequestSizeCustomMetricQuery = "requestSizeMetrics"
|
||||||
|
|
||||||
|
BadRequest = "Bad request. Not a POST request"
|
||||||
|
UnknownFunction = "unknown function"
|
||||||
|
IncorrectFunctionArgument = "incorrect function argument"
|
||||||
|
NotGivenFunctionArgument = "not given function argument"
|
||||||
|
|
||||||
|
FrameworkName = "horizontal-pod-autoscaling"
|
||||||
|
)
|
19
test/images/resource-consumer/controller/Dockerfile
Normal file
19
test/images/resource-consumer/controller/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
FROM busybox
|
||||||
|
MAINTAINER Jerzy Szczepkowski <jsz@google.com>
|
||||||
|
ADD controller /controller
|
||||||
|
EXPOSE 8080
|
||||||
|
ENTRYPOINT ["/controller"]
|
243
test/images/resource-consumer/controller/controller.go
Normal file
243
test/images/resource-consumer/controller/controller.go
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
. "k8s.io/kubernetes/test/images/resource-consumer/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
var port = flag.Int("port", 8080, "Port number.")
|
||||||
|
var consumerPort = flag.Int("consumer-port", 8080, "Port number of consumers.")
|
||||||
|
var consumerServiceName = flag.String("consumer-service-name", "resource-consumer", "Name of service containing resource consumers.")
|
||||||
|
var consumerServiceNamespace = flag.String("consumer-service-namespace", "default", "Namespace of service containing resource consumers.")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
mgr := NewController()
|
||||||
|
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), mgr))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Controller struct {
|
||||||
|
responseWriterLock sync.Mutex
|
||||||
|
waitGroup sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewController() *Controller {
|
||||||
|
c := &Controller{}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *Controller) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
if req.Method != "POST" {
|
||||||
|
http.Error(w, BadRequest, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// parsing POST request data and URL data
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// handle consumeCPU
|
||||||
|
if req.URL.Path == ConsumeCPUAddress {
|
||||||
|
handler.handleConsumeCPU(w, req.Form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// handle consumeMem
|
||||||
|
if req.URL.Path == ConsumeMemAddress {
|
||||||
|
handler.handleConsumeMem(w, req.Form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// handle bumpMetric
|
||||||
|
if req.URL.Path == BumpMetricAddress {
|
||||||
|
handler.handleBumpMetric(w, req.Form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Error(w, UnknownFunction, http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *Controller) handleConsumeCPU(w http.ResponseWriter, query url.Values) {
|
||||||
|
// geting string data for consumeCPU
|
||||||
|
durationSecString := query.Get(DurationSecQuery)
|
||||||
|
millicoresString := query.Get(MillicoresQuery)
|
||||||
|
requestSizeInMillicoresString := query.Get(RequestSizeInMillicoresQuery)
|
||||||
|
if durationSecString == "" || millicoresString == "" || requestSizeInMillicoresString == "" {
|
||||||
|
http.Error(w, NotGivenFunctionArgument, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert data (strings to ints) for consumeCPU
|
||||||
|
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
||||||
|
millicores, millicoresError := strconv.Atoi(millicoresString)
|
||||||
|
requestSizeInMillicores, requestSizeInMillicoresError := strconv.Atoi(requestSizeInMillicoresString)
|
||||||
|
if durationSecError != nil || millicoresError != nil || requestSizeInMillicoresError != nil || requestSizeInMillicores <= 0 {
|
||||||
|
http.Error(w, IncorrectFunctionArgument, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count := millicores / requestSizeInMillicores
|
||||||
|
rest := millicores - count*requestSizeInMillicores
|
||||||
|
fmt.Fprintf(w, "RC manager: sending %v requests to consume %v millicores each and 1 request to consume %v millicores\n", count, requestSizeInMillicores, rest)
|
||||||
|
if count > 0 {
|
||||||
|
handler.waitGroup.Add(count)
|
||||||
|
handler.sendConsumeCPURequests(w, count, requestSizeInMillicores, durationSec)
|
||||||
|
}
|
||||||
|
if rest > 0 {
|
||||||
|
handler.waitGroup.Add(1)
|
||||||
|
go handler.sendOneConsumeCPURequest(w, rest, durationSec)
|
||||||
|
}
|
||||||
|
handler.waitGroup.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *Controller) handleConsumeMem(w http.ResponseWriter, query url.Values) {
|
||||||
|
// geting string data for consumeMem
|
||||||
|
durationSecString := query.Get(DurationSecQuery)
|
||||||
|
megabytesString := query.Get(MegabytesQuery)
|
||||||
|
requestSizeInMegabytesString := query.Get(RequestSizeInMegabytesQuery)
|
||||||
|
if durationSecString == "" || megabytesString == "" || requestSizeInMegabytesString == "" {
|
||||||
|
http.Error(w, NotGivenFunctionArgument, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert data (strings to ints) for consumeMem
|
||||||
|
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
||||||
|
megabytes, megabytesError := strconv.Atoi(megabytesString)
|
||||||
|
requestSizeInMegabytes, requestSizeInMegabytesError := strconv.Atoi(requestSizeInMegabytesString)
|
||||||
|
if durationSecError != nil || megabytesError != nil || requestSizeInMegabytesError != nil || requestSizeInMegabytes <= 0 {
|
||||||
|
http.Error(w, IncorrectFunctionArgument, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count := megabytes / requestSizeInMegabytes
|
||||||
|
rest := megabytes - count*requestSizeInMegabytes
|
||||||
|
fmt.Fprintf(w, "RC manager: sending %v requests to consume %v MB each and 1 request to consume %v MB\n", count, requestSizeInMegabytes, rest)
|
||||||
|
if count > 0 {
|
||||||
|
handler.waitGroup.Add(count)
|
||||||
|
handler.sendConsumeMemRequests(w, count, requestSizeInMegabytes, durationSec)
|
||||||
|
}
|
||||||
|
if rest > 0 {
|
||||||
|
handler.waitGroup.Add(1)
|
||||||
|
go handler.sendOneConsumeMemRequest(w, rest, durationSec)
|
||||||
|
}
|
||||||
|
handler.waitGroup.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *Controller) handleBumpMetric(w http.ResponseWriter, query url.Values) {
|
||||||
|
// geting string data for handleBumpMetric
|
||||||
|
metric := query.Get(MetricNameQuery)
|
||||||
|
deltaString := query.Get(DeltaQuery)
|
||||||
|
durationSecString := query.Get(DurationSecQuery)
|
||||||
|
requestSizeCustomMetricString := query.Get(RequestSizeCustomMetricQuery)
|
||||||
|
if durationSecString == "" || metric == "" || deltaString == "" || requestSizeCustomMetricString == "" {
|
||||||
|
http.Error(w, NotGivenFunctionArgument, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert data (strings to ints/floats) for handleBumpMetric
|
||||||
|
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
||||||
|
delta, deltaError := strconv.Atoi(deltaString)
|
||||||
|
requestSizeCustomMetric, requestSizeCustomMetricError := strconv.Atoi(requestSizeCustomMetricString)
|
||||||
|
if durationSecError != nil || deltaError != nil || requestSizeCustomMetricError != nil || requestSizeCustomMetric <= 0 {
|
||||||
|
http.Error(w, IncorrectFunctionArgument, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count := delta / requestSizeCustomMetric
|
||||||
|
rest := delta - count*requestSizeCustomMetric
|
||||||
|
fmt.Fprintf(w, "RC manager: sending %v requests to bump custom metric by %v each and 1 request to bump by %v\n", count, requestSizeCustomMetric, rest)
|
||||||
|
if count > 0 {
|
||||||
|
handler.waitGroup.Add(count)
|
||||||
|
handler.sendConsumeCustomMetric(w, metric, count, requestSizeCustomMetric, durationSec)
|
||||||
|
}
|
||||||
|
if rest > 0 {
|
||||||
|
handler.waitGroup.Add(1)
|
||||||
|
go handler.sendOneConsumeCustomMetric(w, metric, rest, durationSec)
|
||||||
|
}
|
||||||
|
handler.waitGroup.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (manager *Controller) sendConsumeCPURequests(w http.ResponseWriter, requests, millicores, durationSec int) {
|
||||||
|
for i := 0; i < requests; i++ {
|
||||||
|
go manager.sendOneConsumeCPURequest(w, millicores, durationSec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (manager *Controller) sendConsumeMemRequests(w http.ResponseWriter, requests, megabytes, durationSec int) {
|
||||||
|
for i := 0; i < requests; i++ {
|
||||||
|
go manager.sendOneConsumeMemRequest(w, megabytes, durationSec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (manager *Controller) sendConsumeCustomMetric(w http.ResponseWriter, metric string, requests, delta, durationSec int) {
|
||||||
|
for i := 0; i < requests; i++ {
|
||||||
|
go manager.sendOneConsumeCustomMetric(w, metric, delta, durationSec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createConsumerURL(suffix string) string {
|
||||||
|
return fmt.Sprintf("http://%s.%s.svc.cluster.local:%d%s", *consumerServiceName, *consumerServiceNamespace, *consumerPort, suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendOneConsumeCPURequest sends POST request for cpu consumption
|
||||||
|
func (c *Controller) sendOneConsumeCPURequest(w http.ResponseWriter, millicores int, durationSec int) {
|
||||||
|
defer c.waitGroup.Done()
|
||||||
|
query := createConsumerURL(ConsumeCPUAddress)
|
||||||
|
_, err := http.PostForm(query, url.Values{MillicoresQuery: {strconv.Itoa(millicores)}, DurationSecQuery: {strconv.Itoa(durationSec)}})
|
||||||
|
c.responseWriterLock.Lock()
|
||||||
|
defer c.responseWriterLock.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, "Failed to connect to consumer: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "Consumed %d millicores\n", millicores)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendOneConsumeMemRequest sends POST request for memory consumption
|
||||||
|
func (c *Controller) sendOneConsumeMemRequest(w http.ResponseWriter, megabytes int, durationSec int) {
|
||||||
|
defer c.waitGroup.Done()
|
||||||
|
query := createConsumerURL(ConsumeMemAddress)
|
||||||
|
_, err := http.PostForm(query, url.Values{MegabytesQuery: {strconv.Itoa(megabytes)}, DurationSecQuery: {strconv.Itoa(durationSec)}})
|
||||||
|
c.responseWriterLock.Lock()
|
||||||
|
defer c.responseWriterLock.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, "Failed to connect to consumer: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "Consumed %d megabytes\n", megabytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendOneConsumeCustomMetric sends POST request for custom metric consumption
|
||||||
|
func (c *Controller) sendOneConsumeCustomMetric(w http.ResponseWriter, customMetricName string, delta int, durationSec int) {
|
||||||
|
defer c.waitGroup.Done()
|
||||||
|
query := createConsumerURL(BumpMetricAddress)
|
||||||
|
_, err := http.PostForm(query,
|
||||||
|
url.Values{MetricNameQuery: {customMetricName}, DurationSecQuery: {strconv.Itoa(durationSec)}, DeltaQuery: {strconv.Itoa(delta)}})
|
||||||
|
c.responseWriterLock.Lock()
|
||||||
|
defer c.responseWriterLock.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, "Failed to connect to consumer: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "Bumped metric %s by %d\n", customMetricName, delta)
|
||||||
|
}
|
@ -23,23 +23,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
. "k8s.io/kubernetes/test/images/resource-consumer/common"
|
||||||
badRequest = "Bad request. Not a POST request"
|
|
||||||
unknownFunction = "unknown function"
|
|
||||||
incorrectFunctionArgument = "incorrect function argument"
|
|
||||||
notGivenFunctionArgument = "not given function argument"
|
|
||||||
consumeCPUAddress = "/ConsumeCPU"
|
|
||||||
consumeMemAddress = "/ConsumeMem"
|
|
||||||
bumpMetricAddress = "/BumpMetric"
|
|
||||||
getCurrentStatusAddress = "/GetCurrentStatus"
|
|
||||||
metricsAddress = "/metrics"
|
|
||||||
millicoresQuery = "millicores"
|
|
||||||
megabytesQuery = "megabytes"
|
|
||||||
metricNameQuery = "metric"
|
|
||||||
deltaQuery = "delta"
|
|
||||||
durationSecQuery = "durationSec"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResourceConsumerHandler struct {
|
type ResourceConsumerHandler struct {
|
||||||
@ -53,12 +38,12 @@ func NewResourceConsumerHandler() *ResourceConsumerHandler {
|
|||||||
|
|
||||||
func (handler *ResourceConsumerHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (handler *ResourceConsumerHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
// handle exposing metrics in Prometheus format (both GET & POST)
|
// handle exposing metrics in Prometheus format (both GET & POST)
|
||||||
if req.URL.Path == metricsAddress {
|
if req.URL.Path == MetricsAddress {
|
||||||
handler.handleMetrics(w)
|
handler.handleMetrics(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if req.Method != "POST" {
|
if req.Method != "POST" {
|
||||||
http.Error(w, badRequest, http.StatusBadRequest)
|
http.Error(w, BadRequest, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// parsing POST request data and URL data
|
// parsing POST request data and URL data
|
||||||
@ -67,34 +52,34 @@ func (handler *ResourceConsumerHandler) ServeHTTP(w http.ResponseWriter, req *ht
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// handle consumeCPU
|
// handle consumeCPU
|
||||||
if req.URL.Path == consumeCPUAddress {
|
if req.URL.Path == ConsumeCPUAddress {
|
||||||
handler.handleConsumeCPU(w, req.Form)
|
handler.handleConsumeCPU(w, req.Form)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// handle consumeMem
|
// handle consumeMem
|
||||||
if req.URL.Path == consumeMemAddress {
|
if req.URL.Path == ConsumeMemAddress {
|
||||||
handler.handleConsumeMem(w, req.Form)
|
handler.handleConsumeMem(w, req.Form)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// handle getCurrentStatus
|
// handle getCurrentStatus
|
||||||
if req.URL.Path == getCurrentStatusAddress {
|
if req.URL.Path == GetCurrentStatusAddress {
|
||||||
handler.handleGetCurrentStatus(w)
|
handler.handleGetCurrentStatus(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// handle bumpMetric
|
// handle bumpMetric
|
||||||
if req.URL.Path == bumpMetricAddress {
|
if req.URL.Path == BumpMetricAddress {
|
||||||
handler.handleBumpMetric(w, req.Form)
|
handler.handleBumpMetric(w, req.Form)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Error(w, unknownFunction, http.StatusNotFound)
|
http.Error(w, fmt.Sprintf("%s: %s", UnknownFunction, req.URL.Path), http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *ResourceConsumerHandler) handleConsumeCPU(w http.ResponseWriter, query url.Values) {
|
func (handler *ResourceConsumerHandler) handleConsumeCPU(w http.ResponseWriter, query url.Values) {
|
||||||
// geting string data for consumeCPU
|
// geting string data for consumeCPU
|
||||||
durationSecString := query.Get(durationSecQuery)
|
durationSecString := query.Get(DurationSecQuery)
|
||||||
millicoresString := query.Get(millicoresQuery)
|
millicoresString := query.Get(MillicoresQuery)
|
||||||
if durationSecString == "" || millicoresString == "" {
|
if durationSecString == "" || millicoresString == "" {
|
||||||
http.Error(w, notGivenFunctionArgument, http.StatusBadRequest)
|
http.Error(w, NotGivenFunctionArgument, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,22 +87,22 @@ func (handler *ResourceConsumerHandler) handleConsumeCPU(w http.ResponseWriter,
|
|||||||
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
||||||
millicores, millicoresError := strconv.Atoi(millicoresString)
|
millicores, millicoresError := strconv.Atoi(millicoresString)
|
||||||
if durationSecError != nil || millicoresError != nil {
|
if durationSecError != nil || millicoresError != nil {
|
||||||
http.Error(w, incorrectFunctionArgument, http.StatusBadRequest)
|
http.Error(w, IncorrectFunctionArgument, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go ConsumeCPU(millicores, durationSec)
|
go ConsumeCPU(millicores, durationSec)
|
||||||
fmt.Fprintln(w, consumeCPUAddress[1:])
|
fmt.Fprintln(w, ConsumeCPUAddress[1:])
|
||||||
fmt.Fprintln(w, millicores, millicoresQuery)
|
fmt.Fprintln(w, millicores, MillicoresQuery)
|
||||||
fmt.Fprintln(w, durationSec, durationSecQuery)
|
fmt.Fprintln(w, durationSec, DurationSecQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *ResourceConsumerHandler) handleConsumeMem(w http.ResponseWriter, query url.Values) {
|
func (handler *ResourceConsumerHandler) handleConsumeMem(w http.ResponseWriter, query url.Values) {
|
||||||
// geting string data for consumeMem
|
// geting string data for consumeMem
|
||||||
durationSecString := query.Get(durationSecQuery)
|
durationSecString := query.Get(DurationSecQuery)
|
||||||
megabytesString := query.Get(megabytesQuery)
|
megabytesString := query.Get(MegabytesQuery)
|
||||||
if durationSecString == "" || megabytesString == "" {
|
if durationSecString == "" || megabytesString == "" {
|
||||||
http.Error(w, notGivenFunctionArgument, http.StatusBadRequest)
|
http.Error(w, NotGivenFunctionArgument, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,20 +110,20 @@ func (handler *ResourceConsumerHandler) handleConsumeMem(w http.ResponseWriter,
|
|||||||
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
||||||
megabytes, megabytesError := strconv.Atoi(megabytesString)
|
megabytes, megabytesError := strconv.Atoi(megabytesString)
|
||||||
if durationSecError != nil || megabytesError != nil {
|
if durationSecError != nil || megabytesError != nil {
|
||||||
http.Error(w, incorrectFunctionArgument, http.StatusBadRequest)
|
http.Error(w, IncorrectFunctionArgument, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go ConsumeMem(megabytes, durationSec)
|
go ConsumeMem(megabytes, durationSec)
|
||||||
fmt.Fprintln(w, consumeMemAddress[1:])
|
fmt.Fprintln(w, ConsumeMemAddress[1:])
|
||||||
fmt.Fprintln(w, megabytes, megabytesQuery)
|
fmt.Fprintln(w, megabytes, MegabytesQuery)
|
||||||
fmt.Fprintln(w, durationSec, durationSecQuery)
|
fmt.Fprintln(w, durationSec, DurationSecQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *ResourceConsumerHandler) handleGetCurrentStatus(w http.ResponseWriter) {
|
func (handler *ResourceConsumerHandler) handleGetCurrentStatus(w http.ResponseWriter) {
|
||||||
GetCurrentStatus()
|
GetCurrentStatus()
|
||||||
fmt.Fprintln(w, "Warning: not implemented!")
|
fmt.Fprintln(w, "Warning: not implemented!")
|
||||||
fmt.Fprint(w, getCurrentStatusAddress[1:])
|
fmt.Fprint(w, GetCurrentStatusAddress[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *ResourceConsumerHandler) handleMetrics(w http.ResponseWriter) {
|
func (handler *ResourceConsumerHandler) handleMetrics(w http.ResponseWriter) {
|
||||||
@ -169,11 +154,11 @@ func (handler *ResourceConsumerHandler) bumpMetric(metric string, delta float64,
|
|||||||
|
|
||||||
func (handler *ResourceConsumerHandler) handleBumpMetric(w http.ResponseWriter, query url.Values) {
|
func (handler *ResourceConsumerHandler) handleBumpMetric(w http.ResponseWriter, query url.Values) {
|
||||||
// geting string data for handleBumpMetric
|
// geting string data for handleBumpMetric
|
||||||
metric := query.Get(metricNameQuery)
|
metric := query.Get(MetricNameQuery)
|
||||||
deltaString := query.Get(deltaQuery)
|
deltaString := query.Get(DeltaQuery)
|
||||||
durationSecString := query.Get(durationSecQuery)
|
durationSecString := query.Get(DurationSecQuery)
|
||||||
if durationSecString == "" || metric == "" || deltaString == "" {
|
if durationSecString == "" || metric == "" || deltaString == "" {
|
||||||
http.Error(w, notGivenFunctionArgument, http.StatusBadRequest)
|
http.Error(w, NotGivenFunctionArgument, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,13 +166,13 @@ func (handler *ResourceConsumerHandler) handleBumpMetric(w http.ResponseWriter,
|
|||||||
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
durationSec, durationSecError := strconv.Atoi(durationSecString)
|
||||||
delta, deltaError := strconv.ParseFloat(deltaString, 64)
|
delta, deltaError := strconv.ParseFloat(deltaString, 64)
|
||||||
if durationSecError != nil || deltaError != nil {
|
if durationSecError != nil || deltaError != nil {
|
||||||
http.Error(w, incorrectFunctionArgument, http.StatusBadRequest)
|
http.Error(w, IncorrectFunctionArgument, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go handler.bumpMetric(metric, delta, time.Duration(durationSec)*time.Second)
|
go handler.bumpMetric(metric, delta, time.Duration(durationSec)*time.Second)
|
||||||
fmt.Fprintln(w, bumpMetricAddress[1:])
|
fmt.Fprintln(w, BumpMetricAddress[1:])
|
||||||
fmt.Fprintln(w, metric, metricNameQuery)
|
fmt.Fprintln(w, metric, MetricNameQuery)
|
||||||
fmt.Fprintln(w, delta, deltaQuery)
|
fmt.Fprintln(w, delta, DeltaQuery)
|
||||||
fmt.Fprintln(w, durationSec, durationSecQuery)
|
fmt.Fprintln(w, durationSec, DurationSecQuery)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user