mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 18:00:08 +00:00
Merge pull request #124548 from pohly/dra-scheduler-perf-structured-parameters
scheduler_perf: add DRA structured parameters test with shared claims
This commit is contained in:
commit
3b90ae4f58
@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: test-dra-{{.Index}}
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: registry.k8s.io/pause:3.9
|
||||||
|
name: pause
|
||||||
|
resources:
|
||||||
|
claims:
|
||||||
|
- name: resource
|
||||||
|
resourceClaims:
|
||||||
|
- name: resource
|
||||||
|
source:
|
||||||
|
# Five pods share access to the same claim.
|
||||||
|
resourceClaimName: test-claim-{{div .Index 5}}
|
@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: resource.k8s.io/v1alpha2
|
||||||
|
kind: ResourceClaim
|
||||||
|
metadata:
|
||||||
|
name: test-claim-{{.Index}}
|
||||||
|
spec:
|
||||||
|
resourceClassName: test-class
|
||||||
|
parametersRef:
|
||||||
|
apiGroup: resource.k8s.io
|
||||||
|
kind: ResourceClaimParameters
|
||||||
|
name: test-claim-parameters
|
@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: resource.k8s.io/v1alpha2
|
||||||
|
kind: ResourceClaim
|
||||||
|
metadata:
|
||||||
|
name: test-claim-{{.Index}}
|
||||||
|
spec:
|
||||||
|
resourceClassName: test-class
|
@ -2,6 +2,7 @@ apiVersion: resource.k8s.io/v1alpha2
|
|||||||
kind: ResourceClaimParameters
|
kind: ResourceClaimParameters
|
||||||
metadata:
|
metadata:
|
||||||
name: test-claim-parameters
|
name: test-claim-parameters
|
||||||
|
shareable: true
|
||||||
driverRequests:
|
driverRequests:
|
||||||
- driverName: test-driver.cdi.k8s.io
|
- driverName: test-driver.cdi.k8s.io
|
||||||
requests:
|
requests:
|
||||||
|
@ -746,6 +746,7 @@
|
|||||||
- name: SchedulingWithResourceClaimTemplate
|
- name: SchedulingWithResourceClaimTemplate
|
||||||
featureGates:
|
featureGates:
|
||||||
DynamicResourceAllocation: true
|
DynamicResourceAllocation: true
|
||||||
|
# SchedulerQueueingHints: true
|
||||||
workloadTemplate:
|
workloadTemplate:
|
||||||
- opcode: createNodes
|
- opcode: createNodes
|
||||||
countParam: $nodesWithoutDRA
|
countParam: $nodesWithoutDRA
|
||||||
@ -812,6 +813,7 @@
|
|||||||
- name: SchedulingWithMultipleResourceClaims
|
- name: SchedulingWithMultipleResourceClaims
|
||||||
featureGates:
|
featureGates:
|
||||||
DynamicResourceAllocation: true
|
DynamicResourceAllocation: true
|
||||||
|
# SchedulerQueueingHints: true
|
||||||
workloadTemplate:
|
workloadTemplate:
|
||||||
- opcode: createNodes
|
- opcode: createNodes
|
||||||
countParam: $nodesWithoutDRA
|
countParam: $nodesWithoutDRA
|
||||||
@ -887,6 +889,7 @@
|
|||||||
- name: SchedulingWithResourceClaimTemplateStructured
|
- name: SchedulingWithResourceClaimTemplateStructured
|
||||||
featureGates:
|
featureGates:
|
||||||
DynamicResourceAllocation: true
|
DynamicResourceAllocation: true
|
||||||
|
# SchedulerQueueingHints: true
|
||||||
workloadTemplate:
|
workloadTemplate:
|
||||||
- opcode: createNodes
|
- opcode: createNodes
|
||||||
countParam: $nodesWithoutDRA
|
countParam: $nodesWithoutDRA
|
||||||
@ -935,8 +938,6 @@
|
|||||||
- name: 2000pods_100nodes
|
- name: 2000pods_100nodes
|
||||||
labels: [performance, fast]
|
labels: [performance, fast]
|
||||||
params:
|
params:
|
||||||
# In this testcase, the number of nodes is smaller
|
|
||||||
# than the limit for the PodScheduling slices.
|
|
||||||
nodesWithDRA: 100
|
nodesWithDRA: 100
|
||||||
nodesWithoutDRA: 0
|
nodesWithoutDRA: 0
|
||||||
initPods: 1000
|
initPods: 1000
|
||||||
@ -944,11 +945,102 @@
|
|||||||
maxClaimsPerNode: 20
|
maxClaimsPerNode: 20
|
||||||
- name: 2000pods_200nodes
|
- name: 2000pods_200nodes
|
||||||
params:
|
params:
|
||||||
# In this testcase, the driver and scheduler must
|
|
||||||
# truncate the PotentialNodes and UnsuitableNodes
|
|
||||||
# slices.
|
|
||||||
nodesWithDRA: 200
|
nodesWithDRA: 200
|
||||||
nodesWithoutDRA: 0
|
nodesWithoutDRA: 0
|
||||||
initPods: 1000
|
initPods: 1000
|
||||||
measurePods: 1000
|
measurePods: 1000
|
||||||
maxClaimsPerNode: 10
|
maxClaimsPerNode: 10
|
||||||
|
- name: 5000pods_500nodes
|
||||||
|
params:
|
||||||
|
nodesWithDRA: 500
|
||||||
|
nodesWithoutDRA: 0
|
||||||
|
initPods: 2500
|
||||||
|
measurePods: 2500
|
||||||
|
maxClaimsPerNode: 10
|
||||||
|
|
||||||
|
# SchedulingWithResourceClaimTemplate uses ResourceClaims
|
||||||
|
# with deterministic names that are shared between pods.
|
||||||
|
# There is a fixed ratio of 1:5 between claims and pods.
|
||||||
|
#
|
||||||
|
# The driver uses structured parameters.
|
||||||
|
- name: SchedulingWithResourceClaimStructured
|
||||||
|
featureGates:
|
||||||
|
DynamicResourceAllocation: true
|
||||||
|
# SchedulerQueueingHints: true
|
||||||
|
workloadTemplate:
|
||||||
|
- opcode: createNodes
|
||||||
|
countParam: $nodesWithoutDRA
|
||||||
|
- opcode: createNodes
|
||||||
|
nodeTemplatePath: config/dra/node-with-dra-test-driver.yaml
|
||||||
|
countParam: $nodesWithDRA
|
||||||
|
- opcode: createResourceDriver
|
||||||
|
driverName: test-driver.cdi.k8s.io
|
||||||
|
nodes: scheduler-perf-dra-*
|
||||||
|
maxClaimsPerNodeParam: $maxClaimsPerNode
|
||||||
|
structuredParameters: true
|
||||||
|
- opcode: createAny
|
||||||
|
templatePath: config/dra/resourceclass-structured.yaml
|
||||||
|
- opcode: createAny
|
||||||
|
templatePath: config/dra/resourceclaimparameters.yaml
|
||||||
|
namespace: init
|
||||||
|
- opcode: createAny
|
||||||
|
templatePath: config/dra/resourceclaim-structured.yaml
|
||||||
|
namespace: init
|
||||||
|
countParam: $initClaims
|
||||||
|
- opcode: createPods
|
||||||
|
namespace: init
|
||||||
|
countParam: $initPods
|
||||||
|
podTemplatePath: config/dra/pod-with-claim-ref.yaml
|
||||||
|
- opcode: createAny
|
||||||
|
templatePath: config/dra/resourceclaimparameters.yaml
|
||||||
|
namespace: test
|
||||||
|
- opcode: createAny
|
||||||
|
templatePath: config/dra/resourceclaim-structured.yaml
|
||||||
|
namespace: test
|
||||||
|
countParam: $measureClaims
|
||||||
|
- opcode: createPods
|
||||||
|
namespace: test
|
||||||
|
countParam: $measurePods
|
||||||
|
podTemplatePath: config/dra/pod-with-claim-ref.yaml
|
||||||
|
collectMetrics: true
|
||||||
|
workloads:
|
||||||
|
- name: fast
|
||||||
|
labels: [integration-test, fast]
|
||||||
|
params:
|
||||||
|
# This testcase runs through all code paths without
|
||||||
|
# taking too long overall.
|
||||||
|
nodesWithDRA: 1
|
||||||
|
nodesWithoutDRA: 1
|
||||||
|
initPods: 0
|
||||||
|
initClaims: 0
|
||||||
|
measurePods: 10
|
||||||
|
measureClaims: 2 # must be measurePods / 5
|
||||||
|
maxClaimsPerNode: 2
|
||||||
|
- name: 2000pods_100nodes
|
||||||
|
labels: [performance, fast]
|
||||||
|
params:
|
||||||
|
nodesWithDRA: 100
|
||||||
|
nodesWithoutDRA: 0
|
||||||
|
initPods: 1000
|
||||||
|
initClaims: 200 # must be initPods / 5
|
||||||
|
measurePods: 1000
|
||||||
|
measureClaims: 200 # must be initPods / 5
|
||||||
|
maxClaimsPerNode: 4
|
||||||
|
- name: 2000pods_200nodes
|
||||||
|
params:
|
||||||
|
nodesWithDRA: 200
|
||||||
|
nodesWithoutDRA: 0
|
||||||
|
initPods: 1000
|
||||||
|
initClaims: 200 # must be initPods / 5
|
||||||
|
measurePods: 1000
|
||||||
|
measureClaims: 200 # must be measurePods / 5
|
||||||
|
maxClaimsPerNode: 2
|
||||||
|
- name: 5000pods_500nodes
|
||||||
|
params:
|
||||||
|
nodesWithDRA: 500
|
||||||
|
nodesWithoutDRA: 0
|
||||||
|
initPods: 2500
|
||||||
|
initClaims: 500 # must be initPods / 5
|
||||||
|
measurePods: 2500
|
||||||
|
measureClaims: 500 # must be measurePods / 5
|
||||||
|
maxClaimsPerNode: 2
|
||||||
|
@ -17,8 +17,11 @@ limitations under the License.
|
|||||||
package benchmark
|
package benchmark
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
@ -30,6 +33,8 @@ import (
|
|||||||
"k8s.io/client-go/restmapper"
|
"k8s.io/client-go/restmapper"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"k8s.io/kubernetes/test/utils/ktesting"
|
"k8s.io/kubernetes/test/utils/ktesting"
|
||||||
|
"k8s.io/utils/ptr"
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// createAny defines an op where some object gets created from a YAML file.
|
// createAny defines an op where some object gets created from a YAML file.
|
||||||
@ -40,7 +45,13 @@ type createAny struct {
|
|||||||
// Namespace the object should be created in. Must be empty for cluster-scoped objects.
|
// Namespace the object should be created in. Must be empty for cluster-scoped objects.
|
||||||
Namespace string
|
Namespace string
|
||||||
// Path to spec file describing the object to create.
|
// Path to spec file describing the object to create.
|
||||||
|
// This will be processed with text/template.
|
||||||
|
// .Index will be in the range [0, Count-1] when creating
|
||||||
|
// more than one object. .Count is the total number of objects.
|
||||||
TemplatePath string
|
TemplatePath string
|
||||||
|
// Count determines how many objects get created. Defaults to 1 if unset.
|
||||||
|
Count *int
|
||||||
|
CountParam string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ runnableOp = &createAny{}
|
var _ runnableOp = &createAny{}
|
||||||
@ -61,8 +72,15 @@ func (c *createAny) collectsMetrics() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *createAny) patchParams(w *workload) (realOp, error) {
|
func (c createAny) patchParams(w *workload) (realOp, error) {
|
||||||
return c, c.isValid(false)
|
if c.CountParam != "" {
|
||||||
|
count, err := w.Params.get(c.CountParam[1:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c.Count = ptr.To(count)
|
||||||
|
}
|
||||||
|
return &c, c.isValid(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *createAny) requiredNamespaces() []string {
|
func (c *createAny) requiredNamespaces() []string {
|
||||||
@ -73,8 +91,18 @@ func (c *createAny) requiredNamespaces() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *createAny) run(tCtx ktesting.TContext) {
|
func (c *createAny) run(tCtx ktesting.TContext) {
|
||||||
|
count := 1
|
||||||
|
if c.Count != nil {
|
||||||
|
count = *c.Count
|
||||||
|
}
|
||||||
|
for index := 0; index < count; index++ {
|
||||||
|
c.create(tCtx, map[string]any{"Index": index, "Count": count})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *createAny) create(tCtx ktesting.TContext, env map[string]any) {
|
||||||
var obj *unstructured.Unstructured
|
var obj *unstructured.Unstructured
|
||||||
if err := getSpecFromFile(&c.TemplatePath, &obj); err != nil {
|
if err := getSpecFromTextTemplateFile(c.TemplatePath, env, &obj); err != nil {
|
||||||
tCtx.Fatalf("%s: parsing failed: %v", c.TemplatePath, err)
|
tCtx.Fatalf("%s: parsing failed: %v", c.TemplatePath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,3 +171,23 @@ func (c *createAny) run(tCtx ktesting.TContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSpecFromTextTemplateFile(path string, env map[string]any, spec interface{}) error {
|
||||||
|
content, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fm := template.FuncMap{"div": func(a, b int) int {
|
||||||
|
return a / b
|
||||||
|
}}
|
||||||
|
tmpl, err := template.New("object").Funcs(fm).Parse(string(content))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
if err := tmpl.Execute(&buffer, env); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return yaml.UnmarshalStrict(buffer.Bytes(), spec)
|
||||||
|
}
|
||||||
|
@ -177,6 +177,7 @@ func (op *createResourceDriverOp) run(tCtx ktesting.TContext) {
|
|||||||
DriverName: op.DriverName,
|
DriverName: op.DriverName,
|
||||||
NodeLocal: true,
|
NodeLocal: true,
|
||||||
MaxAllocations: op.MaxClaimsPerNode,
|
MaxAllocations: op.MaxClaimsPerNode,
|
||||||
|
Shareable: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes, err := tCtx.Client().CoreV1().Nodes().List(tCtx, metav1.ListOptions{})
|
nodes, err := tCtx.Client().CoreV1().Nodes().List(tCtx, metav1.ListOptions{})
|
||||||
|
@ -1432,16 +1432,12 @@ func validateTestCases(testCases []*testCase) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getPodStrategy(cpo *createPodsOp) (testutils.TestPodCreateStrategy, error) {
|
func getPodStrategy(cpo *createPodsOp) (testutils.TestPodCreateStrategy, error) {
|
||||||
basePod := makeBasePod()
|
podTemplate := testutils.StaticPodTemplate(makeBasePod())
|
||||||
if cpo.PodTemplatePath != nil {
|
if cpo.PodTemplatePath != nil {
|
||||||
var err error
|
podTemplate = podTemplateFromFile(*cpo.PodTemplatePath)
|
||||||
basePod, err = getPodSpecFromFile(cpo.PodTemplatePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if cpo.PersistentVolumeClaimTemplatePath == nil {
|
if cpo.PersistentVolumeClaimTemplatePath == nil {
|
||||||
return testutils.NewCustomCreatePodStrategy(basePod), nil
|
return testutils.NewCustomCreatePodStrategy(podTemplate), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
pvTemplate, err := getPersistentVolumeSpecFromFile(cpo.PersistentVolumeTemplatePath)
|
pvTemplate, err := getPersistentVolumeSpecFromFile(cpo.PersistentVolumeTemplatePath)
|
||||||
@ -1452,7 +1448,7 @@ func getPodStrategy(cpo *createPodsOp) (testutils.TestPodCreateStrategy, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return testutils.NewCreatePodWithPersistentVolumeStrategy(pvcTemplate, getCustomVolumeFactory(pvTemplate), basePod), nil
|
return testutils.NewCreatePodWithPersistentVolumeStrategy(pvcTemplate, getCustomVolumeFactory(pvTemplate), podTemplate), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNodeSpecFromFile(path *string) (*v1.Node, error) {
|
func getNodeSpecFromFile(path *string) (*v1.Node, error) {
|
||||||
@ -1463,9 +1459,11 @@ func getNodeSpecFromFile(path *string) (*v1.Node, error) {
|
|||||||
return nodeSpec, nil
|
return nodeSpec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPodSpecFromFile(path *string) (*v1.Pod, error) {
|
type podTemplateFromFile string
|
||||||
|
|
||||||
|
func (f podTemplateFromFile) GetPodTemplate(index, count int) (*v1.Pod, error) {
|
||||||
podSpec := &v1.Pod{}
|
podSpec := &v1.Pod{}
|
||||||
if err := getSpecFromFile(path, podSpec); err != nil {
|
if err := getSpecFromTextTemplateFile(string(f), map[string]any{"Index": index, "Count": count}, podSpec); err != nil {
|
||||||
return nil, fmt.Errorf("parsing Pod: %w", err)
|
return nil, fmt.Errorf("parsing Pod: %w", err)
|
||||||
}
|
}
|
||||||
return podSpec, nil
|
return podSpec, nil
|
||||||
|
@ -1235,14 +1235,22 @@ func makeCreatePod(client clientset.Interface, namespace string, podTemplate *v1
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePod(ctx context.Context, client clientset.Interface, namespace string, podCount int, podTemplate *v1.Pod) error {
|
func CreatePod(ctx context.Context, client clientset.Interface, namespace string, podCount int, podTemplate PodTemplate) error {
|
||||||
var createError error
|
var createError error
|
||||||
lock := sync.Mutex{}
|
lock := sync.Mutex{}
|
||||||
createPodFunc := func(i int) {
|
createPodFunc := func(i int) {
|
||||||
|
pod, err := podTemplate.GetPodTemplate(i, podCount)
|
||||||
|
if err != nil {
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
createError = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pod = pod.DeepCopy()
|
||||||
// client-go writes into the object that is passed to Create,
|
// client-go writes into the object that is passed to Create,
|
||||||
// causing a data race unless we create a new copy for each
|
// causing a data race unless we create a new copy for each
|
||||||
// parallel call.
|
// parallel call.
|
||||||
if err := makeCreatePod(client, namespace, podTemplate.DeepCopy()); err != nil {
|
if err := makeCreatePod(client, namespace, pod); err != nil {
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
createError = err
|
createError = err
|
||||||
@ -1257,7 +1265,7 @@ func CreatePod(ctx context.Context, client clientset.Interface, namespace string
|
|||||||
return createError
|
return createError
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePodWithPersistentVolume(ctx context.Context, client clientset.Interface, namespace string, claimTemplate *v1.PersistentVolumeClaim, factory volumeFactory, podTemplate *v1.Pod, count int, bindVolume bool) error {
|
func CreatePodWithPersistentVolume(ctx context.Context, client clientset.Interface, namespace string, claimTemplate *v1.PersistentVolumeClaim, factory volumeFactory, podTemplate PodTemplate, count int, bindVolume bool) error {
|
||||||
var createError error
|
var createError error
|
||||||
lock := sync.Mutex{}
|
lock := sync.Mutex{}
|
||||||
createPodFunc := func(i int) {
|
createPodFunc := func(i int) {
|
||||||
@ -1318,7 +1326,14 @@ func CreatePodWithPersistentVolume(ctx context.Context, client clientset.Interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pod
|
// pod
|
||||||
pod := podTemplate.DeepCopy()
|
pod, err := podTemplate.GetPodTemplate(i, count)
|
||||||
|
if err != nil {
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
createError = fmt.Errorf("error getting pod template: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pod = pod.DeepCopy()
|
||||||
pod.Spec.Volumes = []v1.Volume{
|
pod.Spec.Volumes = []v1.Volume{
|
||||||
{
|
{
|
||||||
Name: "vol",
|
Name: "vol",
|
||||||
@ -1345,7 +1360,7 @@ func CreatePodWithPersistentVolume(ctx context.Context, client clientset.Interfa
|
|||||||
return createError
|
return createError
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCustomCreatePodStrategy(podTemplate *v1.Pod) TestPodCreateStrategy {
|
func NewCustomCreatePodStrategy(podTemplate PodTemplate) TestPodCreateStrategy {
|
||||||
return func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error {
|
return func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error {
|
||||||
return CreatePod(ctx, client, namespace, podCount, podTemplate)
|
return CreatePod(ctx, client, namespace, podCount, podTemplate)
|
||||||
}
|
}
|
||||||
@ -1354,7 +1369,32 @@ func NewCustomCreatePodStrategy(podTemplate *v1.Pod) TestPodCreateStrategy {
|
|||||||
// volumeFactory creates an unique PersistentVolume for given integer.
|
// volumeFactory creates an unique PersistentVolume for given integer.
|
||||||
type volumeFactory func(uniqueID int) *v1.PersistentVolume
|
type volumeFactory func(uniqueID int) *v1.PersistentVolume
|
||||||
|
|
||||||
func NewCreatePodWithPersistentVolumeStrategy(claimTemplate *v1.PersistentVolumeClaim, factory volumeFactory, podTemplate *v1.Pod) TestPodCreateStrategy {
|
// PodTemplate is responsible for creating a v1.Pod instance that is ready
|
||||||
|
// to be sent to the API server.
|
||||||
|
type PodTemplate interface {
|
||||||
|
// GetPodTemplate returns a pod template for one out of many different pods.
|
||||||
|
// Pods with numbers in the range [index, index+count-1] will be created
|
||||||
|
// based on what GetPodTemplate returns. It gets called multiple times
|
||||||
|
// with a fixed index and increasing count parameters. This number can,
|
||||||
|
// but doesn't have to be, used to modify parts of the pod spec like
|
||||||
|
// for example a named reference to some other object.
|
||||||
|
GetPodTemplate(index, count int) (*v1.Pod, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticPodTemplate returns an implementation of PodTemplate for a fixed pod that is the same regardless of the index.
|
||||||
|
func StaticPodTemplate(pod *v1.Pod) PodTemplate {
|
||||||
|
return (*staticPodTemplate)(pod)
|
||||||
|
}
|
||||||
|
|
||||||
|
type staticPodTemplate v1.Pod
|
||||||
|
|
||||||
|
// GetPodTemplate implements [PodTemplate.GetPodTemplate] by returning the same pod
|
||||||
|
// for each call.
|
||||||
|
func (s *staticPodTemplate) GetPodTemplate(index, count int) (*v1.Pod, error) {
|
||||||
|
return (*v1.Pod)(s), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCreatePodWithPersistentVolumeStrategy(claimTemplate *v1.PersistentVolumeClaim, factory volumeFactory, podTemplate PodTemplate) TestPodCreateStrategy {
|
||||||
return func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error {
|
return func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error {
|
||||||
return CreatePodWithPersistentVolume(ctx, client, namespace, claimTemplate, factory, podTemplate, podCount, true /* bindVolume */)
|
return CreatePodWithPersistentVolume(ctx, client, namespace, claimTemplate, factory, podTemplate, podCount, true /* bindVolume */)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user