Skip to content

Commit

Permalink
Merge pull request #2 from fuweid/init-runner-sub-command
Browse files Browse the repository at this point in the history
Init runner sub command
  • Loading branch information
fuweid authored Dec 8, 2023
2 parents 358929d + 31280f2 commit 5084b23
Show file tree
Hide file tree
Showing 13 changed files with 992 additions and 63 deletions.
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM golang:1.20 AS build-stage

WORKDIR /gomod
COPY go.mod go.sum ./
RUN go mod download

RUN mkdir -p /output

WORKDIR /kperf-build
RUN --mount=source=./,target=/kperf-build,rw make build && PREFIX=/output make install

FROM gcr.io/distroless/static-debian12:nonroot AS release-stage

WORKDIR /

COPY --from=build-stage /output/bin/kperf /kperf

USER nonroot:nonroot

ENTRYPOINT ["/kperf"]
24 changes: 23 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
COMMANDS=kperf

# PREFIX is base path to install.
PREFIX ?= /usr/local

GO_BUILDTAGS = -tags "osusergo netgo static_build"

# IMAGE_REPO is default repo for image-build recipe.
IMAGE_REPO ?= localhost:5000
IMAGE_TAG ?= latest
IMAGE_NAME = $(IMAGE_REPO)/kperf:$(IMAGE_TAG)

BINARIES=$(addprefix bin/,$(COMMANDS))

# default recipe is build
Expand All @@ -9,11 +19,23 @@ BINARIES=$(addprefix bin/,$(COMMANDS))
ALWAYS:

bin/%: cmd/% ALWAYS
@go build -o $@ ./$<
@GO_ENABLED=0 go build -o $@ ${GO_BUILDTAGS} ./$<

build: $(BINARIES) ## build binaries
@echo "$@"

install: ## install binaries
@install -d $(PREFIX)/bin
@install $(BINARIES) $(PREFIX)/bin

image-build: ## build image
@echo building ${IMAGE_NAME}
@docker build . -t ${IMAGE_NAME}

image-push: image-build ## push image
@echo pushing ${IMAGE_NAME}
@docker push ${IMAGE_NAME}

test: ## run test
@go test -v ./...

Expand Down
135 changes: 123 additions & 12 deletions api/types/load_traffic.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package types

import "fmt"

