From 60cdd58641b346436ccf01b68037fed3c8facabb Mon Sep 17 00:00:00 2001 From: Karthik Vetrivel Date: Fri, 6 Mar 2026 12:12:31 -0500 Subject: [PATCH] Enable regclient debug logging in gpuop-cfg validation Signed-off-by: Karthik Vetrivel --- .../validate/clusterpolicy/clusterpolicy.go | 12 ++++++++- .../validate/clusterpolicy/images.go | 27 +++++++++---------- cmd/gpuop-cfg/validate/csv/csv.go | 12 ++++++++- cmd/gpuop-cfg/validate/csv/images.go | 11 ++++---- cmd/gpuop-cfg/validate/registry/registry.go | 26 ++++++++++++++++++ 5 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 cmd/gpuop-cfg/validate/registry/registry.go diff --git a/cmd/gpuop-cfg/validate/clusterpolicy/clusterpolicy.go b/cmd/gpuop-cfg/validate/clusterpolicy/clusterpolicy.go index 61737e0a6..169dfc3fb 100644 --- a/cmd/gpuop-cfg/validate/clusterpolicy/clusterpolicy.go +++ b/cmd/gpuop-cfg/validate/clusterpolicy/clusterpolicy.go @@ -22,11 +22,15 @@ import ( "io" "os" + "log/slog" + + "github.com/regclient/regclient" "github.com/sirupsen/logrus" "github.com/urfave/cli/v3" "sigs.k8s.io/yaml" v1 "github.com/NVIDIA/gpu-operator/api/nvidia/v1" + "github.com/NVIDIA/gpu-operator/cmd/gpuop-cfg/validate/registry" ) type command struct { @@ -83,7 +87,13 @@ func (m command) run(ctx context.Context, opts *options) error { return fmt.Errorf("failed to load clusterpolicy spec: %v", err) } - err = validateImages(ctx, &cp.Spec) + var rcOpts []regclient.Opt + if m.logger.GetLevel() >= logrus.DebugLevel { + rcOpts = append(rcOpts, regclient.WithSlog(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelDebug})))) + } + client := registry.NewClient(rcOpts...) + + err = validateImages(ctx, &cp.Spec, client) if err != nil { return fmt.Errorf("failed to validate images: %v", err) } diff --git a/cmd/gpuop-cfg/validate/clusterpolicy/images.go b/cmd/gpuop-cfg/validate/clusterpolicy/images.go index f91c2461d..eeb449b33 100644 --- a/cmd/gpuop-cfg/validate/clusterpolicy/images.go +++ b/cmd/gpuop-cfg/validate/clusterpolicy/images.go @@ -26,7 +26,7 @@ import ( v1 "github.com/NVIDIA/gpu-operator/api/nvidia/v1" ) -func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { +func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec, client *regclient.RegClient) error { // Driver path, err := v1.ImagePath(&spec.Driver) if err != nil { @@ -35,7 +35,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { // For driver, we must append the os-tag path += "-ubuntu22.04" - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -46,7 +46,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -57,7 +57,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -68,7 +68,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -79,7 +79,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -90,7 +90,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -101,7 +101,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -114,7 +114,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { // For GDS driver, we must append the os-tag path += "-ubuntu22.04" - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -125,7 +125,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -136,7 +136,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -147,7 +147,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return fmt.Errorf("failed to construct the image path: %v", err) } - err = validateImage(ctx, path) + err = validateImage(ctx, client, path) if err != nil { return fmt.Errorf("failed to validate image %s: %v", path, err) } @@ -155,8 +155,7 @@ func validateImages(ctx context.Context, spec *v1.ClusterPolicySpec) error { return nil } -func validateImage(ctx context.Context, path string) error { - var client = regclient.New() +func validateImage(ctx context.Context, client *regclient.RegClient, path string) error { ref, err := ref.New(path) if err != nil { return fmt.Errorf("failed to construct an image reference: %v", err) diff --git a/cmd/gpuop-cfg/validate/csv/csv.go b/cmd/gpuop-cfg/validate/csv/csv.go index fb10ceadb..43003c23c 100644 --- a/cmd/gpuop-cfg/validate/csv/csv.go +++ b/cmd/gpuop-cfg/validate/csv/csv.go @@ -20,12 +20,16 @@ import ( "context" "fmt" "io" + "log/slog" "os" "github.com/operator-framework/api/pkg/operators/v1alpha1" + "github.com/regclient/regclient" "github.com/sirupsen/logrus" "github.com/urfave/cli/v3" "sigs.k8s.io/yaml" + + "github.com/NVIDIA/gpu-operator/cmd/gpuop-cfg/validate/registry" ) type command struct { @@ -82,7 +86,13 @@ func (m command) run(ctx context.Context, opts *options) error { return fmt.Errorf("failed to load csv yaml: %v", err) } - err = validateImages(ctx, csv) + var rcOpts []regclient.Opt + if m.logger.GetLevel() >= logrus.DebugLevel { + rcOpts = append(rcOpts, regclient.WithSlog(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelDebug})))) + } + client := registry.NewClient(rcOpts...) + + err = validateImages(ctx, csv, client) if err != nil { return fmt.Errorf("failed to validate images: %v", err) } diff --git a/cmd/gpuop-cfg/validate/csv/images.go b/cmd/gpuop-cfg/validate/csv/images.go index 3d8e4f532..ccfa8bb97 100644 --- a/cmd/gpuop-cfg/validate/csv/images.go +++ b/cmd/gpuop-cfg/validate/csv/images.go @@ -26,11 +26,11 @@ import ( "github.com/regclient/regclient/types/ref" ) -func validateImages(ctx context.Context, csv *v1alpha1.ClusterServiceVersion) error { +func validateImages(ctx context.Context, csv *v1alpha1.ClusterServiceVersion, client *regclient.RegClient) error { // validate all 'relatedImages' images := csv.Spec.RelatedImages for _, image := range images { - err := validateImage(ctx, image.Image) + err := validateImage(ctx, client, image.Image) if err != nil { return fmt.Errorf("failed to validate image %s: %v", image.Name, err) } @@ -41,7 +41,7 @@ func validateImages(ctx context.Context, csv *v1alpha1.ClusterServiceVersion) er ctr := deployment.Spec.Template.Spec.Containers[0] // validate the gpu-operator image - err := validateImage(ctx, ctr.Image) + err := validateImage(ctx, client, ctr.Image) if err != nil { return fmt.Errorf("failed to validate image %s: %v", ctr.Image, err) } @@ -51,7 +51,7 @@ func validateImages(ctx context.Context, csv *v1alpha1.ClusterServiceVersion) er if !strings.HasSuffix(env.Name, "_IMAGE") { continue } - err = validateImage(ctx, env.Value) + err = validateImage(ctx, client, env.Value) if err != nil { return fmt.Errorf("failed to validate image %s: %v", env.Name, err) } @@ -60,8 +60,7 @@ func validateImages(ctx context.Context, csv *v1alpha1.ClusterServiceVersion) er return nil } -func validateImage(ctx context.Context, path string) error { - var client = regclient.New() +func validateImage(ctx context.Context, client *regclient.RegClient, path string) error { ref, err := ref.New(path) if err != nil { return fmt.Errorf("failed to construct an image reference: %v", err) diff --git a/cmd/gpuop-cfg/validate/registry/registry.go b/cmd/gpuop-cfg/validate/registry/registry.go new file mode 100644 index 000000000..e93c3b7cc --- /dev/null +++ b/cmd/gpuop-cfg/validate/registry/registry.go @@ -0,0 +1,26 @@ +/** +# Copyright (c), NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package registry + +import ( + "github.com/regclient/regclient" +) + +// NewClient creates a regclient client with the provided options. +func NewClient(opts ...regclient.Opt) *regclient.RegClient { + return regclient.New(opts...) +}