diff --git a/cmd/dra-multus-driver/cdi.go b/cmd/dra-multus-driver/cdi.go index 7e7011786..334708a17 100644 --- a/cmd/dra-multus-driver/cdi.go +++ b/cmd/dra-multus-driver/cdi.go @@ -20,18 +20,16 @@ import ( "fmt" "os" - "sigs.k8s.io/dra-example-driver/pkg/consts" - cdiapi "tags.cncf.io/container-device-interface/pkg/cdi" cdiparser "tags.cncf.io/container-device-interface/pkg/parser" cdispec "tags.cncf.io/container-device-interface/specs-go" ) const ( - cdiVendor = "k8s." + consts.DriverName - cdiClass = "gpu" - cdiKind = cdiVendor + "/" + cdiClass - + cdiVendor = "k8s." + DriverName + cdiClass = "gpu" + cdiKind = cdiVendor + "/" + cdiClass + DriverName = "gpu.example.com" cdiCommonDeviceName = "common" ) @@ -62,7 +60,7 @@ func (cdi *CDIHandler) CreateCommonSpecFile() error { ContainerEdits: cdispec.ContainerEdits{ Env: []string{ fmt.Sprintf("KUBERNETES_NODE_NAME=%s", os.Getenv("NODE_NAME")), - fmt.Sprintf("DRA_RESOURCE_DRIVER_NAME=%s", consts.DriverName), + fmt.Sprintf("DRA_RESOURCE_DRIVER_NAME=%s", DriverName), }, }, }, diff --git a/cmd/dra-multus-driver/driver.go b/cmd/dra-multus-driver/driver.go index eebc0a358..4c0aff498 100644 --- a/cmd/dra-multus-driver/driver.go +++ b/cmd/dra-multus-driver/driver.go @@ -26,8 +26,6 @@ import ( "k8s.io/klog/v2" drapbv1 "k8s.io/kubelet/pkg/apis/dra/v1beta1" - - "sigs.k8s.io/dra-example-driver/pkg/consts" ) var _ drapbv1.DRAPluginServer = &driver{} @@ -54,7 +52,7 @@ func NewDriver(ctx context.Context, config *Config) (*driver, error) { []any{driver}, kubeletplugin.KubeClient(config.coreclient), kubeletplugin.NodeName(config.flags.nodeName), - kubeletplugin.DriverName(consts.DriverName), + kubeletplugin.DriverName(DriverName), kubeletplugin.RegistrarSocketPath(PluginRegistrationPath), kubeletplugin.PluginSocketPath(DriverPluginSocketPath), kubeletplugin.KubeletPluginSocketPath(DriverPluginSocketPath)) diff --git a/cmd/dra-multus-driver/main.go b/cmd/dra-multus-driver/main.go index 885c7d2e1..313655d9b 100644 --- a/cmd/dra-multus-driver/main.go +++ b/cmd/dra-multus-driver/main.go @@ -28,13 +28,12 @@ import ( coreclientset "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" - "sigs.k8s.io/dra-example-driver/pkg/consts" - "sigs.k8s.io/dra-example-driver/pkg/flags" + "gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/flags" ) const ( - PluginRegistrationPath = "/var/lib/kubelet/plugins_registry/" + consts.DriverName + ".sock" - DriverPluginPath = "/var/lib/kubelet/plugins/" + consts.DriverName + PluginRegistrationPath = "/var/lib/kubelet/plugins_registry/" + DriverName + ".sock" + DriverPluginPath = "/var/lib/kubelet/plugins/" + DriverName DriverPluginSocketPath = DriverPluginPath + "/plugin.sock" DriverPluginCheckpointFile = "checkpoint.json" ) diff --git a/cmd/dra-multus-driver/state.go b/cmd/dra-multus-driver/state.go index c72de7c6a..52c6cef00 100644 --- a/cmd/dra-multus-driver/state.go +++ b/cmd/dra-multus-driver/state.go @@ -27,7 +27,6 @@ import ( "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" configapi "sigs.k8s.io/dra-example-driver/api/example.com/resource/gpu/v1alpha1" - "sigs.k8s.io/dra-example-driver/pkg/consts" cdiapi "tags.cncf.io/container-device-interface/pkg/cdi" cdispec "tags.cncf.io/container-device-interface/specs-go" @@ -181,7 +180,7 @@ func (s *DeviceState) prepareDevices(claim *resourceapi.ResourceClaim) (Prepared // Retrieve the full set of device configs for the driver. configs, err := GetOpaqueDeviceConfigs( configapi.Decoder, - consts.DriverName, + DriverName, claim.Status.Allocation.Devices.Config, ) if err != nil { diff --git a/pkg/flags/kubeclient.go b/pkg/flags/kubeclient.go new file mode 100644 index 000000000..88112ec26 --- /dev/null +++ b/pkg/flags/kubeclient.go @@ -0,0 +1,105 @@ +/* + * Copyright 2023 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 flags + +import ( + "fmt" + + "github.com/urfave/cli/v2" + + coreclientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +type KubeClientConfig struct { + KubeConfig string + KubeAPIQPS float64 + KubeAPIBurst int +} + +type ClientSets struct { + Core coreclientset.Interface +} + +func (k *KubeClientConfig) Flags() []cli.Flag { + flags := []cli.Flag{ + &cli.StringFlag{ + Category: "Kubernetes client:", + Name: "kubeconfig", + Usage: "Absolute path to the `KUBECONFIG` file. Either this flag or the KUBECONFIG env variable need to be set if the driver is being run out of cluster.", + Destination: &k.KubeConfig, + EnvVars: []string{"KUBECONFIG"}, + }, + &cli.Float64Flag{ + Category: "Kubernetes client:", + Name: "kube-api-qps", + Usage: "`QPS` to use while communicating with the Kubernetes apiserver.", + Value: 5, + Destination: &k.KubeAPIQPS, + EnvVars: []string{"KUBE_API_QPS"}, + }, + &cli.IntFlag{ + Category: "Kubernetes client:", + Name: "kube-api-burst", + Usage: "`Burst` to use while communicating with the Kubernetes apiserver.", + Value: 10, + Destination: &k.KubeAPIBurst, + EnvVars: []string{"KUBE_API_BURST"}, + }, + } + + return flags +} + +func (k *KubeClientConfig) NewClientSetConfig() (*rest.Config, error) { + var csconfig *rest.Config + + var err error + if k.KubeConfig == "" { + csconfig, err = rest.InClusterConfig() + if err != nil { + return nil, fmt.Errorf("create in-cluster client configuration: %v", err) + } + } else { + csconfig, err = clientcmd.BuildConfigFromFlags("", k.KubeConfig) + if err != nil { + return nil, fmt.Errorf("create out-of-cluster client configuration: %v", err) + } + } + + csconfig.QPS = float32(k.KubeAPIQPS) + csconfig.Burst = k.KubeAPIBurst + + return csconfig, nil +} + +func (k *KubeClientConfig) NewClientSets() (ClientSets, error) { + csconfig, err := k.NewClientSetConfig() + if err != nil { + return ClientSets{}, fmt.Errorf("create client configuration: %v", err) + } + + coreclient, err := coreclientset.NewForConfig(csconfig) + if err != nil { + return ClientSets{}, fmt.Errorf("create core client: %v", err) + } + + return ClientSets{ + Core: coreclient, + }, nil +} diff --git a/pkg/flags/logging.go b/pkg/flags/logging.go new file mode 100644 index 000000000..ab7a7e950 --- /dev/null +++ b/pkg/flags/logging.go @@ -0,0 +1,87 @@ +/* + * Copyright 2023 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 flags + +import ( + "strings" + + "github.com/spf13/pflag" + "github.com/urfave/cli/v2" + + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/component-base/featuregate" + logsapi "k8s.io/component-base/logs/api/v1" + + _ "k8s.io/component-base/logs/json/register" // for JSON log output support +) + +type LoggingConfig struct { + featureGate featuregate.MutableFeatureGate + config *logsapi.LoggingConfiguration +} + +func NewLoggingConfig() *LoggingConfig { + fg := featuregate.NewFeatureGate() + var _ pflag.Value = fg // compile-time check for the type conversion below + l := &LoggingConfig{ + featureGate: fg, + config: logsapi.NewLoggingConfiguration(), + } + utilruntime.Must(logsapi.AddFeatureGates(l.featureGate)) + utilruntime.Must(l.featureGate.SetFromMap(map[string]bool{string(logsapi.ContextualLogging): true})) + return l +} + +// Apply should be called in a cli.App.Before directly after parsing command +// line flags and before running any code which emits log entries. +func (l *LoggingConfig) Apply() error { + return logsapi.ValidateAndApply(l.config, l.featureGate) +} + +// Flags returns the flags for the configuration. +func (l *LoggingConfig) Flags() []cli.Flag { + var fs pflag.FlagSet + logsapi.AddFlags(l.config, &fs) + + // Adding the feature gates flag to fs means that its going to be added + // with "logging" as category. In practice, the logging code is the + // only code which uses the flag, therefore that seems like a good + // place to report it. + fs.AddFlag(&pflag.Flag{ + Name: "feature-gates", + Usage: "A set of key=value pairs that describe feature gates for alpha/experimental features. " + + "Options are:\n " + strings.Join(l.featureGate.KnownFeatures(), "\n "), + Value: l.featureGate.(pflag.Value), //nolint:forcetypeassert // No need for type check: l.featureGate is a *featuregate.featureGate, which implements pflag.Value. + }) + + var flags []cli.Flag + fs.VisitAll(func(flag *pflag.Flag) { + flags = append(flags, pflagToCLI(flag, "Logging:")) + }) + return flags +} + +func pflagToCLI(flag *pflag.Flag, category string) cli.Flag { + return &cli.GenericFlag{ + Name: flag.Name, + Category: category, + Usage: flag.Usage, + Value: flag.Value, + Destination: flag.Value, + EnvVars: []string{strings.ToUpper(strings.ReplaceAll(flag.Name, "-", "_"))}, + } +}