// LoadProfile defines how to create load traffic from one host to kube-apiserver.
type LoadProfile struct {
// Version defines the version of this object.
Expand All @@ -23,12 +25,14 @@ type LoadProfileSpec struct {
Requests []*WeightedRequest
}

// KubeTypeMeta represents metadata of kubernetes object.
type KubeTypeMeta struct {
// Kind is a string value representing the REST resource the object represents.
Kind string `json:"kind" yaml:"kind"`
// APIVersion defines the versioned schema of the representation of an object.
APIVersion string `json:"apiVersion" yaml:"apiVersion"`
// KubeGroupVersionResource identifies the resource URI.
type KubeGroupVersionResource struct {
// Group is the name about a collection of related functionality.
Group string `json:"group" yaml:"group"`
// Version is a version of that group.
Version string `json:"version" yaml:"version"`
// Resource is a type in that versioned group APIs.
Resource string `json:"resource" yaml:"resource"`
}

// WeightedRequest represents request with weight.
Expand All @@ -50,8 +54,8 @@ type WeightedRequest struct {

// RequestGet defines GET request for target object.
type RequestGet struct {
// KubeTypeMeta represents object's resource type.
KubeTypeMeta `yaml:",inline"`
// KubeGroupVersionResource identifies the resource URI.
KubeGroupVersionResource `yaml:",inline"`
// Namespace is object's namespace.
Namespace string `json:"namespace" yaml:"namespace"`
// Name is object's name.
Expand All @@ -60,8 +64,8 @@ type RequestGet struct {

// RequestList defines LIST request for target objects.
type RequestList struct {
// KubeTypeMeta represents object's resource type.
KubeTypeMeta `yaml:",inline"`
// KubeGroupVersionResource identifies the resource URI.
KubeGroupVersionResource `yaml:",inline"`
// Namespace is object's namespace.
Namespace string `json:"namespace" yaml:"namespace"`
// Limit defines the page size.
Expand All @@ -72,14 +76,14 @@ type RequestList struct {

// RequestPut defines PUT request for target resource type.
type RequestPut struct {
// KubeTypeMeta represents object's resource type.
// KubeGroupVersionResource identifies the resource URI.
//
// NOTE: Currently, it should be configmap or secrets because we can
// generate random bytes as blob for it. However, for the pod resource,
// we need to ensure a lot of things are ready, for instance, volumes,
// resource capacity. It's not easy to generate it randomly. Maybe we
// can introduce pod template in the future.
KubeTypeMeta `yaml:",inline"`
KubeGroupVersionResource `yaml:",inline"`
// Namespace is object's namespace.
Namespace string `json:"namespace" yaml:"namespace"`
// Name is object's prefix name.
Expand All @@ -89,3 +93,110 @@ type RequestPut struct {
// ValueSize is the object's size in bytes.
ValueSize int `json:"valueSize" yaml:"valueSize"`
}

// Validate verifies fields of LoadProfile.
func (lp LoadProfile) Validate() error {
if lp.Version != 1 {
return fmt.Errorf("version should be 1")
}
return lp.Spec.Validate()
}

// Validate verifies fields of LoadProfileSpec.
func (spec LoadProfileSpec) Validate() error {
if spec.Conns <= 0 {
return fmt.Errorf("conns requires > 0: %v", spec.Conns)
}

if spec.Rate < 0 {
return fmt.Errorf("rate requires >= 0: %v", spec.Rate)
}

if spec.Total <= 0 {
return fmt.Errorf("total requires > 0: %v", spec.Total)
}

for idx, req := range spec.Requests {
if err := req.Validate(); err != nil {
return fmt.Errorf("idx: %v request: %v", idx, err)
}
}
return nil
}

// Validate verifies fields of WeightedRequest.
func (r WeightedRequest) Validate() error {
if r.Shares < 0 {
return fmt.Errorf("shares(%v) requires >= 0", r.Shares)
}

switch {
case r.StaleList != nil:
return r.StaleList.Validate()
case r.QuorumList != nil:
return r.QuorumList.Validate()
case r.StaleGet != nil:
return r.StaleGet.Validate()
case r.QuorumGet != nil:
return r.QuorumGet.Validate()
case r.Put != nil:
return r.Put.Validate()
default:
return fmt.Errorf("empty request value")
}
}

// RequestList validates RequestList type.
func (r *RequestList) Validate() error {
if err := r.KubeGroupVersionResource.Validate(); err != nil {
return fmt.Errorf("kube metadata: %v", err)
}

if r.Limit < 0 {
return fmt.Errorf("limit must >= 0")
}
return nil
}

// Validate validates RequestGet type.
func (r *RequestGet) Validate() error {
if err := r.KubeGroupVersionResource.Validate(); err != nil {
return fmt.Errorf("kube metadata: %v", err)
}

if r.Name == "" {
return fmt.Errorf("name is required")
}
return nil
}

// Validate validates RequestPut type.
func (r *RequestPut) Validate() error {
if err := r.KubeGroupVersionResource.Validate(); err != nil {
return fmt.Errorf("kube metadata: %v", err)
}

// TODO: check resource type
if r.Name == "" {
return fmt.Errorf("name pattern is required")
}
if r.KeySpaceSize <= 0 {
return fmt.Errorf("keySpaceSize must > 0")
}
if r.ValueSize <= 0 {
return fmt.Errorf("valueSize must > 0")
}
return nil
}

// Validate validates KubeGroupVersionResource.
func (m *KubeGroupVersionResource) Validate() error {
if m.Version == "" {
return fmt.Errorf("version is required")
}

if m.Resource == "" {
return fmt.Errorf("resource is required")
}
return nil
}
Loading

0 comments on commit 5084b23

Please sign in to comment.