diff --git a/cmd/kueuectl/app/list/list.go b/cmd/kueuectl/app/list/list.go index 51e832a42f..85902849b0 100644 --- a/cmd/kueuectl/app/list/list.go +++ b/cmd/kueuectl/app/list/list.go @@ -40,6 +40,7 @@ func NewListCmd(clientGetter util.ClientGetter, streams genericiooptions.IOStrea cmd.AddCommand(NewLocalQueueCmd(clientGetter, streams, clock)) cmd.AddCommand(NewClusterQueueCmd(clientGetter, streams, clock)) cmd.AddCommand(NewWorkloadCmd(clientGetter, streams, clock)) + cmd.AddCommand(NewResourceFlavorCmd(clientGetter, streams, clock)) return cmd } diff --git a/cmd/kueuectl/app/list/list_resourceflavor.go b/cmd/kueuectl/app/list/list_resourceflavor.go new file mode 100644 index 0000000000..adfda5c055 --- /dev/null +++ b/cmd/kueuectl/app/list/list_resourceflavor.go @@ -0,0 +1,164 @@ +/* +Copyright 2024 The Kubernetes Authors. + +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 list + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/cli-runtime/pkg/genericiooptions" + "k8s.io/cli-runtime/pkg/printers" + "k8s.io/utils/clock" + + "sigs.k8s.io/kueue/client-go/clientset/versioned/scheme" + kueuev1beta1 "sigs.k8s.io/kueue/client-go/clientset/versioned/typed/kueue/v1beta1" + "sigs.k8s.io/kueue/cmd/kueuectl/app/util" +) + +const ( + rfExample = ` # List ResourceFlavor + kueuectl list resourceflavor` +) + +type ResourceFlavorOptions struct { + Clock clock.Clock + PrintFlags *genericclioptions.PrintFlags + + Limit int64 + FieldSelector string + LabelSelector string + + Client kueuev1beta1.KueueV1beta1Interface + + genericiooptions.IOStreams +} + +func NewResourceFlavorOptions(streams genericiooptions.IOStreams, clock clock.Clock) *ResourceFlavorOptions { + return &ResourceFlavorOptions{ + PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme), + IOStreams: streams, + Clock: clock, + } +} + +func NewResourceFlavorCmd(clientGetter util.ClientGetter, streams genericiooptions.IOStreams, clock clock.Clock) *cobra.Command { + o := NewResourceFlavorOptions(streams, clock) + + cmd := &cobra.Command{ + Use: "resourceflavor [--selector KEY=VALUE] [--field-selector FIELD_NAME=VALUE]", + DisableFlagsInUseLine: true, + Aliases: []string{"rf"}, + Short: "List ResourceFlavor", + Example: rfExample, + Run: func(cmd *cobra.Command, args []string) { + cobra.CheckErr(o.Complete(clientGetter)) + cobra.CheckErr(o.Run(cmd.Context())) + }, + } + + o.PrintFlags.AddFlags(cmd) + + addFieldSelectorFlagVar(cmd, &o.FieldSelector) + addLabelSelectorFlagVar(cmd, &o.LabelSelector) + + return cmd +} + +// Complete completes all the required options +func (o *ResourceFlavorOptions) Complete(clientGetter util.ClientGetter) error { + var err error + + o.Limit, err = listRequestLimit() + if err != nil { + return err + } + + clientset, err := clientGetter.KueueClientSet() + if err != nil { + return err + } + + o.Client = clientset.KueueV1beta1() + + return nil +} + +func (o *ResourceFlavorOptions) ToPrinter(headers bool) (printers.ResourcePrinterFunc, error) { + if !o.PrintFlags.OutputFlagSpecified() { + printer := newResourceFlavorTablePrinter().WithHeaders(headers).WithClock(o.Clock) + return printer.PrintObj, nil + } + + printer, err := o.PrintFlags.ToPrinter() + if err != nil { + return nil, err + } + + return printer.PrintObj, nil +} + +// Run performs the list operation. +func (o *ResourceFlavorOptions) Run(ctx context.Context) error { + var totalCount int + + opts := metav1.ListOptions{ + LabelSelector: o.LabelSelector, + FieldSelector: o.FieldSelector, + Limit: o.Limit, + } + + tabWriter := printers.GetNewTabWriter(o.Out) + + for { + headers := totalCount == 0 + + list, err := o.Client.ResourceFlavors().List(ctx, opts) + if err != nil { + return err + } + + totalCount += len(list.Items) + + printer, err := o.ToPrinter(headers) + if err != nil { + return err + } + + if err := printer.PrintObj(list, tabWriter); err != nil { + return err + } + + if list.Continue != "" { + opts.Continue = list.Continue + continue + } + + if totalCount == 0 { + fmt.Fprintln(o.ErrOut, "No resources found") + return nil + } + + if err := tabWriter.Flush(); err != nil { + return err + } + + return nil + } +} diff --git a/cmd/kueuectl/app/list/list_resourceflavor_printer.go b/cmd/kueuectl/app/list/list_resourceflavor_printer.go new file mode 100644 index 0000000000..28ab42f60c --- /dev/null +++ b/cmd/kueuectl/app/list/list_resourceflavor_printer.go @@ -0,0 +1,89 @@ +/* +Copyright 2024 The Kubernetes Authors. + +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 list + +import ( + "errors" + "io" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/duration" + "k8s.io/cli-runtime/pkg/printers" + "k8s.io/utils/clock" + + "sigs.k8s.io/kueue/apis/kueue/v1beta1" +) + +type listResourceFlavorPrinter struct { + clock clock.Clock + printOptions printers.PrintOptions +} + +var _ printers.ResourcePrinter = (*listResourceFlavorPrinter)(nil) + +func (p *listResourceFlavorPrinter) PrintObj(obj runtime.Object, out io.Writer) error { + printer := printers.NewTablePrinter(p.printOptions) + + list, ok := obj.(*v1beta1.ResourceFlavorList) + if !ok { + return errors.New("invalid object type") + } + + table := &metav1.Table{ + ColumnDefinitions: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Age", Type: "string"}, + }, + Rows: p.printResourceFlavorList(list), + } + + return printer.PrintObj(table, out) +} + +func (p *listResourceFlavorPrinter) WithHeaders(f bool) *listResourceFlavorPrinter { + p.printOptions.NoHeaders = !f + return p +} + +func (p *listResourceFlavorPrinter) WithClock(c clock.Clock) *listResourceFlavorPrinter { + p.clock = c + return p +} + +func newResourceFlavorTablePrinter() *listResourceFlavorPrinter { + return &listResourceFlavorPrinter{ + clock: clock.RealClock{}, + } +} + +func (p *listResourceFlavorPrinter) printResourceFlavorList(list *v1beta1.ResourceFlavorList) []metav1.TableRow { + rows := make([]metav1.TableRow, len(list.Items)) + for index := range list.Items { + rows[index] = p.printResourceFlavor(&list.Items[index]) + } + return rows +} + +func (p *listResourceFlavorPrinter) printResourceFlavor(resourceFlavor *v1beta1.ResourceFlavor) metav1.TableRow { + row := metav1.TableRow{Object: runtime.RawExtension{Object: resourceFlavor}} + row.Cells = []any{ + resourceFlavor.Name, + duration.HumanDuration(p.clock.Since(resourceFlavor.CreationTimestamp.Time)), + } + return row +} diff --git a/cmd/kueuectl/app/list/list_resourceflavor_printer_test.go b/cmd/kueuectl/app/list/list_resourceflavor_printer_test.go new file mode 100644 index 0000000000..5f4dd13fd2 --- /dev/null +++ b/cmd/kueuectl/app/list/list_resourceflavor_printer_test.go @@ -0,0 +1,70 @@ +/* +Copyright 2024 The Kubernetes Authors. + +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 list + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + testingclock "k8s.io/utils/clock/testing" + + "sigs.k8s.io/kueue/apis/kueue/v1beta1" + utiltesting "sigs.k8s.io/kueue/pkg/util/testing" +) + +func TestResourceFlavorPrint(t *testing.T) { + testStartTime := time.Now() + + testCases := map[string]struct { + options *ResourceFlavorOptions + in *v1beta1.ResourceFlavorList + out []metav1.TableRow + }{ + "should print resource flavor list": { + options: &ResourceFlavorOptions{}, + in: &v1beta1.ResourceFlavorList{ + Items: []v1beta1.ResourceFlavor{ + *utiltesting.MakeResourceFlavor("rf"). + Creation(testStartTime.Add(-time.Hour).Truncate(time.Second)). + Obj(), + }, + }, + out: []metav1.TableRow{ + { + Cells: []any{"rf", "60m"}, + Object: runtime.RawExtension{ + Object: utiltesting.MakeResourceFlavor("rf"). + Creation(testStartTime.Add(-time.Hour).Truncate(time.Second)). + Obj(), + }, + }, + }, + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + p := newResourceFlavorTablePrinter().WithClock(testingclock.NewFakeClock(testStartTime)) + out := p.printResourceFlavorList(tc.in) + if diff := cmp.Diff(tc.out, out); diff != "" { + t.Errorf("Unexpected result (-want,+got):\n%s", diff) + } + }) + } +} diff --git a/cmd/kueuectl/app/list/list_resourceflavor_test.go b/cmd/kueuectl/app/list/list_resourceflavor_test.go new file mode 100644 index 0000000000..a751466f81 --- /dev/null +++ b/cmd/kueuectl/app/list/list_resourceflavor_test.go @@ -0,0 +1,121 @@ +/* +Copyright 2024 The Kubernetes Authors. + +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 list + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/cli-runtime/pkg/genericiooptions" + testingclock "k8s.io/utils/clock/testing" + + "sigs.k8s.io/kueue/client-go/clientset/versioned/fake" + cmdtesting "sigs.k8s.io/kueue/cmd/kueuectl/app/testing" + utiltesting "sigs.k8s.io/kueue/pkg/util/testing" +) + +func TestResourceFlavorCmd(t *testing.T) { + testStartTime := time.Now() + + testCases := map[string]struct { + objs []runtime.Object + args []string + wantOut string + wantOutErr string + wantErr error + }{ + "should print resource flavor list with namespace filter": { + objs: []runtime.Object{ + utiltesting.MakeResourceFlavor("rf1"). + Creation(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)). + Obj(), + utiltesting.MakeResourceFlavor("rf2"). + Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). + Obj(), + }, + wantOut: `NAME AGE +rf1 60m +rf2 120m +`, + }, + "should print resource flavor list with label selector filter": { + args: []string{"--selector", "key=value1"}, + objs: []runtime.Object{ + utiltesting.MakeResourceFlavor("rf1"). + Label("key", "value1"). + Creation(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)). + Obj(), + utiltesting.MakeResourceFlavor("rf2"). + Creation(testStartTime.Add(-2*time.Hour).Truncate(time.Second)). + Label("key", "value2"). + Obj(), + }, + wantOut: `NAME AGE +rf1 60m +`, + }, + "should print resource flavor list with label selector filter (short flag)": { + args: []string{"-l", "foo=bar"}, + objs: []runtime.Object{ + utiltesting.MakeResourceFlavor("rf1"). + Label("foo", "bar"). + Creation(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)). + Obj(), + utiltesting.MakeResourceFlavor("rf2"). + Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). + Obj(), + }, + wantOut: `NAME AGE +rf1 60m +`, + }, + "should print not found error": { + wantOutErr: "No resources found\n", + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + streams, _, out, outErr := genericiooptions.NewTestIOStreams() + + tf := cmdtesting.NewTestClientGetter() + tf.KueueClientset = fake.NewSimpleClientset(tc.objs...) + + cmd := NewResourceFlavorCmd(tf, streams, testingclock.NewFakeClock(testStartTime)) + cmd.SetOut(out) + cmd.SetErr(outErr) + cmd.SetArgs(tc.args) + + gotErr := cmd.Execute() + if diff := cmp.Diff(tc.wantErr, gotErr, cmpopts.EquateErrors()); diff != "" { + t.Errorf("Unexpected error (-want/+got)\n%s", diff) + } + + gotOut := out.String() + if diff := cmp.Diff(tc.wantOut, gotOut); diff != "" { + t.Errorf("Unexpected output (-want/+got)\n%s", diff) + } + + gotOutErr := outErr.String() + if diff := cmp.Diff(tc.wantOutErr, gotOutErr); diff != "" { + t.Errorf("Unexpected output (-want/+got)\n%s", diff) + } + }) + } +} diff --git a/keps/2076-kueuectl/README.md b/keps/2076-kueuectl/README.md index 168aec405d..67f23ad939 100644 --- a/keps/2076-kueuectl/README.md +++ b/keps/2076-kueuectl/README.md @@ -16,6 +16,7 @@ - [List ClusterQueue](#list-clusterqueue) - [List LocalQueue](#list-localqueue) - [List Workloads](#list-workloads) + - [List ResourceFlavors](#list-resourceflavors) - [Stop ClusterQueue](#stop-clusterqueue) - [Resume ClusterQueue](#resume-clusterqueue) - [Stop LocalQueue](#stop-localqueue) @@ -225,6 +226,18 @@ Output: * Position in Queue (if Pending) * Age +### List ResourceFlavors + +Lists ResourceFlavors. Format: + +``` +kueuectl list resourceflavors +``` + +Output: + +* Name +* Age ### Stop ClusterQueue diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go index c7e7e6f2b6..420b40d33e 100644 --- a/pkg/cache/cache_test.go +++ b/pkg/cache/cache_test.go @@ -82,7 +82,7 @@ func TestCacheClusterQueueOperations(t *testing.T) { setup := func(cache *Cache) error { cache.AddOrUpdateResourceFlavor( utiltesting.MakeResourceFlavor("default"). - Label("cpuType", "default"). + NodeLabel("cpuType", "default"). Obj()) for _, c := range initialClusterQueues { if err := cache.AddClusterQueue(context.Background(), &c); err != nil { @@ -256,7 +256,7 @@ func TestCacheClusterQueueOperations(t *testing.T) { } cache.AddOrUpdateResourceFlavor( utiltesting.MakeResourceFlavor("default"). - Label("cpuType", "default"). + NodeLabel("cpuType", "default"). Obj()) return nil }, @@ -386,8 +386,8 @@ func TestCacheClusterQueueOperations(t *testing.T) { } cache.AddOrUpdateResourceFlavor( utiltesting.MakeResourceFlavor("default"). - Label("cpuType", "default"). - Label("region", "central"). + NodeLabel("cpuType", "default"). + NodeLabel("region", "central"). Obj()) return nil }, diff --git a/pkg/cache/snapshot_test.go b/pkg/cache/snapshot_test.go index 2a8e7aedef..8366675d21 100644 --- a/pkg/cache/snapshot_test.go +++ b/pkg/cache/snapshot_test.go @@ -109,12 +109,12 @@ func TestSnapshot(t *testing.T) { "resourceFlavors": { rfs: []*kueue.ResourceFlavor{ utiltesting.MakeResourceFlavor("demand"). - Label("a", "b"). - Label("instance", "demand"). + NodeLabel("a", "b"). + NodeLabel("instance", "demand"). Obj(), utiltesting.MakeResourceFlavor("spot"). - Label("c", "d"). - Label("instance", "spot"). + NodeLabel("c", "d"). + NodeLabel("instance", "spot"). Obj(), utiltesting.MakeResourceFlavor("default").Obj(), }, @@ -122,12 +122,12 @@ func TestSnapshot(t *testing.T) { ClusterQueues: map[string]*ClusterQueueSnapshot{}, ResourceFlavors: map[kueue.ResourceFlavorReference]*kueue.ResourceFlavor{ "demand": utiltesting.MakeResourceFlavor("demand"). - Label("a", "b"). - Label("instance", "demand"). + NodeLabel("a", "b"). + NodeLabel("instance", "demand"). Obj(), "spot": utiltesting.MakeResourceFlavor("spot"). - Label("c", "d"). - Label("instance", "spot"). + NodeLabel("c", "d"). + NodeLabel("instance", "spot"). Obj(), "default": utiltesting.MakeResourceFlavor("default").Obj(), }, @@ -158,8 +158,8 @@ func TestSnapshot(t *testing.T) { Obj(), }, rfs: []*kueue.ResourceFlavor{ - utiltesting.MakeResourceFlavor("demand").Label("instance", "demand").Obj(), - utiltesting.MakeResourceFlavor("spot").Label("instance", "spot").Obj(), + utiltesting.MakeResourceFlavor("demand").NodeLabel("instance", "demand").Obj(), + utiltesting.MakeResourceFlavor("spot").NodeLabel("instance", "spot").Obj(), utiltesting.MakeResourceFlavor("default").Obj(), }, wls: []*kueue.Workload{ @@ -359,8 +359,8 @@ func TestSnapshot(t *testing.T) { }, }, ResourceFlavors: map[kueue.ResourceFlavorReference]*kueue.ResourceFlavor{ - "demand": utiltesting.MakeResourceFlavor("demand").Label("instance", "demand").Obj(), - "spot": utiltesting.MakeResourceFlavor("spot").Label("instance", "spot").Obj(), + "demand": utiltesting.MakeResourceFlavor("demand").NodeLabel("instance", "demand").Obj(), + "spot": utiltesting.MakeResourceFlavor("spot").NodeLabel("instance", "spot").Obj(), "default": utiltesting.MakeResourceFlavor("default").Obj(), }, } @@ -430,8 +430,8 @@ func TestSnapshot(t *testing.T) { Obj(), }, rfs: []*kueue.ResourceFlavor{ - utiltesting.MakeResourceFlavor("arm").Label("arch", "arm").Obj(), - utiltesting.MakeResourceFlavor("x86").Label("arch", "x86").Obj(), + utiltesting.MakeResourceFlavor("arm").NodeLabel("arch", "arm").Obj(), + utiltesting.MakeResourceFlavor("x86").NodeLabel("arch", "x86").Obj(), }, wls: []*kueue.Workload{ utiltesting.MakeWorkload("alpha", ""). @@ -597,8 +597,8 @@ func TestSnapshot(t *testing.T) { }, }, ResourceFlavors: map[kueue.ResourceFlavorReference]*kueue.ResourceFlavor{ - "arm": utiltesting.MakeResourceFlavor("arm").Label("arch", "arm").Obj(), - "x86": utiltesting.MakeResourceFlavor("x86").Label("arch", "x86").Obj(), + "arm": utiltesting.MakeResourceFlavor("arm").NodeLabel("arch", "arm").Obj(), + "x86": utiltesting.MakeResourceFlavor("x86").NodeLabel("arch", "x86").Obj(), }, } }(), diff --git a/pkg/controller/admissionchecks/provisioning/controller_test.go b/pkg/controller/admissionchecks/provisioning/controller_test.go index ef0a496c4d..175146c5f3 100644 --- a/pkg/controller/admissionchecks/provisioning/controller_test.go +++ b/pkg/controller/admissionchecks/provisioning/controller_test.go @@ -131,7 +131,7 @@ func TestReconcile(t *testing.T) { State: kueue.CheckStateReady, }) - baseFlavor1 := utiltesting.MakeResourceFlavor("flv1").Label("f1l1", "v1"). + baseFlavor1 := utiltesting.MakeResourceFlavor("flv1").NodeLabel("f1l1", "v1"). Toleration(corev1.Toleration{ Key: "f1t1k", Value: "f1t1v", @@ -139,7 +139,7 @@ func TestReconcile(t *testing.T) { Effect: corev1.TaintEffectNoSchedule, }). Obj() - baseFlavor2 := utiltesting.MakeResourceFlavor("flv2").Label("f2l1", "v1").Obj() + baseFlavor2 := utiltesting.MakeResourceFlavor("flv2").NodeLabel("f2l1", "v1").Obj() baseRequest := &autoscaling.ProvisioningRequest{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/controller/jobs/kubeflow/jobs/mxjob/mxjob_controller_test.go b/pkg/controller/jobs/kubeflow/jobs/mxjob/mxjob_controller_test.go index 013f366228..502d62cf44 100644 --- a/pkg/controller/jobs/kubeflow/jobs/mxjob/mxjob_controller_test.go +++ b/pkg/controller/jobs/kubeflow/jobs/mxjob/mxjob_controller_test.go @@ -479,8 +479,8 @@ func TestReconciler(t *testing.T) { "when workload is admitted, job gets node selectors": { flavors: []kueue.ResourceFlavor{ *utiltesting.MakeResourceFlavor("default").Obj(), - *utiltesting.MakeResourceFlavor("on-demand").Label("provisioning", "on-demand").Obj(), - *utiltesting.MakeResourceFlavor("spot").Label("provisioning", "spot").Obj(), + *utiltesting.MakeResourceFlavor("on-demand").NodeLabel("provisioning", "on-demand").Obj(), + *utiltesting.MakeResourceFlavor("spot").NodeLabel("provisioning", "spot").Obj(), }, job: testingmxjob.MakeMXJob("mxjob", "ns"). Image(""). diff --git a/pkg/controller/jobs/pod/pod_controller_test.go b/pkg/controller/jobs/pod/pod_controller_test.go index 94a5485f98..47e453a6f0 100644 --- a/pkg/controller/jobs/pod/pod_controller_test.go +++ b/pkg/controller/jobs/pod/pod_controller_test.go @@ -168,7 +168,7 @@ func TestReconciler(t *testing.T) { }{ "scheduling gate is removed and node selector is added if workload is admitted": { initObjects: []client.Object{ - utiltesting.MakeResourceFlavor("unit-test-flavor").Label("kubernetes.io/arch", "arm64").Obj(), + utiltesting.MakeResourceFlavor("unit-test-flavor").NodeLabel("kubernetes.io/arch", "arm64").Obj(), }, pods: []corev1.Pod{*basePodWrapper. Clone(). @@ -691,7 +691,7 @@ func TestReconciler(t *testing.T) { }, "scheduling gate is removed for all pods in the group if workload is admitted": { initObjects: []client.Object{ - utiltesting.MakeResourceFlavor("unit-test-flavor").Label("kubernetes.io/arch", "arm64").Obj(), + utiltesting.MakeResourceFlavor("unit-test-flavor").NodeLabel("kubernetes.io/arch", "arm64").Obj(), }, pods: []corev1.Pod{ *basePodWrapper. diff --git a/pkg/controller/jobs/raycluster/raycluster_controller_test.go b/pkg/controller/jobs/raycluster/raycluster_controller_test.go index 0179d12d8f..56e848e446 100644 --- a/pkg/controller/jobs/raycluster/raycluster_controller_test.go +++ b/pkg/controller/jobs/raycluster/raycluster_controller_test.go @@ -72,7 +72,7 @@ func TestReconciler(t *testing.T) { }{ "when workload is admitted, cluster is unsuspended": { initObjects: []client.Object{ - utiltesting.MakeResourceFlavor("unit-test-flavor").Label("kubernetes.io/arch", "arm64").Obj(), + utiltesting.MakeResourceFlavor("unit-test-flavor").NodeLabel("kubernetes.io/arch", "arm64").Obj(), }, job: *baseJobWrapper.Clone(). Obj(), @@ -206,7 +206,7 @@ func TestReconciler(t *testing.T) { }, "when workload is admitted but workload's conditions is Evicted, suspend it and restore node selector": { initObjects: []client.Object{ - utiltesting.MakeResourceFlavor("unit-test-flavor").Label("kubernetes.io/arch", "arm64").Obj(), + utiltesting.MakeResourceFlavor("unit-test-flavor").NodeLabel("kubernetes.io/arch", "arm64").Obj(), }, job: *baseJobWrapper.Clone(). Suspend(false). diff --git a/pkg/podset/podset_test.go b/pkg/podset/podset_test.go index 82cd0fbd48..75e2f4d324 100644 --- a/pkg/podset/podset_test.go +++ b/pkg/podset/podset_test.go @@ -50,15 +50,15 @@ func TestFromAssignment(t *testing.T) { } flavor1 := utiltesting.MakeResourceFlavor("flavor1"). - Label("f1l1", "f1v1"). - Label("f1l2", "f1v2"). + NodeLabel("f1l1", "f1v1"). + NodeLabel("f1l2", "f1v2"). Toleration(*toleration1.DeepCopy()). Toleration(*toleration2.DeepCopy()). Obj() flavor2 := utiltesting.MakeResourceFlavor("flavor2"). - Label("f2l1", "f2v1"). - Label("f2l2", "f2v2"). + NodeLabel("f2l1", "f2v1"). + NodeLabel("f2l2", "f2v2"). Toleration(*toleration3.DeepCopy()). Obj() diff --git a/pkg/scheduler/flavorassigner/flavorassigner_test.go b/pkg/scheduler/flavorassigner/flavorassigner_test.go index 6f08ac32aa..b5e7897850 100644 --- a/pkg/scheduler/flavorassigner/flavorassigner_test.go +++ b/pkg/scheduler/flavorassigner/flavorassigner_test.go @@ -46,10 +46,10 @@ func TestAssignFlavors(t *testing.T) { "default": { ObjectMeta: metav1.ObjectMeta{Name: "default"}, }, - "one": utiltesting.MakeResourceFlavor("one").Label("type", "one").Obj(), - "two": utiltesting.MakeResourceFlavor("two").Label("type", "two").Obj(), - "b_one": utiltesting.MakeResourceFlavor("b_one").Label("b_type", "one").Obj(), - "b_two": utiltesting.MakeResourceFlavor("b_two").Label("b_type", "two").Obj(), + "one": utiltesting.MakeResourceFlavor("one").NodeLabel("type", "one").Obj(), + "two": utiltesting.MakeResourceFlavor("two").NodeLabel("type", "two").Obj(), + "b_one": utiltesting.MakeResourceFlavor("b_one").NodeLabel("b_type", "one").Obj(), + "b_two": utiltesting.MakeResourceFlavor("b_two").NodeLabel("b_type", "two").Obj(), "tainted": utiltesting.MakeResourceFlavor("tainted"). Taint(corev1.Taint{ Key: "instance", diff --git a/pkg/util/testing/wrappers.go b/pkg/util/testing/wrappers.go index 43ebc4c631..fd26e8315a 100644 --- a/pkg/util/testing/wrappers.go +++ b/pkg/util/testing/wrappers.go @@ -831,8 +831,17 @@ func (rf *ResourceFlavorWrapper) Obj() *kueue.ResourceFlavor { return &rf.ResourceFlavor } -// Label add a label kueue and value pair to the ResourceFlavor. +// Label sets the label on the ResourceFlavor. func (rf *ResourceFlavorWrapper) Label(k, v string) *ResourceFlavorWrapper { + if rf.ObjectMeta.Labels == nil { + rf.ObjectMeta.Labels = map[string]string{} + } + rf.ObjectMeta.Labels[k] = v + return rf +} + +// NodeLabel add a label kueue and value pair to the ResourceFlavor. +func (rf *ResourceFlavorWrapper) NodeLabel(k, v string) *ResourceFlavorWrapper { rf.Spec.NodeLabels[k] = v return rf } @@ -849,6 +858,12 @@ func (rf *ResourceFlavorWrapper) Toleration(t corev1.Toleration) *ResourceFlavor return rf } +// Creation sets the creation timestamp of the LocalQueue. +func (rf *ResourceFlavorWrapper) Creation(t time.Time) *ResourceFlavorWrapper { + rf.CreationTimestamp = metav1.NewTime(t) + return rf +} + // RuntimeClassWrapper wraps a RuntimeClass. type RuntimeClassWrapper struct{ nodev1.RuntimeClass } diff --git a/pkg/webhooks/resourceflavor_webhook_test.go b/pkg/webhooks/resourceflavor_webhook_test.go index 518b2c807e..a35676b4f7 100644 --- a/pkg/webhooks/resourceflavor_webhook_test.go +++ b/pkg/webhooks/resourceflavor_webhook_test.go @@ -42,7 +42,7 @@ func TestValidateResourceFlavor(t *testing.T) { { name: "valid", rf: utiltesting.MakeResourceFlavor("resource-flavor"). - Label("foo", "bar"). + NodeLabel("foo", "bar"). Taint(corev1.Taint{ Key: "spot", Value: "true", @@ -51,14 +51,14 @@ func TestValidateResourceFlavor(t *testing.T) { }, { name: "invalid label name", - rf: utiltesting.MakeResourceFlavor("resource-flavor").Label("@abc", "foo").Obj(), + rf: utiltesting.MakeResourceFlavor("resource-flavor").NodeLabel("@abc", "foo").Obj(), wantErr: field.ErrorList{ field.Invalid(field.NewPath("spec", "nodeLabels"), "@abc", ""), }, }, { name: "invalid label value", - rf: utiltesting.MakeResourceFlavor("resource-flavor").Label("foo", "@abc").Obj(), + rf: utiltesting.MakeResourceFlavor("resource-flavor").NodeLabel("foo", "@abc").Obj(), wantErr: field.ErrorList{ field.Invalid(field.NewPath("spec", "nodeLabels"), "@abc", ""), }, diff --git a/site/content/en/docs/reference/kubectl-kueue/commands/list.md b/site/content/en/docs/reference/kubectl-kueue/commands/list.md index 212e296108..8bfb800826 100644 --- a/site/content/en/docs/reference/kubectl-kueue/commands/list.md +++ b/site/content/en/docs/reference/kubectl-kueue/commands/list.md @@ -1,7 +1,7 @@ --- title: "kubectl kueue list" linkTitle: "List" -date: 2024-05-13 +date: 2024-07-03 weight: 10 description: > List resource @@ -24,14 +24,18 @@ kubectl kueue list localqueue # List workloads kubectl kueue list workload + +# List resource flavors +kubectl kueue list resourceflavor ``` ## Resource types The following table includes a list of all the supported resource types and their abbreviated aliases: -| Name | Short | API version | Namespaced | Kind | -|--------------|-------|------------------------|------------|--------------| -| localqueue | lq | kueue.x-k8s.io/v1beta1 | true | LocalQueue | -| clusterqueue | cq | kueue.x-k8s.io/v1beta1 | false | ClusterQueue | -| workload | wl | kueue.x-k8s.io/v1beta1 | true | WorkLoad | +| Name | Short | API version | Namespaced | Kind | +|----------------|-------|------------------------|------------|----------------| +| localqueue | lq | kueue.x-k8s.io/v1beta1 | true | LocalQueue | +| clusterqueue | cq | kueue.x-k8s.io/v1beta1 | false | ClusterQueue | +| workload | wl | kueue.x-k8s.io/v1beta1 | true | WorkLoad | +| resourceflavor | wl | kueue.x-k8s.io/v1beta1 | false | ResourceFlavor | diff --git a/test/e2e/singlecluster/e2e_test.go b/test/e2e/singlecluster/e2e_test.go index 92b3f27a23..fc39dd2819 100644 --- a/test/e2e/singlecluster/e2e_test.go +++ b/test/e2e/singlecluster/e2e_test.go @@ -95,10 +95,10 @@ var _ = ginkgo.Describe("Kueue", func() { ) ginkgo.BeforeEach(func() { onDemandRF = testing.MakeResourceFlavor("on-demand"). - Label("instance-type", "on-demand").Obj() + NodeLabel("instance-type", "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandRF)).Should(gomega.Succeed()) spotRF = testing.MakeResourceFlavor("spot"). - Label("instance-type", "spot").Obj() + NodeLabel("instance-type", "spot").Obj() gomega.Expect(k8sClient.Create(ctx, spotRF)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("cluster-queue"). ResourceGroup( @@ -336,7 +336,7 @@ var _ = ginkgo.Describe("Kueue", func() { gomega.Expect(k8sClient.Create(ctx, check)).Should(gomega.Succeed()) util.SetAdmissionCheckActive(ctx, k8sClient, check, metav1.ConditionTrue) onDemandRF = testing.MakeResourceFlavor("on-demand"). - Label("instance-type", "on-demand").Obj() + NodeLabel("instance-type", "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandRF)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("cluster-queue"). ResourceGroup( diff --git a/test/e2e/singlecluster/pod_test.go b/test/e2e/singlecluster/pod_test.go index 7ae30958ba..bfe03f05bc 100644 --- a/test/e2e/singlecluster/pod_test.go +++ b/test/e2e/singlecluster/pod_test.go @@ -59,7 +59,7 @@ var _ = ginkgo.Describe("Pod groups", func() { }, } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandRF = testing.MakeResourceFlavor("on-demand").Label("instance-type", "on-demand").Obj() + onDemandRF = testing.MakeResourceFlavor("on-demand").NodeLabel("instance-type", "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandRF)).To(gomega.Succeed()) }) ginkgo.AfterEach(func() { diff --git a/test/integration/controller/admissionchecks/provisioning/provisioning_test.go b/test/integration/controller/admissionchecks/provisioning/provisioning_test.go index a4965d70e8..8d4d9aa1fd 100644 --- a/test/integration/controller/admissionchecks/provisioning/provisioning_test.go +++ b/test/integration/controller/admissionchecks/provisioning/provisioning_test.go @@ -127,7 +127,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure Obj() gomega.Expect(k8sClient.Create(ctx, ac)).To(gomega.Succeed()) - rf = testing.MakeResourceFlavor(flavorOnDemand).Label("ns1", "ns1v").Obj() + rf = testing.MakeResourceFlavor(flavorOnDemand).NodeLabel("ns1", "ns1v").Obj() gomega.Expect(k8sClient.Create(ctx, rf)).To(gomega.Succeed()) cq = testing.MakeClusterQueue("cluster-queue"). @@ -952,7 +952,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure Obj() gomega.Expect(k8sClient.Create(ctx, ac)).To(gomega.Succeed()) - rf = testing.MakeResourceFlavor("rf1").Label("ns1", "ns1v").Obj() + rf = testing.MakeResourceFlavor("rf1").NodeLabel("ns1", "ns1v").Obj() gomega.Expect(k8sClient.Create(ctx, rf)).To(gomega.Succeed()) cq = testing.MakeClusterQueue("cluster-queue"). diff --git a/test/integration/controller/core/clusterqueue_controller_test.go b/test/integration/controller/core/clusterqueue_controller_test.go index 3d87802384..f8c7a36a96 100644 --- a/test/integration/controller/core/clusterqueue_controller_test.go +++ b/test/integration/controller/core/clusterqueue_controller_test.go @@ -214,9 +214,9 @@ var _ = ginkgo.Describe("ClusterQueue controller", ginkgo.Ordered, ginkgo.Contin gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).To(gomega.Succeed()) spotFlavor = testing.MakeResourceFlavor(flavorSpot).Obj() gomega.Expect(k8sClient.Create(ctx, spotFlavor)).To(gomega.Succeed()) - modelAFlavor = testing.MakeResourceFlavor(flavorModelA).Label(resourceGPU.String(), flavorModelA).Obj() + modelAFlavor = testing.MakeResourceFlavor(flavorModelA).NodeLabel(resourceGPU.String(), flavorModelA).Obj() gomega.Expect(k8sClient.Create(ctx, modelAFlavor)).To(gomega.Succeed()) - modelBFlavor = testing.MakeResourceFlavor(flavorModelB).Label(resourceGPU.String(), flavorModelB).Obj() + modelBFlavor = testing.MakeResourceFlavor(flavorModelB).NodeLabel(resourceGPU.String(), flavorModelB).Obj() gomega.Expect(k8sClient.Create(ctx, modelBFlavor)).To(gomega.Succeed()) ginkgo.By("Set workloads quota reservation") @@ -424,9 +424,9 @@ var _ = ginkgo.Describe("ClusterQueue controller", ginkgo.Ordered, ginkgo.Contin gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).To(gomega.Succeed()) spotFlavor = testing.MakeResourceFlavor(flavorSpot).Obj() gomega.Expect(k8sClient.Create(ctx, spotFlavor)).To(gomega.Succeed()) - modelAFlavor = testing.MakeResourceFlavor(flavorModelA).Label(resourceGPU.String(), flavorModelA).Obj() + modelAFlavor = testing.MakeResourceFlavor(flavorModelA).NodeLabel(resourceGPU.String(), flavorModelA).Obj() gomega.Expect(k8sClient.Create(ctx, modelAFlavor)).To(gomega.Succeed()) - modelBFlavor = testing.MakeResourceFlavor(flavorModelB).Label(resourceGPU.String(), flavorModelB).Obj() + modelBFlavor = testing.MakeResourceFlavor(flavorModelB).NodeLabel(resourceGPU.String(), flavorModelB).Obj() gomega.Expect(k8sClient.Create(ctx, modelBFlavor)).To(gomega.Succeed()) }) diff --git a/test/integration/controller/core/localqueue_controller_test.go b/test/integration/controller/core/localqueue_controller_test.go index df4365c927..88521e6f3c 100644 --- a/test/integration/controller/core/localqueue_controller_test.go +++ b/test/integration/controller/core/localqueue_controller_test.go @@ -42,8 +42,8 @@ var _ = ginkgo.Describe("Queue controller", ginkgo.Ordered, ginkgo.ContinueOnFai queue *kueue.LocalQueue clusterQueue *kueue.ClusterQueue resourceFlavors = []kueue.ResourceFlavor{ - *testing.MakeResourceFlavor(flavorModelC).Label(resourceGPU.String(), flavorModelC).Obj(), - *testing.MakeResourceFlavor(flavorModelD).Label(resourceGPU.String(), flavorModelD).Obj(), + *testing.MakeResourceFlavor(flavorModelC).NodeLabel(resourceGPU.String(), flavorModelC).Obj(), + *testing.MakeResourceFlavor(flavorModelD).NodeLabel(resourceGPU.String(), flavorModelD).Obj(), } ac *kueue.AdmissionCheck ) diff --git a/test/integration/controller/jobs/job/job_controller_test.go b/test/integration/controller/jobs/job/job_controller_test.go index a6155c60a6..78d2486cf9 100644 --- a/test/integration/controller/jobs/job/job_controller_test.go +++ b/test/integration/controller/jobs/job/job_controller_test.go @@ -188,9 +188,9 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu }, util.Timeout, util.Interval).Should(gomega.BeTrue()) ginkgo.By("checking the job is unsuspended when workload is assigned") - onDemandFlavor := testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor := testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotFlavor := testing.MakeResourceFlavor("spot").Label(instanceKey, "spot").Obj() + spotFlavor := testing.MakeResourceFlavor("spot").NodeLabel(instanceKey, "spot").Obj() gomega.Expect(k8sClient.Create(ctx, spotFlavor)).Should(gomega.Succeed()) clusterQueue := testing.MakeClusterQueue("cluster-queue"). ResourceGroup( @@ -381,7 +381,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu ginkgo.It("Should change the suspension status of the child job when the parent's workload is not admitted", func() { ginkgo.By("Create a resource flavor") - defaultFlavor := testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + defaultFlavor := testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() gomega.Expect(k8sClient.Create(ctx, defaultFlavor)).Should(gomega.Succeed()) ginkgo.By("creating the parent job") @@ -607,7 +607,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu gomega.Expect(k8sClient.Create(ctx, clusterQueueAc)).Should(gomega.Succeed()) localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueueAc.Name).Obj() gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed()) - testFlavor = testing.MakeResourceFlavor("test-flavor").Label(instanceKey, "test-flavor").Obj() + testFlavor = testing.MakeResourceFlavor("test-flavor").NodeLabel(instanceKey, "test-flavor").Obj() gomega.Expect(k8sClient.Create(ctx, testFlavor)).Should(gomega.Succeed()) jobLookupKey = &types.NamespacedName{Name: jobName, Namespace: ns.Name} @@ -847,7 +847,7 @@ var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.O var ( ns *corev1.Namespace - defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ) ginkgo.BeforeAll(func() { @@ -1130,11 +1130,11 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) spotTaintedFlavor = testing.MakeResourceFlavor("spot-tainted"). - Label(instanceKey, "spot-tainted"). + NodeLabel(instanceKey, "spot-tainted"). Taint(corev1.Taint{ Key: instanceKey, Value: "spot-tainted", @@ -1142,7 +1142,7 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde }).Obj() gomega.Expect(k8sClient.Create(ctx, spotTaintedFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) prodClusterQ = testing.MakeClusterQueue("prod-cq"). diff --git a/test/integration/controller/jobs/jobset/jobset_controller_test.go b/test/integration/controller/jobs/jobset/jobset_controller_test.go index ffb6a91bcd..5861d4a4da 100644 --- a/test/integration/controller/jobs/jobset/jobset_controller_test.go +++ b/test/integration/controller/jobs/jobset/jobset_controller_test.go @@ -98,9 +98,9 @@ var _ = ginkgo.Describe("JobSet controller", ginkgo.Ordered, ginkgo.ContinueOnFa gomega.Expect(k8sClient.Create(ctx, clusterQueue)).Should(gomega.Succeed()) localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj() gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotFlavor = testing.MakeResourceFlavor("spot").Label(instanceKey, "spot").Obj() + spotFlavor = testing.MakeResourceFlavor("spot").NodeLabel(instanceKey, "spot").Obj() gomega.Expect(k8sClient.Create(ctx, spotFlavor)).Should(gomega.Succeed()) }) @@ -370,7 +370,7 @@ var _ = ginkgo.Describe("JobSet controller", ginkgo.Ordered, ginkgo.ContinueOnFa gomega.Expect(k8sClient.Create(ctx, clusterQueueAc)).Should(gomega.Succeed()) localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueueAc.Name).Obj() gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed()) - testFlavor = testing.MakeResourceFlavor("test-flavor").Label(instanceKey, "test-flavor").Obj() + testFlavor = testing.MakeResourceFlavor("test-flavor").NodeLabel(instanceKey, "test-flavor").Obj() gomega.Expect(k8sClient.Create(ctx, testFlavor)).Should(gomega.Succeed()) jobLookupKey = &types.NamespacedName{Name: jobSetName, Namespace: ns.Name} @@ -642,7 +642,7 @@ var _ = ginkgo.Describe("JobSet controller when waitForPodsReady enabled", ginkg wantCondition *metav1.Condition } - var defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + var defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ginkgo.BeforeAll(func() { fwk = &framework.Framework{ @@ -888,10 +888,10 @@ var _ = ginkgo.Describe("JobSet controller interacting with scheduler", ginkgo.O } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). diff --git a/test/integration/controller/jobs/kubeflow/kubeflowjob.go b/test/integration/controller/jobs/kubeflow/kubeflowjob.go index 0d9c59e8b6..faadf68c55 100644 --- a/test/integration/controller/jobs/kubeflow/kubeflowjob.go +++ b/test/integration/controller/jobs/kubeflow/kubeflowjob.go @@ -121,9 +121,9 @@ func ShouldReconcileJob(ctx context.Context, k8sClient client.Client, job, creat }, util.Timeout, util.Interval).Should(gomega.Succeed()) ginkgo.By("checking the job is unsuspended when workload is assigned") - onDemandFlavor := testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor := testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotFlavor := testing.MakeResourceFlavor("spot").Label(instanceKey, "spot").Obj() + spotFlavor := testing.MakeResourceFlavor("spot").NodeLabel(instanceKey, "spot").Obj() gomega.Expect(k8sClient.Create(ctx, spotFlavor)).Should(gomega.Succeed()) clusterQueue := testing.MakeClusterQueue("cluster-queue"). ResourceGroup( diff --git a/test/integration/controller/jobs/mpijob/mpijob_controller_test.go b/test/integration/controller/jobs/mpijob/mpijob_controller_test.go index ba727b0894..979aae6b3c 100644 --- a/test/integration/controller/jobs/mpijob/mpijob_controller_test.go +++ b/test/integration/controller/jobs/mpijob/mpijob_controller_test.go @@ -148,9 +148,9 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu }, util.Timeout, util.Interval).Should(gomega.Succeed()) ginkgo.By("checking the job is unsuspended when workload is assigned") - onDemandFlavor := testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor := testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotFlavor := testing.MakeResourceFlavor("spot").Label(instanceKey, "spot").Obj() + spotFlavor := testing.MakeResourceFlavor("spot").NodeLabel(instanceKey, "spot").Obj() gomega.Expect(k8sClient.Create(ctx, spotFlavor)).Should(gomega.Succeed()) clusterQueue := testing.MakeClusterQueue("cluster-queue"). ResourceGroup( @@ -301,7 +301,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu gomega.Expect(k8sClient.Create(ctx, clusterQueueAc)).Should(gomega.Succeed()) localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueueAc.Name).Obj() gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed()) - testFlavor = testing.MakeResourceFlavor("test-flavor").Label(instanceKey, "test-flavor").Obj() + testFlavor = testing.MakeResourceFlavor("test-flavor").NodeLabel(instanceKey, "test-flavor").Obj() gomega.Expect(k8sClient.Create(ctx, testFlavor)).Should(gomega.Succeed()) jobLookupKey = &types.NamespacedName{Name: jobName, Namespace: ns.Name} @@ -582,7 +582,7 @@ var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.O var ( ns *corev1.Namespace - defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ) ginkgo.BeforeAll(func() { @@ -812,10 +812,10 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). diff --git a/test/integration/controller/jobs/mxjob/mxjob_controller_test.go b/test/integration/controller/jobs/mxjob/mxjob_controller_test.go index e9d04754b0..fae85a7910 100644 --- a/test/integration/controller/jobs/mxjob/mxjob_controller_test.go +++ b/test/integration/controller/jobs/mxjob/mxjob_controller_test.go @@ -96,7 +96,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() { var ( ns *corev1.Namespace - defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ) ginkgo.BeforeAll(func() { @@ -260,10 +260,10 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). diff --git a/test/integration/controller/jobs/paddlejob/paddlejob_controller_test.go b/test/integration/controller/jobs/paddlejob/paddlejob_controller_test.go index 9ee70983b3..cd9709313a 100644 --- a/test/integration/controller/jobs/paddlejob/paddlejob_controller_test.go +++ b/test/integration/controller/jobs/paddlejob/paddlejob_controller_test.go @@ -94,7 +94,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() { var ( ns *corev1.Namespace - defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ) ginkgo.BeforeAll(func() { @@ -254,10 +254,10 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). diff --git a/test/integration/controller/jobs/pod/pod_controller_test.go b/test/integration/controller/jobs/pod/pod_controller_test.go index f787b62944..8bb6eebc52 100644 --- a/test/integration/controller/jobs/pod/pod_controller_test.go +++ b/test/integration/controller/jobs/pod/pod_controller_test.go @@ -59,7 +59,7 @@ var ( var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() { ginkgo.When("manageJobsWithoutQueueName is disabled", func() { - var defaultFlavor = testing.MakeResourceFlavor("default").Label("kubernetes.io/arch", "arm64").Obj() + var defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel("kubernetes.io/arch", "arm64").Obj() var clusterQueue = testing.MakeClusterQueue("cluster-queue"). ResourceGroup( *testing.MakeFlavorQuotas(defaultFlavor.Name).Resource(corev1.ResourceCPU, "1").Obj(), @@ -426,7 +426,7 @@ var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailu gomega.Expect(k8sClient.Create(ctx, clusterQueueAc)).Should(gomega.Succeed()) localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueueAc.Name).Obj() gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed()) - testFlavor = testing.MakeResourceFlavor("test-flavor").Label(instanceKey, "test-flavor").Obj() + testFlavor = testing.MakeResourceFlavor("test-flavor").NodeLabel(instanceKey, "test-flavor").Obj() gomega.Expect(k8sClient.Create(ctx, testFlavor)).Should(gomega.Succeed()) podLookupKey = &types.NamespacedName{Name: podName, Namespace: ns.Name} @@ -1412,7 +1412,7 @@ var _ = ginkgo.Describe("Pod controller interacting with scheduler", ginkgo.Orde }, }), )) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). diff --git a/test/integration/controller/jobs/pytorchjob/pytorchjob_controller_test.go b/test/integration/controller/jobs/pytorchjob/pytorchjob_controller_test.go index dfdd726383..3ee6b638a9 100644 --- a/test/integration/controller/jobs/pytorchjob/pytorchjob_controller_test.go +++ b/test/integration/controller/jobs/pytorchjob/pytorchjob_controller_test.go @@ -165,7 +165,7 @@ var _ = ginkgo.Describe("Job controller for workloads when only jobs with queue gomega.Expect(k8sClient.Create(ctx, clusterQueueAc)).Should(gomega.Succeed()) localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueueAc.Name).Obj() gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed()) - testFlavor = testing.MakeResourceFlavor("test-flavor").Label(instanceKey, "test-flavor").Obj() + testFlavor = testing.MakeResourceFlavor("test-flavor").NodeLabel(instanceKey, "test-flavor").Obj() gomega.Expect(k8sClient.Create(ctx, testFlavor)).Should(gomega.Succeed()) jobLookupKey = &types.NamespacedName{Name: jobName, Namespace: ns.Name} @@ -326,7 +326,7 @@ var _ = ginkgo.Describe("Job controller for workloads when only jobs with queue var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() { var ( ns *corev1.Namespace - defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ) ginkgo.BeforeAll(func() { @@ -486,10 +486,10 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). diff --git a/test/integration/controller/jobs/raycluster/raycluster_controller_test.go b/test/integration/controller/jobs/raycluster/raycluster_controller_test.go index ebb1ad8e6d..3a5f78fd93 100644 --- a/test/integration/controller/jobs/raycluster/raycluster_controller_test.go +++ b/test/integration/controller/jobs/raycluster/raycluster_controller_test.go @@ -152,9 +152,9 @@ var _ = ginkgo.Describe("RayCluster controller", ginkgo.Ordered, ginkgo.Continue }, util.Timeout, util.Interval).Should(gomega.Succeed()) ginkgo.By("checking the job is unsuspended when workload is assigned") - onDemandFlavor := testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor := testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotFlavor := testing.MakeResourceFlavor("spot").Label(instanceKey, "spot").Obj() + spotFlavor := testing.MakeResourceFlavor("spot").NodeLabel(instanceKey, "spot").Obj() gomega.Expect(k8sClient.Create(ctx, spotFlavor)).Should(gomega.Succeed()) clusterQueue := testing.MakeClusterQueue("cluster-queue"). ResourceGroup( @@ -335,7 +335,7 @@ var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.O wantCondition *metav1.Condition } - var defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + var defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ginkgo.BeforeAll(func() { fwk = &framework.Framework{ @@ -542,10 +542,10 @@ var _ = ginkgo.Describe("RayCluster Job controller interacting with scheduler", } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). @@ -656,7 +656,7 @@ var _ = ginkgo.Describe("Job controller with preemption enabled", ginkgo.Ordered } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("clusterqueue"). diff --git a/test/integration/controller/jobs/rayjob/rayjob_controller_test.go b/test/integration/controller/jobs/rayjob/rayjob_controller_test.go index d1bf93d32f..20fe0f010a 100644 --- a/test/integration/controller/jobs/rayjob/rayjob_controller_test.go +++ b/test/integration/controller/jobs/rayjob/rayjob_controller_test.go @@ -162,9 +162,9 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu }, util.Timeout, util.Interval).Should(gomega.Succeed()) ginkgo.By("checking the job is unsuspended when workload is assigned") - onDemandFlavor := testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor := testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotFlavor := testing.MakeResourceFlavor("spot").Label(instanceKey, "spot").Obj() + spotFlavor := testing.MakeResourceFlavor("spot").NodeLabel(instanceKey, "spot").Obj() gomega.Expect(k8sClient.Create(ctx, spotFlavor)).Should(gomega.Succeed()) clusterQueue := testing.MakeClusterQueue("cluster-queue"). ResourceGroup( @@ -332,7 +332,7 @@ var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.O wantCondition *metav1.Condition } - var defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + var defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ginkgo.BeforeAll(func() { fwk = &framework.Framework{ @@ -551,10 +551,10 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). @@ -624,7 +624,7 @@ var _ = ginkgo.Describe("Job controller with preemption enabled", ginkgo.Ordered } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("clusterqueue"). diff --git a/test/integration/controller/jobs/tfjob/tfjob_controller_test.go b/test/integration/controller/jobs/tfjob/tfjob_controller_test.go index 055db55094..0e1c97b833 100644 --- a/test/integration/controller/jobs/tfjob/tfjob_controller_test.go +++ b/test/integration/controller/jobs/tfjob/tfjob_controller_test.go @@ -97,7 +97,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() { var ( ns *corev1.Namespace - defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ) ginkgo.BeforeAll(func() { @@ -261,10 +261,10 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). diff --git a/test/integration/controller/jobs/xgboostjob/xgboostjob_controller_test.go b/test/integration/controller/jobs/xgboostjob/xgboostjob_controller_test.go index 4f9aaa48de..9ebae9e27b 100644 --- a/test/integration/controller/jobs/xgboostjob/xgboostjob_controller_test.go +++ b/test/integration/controller/jobs/xgboostjob/xgboostjob_controller_test.go @@ -92,7 +92,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu var _ = ginkgo.Describe("Job controller when waitForPodsReady enabled", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() { var ( ns *corev1.Namespace - defaultFlavor = testing.MakeResourceFlavor("default").Label(instanceKey, "default").Obj() + defaultFlavor = testing.MakeResourceFlavor("default").NodeLabel(instanceKey, "default").Obj() ) ginkgo.BeforeAll(func() { @@ -251,10 +251,10 @@ var _ = ginkgo.Describe("Job controller interacting with scheduler", ginkgo.Orde } gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() gomega.Expect(k8sClient.Create(ctx, onDemandFlavor)).Should(gomega.Succeed()) - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() gomega.Expect(k8sClient.Create(ctx, spotUntaintedFlavor)).Should(gomega.Succeed()) clusterQueue = testing.MakeClusterQueue("dev-clusterqueue"). diff --git a/test/integration/kueuectl/list_test.go b/test/integration/kueuectl/list_test.go index ee092d8c23..1ede31f934 100644 --- a/test/integration/kueuectl/list_test.go +++ b/test/integration/kueuectl/list_test.go @@ -246,4 +246,73 @@ wl2 very-long-local-queue-name ))) }) }) + + ginkgo.When("List ResourceFlavors", func() { + var ( + rf1 *v1beta1.ResourceFlavor + rf2 *v1beta1.ResourceFlavor + ) + + ginkgo.JustBeforeEach(func() { + rf1 = testing.MakeResourceFlavor("rf1").Obj() + gomega.Expect(k8sClient.Create(ctx, rf1)).To(gomega.Succeed()) + + rf2 = testing.MakeResourceFlavor("very-long-resource-flavor-name").Obj() + gomega.Expect(k8sClient.Create(ctx, rf2)).To(gomega.Succeed()) + }) + + ginkgo.JustAfterEach(func() { + util.ExpectResourceFlavorToBeDeleted(ctx, k8sClient, rf1, true) + util.ExpectResourceFlavorToBeDeleted(ctx, k8sClient, rf2, true) + }) + + // Simple client set that are using on unit tests not allow to filter by field selector. + ginkgo.It("Should print resource flavor list filtered by field selector", func() { + streams, _, output, errOutput := genericiooptions.NewTestIOStreams() + configFlags := CreateConfigFlagsWithRestConfig(cfg, streams) + executeTime := time.Now() + kueuectl := app.NewKueuectlCmd(app.KueuectlOptions{ + ConfigFlags: configFlags, + IOStreams: streams, + Clock: testingclock.NewFakeClock(executeTime), + }) + + kueuectl.SetArgs([]string{"list", "resourceflavor", "--field-selector", + fmt.Sprintf("metadata.name=%s", rf1.Name)}) + err := kueuectl.Execute() + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "%s: %s", err, output) + gomega.Expect(errOutput.String()).Should(gomega.BeEmpty()) + gomega.Expect(output.String()).Should(gomega.Equal(fmt.Sprintf(`NAME AGE +rf1 %s +`, + duration.HumanDuration(executeTime.Sub(rf1.CreationTimestamp.Time)), + ))) + }) + + // Simple client set that are using on unit tests not allow paging. + ginkgo.It("Should print resource flavor list with paging", func() { + streams, _, output, errOutput := genericiooptions.NewTestIOStreams() + configFlags := CreateConfigFlagsWithRestConfig(cfg, streams) + executeTime := time.Now() + kueuectl := app.NewKueuectlCmd(app.KueuectlOptions{ + ConfigFlags: configFlags, + IOStreams: streams, + Clock: testingclock.NewFakeClock(executeTime), + }) + + os.Setenv(list.KueuectlListRequestLimitEnvName, "1") + kueuectl.SetArgs([]string{"list", "resourceflavor"}) + err := kueuectl.Execute() + + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "%s: %s", err, output) + gomega.Expect(errOutput.String()).Should(gomega.BeEmpty()) + gomega.Expect(output.String()).Should(gomega.Equal(fmt.Sprintf(`NAME AGE +rf1 %s +very-long-resource-flavor-name %s +`, + duration.HumanDuration(executeTime.Sub(rf1.CreationTimestamp.Time)), + duration.HumanDuration(executeTime.Sub(rf2.CreationTimestamp.Time)), + ))) + }) + }) }) diff --git a/test/integration/kueuectl/passthrough_test.go b/test/integration/kueuectl/passthrough_test.go index 825dea65ca..e6e0397237 100644 --- a/test/integration/kueuectl/passthrough_test.go +++ b/test/integration/kueuectl/passthrough_test.go @@ -38,7 +38,7 @@ func makePassThroughWorkload(ns string) client.Object { } func makePassThroughResourceFlavor(_ string) client.Object { - return testing.MakeResourceFlavor("pass-through-resource-flavor").Label("type", "small").Obj() + return testing.MakeResourceFlavor("pass-through-resource-flavor").NodeLabel("type", "small").Obj() } func setupEnv(c *exec.Cmd, kassetsPath string, kubeconfigPath string) { diff --git a/test/integration/scheduler/scheduler_test.go b/test/integration/scheduler/scheduler_test.go index b731cb8934..fad64c65d2 100644 --- a/test/integration/scheduler/scheduler_test.go +++ b/test/integration/scheduler/scheduler_test.go @@ -60,10 +60,10 @@ var _ = ginkgo.Describe("Scheduler", func() { _ = features.SetEnable(features.FlavorFungibility, true) gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed()) - onDemandFlavor = testing.MakeResourceFlavor("on-demand").Label(instanceKey, "on-demand").Obj() + onDemandFlavor = testing.MakeResourceFlavor("on-demand").NodeLabel(instanceKey, "on-demand").Obj() spotTaintedFlavor = testing.MakeResourceFlavor("spot-tainted"). - Label(instanceKey, "spot-tainted"). + NodeLabel(instanceKey, "spot-tainted"). Taint(corev1.Taint{ Key: instanceKey, Value: "spot-tainted", @@ -77,7 +77,7 @@ var _ = ginkgo.Describe("Scheduler", func() { Effect: corev1.TaintEffectNoSchedule, } - spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").Label(instanceKey, "spot-untainted").Obj() + spotUntaintedFlavor = testing.MakeResourceFlavor("spot-untainted").NodeLabel(instanceKey, "spot-untainted").Obj() }) ginkgo.When("Scheduling workloads on clusterQueues", func() { diff --git a/test/integration/webhook/resourceflavor_test.go b/test/integration/webhook/resourceflavor_test.go index ceeef04436..dd2da2cc33 100644 --- a/test/integration/webhook/resourceflavor_test.go +++ b/test/integration/webhook/resourceflavor_test.go @@ -52,7 +52,7 @@ var _ = ginkgo.Describe("ResourceFlavor Webhook", func() { ginkgo.When("Creating a ResourceFlavor", func() { ginkgo.It("Should be valid", func() { - resourceFlavor := testing.MakeResourceFlavor("resource-flavor").Label("foo", "bar"). + resourceFlavor := testing.MakeResourceFlavor("resource-flavor").NodeLabel("foo", "bar"). Taint(corev1.Taint{ Key: "spot", Value: "true", @@ -94,7 +94,7 @@ var _ = ginkgo.Describe("ResourceFlavor Webhook", func() { }) } for i := 0; i < nodeSelectorCount; i++ { - rf = rf.Label(fmt.Sprintf("l%d", i), "") + rf = rf.NodeLabel(fmt.Sprintf("l%d", i), "") } resourceFlavor := rf.Obj() err := k8sClient.Create(ctx, resourceFlavor) @@ -175,7 +175,7 @@ var _ = ginkgo.Describe("ResourceFlavor Webhook", func() { }).Obj(), isInvalid), ginkgo.Entry("Should fail to create with invalid label name", - testing.MakeResourceFlavor("resource-flavor").Label("@abc", "foo").Obj(), + testing.MakeResourceFlavor("resource-flavor").NodeLabel("@abc", "foo").Obj(), isForbidden), ginkgo.Entry("Should fail to create with invalid tolerations", testing.MakeResourceFlavor("resource-flavor"). diff --git a/test/performance/scheduler/runner/generator/generator.go b/test/performance/scheduler/runner/generator/generator.go index 2450eae89b..9090059952 100644 --- a/test/performance/scheduler/runner/generator/generator.go +++ b/test/performance/scheduler/runner/generator/generator.go @@ -202,7 +202,7 @@ func Generate(ctx context.Context, c client.Client, cSets []CohortSet) error { log := ctrl.LoggerFrom(ctx).WithName("generate cohort sets").WithValues("numSets", len(cSets)) log.Info("Start generation") defer log.Info("End generation") - rf := utiltesting.MakeResourceFlavor(resourceFlavorName).Label(CleanupLabel, "true").Obj() + rf := utiltesting.MakeResourceFlavor(resourceFlavorName).NodeLabel(CleanupLabel, "true").Obj() err := c.Create(ctx, rf) if err != nil { return err