mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2025-06-26 18:18:24 +00:00
Compare commits
55 Commits
pull-reque
...
pull-reque
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
699608902b | ||
|
|
d4b331fbbb | ||
|
|
f3b730c805 | ||
|
|
1cfaef4b01 | ||
|
|
76b6d4d38f | ||
|
|
4523b2e35d | ||
|
|
d757f6e68c | ||
|
|
5d5166cbb6 | ||
|
|
3df59b955a | ||
|
|
33280cd2b2 | ||
|
|
3306d5081e | ||
|
|
7c3ab75d08 | ||
|
|
71985df972 | ||
|
|
4255d73d89 | ||
|
|
9bdb74aec2 | ||
|
|
e436533a6f | ||
|
|
0f299c3431 | ||
|
|
f852043078 | ||
|
|
ef0b16bc24 | ||
|
|
225dfec83f | ||
|
|
03c48a6824 | ||
|
|
6530826293 | ||
|
|
971fd195b3 | ||
|
|
3b10afd0fe | ||
|
|
6b7ed26fba | ||
|
|
8d5f1e2427 | ||
|
|
d82a9ccd89 | ||
|
|
8ac213e3e6 | ||
|
|
0128762832 | ||
|
|
d7b150a2e6 | ||
|
|
57c917e3b1 | ||
|
|
bc9ec77fdd | ||
|
|
82f2eb7b73 | ||
|
|
712d829018 | ||
|
|
598b9740fc | ||
|
|
968e2ccca4 | ||
|
|
aff9301f2e | ||
|
|
011fb72330 | ||
|
|
2adef9903e | ||
|
|
70b1f5af98 | ||
|
|
c9422f12b3 | ||
|
|
b7fbd56f7e | ||
|
|
bd87c009ba | ||
|
|
fc65d3a784 | ||
|
|
52b9631333 | ||
|
|
9429fbac5f | ||
|
|
04e9bf4ac1 | ||
|
|
3ceaf1f85c | ||
|
|
9f0c1042c4 | ||
|
|
352b55c8ce | ||
|
|
b13139793b | ||
|
|
05f44b7752 | ||
|
|
a109f28cb6 | ||
|
|
65b575fa96 | ||
|
|
6e413d8445 |
2
Makefile
2
Makefile
@@ -115,7 +115,7 @@ mod-verify:
|
|||||||
|
|
||||||
|
|
||||||
check-vendor: vendor
|
check-vendor: vendor
|
||||||
git diff --quiet HEAD -- go.mod go.sum vendor
|
git diff --exit-code HEAD -- go.mod go.sum vendor
|
||||||
|
|
||||||
licenses:
|
licenses:
|
||||||
go-licenses csv $(MODULE)/...
|
go-licenses csv $(MODULE)/...
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/chmod"
|
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/chmod"
|
||||||
symlinks "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/create-symlinks"
|
symlinks "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/create-symlinks"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/cudacompat"
|
||||||
ldcache "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/update-ldcache"
|
ldcache "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/update-ldcache"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
)
|
)
|
||||||
@@ -32,5 +33,6 @@ func New(logger logger.Interface) []*cli.Command {
|
|||||||
ldcache.NewCommand(logger),
|
ldcache.NewCommand(logger),
|
||||||
symlinks.NewCommand(logger),
|
symlinks.NewCommand(logger),
|
||||||
chmod.NewCommand(logger),
|
chmod.NewCommand(logger),
|
||||||
|
cudacompat.NewCommand(logger),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
76
cmd/nvidia-cdi-hook/cudacompat/container-root.go
Normal file
76
cmd/nvidia-cdi-hook/cudacompat/container-root.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 cudacompat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/moby/sys/symlink"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A containerRoot represents the root filesystem of a container.
|
||||||
|
type containerRoot string
|
||||||
|
|
||||||
|
// hasPath checks whether the specified path exists in the root.
|
||||||
|
func (r containerRoot) hasPath(path string) bool {
|
||||||
|
resolved, err := r.resolve(path)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(resolved); err != nil && os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// globFiles matches the specified pattern in the root.
|
||||||
|
// The files that match must be regular files.
|
||||||
|
func (r containerRoot) globFiles(pattern string) ([]string, error) {
|
||||||
|
patternPath, err := r.resolve(pattern)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
matches, err := filepath.Glob(patternPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var files []string
|
||||||
|
for _, match := range matches {
|
||||||
|
info, err := os.Lstat(match)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Ignore symlinks.
|
||||||
|
if info.Mode()&os.ModeSymlink != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Ignore directories.
|
||||||
|
if info.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
files = append(files, match)
|
||||||
|
}
|
||||||
|
return files, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve returns the absolute path including root path.
|
||||||
|
// Symlinks are resolved, but are guaranteed to resolve in the root.
|
||||||
|
func (r containerRoot) resolve(path string) (string, error) {
|
||||||
|
absolute := filepath.Clean(filepath.Join(string(r), path))
|
||||||
|
return symlink.FollowSymlinkInScope(absolute, string(r))
|
||||||
|
}
|
||||||
221
cmd/nvidia-cdi-hook/cudacompat/cudacompat.go
Normal file
221
cmd/nvidia-cdi-hook/cudacompat/cudacompat.go
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 cudacompat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cudaCompatPath = "/usr/local/cuda/compat"
|
||||||
|
// cudaCompatLdsoconfdFilenamePattern specifies the pattern for the filename
|
||||||
|
// in ld.so.conf.d that includes a reference to the CUDA compat path.
|
||||||
|
// The 00-compat prefix is chosen to ensure that these libraries have a
|
||||||
|
// higher precedence than other libraries on the system.
|
||||||
|
cudaCompatLdsoconfdFilenamePattern = "00-compat-*.conf"
|
||||||
|
)
|
||||||
|
|
||||||
|
type command struct {
|
||||||
|
logger logger.Interface
|
||||||
|
}
|
||||||
|
|
||||||
|
type options struct {
|
||||||
|
hostDriverVersion string
|
||||||
|
containerSpec string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCommand constructs a cuda-compat command with the specified logger
|
||||||
|
func NewCommand(logger logger.Interface) *cli.Command {
|
||||||
|
c := command{
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
return c.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the enable-cuda-compat command
|
||||||
|
func (m command) build() *cli.Command {
|
||||||
|
cfg := options{}
|
||||||
|
|
||||||
|
// Create the 'enable-cuda-compat' command
|
||||||
|
c := cli.Command{
|
||||||
|
Name: "enable-cuda-compat",
|
||||||
|
Usage: "This hook ensures that the folder containing the CUDA compat libraries is added to the ldconfig search path if required.",
|
||||||
|
Before: func(c *cli.Context) error {
|
||||||
|
return m.validateFlags(c, &cfg)
|
||||||
|
},
|
||||||
|
Action: func(c *cli.Context) error {
|
||||||
|
return m.run(c, &cfg)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Flags = []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "host-driver-version",
|
||||||
|
Usage: "Specify the host driver version. If the CUDA compat libraries detected in the container do not have a higher MAJOR version, the hook is a no-op.",
|
||||||
|
Destination: &cfg.hostDriverVersion,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "container-spec",
|
||||||
|
Hidden: true,
|
||||||
|
Category: "testing-only",
|
||||||
|
Usage: "Specify the path to the OCI container spec. If empty or '-' the spec will be read from STDIN",
|
||||||
|
Destination: &cfg.containerSpec,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return &c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m command) validateFlags(_ *cli.Context, cfg *options) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m command) run(_ *cli.Context, cfg *options) error {
|
||||||
|
if cfg.hostDriverVersion == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := oci.LoadContainerState(cfg.containerSpec)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to load container state: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
containerRootDir, err := s.GetContainerRoot()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to determined container root: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
containerForwardCompatDir, err := m.getContainerForwardCompatDir(containerRoot(containerRootDir), cfg.hostDriverVersion)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get container forward compat directory: %w", err)
|
||||||
|
}
|
||||||
|
if containerForwardCompatDir == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.createLdsoconfdFile(containerRoot(containerRootDir), cudaCompatLdsoconfdFilenamePattern, containerForwardCompatDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m command) getContainerForwardCompatDir(containerRoot containerRoot, hostDriverVersion string) (string, error) {
|
||||||
|
if hostDriverVersion == "" {
|
||||||
|
m.logger.Debugf("Host driver version not specified")
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
if !containerRoot.hasPath(cudaCompatPath) {
|
||||||
|
m.logger.Debugf("No CUDA forward compatibility libraries directory in container")
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
if !containerRoot.hasPath("/etc/ld.so.cache") {
|
||||||
|
m.logger.Debugf("The container does not have an LDCache")
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
libs, err := containerRoot.globFiles(filepath.Join(cudaCompatPath, "libcuda.so.*.*"))
|
||||||
|
if err != nil {
|
||||||
|
m.logger.Warningf("Failed to find CUDA compat library: %w", err)
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(libs) == 0 {
|
||||||
|
m.logger.Debugf("No CUDA forward compatibility libraries container")
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(libs) != 1 {
|
||||||
|
m.logger.Warningf("Unexpected number of CUDA compat libraries in container: %v", libs)
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
compatDriverVersion := strings.TrimPrefix(filepath.Base(libs[0]), "libcuda.so.")
|
||||||
|
compatMajor, err := extractMajorVersion(compatDriverVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to extract major version from %q: %v", compatDriverVersion, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
driverMajor, err := extractMajorVersion(hostDriverVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to extract major version from %q: %v", hostDriverVersion, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if driverMajor >= compatMajor {
|
||||||
|
m.logger.Debugf("Compat major version is not greater than the host driver major version (%v >= %v)", hostDriverVersion, compatDriverVersion)
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedCompatDir := strings.TrimPrefix(filepath.Dir(libs[0]), string(containerRoot))
|
||||||
|
return resolvedCompatDir, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// createLdsoconfdFile creates a file at /etc/ld.so.conf.d/ in the specified root.
|
||||||
|
// The file is created at /etc/ld.so.conf.d/{{ .pattern }} using `CreateTemp` and
|
||||||
|
// contains the specified directories on each line.
|
||||||
|
func (m command) createLdsoconfdFile(in containerRoot, pattern string, dirs ...string) error {
|
||||||
|
if len(dirs) == 0 {
|
||||||
|
m.logger.Debugf("No directories to add to /etc/ld.so.conf")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ldsoconfdDir, err := in.resolve("/etc/ld.so.conf.d")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(ldsoconfdDir, 0755); err != nil {
|
||||||
|
return fmt.Errorf("failed to create ld.so.conf.d: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configFile, err := os.CreateTemp(ldsoconfdDir, pattern)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create config file: %w", err)
|
||||||
|
}
|
||||||
|
defer configFile.Close()
|
||||||
|
|
||||||
|
m.logger.Debugf("Adding directories %v to %v", dirs, configFile.Name())
|
||||||
|
|
||||||
|
added := make(map[string]bool)
|
||||||
|
for _, dir := range dirs {
|
||||||
|
if added[dir] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, err = configFile.WriteString(fmt.Sprintf("%s\n", dir))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to update config file: %w", err)
|
||||||
|
}
|
||||||
|
added[dir] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// The created file needs to be world readable for the cases where the container is run as a non-root user.
|
||||||
|
if err := configFile.Chmod(0644); err != nil {
|
||||||
|
return fmt.Errorf("failed to chmod config file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractMajorVersion parses a version string and returns the major version as an int.
|
||||||
|
func extractMajorVersion(version string) (int, error) {
|
||||||
|
majorString := strings.SplitN(version, ".", 2)[0]
|
||||||
|
return strconv.Atoi(majorString)
|
||||||
|
}
|
||||||
182
cmd/nvidia-cdi-hook/cudacompat/cudacompat_test.go
Normal file
182
cmd/nvidia-cdi-hook/cudacompat/cudacompat_test.go
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
# Copyright (c) 2025, 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 cudacompat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
testlog "github.com/sirupsen/logrus/hooks/test"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCompatLibs(t *testing.T) {
|
||||||
|
logger, _ := testlog.NewNullLogger()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
description string
|
||||||
|
contents map[string]string
|
||||||
|
hostDriverVersion string
|
||||||
|
expectedContainerForwardCompatDir string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "empty root",
|
||||||
|
hostDriverVersion: "222.55.66",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "compat lib is newer; no ldcache",
|
||||||
|
contents: map[string]string{
|
||||||
|
"/usr/local/cuda/compat/libcuda.so.333.88.99": "",
|
||||||
|
},
|
||||||
|
hostDriverVersion: "222.55.66",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "compat lib is newer; ldcache",
|
||||||
|
contents: map[string]string{
|
||||||
|
"/etc/ld.so.cache": "",
|
||||||
|
"/usr/local/cuda/compat/libcuda.so.333.88.99": "",
|
||||||
|
},
|
||||||
|
hostDriverVersion: "222.55.66",
|
||||||
|
expectedContainerForwardCompatDir: "/usr/local/cuda/compat",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "compat lib is older; ldcache",
|
||||||
|
contents: map[string]string{
|
||||||
|
"/etc/ld.so.cache": "",
|
||||||
|
"/usr/local/cuda/compat/libcuda.so.111.88.99": "",
|
||||||
|
},
|
||||||
|
hostDriverVersion: "222.55.66",
|
||||||
|
expectedContainerForwardCompatDir: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "compat lib has same major version; ldcache",
|
||||||
|
contents: map[string]string{
|
||||||
|
"/etc/ld.so.cache": "",
|
||||||
|
"/usr/local/cuda/compat/libcuda.so.222.88.99": "",
|
||||||
|
},
|
||||||
|
hostDriverVersion: "222.55.66",
|
||||||
|
expectedContainerForwardCompatDir: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "numeric comparison is used; ldcache",
|
||||||
|
contents: map[string]string{
|
||||||
|
"/etc/ld.so.cache": "",
|
||||||
|
"/usr/local/cuda/compat/libcuda.so.222.88.99": "",
|
||||||
|
},
|
||||||
|
hostDriverVersion: "99.55.66",
|
||||||
|
expectedContainerForwardCompatDir: "/usr/local/cuda/compat",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "driver version empty; ldcache",
|
||||||
|
contents: map[string]string{
|
||||||
|
"/etc/ld.so.cache": "",
|
||||||
|
"/usr/local/cuda/compat/libcuda.so.222.88.99": "",
|
||||||
|
},
|
||||||
|
hostDriverVersion: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "symlinks are followed",
|
||||||
|
contents: map[string]string{
|
||||||
|
"/etc/ld.so.cache": "",
|
||||||
|
"/etc/alternatives/cuda/compat/libcuda.so.333.88.99": "",
|
||||||
|
"/usr/local/cuda": "symlink=/etc/alternatives/cuda",
|
||||||
|
},
|
||||||
|
hostDriverVersion: "222.55.66",
|
||||||
|
expectedContainerForwardCompatDir: "/etc/alternatives/cuda/compat",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "symlinks stay in container",
|
||||||
|
contents: map[string]string{
|
||||||
|
"/etc/ld.so.cache": "",
|
||||||
|
"/compat/libcuda.so.333.88.99": "",
|
||||||
|
"/usr/local/cuda": "symlink=../../../../../../",
|
||||||
|
},
|
||||||
|
hostDriverVersion: "222.55.66",
|
||||||
|
expectedContainerForwardCompatDir: "/compat",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
|
containerRootDir := t.TempDir()
|
||||||
|
for name, contents := range tc.contents {
|
||||||
|
target := filepath.Join(containerRootDir, name)
|
||||||
|
require.NoError(t, os.MkdirAll(filepath.Dir(target), 0755))
|
||||||
|
|
||||||
|
if strings.HasPrefix(contents, "symlink=") {
|
||||||
|
require.NoError(t, os.Symlink(strings.TrimPrefix(contents, "symlink="), target))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, os.WriteFile(target, []byte(contents), 0600))
|
||||||
|
}
|
||||||
|
|
||||||
|
c := command{
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
containerForwardCompatDir, err := c.getContainerForwardCompatDir(containerRoot(containerRootDir), tc.hostDriverVersion)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, tc.expectedContainerForwardCompatDir, containerForwardCompatDir)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateLdconfig(t *testing.T) {
|
||||||
|
logger, _ := testlog.NewNullLogger()
|
||||||
|
testCases := []struct {
|
||||||
|
description string
|
||||||
|
folders []string
|
||||||
|
expectedContents string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "no folders; have no contents",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "single folder is added",
|
||||||
|
folders: []string{"/usr/local/cuda/compat"},
|
||||||
|
expectedContents: "/usr/local/cuda/compat\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
|
containerRootDir := t.TempDir()
|
||||||
|
c := command{
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
err := c.createLdsoconfdFile(containerRoot(containerRootDir), cudaCompatLdsoconfdFilenamePattern, tc.folders...)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
matches, err := filepath.Glob(filepath.Join(containerRootDir, "/etc/ld.so.conf.d/00-compat-*.conf"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if tc.expectedContents == "" {
|
||||||
|
require.Empty(t, matches)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Len(t, matches, 1)
|
||||||
|
contents, err := os.ReadFile(matches[0])
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.EqualValues(t, tc.expectedContents, string(contents))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
46
cmd/nvidia-cdi-hook/update-ldcache/container-root.go
Normal file
46
cmd/nvidia-cdi-hook/update-ldcache/container-root.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 ldcache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/moby/sys/symlink"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A containerRoot represents the root filesystem of a container.
|
||||||
|
type containerRoot string
|
||||||
|
|
||||||
|
// hasPath checks whether the specified path exists in the root.
|
||||||
|
func (r containerRoot) hasPath(path string) bool {
|
||||||
|
resolved, err := r.resolve(path)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(resolved); err != nil && os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve returns the absolute path including root path.
|
||||||
|
// Symlinks are resolved, but are guaranteed to resolve in the root.
|
||||||
|
func (r containerRoot) resolve(path string) (string, error) {
|
||||||
|
absolute := filepath.Clean(filepath.Join(string(r), path))
|
||||||
|
return symlink.FollowSymlinkInScope(absolute, string(r))
|
||||||
|
}
|
||||||
57
cmd/nvidia-cdi-hook/update-ldcache/safe-exec_linux.go
Normal file
57
cmd/nvidia-cdi-hook/update-ldcache/safe-exec_linux.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 ldcache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/opencontainers/runc/libcontainer/dmz"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SafeExec attempts to clone the specified binary (as an memfd, for example) before executing it.
|
||||||
|
func (m command) SafeExec(path string, args []string, envv []string) error {
|
||||||
|
safeExe, err := cloneBinary(path)
|
||||||
|
if err != nil {
|
||||||
|
m.logger.Warningf("Failed to clone binary %q: %v; falling back to Exec", path, err)
|
||||||
|
//nolint:gosec // TODO: Can we harden this so that there is less risk of command injection
|
||||||
|
return syscall.Exec(path, args, envv)
|
||||||
|
}
|
||||||
|
defer safeExe.Close()
|
||||||
|
|
||||||
|
exePath := "/proc/self/fd/" + strconv.Itoa(int(safeExe.Fd()))
|
||||||
|
//nolint:gosec // TODO: Can we harden this so that there is less risk of command injection
|
||||||
|
return syscall.Exec(exePath, args, envv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cloneBinary(path string) (*os.File, error) {
|
||||||
|
exe, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("opening current binary: %w", err)
|
||||||
|
}
|
||||||
|
defer exe.Close()
|
||||||
|
|
||||||
|
stat, err := exe.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("checking %v size: %w", path, err)
|
||||||
|
}
|
||||||
|
size := stat.Size()
|
||||||
|
|
||||||
|
return dmz.CloneBinary(exe, size, path, os.TempDir())
|
||||||
|
}
|
||||||
29
cmd/nvidia-cdi-hook/update-ldcache/safe-exec_other.go
Normal file
29
cmd/nvidia-cdi-hook/update-ldcache/safe-exec_other.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
//go:build !linux
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 ldcache
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// SafeExec is not implemented on non-linux systems and forwards directly to the
|
||||||
|
// Exec syscall.
|
||||||
|
func (m *command) SafeExec(path string, args []string, envv []string) error {
|
||||||
|
//nolint:gosec // TODO: Can we harden this so that there is less risk of command injection
|
||||||
|
return syscall.Exec(path, args, envv)
|
||||||
|
}
|
||||||
@@ -22,7 +22,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
@@ -31,6 +30,15 @@ import (
|
|||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ldsoconfdFilenamePattern specifies the pattern for the filename
|
||||||
|
// in ld.so.conf.d that includes references to the specified directories.
|
||||||
|
// The 00-nvcr prefix is chosen to ensure that these libraries have a
|
||||||
|
// higher precedence than other libraries on the system, but lower than
|
||||||
|
// the 00-cuda-compat that is included in some containers.
|
||||||
|
ldsoconfdFilenamePattern = "00-nvcr-*.conf"
|
||||||
|
)
|
||||||
|
|
||||||
type command struct {
|
type command struct {
|
||||||
logger logger.Interface
|
logger logger.Interface
|
||||||
}
|
}
|
||||||
@@ -100,18 +108,20 @@ func (m command) run(c *cli.Context, cfg *options) error {
|
|||||||
return fmt.Errorf("failed to load container state: %v", err)
|
return fmt.Errorf("failed to load container state: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
containerRoot, err := s.GetContainerRoot()
|
containerRootDir, err := s.GetContainerRoot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to determined container root: %v", err)
|
return fmt.Errorf("failed to determined container root: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ldconfigPath := m.resolveLDConfigPath(cfg.ldconfigPath)
|
ldconfigPath := m.resolveLDConfigPath(cfg.ldconfigPath)
|
||||||
args := []string{filepath.Base(ldconfigPath)}
|
args := []string{filepath.Base(ldconfigPath)}
|
||||||
if containerRoot != "" {
|
if containerRootDir != "" {
|
||||||
args = append(args, "-r", containerRoot)
|
args = append(args, "-r", containerRootDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
if root(containerRoot).hasPath("/etc/ld.so.cache") {
|
containerRoot := containerRoot(containerRootDir)
|
||||||
|
|
||||||
|
if containerRoot.hasPath("/etc/ld.so.cache") {
|
||||||
args = append(args, "-C", "/etc/ld.so.cache")
|
args = append(args, "-C", "/etc/ld.so.cache")
|
||||||
} else {
|
} else {
|
||||||
m.logger.Debugf("No ld.so.cache found, skipping update")
|
m.logger.Debugf("No ld.so.cache found, skipping update")
|
||||||
@@ -119,8 +129,8 @@ func (m command) run(c *cli.Context, cfg *options) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
folders := cfg.folders.Value()
|
folders := cfg.folders.Value()
|
||||||
if root(containerRoot).hasPath("/etc/ld.so.conf.d") {
|
if containerRoot.hasPath("/etc/ld.so.conf.d") {
|
||||||
err := m.createConfig(containerRoot, folders)
|
err := m.createLdsoconfdFile(containerRoot, ldsoconfdFilenamePattern, folders...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to update ld.so.conf.d: %v", err)
|
return fmt.Errorf("failed to update ld.so.conf.d: %v", err)
|
||||||
}
|
}
|
||||||
@@ -132,18 +142,7 @@ func (m command) run(c *cli.Context, cfg *options) error {
|
|||||||
// be configured to use a different config file by default.
|
// be configured to use a different config file by default.
|
||||||
args = append(args, "-f", "/etc/ld.so.conf")
|
args = append(args, "-f", "/etc/ld.so.conf")
|
||||||
|
|
||||||
//nolint:gosec // TODO: Can we harden this so that there is less risk of command injection
|
return m.SafeExec(ldconfigPath, args, nil)
|
||||||
return syscall.Exec(ldconfigPath, args, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
type root string
|
|
||||||
|
|
||||||
func (r root) hasPath(path string) bool {
|
|
||||||
_, err := os.Stat(filepath.Join(string(r), path))
|
|
||||||
if err != nil && os.IsNotExist(err) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveLDConfigPath determines the LDConfig path to use for the system.
|
// resolveLDConfigPath determines the LDConfig path to use for the system.
|
||||||
@@ -153,44 +152,46 @@ func (m command) resolveLDConfigPath(path string) string {
|
|||||||
return strings.TrimPrefix(config.NormalizeLDConfigPath("@"+path), "@")
|
return strings.TrimPrefix(config.NormalizeLDConfigPath("@"+path), "@")
|
||||||
}
|
}
|
||||||
|
|
||||||
// createConfig creates (or updates) /etc/ld.so.conf.d/00-nvcr-<RANDOM_STRING>.conf in the container
|
// createLdsoconfdFile creates a file at /etc/ld.so.conf.d/ in the specified root.
|
||||||
// to include the required paths.
|
// The file is created at /etc/ld.so.conf.d/{{ .pattern }} using `CreateTemp` and
|
||||||
// Note that the 00-nvcr prefix is chosen to ensure that these libraries have
|
// contains the specified directories on each line.
|
||||||
// a higher precedence than other libraries on the system but are applied AFTER
|
func (m command) createLdsoconfdFile(in containerRoot, pattern string, dirs ...string) error {
|
||||||
// 00-cuda-compat.conf.
|
if len(dirs) == 0 {
|
||||||
func (m command) createConfig(root string, folders []string) error {
|
m.logger.Debugf("No directories to add to /etc/ld.so.conf")
|
||||||
if len(folders) == 0 {
|
|
||||||
m.logger.Debugf("No folders to add to /etc/ld.so.conf")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(filepath.Join(root, "/etc/ld.so.conf.d"), 0755); err != nil {
|
ldsoconfdDir, err := in.resolve("/etc/ld.so.conf.d")
|
||||||
return fmt.Errorf("failed to create ld.so.conf.d: %v", err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(ldsoconfdDir, 0755); err != nil {
|
||||||
|
return fmt.Errorf("failed to create ld.so.conf.d: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
configFile, err := os.CreateTemp(filepath.Join(root, "/etc/ld.so.conf.d"), "00-nvcr-*.conf")
|
configFile, err := os.CreateTemp(ldsoconfdDir, pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create config file: %v", err)
|
return fmt.Errorf("failed to create config file: %w", err)
|
||||||
}
|
}
|
||||||
defer configFile.Close()
|
defer configFile.Close()
|
||||||
|
|
||||||
m.logger.Debugf("Adding folders %v to %v", folders, configFile.Name())
|
m.logger.Debugf("Adding directories %v to %v", dirs, configFile.Name())
|
||||||
|
|
||||||
configured := make(map[string]bool)
|
added := make(map[string]bool)
|
||||||
for _, folder := range folders {
|
for _, dir := range dirs {
|
||||||
if configured[folder] {
|
if added[dir] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err = configFile.WriteString(fmt.Sprintf("%s\n", folder))
|
_, err = configFile.WriteString(fmt.Sprintf("%s\n", dir))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to update ld.so.conf.d: %v", err)
|
return fmt.Errorf("failed to update config file: %w", err)
|
||||||
}
|
}
|
||||||
configured[folder] = true
|
added[dir] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// The created file needs to be world readable for the cases where the container is run as a non-root user.
|
// The created file needs to be world readable for the cases where the container is run as a non-root user.
|
||||||
if err := os.Chmod(configFile.Name(), 0644); err != nil {
|
if err := configFile.Chmod(0644); err != nil {
|
||||||
return fmt.Errorf("failed to chmod config file: %v", err)
|
return fmt.Errorf("failed to chmod config file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -198,6 +198,10 @@ func getMigDevices(image image.CUDA, envvar string) *string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (hookConfig *hookConfig) getImexChannels(image image.CUDA, privileged bool) []string {
|
func (hookConfig *hookConfig) getImexChannels(image image.CUDA, privileged bool) []string {
|
||||||
|
if hookConfig.Features.IgnoreImexChannelRequests.IsEnabled() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// If enabled, try and get the device list from volume mounts first
|
// If enabled, try and get the device list from volume mounts first
|
||||||
if hookConfig.AcceptDeviceListAsVolumeMounts {
|
if hookConfig.AcceptDeviceListAsVolumeMounts {
|
||||||
devices := image.ImexChannelsFromMounts()
|
devices := image.ImexChannelsFromMounts()
|
||||||
|
|||||||
@@ -69,47 +69,47 @@ func TestInstall(t *testing.T) {
|
|||||||
cdiEnabled: true,
|
cdiEnabled: true,
|
||||||
expectedCdiSpec: `---
|
expectedCdiSpec: `---
|
||||||
cdiVersion: 0.5.0
|
cdiVersion: 0.5.0
|
||||||
|
kind: example.com/class
|
||||||
|
devices:
|
||||||
|
- name: all
|
||||||
|
containerEdits:
|
||||||
|
deviceNodes:
|
||||||
|
- path: /dev/nvidia0
|
||||||
|
hostPath: /host/driver/root/dev/nvidia0
|
||||||
|
- path: /dev/nvidiactl
|
||||||
|
hostPath: /host/driver/root/dev/nvidiactl
|
||||||
|
- path: /dev/nvidia-caps-imex-channels/channel0
|
||||||
|
hostPath: /host/driver/root/dev/nvidia-caps-imex-channels/channel0
|
||||||
|
- path: /dev/nvidia-caps-imex-channels/channel1
|
||||||
|
hostPath: /host/driver/root/dev/nvidia-caps-imex-channels/channel1
|
||||||
|
- path: /dev/nvidia-caps-imex-channels/channel2047
|
||||||
|
hostPath: /host/driver/root/dev/nvidia-caps-imex-channels/channel2047
|
||||||
containerEdits:
|
containerEdits:
|
||||||
env:
|
env:
|
||||||
- NVIDIA_VISIBLE_DEVICES=void
|
- NVIDIA_VISIBLE_DEVICES=void
|
||||||
hooks:
|
hooks:
|
||||||
- args:
|
- hookName: createContainer
|
||||||
|
path: {{ .toolkitRoot }}/nvidia-cdi-hook
|
||||||
|
args:
|
||||||
- nvidia-cdi-hook
|
- nvidia-cdi-hook
|
||||||
- create-symlinks
|
- create-symlinks
|
||||||
- --link
|
- --link
|
||||||
- libcuda.so.1::/lib/x86_64-linux-gnu/libcuda.so
|
- libcuda.so.1::/lib/x86_64-linux-gnu/libcuda.so
|
||||||
hookName: createContainer
|
- hookName: createContainer
|
||||||
path: {{ .toolkitRoot }}/nvidia-cdi-hook
|
path: {{ .toolkitRoot }}/nvidia-cdi-hook
|
||||||
- args:
|
args:
|
||||||
- nvidia-cdi-hook
|
- nvidia-cdi-hook
|
||||||
- update-ldcache
|
- update-ldcache
|
||||||
- --folder
|
- --folder
|
||||||
- /lib/x86_64-linux-gnu
|
- /lib/x86_64-linux-gnu
|
||||||
hookName: createContainer
|
|
||||||
path: {{ .toolkitRoot }}/nvidia-cdi-hook
|
|
||||||
mounts:
|
mounts:
|
||||||
- containerPath: /lib/x86_64-linux-gnu/libcuda.so.999.88.77
|
- hostPath: /host/driver/root/lib/x86_64-linux-gnu/libcuda.so.999.88.77
|
||||||
hostPath: /host/driver/root/lib/x86_64-linux-gnu/libcuda.so.999.88.77
|
containerPath: /lib/x86_64-linux-gnu/libcuda.so.999.88.77
|
||||||
options:
|
options:
|
||||||
- ro
|
- ro
|
||||||
- nosuid
|
- nosuid
|
||||||
- nodev
|
- nodev
|
||||||
- bind
|
- bind
|
||||||
devices:
|
|
||||||
- containerEdits:
|
|
||||||
deviceNodes:
|
|
||||||
- hostPath: /host/driver/root/dev/nvidia0
|
|
||||||
path: /dev/nvidia0
|
|
||||||
- hostPath: /host/driver/root/dev/nvidiactl
|
|
||||||
path: /dev/nvidiactl
|
|
||||||
- hostPath: /host/driver/root/dev/nvidia-caps-imex-channels/channel0
|
|
||||||
path: /dev/nvidia-caps-imex-channels/channel0
|
|
||||||
- hostPath: /host/driver/root/dev/nvidia-caps-imex-channels/channel1
|
|
||||||
path: /dev/nvidia-caps-imex-channels/channel1
|
|
||||||
- hostPath: /host/driver/root/dev/nvidia-caps-imex-channels/channel2047
|
|
||||||
path: /dev/nvidia-caps-imex-channels/channel2047
|
|
||||||
name: all
|
|
||||||
kind: example.com/class
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,6 +141,9 @@ swarm-resource = ""
|
|||||||
[nvidia-container-runtime.modes.csv]
|
[nvidia-container-runtime.modes.csv]
|
||||||
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
||||||
|
|
||||||
|
[nvidia-container-runtime.modes.jit-cdi]
|
||||||
|
load-kernel-modules = ["nvidia", "nvidia-uvm", "nvidia-modeset"]
|
||||||
|
|
||||||
[nvidia-container-runtime-hook]
|
[nvidia-container-runtime-hook]
|
||||||
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
||||||
skip-mode-detection = true
|
skip-mode-detection = true
|
||||||
@@ -202,6 +205,9 @@ swarm-resource = ""
|
|||||||
[nvidia-container-runtime.modes.csv]
|
[nvidia-container-runtime.modes.csv]
|
||||||
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
||||||
|
|
||||||
|
[nvidia-container-runtime.modes.jit-cdi]
|
||||||
|
load-kernel-modules = ["nvidia", "nvidia-uvm", "nvidia-modeset"]
|
||||||
|
|
||||||
[nvidia-container-runtime-hook]
|
[nvidia-container-runtime-hook]
|
||||||
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
||||||
skip-mode-detection = true
|
skip-mode-detection = true
|
||||||
@@ -266,6 +272,9 @@ swarm-resource = ""
|
|||||||
[nvidia-container-runtime.modes.csv]
|
[nvidia-container-runtime.modes.csv]
|
||||||
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
||||||
|
|
||||||
|
[nvidia-container-runtime.modes.jit-cdi]
|
||||||
|
load-kernel-modules = ["nvidia", "nvidia-uvm", "nvidia-modeset"]
|
||||||
|
|
||||||
[nvidia-container-runtime-hook]
|
[nvidia-container-runtime-hook]
|
||||||
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
||||||
skip-mode-detection = true
|
skip-mode-detection = true
|
||||||
@@ -327,6 +336,9 @@ swarm-resource = ""
|
|||||||
[nvidia-container-runtime.modes.csv]
|
[nvidia-container-runtime.modes.csv]
|
||||||
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
||||||
|
|
||||||
|
[nvidia-container-runtime.modes.jit-cdi]
|
||||||
|
load-kernel-modules = ["nvidia", "nvidia-uvm", "nvidia-modeset"]
|
||||||
|
|
||||||
[nvidia-container-runtime-hook]
|
[nvidia-container-runtime-hook]
|
||||||
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
||||||
skip-mode-detection = true
|
skip-mode-detection = true
|
||||||
@@ -410,6 +422,9 @@ swarm-resource = ""
|
|||||||
[nvidia-container-runtime.modes.csv]
|
[nvidia-container-runtime.modes.csv]
|
||||||
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
||||||
|
|
||||||
|
[nvidia-container-runtime.modes.jit-cdi]
|
||||||
|
load-kernel-modules = ["nvidia", "nvidia-uvm", "nvidia-modeset"]
|
||||||
|
|
||||||
[nvidia-container-runtime-hook]
|
[nvidia-container-runtime-hook]
|
||||||
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
path = "{{ .toolkitRoot }}/toolkit/nvidia-container-runtime-hook"
|
||||||
skip-mode-detection = true
|
skip-mode-detection = true
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
cdi "tags.cncf.io/container-device-interface/pkg/parser"
|
cdi "tags.cncf.io/container-device-interface/pkg/parser"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/go-nvml/pkg/nvml"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv"
|
||||||
@@ -60,6 +62,9 @@ type options struct {
|
|||||||
files cli.StringSlice
|
files cli.StringSlice
|
||||||
ignorePatterns cli.StringSlice
|
ignorePatterns cli.StringSlice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the following are used for dependency injection during spec generation.
|
||||||
|
nvmllib nvml.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommand constructs a generate-cdi command with the specified logger
|
// NewCommand constructs a generate-cdi command with the specified logger
|
||||||
@@ -269,6 +274,8 @@ func (m command) generateSpec(opts *options) (spec.Interface, error) {
|
|||||||
nvcdi.WithLibrarySearchPaths(opts.librarySearchPaths.Value()),
|
nvcdi.WithLibrarySearchPaths(opts.librarySearchPaths.Value()),
|
||||||
nvcdi.WithCSVFiles(opts.csv.files.Value()),
|
nvcdi.WithCSVFiles(opts.csv.files.Value()),
|
||||||
nvcdi.WithCSVIgnorePatterns(opts.csv.ignorePatterns.Value()),
|
nvcdi.WithCSVIgnorePatterns(opts.csv.ignorePatterns.Value()),
|
||||||
|
// We set the following to allow for dependency injection:
|
||||||
|
nvcdi.WithNvmlLib(opts.nvmllib),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create CDI library: %v", err)
|
return nil, fmt.Errorf("failed to create CDI library: %v", err)
|
||||||
|
|||||||
157
cmd/nvidia-ctk/cdi/generate/generate_test.go
Normal file
157
cmd/nvidia-ctk/cdi/generate/generate_test.go
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/go-nvml/pkg/nvml"
|
||||||
|
"github.com/NVIDIA/go-nvml/pkg/nvml/mock/dgxa100"
|
||||||
|
testlog "github.com/sirupsen/logrus/hooks/test"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateSpec(t *testing.T) {
|
||||||
|
t.Setenv("__NVCT_TESTING_DEVICES_ARE_FILES", "true")
|
||||||
|
moduleRoot, err := test.GetModuleRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
driverRoot := filepath.Join(moduleRoot, "testdata", "lookup", "rootfs-1")
|
||||||
|
|
||||||
|
logger, _ := testlog.NewNullLogger()
|
||||||
|
testCases := []struct {
|
||||||
|
description string
|
||||||
|
options options
|
||||||
|
expectedValidateError error
|
||||||
|
expectedOptions options
|
||||||
|
expectedError error
|
||||||
|
expectedSpec string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "default",
|
||||||
|
options: options{
|
||||||
|
format: "yaml",
|
||||||
|
mode: "nvml",
|
||||||
|
vendor: "example.com",
|
||||||
|
class: "device",
|
||||||
|
driverRoot: driverRoot,
|
||||||
|
},
|
||||||
|
expectedOptions: options{
|
||||||
|
format: "yaml",
|
||||||
|
mode: "nvml",
|
||||||
|
vendor: "example.com",
|
||||||
|
class: "device",
|
||||||
|
nvidiaCDIHookPath: "/usr/bin/nvidia-cdi-hook",
|
||||||
|
driverRoot: driverRoot,
|
||||||
|
},
|
||||||
|
expectedSpec: `---
|
||||||
|
cdiVersion: 0.5.0
|
||||||
|
kind: example.com/device
|
||||||
|
devices:
|
||||||
|
- name: "0"
|
||||||
|
containerEdits:
|
||||||
|
deviceNodes:
|
||||||
|
- path: /dev/nvidia0
|
||||||
|
hostPath: {{ .driverRoot }}/dev/nvidia0
|
||||||
|
- name: all
|
||||||
|
containerEdits:
|
||||||
|
deviceNodes:
|
||||||
|
- path: /dev/nvidia0
|
||||||
|
hostPath: {{ .driverRoot }}/dev/nvidia0
|
||||||
|
containerEdits:
|
||||||
|
env:
|
||||||
|
- NVIDIA_VISIBLE_DEVICES=void
|
||||||
|
deviceNodes:
|
||||||
|
- path: /dev/nvidiactl
|
||||||
|
hostPath: {{ .driverRoot }}/dev/nvidiactl
|
||||||
|
hooks:
|
||||||
|
- hookName: createContainer
|
||||||
|
path: /usr/bin/nvidia-cdi-hook
|
||||||
|
args:
|
||||||
|
- nvidia-cdi-hook
|
||||||
|
- create-symlinks
|
||||||
|
- --link
|
||||||
|
- libcuda.so.1::/lib/x86_64-linux-gnu/libcuda.so
|
||||||
|
- hookName: createContainer
|
||||||
|
path: /usr/bin/nvidia-cdi-hook
|
||||||
|
args:
|
||||||
|
- nvidia-cdi-hook
|
||||||
|
- enable-cuda-compat
|
||||||
|
- --host-driver-version=999.88.77
|
||||||
|
- hookName: createContainer
|
||||||
|
path: /usr/bin/nvidia-cdi-hook
|
||||||
|
args:
|
||||||
|
- nvidia-cdi-hook
|
||||||
|
- update-ldcache
|
||||||
|
- --folder
|
||||||
|
- /lib/x86_64-linux-gnu
|
||||||
|
mounts:
|
||||||
|
- hostPath: {{ .driverRoot }}/lib/x86_64-linux-gnu/libcuda.so.999.88.77
|
||||||
|
containerPath: /lib/x86_64-linux-gnu/libcuda.so.999.88.77
|
||||||
|
options:
|
||||||
|
- ro
|
||||||
|
- nosuid
|
||||||
|
- nodev
|
||||||
|
- bind
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
|
c := command{
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.validateFlags(nil, &tc.options)
|
||||||
|
require.ErrorIs(t, err, tc.expectedValidateError)
|
||||||
|
require.EqualValues(t, tc.expectedOptions, tc.options)
|
||||||
|
|
||||||
|
// Set up a mock server, reusing the DGX A100 mock.
|
||||||
|
server := dgxa100.New()
|
||||||
|
// Override the driver version to match the version in our mock filesystem.
|
||||||
|
server.SystemGetDriverVersionFunc = func() (string, nvml.Return) {
|
||||||
|
return "999.88.77", nvml.SUCCESS
|
||||||
|
}
|
||||||
|
// Set the device count to 1 explicitly since we only have a single device node.
|
||||||
|
server.DeviceGetCountFunc = func() (int, nvml.Return) {
|
||||||
|
return 1, nvml.SUCCESS
|
||||||
|
}
|
||||||
|
for _, d := range server.Devices {
|
||||||
|
// TODO: This is not implemented in the mock.
|
||||||
|
(d.(*dgxa100.Device)).GetMaxMigDeviceCountFunc = func() (int, nvml.Return) {
|
||||||
|
return 0, nvml.SUCCESS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tc.options.nvmllib = server
|
||||||
|
|
||||||
|
spec, err := c.generateSpec(&tc.options)
|
||||||
|
require.ErrorIs(t, err, tc.expectedError)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
_, err = spec.WriteTo(&buf)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, strings.ReplaceAll(tc.expectedSpec, "{{ .driverRoot }}", driverRoot), buf.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -145,21 +145,9 @@ func (m allPossible) getGPUDeviceNodes(gpu int) []deviceNode {
|
|||||||
// getNVCapDeviceNodes generates a list of cap device nodes for a given GPU.
|
// getNVCapDeviceNodes generates a list of cap device nodes for a given GPU.
|
||||||
func (m allPossible) getNVCapDeviceNodes(gpu int) []deviceNode {
|
func (m allPossible) getNVCapDeviceNodes(gpu int) []deviceNode {
|
||||||
var selectedCapMinors []nvcaps.MigMinor
|
var selectedCapMinors []nvcaps.MigMinor
|
||||||
for gi := 0; ; gi++ {
|
|
||||||
giCap := nvcaps.NewGPUInstanceCap(gpu, gi)
|
for _, capMinors := range m.migCaps.FilterForGPU(nvcaps.Index(gpu)) {
|
||||||
giMinor, exist := m.migCaps[giCap]
|
selectedCapMinors = append(selectedCapMinors, capMinors)
|
||||||
if !exist {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
selectedCapMinors = append(selectedCapMinors, giMinor)
|
|
||||||
for ci := 0; ; ci++ {
|
|
||||||
ciCap := nvcaps.NewComputeInstanceCap(gpu, gi, ci)
|
|
||||||
ciMinor, exist := m.migCaps[ciCap]
|
|
||||||
if !exist {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
selectedCapMinors = append(selectedCapMinors, ciMinor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var deviceNodes []deviceNode
|
var deviceNodes []deviceNode
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ go 1.24
|
|||||||
toolchain go1.24.0
|
toolchain go1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golangci/golangci-lint v1.64.5
|
github.com/golangci/golangci-lint v1.64.6
|
||||||
github.com/matryer/moq v0.5.3
|
github.com/matryer/moq v0.5.3
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
|
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
|
||||||
4d63.com/gochecknoglobals v0.2.2 // indirect
|
4d63.com/gochecknoglobals v0.2.2 // indirect
|
||||||
github.com/4meepo/tagalign v1.4.1 // indirect
|
github.com/4meepo/tagalign v1.4.2 // indirect
|
||||||
github.com/Abirdcfly/dupword v0.1.3 // indirect
|
github.com/Abirdcfly/dupword v0.1.3 // indirect
|
||||||
github.com/Antonboom/errname v1.0.0 // indirect
|
github.com/Antonboom/errname v1.0.0 // indirect
|
||||||
github.com/Antonboom/nilnil v1.0.1 // indirect
|
github.com/Antonboom/nilnil v1.0.1 // indirect
|
||||||
@@ -20,7 +20,7 @@ require (
|
|||||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
|
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
|
||||||
github.com/Crocmagnon/fatcontext v0.7.1 // indirect
|
github.com/Crocmagnon/fatcontext v0.7.1 // indirect
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect
|
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect
|
github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect
|
||||||
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
|
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
|
||||||
@@ -38,7 +38,7 @@ require (
|
|||||||
github.com/breml/errchkjson v0.4.0 // indirect
|
github.com/breml/errchkjson v0.4.0 // indirect
|
||||||
github.com/butuzov/ireturn v0.3.1 // indirect
|
github.com/butuzov/ireturn v0.3.1 // indirect
|
||||||
github.com/butuzov/mirror v1.3.0 // indirect
|
github.com/butuzov/mirror v1.3.0 // indirect
|
||||||
github.com/catenacyber/perfsprint v0.8.1 // indirect
|
github.com/catenacyber/perfsprint v0.8.2 // indirect
|
||||||
github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
|
github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/charithe/durationcheck v0.0.10 // indirect
|
github.com/charithe/durationcheck v0.0.10 // indirect
|
||||||
@@ -75,10 +75,10 @@ require (
|
|||||||
github.com/golangci/plugin-module-register v0.1.1 // indirect
|
github.com/golangci/plugin-module-register v0.1.1 // indirect
|
||||||
github.com/golangci/revgrep v0.8.0 // indirect
|
github.com/golangci/revgrep v0.8.0 // indirect
|
||||||
github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect
|
github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
github.com/gordonklaus/ineffassign v0.1.0 // indirect
|
github.com/gordonklaus/ineffassign v0.1.0 // indirect
|
||||||
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
||||||
github.com/gostaticanalysis/comment v1.4.2 // indirect
|
github.com/gostaticanalysis/comment v1.5.0 // indirect
|
||||||
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
|
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
|
||||||
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
||||||
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
|
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
|
||||||
@@ -92,12 +92,12 @@ require (
|
|||||||
github.com/jjti/go-spancheck v0.6.4 // indirect
|
github.com/jjti/go-spancheck v0.6.4 // indirect
|
||||||
github.com/julz/importas v0.2.0 // indirect
|
github.com/julz/importas v0.2.0 // indirect
|
||||||
github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect
|
github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect
|
||||||
github.com/kisielk/errcheck v1.8.0 // indirect
|
github.com/kisielk/errcheck v1.9.0 // indirect
|
||||||
github.com/kkHAIKE/contextcheck v1.1.5 // indirect
|
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
|
||||||
github.com/kulti/thelper v0.6.3 // indirect
|
github.com/kulti/thelper v0.6.3 // indirect
|
||||||
github.com/kunwardeep/paralleltest v1.0.10 // indirect
|
github.com/kunwardeep/paralleltest v1.0.10 // indirect
|
||||||
github.com/lasiar/canonicalheader v1.1.2 // indirect
|
github.com/lasiar/canonicalheader v1.1.2 // indirect
|
||||||
github.com/ldez/exptostd v0.4.1 // indirect
|
github.com/ldez/exptostd v0.4.2 // indirect
|
||||||
github.com/ldez/gomoddirectives v0.6.1 // indirect
|
github.com/ldez/gomoddirectives v0.6.1 // indirect
|
||||||
github.com/ldez/grignotin v0.9.0 // indirect
|
github.com/ldez/grignotin v0.9.0 // indirect
|
||||||
github.com/ldez/tagliatelle v0.7.1 // indirect
|
github.com/ldez/tagliatelle v0.7.1 // indirect
|
||||||
@@ -112,14 +112,14 @@ require (
|
|||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||||
github.com/mgechev/revive v1.6.1 // indirect
|
github.com/mgechev/revive v1.7.0 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/moricho/tparallel v0.3.2 // indirect
|
github.com/moricho/tparallel v0.3.2 // indirect
|
||||||
github.com/nakabonne/nestif v0.3.1 // indirect
|
github.com/nakabonne/nestif v0.3.1 // indirect
|
||||||
github.com/nishanths/exhaustive v0.12.0 // indirect
|
github.com/nishanths/exhaustive v0.12.0 // indirect
|
||||||
github.com/nishanths/predeclared v0.2.2 // indirect
|
github.com/nishanths/predeclared v0.2.2 // indirect
|
||||||
github.com/nunnatsa/ginkgolinter v0.19.0 // indirect
|
github.com/nunnatsa/ginkgolinter v0.19.1 // indirect
|
||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||||
@@ -136,7 +136,7 @@ require (
|
|||||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
||||||
github.com/raeperd/recvcheck v0.2.0 // indirect
|
github.com/raeperd/recvcheck v0.2.0 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||||
github.com/ryancurrah/gomodguard v1.3.5 // indirect
|
github.com/ryancurrah/gomodguard v1.3.5 // indirect
|
||||||
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
|
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
|
||||||
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
|
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
|
||||||
@@ -151,7 +151,7 @@ require (
|
|||||||
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
||||||
github.com/spf13/afero v1.12.0 // indirect
|
github.com/spf13/afero v1.12.0 // indirect
|
||||||
github.com/spf13/cast v1.5.0 // indirect
|
github.com/spf13/cast v1.5.0 // indirect
|
||||||
github.com/spf13/cobra v1.8.1 // indirect
|
github.com/spf13/cobra v1.9.1 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.6 // indirect
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
github.com/spf13/viper v1.12.0 // indirect
|
github.com/spf13/viper v1.12.0 // indirect
|
||||||
@@ -160,8 +160,8 @@ require (
|
|||||||
github.com/stretchr/objx v0.5.2 // indirect
|
github.com/stretchr/objx v0.5.2 // indirect
|
||||||
github.com/stretchr/testify v1.10.0 // indirect
|
github.com/stretchr/testify v1.10.0 // indirect
|
||||||
github.com/subosito/gotenv v1.4.1 // indirect
|
github.com/subosito/gotenv v1.4.1 // indirect
|
||||||
github.com/tdakkota/asciicheck v0.4.0 // indirect
|
github.com/tdakkota/asciicheck v0.4.1 // indirect
|
||||||
github.com/tetafro/godot v1.4.20 // indirect
|
github.com/tetafro/godot v1.5.0 // indirect
|
||||||
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 // indirect
|
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 // indirect
|
||||||
github.com/timonwong/loggercheck v0.10.1 // indirect
|
github.com/timonwong/loggercheck v0.10.1 // indirect
|
||||||
github.com/tomarrell/wrapcheck/v2 v2.10.0 // indirect
|
github.com/tomarrell/wrapcheck/v2 v2.10.0 // indirect
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA=
|
4d63.com/gocheckcompilerdirectives v1.3.0 h1:Ew5y5CtcAAQeTVKUVFrE7EwHMrTO6BggtEj8BZSjZ3A=
|
||||||
4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=
|
4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY=
|
||||||
4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU=
|
4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU=
|
||||||
4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
|
4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
@@ -35,8 +35,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
|||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/4meepo/tagalign v1.4.1 h1:GYTu2FaPGOGb/xJalcqHeD4il5BiCywyEYZOA55P6J4=
|
github.com/4meepo/tagalign v1.4.2 h1:0hcLHPGMjDyM1gHG58cS73aQF8J4TdVR96TZViorO9E=
|
||||||
github.com/4meepo/tagalign v1.4.1/go.mod h1:2H9Yu6sZ67hmuraFgfZkNcg5Py9Ch/Om9l2K/2W1qS4=
|
github.com/4meepo/tagalign v1.4.2/go.mod h1:+p4aMyFM+ra7nb41CnFG6aSDXqRxU/w1VQqScKqDARI=
|
||||||
github.com/Abirdcfly/dupword v0.1.3 h1:9Pa1NuAsZvpFPi9Pqkd93I7LIYRURj+A//dFd5tgBeE=
|
github.com/Abirdcfly/dupword v0.1.3 h1:9Pa1NuAsZvpFPi9Pqkd93I7LIYRURj+A//dFd5tgBeE=
|
||||||
github.com/Abirdcfly/dupword v0.1.3/go.mod h1:8VbB2t7e10KRNdwTVoxdBaxla6avbhGzb8sCTygUMhw=
|
github.com/Abirdcfly/dupword v0.1.3/go.mod h1:8VbB2t7e10KRNdwTVoxdBaxla6avbhGzb8sCTygUMhw=
|
||||||
github.com/Antonboom/errname v1.0.0 h1:oJOOWR07vS1kRusl6YRSlat7HFnb3mSfMl6sDMRoTBA=
|
github.com/Antonboom/errname v1.0.0 h1:oJOOWR07vS1kRusl6YRSlat7HFnb3mSfMl6sDMRoTBA=
|
||||||
@@ -53,8 +53,8 @@ github.com/Crocmagnon/fatcontext v0.7.1 h1:SC/VIbRRZQeQWj/TcQBS6JmrXcfA+BU4OGSVU
|
|||||||
github.com/Crocmagnon/fatcontext v0.7.1/go.mod h1:1wMvv3NXEBJucFGfwOJBxSVWcoIO6emV215SMkW9MFU=
|
github.com/Crocmagnon/fatcontext v0.7.1/go.mod h1:1wMvv3NXEBJucFGfwOJBxSVWcoIO6emV215SMkW9MFU=
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU=
|
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 h1:Sz1JIXEcSfhz7fUi7xHnhpIE0thVASYjvosApmHuD2k=
|
||||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0/go.mod h1:ONJg5sxcbsdQQ4pOW8TGdTidT2TMAUy/2Xhr8mrYaao=
|
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1/go.mod h1:n/LSCXNuIYqVfBlVXyHfMQkZDdp1/mmxfSjADd3z1Zg=
|
||||||
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
|
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
|
||||||
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA=
|
github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA=
|
||||||
@@ -102,8 +102,8 @@ github.com/butuzov/ireturn v0.3.1 h1:mFgbEI6m+9W8oP/oDdfA34dLisRFCj2G6o/yiI1yZrY
|
|||||||
github.com/butuzov/ireturn v0.3.1/go.mod h1:ZfRp+E7eJLC0NQmk1Nrm1LOrn/gQlOykv+cVPdiXH5M=
|
github.com/butuzov/ireturn v0.3.1/go.mod h1:ZfRp+E7eJLC0NQmk1Nrm1LOrn/gQlOykv+cVPdiXH5M=
|
||||||
github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc=
|
github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc=
|
||||||
github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
|
github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
|
||||||
github.com/catenacyber/perfsprint v0.8.1 h1:bGOHuzHe0IkoGeY831RW4aSlt1lPRd3WRAScSWOaV7E=
|
github.com/catenacyber/perfsprint v0.8.2 h1:+o9zVmCSVa7M4MvabsWvESEhpsMkhfE7k0sHNGL95yw=
|
||||||
github.com/catenacyber/perfsprint v0.8.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50=
|
github.com/catenacyber/perfsprint v0.8.2/go.mod h1:q//VWC2fWbcdSLEY1R3l8n0zQCDPdE4IjZwyY1HMunM=
|
||||||
github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
|
github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
|
||||||
github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60=
|
github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
@@ -122,7 +122,7 @@ github.com/ckaznocha/intrange v0.3.0 h1:VqnxtK32pxgkhJgYQEeOArVidIPg+ahLP7WBOXZd
|
|||||||
github.com/ckaznocha/intrange v0.3.0/go.mod h1:+I/o2d2A1FBHgGELbGxzIcyd3/9l9DuwjM8FsbSS3Lo=
|
github.com/ckaznocha/intrange v0.3.0/go.mod h1:+I/o2d2A1FBHgGELbGxzIcyd3/9l9DuwjM8FsbSS3Lo=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs=
|
github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs=
|
||||||
github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=
|
github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=
|
||||||
github.com/daixiang0/gci v0.13.5 h1:kThgmH1yBmZSBCh1EJVxQ7JsHpm5Oms0AMed/0LaH4c=
|
github.com/daixiang0/gci v0.13.5 h1:kThgmH1yBmZSBCh1EJVxQ7JsHpm5Oms0AMed/0LaH4c=
|
||||||
@@ -235,8 +235,8 @@ github.com/golangci/go-printf-func-name v0.1.0 h1:dVokQP+NMTO7jwO4bwsRwLWeudOVUP
|
|||||||
github.com/golangci/go-printf-func-name v0.1.0/go.mod h1:wqhWFH5mUdJQhweRnldEywnR5021wTdZSNgwYceV14s=
|
github.com/golangci/go-printf-func-name v0.1.0/go.mod h1:wqhWFH5mUdJQhweRnldEywnR5021wTdZSNgwYceV14s=
|
||||||
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE=
|
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE=
|
||||||
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=
|
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=
|
||||||
github.com/golangci/golangci-lint v1.64.5 h1:5omC86XFBKXZgCrVdUWU+WNHKd+CWCxNx717KXnzKZY=
|
github.com/golangci/golangci-lint v1.64.6 h1:jOLaQN41IV7bMzXuNC4UnQGll7N1xY6eFDXkXEPGKAs=
|
||||||
github.com/golangci/golangci-lint v1.64.5/go.mod h1:WZnwq8TF0z61h3jLQ7Sk5trcP7b3kUFxLD6l1ivtdvU=
|
github.com/golangci/golangci-lint v1.64.6/go.mod h1:Wz9q+6EVuqGQ94GQ96RB2mjpcZYTOGhBhbt4O7REPu4=
|
||||||
github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=
|
github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=
|
||||||
github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
|
github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
|
||||||
github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c=
|
github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c=
|
||||||
@@ -259,8 +259,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
@@ -281,8 +281,9 @@ github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it
|
|||||||
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
|
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
|
||||||
github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
|
github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
|
||||||
github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
|
github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
|
||||||
github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q=
|
|
||||||
github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
|
github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
|
||||||
|
github.com/gostaticanalysis/comment v1.5.0 h1:X82FLl+TswsUMpMh17srGRuKaaXprTaytmEpgnKIDu8=
|
||||||
|
github.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc=
|
||||||
github.com/gostaticanalysis/forcetypeassert v0.2.0 h1:uSnWrrUEYDr86OCxWa4/Tp2jeYDlogZiZHzGkWFefTk=
|
github.com/gostaticanalysis/forcetypeassert v0.2.0 h1:uSnWrrUEYDr86OCxWa4/Tp2jeYDlogZiZHzGkWFefTk=
|
||||||
github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY=
|
github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY=
|
||||||
github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk=
|
github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk=
|
||||||
@@ -327,11 +328,11 @@ github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ=
|
|||||||
github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=
|
github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=
|
||||||
github.com/karamaru-alpha/copyloopvar v1.2.1 h1:wmZaZYIjnJ0b5UoKDjUHrikcV0zuPyyxI4SVplLd2CI=
|
github.com/karamaru-alpha/copyloopvar v1.2.1 h1:wmZaZYIjnJ0b5UoKDjUHrikcV0zuPyyxI4SVplLd2CI=
|
||||||
github.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmTJxVCY0lhxBtlfOypMM=
|
github.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmTJxVCY0lhxBtlfOypMM=
|
||||||
github.com/kisielk/errcheck v1.8.0 h1:ZX/URYa7ilESY19ik/vBmCn6zdGQLxACwjAcWbHlYlg=
|
github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M=
|
||||||
github.com/kisielk/errcheck v1.8.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ=
|
github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg=
|
github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE=
|
||||||
github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA=
|
github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
@@ -348,8 +349,8 @@ github.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCT
|
|||||||
github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY=
|
github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY=
|
||||||
github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4=
|
github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4=
|
||||||
github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=
|
github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=
|
||||||
github.com/ldez/exptostd v0.4.1 h1:DIollgQ3LWZMp3HJbSXsdE2giJxMfjyHj3eX4oiD6JU=
|
github.com/ldez/exptostd v0.4.2 h1:l5pOzHBz8mFOlbcifTxzfyYbgEmoUqjxLFHZkjlbHXs=
|
||||||
github.com/ldez/exptostd v0.4.1/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ=
|
github.com/ldez/exptostd v0.4.2/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ=
|
||||||
github.com/ldez/gomoddirectives v0.6.1 h1:Z+PxGAY+217f/bSGjNZr/b2KTXcyYLgiWI6geMBN2Qc=
|
github.com/ldez/gomoddirectives v0.6.1 h1:Z+PxGAY+217f/bSGjNZr/b2KTXcyYLgiWI6geMBN2Qc=
|
||||||
github.com/ldez/gomoddirectives v0.6.1/go.mod h1:cVBiu3AHR9V31em9u2kwfMKD43ayN5/XDgr+cdaFaKs=
|
github.com/ldez/gomoddirectives v0.6.1/go.mod h1:cVBiu3AHR9V31em9u2kwfMKD43ayN5/XDgr+cdaFaKs=
|
||||||
github.com/ldez/grignotin v0.9.0 h1:MgOEmjZIVNn6p5wPaGp/0OKWyvq42KnzAt/DAb8O4Ow=
|
github.com/ldez/grignotin v0.9.0 h1:MgOEmjZIVNn6p5wPaGp/0OKWyvq42KnzAt/DAb8O4Ow=
|
||||||
@@ -383,8 +384,8 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T
|
|||||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mgechev/revive v1.6.1 h1:ncK0ZCMWtb8GXwVAmk+IeWF2ULIDsvRxSRfg5sTwQ2w=
|
github.com/mgechev/revive v1.7.0 h1:JyeQ4yO5K8aZhIKf5rec56u0376h8AlKNQEmjfkjKlY=
|
||||||
github.com/mgechev/revive v1.6.1/go.mod h1:/2tfHWVO8UQi/hqJsIYNEKELi+DJy/e+PQpLgTB1v88=
|
github.com/mgechev/revive v1.7.0/go.mod h1:qZnwcNhoguE58dfi96IJeSTPeZQejNeoMQLUZGi4SW4=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
@@ -404,8 +405,8 @@ github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhK
|
|||||||
github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
|
github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
|
||||||
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
|
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
|
||||||
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
|
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
|
||||||
github.com/nunnatsa/ginkgolinter v0.19.0 h1:CnHRFAeBS3LdLI9h+Jidbcc5KH71GKOmaBZQk8Srnto=
|
github.com/nunnatsa/ginkgolinter v0.19.1 h1:mjwbOlDQxZi9Cal+KfbEJTCz327OLNfwNvoZ70NJ+c4=
|
||||||
github.com/nunnatsa/ginkgolinter v0.19.0/go.mod h1:jkQ3naZDmxaZMXPWaS9rblH+i+GWXQCaS/JFIWcOH2s=
|
github.com/nunnatsa/ginkgolinter v0.19.1/go.mod h1:jkQ3naZDmxaZMXPWaS9rblH+i+GWXQCaS/JFIWcOH2s=
|
||||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||||
@@ -471,8 +472,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
|
|||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryancurrah/gomodguard v1.3.5 h1:cShyguSwUEeC0jS7ylOiG/idnd1TpJ1LfHGpV3oJmPU=
|
github.com/ryancurrah/gomodguard v1.3.5 h1:cShyguSwUEeC0jS7ylOiG/idnd1TpJ1LfHGpV3oJmPU=
|
||||||
github.com/ryancurrah/gomodguard v1.3.5/go.mod h1:MXlEPQRxgfPQa62O8wzK3Ozbkv9Rkqr+wKjSxTdsNJE=
|
github.com/ryancurrah/gomodguard v1.3.5/go.mod h1:MXlEPQRxgfPQa62O8wzK3Ozbkv9Rkqr+wKjSxTdsNJE=
|
||||||
@@ -507,8 +508,8 @@ github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
|
|||||||
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
|
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
|
||||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
@@ -538,14 +539,14 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
|
|||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
||||||
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||||
github.com/tdakkota/asciicheck v0.4.0 h1:VZ13Itw4k1i7d+dpDSNS8Op645XgGHpkCEh/WHicgWw=
|
github.com/tdakkota/asciicheck v0.4.1 h1:bm0tbcmi0jezRA2b5kg4ozmMuGAFotKI3RZfrhfovg8=
|
||||||
github.com/tdakkota/asciicheck v0.4.0/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=
|
github.com/tdakkota/asciicheck v0.4.1/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=
|
||||||
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
|
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
|
||||||
github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
|
github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
|
||||||
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
|
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
|
||||||
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
|
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
|
||||||
github.com/tetafro/godot v1.4.20 h1:z/p8Ek55UdNvzt4TFn2zx2KscpW4rWqcnUrdmvWJj7E=
|
github.com/tetafro/godot v1.5.0 h1:aNwfVI4I3+gdxjMgYPus9eHmoBeJIbnajOyqZYStzuw=
|
||||||
github.com/tetafro/godot v1.4.20/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=
|
github.com/tetafro/godot v1.5.0/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=
|
||||||
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 h1:y4mJRFlM6fUyPhoXuFg/Yu02fg/nIPFMOY8tOqppoFg=
|
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 h1:y4mJRFlM6fUyPhoXuFg/Yu02fg/nIPFMOY8tOqppoFg=
|
||||||
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=
|
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=
|
||||||
github.com/timonwong/loggercheck v0.10.1 h1:uVZYClxQFpw55eh+PIoqM7uAOHMrhVcDoWDery9R8Lg=
|
github.com/timonwong/loggercheck v0.10.1 h1:uVZYClxQFpw55eh+PIoqM7uAOHMrhVcDoWDery9R8Lg=
|
||||||
|
|||||||
17
go.mod
17
go.mod
@@ -1,31 +1,32 @@
|
|||||||
module github.com/NVIDIA/nvidia-container-toolkit
|
module github.com/NVIDIA/nvidia-container-toolkit
|
||||||
|
|
||||||
go 1.22.0
|
go 1.23.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/NVIDIA/go-nvlib v0.7.1
|
github.com/NVIDIA/go-nvlib v0.7.1
|
||||||
github.com/NVIDIA/go-nvml v0.12.4-1
|
github.com/NVIDIA/go-nvml v0.12.4-1
|
||||||
github.com/moby/sys/symlink v0.3.0
|
github.com/moby/sys/symlink v0.3.0
|
||||||
github.com/opencontainers/runtime-spec v1.2.0
|
github.com/opencontainers/runc v1.2.5
|
||||||
|
github.com/opencontainers/runtime-spec v1.2.1
|
||||||
github.com/pelletier/go-toml v1.9.5
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/urfave/cli/v2 v2.27.5
|
github.com/urfave/cli/v2 v2.27.6
|
||||||
golang.org/x/mod v0.23.0
|
golang.org/x/mod v0.24.0
|
||||||
golang.org/x/sys v0.30.0
|
golang.org/x/sys v0.31.0
|
||||||
tags.cncf.io/container-device-interface v0.8.0
|
tags.cncf.io/container-device-interface v1.0.0
|
||||||
tags.cncf.io/container-device-interface/specs-go v0.8.0
|
tags.cncf.io/container-device-interface/specs-go v1.0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 // indirect
|
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 // indirect
|
||||||
github.com/opencontainers/selinux v1.11.0 // indirect
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
|
||||||
|
|||||||
28
go.sum
28
go.sum
@@ -7,6 +7,8 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y
|
|||||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -31,9 +33,11 @@ github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34
|
|||||||
github.com/moby/sys/symlink v0.3.0 h1:GZX89mEZ9u53f97npBy4Rc3vJKj7JBDj/PN2I22GrNU=
|
github.com/moby/sys/symlink v0.3.0 h1:GZX89mEZ9u53f97npBy4Rc3vJKj7JBDj/PN2I22GrNU=
|
||||||
github.com/moby/sys/symlink v0.3.0/go.mod h1:3eNdhduHmYPcgsJtZXW1W4XUJdZGBIkttZ8xKqPUJq0=
|
github.com/moby/sys/symlink v0.3.0/go.mod h1:3eNdhduHmYPcgsJtZXW1W4XUJdZGBIkttZ8xKqPUJq0=
|
||||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||||
|
github.com/opencontainers/runc v1.2.5 h1:8KAkq3Wrem8bApgOHyhRI/8IeLXIfmZ6Qaw6DNSLnA4=
|
||||||
|
github.com/opencontainers/runc v1.2.5/go.mod h1:dOQeFo29xZKBNeRBI0B19mJtfHv68YgCTh1X+YphA+4=
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
|
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
|
||||||
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
|
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
|
||||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
|
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
|
||||||
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||||
@@ -60,8 +64,8 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf
|
|||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
|
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
|
||||||
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
@@ -71,13 +75,13 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
|
|||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
@@ -88,7 +92,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||||
tags.cncf.io/container-device-interface v0.8.0 h1:8bCFo/g9WODjWx3m6EYl3GfUG31eKJbaggyBDxEldRc=
|
tags.cncf.io/container-device-interface v1.0.0 h1:fbwPQiWZNpXUb9Os6t6JW52rsOppTFUbeJOpNtN1TmI=
|
||||||
tags.cncf.io/container-device-interface v0.8.0/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y=
|
tags.cncf.io/container-device-interface v1.0.0/go.mod h1:mmi2aRGmOjK/6NR3TXjLpEIarOJ9qwgZjQ3nTIRwAaA=
|
||||||
tags.cncf.io/container-device-interface/specs-go v0.8.0 h1:QYGFzGxvYK/ZLMrjhvY0RjpUavIn4KcmRmVP/JjdBTA=
|
tags.cncf.io/container-device-interface/specs-go v1.0.0 h1:8gLw29hH1ZQP9K1YtAzpvkHCjjyIxHZYzBAvlQ+0vD8=
|
||||||
tags.cncf.io/container-device-interface/specs-go v0.8.0/go.mod h1:BhJIkjjPh4qpys+qm4DAYtUyryaTDg9zris+AczXyws=
|
tags.cncf.io/container-device-interface/specs-go v1.0.0/go.mod h1:u86hoFWqnh3hWz3esofRFKbI261bUlvUfLKGrDhJkgQ=
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ func GetDefault() (*Config, error) {
|
|||||||
AnnotationPrefixes: []string{cdi.AnnotationPrefix},
|
AnnotationPrefixes: []string{cdi.AnnotationPrefix},
|
||||||
SpecDirs: cdi.DefaultSpecDirs,
|
SpecDirs: cdi.DefaultSpecDirs,
|
||||||
},
|
},
|
||||||
|
JitCDI: jitCDIModeConfig{
|
||||||
|
LoadKernelModules: []string{"nvidia", "nvidia-uvm", "nvidia-modeset"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
AnnotationPrefixes: []string{"cdi.k8s.io/"},
|
AnnotationPrefixes: []string{"cdi.k8s.io/"},
|
||||||
SpecDirs: []string{"/etc/cdi", "/var/run/cdi"},
|
SpecDirs: []string{"/etc/cdi", "/var/run/cdi"},
|
||||||
},
|
},
|
||||||
|
JitCDI: jitCDIModeConfig{
|
||||||
|
LoadKernelModules: []string{"nvidia", "nvidia-uvm", "nvidia-modeset"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
@@ -102,6 +105,7 @@ func TestGetConfig(t *testing.T) {
|
|||||||
"nvidia-container-runtime.modes.cdi.annotation-prefixes = [\"cdi.k8s.io/\", \"example.vendor.com/\",]",
|
"nvidia-container-runtime.modes.cdi.annotation-prefixes = [\"cdi.k8s.io/\", \"example.vendor.com/\",]",
|
||||||
"nvidia-container-runtime.modes.cdi.spec-dirs = [\"/except/etc/cdi\", \"/not/var/run/cdi\",]",
|
"nvidia-container-runtime.modes.cdi.spec-dirs = [\"/except/etc/cdi\", \"/not/var/run/cdi\",]",
|
||||||
"nvidia-container-runtime.modes.csv.mount-spec-path = \"/not/etc/nvidia-container-runtime/host-files-for-container.d\"",
|
"nvidia-container-runtime.modes.csv.mount-spec-path = \"/not/etc/nvidia-container-runtime/host-files-for-container.d\"",
|
||||||
|
"nvidia-container-runtime.modes.jit-cdi.load-kernel-modules = [\"foo\"]",
|
||||||
"nvidia-container-runtime-hook.path = \"/foo/bar/nvidia-container-runtime-hook\"",
|
"nvidia-container-runtime-hook.path = \"/foo/bar/nvidia-container-runtime-hook\"",
|
||||||
"nvidia-ctk.path = \"/foo/bar/nvidia-ctk\"",
|
"nvidia-ctk.path = \"/foo/bar/nvidia-ctk\"",
|
||||||
},
|
},
|
||||||
@@ -134,6 +138,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
"/not/var/run/cdi",
|
"/not/var/run/cdi",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
JitCDI: jitCDIModeConfig{
|
||||||
|
LoadKernelModules: []string{"foo"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
@@ -178,6 +185,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
"/var/run/cdi",
|
"/var/run/cdi",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
JitCDI: jitCDIModeConfig{
|
||||||
|
LoadKernelModules: []string{"nvidia", "nvidia-uvm", "nvidia-modeset"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
@@ -213,6 +223,8 @@ func TestGetConfig(t *testing.T) {
|
|||||||
"spec-dirs = [\"/except/etc/cdi\", \"/not/var/run/cdi\",]",
|
"spec-dirs = [\"/except/etc/cdi\", \"/not/var/run/cdi\",]",
|
||||||
"[nvidia-container-runtime.modes.csv]",
|
"[nvidia-container-runtime.modes.csv]",
|
||||||
"mount-spec-path = \"/not/etc/nvidia-container-runtime/host-files-for-container.d\"",
|
"mount-spec-path = \"/not/etc/nvidia-container-runtime/host-files-for-container.d\"",
|
||||||
|
"[nvidia-container-runtime.modes.jit-cdi]",
|
||||||
|
"load-kernel-modules = [\"foo\"]",
|
||||||
"[nvidia-container-runtime-hook]",
|
"[nvidia-container-runtime-hook]",
|
||||||
"path = \"/foo/bar/nvidia-container-runtime-hook\"",
|
"path = \"/foo/bar/nvidia-container-runtime-hook\"",
|
||||||
"[nvidia-ctk]",
|
"[nvidia-ctk]",
|
||||||
@@ -247,6 +259,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
"/not/var/run/cdi",
|
"/not/var/run/cdi",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
JitCDI: jitCDIModeConfig{
|
||||||
|
LoadKernelModules: []string{"foo"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
@@ -283,6 +298,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
AnnotationPrefixes: []string{"cdi.k8s.io/"},
|
AnnotationPrefixes: []string{"cdi.k8s.io/"},
|
||||||
SpecDirs: []string{"/etc/cdi", "/var/run/cdi"},
|
SpecDirs: []string{"/etc/cdi", "/var/run/cdi"},
|
||||||
},
|
},
|
||||||
|
JitCDI: jitCDIModeConfig{
|
||||||
|
LoadKernelModules: []string{"nvidia", "nvidia-uvm", "nvidia-modeset"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
@@ -322,6 +340,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
AnnotationPrefixes: []string{"cdi.k8s.io/"},
|
AnnotationPrefixes: []string{"cdi.k8s.io/"},
|
||||||
SpecDirs: []string{"/etc/cdi", "/var/run/cdi"},
|
SpecDirs: []string{"/etc/cdi", "/var/run/cdi"},
|
||||||
},
|
},
|
||||||
|
JitCDI: jitCDIModeConfig{
|
||||||
|
LoadKernelModules: []string{"nvidia", "nvidia-uvm", "nvidia-modeset"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
|
|||||||
@@ -25,9 +25,23 @@ type features struct {
|
|||||||
// If this feature flag is not set to 'true' only host-rooted config paths
|
// If this feature flag is not set to 'true' only host-rooted config paths
|
||||||
// (i.e. paths starting with an '@' are considered valid)
|
// (i.e. paths starting with an '@' are considered valid)
|
||||||
AllowLDConfigFromContainer *feature `toml:"allow-ldconfig-from-container,omitempty"`
|
AllowLDConfigFromContainer *feature `toml:"allow-ldconfig-from-container,omitempty"`
|
||||||
|
// DisableCUDACompatLibHook, when enabled skips the injection of a specific
|
||||||
|
// hook to process CUDA compatibility libraries.
|
||||||
|
//
|
||||||
|
// Note: Since this mechanism replaces the logic in the `nvidia-container-cli`,
|
||||||
|
// toggling this feature has no effect if `allow-cuda-compat-libs-from-container` is enabled.
|
||||||
|
DisableCUDACompatLibHook *feature `toml:"disable-cuda-compat-lib-hook,omitempty"`
|
||||||
// DisableImexChannelCreation ensures that the implicit creation of
|
// DisableImexChannelCreation ensures that the implicit creation of
|
||||||
// requested IMEX channels is skipped when invoking the nvidia-container-cli.
|
// requested IMEX channels is skipped when invoking the nvidia-container-cli.
|
||||||
DisableImexChannelCreation *feature `toml:"disable-imex-channel-creation,omitempty"`
|
DisableImexChannelCreation *feature `toml:"disable-imex-channel-creation,omitempty"`
|
||||||
|
// IgnoreImexChannelRequests configures the NVIDIA Container Toolkit to
|
||||||
|
// ignore IMEX channel requests through the NVIDIA_IMEX_CHANNELS envvar or
|
||||||
|
// volume mounts.
|
||||||
|
// This ensures that the NVIDIA Container Toolkit cannot be used to provide
|
||||||
|
// access to an IMEX channel by simply specifying an environment variable,
|
||||||
|
// possibly bypassing other checks by an orchestration system such as
|
||||||
|
// kubernetes.
|
||||||
|
IgnoreImexChannelRequests *feature `toml:"ignore-imex-channel-requests,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type feature bool
|
type feature bool
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ type RuntimeConfig struct {
|
|||||||
|
|
||||||
// modesConfig defines (optional) per-mode configs
|
// modesConfig defines (optional) per-mode configs
|
||||||
type modesConfig struct {
|
type modesConfig struct {
|
||||||
CSV csvModeConfig `toml:"csv"`
|
CSV csvModeConfig `toml:"csv"`
|
||||||
CDI cdiModeConfig `toml:"cdi"`
|
CDI cdiModeConfig `toml:"cdi"`
|
||||||
|
JitCDI jitCDIModeConfig `toml:"jit-cdi"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type cdiModeConfig struct {
|
type cdiModeConfig struct {
|
||||||
@@ -45,3 +46,11 @@ type cdiModeConfig struct {
|
|||||||
type csvModeConfig struct {
|
type csvModeConfig struct {
|
||||||
MountSpecPath string `toml:"mount-spec-path"`
|
MountSpecPath string `toml:"mount-spec-path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type jitCDIModeConfig struct {
|
||||||
|
// LoadKernelModules defines the names of the kernel modules that should be
|
||||||
|
// loaded before generating a just-in-time CDI specification.
|
||||||
|
// The module names must start with `nvidia` and if no modules are specified
|
||||||
|
// no kernel modules are loaded.
|
||||||
|
LoadKernelModules []string `toml:"load-kernel-modules"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ spec-dirs = ["/etc/cdi", "/var/run/cdi"]
|
|||||||
[nvidia-container-runtime.modes.csv]
|
[nvidia-container-runtime.modes.csv]
|
||||||
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"
|
||||||
|
|
||||||
|
[nvidia-container-runtime.modes.jit-cdi]
|
||||||
|
load-kernel-modules = ["nvidia", "nvidia-uvm", "nvidia-modeset"]
|
||||||
|
|
||||||
[nvidia-container-runtime-hook]
|
[nvidia-container-runtime-hook]
|
||||||
path = "nvidia-container-runtime-hook"
|
path = "nvidia-container-runtime-hook"
|
||||||
skip-mode-detection = false
|
skip-mode-detection = false
|
||||||
|
|||||||
24
internal/discover/compat_libs.go
Normal file
24
internal/discover/compat_libs.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package discover
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/root"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewCUDACompatHookDiscoverer creates a discoverer for a enable-cuda-compat hook.
|
||||||
|
// This hook is responsible for setting up CUDA compatibility in the container and depends on the host driver version.
|
||||||
|
func NewCUDACompatHookDiscoverer(logger logger.Interface, nvidiaCDIHookPath string, driver *root.Driver) Discover {
|
||||||
|
_, cudaVersionPattern := getCUDALibRootAndVersionPattern(logger, driver)
|
||||||
|
var args []string
|
||||||
|
if !strings.Contains(cudaVersionPattern, "*") {
|
||||||
|
args = append(args, "--host-driver-version="+cudaVersionPattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateNvidiaCDIHook(
|
||||||
|
nvidiaCDIHookPath,
|
||||||
|
"enable-cuda-compat",
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -45,7 +45,7 @@ func New(opts ...Option) Devices {
|
|||||||
type Option func(*builder)
|
type Option func(*builder)
|
||||||
|
|
||||||
// WithDeviceToMajor specifies an explicit device name to major number map.
|
// WithDeviceToMajor specifies an explicit device name to major number map.
|
||||||
func WithDeviceToMajor(deviceToMajor map[string]int) Option {
|
func WithDeviceToMajor(deviceToMajor map[string]uint32) Option {
|
||||||
return func(b *builder) {
|
return func(b *builder) {
|
||||||
b.asMap = make(devices)
|
b.asMap = make(devices)
|
||||||
for name, major := range deviceToMajor {
|
for name, major := range deviceToMajor {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const (
|
|||||||
type Name string
|
type Name string
|
||||||
|
|
||||||
// Major represents a device major as specified under /proc/devices
|
// Major represents a device major as specified under /proc/devices
|
||||||
type Major int
|
type Major uint32
|
||||||
|
|
||||||
// Devices represents the set of devices under /proc/devices
|
// Devices represents the set of devices under /proc/devices
|
||||||
//
|
//
|
||||||
@@ -130,8 +130,8 @@ func nvidiaDeviceFrom(reader io.Reader) (Devices, error) {
|
|||||||
return nvidiaDevices, nil
|
return nvidiaDevices, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func devicesFrom(reader io.Reader) map[string]int {
|
func devicesFrom(reader io.Reader) map[string]uint32 {
|
||||||
allDevices := make(map[string]int)
|
allDevices := make(map[string]uint32)
|
||||||
scanner := bufio.NewScanner(reader)
|
scanner := bufio.NewScanner(reader)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
device, major, err := processProcDeviceLine(scanner.Text())
|
device, major, err := processProcDeviceLine(scanner.Text())
|
||||||
@@ -143,11 +143,11 @@ func devicesFrom(reader io.Reader) map[string]int {
|
|||||||
return allDevices
|
return allDevices
|
||||||
}
|
}
|
||||||
|
|
||||||
func processProcDeviceLine(line string) (string, int, error) {
|
func processProcDeviceLine(line string) (string, uint32, error) {
|
||||||
trimmed := strings.TrimSpace(line)
|
trimmed := strings.TrimSpace(line)
|
||||||
|
|
||||||
var name string
|
var name string
|
||||||
var major int
|
var major uint32
|
||||||
|
|
||||||
n, _ := fmt.Sscanf(trimmed, "%d %s", &major, &name)
|
n, _ := fmt.Sscanf(trimmed, "%d %s", &major, &name)
|
||||||
if n == 2 {
|
if n == 2 {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNvidiaDevices(t *testing.T) {
|
func TestNvidiaDevices(t *testing.T) {
|
||||||
perDriverDeviceMaps := map[string]map[string]int{
|
perDriverDeviceMaps := map[string]map[string]uint32{
|
||||||
"pre550": {
|
"pre550": {
|
||||||
"nvidia-frontend": 195,
|
"nvidia-frontend": 195,
|
||||||
"nvidia-nvlink": 234,
|
"nvidia-nvlink": 234,
|
||||||
@@ -100,7 +100,7 @@ func TestProcessDeviceFileLine(t *testing.T) {
|
|||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
line string
|
line string
|
||||||
name string
|
name string
|
||||||
major int
|
major uint32
|
||||||
err bool
|
err bool
|
||||||
}{
|
}{
|
||||||
{"", "", 0, true},
|
{"", "", 0, true},
|
||||||
|
|||||||
@@ -17,12 +17,15 @@
|
|||||||
package root
|
package root
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/system/nvmodules"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Driver represents a filesystem in which a set of drivers or devices is defined.
|
// Driver represents a filesystem in which a set of drivers or devices is defined.
|
||||||
@@ -125,3 +128,20 @@ func xdgDataDirs() []string {
|
|||||||
|
|
||||||
return []string{"/usr/local/share", "/usr/share"}
|
return []string{"/usr/local/share", "/usr/share"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadKmods loads the specified kernel modules in the driver root.
|
||||||
|
// Errors in loading a module do not prevent other modules from being attempted.
|
||||||
|
func (r *Driver) LoadKernelModules(moduleNames ...string) error {
|
||||||
|
modules := nvmodules.New(
|
||||||
|
nvmodules.WithLogger(r.logger),
|
||||||
|
nvmodules.WithRoot(r.Root),
|
||||||
|
)
|
||||||
|
|
||||||
|
var errs error
|
||||||
|
for _, moduleName := range moduleNames {
|
||||||
|
if err := modules.Load(moduleName); err != nil {
|
||||||
|
errs = errors.Join(errs, fmt.Errorf("failed to load kernel module %q: %w", moduleName, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,11 +22,15 @@ import (
|
|||||||
|
|
||||||
"tags.cncf.io/container-device-interface/pkg/parser"
|
"tags.cncf.io/container-device-interface/pkg/parser"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/go-nvlib/pkg/nvlib/device"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/root"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/modifier/cdi"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/modifier/cdi"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/system/nvdevices"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi"
|
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec"
|
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec"
|
||||||
)
|
)
|
||||||
@@ -34,7 +38,7 @@ import (
|
|||||||
// NewCDIModifier creates an OCI spec modifier that determines the modifications to make based on the
|
// NewCDIModifier creates an OCI spec modifier that determines the modifications to make based on the
|
||||||
// CDI specifications available on the system. The NVIDIA_VISIBLE_DEVICES environment variable is
|
// CDI specifications available on the system. The NVIDIA_VISIBLE_DEVICES environment variable is
|
||||||
// used to select the devices to include.
|
// used to select the devices to include.
|
||||||
func NewCDIModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Spec) (oci.SpecModifier, error) {
|
func NewCDIModifier(logger logger.Interface, cfg *config.Config, driver *root.Driver, ociSpec oci.Spec) (oci.SpecModifier, error) {
|
||||||
devices, err := getDevicesFromSpec(logger, ociSpec, cfg)
|
devices, err := getDevicesFromSpec(logger, ociSpec, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get required devices from OCI specification: %v", err)
|
return nil, fmt.Errorf("failed to get required devices from OCI specification: %v", err)
|
||||||
@@ -50,7 +54,7 @@ func NewCDIModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Spe
|
|||||||
return nil, fmt.Errorf("requesting a CDI device with vendor 'runtime.nvidia.com' is not supported when requesting other CDI devices")
|
return nil, fmt.Errorf("requesting a CDI device with vendor 'runtime.nvidia.com' is not supported when requesting other CDI devices")
|
||||||
}
|
}
|
||||||
if len(automaticDevices) > 0 {
|
if len(automaticDevices) > 0 {
|
||||||
automaticModifier, err := newAutomaticCDISpecModifier(logger, cfg, automaticDevices)
|
automaticModifier, err := newAutomaticCDISpecModifier(logger, cfg, driver, automaticDevices)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return automaticModifier, nil
|
return automaticModifier, nil
|
||||||
}
|
}
|
||||||
@@ -163,9 +167,9 @@ func filterAutomaticDevices(devices []string) []string {
|
|||||||
return automatic
|
return automatic
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAutomaticCDISpecModifier(logger logger.Interface, cfg *config.Config, devices []string) (oci.SpecModifier, error) {
|
func newAutomaticCDISpecModifier(logger logger.Interface, cfg *config.Config, driver *root.Driver, devices []string) (oci.SpecModifier, error) {
|
||||||
logger.Debugf("Generating in-memory CDI specs for devices %v", devices)
|
logger.Debugf("Generating in-memory CDI specs for devices %v", devices)
|
||||||
spec, err := generateAutomaticCDISpec(logger, cfg, devices)
|
spec, err := generateAutomaticCDISpec(logger, cfg, driver, devices)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to generate CDI spec: %w", err)
|
return nil, fmt.Errorf("failed to generate CDI spec: %w", err)
|
||||||
}
|
}
|
||||||
@@ -180,7 +184,7 @@ func newAutomaticCDISpecModifier(logger logger.Interface, cfg *config.Config, de
|
|||||||
return cdiModifier, nil
|
return cdiModifier, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, devices []string) (spec.Interface, error) {
|
func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, driver *root.Driver, devices []string) (spec.Interface, error) {
|
||||||
cdilib, err := nvcdi.New(
|
cdilib, err := nvcdi.New(
|
||||||
nvcdi.WithLogger(logger),
|
nvcdi.WithLogger(logger),
|
||||||
nvcdi.WithNVIDIACDIHookPath(cfg.NVIDIACTKConfig.Path),
|
nvcdi.WithNVIDIACDIHookPath(cfg.NVIDIACTKConfig.Path),
|
||||||
@@ -192,12 +196,19 @@ func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, devic
|
|||||||
return nil, fmt.Errorf("failed to construct CDI library: %w", err)
|
return nil, fmt.Errorf("failed to construct CDI library: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
identifiers := []string{}
|
// TODO: Consider moving this into the nvcdi API.
|
||||||
|
if err := driver.LoadKernelModules(cfg.NVIDIAContainerRuntimeConfig.Modes.JitCDI.LoadKernelModules...); err != nil {
|
||||||
|
logger.Warningf("Ignoring error(s) loading kernel modules: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var identifiers []string
|
||||||
for _, device := range devices {
|
for _, device := range devices {
|
||||||
_, _, id := parser.ParseDevice(device)
|
_, _, id := parser.ParseDevice(device)
|
||||||
identifiers = append(identifiers, id)
|
identifiers = append(identifiers, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tryCreateDeviceNodes(logger, driver, identifiers...)
|
||||||
|
|
||||||
deviceSpecs, err := cdilib.GetDeviceSpecsByID(identifiers...)
|
deviceSpecs, err := cdilib.GetDeviceSpecsByID(identifiers...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get CDI device specs: %w", err)
|
return nil, fmt.Errorf("failed to get CDI device specs: %w", err)
|
||||||
@@ -215,3 +226,27 @@ func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, devic
|
|||||||
spec.WithClass("gpu"),
|
spec.WithClass("gpu"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tryCreateDeviceNodes(logger logger.Interface, driver *root.Driver, identifiers ...string) {
|
||||||
|
devices, err := nvdevices.New(
|
||||||
|
nvdevices.WithLogger(logger),
|
||||||
|
nvdevices.WithDevRoot(driver.Root),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warningf("Failed to create devices library: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := devices.CreateNVIDIAControlDevices(); err != nil {
|
||||||
|
logger.Warningf("Failed to create control devices: %v", err)
|
||||||
|
}
|
||||||
|
if err := devices.CreateNVIDIACapsControlDeviceNodes(); err != nil {
|
||||||
|
logger.Warningf("Failed to create nvidia-caps control devices: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, id := range identifiers {
|
||||||
|
identifier := device.Identifier(id)
|
||||||
|
if err := devices.CreateDeviceNodes(identifier); err != nil {
|
||||||
|
logger.Warningf("Error creating device nodes for %v: %v", identifier, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/discover"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/discover"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/root"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ import (
|
|||||||
// NVIDIA_GDRCOPY=enabled
|
// NVIDIA_GDRCOPY=enabled
|
||||||
//
|
//
|
||||||
// If not devices are selected, no changes are made.
|
// If not devices are selected, no changes are made.
|
||||||
func NewFeatureGatedModifier(logger logger.Interface, cfg *config.Config, image image.CUDA) (oci.SpecModifier, error) {
|
func NewFeatureGatedModifier(logger logger.Interface, cfg *config.Config, image image.CUDA, driver *root.Driver) (oci.SpecModifier, error) {
|
||||||
if devices := image.VisibleDevicesFromEnvVar(); len(devices) == 0 {
|
if devices := image.VisibleDevicesFromEnvVar(); len(devices) == 0 {
|
||||||
logger.Infof("No modification required; no devices requested")
|
logger.Infof("No modification required; no devices requested")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -78,5 +79,24 @@ func NewFeatureGatedModifier(logger logger.Interface, cfg *config.Config, image
|
|||||||
discoverers = append(discoverers, d)
|
discoverers = append(discoverers, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !cfg.Features.AllowCUDACompatLibsFromContainer.IsEnabled() && !cfg.Features.DisableCUDACompatLibHook.IsEnabled() {
|
||||||
|
compatLibHookDiscoverer := discover.NewCUDACompatHookDiscoverer(logger, cfg.NVIDIACTKConfig.Path, driver)
|
||||||
|
discoverers = append(discoverers, compatLibHookDiscoverer)
|
||||||
|
// For legacy mode, we also need to inject a hook to update the LDCache
|
||||||
|
// after we have modifed the configuration.
|
||||||
|
if cfg.NVIDIAContainerRuntimeConfig.Mode == "legacy" {
|
||||||
|
ldcacheUpdateHookDiscoverer, err := discover.NewLDCacheUpdateHook(
|
||||||
|
logger,
|
||||||
|
discover.None{},
|
||||||
|
cfg.NVIDIACTKConfig.Path,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to construct ldcache update discoverer: %w", err)
|
||||||
|
}
|
||||||
|
discoverers = append(discoverers, ldcacheUpdateHookDiscoverer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NewModifierFromDiscoverer(logger, discover.Merge(discoverers...))
|
return NewModifierFromDiscoverer(logger, discover.Merge(discoverers...))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,20 @@ const (
|
|||||||
nvcapsDevicePath = "/dev/nvidia-caps"
|
nvcapsDevicePath = "/dev/nvidia-caps"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MigMinor represents the minor number of a MIG device
|
// An Index represents a gpu, ci, or gi index.
|
||||||
type MigMinor int
|
// We use uint32 as this typically maps to a device minor number.
|
||||||
|
type Index uint32
|
||||||
|
|
||||||
// MigCap represents the path to a MIG cap file
|
// MigMinor represents the minor number of a MIG device
|
||||||
|
type MigMinor Index
|
||||||
|
|
||||||
|
// MigCap represents the path to a MIG cap file.
|
||||||
|
// These are listed in /proc/driver/nvidia-caps/mig-minors and have one of the
|
||||||
|
// follown forms:
|
||||||
|
// - config
|
||||||
|
// - monitor
|
||||||
|
// - gpu{{ .gpuIndex }}/gi{{ .gi }}/access
|
||||||
|
// - gpu{{ .gpuIndex }}/gi{{ .gi }}/ci {{ .ci }}/access
|
||||||
type MigCap string
|
type MigCap string
|
||||||
|
|
||||||
// MigCaps stores a map of MIG cap file paths to MIG minors
|
// MigCaps stores a map of MIG cap file paths to MIG minors
|
||||||
@@ -47,16 +57,41 @@ type MigCaps map[MigCap]MigMinor
|
|||||||
|
|
||||||
// NewGPUInstanceCap creates a MigCap for the specified MIG GPU instance.
|
// NewGPUInstanceCap creates a MigCap for the specified MIG GPU instance.
|
||||||
// A GPU instance is uniquely defined by the GPU minor number and GI instance ID.
|
// A GPU instance is uniquely defined by the GPU minor number and GI instance ID.
|
||||||
func NewGPUInstanceCap(gpu, gi int) MigCap {
|
func NewGPUInstanceCap[T uint32 | int | Index](gpu, gi T) MigCap {
|
||||||
return MigCap(fmt.Sprintf("gpu%d/gi%d/access", gpu, gi))
|
return MigCap(fmt.Sprintf("gpu%d/gi%d/access", gpu, gi))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewComputeInstanceCap creates a MigCap for the specified MIG Compute instance.
|
// NewComputeInstanceCap creates a MigCap for the specified MIG Compute instance.
|
||||||
// A GPU instance is uniquely defined by the GPU minor number, GI instance ID, and CI instance ID.
|
// A GPU instance is uniquely defined by the GPU minor number, GI instance ID, and CI instance ID.
|
||||||
func NewComputeInstanceCap(gpu, gi, ci int) MigCap {
|
func NewComputeInstanceCap[T uint32 | int | Index](gpu, gi, ci T) MigCap {
|
||||||
return MigCap(fmt.Sprintf("gpu%d/gi%d/ci%d/access", gpu, gi, ci))
|
return MigCap(fmt.Sprintf("gpu%d/gi%d/ci%d/access", gpu, gi, ci))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterForGPU limits the MIG Caps to those associated with a particular GPU.
|
||||||
|
func (m MigCaps) FilterForGPU(gpu Index) MigCaps {
|
||||||
|
if m == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
filtered := make(MigCaps)
|
||||||
|
for gi := Index(0); ; gi++ {
|
||||||
|
giCap := NewGPUInstanceCap(gpu, gi)
|
||||||
|
giMinor, exist := m[giCap]
|
||||||
|
if !exist {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
filtered[giCap] = giMinor
|
||||||
|
for ci := Index(0); ; ci++ {
|
||||||
|
ciCap := NewComputeInstanceCap(gpu, gi, ci)
|
||||||
|
ciMinor, exist := m[ciCap]
|
||||||
|
if !exist {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
filtered[ciCap] = ciMinor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filtered
|
||||||
|
}
|
||||||
|
|
||||||
// GetCapDevicePath returns the path to the cap device for the specified cap.
|
// GetCapDevicePath returns the path to the cap device for the specified cap.
|
||||||
// An error is returned if the cap is invalid.
|
// An error is returned if the cap is invalid.
|
||||||
func (m MigCaps) GetCapDevicePath(cap MigCap) (string, error) {
|
func (m MigCaps) GetCapDevicePath(cap MigCap) (string, error) {
|
||||||
@@ -113,7 +148,7 @@ func processMigMinorsLine(line string) (MigCap, MigMinor, error) {
|
|||||||
return "", 0, fmt.Errorf("invalid MIG minors line: '%v'", line)
|
return "", 0, fmt.Errorf("invalid MIG minors line: '%v'", line)
|
||||||
}
|
}
|
||||||
|
|
||||||
minor, err := strconv.Atoi(parts[1])
|
minor, err := strconv.ParseUint(parts[1], 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, fmt.Errorf("error reading MIG minor from '%v': %v", line, err)
|
return "", 0, fmt.Errorf("error reading MIG minor from '%v': %v", line, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,8 @@
|
|||||||
package oci
|
package oci
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure, that SpecMock does implement Spec.
|
// Ensure, that SpecMock does implement Spec.
|
||||||
|
|||||||
@@ -75,7 +75,9 @@ func newSpecModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Sp
|
|||||||
}
|
}
|
||||||
|
|
||||||
mode := info.ResolveAutoMode(logger, cfg.NVIDIAContainerRuntimeConfig.Mode, image)
|
mode := info.ResolveAutoMode(logger, cfg.NVIDIAContainerRuntimeConfig.Mode, image)
|
||||||
modeModifier, err := newModeModifier(logger, mode, cfg, ociSpec, image)
|
// We update the mode here so that we can continue passing just the config to other functions.
|
||||||
|
cfg.NVIDIAContainerRuntimeConfig.Mode = mode
|
||||||
|
modeModifier, err := newModeModifier(logger, mode, cfg, driver, ociSpec, image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -94,7 +96,7 @@ func newSpecModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Sp
|
|||||||
}
|
}
|
||||||
modifiers = append(modifiers, graphicsModifier)
|
modifiers = append(modifiers, graphicsModifier)
|
||||||
case "feature-gated":
|
case "feature-gated":
|
||||||
featureGatedModifier, err := modifier.NewFeatureGatedModifier(logger, cfg, image)
|
featureGatedModifier, err := modifier.NewFeatureGatedModifier(logger, cfg, image, driver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -105,14 +107,14 @@ func newSpecModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Sp
|
|||||||
return modifiers, nil
|
return modifiers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newModeModifier(logger logger.Interface, mode string, cfg *config.Config, ociSpec oci.Spec, image image.CUDA) (oci.SpecModifier, error) {
|
func newModeModifier(logger logger.Interface, mode string, cfg *config.Config, driver *root.Driver, ociSpec oci.Spec, image image.CUDA) (oci.SpecModifier, error) {
|
||||||
switch mode {
|
switch mode {
|
||||||
case "legacy":
|
case "legacy":
|
||||||
return modifier.NewStableRuntimeModifier(logger, cfg.NVIDIAContainerRuntimeHookConfig.Path), nil
|
return modifier.NewStableRuntimeModifier(logger, cfg.NVIDIAContainerRuntimeHookConfig.Path), nil
|
||||||
case "csv":
|
case "csv":
|
||||||
return modifier.NewCSVModifier(logger, cfg, image)
|
return modifier.NewCSVModifier(logger, cfg, image)
|
||||||
case "cdi":
|
case "cdi":
|
||||||
return modifier.NewCDIModifier(logger, cfg, ociSpec)
|
return modifier.NewCDIModifier(logger, cfg, driver, ociSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("invalid runtime mode: %v", cfg.NVIDIAContainerRuntimeConfig.Mode)
|
return nil, fmt.Errorf("invalid runtime mode: %v", cfg.NVIDIAContainerRuntimeConfig.Mode)
|
||||||
@@ -126,8 +128,8 @@ func supportedModifierTypes(mode string) []string {
|
|||||||
return []string{"nvidia-hook-remover", "mode"}
|
return []string{"nvidia-hook-remover", "mode"}
|
||||||
case "csv":
|
case "csv":
|
||||||
// For CSV mode we support mode and feature-gated modification.
|
// For CSV mode we support mode and feature-gated modification.
|
||||||
return []string{"nvidia-hook-remover", "mode", "feature-gated"}
|
return []string{"nvidia-hook-remover", "feature-gated", "mode"}
|
||||||
default:
|
default:
|
||||||
return []string{"mode", "graphics", "feature-gated"}
|
return []string{"feature-gated", "graphics", "mode"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
122
internal/system/nvdevices/control-device-nodes.go
Normal file
122
internal/system/nvdevices/control-device-nodes.go
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 nvdevices
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/info/proc/devices"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/nvcaps"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A controlDeviceNode represents an NVIDIA devices node for control or meta devices.
|
||||||
|
// Such device nodes are typically required regardless of which GPU is being accessed.
|
||||||
|
type controlDeviceNode string
|
||||||
|
|
||||||
|
func (c controlDeviceNode) path() string {
|
||||||
|
return filepath.Join("dev", string(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNVIDIAControlDevices creates the NVIDIA control device nodes at the configured devRoot.
|
||||||
|
func (m *Interface) CreateNVIDIAControlDevices() error {
|
||||||
|
controlNodes := []controlDeviceNode{"nvidiactl", "nvidia-modeset", "nvidia-uvm", "nvidia-uvm-tools"}
|
||||||
|
for _, node := range controlNodes {
|
||||||
|
if err := m.createControlDeviceNode(node); err != nil {
|
||||||
|
return fmt.Errorf("failed to create device node %s: %w", node, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNVIDIACapsControlDeviceNodes creates the nvidia-caps control device nodes at the configured devRoot.
|
||||||
|
func (m *Interface) CreateNVIDIACapsControlDeviceNodes() error {
|
||||||
|
capsMajor, exists := m.Get("nvidia-caps")
|
||||||
|
if !exists {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs error
|
||||||
|
for _, migCap := range []nvcaps.MigCap{"config", "monitor"} {
|
||||||
|
migMinor, exists := m.migCaps[migCap]
|
||||||
|
if !exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
deviceNodePath := migMinor.DevicePath()
|
||||||
|
if err := m.createDeviceNode(deviceNodePath, capsMajor, uint32(migMinor)); err != nil {
|
||||||
|
errs = errors.Join(errs, fmt.Errorf("failed to create nvidia-caps device node %v: %w", deviceNodePath, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
// createControlDeviceNode creates the specified NVIDIA device node at the configured devRoot.
|
||||||
|
func (m *Interface) createControlDeviceNode(node controlDeviceNode) error {
|
||||||
|
if !strings.HasPrefix(string(node), "nvidia") {
|
||||||
|
return fmt.Errorf("invalid device node %q: %w", node, errInvalidDeviceNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
major, err := m.controlDeviceNodeMajor(node)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to determine major: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
minor, err := m.controlDeviceNodeMinor(node)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to determine minor: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.createDeviceNode(node.path(), major, minor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// controlDeviceNodeMajor returns the major number for the specified NVIDIA control device node.
|
||||||
|
// If the device node is not supported, an error is returned.
|
||||||
|
func (m *Interface) controlDeviceNodeMajor(node controlDeviceNode) (devices.Major, error) {
|
||||||
|
var valid bool
|
||||||
|
var major devices.Major
|
||||||
|
switch node {
|
||||||
|
case "nvidia-uvm", "nvidia-uvm-tools":
|
||||||
|
major, valid = m.Get(devices.NVIDIAUVM)
|
||||||
|
case "nvidia-modeset", "nvidiactl":
|
||||||
|
major, valid = m.Get(devices.NVIDIAGPU)
|
||||||
|
}
|
||||||
|
|
||||||
|
if valid {
|
||||||
|
return major, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, errInvalidDeviceNode
|
||||||
|
}
|
||||||
|
|
||||||
|
// controlDeviceNodeMinor returns the minor number for the specified NVIDIA control device node.
|
||||||
|
// If the device node is not supported, an error is returned.
|
||||||
|
func (m *Interface) controlDeviceNodeMinor(node controlDeviceNode) (uint32, error) {
|
||||||
|
switch node {
|
||||||
|
case "nvidia-modeset":
|
||||||
|
return devices.NVIDIAModesetMinor, nil
|
||||||
|
case "nvidia-uvm-tools":
|
||||||
|
return devices.NVIDIAUVMToolsMinor, nil
|
||||||
|
case "nvidia-uvm":
|
||||||
|
return devices.NVIDIAUVMMinor, nil
|
||||||
|
case "nvidiactl":
|
||||||
|
return devices.NVIDIACTLMinor, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, errInvalidDeviceNode
|
||||||
|
}
|
||||||
@@ -22,8 +22,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/go-nvlib/pkg/nvlib/device"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/info/proc/devices"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/info/proc/devices"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/nvcaps"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errInvalidDeviceNode = errors.New("invalid device node")
|
var errInvalidDeviceNode = errors.New("invalid device node")
|
||||||
@@ -38,6 +41,8 @@ type Interface struct {
|
|||||||
// devRoot is the root directory where device nodes are expected to exist.
|
// devRoot is the root directory where device nodes are expected to exist.
|
||||||
devRoot string
|
devRoot string
|
||||||
|
|
||||||
|
migCaps nvcaps.MigCaps
|
||||||
|
|
||||||
mknoder
|
mknoder
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +67,14 @@ func New(opts ...Option) (*Interface, error) {
|
|||||||
i.Devices = devices
|
i.Devices = devices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if i.migCaps == nil {
|
||||||
|
migCaps, err := nvcaps.NewMigCaps()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to load MIG caps: %w", err)
|
||||||
|
}
|
||||||
|
i.migCaps = migCaps
|
||||||
|
}
|
||||||
|
|
||||||
if i.dryRun {
|
if i.dryRun {
|
||||||
i.mknoder = &mknodLogger{i.logger}
|
i.mknoder = &mknodLogger{i.logger}
|
||||||
} else {
|
} else {
|
||||||
@@ -70,77 +83,40 @@ func New(opts ...Option) (*Interface, error) {
|
|||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateNVIDIAControlDevices creates the NVIDIA control device nodes at the configured devRoot.
|
// CreateDeviceNodes creates the device nodes for a device with the specified identifier.
|
||||||
func (m *Interface) CreateNVIDIAControlDevices() error {
|
// A list of created device nodes are returned and an error.
|
||||||
controlNodes := []string{"nvidiactl", "nvidia-modeset", "nvidia-uvm", "nvidia-uvm-tools"}
|
func (m *Interface) CreateDeviceNodes(id device.Identifier) error {
|
||||||
for _, node := range controlNodes {
|
switch {
|
||||||
err := m.CreateNVIDIADevice(node)
|
case id.IsGpuIndex():
|
||||||
|
gpuIndex, err := toIndex(string(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create device node %s: %w", node, err)
|
return fmt.Errorf("invalid GPU index: %v", id)
|
||||||
|
}
|
||||||
|
return m.createGPUDeviceNode(gpuIndex)
|
||||||
|
case id.IsMigIndex():
|
||||||
|
indices := strings.Split(string(id), ":")
|
||||||
|
if len(indices) != 2 {
|
||||||
|
return fmt.Errorf("invalid MIG index %v", id)
|
||||||
|
}
|
||||||
|
gpuIndex, err := toIndex(indices[0])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid parent index %v: %w", indices[0], err)
|
||||||
|
}
|
||||||
|
if err := m.createGPUDeviceNode(gpuIndex); err != nil {
|
||||||
|
return fmt.Errorf("failed to create parent device node: %w", err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateNVIDIADevice creates the specified NVIDIA device node at the configured devRoot.
|
return m.createMigDeviceNodes(gpuIndex)
|
||||||
func (m *Interface) CreateNVIDIADevice(node string) error {
|
case id.IsGpuUUID(), id.IsMigUUID(), id == "all":
|
||||||
node = filepath.Base(node)
|
return m.createAllGPUDeviceNodes()
|
||||||
if !strings.HasPrefix(node, "nvidia") {
|
default:
|
||||||
return fmt.Errorf("invalid device node %q: %w", node, errInvalidDeviceNode)
|
return fmt.Errorf("invalid device identifier: %v", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
major, err := m.Major(node)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to determine major: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
minor, err := m.Minor(node)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to determine minor: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.createDeviceNode(filepath.Join("dev", node), int(major), int(minor))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// createDeviceNode creates the specified device node with the require major and minor numbers.
|
// createDeviceNode creates the specified device node with the require major and minor numbers.
|
||||||
// If a devRoot is configured, this is prepended to the path.
|
// If a devRoot is configured, this is prepended to the path.
|
||||||
func (m *Interface) createDeviceNode(path string, major int, minor int) error {
|
func (m *Interface) createDeviceNode(path string, major devices.Major, minor uint32) error {
|
||||||
path = filepath.Join(m.devRoot, path)
|
path = filepath.Join(m.devRoot, path)
|
||||||
return m.Mknode(path, major, minor)
|
return m.Mknode(path, uint32(major), minor)
|
||||||
}
|
|
||||||
|
|
||||||
// Major returns the major number for the specified NVIDIA device node.
|
|
||||||
// If the device node is not supported, an error is returned.
|
|
||||||
func (m *Interface) Major(node string) (int64, error) {
|
|
||||||
var valid bool
|
|
||||||
var major devices.Major
|
|
||||||
switch node {
|
|
||||||
case "nvidia-uvm", "nvidia-uvm-tools":
|
|
||||||
major, valid = m.Get(devices.NVIDIAUVM)
|
|
||||||
case "nvidia-modeset", "nvidiactl":
|
|
||||||
major, valid = m.Get(devices.NVIDIAGPU)
|
|
||||||
}
|
|
||||||
|
|
||||||
if valid {
|
|
||||||
return int64(major), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, errInvalidDeviceNode
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor number for the specified NVIDIA device node.
|
|
||||||
// If the device node is not supported, an error is returned.
|
|
||||||
func (m *Interface) Minor(node string) (int64, error) {
|
|
||||||
switch node {
|
|
||||||
case "nvidia-modeset":
|
|
||||||
return devices.NVIDIAModesetMinor, nil
|
|
||||||
case "nvidia-uvm-tools":
|
|
||||||
return devices.NVIDIAUVMToolsMinor, nil
|
|
||||||
case "nvidia-uvm":
|
|
||||||
return devices.NVIDIAUVMMinor, nil
|
|
||||||
case "nvidiactl":
|
|
||||||
return devices.NVIDIACTLMinor, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, errInvalidDeviceNode
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ func TestCreateControlDevices(t *testing.T) {
|
|||||||
logger, _ := testlog.NewNullLogger()
|
logger, _ := testlog.NewNullLogger()
|
||||||
|
|
||||||
nvidiaDevices := devices.New(
|
nvidiaDevices := devices.New(
|
||||||
devices.WithDeviceToMajor(map[string]int{
|
devices.WithDeviceToMajor(map[string]uint32{
|
||||||
"nvidia-frontend": 195,
|
"nvidia-frontend": 195,
|
||||||
"nvidia-uvm": 243,
|
"nvidia-uvm": 243,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
nvidia550Devices := devices.New(
|
nvidia550Devices := devices.New(
|
||||||
devices.WithDeviceToMajor(map[string]int{
|
devices.WithDeviceToMajor(map[string]uint32{
|
||||||
"nvidia": 195,
|
"nvidia": 195,
|
||||||
"nvidia-uvm": 243,
|
"nvidia-uvm": 243,
|
||||||
}),
|
}),
|
||||||
@@ -52,8 +52,8 @@ func TestCreateControlDevices(t *testing.T) {
|
|||||||
expectedError error
|
expectedError error
|
||||||
expectedCalls []struct {
|
expectedCalls []struct {
|
||||||
S string
|
S string
|
||||||
N1 int
|
V1 uint32
|
||||||
N2 int
|
V2 uint32
|
||||||
}
|
}
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -63,8 +63,8 @@ func TestCreateControlDevices(t *testing.T) {
|
|||||||
mknodeError: nil,
|
mknodeError: nil,
|
||||||
expectedCalls: []struct {
|
expectedCalls: []struct {
|
||||||
S string
|
S string
|
||||||
N1 int
|
V1 uint32
|
||||||
N2 int
|
V2 uint32
|
||||||
}{
|
}{
|
||||||
{"/dev/nvidiactl", 195, 255},
|
{"/dev/nvidiactl", 195, 255},
|
||||||
{"/dev/nvidia-modeset", 195, 254},
|
{"/dev/nvidia-modeset", 195, 254},
|
||||||
@@ -79,8 +79,8 @@ func TestCreateControlDevices(t *testing.T) {
|
|||||||
mknodeError: nil,
|
mknodeError: nil,
|
||||||
expectedCalls: []struct {
|
expectedCalls: []struct {
|
||||||
S string
|
S string
|
||||||
N1 int
|
V1 uint32
|
||||||
N2 int
|
V2 uint32
|
||||||
}{
|
}{
|
||||||
{"/dev/nvidiactl", 195, 255},
|
{"/dev/nvidiactl", 195, 255},
|
||||||
{"/dev/nvidia-modeset", 195, 254},
|
{"/dev/nvidia-modeset", 195, 254},
|
||||||
@@ -95,8 +95,8 @@ func TestCreateControlDevices(t *testing.T) {
|
|||||||
mknodeError: nil,
|
mknodeError: nil,
|
||||||
expectedCalls: []struct {
|
expectedCalls: []struct {
|
||||||
S string
|
S string
|
||||||
N1 int
|
V1 uint32
|
||||||
N2 int
|
V2 uint32
|
||||||
}{
|
}{
|
||||||
{"/some/root/dev/nvidiactl", 195, 255},
|
{"/some/root/dev/nvidiactl", 195, 255},
|
||||||
{"/some/root/dev/nvidia-modeset", 195, 254},
|
{"/some/root/dev/nvidia-modeset", 195, 254},
|
||||||
@@ -112,8 +112,8 @@ func TestCreateControlDevices(t *testing.T) {
|
|||||||
// We expect the first call to this to fail, and the rest to be skipped
|
// We expect the first call to this to fail, and the rest to be skipped
|
||||||
expectedCalls: []struct {
|
expectedCalls: []struct {
|
||||||
S string
|
S string
|
||||||
N1 int
|
V1 uint32
|
||||||
N2 int
|
V2 uint32
|
||||||
}{
|
}{
|
||||||
{"/dev/nvidiactl", 195, 255},
|
{"/dev/nvidiactl", 195, 255},
|
||||||
},
|
},
|
||||||
@@ -132,7 +132,7 @@ func TestCreateControlDevices(t *testing.T) {
|
|||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
mknode := &mknoderMock{
|
mknode := &mknoderMock{
|
||||||
MknodeFunc: func(string, int, int) error {
|
MknodeFunc: func(string, uint32, uint32) error {
|
||||||
return tc.mknodeError
|
return tc.mknodeError
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
88
internal/system/nvdevices/gpu-device-nodes.go
Normal file
88
internal/system/nvdevices/gpu-device-nodes.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 nvdevices
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/go-nvlib/pkg/nvpci"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/info/proc/devices"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/nvcaps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type gpuIndex nvcaps.Index
|
||||||
|
|
||||||
|
func toIndex(index string) (gpuIndex, error) {
|
||||||
|
i, err := strconv.ParseUint(index, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return gpuIndex(i), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Interface) createGPUDeviceNode(gpu gpuIndex) error {
|
||||||
|
major, exists := m.Get(devices.NVIDIAGPU)
|
||||||
|
if !exists {
|
||||||
|
return fmt.Errorf("failed to determine device major; nvidia kernel module may not be loaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceNodePath := fmt.Sprintf("/dev/nvidia%d", gpu)
|
||||||
|
if err := m.createDeviceNode(deviceNodePath, major, uint32(gpu)); err != nil {
|
||||||
|
return fmt.Errorf("failed to create device node %v: %w", deviceNodePath, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Interface) createMigDeviceNodes(gpu gpuIndex) error {
|
||||||
|
capsMajor, exists := m.Get("nvidia-caps")
|
||||||
|
if !exists {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var errs error
|
||||||
|
for _, capsDeviceMinor := range m.migCaps.FilterForGPU(nvcaps.Index(gpu)) {
|
||||||
|
capDevicePath := capsDeviceMinor.DevicePath()
|
||||||
|
err := m.createDeviceNode(capDevicePath, capsMajor, uint32(capsDeviceMinor))
|
||||||
|
errs = errors.Join(errs, fmt.Errorf("failed to create %v: %w", capDevicePath, err))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Interface) createAllGPUDeviceNodes() error {
|
||||||
|
gpus, err := nvpci.New(
|
||||||
|
nvpci.WithPCIDevicesRoot(filepath.Join(m.devRoot, nvpci.PCIDevicesRoot)),
|
||||||
|
nvpci.WithLogger(m.logger),
|
||||||
|
).GetGPUs()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get GPU information from PCI: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
count := gpuIndex(len(gpus))
|
||||||
|
if count == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs error
|
||||||
|
for gpuIndex := gpuIndex(0); gpuIndex < count; gpuIndex++ {
|
||||||
|
errs = errors.Join(errs, m.createGPUDeviceNode(gpuIndex))
|
||||||
|
errs = errors.Join(errs, m.createMigDeviceNodes(gpuIndex))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
@@ -25,16 +25,16 @@ import (
|
|||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate moq -stub -out mknod_mock.go . mknoder
|
//go:generate moq -fmt=goimports -rm -stub -out mknod_mock.go . mknoder
|
||||||
type mknoder interface {
|
type mknoder interface {
|
||||||
Mknode(string, int, int) error
|
Mknode(string, uint32, uint32) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type mknodLogger struct {
|
type mknodLogger struct {
|
||||||
logger.Interface
|
logger.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mknodLogger) Mknode(path string, major, minor int) error {
|
func (m *mknodLogger) Mknode(path string, major uint32, minor uint32) error {
|
||||||
m.Infof("Running: mknod --mode=0666 %s c %d %d", path, major, minor)
|
m.Infof("Running: mknod --mode=0666 %s c %d %d", path, major, minor)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ type mknodUnix struct {
|
|||||||
logger logger.Interface
|
logger logger.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mknodUnix) Mknode(path string, major, minor int) error {
|
func (m *mknodUnix) Mknode(path string, major uint32, minor uint32) error {
|
||||||
// TODO: Ensure that the existing device node has the correct properties.
|
// TODO: Ensure that the existing device node has the correct properties.
|
||||||
if _, err := os.Stat(path); err == nil {
|
if _, err := os.Stat(path); err == nil {
|
||||||
m.logger.Infof("Skipping: %s already exists", path)
|
m.logger.Infof("Skipping: %s already exists", path)
|
||||||
@@ -52,7 +52,7 @@ func (m *mknodUnix) Mknode(path string, major, minor int) error {
|
|||||||
return fmt.Errorf("failed to stat %s: %v", path, err)
|
return fmt.Errorf("failed to stat %s: %v", path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := unix.Mknod(path, unix.S_IFCHR, int(unix.Mkdev(uint32(major), uint32(minor))))
|
err := unix.Mknod(path, unix.S_IFCHR, int(unix.Mkdev(major, minor)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ var _ mknoder = &mknoderMock{}
|
|||||||
//
|
//
|
||||||
// // make and configure a mocked mknoder
|
// // make and configure a mocked mknoder
|
||||||
// mockedmknoder := &mknoderMock{
|
// mockedmknoder := &mknoderMock{
|
||||||
// MknodeFunc: func(s string, n1 int, n2 int) error {
|
// MknodeFunc: func(s string, v1 uint32, v2 uint32) error {
|
||||||
// panic("mock out the Mknode method")
|
// panic("mock out the Mknode method")
|
||||||
// },
|
// },
|
||||||
// }
|
// }
|
||||||
@@ -28,7 +28,7 @@ var _ mknoder = &mknoderMock{}
|
|||||||
// }
|
// }
|
||||||
type mknoderMock struct {
|
type mknoderMock struct {
|
||||||
// MknodeFunc mocks the Mknode method.
|
// MknodeFunc mocks the Mknode method.
|
||||||
MknodeFunc func(s string, n1 int, n2 int) error
|
MknodeFunc func(s string, v1 uint32, v2 uint32) error
|
||||||
|
|
||||||
// calls tracks calls to the methods.
|
// calls tracks calls to the methods.
|
||||||
calls struct {
|
calls struct {
|
||||||
@@ -36,25 +36,25 @@ type mknoderMock struct {
|
|||||||
Mknode []struct {
|
Mknode []struct {
|
||||||
// S is the s argument value.
|
// S is the s argument value.
|
||||||
S string
|
S string
|
||||||
// N1 is the n1 argument value.
|
// V1 is the v1 argument value.
|
||||||
N1 int
|
V1 uint32
|
||||||
// N2 is the n2 argument value.
|
// V2 is the v2 argument value.
|
||||||
N2 int
|
V2 uint32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lockMknode sync.RWMutex
|
lockMknode sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mknode calls MknodeFunc.
|
// Mknode calls MknodeFunc.
|
||||||
func (mock *mknoderMock) Mknode(s string, n1 int, n2 int) error {
|
func (mock *mknoderMock) Mknode(s string, v1 uint32, v2 uint32) error {
|
||||||
callInfo := struct {
|
callInfo := struct {
|
||||||
S string
|
S string
|
||||||
N1 int
|
V1 uint32
|
||||||
N2 int
|
V2 uint32
|
||||||
}{
|
}{
|
||||||
S: s,
|
S: s,
|
||||||
N1: n1,
|
V1: v1,
|
||||||
N2: n2,
|
V2: v2,
|
||||||
}
|
}
|
||||||
mock.lockMknode.Lock()
|
mock.lockMknode.Lock()
|
||||||
mock.calls.Mknode = append(mock.calls.Mknode, callInfo)
|
mock.calls.Mknode = append(mock.calls.Mknode, callInfo)
|
||||||
@@ -65,7 +65,7 @@ func (mock *mknoderMock) Mknode(s string, n1 int, n2 int) error {
|
|||||||
)
|
)
|
||||||
return errOut
|
return errOut
|
||||||
}
|
}
|
||||||
return mock.MknodeFunc(s, n1, n2)
|
return mock.MknodeFunc(s, v1, v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MknodeCalls gets all the calls that were made to Mknode.
|
// MknodeCalls gets all the calls that were made to Mknode.
|
||||||
@@ -74,13 +74,13 @@ func (mock *mknoderMock) Mknode(s string, n1 int, n2 int) error {
|
|||||||
// len(mockedmknoder.MknodeCalls())
|
// len(mockedmknoder.MknodeCalls())
|
||||||
func (mock *mknoderMock) MknodeCalls() []struct {
|
func (mock *mknoderMock) MknodeCalls() []struct {
|
||||||
S string
|
S string
|
||||||
N1 int
|
V1 uint32
|
||||||
N2 int
|
V2 uint32
|
||||||
} {
|
} {
|
||||||
var calls []struct {
|
var calls []struct {
|
||||||
S string
|
S string
|
||||||
N1 int
|
V1 uint32
|
||||||
N2 int
|
V2 uint32
|
||||||
}
|
}
|
||||||
mock.lockMknode.RLock()
|
mock.lockMknode.RLock()
|
||||||
calls = mock.calls.Mknode
|
calls = mock.calls.Mknode
|
||||||
|
|||||||
@@ -35,3 +35,13 @@ type Interface interface {
|
|||||||
GetMIGDeviceSpecs(int, device.Device, int, device.MigDevice) ([]specs.Device, error)
|
GetMIGDeviceSpecs(int, device.Device, int, device.MigDevice) ([]specs.Device, error)
|
||||||
GetDeviceSpecsByID(...string) ([]specs.Device, error)
|
GetDeviceSpecsByID(...string) ([]specs.Device, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A HookName refers to one of the predefined set of CDI hooks that may be
|
||||||
|
// included in the generated CDI specification.
|
||||||
|
type HookName string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// HookEnableCudaCompat refers to the hook used to enable CUDA Forward Compatibility.
|
||||||
|
// This was added with v1.17.5 of the NVIDIA Container Toolkit.
|
||||||
|
HookEnableCudaCompat = HookName("enable-cuda-compat")
|
||||||
|
)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func (l *nvmllib) newCommonNVMLDiscoverer() (discover.Discover, error) {
|
|||||||
l.logger.Warningf("failed to create discoverer for graphics mounts: %v", err)
|
l.logger.Warningf("failed to create discoverer for graphics mounts: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
driverFiles, err := NewDriverDiscoverer(l.logger, l.driver, l.nvidiaCDIHookPath, l.ldconfigPath, l.nvmllib)
|
driverFiles, err := l.NewDriverDiscoverer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create discoverer for driver files: %v", err)
|
return nil, fmt.Errorf("failed to create discoverer for driver files: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,41 +34,41 @@ import (
|
|||||||
|
|
||||||
// NewDriverDiscoverer creates a discoverer for the libraries and binaries associated with a driver installation.
|
// NewDriverDiscoverer creates a discoverer for the libraries and binaries associated with a driver installation.
|
||||||
// The supplied NVML Library is used to query the expected driver version.
|
// The supplied NVML Library is used to query the expected driver version.
|
||||||
func NewDriverDiscoverer(logger logger.Interface, driver *root.Driver, nvidiaCDIHookPath string, ldconfigPath string, nvmllib nvml.Interface) (discover.Discover, error) {
|
func (l *nvmllib) NewDriverDiscoverer() (discover.Discover, error) {
|
||||||
if r := nvmllib.Init(); r != nvml.SUCCESS {
|
if r := l.nvmllib.Init(); r != nvml.SUCCESS {
|
||||||
return nil, fmt.Errorf("failed to initialize NVML: %v", r)
|
return nil, fmt.Errorf("failed to initialize NVML: %v", r)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := nvmllib.Shutdown(); r != nvml.SUCCESS {
|
if r := l.nvmllib.Shutdown(); r != nvml.SUCCESS {
|
||||||
logger.Warningf("failed to shutdown NVML: %v", r)
|
l.logger.Warningf("failed to shutdown NVML: %v", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
version, r := nvmllib.SystemGetDriverVersion()
|
version, r := l.nvmllib.SystemGetDriverVersion()
|
||||||
if r != nvml.SUCCESS {
|
if r != nvml.SUCCESS {
|
||||||
return nil, fmt.Errorf("failed to determine driver version: %v", r)
|
return nil, fmt.Errorf("failed to determine driver version: %v", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newDriverVersionDiscoverer(logger, driver, nvidiaCDIHookPath, ldconfigPath, version)
|
return (*nvcdilib)(l).newDriverVersionDiscoverer(version)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDriverVersionDiscoverer(logger logger.Interface, driver *root.Driver, nvidiaCDIHookPath, ldconfigPath, version string) (discover.Discover, error) {
|
func (l *nvcdilib) newDriverVersionDiscoverer(version string) (discover.Discover, error) {
|
||||||
libraries, err := NewDriverLibraryDiscoverer(logger, driver, nvidiaCDIHookPath, ldconfigPath, version)
|
libraries, err := l.NewDriverLibraryDiscoverer(version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create discoverer for driver libraries: %v", err)
|
return nil, fmt.Errorf("failed to create discoverer for driver libraries: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcs, err := discover.NewIPCDiscoverer(logger, driver.Root)
|
ipcs, err := discover.NewIPCDiscoverer(l.logger, l.driver.Root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create discoverer for IPC sockets: %v", err)
|
return nil, fmt.Errorf("failed to create discoverer for IPC sockets: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
firmwares, err := NewDriverFirmwareDiscoverer(logger, driver.Root, version)
|
firmwares, err := NewDriverFirmwareDiscoverer(l.logger, l.driver.Root, version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create discoverer for GSP firmware: %v", err)
|
return nil, fmt.Errorf("failed to create discoverer for GSP firmware: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
binaries := NewDriverBinariesDiscoverer(logger, driver.Root)
|
binaries := NewDriverBinariesDiscoverer(l.logger, l.driver.Root)
|
||||||
|
|
||||||
d := discover.Merge(
|
d := discover.Merge(
|
||||||
libraries,
|
libraries,
|
||||||
@@ -81,32 +81,41 @@ func newDriverVersionDiscoverer(logger logger.Interface, driver *root.Driver, nv
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewDriverLibraryDiscoverer creates a discoverer for the libraries associated with the specified driver version.
|
// NewDriverLibraryDiscoverer creates a discoverer for the libraries associated with the specified driver version.
|
||||||
func NewDriverLibraryDiscoverer(logger logger.Interface, driver *root.Driver, nvidiaCDIHookPath, ldconfigPath, version string) (discover.Discover, error) {
|
func (l *nvcdilib) NewDriverLibraryDiscoverer(version string) (discover.Discover, error) {
|
||||||
libraryPaths, err := getVersionLibs(logger, driver, version)
|
libraryPaths, err := getVersionLibs(l.logger, l.driver, version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get libraries for driver version: %v", err)
|
return nil, fmt.Errorf("failed to get libraries for driver version: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
libraries := discover.NewMounts(
|
libraries := discover.NewMounts(
|
||||||
logger,
|
l.logger,
|
||||||
lookup.NewFileLocator(
|
lookup.NewFileLocator(
|
||||||
lookup.WithLogger(logger),
|
lookup.WithLogger(l.logger),
|
||||||
lookup.WithRoot(driver.Root),
|
lookup.WithRoot(l.driver.Root),
|
||||||
),
|
),
|
||||||
driver.Root,
|
l.driver.Root,
|
||||||
libraryPaths,
|
libraryPaths,
|
||||||
)
|
)
|
||||||
|
|
||||||
updateLDCache, _ := discover.NewLDCacheUpdateHook(logger, libraries, nvidiaCDIHookPath, ldconfigPath)
|
var discoverers []discover.Discover
|
||||||
|
|
||||||
d := discover.Merge(
|
driverDotSoSymlinksDiscoverer := discover.WithDriverDotSoSymlinks(
|
||||||
discover.WithDriverDotSoSymlinks(
|
libraries,
|
||||||
libraries,
|
version,
|
||||||
version,
|
l.nvidiaCDIHookPath,
|
||||||
nvidiaCDIHookPath,
|
|
||||||
),
|
|
||||||
updateLDCache,
|
|
||||||
)
|
)
|
||||||
|
discoverers = append(discoverers, driverDotSoSymlinksDiscoverer)
|
||||||
|
|
||||||
|
if l.HookIsSupported(HookEnableCudaCompat) {
|
||||||
|
// TODO: The following should use the version directly.
|
||||||
|
cudaCompatLibHookDiscoverer := discover.NewCUDACompatHookDiscoverer(l.logger, l.nvidiaCDIHookPath, l.driver)
|
||||||
|
discoverers = append(discoverers, cudaCompatLibHookDiscoverer)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLDCache, _ := discover.NewLDCacheUpdateHook(l.logger, libraries, l.nvidiaCDIHookPath, l.ldconfigPath)
|
||||||
|
discoverers = append(discoverers, updateLDCache)
|
||||||
|
|
||||||
|
d := discover.Merge(discoverers...)
|
||||||
|
|
||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|||||||
30
pkg/nvcdi/hooks.go
Normal file
30
pkg/nvcdi/hooks.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 2025, 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 nvcdi
|
||||||
|
|
||||||
|
// disabledHooks allows individual hooks to be disabled.
|
||||||
|
type disabledHooks map[HookName]bool
|
||||||
|
|
||||||
|
// HookIsSupported checks whether a hook of the specified name is supported.
|
||||||
|
// Hooks must be explicitly disabled, meaning that if no disabled hooks are
|
||||||
|
// all hooks are supported.
|
||||||
|
func (l *nvcdilib) HookIsSupported(h HookName) bool {
|
||||||
|
if len(l.disabledHooks) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return !l.disabledHooks[h]
|
||||||
|
}
|
||||||
@@ -39,26 +39,26 @@ func TestImexMode(t *testing.T) {
|
|||||||
|
|
||||||
expectedSpec := `---
|
expectedSpec := `---
|
||||||
cdiVersion: 0.5.0
|
cdiVersion: 0.5.0
|
||||||
|
kind: nvidia.com/imex-channel
|
||||||
|
devices:
|
||||||
|
- name: "0"
|
||||||
|
containerEdits:
|
||||||
|
deviceNodes:
|
||||||
|
- path: /dev/nvidia-caps-imex-channels/channel0
|
||||||
|
hostPath: {{ .hostRoot }}/dev/nvidia-caps-imex-channels/channel0
|
||||||
|
- name: "1"
|
||||||
|
containerEdits:
|
||||||
|
deviceNodes:
|
||||||
|
- path: /dev/nvidia-caps-imex-channels/channel1
|
||||||
|
hostPath: {{ .hostRoot }}/dev/nvidia-caps-imex-channels/channel1
|
||||||
|
- name: "2047"
|
||||||
|
containerEdits:
|
||||||
|
deviceNodes:
|
||||||
|
- path: /dev/nvidia-caps-imex-channels/channel2047
|
||||||
|
hostPath: {{ .hostRoot }}/dev/nvidia-caps-imex-channels/channel2047
|
||||||
containerEdits:
|
containerEdits:
|
||||||
env:
|
env:
|
||||||
- NVIDIA_VISIBLE_DEVICES=void
|
- NVIDIA_VISIBLE_DEVICES=void
|
||||||
devices:
|
|
||||||
- containerEdits:
|
|
||||||
deviceNodes:
|
|
||||||
- hostPath: {{ .hostRoot }}/dev/nvidia-caps-imex-channels/channel0
|
|
||||||
path: /dev/nvidia-caps-imex-channels/channel0
|
|
||||||
name: "0"
|
|
||||||
- containerEdits:
|
|
||||||
deviceNodes:
|
|
||||||
- hostPath: {{ .hostRoot }}/dev/nvidia-caps-imex-channels/channel1
|
|
||||||
path: /dev/nvidia-caps-imex-channels/channel1
|
|
||||||
name: "1"
|
|
||||||
- containerEdits:
|
|
||||||
deviceNodes:
|
|
||||||
- hostPath: {{ .hostRoot }}/dev/nvidia-caps-imex-channels/channel2047
|
|
||||||
path: /dev/nvidia-caps-imex-channels/channel2047
|
|
||||||
name: "2047"
|
|
||||||
kind: nvidia.com/imex-channel
|
|
||||||
`
|
`
|
||||||
expectedSpec = strings.ReplaceAll(expectedSpec, "{{ .hostRoot }}", hostRoot)
|
expectedSpec = strings.ReplaceAll(expectedSpec, "{{ .hostRoot }}", hostRoot)
|
||||||
|
|
||||||
|
|||||||
@@ -22,26 +22,14 @@ import (
|
|||||||
"github.com/NVIDIA/go-nvlib/pkg/nvlib/device"
|
"github.com/NVIDIA/go-nvlib/pkg/nvlib/device"
|
||||||
"github.com/NVIDIA/go-nvlib/pkg/nvlib/info"
|
"github.com/NVIDIA/go-nvlib/pkg/nvlib/info"
|
||||||
"github.com/NVIDIA/go-nvml/pkg/nvml"
|
"github.com/NVIDIA/go-nvml/pkg/nvml"
|
||||||
"tags.cncf.io/container-device-interface/pkg/cdi"
|
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/root"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/root"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec"
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform"
|
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform"
|
||||||
)
|
)
|
||||||
|
|
||||||
type wrapper struct {
|
|
||||||
Interface
|
|
||||||
|
|
||||||
vendor string
|
|
||||||
class string
|
|
||||||
|
|
||||||
mergedDeviceOptions []transform.MergedDeviceOption
|
|
||||||
}
|
|
||||||
|
|
||||||
type nvcdilib struct {
|
type nvcdilib struct {
|
||||||
logger logger.Interface
|
logger logger.Interface
|
||||||
nvmllib nvml.Interface
|
nvmllib nvml.Interface
|
||||||
@@ -66,11 +54,15 @@ type nvcdilib struct {
|
|||||||
infolib info.Interface
|
infolib info.Interface
|
||||||
|
|
||||||
mergedDeviceOptions []transform.MergedDeviceOption
|
mergedDeviceOptions []transform.MergedDeviceOption
|
||||||
|
|
||||||
|
disabledHooks disabledHooks
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new nvcdi library
|
// New creates a new nvcdi library
|
||||||
func New(opts ...Option) (Interface, error) {
|
func New(opts ...Option) (Interface, error) {
|
||||||
l := &nvcdilib{}
|
l := &nvcdilib{
|
||||||
|
disabledHooks: make(disabledHooks),
|
||||||
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(l)
|
opt(l)
|
||||||
}
|
}
|
||||||
@@ -111,19 +103,24 @@ func New(opts ...Option) (Interface, error) {
|
|||||||
}
|
}
|
||||||
l.nvmllib = nvml.New(nvmlOpts...)
|
l.nvmllib = nvml.New(nvmlOpts...)
|
||||||
}
|
}
|
||||||
if l.nvsandboxutilslib == nil {
|
// TODO: Repeated calls to nvsandboxutils.Init and Shutdown are causing
|
||||||
var nvsandboxutilsOpts []nvsandboxutils.LibraryOption
|
// segmentation violations. Here we disabled nvsandbox utils unless explicitly
|
||||||
// Set the library path for libnvidia-sandboxutils
|
// specified.
|
||||||
candidates, err := l.driver.Libraries().Locate("libnvidia-sandboxutils.so.1")
|
// This will be reenabled as soon as we have more visibility into why this is
|
||||||
if err != nil {
|
// happening and a mechanism to detect and disable this if required.
|
||||||
l.logger.Warningf("Ignoring error in locating libnvidia-sandboxutils.so.1: %v", err)
|
// if l.nvsandboxutilslib == nil {
|
||||||
} else {
|
// var nvsandboxutilsOpts []nvsandboxutils.LibraryOption
|
||||||
libNvidiaSandboxutilsPath := candidates[0]
|
// // Set the library path for libnvidia-sandboxutils
|
||||||
l.logger.Infof("Using %v", libNvidiaSandboxutilsPath)
|
// candidates, err := l.driver.Libraries().Locate("libnvidia-sandboxutils.so.1")
|
||||||
nvsandboxutilsOpts = append(nvsandboxutilsOpts, nvsandboxutils.WithLibraryPath(libNvidiaSandboxutilsPath))
|
// if err != nil {
|
||||||
}
|
// l.logger.Warningf("Ignoring error in locating libnvidia-sandboxutils.so.1: %v", err)
|
||||||
l.nvsandboxutilslib = nvsandboxutils.New(nvsandboxutilsOpts...)
|
// } else {
|
||||||
}
|
// libNvidiaSandboxutilsPath := candidates[0]
|
||||||
|
// l.logger.Infof("Using %v", libNvidiaSandboxutilsPath)
|
||||||
|
// nvsandboxutilsOpts = append(nvsandboxutilsOpts, nvsandboxutils.WithLibraryPath(libNvidiaSandboxutilsPath))
|
||||||
|
// }
|
||||||
|
// l.nvsandboxutilslib = nvsandboxutils.New(nvsandboxutilsOpts...)
|
||||||
|
// }
|
||||||
if l.devicelib == nil {
|
if l.devicelib == nil {
|
||||||
l.devicelib = device.New(l.nvmllib)
|
l.devicelib = device.New(l.nvmllib)
|
||||||
}
|
}
|
||||||
@@ -147,6 +144,8 @@ func New(opts ...Option) (Interface, error) {
|
|||||||
if l.vendor == "" {
|
if l.vendor == "" {
|
||||||
l.vendor = "management.nvidia.com"
|
l.vendor = "management.nvidia.com"
|
||||||
}
|
}
|
||||||
|
// Management containers in general do not require CUDA Forward compatibility.
|
||||||
|
l.disabledHooks[HookEnableCudaCompat] = true
|
||||||
lib = (*managementlib)(l)
|
lib = (*managementlib)(l)
|
||||||
case ModeNvml:
|
case ModeNvml:
|
||||||
lib = (*nvmllib)(l)
|
lib = (*nvmllib)(l)
|
||||||
@@ -180,38 +179,6 @@ func New(opts ...Option) (Interface, error) {
|
|||||||
return &w, nil
|
return &w, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSpec combines the device specs and common edits from the wrapped Interface to a single spec.Interface.
|
|
||||||
func (l *wrapper) GetSpec() (spec.Interface, error) {
|
|
||||||
deviceSpecs, err := l.GetAllDeviceSpecs()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
edits, err := l.GetCommonEdits()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return spec.New(
|
|
||||||
spec.WithDeviceSpecs(deviceSpecs),
|
|
||||||
spec.WithEdits(*edits.ContainerEdits),
|
|
||||||
spec.WithVendor(l.vendor),
|
|
||||||
spec.WithClass(l.class),
|
|
||||||
spec.WithMergedDeviceOptions(l.mergedDeviceOptions...),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCommonEdits returns the wrapped edits and adds additional edits on top.
|
|
||||||
func (m *wrapper) GetCommonEdits() (*cdi.ContainerEdits, error) {
|
|
||||||
edits, err := m.Interface.GetCommonEdits()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
edits.Env = append(edits.Env, image.EnvVarNvidiaVisibleDevices+"=void")
|
|
||||||
|
|
||||||
return edits, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getCudaVersion returns the CUDA version of the current system.
|
// getCudaVersion returns the CUDA version of the current system.
|
||||||
func (l *nvcdilib) getCudaVersion() (string, error) {
|
func (l *nvcdilib) getCudaVersion() (string, error) {
|
||||||
version, err := l.getCudaVersionNvsandboxutils()
|
version, err := l.getCudaVersionNvsandboxutils()
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func (m *managementlib) GetCommonEdits() (*cdi.ContainerEdits, error) {
|
|||||||
return nil, fmt.Errorf("failed to get CUDA version: %v", err)
|
return nil, fmt.Errorf("failed to get CUDA version: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
driver, err := newDriverVersionDiscoverer(m.logger, m.driver, m.nvidiaCDIHookPath, m.ldconfigPath, version)
|
driver, err := (*nvcdilib)(m).newDriverVersionDiscoverer(version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create driver library discoverer: %v", err)
|
return nil, fmt.Errorf("failed to create driver library discoverer: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,8 @@
|
|||||||
package nvcdi
|
package nvcdi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/NVIDIA/go-nvml/pkg/nvml"
|
"github.com/NVIDIA/go-nvml/pkg/nvml"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure, that nvmlUUIDerMock does implement nvmlUUIDer.
|
// Ensure, that nvmlUUIDerMock does implement nvmlUUIDer.
|
||||||
|
|||||||
@@ -155,3 +155,14 @@ func WithLibrarySearchPaths(paths []string) Option {
|
|||||||
o.librarySearchPaths = paths
|
o.librarySearchPaths = paths
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithDisabledHook allows specific hooks to the disabled.
|
||||||
|
// This option can be specified multiple times for each hook.
|
||||||
|
func WithDisabledHook(hook HookName) Option {
|
||||||
|
return func(o *nvcdilib) {
|
||||||
|
if o.disabledHooks == nil {
|
||||||
|
o.disabledHooks = make(map[HookName]bool)
|
||||||
|
}
|
||||||
|
o.disabledHooks[hook] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"tags.cncf.io/container-device-interface/pkg/cdi"
|
|
||||||
"tags.cncf.io/container-device-interface/pkg/parser"
|
"tags.cncf.io/container-device-interface/pkg/parser"
|
||||||
"tags.cncf.io/container-device-interface/specs-go"
|
"tags.cncf.io/container-device-interface/specs-go"
|
||||||
|
cdi "tags.cncf.io/container-device-interface/specs-go"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform"
|
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,6 +28,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestSpec(t *testing.T) {
|
func TestSpec(t *testing.T) {
|
||||||
|
minimalSpec := &specs.Spec{
|
||||||
|
Kind: "nvidia.com/gpu",
|
||||||
|
Devices: []specs.Device{
|
||||||
|
{
|
||||||
|
Name: "one",
|
||||||
|
ContainerEdits: specs.ContainerEdits{
|
||||||
|
Env: []string{"DEVICE_FOO=bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
description string
|
description string
|
||||||
options []Option
|
options []Option
|
||||||
@@ -35,23 +47,17 @@ func TestSpec(t *testing.T) {
|
|||||||
transform transform.Transformer
|
transform transform.Transformer
|
||||||
expectedSpec string
|
expectedSpec string
|
||||||
}{
|
}{
|
||||||
{
|
|
||||||
description: "default options return empty spec",
|
|
||||||
expectedSpec: `---
|
|
||||||
cdiVersion: 0.3.0
|
|
||||||
containerEdits: {}
|
|
||||||
devices: null
|
|
||||||
kind: nvidia.com/gpu
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "version is overridden",
|
description: "version is overridden",
|
||||||
options: []Option{WithVersion("0.5.0")},
|
options: []Option{WithVersion("0.8.0"), WithRawSpec(minimalSpec)},
|
||||||
expectedSpec: `---
|
expectedSpec: `---
|
||||||
cdiVersion: 0.5.0
|
cdiVersion: 0.8.0
|
||||||
containerEdits: {}
|
|
||||||
devices: null
|
|
||||||
kind: nvidia.com/gpu
|
kind: nvidia.com/gpu
|
||||||
|
devices:
|
||||||
|
- name: one
|
||||||
|
containerEdits:
|
||||||
|
env:
|
||||||
|
- DEVICE_FOO=bar
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -60,18 +66,24 @@ kind: nvidia.com/gpu
|
|||||||
&specs.Spec{
|
&specs.Spec{
|
||||||
Version: "0.5.0",
|
Version: "0.5.0",
|
||||||
Kind: "nvidia.com/gpu",
|
Kind: "nvidia.com/gpu",
|
||||||
ContainerEdits: specs.ContainerEdits{
|
Devices: []specs.Device{
|
||||||
Env: []string{"FOO=bar"},
|
{
|
||||||
|
Name: "one",
|
||||||
|
ContainerEdits: specs.ContainerEdits{
|
||||||
|
Env: []string{"DEVICE_FOO=bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)},
|
)},
|
||||||
expectedSpec: `---
|
expectedSpec: `---
|
||||||
cdiVersion: 0.5.0
|
cdiVersion: 0.5.0
|
||||||
containerEdits:
|
|
||||||
env:
|
|
||||||
- FOO=bar
|
|
||||||
devices: null
|
|
||||||
kind: nvidia.com/gpu
|
kind: nvidia.com/gpu
|
||||||
|
devices:
|
||||||
|
- name: one
|
||||||
|
containerEdits:
|
||||||
|
env:
|
||||||
|
- DEVICE_FOO=bar
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -79,18 +91,24 @@ kind: nvidia.com/gpu
|
|||||||
options: []Option{WithRawSpec(
|
options: []Option{WithRawSpec(
|
||||||
&specs.Spec{
|
&specs.Spec{
|
||||||
Kind: "nvidia.com/gpu",
|
Kind: "nvidia.com/gpu",
|
||||||
ContainerEdits: specs.ContainerEdits{
|
Devices: []specs.Device{
|
||||||
Env: []string{"FOO=bar"},
|
{
|
||||||
|
Name: "one",
|
||||||
|
ContainerEdits: specs.ContainerEdits{
|
||||||
|
Env: []string{"DEVICE_FOO=bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)},
|
)},
|
||||||
expectedSpec: `---
|
expectedSpec: `---
|
||||||
cdiVersion: 0.3.0
|
cdiVersion: 0.3.0
|
||||||
containerEdits:
|
|
||||||
env:
|
|
||||||
- FOO=bar
|
|
||||||
devices: null
|
|
||||||
kind: nvidia.com/gpu
|
kind: nvidia.com/gpu
|
||||||
|
devices:
|
||||||
|
- name: one
|
||||||
|
containerEdits:
|
||||||
|
env:
|
||||||
|
- DEVICE_FOO=bar
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -98,8 +116,15 @@ kind: nvidia.com/gpu
|
|||||||
options: []Option{WithRawSpec(
|
options: []Option{WithRawSpec(
|
||||||
&specs.Spec{
|
&specs.Spec{
|
||||||
Kind: "nvidia.com/gpu",
|
Kind: "nvidia.com/gpu",
|
||||||
|
Devices: []specs.Device{
|
||||||
|
{
|
||||||
|
Name: "one",
|
||||||
|
ContainerEdits: specs.ContainerEdits{
|
||||||
|
Env: []string{"DEVICE_FOO=bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
ContainerEdits: specs.ContainerEdits{
|
ContainerEdits: specs.ContainerEdits{
|
||||||
Env: []string{"FOO=bar"},
|
|
||||||
DeviceNodes: []*specs.DeviceNode{
|
DeviceNodes: []*specs.DeviceNode{
|
||||||
{
|
{
|
||||||
HostPath: "/some/dev/dev0",
|
HostPath: "/some/dev/dev0",
|
||||||
@@ -111,14 +136,16 @@ kind: nvidia.com/gpu
|
|||||||
)},
|
)},
|
||||||
expectedSpec: `---
|
expectedSpec: `---
|
||||||
cdiVersion: 0.5.0
|
cdiVersion: 0.5.0
|
||||||
|
kind: nvidia.com/gpu
|
||||||
|
devices:
|
||||||
|
- name: one
|
||||||
|
containerEdits:
|
||||||
|
env:
|
||||||
|
- DEVICE_FOO=bar
|
||||||
containerEdits:
|
containerEdits:
|
||||||
deviceNodes:
|
deviceNodes:
|
||||||
- hostPath: /some/dev/dev0
|
- path: /dev/dev0
|
||||||
path: /dev/dev0
|
hostPath: /some/dev/dev0
|
||||||
env:
|
|
||||||
- FOO=bar
|
|
||||||
devices: null
|
|
||||||
kind: nvidia.com/gpu
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -126,8 +153,15 @@ kind: nvidia.com/gpu
|
|||||||
options: []Option{WithRawSpec(
|
options: []Option{WithRawSpec(
|
||||||
&specs.Spec{
|
&specs.Spec{
|
||||||
Kind: "nvidia.com/gpu",
|
Kind: "nvidia.com/gpu",
|
||||||
|
Devices: []specs.Device{
|
||||||
|
{
|
||||||
|
Name: "one",
|
||||||
|
ContainerEdits: specs.ContainerEdits{
|
||||||
|
Env: []string{"DEVICE_FOO=bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
ContainerEdits: specs.ContainerEdits{
|
ContainerEdits: specs.ContainerEdits{
|
||||||
Env: []string{"FOO=bar"},
|
|
||||||
DeviceNodes: []*specs.DeviceNode{
|
DeviceNodes: []*specs.DeviceNode{
|
||||||
{
|
{
|
||||||
HostPath: "/some/dev/dev0",
|
HostPath: "/some/dev/dev0",
|
||||||
@@ -147,14 +181,16 @@ kind: nvidia.com/gpu
|
|||||||
),
|
),
|
||||||
expectedSpec: `---
|
expectedSpec: `---
|
||||||
cdiVersion: 0.5.0
|
cdiVersion: 0.5.0
|
||||||
|
kind: nvidia.com/gpu
|
||||||
|
devices:
|
||||||
|
- name: one
|
||||||
|
containerEdits:
|
||||||
|
env:
|
||||||
|
- DEVICE_FOO=bar
|
||||||
containerEdits:
|
containerEdits:
|
||||||
deviceNodes:
|
deviceNodes:
|
||||||
- hostPath: /dev/dev0
|
- path: /dev/dev0
|
||||||
path: /dev/dev0
|
hostPath: /dev/dev0
|
||||||
env:
|
|
||||||
- FOO=bar
|
|
||||||
devices: null
|
|
||||||
kind: nvidia.com/gpu
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
72
pkg/nvcdi/wrapper.go
Normal file
72
pkg/nvcdi/wrapper.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
# Copyright 2025 NVIDIA CORPORATION
|
||||||
|
#
|
||||||
|
# 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 nvcdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"tags.cncf.io/container-device-interface/pkg/cdi"
|
||||||
|
"tags.cncf.io/container-device-interface/specs-go"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec"
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform"
|
||||||
|
)
|
||||||
|
|
||||||
|
type wrapper struct {
|
||||||
|
Interface
|
||||||
|
|
||||||
|
vendor string
|
||||||
|
class string
|
||||||
|
|
||||||
|
mergedDeviceOptions []transform.MergedDeviceOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpec combines the device specs and common edits from the wrapped Interface to a single spec.Interface.
|
||||||
|
func (l *wrapper) GetSpec() (spec.Interface, error) {
|
||||||
|
deviceSpecs, err := l.GetAllDeviceSpecs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
edits, err := l.GetCommonEdits()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec.New(
|
||||||
|
spec.WithDeviceSpecs(deviceSpecs),
|
||||||
|
spec.WithEdits(*edits.ContainerEdits),
|
||||||
|
spec.WithVendor(l.vendor),
|
||||||
|
spec.WithClass(l.class),
|
||||||
|
spec.WithMergedDeviceOptions(l.mergedDeviceOptions...),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllDeviceSpecs returns the device specs for all available devices.
|
||||||
|
func (l *wrapper) GetAllDeviceSpecs() ([]specs.Device, error) {
|
||||||
|
return l.Interface.GetAllDeviceSpecs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommonEdits returns the wrapped edits and adds additional edits on top.
|
||||||
|
func (m *wrapper) GetCommonEdits() (*cdi.ContainerEdits, error) {
|
||||||
|
edits, err := m.Interface.GetCommonEdits()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
edits.Env = append(edits.Env, image.EnvVarNvidiaVisibleDevices+"=void")
|
||||||
|
|
||||||
|
return edits, nil
|
||||||
|
}
|
||||||
@@ -18,13 +18,15 @@ package e2e
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Integration tests for Docker runtime
|
// Integration tests for Docker runtime
|
||||||
var _ = Describe("docker", Ordered, func() {
|
var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
|
||||||
var r Runner
|
var r Runner
|
||||||
|
|
||||||
// Install the NVIDIA Container Toolkit
|
// Install the NVIDIA Container Toolkit
|
||||||
@@ -166,4 +168,51 @@ var _ = Describe("docker", Ordered, func() {
|
|||||||
Expect(referenceOutput).To(Equal(out4))
|
Expect(referenceOutput).To(Equal(out4))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Describe("CUDA Forward compatibility", Ordered, func() {
|
||||||
|
BeforeAll(func(ctx context.Context) {
|
||||||
|
_, _, err := r.Run("docker pull nvcr.io/nvidia/cuda:12.8.0-base-ubi8")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
BeforeAll(func(ctx context.Context) {
|
||||||
|
compatOutput, _, err := r.Run("docker run --rm -i -e NVIDIA_VISIBLE_DEVICES=void nvcr.io/nvidia/cuda:12.8.0-base-ubi8 bash -c \"ls /usr/local/cuda/compat/libcuda.*.*\"")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(compatOutput).ToNot(BeEmpty())
|
||||||
|
compatDriverVersion := strings.TrimPrefix(filepath.Base(compatOutput), "libcuda.so.")
|
||||||
|
compatMajor := strings.SplitN(compatDriverVersion, ".", 2)[0]
|
||||||
|
|
||||||
|
driverOutput, _, err := r.Run("nvidia-smi -q | grep \"Driver Version\"")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
parts := strings.SplitN(driverOutput, ":", 2)
|
||||||
|
Expect(parts).To(HaveLen(2))
|
||||||
|
|
||||||
|
hostDriverVersion := strings.TrimSpace(parts[1])
|
||||||
|
Expect(hostDriverVersion).ToNot(BeEmpty())
|
||||||
|
driverMajor := strings.SplitN(hostDriverVersion, ".", 2)[0]
|
||||||
|
|
||||||
|
if driverMajor >= compatMajor {
|
||||||
|
GinkgoLogr.Info("CUDA Forward Compatibility tests require an older driver version", "hostDriverVersion", hostDriverVersion, "compatDriverVersion", compatDriverVersion)
|
||||||
|
Skip("CUDA Forward Compatibility tests require an older driver version")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should work with the nvidia runtime in legacy mode", func(ctx context.Context) {
|
||||||
|
ldconfigOut, _, err := r.Run("docker run --rm -i -e NVIDIA_DISABLE_REQUIRE=true --runtime=nvidia --gpus all nvcr.io/nvidia/cuda:12.8.0-base-ubi8 bash -c \"ldconfig -p | grep libcuda.so.1\"")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(ldconfigOut).To(ContainSubstring("/usr/local/cuda/compat"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should work with the nvidia runtime in CDI mode", func(ctx context.Context) {
|
||||||
|
ldconfigOut, _, err := r.Run("docker run --rm -i -e NVIDIA_DISABLE_REQUIRE=true --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=runtime.nvidia.com/gpu=all nvcr.io/nvidia/cuda:12.8.0-base-ubi8 bash -c \"ldconfig -p | grep libcuda.so.1\"")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(ldconfigOut).To(ContainSubstring("/usr/local/cuda/compat"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should NOT work with nvidia-container-runtime-hook", func(ctx context.Context) {
|
||||||
|
ldconfigOut, _, err := r.Run("docker run --rm -i -e NVIDIA_DISABLE_REQUIRE=true --runtime=runc --gpus all nvcr.io/nvidia/cuda:12.8.0-base-ubi8 bash -c \"ldconfig -p | grep libcuda.so.1\"")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(ldconfigOut).To(ContainSubstring("/usr/lib64"))
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
12
tests/go.mod
12
tests/go.mod
@@ -3,9 +3,9 @@ module github.com/NVIDIA/nvidia-container-toolkit/tests
|
|||||||
go 1.23.2
|
go 1.23.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/onsi/ginkgo/v2 v2.22.2
|
github.com/onsi/ginkgo/v2 v2.23.0
|
||||||
github.com/onsi/gomega v1.36.2
|
github.com/onsi/gomega v1.36.2
|
||||||
golang.org/x/crypto v0.33.0
|
golang.org/x/crypto v0.36.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -13,9 +13,9 @@ require (
|
|||||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||||
golang.org/x/net v0.33.0 // indirect
|
golang.org/x/net v0.35.0 // indirect
|
||||||
golang.org/x/sys v0.30.0 // indirect
|
golang.org/x/sys v0.31.0 // indirect
|
||||||
golang.org/x/text v0.22.0 // indirect
|
golang.org/x/text v0.23.0 // indirect
|
||||||
golang.org/x/tools v0.28.0 // indirect
|
golang.org/x/tools v0.30.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
28
tests/go.sum
28
tests/go.sum
@@ -8,26 +8,26 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
|||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||||
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
github.com/onsi/ginkgo/v2 v2.23.0 h1:FA1xjp8ieYDzlgS5ABTpdUDB7wtngggONc8a7ku2NqQ=
|
||||||
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
github.com/onsi/ginkgo/v2 v2.23.0/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
|
||||||
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||||
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||||
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
|
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
|
||||||
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
|
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
|
||||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
|||||||
25
tests/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
generated
vendored
25
tests/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
generated
vendored
@@ -1,3 +1,26 @@
|
|||||||
|
## 2.23.0
|
||||||
|
|
||||||
|
Ginkgo 2.23.0 adds a handful of methods to `GinkgoT()` to make it compatible with the `testing.TB` interface in Go 1.24. `GinkgoT().Context()`, in particular, is a useful shorthand for generating a new context that will clean itself up in a `DeferCleanup()`. This has subtle behavior differences from the golang implementation but should make sense in a Ginkgo... um... context.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- bump to go 1.24.0 - support new testing.TB methods and add a test to cover testing.TB regressions [37a511b]
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- fix edge case where build -o is pointing at an explicit file, not a directory [7556a86]
|
||||||
|
- Fix binary paths when precompiling multiple suites. [4df06c6]
|
||||||
|
|
||||||
|
### Maintenance
|
||||||
|
- Fix: Correct Markdown list rendering in MIGRATING_TO_V2.md [cbcf39a]
|
||||||
|
- docs: fix test workflow badge (#1512) [9b261ff]
|
||||||
|
- Bump golang.org/x/net in /integration/_fixtures/version_mismatch_fixture (#1516) [00f19c8]
|
||||||
|
- Bump golang.org/x/tools from 0.28.0 to 0.30.0 (#1515) [e98a4df]
|
||||||
|
- Bump activesupport from 6.0.6.1 to 6.1.7.5 in /docs (#1504) [60cc4e2]
|
||||||
|
- Bump github-pages from 231 to 232 in /docs (#1447) [fea6f2d]
|
||||||
|
- Bump rexml from 3.2.8 to 3.3.9 in /docs (#1497) [31d7813]
|
||||||
|
- Bump webrick from 1.8.1 to 1.9.1 in /docs (#1501) [fc3bbd6]
|
||||||
|
- Code linting (#1500) [aee0d56]
|
||||||
|
- change interface{} to any (#1502) [809a710]
|
||||||
|
|
||||||
## 2.22.2
|
## 2.22.2
|
||||||
|
|
||||||
### Maintenance
|
### Maintenance
|
||||||
@@ -630,7 +653,7 @@ Ginkgo also uses this progress reporting infrastructure under the hood when hand
|
|||||||
### Features
|
### Features
|
||||||
- `BeforeSuite`, `AfterSuite`, `SynchronizedBeforeSuite`, `SynchronizedAfterSuite`, and `ReportAfterSuite` now support (the relevant subset of) decorators. These can be passed in _after_ the callback functions that are usually passed into these nodes.
|
- `BeforeSuite`, `AfterSuite`, `SynchronizedBeforeSuite`, `SynchronizedAfterSuite`, and `ReportAfterSuite` now support (the relevant subset of) decorators. These can be passed in _after_ the callback functions that are usually passed into these nodes.
|
||||||
|
|
||||||
As a result the **signature of these methods has changed** and now includes a trailing `args ...interface{}`. For most users simply using the DSL, this change is transparent. However if you were assigning one of these functions to a custom variable (or passing it around) then your code may need to change to reflect the new signature.
|
As a result the **signature of these methods has changed** and now includes a trailing `args ...any`. For most users simply using the DSL, this change is transparent. However if you were assigning one of these functions to a custom variable (or passing it around) then your code may need to change to reflect the new signature.
|
||||||
|
|
||||||
### Maintenance
|
### Maintenance
|
||||||
- Modernize the invocation of Ginkgo in github actions [0ffde58]
|
- Modernize the invocation of Ginkgo in github actions [0ffde58]
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/README.md
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/README.md
generated
vendored
@@ -1,6 +1,6 @@
|
|||||||

|

|
||||||
|
|
||||||
[](https://github.com/onsi/ginkgo/actions?query=workflow%3Atest+branch%3Amaster) | [Ginkgo Docs](https://onsi.github.io/ginkgo/)
|
[](https://github.com/onsi/ginkgo/actions?query=workflow%3Atest+branch%3Amaster) | [Ginkgo Docs](https://onsi.github.io/ginkgo/)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
58
tests/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
generated
vendored
58
tests/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
generated
vendored
@@ -83,9 +83,9 @@ func exitIfErrors(errors []error) {
|
|||||||
type GinkgoWriterInterface interface {
|
type GinkgoWriterInterface interface {
|
||||||
io.Writer
|
io.Writer
|
||||||
|
|
||||||
Print(a ...interface{})
|
Print(a ...any)
|
||||||
Printf(format string, a ...interface{})
|
Printf(format string, a ...any)
|
||||||
Println(a ...interface{})
|
Println(a ...any)
|
||||||
|
|
||||||
TeeTo(writer io.Writer)
|
TeeTo(writer io.Writer)
|
||||||
ClearTeeWriters()
|
ClearTeeWriters()
|
||||||
@@ -243,7 +243,7 @@ for more on how specs are parallelized in Ginkgo.
|
|||||||
|
|
||||||
You can also pass suite-level Label() decorators to RunSpecs. The passed-in labels will apply to all specs in the suite.
|
You can also pass suite-level Label() decorators to RunSpecs. The passed-in labels will apply to all specs in the suite.
|
||||||
*/
|
*/
|
||||||
func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool {
|
func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
|
||||||
if suiteDidRun {
|
if suiteDidRun {
|
||||||
exitIfErr(types.GinkgoErrors.RerunningSuite())
|
exitIfErr(types.GinkgoErrors.RerunningSuite())
|
||||||
}
|
}
|
||||||
@@ -316,7 +316,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool {
|
|||||||
return passed
|
return passed
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractSuiteConfiguration(args []interface{}) Labels {
|
func extractSuiteConfiguration(args []any) Labels {
|
||||||
suiteLabels := Labels{}
|
suiteLabels := Labels{}
|
||||||
configErrors := []error{}
|
configErrors := []error{}
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
@@ -491,14 +491,14 @@ to Describe the behavior of an object or function and, within that Describe, out
|
|||||||
You can learn more at https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes
|
You can learn more at https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes
|
||||||
In addition, container nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
|
In addition, container nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
|
||||||
*/
|
*/
|
||||||
func Describe(text string, args ...interface{}) bool {
|
func Describe(text string, args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FDescribe focuses specs within the Describe block.
|
FDescribe focuses specs within the Describe block.
|
||||||
*/
|
*/
|
||||||
func FDescribe(text string, args ...interface{}) bool {
|
func FDescribe(text string, args ...any) bool {
|
||||||
args = append(args, internal.Focus)
|
args = append(args, internal.Focus)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
|
||||||
}
|
}
|
||||||
@@ -506,7 +506,7 @@ func FDescribe(text string, args ...interface{}) bool {
|
|||||||
/*
|
/*
|
||||||
PDescribe marks specs within the Describe block as pending.
|
PDescribe marks specs within the Describe block as pending.
|
||||||
*/
|
*/
|
||||||
func PDescribe(text string, args ...interface{}) bool {
|
func PDescribe(text string, args ...any) bool {
|
||||||
args = append(args, internal.Pending)
|
args = append(args, internal.Pending)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
|
||||||
}
|
}
|
||||||
@@ -522,18 +522,18 @@ var XDescribe = PDescribe
|
|||||||
var Context, FContext, PContext, XContext = Describe, FDescribe, PDescribe, XDescribe
|
var Context, FContext, PContext, XContext = Describe, FDescribe, PDescribe, XDescribe
|
||||||
|
|
||||||
/* When is an alias for Describe - it generates the exact same kind of Container node */
|
/* When is an alias for Describe - it generates the exact same kind of Container node */
|
||||||
func When(text string, args ...interface{}) bool {
|
func When(text string, args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When is an alias for Describe - it generates the exact same kind of Container node */
|
/* When is an alias for Describe - it generates the exact same kind of Container node */
|
||||||
func FWhen(text string, args ...interface{}) bool {
|
func FWhen(text string, args ...any) bool {
|
||||||
args = append(args, internal.Focus)
|
args = append(args, internal.Focus)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When is an alias for Describe - it generates the exact same kind of Container node */
|
/* When is an alias for Describe - it generates the exact same kind of Container node */
|
||||||
func PWhen(text string, args ...interface{}) bool {
|
func PWhen(text string, args ...any) bool {
|
||||||
args = append(args, internal.Pending)
|
args = append(args, internal.Pending)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
|
||||||
}
|
}
|
||||||
@@ -550,14 +550,14 @@ You can pass It nodes bare functions (func() {}) or functions that receive a Spe
|
|||||||
You can learn more at https://onsi.github.io/ginkgo/#spec-subjects-it
|
You can learn more at https://onsi.github.io/ginkgo/#spec-subjects-it
|
||||||
In addition, subject nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
|
In addition, subject nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
|
||||||
*/
|
*/
|
||||||
func It(text string, args ...interface{}) bool {
|
func It(text string, args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FIt allows you to focus an individual It.
|
FIt allows you to focus an individual It.
|
||||||
*/
|
*/
|
||||||
func FIt(text string, args ...interface{}) bool {
|
func FIt(text string, args ...any) bool {
|
||||||
args = append(args, internal.Focus)
|
args = append(args, internal.Focus)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
|
||||||
}
|
}
|
||||||
@@ -565,7 +565,7 @@ func FIt(text string, args ...interface{}) bool {
|
|||||||
/*
|
/*
|
||||||
PIt allows you to mark an individual It as pending.
|
PIt allows you to mark an individual It as pending.
|
||||||
*/
|
*/
|
||||||
func PIt(text string, args ...interface{}) bool {
|
func PIt(text string, args ...any) bool {
|
||||||
args = append(args, internal.Pending)
|
args = append(args, internal.Pending)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
|
||||||
}
|
}
|
||||||
@@ -611,8 +611,8 @@ BeforeSuite can take a func() body, or an interruptible func(SpecContext)/func(c
|
|||||||
You cannot nest any other Ginkgo nodes within a BeforeSuite node's closure.
|
You cannot nest any other Ginkgo nodes within a BeforeSuite node's closure.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
|
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
|
||||||
*/
|
*/
|
||||||
func BeforeSuite(body interface{}, args ...interface{}) bool {
|
func BeforeSuite(body any, args ...any) bool {
|
||||||
combinedArgs := []interface{}{body}
|
combinedArgs := []any{body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...))
|
||||||
}
|
}
|
||||||
@@ -630,8 +630,8 @@ AfterSuite can take a func() body, or an interruptible func(SpecContext)/func(co
|
|||||||
You cannot nest any other Ginkgo nodes within an AfterSuite node's closure.
|
You cannot nest any other Ginkgo nodes within an AfterSuite node's closure.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
|
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
|
||||||
*/
|
*/
|
||||||
func AfterSuite(body interface{}, args ...interface{}) bool {
|
func AfterSuite(body any, args ...any) bool {
|
||||||
combinedArgs := []interface{}{body}
|
combinedArgs := []any{body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...))
|
||||||
}
|
}
|
||||||
@@ -667,8 +667,8 @@ If either function receives a context.Context/SpecContext it is considered inter
|
|||||||
You cannot nest any other Ginkgo nodes within an SynchronizedBeforeSuite node's closure.
|
You cannot nest any other Ginkgo nodes within an SynchronizedBeforeSuite node's closure.
|
||||||
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
|
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
|
||||||
*/
|
*/
|
||||||
func SynchronizedBeforeSuite(process1Body interface{}, allProcessBody interface{}, args ...interface{}) bool {
|
func SynchronizedBeforeSuite(process1Body any, allProcessBody any, args ...any) bool {
|
||||||
combinedArgs := []interface{}{process1Body, allProcessBody}
|
combinedArgs := []any{process1Body, allProcessBody}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
|
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedBeforeSuite, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedBeforeSuite, "", combinedArgs...))
|
||||||
@@ -687,8 +687,8 @@ Note that you can also use DeferCleanup() in SynchronizedBeforeSuite to accompli
|
|||||||
You cannot nest any other Ginkgo nodes within an SynchronizedAfterSuite node's closure.
|
You cannot nest any other Ginkgo nodes within an SynchronizedAfterSuite node's closure.
|
||||||
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
|
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
|
||||||
*/
|
*/
|
||||||
func SynchronizedAfterSuite(allProcessBody interface{}, process1Body interface{}, args ...interface{}) bool {
|
func SynchronizedAfterSuite(allProcessBody any, process1Body any, args ...any) bool {
|
||||||
combinedArgs := []interface{}{allProcessBody, process1Body}
|
combinedArgs := []any{allProcessBody, process1Body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
|
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedAfterSuite, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedAfterSuite, "", combinedArgs...))
|
||||||
@@ -703,7 +703,7 @@ BeforeEach can take a func() body, or an interruptible func(SpecContext)/func(co
|
|||||||
You cannot nest any other Ginkgo nodes within a BeforeEach node's closure.
|
You cannot nest any other Ginkgo nodes within a BeforeEach node's closure.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach
|
You can learn more here: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach
|
||||||
*/
|
*/
|
||||||
func BeforeEach(args ...interface{}) bool {
|
func BeforeEach(args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeEach, "", args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeEach, "", args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,7 +716,7 @@ JustBeforeEach can take a func() body, or an interruptible func(SpecContext)/fun
|
|||||||
You cannot nest any other Ginkgo nodes within a JustBeforeEach node's closure.
|
You cannot nest any other Ginkgo nodes within a JustBeforeEach node's closure.
|
||||||
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach
|
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach
|
||||||
*/
|
*/
|
||||||
func JustBeforeEach(args ...interface{}) bool {
|
func JustBeforeEach(args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustBeforeEach, "", args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustBeforeEach, "", args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,7 +731,7 @@ AfterEach can take a func() body, or an interruptible func(SpecContext)/func(con
|
|||||||
You cannot nest any other Ginkgo nodes within an AfterEach node's closure.
|
You cannot nest any other Ginkgo nodes within an AfterEach node's closure.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#spec-cleanup-aftereach-and-defercleanup
|
You can learn more here: https://onsi.github.io/ginkgo/#spec-cleanup-aftereach-and-defercleanup
|
||||||
*/
|
*/
|
||||||
func AfterEach(args ...interface{}) bool {
|
func AfterEach(args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterEach, "", args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterEach, "", args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,7 +743,7 @@ JustAfterEach can take a func() body, or an interruptible func(SpecContext)/func
|
|||||||
You cannot nest any other Ginkgo nodes within a JustAfterEach node's closure.
|
You cannot nest any other Ginkgo nodes within a JustAfterEach node's closure.
|
||||||
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-diagnostics-collection-and-teardown-justaftereach
|
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-diagnostics-collection-and-teardown-justaftereach
|
||||||
*/
|
*/
|
||||||
func JustAfterEach(args ...interface{}) bool {
|
func JustAfterEach(args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustAfterEach, "", args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustAfterEach, "", args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,7 +758,7 @@ You cannot nest any other Ginkgo nodes within a BeforeAll node's closure.
|
|||||||
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
|
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
|
||||||
And you can learn more about BeforeAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
|
And you can learn more about BeforeAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
|
||||||
*/
|
*/
|
||||||
func BeforeAll(args ...interface{}) bool {
|
func BeforeAll(args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeAll, "", args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeAll, "", args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,7 +775,7 @@ You cannot nest any other Ginkgo nodes within an AfterAll node's closure.
|
|||||||
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
|
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
|
||||||
And you can learn more about AfterAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
|
And you can learn more about AfterAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
|
||||||
*/
|
*/
|
||||||
func AfterAll(args ...interface{}) bool {
|
func AfterAll(args ...any) bool {
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterAll, "", args...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterAll, "", args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,7 +818,7 @@ When DeferCleanup is called in BeforeSuite, SynchronizedBeforeSuite, AfterSuite,
|
|||||||
Note that DeferCleanup does not represent a node but rather dynamically generates the appropriate type of cleanup node based on the context in which it is called. As such you must call DeferCleanup within a Setup or Subject node, and not within a Container node.
|
Note that DeferCleanup does not represent a node but rather dynamically generates the appropriate type of cleanup node based on the context in which it is called. As such you must call DeferCleanup within a Setup or Subject node, and not within a Container node.
|
||||||
You can learn more about DeferCleanup here: https://onsi.github.io/ginkgo/#cleaning-up-our-cleanup-code-defercleanup
|
You can learn more about DeferCleanup here: https://onsi.github.io/ginkgo/#cleaning-up-our-cleanup-code-defercleanup
|
||||||
*/
|
*/
|
||||||
func DeferCleanup(args ...interface{}) {
|
func DeferCleanup(args ...any) {
|
||||||
fail := func(message string, cl types.CodeLocation) {
|
fail := func(message string, cl types.CodeLocation) {
|
||||||
global.Failer.Fail(message, cl)
|
global.Failer.Fail(message, cl)
|
||||||
}
|
}
|
||||||
|
|||||||
8
tests/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go
generated
vendored
8
tests/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go
generated
vendored
@@ -118,9 +118,9 @@ Use Gomega's gmeasure package instead.
|
|||||||
You can learn more here: https://onsi.github.io/ginkgo/#benchmarking-code
|
You can learn more here: https://onsi.github.io/ginkgo/#benchmarking-code
|
||||||
*/
|
*/
|
||||||
type Benchmarker interface {
|
type Benchmarker interface {
|
||||||
Time(name string, body func(), info ...interface{}) (elapsedTime time.Duration)
|
Time(name string, body func(), info ...any) (elapsedTime time.Duration)
|
||||||
RecordValue(name string, value float64, info ...interface{})
|
RecordValue(name string, value float64, info ...any)
|
||||||
RecordValueWithPrecision(name string, value float64, units string, precision int, info ...interface{})
|
RecordValueWithPrecision(name string, value float64, units string, precision int, info ...any)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -129,7 +129,7 @@ Deprecated: Measure() has been removed from Ginkgo 2.0
|
|||||||
Use Gomega's gmeasure package instead.
|
Use Gomega's gmeasure package instead.
|
||||||
You can learn more here: https://onsi.github.io/ginkgo/#benchmarking-code
|
You can learn more here: https://onsi.github.io/ginkgo/#benchmarking-code
|
||||||
*/
|
*/
|
||||||
func Measure(_ ...interface{}) bool {
|
func Measure(_ ...any) bool {
|
||||||
deprecationTracker.TrackDeprecation(types.Deprecations.Measure(), types.NewCodeLocation(1))
|
deprecationTracker.TrackDeprecation(types.Deprecations.Measure(), types.NewCodeLocation(1))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
12
tests/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
generated
vendored
12
tests/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
generated
vendored
@@ -24,15 +24,15 @@ const (
|
|||||||
|
|
||||||
var SingletonFormatter = New(ColorModeTerminal)
|
var SingletonFormatter = New(ColorModeTerminal)
|
||||||
|
|
||||||
func F(format string, args ...interface{}) string {
|
func F(format string, args ...any) string {
|
||||||
return SingletonFormatter.F(format, args...)
|
return SingletonFormatter.F(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fi(indentation uint, format string, args ...interface{}) string {
|
func Fi(indentation uint, format string, args ...any) string {
|
||||||
return SingletonFormatter.Fi(indentation, format, args...)
|
return SingletonFormatter.Fi(indentation, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
|
func Fiw(indentation uint, maxWidth uint, format string, args ...any) string {
|
||||||
return SingletonFormatter.Fiw(indentation, maxWidth, format, args...)
|
return SingletonFormatter.Fiw(indentation, maxWidth, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,15 +115,15 @@ func New(colorMode ColorMode) Formatter {
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Formatter) F(format string, args ...interface{}) string {
|
func (f Formatter) F(format string, args ...any) string {
|
||||||
return f.Fi(0, format, args...)
|
return f.Fi(0, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Formatter) Fi(indentation uint, format string, args ...interface{}) string {
|
func (f Formatter) Fi(indentation uint, format string, args ...any) string {
|
||||||
return f.Fiw(indentation, 0, format, args...)
|
return f.Fiw(indentation, 0, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
|
func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...any) string {
|
||||||
out := f.style(format)
|
out := f.style(format)
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
out = fmt.Sprintf(out, args...)
|
out = fmt.Sprintf(out, args...)
|
||||||
|
|||||||
14
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go
generated
vendored
14
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go
generated
vendored
@@ -55,18 +55,22 @@ func buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.Go
|
|||||||
if suite.State.Is(internal.TestSuiteStateFailedToCompile) {
|
if suite.State.Is(internal.TestSuiteStateFailedToCompile) {
|
||||||
fmt.Println(suite.CompilationError.Error())
|
fmt.Println(suite.CompilationError.Error())
|
||||||
} else {
|
} else {
|
||||||
if len(goFlagsConfig.O) == 0 {
|
var testBinPath string
|
||||||
goFlagsConfig.O = path.Join(suite.Path, suite.PackageName+".test")
|
if len(goFlagsConfig.O) != 0 {
|
||||||
} else {
|
|
||||||
stat, err := os.Stat(goFlagsConfig.O)
|
stat, err := os.Stat(goFlagsConfig.O)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if stat.IsDir() {
|
if stat.IsDir() {
|
||||||
goFlagsConfig.O += "/" + suite.PackageName + ".test"
|
testBinPath = goFlagsConfig.O + "/" + suite.PackageName + ".test"
|
||||||
|
} else {
|
||||||
|
testBinPath = goFlagsConfig.O
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("Compiled %s\n", goFlagsConfig.O)
|
if len(testBinPath) == 0 {
|
||||||
|
testBinPath = path.Join(suite.Path, suite.PackageName+".test")
|
||||||
|
}
|
||||||
|
fmt.Printf("Compiled %s\n", testBinPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go
generated
vendored
6
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go
generated
vendored
@@ -12,7 +12,7 @@ func Abort(details AbortDetails) {
|
|||||||
panic(details)
|
panic(details)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AbortGracefullyWith(format string, args ...interface{}) {
|
func AbortGracefullyWith(format string, args ...any) {
|
||||||
Abort(AbortDetails{
|
Abort(AbortDetails{
|
||||||
ExitCode: 0,
|
ExitCode: 0,
|
||||||
Error: fmt.Errorf(format, args...),
|
Error: fmt.Errorf(format, args...),
|
||||||
@@ -20,7 +20,7 @@ func AbortGracefullyWith(format string, args ...interface{}) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func AbortWith(format string, args ...interface{}) {
|
func AbortWith(format string, args ...any) {
|
||||||
Abort(AbortDetails{
|
Abort(AbortDetails{
|
||||||
ExitCode: 1,
|
ExitCode: 1,
|
||||||
Error: fmt.Errorf(format, args...),
|
Error: fmt.Errorf(format, args...),
|
||||||
@@ -28,7 +28,7 @@ func AbortWith(format string, args ...interface{}) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func AbortWithUsage(format string, args ...interface{}) {
|
func AbortWithUsage(format string, args ...any) {
|
||||||
Abort(AbortDetails{
|
Abort(AbortDetails{
|
||||||
ExitCode: 1,
|
ExitCode: 1,
|
||||||
Error: fmt.Errorf(format, args...),
|
Error: fmt.Errorf(format, args...),
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
generated
vendored
@@ -68,7 +68,6 @@ func (p Program) RunAndExit(osArgs []string) {
|
|||||||
fmt.Fprintln(p.ErrWriter, deprecationTracker.DeprecationsReport())
|
fmt.Fprintln(p.ErrWriter, deprecationTracker.DeprecationsReport())
|
||||||
}
|
}
|
||||||
p.Exiter(exitCode)
|
p.Exiter(exitCode)
|
||||||
return
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
args, additionalArgs := []string{}, []string{}
|
args, additionalArgs := []string{}, []string{}
|
||||||
@@ -157,7 +156,6 @@ func (p Program) handleHelpRequestsAndExit(writer io.Writer, args []string) {
|
|||||||
p.EmitUsage(writer)
|
p.EmitUsage(writer)
|
||||||
Abort(AbortDetails{ExitCode: 1})
|
Abort(AbortDetails{ExitCode: 1})
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Program) EmitUsage(writer io.Writer) {
|
func (p Program) EmitUsage(writer io.Writer) {
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go
generated
vendored
@@ -89,7 +89,7 @@ func mergeProfileBlock(p *cover.Profile, pb cover.ProfileBlock, startIndex int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
if sortFunc(i) != true {
|
if !sortFunc(i) {
|
||||||
i = sort.Search(len(p.Blocks)-startIndex, sortFunc)
|
i = sort.Search(len(p.Blocks)-startIndex, sortFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
generated
vendored
@@ -142,7 +142,7 @@ OUTER_LOOP:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !endTime.IsZero() {
|
if !endTime.IsZero() {
|
||||||
r.suiteConfig.Timeout = endTime.Sub(time.Now())
|
r.suiteConfig.Timeout = time.Until(endTime)
|
||||||
if r.suiteConfig.Timeout <= 0 {
|
if r.suiteConfig.Timeout <= 0 {
|
||||||
suites[suiteIdx].State = internal.TestSuiteStateFailedDueToTimeout
|
suites[suiteIdx].State = internal.TestSuiteStateFailedDueToTimeout
|
||||||
opc.StopAndDrain()
|
opc.StopAndDrain()
|
||||||
|
|||||||
3
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
generated
vendored
3
tests/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
generated
vendored
@@ -1,6 +1,7 @@
|
|||||||
package ginkgo
|
package ginkgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2/internal/testingtproxy"
|
"github.com/onsi/ginkgo/v2/internal/testingtproxy"
|
||||||
@@ -48,6 +49,8 @@ The portion of the interface returned by GinkgoT() that maps onto methods in the
|
|||||||
*/
|
*/
|
||||||
type GinkgoTInterface interface {
|
type GinkgoTInterface interface {
|
||||||
Cleanup(func())
|
Cleanup(func())
|
||||||
|
Chdir(dir string)
|
||||||
|
Context() context.Context
|
||||||
Setenv(kev, value string)
|
Setenv(kev, value string)
|
||||||
Error(args ...any)
|
Error(args ...any)
|
||||||
Errorf(format string, args ...any)
|
Errorf(format string, args ...any)
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/failer.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/failer.go
generated
vendored
@@ -32,7 +32,7 @@ func (f *Failer) GetFailure() types.Failure {
|
|||||||
return f.failure
|
return f.failure
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Failer) Panic(location types.CodeLocation, forwardedPanic interface{}) {
|
func (f *Failer) Panic(location types.CodeLocation, forwardedPanic any) {
|
||||||
f.lock.Lock()
|
f.lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.lock.Unlock()
|
||||||
|
|
||||||
|
|||||||
22
tests/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
generated
vendored
22
tests/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
generated
vendored
@@ -40,7 +40,7 @@ func (ic InterruptCause) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InterruptStatus struct {
|
type InterruptStatus struct {
|
||||||
Channel chan interface{}
|
Channel chan any
|
||||||
Level InterruptLevel
|
Level InterruptLevel
|
||||||
Cause InterruptCause
|
Cause InterruptCause
|
||||||
}
|
}
|
||||||
@@ -62,14 +62,14 @@ type InterruptHandlerInterface interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InterruptHandler struct {
|
type InterruptHandler struct {
|
||||||
c chan interface{}
|
c chan any
|
||||||
lock *sync.Mutex
|
lock *sync.Mutex
|
||||||
level InterruptLevel
|
level InterruptLevel
|
||||||
cause InterruptCause
|
cause InterruptCause
|
||||||
client parallel_support.Client
|
client parallel_support.Client
|
||||||
stop chan interface{}
|
stop chan any
|
||||||
signals []os.Signal
|
signals []os.Signal
|
||||||
requestAbortCheck chan interface{}
|
requestAbortCheck chan any
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler {
|
func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler {
|
||||||
@@ -77,10 +77,10 @@ func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *
|
|||||||
signals = []os.Signal{os.Interrupt, syscall.SIGTERM}
|
signals = []os.Signal{os.Interrupt, syscall.SIGTERM}
|
||||||
}
|
}
|
||||||
handler := &InterruptHandler{
|
handler := &InterruptHandler{
|
||||||
c: make(chan interface{}),
|
c: make(chan any),
|
||||||
lock: &sync.Mutex{},
|
lock: &sync.Mutex{},
|
||||||
stop: make(chan interface{}),
|
stop: make(chan any),
|
||||||
requestAbortCheck: make(chan interface{}),
|
requestAbortCheck: make(chan any),
|
||||||
client: client,
|
client: client,
|
||||||
signals: signals,
|
signals: signals,
|
||||||
}
|
}
|
||||||
@@ -98,9 +98,9 @@ func (handler *InterruptHandler) registerForInterrupts() {
|
|||||||
signal.Notify(signalChannel, handler.signals...)
|
signal.Notify(signalChannel, handler.signals...)
|
||||||
|
|
||||||
// cross-process abort handling
|
// cross-process abort handling
|
||||||
var abortChannel chan interface{}
|
var abortChannel chan any
|
||||||
if handler.client != nil {
|
if handler.client != nil {
|
||||||
abortChannel = make(chan interface{})
|
abortChannel = make(chan any)
|
||||||
go func() {
|
go func() {
|
||||||
pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL)
|
pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL)
|
||||||
for {
|
for {
|
||||||
@@ -125,7 +125,7 @@ func (handler *InterruptHandler) registerForInterrupts() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
go func(abortChannel chan interface{}) {
|
go func(abortChannel chan any) {
|
||||||
var interruptCause InterruptCause
|
var interruptCause InterruptCause
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -151,7 +151,7 @@ func (handler *InterruptHandler) registerForInterrupts() {
|
|||||||
}
|
}
|
||||||
if handler.level != oldLevel {
|
if handler.level != oldLevel {
|
||||||
close(handler.c)
|
close(handler.c)
|
||||||
handler.c = make(chan interface{})
|
handler.c = make(chan any)
|
||||||
}
|
}
|
||||||
handler.lock.Unlock()
|
handler.lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|||||||
34
tests/vendor/github.com/onsi/ginkgo/v2/internal/node.go
generated
vendored
34
tests/vendor/github.com/onsi/ginkgo/v2/internal/node.go
generated
vendored
@@ -84,7 +84,7 @@ const SuppressProgressReporting = suppressProgressReporting(true)
|
|||||||
type FlakeAttempts uint
|
type FlakeAttempts uint
|
||||||
type MustPassRepeatedly uint
|
type MustPassRepeatedly uint
|
||||||
type Offset uint
|
type Offset uint
|
||||||
type Done chan<- interface{} // Deprecated Done Channel for asynchronous testing
|
type Done chan<- any // Deprecated Done Channel for asynchronous testing
|
||||||
type Labels []string
|
type Labels []string
|
||||||
type PollProgressInterval time.Duration
|
type PollProgressInterval time.Duration
|
||||||
type PollProgressAfter time.Duration
|
type PollProgressAfter time.Duration
|
||||||
@@ -110,9 +110,9 @@ func UnionOfLabels(labels ...Labels) Labels {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func PartitionDecorations(args ...interface{}) ([]interface{}, []interface{}) {
|
func PartitionDecorations(args ...any) ([]any, []any) {
|
||||||
decorations := []interface{}{}
|
decorations := []any{}
|
||||||
remainingArgs := []interface{}{}
|
remainingArgs := []any{}
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
if isDecoration(arg) {
|
if isDecoration(arg) {
|
||||||
decorations = append(decorations, arg)
|
decorations = append(decorations, arg)
|
||||||
@@ -123,7 +123,7 @@ func PartitionDecorations(args ...interface{}) ([]interface{}, []interface{}) {
|
|||||||
return decorations, remainingArgs
|
return decorations, remainingArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
func isDecoration(arg interface{}) bool {
|
func isDecoration(arg any) bool {
|
||||||
switch t := reflect.TypeOf(arg); {
|
switch t := reflect.TypeOf(arg); {
|
||||||
case t == nil:
|
case t == nil:
|
||||||
return false
|
return false
|
||||||
@@ -168,7 +168,7 @@ func isDecoration(arg interface{}) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSliceOfDecorations(slice interface{}) bool {
|
func isSliceOfDecorations(slice any) bool {
|
||||||
vSlice := reflect.ValueOf(slice)
|
vSlice := reflect.ValueOf(slice)
|
||||||
if vSlice.Len() == 0 {
|
if vSlice.Len() == 0 {
|
||||||
return false
|
return false
|
||||||
@@ -184,7 +184,7 @@ func isSliceOfDecorations(slice interface{}) bool {
|
|||||||
var contextType = reflect.TypeOf(new(context.Context)).Elem()
|
var contextType = reflect.TypeOf(new(context.Context)).Elem()
|
||||||
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
|
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
|
||||||
|
|
||||||
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...interface{}) (Node, []error) {
|
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (Node, []error) {
|
||||||
baseOffset := 2
|
baseOffset := 2
|
||||||
node := Node{
|
node := Node{
|
||||||
ID: UniqueNodeID(),
|
ID: UniqueNodeID(),
|
||||||
@@ -207,7 +207,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
|
|
||||||
args = unrollInterfaceSlice(args)
|
args = unrollInterfaceSlice(args)
|
||||||
|
|
||||||
remainingArgs := []interface{}{}
|
remainingArgs := []any{}
|
||||||
// First get the CodeLocation up-to-date
|
// First get the CodeLocation up-to-date
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
switch v := arg.(type) {
|
switch v := arg.(type) {
|
||||||
@@ -223,7 +223,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
labelsSeen := map[string]bool{}
|
labelsSeen := map[string]bool{}
|
||||||
trackedFunctionError := false
|
trackedFunctionError := false
|
||||||
args = remainingArgs
|
args = remainingArgs
|
||||||
remainingArgs = []interface{}{}
|
remainingArgs = []any{}
|
||||||
// now process the rest of the args
|
// now process the rest of the args
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
switch t := reflect.TypeOf(arg); {
|
switch t := reflect.TypeOf(arg); {
|
||||||
@@ -451,7 +451,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
|||||||
|
|
||||||
var doneType = reflect.TypeOf(make(Done))
|
var doneType = reflect.TypeOf(make(Done))
|
||||||
|
|
||||||
func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.CodeLocation, arg interface{}) (func(SpecContext), bool) {
|
func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.CodeLocation, arg any) (func(SpecContext), bool) {
|
||||||
t := reflect.TypeOf(arg)
|
t := reflect.TypeOf(arg)
|
||||||
if t.NumOut() > 0 || t.NumIn() > 1 {
|
if t.NumOut() > 0 || t.NumIn() > 1 {
|
||||||
return nil, false
|
return nil, false
|
||||||
@@ -477,7 +477,7 @@ func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.
|
|||||||
|
|
||||||
var byteType = reflect.TypeOf([]byte{})
|
var byteType = reflect.TypeOf([]byte{})
|
||||||
|
|
||||||
func extractSynchronizedBeforeSuiteProc1Body(arg interface{}) (func(SpecContext) []byte, bool) {
|
func extractSynchronizedBeforeSuiteProc1Body(arg any) (func(SpecContext) []byte, bool) {
|
||||||
t := reflect.TypeOf(arg)
|
t := reflect.TypeOf(arg)
|
||||||
v := reflect.ValueOf(arg)
|
v := reflect.ValueOf(arg)
|
||||||
|
|
||||||
@@ -505,7 +505,7 @@ func extractSynchronizedBeforeSuiteProc1Body(arg interface{}) (func(SpecContext)
|
|||||||
}, hasContext
|
}, hasContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractSynchronizedBeforeSuiteAllProcsBody(arg interface{}) (func(SpecContext, []byte), bool) {
|
func extractSynchronizedBeforeSuiteAllProcsBody(arg any) (func(SpecContext, []byte), bool) {
|
||||||
t := reflect.TypeOf(arg)
|
t := reflect.TypeOf(arg)
|
||||||
v := reflect.ValueOf(arg)
|
v := reflect.ValueOf(arg)
|
||||||
hasContext, hasByte := false, false
|
hasContext, hasByte := false, false
|
||||||
@@ -536,11 +536,11 @@ func extractSynchronizedBeforeSuiteAllProcsBody(arg interface{}) (func(SpecConte
|
|||||||
|
|
||||||
var errInterface = reflect.TypeOf((*error)(nil)).Elem()
|
var errInterface = reflect.TypeOf((*error)(nil)).Elem()
|
||||||
|
|
||||||
func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(string, types.CodeLocation), args ...interface{}) (Node, []error) {
|
func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(string, types.CodeLocation), args ...any) (Node, []error) {
|
||||||
decorations, remainingArgs := PartitionDecorations(args...)
|
decorations, remainingArgs := PartitionDecorations(args...)
|
||||||
baseOffset := 2
|
baseOffset := 2
|
||||||
cl := types.NewCodeLocation(baseOffset)
|
cl := types.NewCodeLocation(baseOffset)
|
||||||
finalArgs := []interface{}{}
|
finalArgs := []any{}
|
||||||
for _, arg := range decorations {
|
for _, arg := range decorations {
|
||||||
switch t := reflect.TypeOf(arg); {
|
switch t := reflect.TypeOf(arg); {
|
||||||
case t == reflect.TypeOf(Offset(0)):
|
case t == reflect.TypeOf(Offset(0)):
|
||||||
@@ -920,12 +920,12 @@ func (n Nodes) GetMaxMustPassRepeatedly() int {
|
|||||||
return maxMustPassRepeatedly
|
return maxMustPassRepeatedly
|
||||||
}
|
}
|
||||||
|
|
||||||
func unrollInterfaceSlice(args interface{}) []interface{} {
|
func unrollInterfaceSlice(args any) []any {
|
||||||
v := reflect.ValueOf(args)
|
v := reflect.ValueOf(args)
|
||||||
if v.Kind() != reflect.Slice {
|
if v.Kind() != reflect.Slice {
|
||||||
return []interface{}{args}
|
return []any{args}
|
||||||
}
|
}
|
||||||
out := []interface{}{}
|
out := []any{}
|
||||||
for i := 0; i < v.Len(); i++ {
|
for i := 0; i < v.Len(); i++ {
|
||||||
el := reflect.ValueOf(v.Index(i).Interface())
|
el := reflect.ValueOf(v.Index(i).Interface())
|
||||||
if el.Kind() == reflect.Slice && el.Type() != reflect.TypeOf(Labels{}) {
|
if el.Kind() == reflect.Slice && el.Type() != reflect.TypeOf(Labels{}) {
|
||||||
|
|||||||
14
tests/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go
generated
vendored
14
tests/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go
generated
vendored
@@ -69,7 +69,7 @@ type pipePair struct {
|
|||||||
writer *os.File
|
writer *os.File
|
||||||
}
|
}
|
||||||
|
|
||||||
func startPipeFactory(pipeChannel chan pipePair, shutdown chan interface{}) {
|
func startPipeFactory(pipeChannel chan pipePair, shutdown chan any) {
|
||||||
for {
|
for {
|
||||||
//make the next pipe...
|
//make the next pipe...
|
||||||
pair := pipePair{}
|
pair := pipePair{}
|
||||||
@@ -101,8 +101,8 @@ type genericOutputInterceptor struct {
|
|||||||
stderrClone *os.File
|
stderrClone *os.File
|
||||||
pipe pipePair
|
pipe pipePair
|
||||||
|
|
||||||
shutdown chan interface{}
|
shutdown chan any
|
||||||
emergencyBailout chan interface{}
|
emergencyBailout chan any
|
||||||
pipeChannel chan pipePair
|
pipeChannel chan pipePair
|
||||||
interceptedContent chan string
|
interceptedContent chan string
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ func (interceptor *genericOutputInterceptor) ResumeIntercepting() {
|
|||||||
interceptor.intercepting = true
|
interceptor.intercepting = true
|
||||||
if interceptor.stdoutClone == nil {
|
if interceptor.stdoutClone == nil {
|
||||||
interceptor.stdoutClone, interceptor.stderrClone = interceptor.implementation.CreateStdoutStderrClones()
|
interceptor.stdoutClone, interceptor.stderrClone = interceptor.implementation.CreateStdoutStderrClones()
|
||||||
interceptor.shutdown = make(chan interface{})
|
interceptor.shutdown = make(chan any)
|
||||||
go startPipeFactory(interceptor.pipeChannel, interceptor.shutdown)
|
go startPipeFactory(interceptor.pipeChannel, interceptor.shutdown)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,13 +147,13 @@ func (interceptor *genericOutputInterceptor) ResumeIntercepting() {
|
|||||||
// we get the pipe from our pipe factory. it runs in the background so we can request the next pipe while the spec being intercepted is running
|
// we get the pipe from our pipe factory. it runs in the background so we can request the next pipe while the spec being intercepted is running
|
||||||
interceptor.pipe = <-interceptor.pipeChannel
|
interceptor.pipe = <-interceptor.pipeChannel
|
||||||
|
|
||||||
interceptor.emergencyBailout = make(chan interface{})
|
interceptor.emergencyBailout = make(chan any)
|
||||||
|
|
||||||
//Spin up a goroutine to copy data from the pipe into a buffer, this is how we capture any output the user is emitting
|
//Spin up a goroutine to copy data from the pipe into a buffer, this is how we capture any output the user is emitting
|
||||||
go func() {
|
go func() {
|
||||||
buffer := &bytes.Buffer{}
|
buffer := &bytes.Buffer{}
|
||||||
destination := io.MultiWriter(buffer, interceptor.forwardTo)
|
destination := io.MultiWriter(buffer, interceptor.forwardTo)
|
||||||
copyFinished := make(chan interface{})
|
copyFinished := make(chan any)
|
||||||
reader := interceptor.pipe.reader
|
reader := interceptor.pipe.reader
|
||||||
go func() {
|
go func() {
|
||||||
io.Copy(destination, reader)
|
io.Copy(destination, reader)
|
||||||
@@ -224,7 +224,7 @@ func NewOSGlobalReassigningOutputInterceptor() OutputInterceptor {
|
|||||||
return &genericOutputInterceptor{
|
return &genericOutputInterceptor{
|
||||||
interceptedContent: make(chan string),
|
interceptedContent: make(chan string),
|
||||||
pipeChannel: make(chan pipePair),
|
pipeChannel: make(chan pipePair),
|
||||||
shutdown: make(chan interface{}),
|
shutdown: make(chan any),
|
||||||
implementation: &osGlobalReassigningOutputInterceptorImpl{},
|
implementation: &osGlobalReassigningOutputInterceptorImpl{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go
generated
vendored
@@ -13,7 +13,7 @@ func NewOutputInterceptor() OutputInterceptor {
|
|||||||
return &genericOutputInterceptor{
|
return &genericOutputInterceptor{
|
||||||
interceptedContent: make(chan string),
|
interceptedContent: make(chan string),
|
||||||
pipeChannel: make(chan pipePair),
|
pipeChannel: make(chan pipePair),
|
||||||
shutdown: make(chan interface{}),
|
shutdown: make(chan any),
|
||||||
implementation: &dupSyscallOutputInterceptorImpl{},
|
implementation: &dupSyscallOutputInterceptorImpl{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go
generated
vendored
@@ -30,7 +30,7 @@ type Server interface {
|
|||||||
Close()
|
Close()
|
||||||
Address() string
|
Address() string
|
||||||
RegisterAlive(node int, alive func() bool)
|
RegisterAlive(node int, alive func() bool)
|
||||||
GetSuiteDone() chan interface{}
|
GetSuiteDone() chan any
|
||||||
GetOutputDestination() io.Writer
|
GetOutputDestination() io.Writer
|
||||||
SetOutputDestination(io.Writer)
|
SetOutputDestination(io.Writer)
|
||||||
}
|
}
|
||||||
|
|||||||
9
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go
generated
vendored
9
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go
generated
vendored
@@ -34,7 +34,7 @@ func (client *httpClient) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *httpClient) post(path string, data interface{}) error {
|
func (client *httpClient) post(path string, data any) error {
|
||||||
var body io.Reader
|
var body io.Reader
|
||||||
if data != nil {
|
if data != nil {
|
||||||
encoded, err := json.Marshal(data)
|
encoded, err := json.Marshal(data)
|
||||||
@@ -54,7 +54,7 @@ func (client *httpClient) post(path string, data interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *httpClient) poll(path string, data interface{}) error {
|
func (client *httpClient) poll(path string, data any) error {
|
||||||
for {
|
for {
|
||||||
resp, err := http.Get(client.serverHost + path)
|
resp, err := http.Get(client.serverHost + path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -153,10 +153,7 @@ func (client *httpClient) PostAbort() error {
|
|||||||
|
|
||||||
func (client *httpClient) ShouldAbort() bool {
|
func (client *httpClient) ShouldAbort() bool {
|
||||||
err := client.poll("/abort", nil)
|
err := client.poll("/abort", nil)
|
||||||
if err == ErrorGone {
|
return err == ErrorGone
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *httpClient) Write(p []byte) (int, error) {
|
func (client *httpClient) Write(p []byte) (int, error) {
|
||||||
|
|||||||
4
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go
generated
vendored
4
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go
generated
vendored
@@ -75,7 +75,7 @@ func (server *httpServer) Address() string {
|
|||||||
return "http://" + server.listener.Addr().String()
|
return "http://" + server.listener.Addr().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *httpServer) GetSuiteDone() chan interface{} {
|
func (server *httpServer) GetSuiteDone() chan any {
|
||||||
return server.handler.done
|
return server.handler.done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ func (server *httpServer) RegisterAlive(node int, alive func() bool) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
// The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters`
|
// The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters`
|
||||||
func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object interface{}) bool {
|
func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object any) bool {
|
||||||
defer request.Body.Close()
|
defer request.Body.Close()
|
||||||
if json.NewDecoder(request.Body).Decode(object) != nil {
|
if json.NewDecoder(request.Body).Decode(object) != nil {
|
||||||
writer.WriteHeader(http.StatusBadRequest)
|
writer.WriteHeader(http.StatusBadRequest)
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go
generated
vendored
@@ -35,7 +35,7 @@ func (client *rpcClient) Close() error {
|
|||||||
return client.client.Close()
|
return client.client.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *rpcClient) poll(method string, data interface{}) error {
|
func (client *rpcClient) poll(method string, data any) error {
|
||||||
for {
|
for {
|
||||||
err := client.client.Call(method, voidSender, data)
|
err := client.client.Call(method, voidSender, data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
10
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go
generated
vendored
10
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go
generated
vendored
@@ -25,7 +25,7 @@ type RPCServer struct {
|
|||||||
handler *ServerHandler
|
handler *ServerHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create a new server, automatically selecting a port
|
// Create a new server, automatically selecting a port
|
||||||
func newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, error) {
|
func newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, error) {
|
||||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -37,7 +37,7 @@ func newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, e
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Start the server. You don't need to `go s.Start()`, just `s.Start()`
|
// Start the server. You don't need to `go s.Start()`, just `s.Start()`
|
||||||
func (server *RPCServer) Start() {
|
func (server *RPCServer) Start() {
|
||||||
rpcServer := rpc.NewServer()
|
rpcServer := rpc.NewServer()
|
||||||
rpcServer.RegisterName("Server", server.handler) //register the handler's methods as the server
|
rpcServer.RegisterName("Server", server.handler) //register the handler's methods as the server
|
||||||
@@ -48,17 +48,17 @@ func (server *RPCServer) Start() {
|
|||||||
go httpServer.Serve(server.listener)
|
go httpServer.Serve(server.listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Stop the server
|
// Stop the server
|
||||||
func (server *RPCServer) Close() {
|
func (server *RPCServer) Close() {
|
||||||
server.listener.Close()
|
server.listener.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
//The address the server can be reached it. Pass this into the `ForwardingReporter`.
|
// The address the server can be reached it. Pass this into the `ForwardingReporter`.
|
||||||
func (server *RPCServer) Address() string {
|
func (server *RPCServer) Address() string {
|
||||||
return server.listener.Addr().String()
|
return server.listener.Addr().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *RPCServer) GetSuiteDone() chan interface{} {
|
func (server *RPCServer) GetSuiteDone() chan any {
|
||||||
return server.handler.done
|
return server.handler.done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go
generated
vendored
4
tests/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go
generated
vendored
@@ -18,7 +18,7 @@ var voidSender Void
|
|||||||
// It handles all the business logic to avoid duplication between the two servers
|
// It handles all the business logic to avoid duplication between the two servers
|
||||||
|
|
||||||
type ServerHandler struct {
|
type ServerHandler struct {
|
||||||
done chan interface{}
|
done chan any
|
||||||
outputDestination io.Writer
|
outputDestination io.Writer
|
||||||
reporter reporters.Reporter
|
reporter reporters.Reporter
|
||||||
alives []func() bool
|
alives []func() bool
|
||||||
@@ -46,7 +46,7 @@ func newServerHandler(parallelTotal int, reporter reporters.Reporter) *ServerHan
|
|||||||
|
|
||||||
parallelTotal: parallelTotal,
|
parallelTotal: parallelTotal,
|
||||||
outputDestination: os.Stdout,
|
outputDestination: os.Stdout,
|
||||||
done: make(chan interface{}),
|
done: make(chan any),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go
generated
vendored
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
type ReportEntry = types.ReportEntry
|
type ReportEntry = types.ReportEntry
|
||||||
|
|
||||||
func NewReportEntry(name string, cl types.CodeLocation, args ...interface{}) (ReportEntry, error) {
|
func NewReportEntry(name string, cl types.CodeLocation, args ...any) (ReportEntry, error) {
|
||||||
out := ReportEntry{
|
out := ReportEntry{
|
||||||
Visibility: types.ReportEntryVisibilityAlways,
|
Visibility: types.ReportEntryVisibilityAlways,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|||||||
43
tests/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go
generated
vendored
43
tests/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go
generated
vendored
@@ -1,6 +1,7 @@
|
|||||||
package testingtproxy
|
package testingtproxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@@ -19,9 +20,9 @@ type addReportEntryFunc func(names string, args ...any)
|
|||||||
type ginkgoWriterInterface interface {
|
type ginkgoWriterInterface interface {
|
||||||
io.Writer
|
io.Writer
|
||||||
|
|
||||||
Print(a ...interface{})
|
Print(a ...any)
|
||||||
Printf(format string, a ...interface{})
|
Printf(format string, a ...any)
|
||||||
Println(a ...interface{})
|
Println(a ...any)
|
||||||
}
|
}
|
||||||
type ginkgoRecoverFunc func()
|
type ginkgoRecoverFunc func()
|
||||||
type attachProgressReporterFunc func(func() string) func()
|
type attachProgressReporterFunc func(func() string) func()
|
||||||
@@ -80,11 +81,31 @@ func (t *ginkgoTestingTProxy) Setenv(key, value string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ginkgoTestingTProxy) Error(args ...interface{}) {
|
func (t *ginkgoTestingTProxy) Chdir(dir string) {
|
||||||
|
currentDir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.fail(fmt.Sprintf("Failed to get current directory: %v", err), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.cleanup(os.Chdir, currentDir, internal.Offset(1))
|
||||||
|
|
||||||
|
err = os.Chdir(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.fail(fmt.Sprintf("Failed to change directory: %v", err), 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ginkgoTestingTProxy) Context() context.Context {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
t.cleanup(cancel, internal.Offset(1))
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ginkgoTestingTProxy) Error(args ...any) {
|
||||||
t.fail(fmt.Sprintln(args...), t.offset)
|
t.fail(fmt.Sprintln(args...), t.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ginkgoTestingTProxy) Errorf(format string, args ...interface{}) {
|
func (t *ginkgoTestingTProxy) Errorf(format string, args ...any) {
|
||||||
t.fail(fmt.Sprintf(format, args...), t.offset)
|
t.fail(fmt.Sprintf(format, args...), t.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,11 +121,11 @@ func (t *ginkgoTestingTProxy) Failed() bool {
|
|||||||
return t.report().Failed()
|
return t.report().Failed()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ginkgoTestingTProxy) Fatal(args ...interface{}) {
|
func (t *ginkgoTestingTProxy) Fatal(args ...any) {
|
||||||
t.fail(fmt.Sprintln(args...), t.offset)
|
t.fail(fmt.Sprintln(args...), t.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ginkgoTestingTProxy) Fatalf(format string, args ...interface{}) {
|
func (t *ginkgoTestingTProxy) Fatalf(format string, args ...any) {
|
||||||
t.fail(fmt.Sprintf(format, args...), t.offset)
|
t.fail(fmt.Sprintf(format, args...), t.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,11 +133,11 @@ func (t *ginkgoTestingTProxy) Helper() {
|
|||||||
types.MarkAsHelper(1)
|
types.MarkAsHelper(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ginkgoTestingTProxy) Log(args ...interface{}) {
|
func (t *ginkgoTestingTProxy) Log(args ...any) {
|
||||||
fmt.Fprintln(t.writer, args...)
|
fmt.Fprintln(t.writer, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ginkgoTestingTProxy) Logf(format string, args ...interface{}) {
|
func (t *ginkgoTestingTProxy) Logf(format string, args ...any) {
|
||||||
t.Log(fmt.Sprintf(format, args...))
|
t.Log(fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +149,7 @@ func (t *ginkgoTestingTProxy) Parallel() {
|
|||||||
// No-op
|
// No-op
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ginkgoTestingTProxy) Skip(args ...interface{}) {
|
func (t *ginkgoTestingTProxy) Skip(args ...any) {
|
||||||
t.skip(fmt.Sprintln(args...), t.offset)
|
t.skip(fmt.Sprintln(args...), t.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +157,7 @@ func (t *ginkgoTestingTProxy) SkipNow() {
|
|||||||
t.skip("skip", t.offset)
|
t.skip("skip", t.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ginkgoTestingTProxy) Skipf(format string, args ...interface{}) {
|
func (t *ginkgoTestingTProxy) Skipf(format string, args ...any) {
|
||||||
t.skip(fmt.Sprintf(format, args...), t.offset)
|
t.skip(fmt.Sprintf(format, args...), t.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
tests/vendor/github.com/onsi/ginkgo/v2/internal/writer.go
generated
vendored
6
tests/vendor/github.com/onsi/ginkgo/v2/internal/writer.go
generated
vendored
@@ -121,15 +121,15 @@ func (w *Writer) ClearTeeWriters() {
|
|||||||
w.teeWriters = []io.Writer{}
|
w.teeWriters = []io.Writer{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Writer) Print(a ...interface{}) {
|
func (w *Writer) Print(a ...any) {
|
||||||
fmt.Fprint(w, a...)
|
fmt.Fprint(w, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Writer) Printf(format string, a ...interface{}) {
|
func (w *Writer) Printf(format string, a ...any) {
|
||||||
fmt.Fprintf(w, format, a...)
|
fmt.Fprintf(w, format, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Writer) Println(a ...interface{}) {
|
func (w *Writer) Println(a ...any) {
|
||||||
fmt.Fprintln(w, a...)
|
fmt.Fprintln(w, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4
tests/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
generated
vendored
4
tests/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
generated
vendored
@@ -685,11 +685,11 @@ func (r *DefaultReporter) _emit(s string, block bool, isDelimiter bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Rendering text */
|
/* Rendering text */
|
||||||
func (r *DefaultReporter) f(format string, args ...interface{}) string {
|
func (r *DefaultReporter) f(format string, args ...any) string {
|
||||||
return r.formatter.F(format, args...)
|
return r.formatter.F(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DefaultReporter) fi(indentation uint, format string, args ...interface{}) string {
|
func (r *DefaultReporter) fi(indentation uint, format string, args ...any) string {
|
||||||
return r.formatter.Fi(indentation, format, args...)
|
return r.formatter.Fi(indentation, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
tests/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go
generated
vendored
12
tests/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go
generated
vendored
@@ -60,7 +60,7 @@ AddReportEntry() must be called within a Subject or Setup node - not in a Contai
|
|||||||
|
|
||||||
You can learn more about Report Entries here: https://onsi.github.io/ginkgo/#attaching-data-to-reports
|
You can learn more about Report Entries here: https://onsi.github.io/ginkgo/#attaching-data-to-reports
|
||||||
*/
|
*/
|
||||||
func AddReportEntry(name string, args ...interface{}) {
|
func AddReportEntry(name string, args ...any) {
|
||||||
cl := types.NewCodeLocation(1)
|
cl := types.NewCodeLocation(1)
|
||||||
reportEntry, err := internal.NewReportEntry(name, cl, args...)
|
reportEntry, err := internal.NewReportEntry(name, cl, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -89,7 +89,7 @@ You can learn more about ReportBeforeEach here: https://onsi.github.io/ginkgo/#g
|
|||||||
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
|
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
|
||||||
*/
|
*/
|
||||||
func ReportBeforeEach(body any, args ...any) bool {
|
func ReportBeforeEach(body any, args ...any) bool {
|
||||||
combinedArgs := []interface{}{body}
|
combinedArgs := []any{body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
|
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeEach, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeEach, "", combinedArgs...))
|
||||||
@@ -113,7 +113,7 @@ You can learn more about ReportAfterEach here: https://onsi.github.io/ginkgo/#ge
|
|||||||
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
|
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
|
||||||
*/
|
*/
|
||||||
func ReportAfterEach(body any, args ...any) bool {
|
func ReportAfterEach(body any, args ...any) bool {
|
||||||
combinedArgs := []interface{}{body}
|
combinedArgs := []any{body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
|
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...))
|
||||||
@@ -143,7 +143,7 @@ You can learn more about Ginkgo's reporting infrastructure, including generating
|
|||||||
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
|
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
|
||||||
*/
|
*/
|
||||||
func ReportBeforeSuite(body any, args ...any) bool {
|
func ReportBeforeSuite(body any, args ...any) bool {
|
||||||
combinedArgs := []interface{}{body}
|
combinedArgs := []any{body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...))
|
||||||
}
|
}
|
||||||
@@ -174,8 +174,8 @@ You can learn more about Ginkgo's reporting infrastructure, including generating
|
|||||||
|
|
||||||
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
|
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
|
||||||
*/
|
*/
|
||||||
func ReportAfterSuite(text string, body any, args ...interface{}) bool {
|
func ReportAfterSuite(text string, body any, args ...any) bool {
|
||||||
combinedArgs := []interface{}{body}
|
combinedArgs := []any{body}
|
||||||
combinedArgs = append(combinedArgs, args...)
|
combinedArgs = append(combinedArgs, args...)
|
||||||
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...))
|
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...))
|
||||||
}
|
}
|
||||||
|
|||||||
46
tests/vendor/github.com/onsi/ginkgo/v2/table_dsl.go
generated
vendored
46
tests/vendor/github.com/onsi/ginkgo/v2/table_dsl.go
generated
vendored
@@ -23,7 +23,7 @@ You can learn more about generating EntryDescriptions here: https://onsi.github.
|
|||||||
*/
|
*/
|
||||||
type EntryDescription string
|
type EntryDescription string
|
||||||
|
|
||||||
func (ed EntryDescription) render(args ...interface{}) string {
|
func (ed EntryDescription) render(args ...any) string {
|
||||||
return fmt.Sprintf(string(ed), args...)
|
return fmt.Sprintf(string(ed), args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ For example:
|
|||||||
You can learn more about DescribeTable here: https://onsi.github.io/ginkgo/#table-specs
|
You can learn more about DescribeTable here: https://onsi.github.io/ginkgo/#table-specs
|
||||||
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
|
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
|
||||||
*/
|
*/
|
||||||
func DescribeTable(description string, args ...interface{}) bool {
|
func DescribeTable(description string, args ...any) bool {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
generateTable(description, false, args...)
|
generateTable(description, false, args...)
|
||||||
return true
|
return true
|
||||||
@@ -53,7 +53,7 @@ func DescribeTable(description string, args ...interface{}) bool {
|
|||||||
/*
|
/*
|
||||||
You can focus a table with `FDescribeTable`. This is equivalent to `FDescribe`.
|
You can focus a table with `FDescribeTable`. This is equivalent to `FDescribe`.
|
||||||
*/
|
*/
|
||||||
func FDescribeTable(description string, args ...interface{}) bool {
|
func FDescribeTable(description string, args ...any) bool {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
args = append(args, internal.Focus)
|
args = append(args, internal.Focus)
|
||||||
generateTable(description, false, args...)
|
generateTable(description, false, args...)
|
||||||
@@ -63,7 +63,7 @@ func FDescribeTable(description string, args ...interface{}) bool {
|
|||||||
/*
|
/*
|
||||||
You can mark a table as pending with `PDescribeTable`. This is equivalent to `PDescribe`.
|
You can mark a table as pending with `PDescribeTable`. This is equivalent to `PDescribe`.
|
||||||
*/
|
*/
|
||||||
func PDescribeTable(description string, args ...interface{}) bool {
|
func PDescribeTable(description string, args ...any) bool {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
args = append(args, internal.Pending)
|
args = append(args, internal.Pending)
|
||||||
generateTable(description, false, args...)
|
generateTable(description, false, args...)
|
||||||
@@ -109,7 +109,7 @@ Note that you **must** place define an It inside the body function.
|
|||||||
You can learn more about DescribeTableSubtree here: https://onsi.github.io/ginkgo/#table-specs
|
You can learn more about DescribeTableSubtree here: https://onsi.github.io/ginkgo/#table-specs
|
||||||
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
|
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
|
||||||
*/
|
*/
|
||||||
func DescribeTableSubtree(description string, args ...interface{}) bool {
|
func DescribeTableSubtree(description string, args ...any) bool {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
generateTable(description, true, args...)
|
generateTable(description, true, args...)
|
||||||
return true
|
return true
|
||||||
@@ -118,7 +118,7 @@ func DescribeTableSubtree(description string, args ...interface{}) bool {
|
|||||||
/*
|
/*
|
||||||
You can focus a table with `FDescribeTableSubtree`. This is equivalent to `FDescribe`.
|
You can focus a table with `FDescribeTableSubtree`. This is equivalent to `FDescribe`.
|
||||||
*/
|
*/
|
||||||
func FDescribeTableSubtree(description string, args ...interface{}) bool {
|
func FDescribeTableSubtree(description string, args ...any) bool {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
args = append(args, internal.Focus)
|
args = append(args, internal.Focus)
|
||||||
generateTable(description, true, args...)
|
generateTable(description, true, args...)
|
||||||
@@ -128,7 +128,7 @@ func FDescribeTableSubtree(description string, args ...interface{}) bool {
|
|||||||
/*
|
/*
|
||||||
You can mark a table as pending with `PDescribeTableSubtree`. This is equivalent to `PDescribe`.
|
You can mark a table as pending with `PDescribeTableSubtree`. This is equivalent to `PDescribe`.
|
||||||
*/
|
*/
|
||||||
func PDescribeTableSubtree(description string, args ...interface{}) bool {
|
func PDescribeTableSubtree(description string, args ...any) bool {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
args = append(args, internal.Pending)
|
args = append(args, internal.Pending)
|
||||||
generateTable(description, true, args...)
|
generateTable(description, true, args...)
|
||||||
@@ -144,9 +144,9 @@ var XDescribeTableSubtree = PDescribeTableSubtree
|
|||||||
TableEntry represents an entry in a table test. You generally use the `Entry` constructor.
|
TableEntry represents an entry in a table test. You generally use the `Entry` constructor.
|
||||||
*/
|
*/
|
||||||
type TableEntry struct {
|
type TableEntry struct {
|
||||||
description interface{}
|
description any
|
||||||
decorations []interface{}
|
decorations []any
|
||||||
parameters []interface{}
|
parameters []any
|
||||||
codeLocation types.CodeLocation
|
codeLocation types.CodeLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ If you want to generate interruptible specs simply write a Table function that a
|
|||||||
|
|
||||||
You can learn more about Entry here: https://onsi.github.io/ginkgo/#table-specs
|
You can learn more about Entry here: https://onsi.github.io/ginkgo/#table-specs
|
||||||
*/
|
*/
|
||||||
func Entry(description interface{}, args ...interface{}) TableEntry {
|
func Entry(description any, args ...any) TableEntry {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
decorations, parameters := internal.PartitionDecorations(args...)
|
decorations, parameters := internal.PartitionDecorations(args...)
|
||||||
return TableEntry{description: description, decorations: decorations, parameters: parameters, codeLocation: types.NewCodeLocation(0)}
|
return TableEntry{description: description, decorations: decorations, parameters: parameters, codeLocation: types.NewCodeLocation(0)}
|
||||||
@@ -171,7 +171,7 @@ func Entry(description interface{}, args ...interface{}) TableEntry {
|
|||||||
/*
|
/*
|
||||||
You can focus a particular entry with FEntry. This is equivalent to FIt.
|
You can focus a particular entry with FEntry. This is equivalent to FIt.
|
||||||
*/
|
*/
|
||||||
func FEntry(description interface{}, args ...interface{}) TableEntry {
|
func FEntry(description any, args ...any) TableEntry {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
decorations, parameters := internal.PartitionDecorations(args...)
|
decorations, parameters := internal.PartitionDecorations(args...)
|
||||||
decorations = append(decorations, internal.Focus)
|
decorations = append(decorations, internal.Focus)
|
||||||
@@ -181,7 +181,7 @@ func FEntry(description interface{}, args ...interface{}) TableEntry {
|
|||||||
/*
|
/*
|
||||||
You can mark a particular entry as pending with PEntry. This is equivalent to PIt.
|
You can mark a particular entry as pending with PEntry. This is equivalent to PIt.
|
||||||
*/
|
*/
|
||||||
func PEntry(description interface{}, args ...interface{}) TableEntry {
|
func PEntry(description any, args ...any) TableEntry {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
decorations, parameters := internal.PartitionDecorations(args...)
|
decorations, parameters := internal.PartitionDecorations(args...)
|
||||||
decorations = append(decorations, internal.Pending)
|
decorations = append(decorations, internal.Pending)
|
||||||
@@ -196,17 +196,17 @@ var XEntry = PEntry
|
|||||||
var contextType = reflect.TypeOf(new(context.Context)).Elem()
|
var contextType = reflect.TypeOf(new(context.Context)).Elem()
|
||||||
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
|
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
|
||||||
|
|
||||||
func generateTable(description string, isSubtree bool, args ...interface{}) {
|
func generateTable(description string, isSubtree bool, args ...any) {
|
||||||
GinkgoHelper()
|
GinkgoHelper()
|
||||||
cl := types.NewCodeLocation(0)
|
cl := types.NewCodeLocation(0)
|
||||||
containerNodeArgs := []interface{}{cl}
|
containerNodeArgs := []any{cl}
|
||||||
|
|
||||||
entries := []TableEntry{}
|
entries := []TableEntry{}
|
||||||
var internalBody interface{}
|
var internalBody any
|
||||||
var internalBodyType reflect.Type
|
var internalBodyType reflect.Type
|
||||||
|
|
||||||
var tableLevelEntryDescription interface{}
|
var tableLevelEntryDescription any
|
||||||
tableLevelEntryDescription = func(args ...interface{}) string {
|
tableLevelEntryDescription = func(args ...any) string {
|
||||||
out := []string{}
|
out := []string{}
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
out = append(out, fmt.Sprint(arg))
|
out = append(out, fmt.Sprint(arg))
|
||||||
@@ -265,7 +265,7 @@ func generateTable(description string, isSubtree bool, args ...interface{}) {
|
|||||||
err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation)
|
err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation)
|
||||||
}
|
}
|
||||||
|
|
||||||
internalNodeArgs := []interface{}{entry.codeLocation}
|
internalNodeArgs := []any{entry.codeLocation}
|
||||||
internalNodeArgs = append(internalNodeArgs, entry.decorations...)
|
internalNodeArgs = append(internalNodeArgs, entry.decorations...)
|
||||||
|
|
||||||
hasContext := false
|
hasContext := false
|
||||||
@@ -290,7 +290,7 @@ func generateTable(description string, isSubtree bool, args ...interface{}) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
invokeFunction(internalBody, append([]interface{}{c}, entry.parameters...))
|
invokeFunction(internalBody, append([]any{c}, entry.parameters...))
|
||||||
})
|
})
|
||||||
if isSubtree {
|
if isSubtree {
|
||||||
exitIfErr(types.GinkgoErrors.ContextsCannotBeUsedInSubtreeTables(cl))
|
exitIfErr(types.GinkgoErrors.ContextsCannotBeUsedInSubtreeTables(cl))
|
||||||
@@ -316,7 +316,7 @@ func generateTable(description string, isSubtree bool, args ...interface{}) {
|
|||||||
pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, description, containerNodeArgs...))
|
pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, description, containerNodeArgs...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func invokeFunction(function interface{}, parameters []interface{}) []reflect.Value {
|
func invokeFunction(function any, parameters []any) []reflect.Value {
|
||||||
inValues := make([]reflect.Value, len(parameters))
|
inValues := make([]reflect.Value, len(parameters))
|
||||||
|
|
||||||
funcType := reflect.TypeOf(function)
|
funcType := reflect.TypeOf(function)
|
||||||
@@ -339,7 +339,7 @@ func invokeFunction(function interface{}, parameters []interface{}) []reflect.Va
|
|||||||
return reflect.ValueOf(function).Call(inValues)
|
return reflect.ValueOf(function).Call(inValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateParameters(function interface{}, parameters []interface{}, kind string, cl types.CodeLocation, hasContext bool) error {
|
func validateParameters(function any, parameters []any, kind string, cl types.CodeLocation, hasContext bool) error {
|
||||||
funcType := reflect.TypeOf(function)
|
funcType := reflect.TypeOf(function)
|
||||||
limit := funcType.NumIn()
|
limit := funcType.NumIn()
|
||||||
offset := 0
|
offset := 0
|
||||||
@@ -377,7 +377,7 @@ func validateParameters(function interface{}, parameters []interface{}, kind str
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeValue(parameter interface{}, t reflect.Type) reflect.Value {
|
func computeValue(parameter any, t reflect.Type) reflect.Value {
|
||||||
if parameter == nil {
|
if parameter == nil {
|
||||||
return reflect.Zero(t)
|
return reflect.Zero(t)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
16
tests/vendor/github.com/onsi/ginkgo/v2/types/config.go
generated
vendored
16
tests/vendor/github.com/onsi/ginkgo/v2/types/config.go
generated
vendored
@@ -365,7 +365,7 @@ var ReporterConfigFlags = GinkgoFlags{
|
|||||||
func BuildTestSuiteFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig) (GinkgoFlagSet, error) {
|
func BuildTestSuiteFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig) (GinkgoFlagSet, error) {
|
||||||
flags := SuiteConfigFlags.CopyAppend(ParallelConfigFlags...).CopyAppend(ReporterConfigFlags...)
|
flags := SuiteConfigFlags.CopyAppend(ParallelConfigFlags...).CopyAppend(ReporterConfigFlags...)
|
||||||
flags = flags.WithPrefix("ginkgo")
|
flags = flags.WithPrefix("ginkgo")
|
||||||
bindings := map[string]interface{}{
|
bindings := map[string]any{
|
||||||
"S": suiteConfig,
|
"S": suiteConfig,
|
||||||
"R": reporterConfig,
|
"R": reporterConfig,
|
||||||
"D": &deprecatedConfig{},
|
"D": &deprecatedConfig{},
|
||||||
@@ -646,7 +646,7 @@ func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, packageToBuild strin
|
|||||||
args := []string{"test", "-c", packageToBuild}
|
args := []string{"test", "-c", packageToBuild}
|
||||||
goArgs, err := GenerateFlagArgs(
|
goArgs, err := GenerateFlagArgs(
|
||||||
GoBuildFlags,
|
GoBuildFlags,
|
||||||
map[string]interface{}{
|
map[string]any{
|
||||||
"Go": &goFlagsConfig,
|
"Go": &goFlagsConfig,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -665,7 +665,7 @@ func GenerateGinkgoTestRunArgs(suiteConfig SuiteConfig, reporterConfig ReporterC
|
|||||||
flags = flags.CopyAppend(ParallelConfigFlags.WithPrefix("ginkgo")...)
|
flags = flags.CopyAppend(ParallelConfigFlags.WithPrefix("ginkgo")...)
|
||||||
flags = flags.CopyAppend(ReporterConfigFlags.WithPrefix("ginkgo")...)
|
flags = flags.CopyAppend(ReporterConfigFlags.WithPrefix("ginkgo")...)
|
||||||
flags = flags.CopyAppend(GoRunFlags.WithPrefix("test")...)
|
flags = flags.CopyAppend(GoRunFlags.WithPrefix("test")...)
|
||||||
bindings := map[string]interface{}{
|
bindings := map[string]any{
|
||||||
"S": &suiteConfig,
|
"S": &suiteConfig,
|
||||||
"R": &reporterConfig,
|
"R": &reporterConfig,
|
||||||
"Go": &goFlagsConfig,
|
"Go": &goFlagsConfig,
|
||||||
@@ -677,7 +677,7 @@ func GenerateGinkgoTestRunArgs(suiteConfig SuiteConfig, reporterConfig ReporterC
|
|||||||
// GenerateGoTestRunArgs is used by the Ginkgo CLI to generate command line arguments to pass to the compiled non-Ginkgo test binary
|
// GenerateGoTestRunArgs is used by the Ginkgo CLI to generate command line arguments to pass to the compiled non-Ginkgo test binary
|
||||||
func GenerateGoTestRunArgs(goFlagsConfig GoFlagsConfig) ([]string, error) {
|
func GenerateGoTestRunArgs(goFlagsConfig GoFlagsConfig) ([]string, error) {
|
||||||
flags := GoRunFlags.WithPrefix("test")
|
flags := GoRunFlags.WithPrefix("test")
|
||||||
bindings := map[string]interface{}{
|
bindings := map[string]any{
|
||||||
"Go": &goFlagsConfig,
|
"Go": &goFlagsConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,7 +699,7 @@ func BuildRunCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterCo
|
|||||||
flags = flags.CopyAppend(GoBuildFlags...)
|
flags = flags.CopyAppend(GoBuildFlags...)
|
||||||
flags = flags.CopyAppend(GoRunFlags...)
|
flags = flags.CopyAppend(GoRunFlags...)
|
||||||
|
|
||||||
bindings := map[string]interface{}{
|
bindings := map[string]any{
|
||||||
"S": suiteConfig,
|
"S": suiteConfig,
|
||||||
"R": reporterConfig,
|
"R": reporterConfig,
|
||||||
"C": cliConfig,
|
"C": cliConfig,
|
||||||
@@ -720,7 +720,7 @@ func BuildWatchCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *Reporter
|
|||||||
flags = flags.CopyAppend(GoBuildFlags...)
|
flags = flags.CopyAppend(GoBuildFlags...)
|
||||||
flags = flags.CopyAppend(GoRunFlags...)
|
flags = flags.CopyAppend(GoRunFlags...)
|
||||||
|
|
||||||
bindings := map[string]interface{}{
|
bindings := map[string]any{
|
||||||
"S": suiteConfig,
|
"S": suiteConfig,
|
||||||
"R": reporterConfig,
|
"R": reporterConfig,
|
||||||
"C": cliConfig,
|
"C": cliConfig,
|
||||||
@@ -736,7 +736,7 @@ func BuildBuildCommandFlagSet(cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig
|
|||||||
flags := GinkgoCLISharedFlags
|
flags := GinkgoCLISharedFlags
|
||||||
flags = flags.CopyAppend(GoBuildFlags...)
|
flags = flags.CopyAppend(GoBuildFlags...)
|
||||||
|
|
||||||
bindings := map[string]interface{}{
|
bindings := map[string]any{
|
||||||
"C": cliConfig,
|
"C": cliConfig,
|
||||||
"Go": goFlagsConfig,
|
"Go": goFlagsConfig,
|
||||||
"D": &deprecatedConfig{},
|
"D": &deprecatedConfig{},
|
||||||
@@ -760,7 +760,7 @@ func BuildBuildCommandFlagSet(cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig
|
|||||||
func BuildLabelsCommandFlagSet(cliConfig *CLIConfig) (GinkgoFlagSet, error) {
|
func BuildLabelsCommandFlagSet(cliConfig *CLIConfig) (GinkgoFlagSet, error) {
|
||||||
flags := GinkgoCLISharedFlags.SubsetWithNames("r", "skip-package")
|
flags := GinkgoCLISharedFlags.SubsetWithNames("r", "skip-package")
|
||||||
|
|
||||||
bindings := map[string]interface{}{
|
bindings := map[string]any{
|
||||||
"C": cliConfig,
|
"C": cliConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go
generated
vendored
@@ -113,7 +113,7 @@ type DeprecatedSpecFailure struct {
|
|||||||
|
|
||||||
type DeprecatedSpecMeasurement struct {
|
type DeprecatedSpecMeasurement struct {
|
||||||
Name string
|
Name string
|
||||||
Info interface{}
|
Info any
|
||||||
Order int
|
Order int
|
||||||
|
|
||||||
Results []float64
|
Results []float64
|
||||||
|
|||||||
8
tests/vendor/github.com/onsi/ginkgo/v2/types/errors.go
generated
vendored
8
tests/vendor/github.com/onsi/ginkgo/v2/types/errors.go
generated
vendored
@@ -88,7 +88,7 @@ body of a {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}.`, n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic interface{}, cl CodeLocation) error {
|
func (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic any, cl CodeLocation) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "Assertion or Panic detected during tree construction",
|
Heading: "Assertion or Panic detected during tree construction",
|
||||||
Message: formatter.F(
|
Message: formatter.F(
|
||||||
@@ -189,7 +189,7 @@ func (g ginkgoErrors) InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(cl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator interface{}) error {
|
func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator any) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "Unknown Decorator",
|
Heading: "Unknown Decorator",
|
||||||
Message: formatter.F(`[%s] node was passed an unknown decorator: '%#v'`, nodeType, decorator),
|
Message: formatter.F(`[%s] node was passed an unknown decorator: '%#v'`, nodeType, decorator),
|
||||||
@@ -345,7 +345,7 @@ func (g ginkgoErrors) PushingCleanupInCleanupNode(cl CodeLocation) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ReportEntry errors */
|
/* ReportEntry errors */
|
||||||
func (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg interface{}) error {
|
func (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg any) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "Too Many ReportEntry Values",
|
Heading: "Too Many ReportEntry Values",
|
||||||
Message: formatter.F(`{{bold}}AddGinkgoReport{{/}} can only be given one value. Got unexpected value: %#v`, arg),
|
Message: formatter.F(`{{bold}}AddGinkgoReport{{/}} can only be given one value. Got unexpected value: %#v`, arg),
|
||||||
@@ -539,7 +539,7 @@ func (g ginkgoErrors) SynchronizedBeforeSuiteDisappearedOnProc1() error {
|
|||||||
|
|
||||||
/* Configuration errors */
|
/* Configuration errors */
|
||||||
|
|
||||||
func (g ginkgoErrors) UnknownTypePassedToRunSpecs(value interface{}) error {
|
func (g ginkgoErrors) UnknownTypePassedToRunSpecs(value any) error {
|
||||||
return GinkgoError{
|
return GinkgoError{
|
||||||
Heading: "Unknown Type passed to RunSpecs",
|
Heading: "Unknown Type passed to RunSpecs",
|
||||||
Message: fmt.Sprintf("RunSpecs() accepts labels, and configuration of type types.SuiteConfig and/or types.ReporterConfig.\n You passed in: %v", value),
|
Message: fmt.Sprintf("RunSpecs() accepts labels, and configuration of type types.SuiteConfig and/or types.ReporterConfig.\n You passed in: %v", value),
|
||||||
|
|||||||
10
tests/vendor/github.com/onsi/ginkgo/v2/types/flags.go
generated
vendored
10
tests/vendor/github.com/onsi/ginkgo/v2/types/flags.go
generated
vendored
@@ -92,7 +92,7 @@ func (gfs GinkgoFlagSections) Lookup(key string) (GinkgoFlagSection, bool) {
|
|||||||
|
|
||||||
type GinkgoFlagSet struct {
|
type GinkgoFlagSet struct {
|
||||||
flags GinkgoFlags
|
flags GinkgoFlags
|
||||||
bindings interface{}
|
bindings any
|
||||||
|
|
||||||
sections GinkgoFlagSections
|
sections GinkgoFlagSections
|
||||||
extraGoFlagsSection GinkgoFlagSection
|
extraGoFlagsSection GinkgoFlagSection
|
||||||
@@ -101,7 +101,7 @@ type GinkgoFlagSet struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call NewGinkgoFlagSet to create GinkgoFlagSet that creates and binds to it's own *flag.FlagSet
|
// Call NewGinkgoFlagSet to create GinkgoFlagSet that creates and binds to it's own *flag.FlagSet
|
||||||
func NewGinkgoFlagSet(flags GinkgoFlags, bindings interface{}, sections GinkgoFlagSections) (GinkgoFlagSet, error) {
|
func NewGinkgoFlagSet(flags GinkgoFlags, bindings any, sections GinkgoFlagSections) (GinkgoFlagSet, error) {
|
||||||
return bindFlagSet(GinkgoFlagSet{
|
return bindFlagSet(GinkgoFlagSet{
|
||||||
flags: flags,
|
flags: flags,
|
||||||
bindings: bindings,
|
bindings: bindings,
|
||||||
@@ -110,7 +110,7 @@ func NewGinkgoFlagSet(flags GinkgoFlags, bindings interface{}, sections GinkgoFl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call NewGinkgoFlagSet to create GinkgoFlagSet that extends an existing *flag.FlagSet
|
// Call NewGinkgoFlagSet to create GinkgoFlagSet that extends an existing *flag.FlagSet
|
||||||
func NewAttachedGinkgoFlagSet(flagSet *flag.FlagSet, flags GinkgoFlags, bindings interface{}, sections GinkgoFlagSections, extraGoFlagsSection GinkgoFlagSection) (GinkgoFlagSet, error) {
|
func NewAttachedGinkgoFlagSet(flagSet *flag.FlagSet, flags GinkgoFlags, bindings any, sections GinkgoFlagSections, extraGoFlagsSection GinkgoFlagSection) (GinkgoFlagSet, error) {
|
||||||
return bindFlagSet(GinkgoFlagSet{
|
return bindFlagSet(GinkgoFlagSet{
|
||||||
flags: flags,
|
flags: flags,
|
||||||
bindings: bindings,
|
bindings: bindings,
|
||||||
@@ -335,7 +335,7 @@ func (f GinkgoFlagSet) substituteUsage() {
|
|||||||
fmt.Fprintln(f.flagSet.Output(), f.Usage())
|
fmt.Fprintln(f.flagSet.Output(), f.Usage())
|
||||||
}
|
}
|
||||||
|
|
||||||
func valueAtKeyPath(root interface{}, keyPath string) (reflect.Value, bool) {
|
func valueAtKeyPath(root any, keyPath string) (reflect.Value, bool) {
|
||||||
if len(keyPath) == 0 {
|
if len(keyPath) == 0 {
|
||||||
return reflect.Value{}, false
|
return reflect.Value{}, false
|
||||||
}
|
}
|
||||||
@@ -433,7 +433,7 @@ func (ssv stringSliceVar) Set(s string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured.
|
// given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured.
|
||||||
func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error) {
|
func GenerateFlagArgs(flags GinkgoFlags, bindings any) ([]string, error) {
|
||||||
result := []string{}
|
result := []string{}
|
||||||
for _, flag := range flags {
|
for _, flag := range flags {
|
||||||
name := flag.ExportAs
|
name := flag.ExportAs
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go
generated
vendored
@@ -343,7 +343,7 @@ func tokenize(input string) func() (*treeNode, error) {
|
|||||||
consumeUntil := func(cutset string) (string, int) {
|
consumeUntil := func(cutset string) (string, int) {
|
||||||
j := i
|
j := i
|
||||||
for ; j < len(runes); j++ {
|
for ; j < len(runes); j++ {
|
||||||
if strings.IndexRune(cutset, runes[j]) >= 0 {
|
if strings.ContainsRune(cutset, runes[j]) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
tests/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go
generated
vendored
8
tests/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go
generated
vendored
@@ -9,18 +9,18 @@ import (
|
|||||||
// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports
|
// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports
|
||||||
// and across the network connection when running in parallel
|
// and across the network connection when running in parallel
|
||||||
type ReportEntryValue struct {
|
type ReportEntryValue struct {
|
||||||
raw interface{} //unexported to prevent gob from freaking out about unregistered structs
|
raw any //unexported to prevent gob from freaking out about unregistered structs
|
||||||
AsJSON string
|
AsJSON string
|
||||||
Representation string
|
Representation string
|
||||||
}
|
}
|
||||||
|
|
||||||
func WrapEntryValue(value interface{}) ReportEntryValue {
|
func WrapEntryValue(value any) ReportEntryValue {
|
||||||
return ReportEntryValue{
|
return ReportEntryValue{
|
||||||
raw: value,
|
raw: value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rev ReportEntryValue) GetRawValue() interface{} {
|
func (rev ReportEntryValue) GetRawValue() any {
|
||||||
return rev.raw
|
return rev.raw
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ func (entry ReportEntry) StringRepresentation() string {
|
|||||||
// If used from a rehydrated JSON file _or_ in a ReportAfterSuite when running in parallel this will be
|
// If used from a rehydrated JSON file _or_ in a ReportAfterSuite when running in parallel this will be
|
||||||
// a JSON-decoded {}interface. If you want to reconstitute your original object you can decode the entry.Value.AsJSON
|
// a JSON-decoded {}interface. If you want to reconstitute your original object you can decode the entry.Value.AsJSON
|
||||||
// field yourself.
|
// field yourself.
|
||||||
func (entry ReportEntry) GetRawValue() interface{} {
|
func (entry ReportEntry) GetRawValue() any {
|
||||||
return entry.Value.GetRawValue()
|
return entry.Value.GetRawValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
tests/vendor/github.com/onsi/ginkgo/v2/types/version.go
generated
vendored
2
tests/vendor/github.com/onsi/ginkgo/v2/types/version.go
generated
vendored
@@ -1,3 +1,3 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
const VERSION = "2.22.2"
|
const VERSION = "2.23.0"
|
||||||
|
|||||||
47
tests/vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
47
tests/vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
@@ -25,6 +25,11 @@ const debugHandshake = false
|
|||||||
// quickly.
|
// quickly.
|
||||||
const chanSize = 16
|
const chanSize = 16
|
||||||
|
|
||||||
|
// maxPendingPackets sets the maximum number of packets to queue while waiting
|
||||||
|
// for KEX to complete. This limits the total pending data to maxPendingPackets
|
||||||
|
// * maxPacket bytes, which is ~16.8MB.
|
||||||
|
const maxPendingPackets = 64
|
||||||
|
|
||||||
// keyingTransport is a packet based transport that supports key
|
// keyingTransport is a packet based transport that supports key
|
||||||
// changes. It need not be thread-safe. It should pass through
|
// changes. It need not be thread-safe. It should pass through
|
||||||
// msgNewKeys in both directions.
|
// msgNewKeys in both directions.
|
||||||
@@ -73,11 +78,19 @@ type handshakeTransport struct {
|
|||||||
incoming chan []byte
|
incoming chan []byte
|
||||||
readError error
|
readError error
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
writeError error
|
// Condition for the above mutex. It is used to notify a completed key
|
||||||
sentInitPacket []byte
|
// exchange or a write failure. Writes can wait for this condition while a
|
||||||
sentInitMsg *kexInitMsg
|
// key exchange is in progress.
|
||||||
pendingPackets [][]byte // Used when a key exchange is in progress.
|
writeCond *sync.Cond
|
||||||
|
writeError error
|
||||||
|
sentInitPacket []byte
|
||||||
|
sentInitMsg *kexInitMsg
|
||||||
|
// Used to queue writes when a key exchange is in progress. The length is
|
||||||
|
// limited by pendingPacketsSize. Once full, writes will block until the key
|
||||||
|
// exchange is completed or an error occurs. If not empty, it is emptied
|
||||||
|
// all at once when the key exchange is completed in kexLoop.
|
||||||
|
pendingPackets [][]byte
|
||||||
writePacketsLeft uint32
|
writePacketsLeft uint32
|
||||||
writeBytesLeft int64
|
writeBytesLeft int64
|
||||||
userAuthComplete bool // whether the user authentication phase is complete
|
userAuthComplete bool // whether the user authentication phase is complete
|
||||||
@@ -134,6 +147,7 @@ func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion,
|
|||||||
|
|
||||||
config: config,
|
config: config,
|
||||||
}
|
}
|
||||||
|
t.writeCond = sync.NewCond(&t.mu)
|
||||||
t.resetReadThresholds()
|
t.resetReadThresholds()
|
||||||
t.resetWriteThresholds()
|
t.resetWriteThresholds()
|
||||||
|
|
||||||
@@ -260,6 +274,7 @@ func (t *handshakeTransport) recordWriteError(err error) {
|
|||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
if t.writeError == nil && err != nil {
|
if t.writeError == nil && err != nil {
|
||||||
t.writeError = err
|
t.writeError = err
|
||||||
|
t.writeCond.Broadcast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,6 +378,8 @@ write:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.pendingPackets = t.pendingPackets[:0]
|
t.pendingPackets = t.pendingPackets[:0]
|
||||||
|
// Unblock writePacket if waiting for KEX.
|
||||||
|
t.writeCond.Broadcast()
|
||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,11 +594,20 @@ func (t *handshakeTransport) writePacket(p []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if t.sentInitMsg != nil {
|
if t.sentInitMsg != nil {
|
||||||
// Copy the packet so the writer can reuse the buffer.
|
if len(t.pendingPackets) < maxPendingPackets {
|
||||||
cp := make([]byte, len(p))
|
// Copy the packet so the writer can reuse the buffer.
|
||||||
copy(cp, p)
|
cp := make([]byte, len(p))
|
||||||
t.pendingPackets = append(t.pendingPackets, cp)
|
copy(cp, p)
|
||||||
return nil
|
t.pendingPackets = append(t.pendingPackets, cp)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for t.sentInitMsg != nil {
|
||||||
|
// Block and wait for KEX to complete or an error.
|
||||||
|
t.writeCond.Wait()
|
||||||
|
if t.writeError != nil {
|
||||||
|
return t.writeError
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.writeBytesLeft > 0 {
|
if t.writeBytesLeft > 0 {
|
||||||
@@ -598,6 +624,7 @@ func (t *handshakeTransport) writePacket(p []byte) error {
|
|||||||
|
|
||||||
if err := t.pushPacket(p); err != nil {
|
if err := t.pushPacket(p); err != nil {
|
||||||
t.writeError = err
|
t.writeError = err
|
||||||
|
t.writeCond.Broadcast()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
2
tests/vendor/golang.org/x/crypto/ssh/messages.go
generated
vendored
2
tests/vendor/golang.org/x/crypto/ssh/messages.go
generated
vendored
@@ -818,6 +818,8 @@ func decode(packet []byte) (interface{}, error) {
|
|||||||
return new(userAuthSuccessMsg), nil
|
return new(userAuthSuccessMsg), nil
|
||||||
case msgUserAuthFailure:
|
case msgUserAuthFailure:
|
||||||
msg = new(userAuthFailureMsg)
|
msg = new(userAuthFailureMsg)
|
||||||
|
case msgUserAuthBanner:
|
||||||
|
msg = new(userAuthBannerMsg)
|
||||||
case msgUserAuthPubKeyOk:
|
case msgUserAuthPubKeyOk:
|
||||||
msg = new(userAuthPubKeyOkMsg)
|
msg = new(userAuthPubKeyOkMsg)
|
||||||
case msgGlobalRequest:
|
case msgGlobalRequest:
|
||||||
|
|||||||
2
tests/vendor/golang.org/x/crypto/ssh/tcpip.go
generated
vendored
2
tests/vendor/golang.org/x/crypto/ssh/tcpip.go
generated
vendored
@@ -459,7 +459,7 @@ func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
go DiscardRequests(in)
|
go DiscardRequests(in)
|
||||||
return ch, err
|
return ch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type tcpChan struct {
|
type tcpChan struct {
|
||||||
|
|||||||
2
tests/vendor/golang.org/x/text/language/parse.go
generated
vendored
2
tests/vendor/golang.org/x/text/language/parse.go
generated
vendored
@@ -59,7 +59,7 @@ func (c CanonType) Parse(s string) (t Tag, err error) {
|
|||||||
if changed {
|
if changed {
|
||||||
tt.RemakeString()
|
tt.RemakeString()
|
||||||
}
|
}
|
||||||
return makeTag(tt), err
|
return makeTag(tt), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compose creates a Tag from individual parts, which may be of type Tag, Base,
|
// Compose creates a Tag from individual parts, which may be of type Tag, Base,
|
||||||
|
|||||||
139
tests/vendor/golang.org/x/tools/go/ast/inspector/inspector.go
generated
vendored
139
tests/vendor/golang.org/x/tools/go/ast/inspector/inspector.go
generated
vendored
@@ -36,6 +36,9 @@ package inspector
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/astutil/edge"
|
||||||
)
|
)
|
||||||
|
|
||||||
// An Inspector provides methods for inspecting
|
// An Inspector provides methods for inspecting
|
||||||
@@ -44,6 +47,24 @@ type Inspector struct {
|
|||||||
events []event
|
events []event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname events
|
||||||
|
func events(in *Inspector) []event { return in.events }
|
||||||
|
|
||||||
|
func packEdgeKindAndIndex(ek edge.Kind, index int) int32 {
|
||||||
|
return int32(uint32(index+1)<<7 | uint32(ek))
|
||||||
|
}
|
||||||
|
|
||||||
|
// unpackEdgeKindAndIndex unpacks the edge kind and edge index (within
|
||||||
|
// an []ast.Node slice) from the parent field of a pop event.
|
||||||
|
//
|
||||||
|
//go:linkname unpackEdgeKindAndIndex
|
||||||
|
func unpackEdgeKindAndIndex(x int32) (edge.Kind, int) {
|
||||||
|
// The "parent" field of a pop node holds the
|
||||||
|
// edge Kind in the lower 7 bits and the index+1
|
||||||
|
// in the upper 25.
|
||||||
|
return edge.Kind(x & 0x7f), int(x>>7) - 1
|
||||||
|
}
|
||||||
|
|
||||||
// New returns an Inspector for the specified syntax trees.
|
// New returns an Inspector for the specified syntax trees.
|
||||||
func New(files []*ast.File) *Inspector {
|
func New(files []*ast.File) *Inspector {
|
||||||
return &Inspector{traverse(files)}
|
return &Inspector{traverse(files)}
|
||||||
@@ -52,9 +73,10 @@ func New(files []*ast.File) *Inspector {
|
|||||||
// An event represents a push or a pop
|
// An event represents a push or a pop
|
||||||
// of an ast.Node during a traversal.
|
// of an ast.Node during a traversal.
|
||||||
type event struct {
|
type event struct {
|
||||||
node ast.Node
|
node ast.Node
|
||||||
typ uint64 // typeOf(node) on push event, or union of typ strictly between push and pop events on pop events
|
typ uint64 // typeOf(node) on push event, or union of typ strictly between push and pop events on pop events
|
||||||
index int // index of corresponding push or pop event
|
index int32 // index of corresponding push or pop event
|
||||||
|
parent int32 // index of parent's push node (push nodes only), or packed edge kind/index (pop nodes only)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Experiment with storing only the second word of event.node (unsafe.Pointer).
|
// TODO: Experiment with storing only the second word of event.node (unsafe.Pointer).
|
||||||
@@ -83,7 +105,7 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
|
|||||||
// })
|
// })
|
||||||
|
|
||||||
mask := maskOf(types)
|
mask := maskOf(types)
|
||||||
for i := 0; i < len(in.events); {
|
for i := int32(0); i < int32(len(in.events)); {
|
||||||
ev := in.events[i]
|
ev := in.events[i]
|
||||||
if ev.index > i {
|
if ev.index > i {
|
||||||
// push
|
// push
|
||||||
@@ -113,7 +135,7 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
|
|||||||
// matches an element of the types slice.
|
// matches an element of the types slice.
|
||||||
func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) {
|
func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) {
|
||||||
mask := maskOf(types)
|
mask := maskOf(types)
|
||||||
for i := 0; i < len(in.events); {
|
for i := int32(0); i < int32(len(in.events)); {
|
||||||
ev := in.events[i]
|
ev := in.events[i]
|
||||||
if ev.index > i {
|
if ev.index > i {
|
||||||
// push
|
// push
|
||||||
@@ -147,7 +169,7 @@ func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proc
|
|||||||
func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) {
|
func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) {
|
||||||
mask := maskOf(types)
|
mask := maskOf(types)
|
||||||
var stack []ast.Node
|
var stack []ast.Node
|
||||||
for i := 0; i < len(in.events); {
|
for i := int32(0); i < int32(len(in.events)); {
|
||||||
ev := in.events[i]
|
ev := in.events[i]
|
||||||
if ev.index > i {
|
if ev.index > i {
|
||||||
// push
|
// push
|
||||||
@@ -189,43 +211,74 @@ func traverse(files []*ast.File) []event {
|
|||||||
extent += int(f.End() - f.Pos())
|
extent += int(f.End() - f.Pos())
|
||||||
}
|
}
|
||||||
// This estimate is based on the net/http package.
|
// This estimate is based on the net/http package.
|
||||||
capacity := extent * 33 / 100
|
capacity := min(extent*33/100, 1e6) // impose some reasonable maximum (1M)
|
||||||
if capacity > 1e6 {
|
|
||||||
capacity = 1e6 // impose some reasonable maximum
|
v := &visitor{
|
||||||
|
events: make([]event, 0, capacity),
|
||||||
|
stack: []item{{index: -1}}, // include an extra event so file nodes have a parent
|
||||||
}
|
}
|
||||||
events := make([]event, 0, capacity)
|
for _, file := range files {
|
||||||
|
walk(v, edge.Invalid, -1, file)
|
||||||
var stack []event
|
|
||||||
stack = append(stack, event{}) // include an extra event so file nodes have a parent
|
|
||||||
for _, f := range files {
|
|
||||||
ast.Inspect(f, func(n ast.Node) bool {
|
|
||||||
if n != nil {
|
|
||||||
// push
|
|
||||||
ev := event{
|
|
||||||
node: n,
|
|
||||||
typ: 0, // temporarily used to accumulate type bits of subtree
|
|
||||||
index: len(events), // push event temporarily holds own index
|
|
||||||
}
|
|
||||||
stack = append(stack, ev)
|
|
||||||
events = append(events, ev)
|
|
||||||
} else {
|
|
||||||
// pop
|
|
||||||
top := len(stack) - 1
|
|
||||||
ev := stack[top]
|
|
||||||
typ := typeOf(ev.node)
|
|
||||||
push := ev.index
|
|
||||||
parent := top - 1
|
|
||||||
|
|
||||||
events[push].typ = typ // set type of push
|
|
||||||
stack[parent].typ |= typ | ev.typ // parent's typ contains push and pop's typs.
|
|
||||||
events[push].index = len(events) // make push refer to pop
|
|
||||||
|
|
||||||
stack = stack[:top]
|
|
||||||
events = append(events, ev)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
return v.events
|
||||||
return events
|
}
|
||||||
|
|
||||||
|
type visitor struct {
|
||||||
|
events []event
|
||||||
|
stack []item
|
||||||
|
}
|
||||||
|
|
||||||
|
type item struct {
|
||||||
|
index int32 // index of current node's push event
|
||||||
|
parentIndex int32 // index of parent node's push event
|
||||||
|
typAccum uint64 // accumulated type bits of current node's descendents
|
||||||
|
edgeKindAndIndex int32 // edge.Kind and index, bit packed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *visitor) push(ek edge.Kind, eindex int, node ast.Node) {
|
||||||
|
var (
|
||||||
|
index = int32(len(v.events))
|
||||||
|
parentIndex = v.stack[len(v.stack)-1].index
|
||||||
|
)
|
||||||
|
v.events = append(v.events, event{
|
||||||
|
node: node,
|
||||||
|
parent: parentIndex,
|
||||||
|
typ: typeOf(node),
|
||||||
|
index: 0, // (pop index is set later by visitor.pop)
|
||||||
|
})
|
||||||
|
v.stack = append(v.stack, item{
|
||||||
|
index: index,
|
||||||
|
parentIndex: parentIndex,
|
||||||
|
edgeKindAndIndex: packEdgeKindAndIndex(ek, eindex),
|
||||||
|
})
|
||||||
|
|
||||||
|
// 2B nodes ought to be enough for anyone!
|
||||||
|
if int32(len(v.events)) < 0 {
|
||||||
|
panic("event index exceeded int32")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 32M elements in an []ast.Node ought to be enough for anyone!
|
||||||
|
if ek2, eindex2 := unpackEdgeKindAndIndex(packEdgeKindAndIndex(ek, eindex)); ek2 != ek || eindex2 != eindex {
|
||||||
|
panic("Node slice index exceeded uint25")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *visitor) pop(node ast.Node) {
|
||||||
|
top := len(v.stack) - 1
|
||||||
|
current := v.stack[top]
|
||||||
|
|
||||||
|
push := &v.events[current.index]
|
||||||
|
parent := &v.stack[top-1]
|
||||||
|
|
||||||
|
push.index = int32(len(v.events)) // make push event refer to pop
|
||||||
|
parent.typAccum |= current.typAccum | push.typ // accumulate type bits into parent
|
||||||
|
|
||||||
|
v.stack = v.stack[:top]
|
||||||
|
|
||||||
|
v.events = append(v.events, event{
|
||||||
|
node: node,
|
||||||
|
typ: current.typAccum,
|
||||||
|
index: current.index,
|
||||||
|
parent: current.edgeKindAndIndex, // see [unpackEdgeKindAndIndex]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
4
tests/vendor/golang.org/x/tools/go/ast/inspector/iter.go
generated
vendored
4
tests/vendor/golang.org/x/tools/go/ast/inspector/iter.go
generated
vendored
@@ -26,7 +26,7 @@ func (in *Inspector) PreorderSeq(types ...ast.Node) iter.Seq[ast.Node] {
|
|||||||
|
|
||||||
return func(yield func(ast.Node) bool) {
|
return func(yield func(ast.Node) bool) {
|
||||||
mask := maskOf(types)
|
mask := maskOf(types)
|
||||||
for i := 0; i < len(in.events); {
|
for i := int32(0); i < int32(len(in.events)); {
|
||||||
ev := in.events[i]
|
ev := in.events[i]
|
||||||
if ev.index > i {
|
if ev.index > i {
|
||||||
// push
|
// push
|
||||||
@@ -63,7 +63,7 @@ func All[N interface {
|
|||||||
|
|
||||||
mask := typeOf((N)(nil))
|
mask := typeOf((N)(nil))
|
||||||
return func(yield func(N) bool) {
|
return func(yield func(N) bool) {
|
||||||
for i := 0; i < len(in.events); {
|
for i := int32(0); i < int32(len(in.events)); {
|
||||||
ev := in.events[i]
|
ev := in.events[i]
|
||||||
if ev.index > i {
|
if ev.index > i {
|
||||||
// push
|
// push
|
||||||
|
|||||||
5
tests/vendor/golang.org/x/tools/go/ast/inspector/typeof.go
generated
vendored
5
tests/vendor/golang.org/x/tools/go/ast/inspector/typeof.go
generated
vendored
@@ -12,6 +12,8 @@ package inspector
|
|||||||
import (
|
import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
_ "unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -215,8 +217,9 @@ func typeOf(n ast.Node) uint64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname maskOf
|
||||||
func maskOf(nodes []ast.Node) uint64 {
|
func maskOf(nodes []ast.Node) uint64 {
|
||||||
if nodes == nil {
|
if len(nodes) == 0 {
|
||||||
return math.MaxUint64 // match all node types
|
return math.MaxUint64 // match all node types
|
||||||
}
|
}
|
||||||
var mask uint64
|
var mask uint64
|
||||||
|
|||||||
341
tests/vendor/golang.org/x/tools/go/ast/inspector/walk.go
generated
vendored
Normal file
341
tests/vendor/golang.org/x/tools/go/ast/inspector/walk.go
generated
vendored
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package inspector
|
||||||
|
|
||||||
|
// This file is a fork of ast.Inspect to reduce unnecessary dynamic
|
||||||
|
// calls and to gather edge information.
|
||||||
|
//
|
||||||
|
// Consistency with the original is ensured by TestInspectAllNodes.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/astutil/edge"
|
||||||
|
)
|
||||||
|
|
||||||
|
func walkList[N ast.Node](v *visitor, ek edge.Kind, list []N) {
|
||||||
|
for i, node := range list {
|
||||||
|
walk(v, ek, i, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func walk(v *visitor, ek edge.Kind, index int, node ast.Node) {
|
||||||
|
v.push(ek, index, node)
|
||||||
|
|
||||||
|
// walk children
|
||||||
|
// (the order of the cases matches the order
|
||||||
|
// of the corresponding node types in ast.go)
|
||||||
|
switch n := node.(type) {
|
||||||
|
// Comments and fields
|
||||||
|
case *ast.Comment:
|
||||||
|
// nothing to do
|
||||||
|
|
||||||
|
case *ast.CommentGroup:
|
||||||
|
walkList(v, edge.CommentGroup_List, n.List)
|
||||||
|
|
||||||
|
case *ast.Field:
|
||||||
|
if n.Doc != nil {
|
||||||
|
walk(v, edge.Field_Doc, -1, n.Doc)
|
||||||
|
}
|
||||||
|
walkList(v, edge.Field_Names, n.Names)
|
||||||
|
if n.Type != nil {
|
||||||
|
walk(v, edge.Field_Type, -1, n.Type)
|
||||||
|
}
|
||||||
|
if n.Tag != nil {
|
||||||
|
walk(v, edge.Field_Tag, -1, n.Tag)
|
||||||
|
}
|
||||||
|
if n.Comment != nil {
|
||||||
|
walk(v, edge.Field_Comment, -1, n.Comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.FieldList:
|
||||||
|
walkList(v, edge.FieldList_List, n.List)
|
||||||
|
|
||||||
|
// Expressions
|
||||||
|
case *ast.BadExpr, *ast.Ident, *ast.BasicLit:
|
||||||
|
// nothing to do
|
||||||
|
|
||||||
|
case *ast.Ellipsis:
|
||||||
|
if n.Elt != nil {
|
||||||
|
walk(v, edge.Ellipsis_Elt, -1, n.Elt)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.FuncLit:
|
||||||
|
walk(v, edge.FuncLit_Type, -1, n.Type)
|
||||||
|
walk(v, edge.FuncLit_Body, -1, n.Body)
|
||||||
|
|
||||||
|
case *ast.CompositeLit:
|
||||||
|
if n.Type != nil {
|
||||||
|
walk(v, edge.CompositeLit_Type, -1, n.Type)
|
||||||
|
}
|
||||||
|
walkList(v, edge.CompositeLit_Elts, n.Elts)
|
||||||
|
|
||||||
|
case *ast.ParenExpr:
|
||||||
|
walk(v, edge.ParenExpr_X, -1, n.X)
|
||||||
|
|
||||||
|
case *ast.SelectorExpr:
|
||||||
|
walk(v, edge.SelectorExpr_X, -1, n.X)
|
||||||
|
walk(v, edge.SelectorExpr_Sel, -1, n.Sel)
|
||||||
|
|
||||||
|
case *ast.IndexExpr:
|
||||||
|
walk(v, edge.IndexExpr_X, -1, n.X)
|
||||||
|
walk(v, edge.IndexExpr_Index, -1, n.Index)
|
||||||
|
|
||||||
|
case *ast.IndexListExpr:
|
||||||
|
walk(v, edge.IndexListExpr_X, -1, n.X)
|
||||||
|
walkList(v, edge.IndexListExpr_Indices, n.Indices)
|
||||||
|
|
||||||
|
case *ast.SliceExpr:
|
||||||
|
walk(v, edge.SliceExpr_X, -1, n.X)
|
||||||
|
if n.Low != nil {
|
||||||
|
walk(v, edge.SliceExpr_Low, -1, n.Low)
|
||||||
|
}
|
||||||
|
if n.High != nil {
|
||||||
|
walk(v, edge.SliceExpr_High, -1, n.High)
|
||||||
|
}
|
||||||
|
if n.Max != nil {
|
||||||
|
walk(v, edge.SliceExpr_Max, -1, n.Max)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.TypeAssertExpr:
|
||||||
|
walk(v, edge.TypeAssertExpr_X, -1, n.X)
|
||||||
|
if n.Type != nil {
|
||||||
|
walk(v, edge.TypeAssertExpr_Type, -1, n.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.CallExpr:
|
||||||
|
walk(v, edge.CallExpr_Fun, -1, n.Fun)
|
||||||
|
walkList(v, edge.CallExpr_Args, n.Args)
|
||||||
|
|
||||||
|
case *ast.StarExpr:
|
||||||
|
walk(v, edge.StarExpr_X, -1, n.X)
|
||||||
|
|
||||||
|
case *ast.UnaryExpr:
|
||||||
|
walk(v, edge.UnaryExpr_X, -1, n.X)
|
||||||
|
|
||||||
|
case *ast.BinaryExpr:
|
||||||
|
walk(v, edge.BinaryExpr_X, -1, n.X)
|
||||||
|
walk(v, edge.BinaryExpr_Y, -1, n.Y)
|
||||||
|
|
||||||
|
case *ast.KeyValueExpr:
|
||||||
|
walk(v, edge.KeyValueExpr_Key, -1, n.Key)
|
||||||
|
walk(v, edge.KeyValueExpr_Value, -1, n.Value)
|
||||||
|
|
||||||
|
// Types
|
||||||
|
case *ast.ArrayType:
|
||||||
|
if n.Len != nil {
|
||||||
|
walk(v, edge.ArrayType_Len, -1, n.Len)
|
||||||
|
}
|
||||||
|
walk(v, edge.ArrayType_Elt, -1, n.Elt)
|
||||||
|
|
||||||
|
case *ast.StructType:
|
||||||
|
walk(v, edge.StructType_Fields, -1, n.Fields)
|
||||||
|
|
||||||
|
case *ast.FuncType:
|
||||||
|
if n.TypeParams != nil {
|
||||||
|
walk(v, edge.FuncType_TypeParams, -1, n.TypeParams)
|
||||||
|
}
|
||||||
|
if n.Params != nil {
|
||||||
|
walk(v, edge.FuncType_Params, -1, n.Params)
|
||||||
|
}
|
||||||
|
if n.Results != nil {
|
||||||
|
walk(v, edge.FuncType_Results, -1, n.Results)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.InterfaceType:
|
||||||
|
walk(v, edge.InterfaceType_Methods, -1, n.Methods)
|
||||||
|
|
||||||
|
case *ast.MapType:
|
||||||
|
walk(v, edge.MapType_Key, -1, n.Key)
|
||||||
|
walk(v, edge.MapType_Value, -1, n.Value)
|
||||||
|
|
||||||
|
case *ast.ChanType:
|
||||||
|
walk(v, edge.ChanType_Value, -1, n.Value)
|
||||||
|
|
||||||
|
// Statements
|
||||||
|
case *ast.BadStmt:
|
||||||
|
// nothing to do
|
||||||
|
|
||||||
|
case *ast.DeclStmt:
|
||||||
|
walk(v, edge.DeclStmt_Decl, -1, n.Decl)
|
||||||
|
|
||||||
|
case *ast.EmptyStmt:
|
||||||
|
// nothing to do
|
||||||
|
|
||||||
|
case *ast.LabeledStmt:
|
||||||
|
walk(v, edge.LabeledStmt_Label, -1, n.Label)
|
||||||
|
walk(v, edge.LabeledStmt_Stmt, -1, n.Stmt)
|
||||||
|
|
||||||
|
case *ast.ExprStmt:
|
||||||
|
walk(v, edge.ExprStmt_X, -1, n.X)
|
||||||
|
|
||||||
|
case *ast.SendStmt:
|
||||||
|
walk(v, edge.SendStmt_Chan, -1, n.Chan)
|
||||||
|
walk(v, edge.SendStmt_Value, -1, n.Value)
|
||||||
|
|
||||||
|
case *ast.IncDecStmt:
|
||||||
|
walk(v, edge.IncDecStmt_X, -1, n.X)
|
||||||
|
|
||||||
|
case *ast.AssignStmt:
|
||||||
|
walkList(v, edge.AssignStmt_Lhs, n.Lhs)
|
||||||
|
walkList(v, edge.AssignStmt_Rhs, n.Rhs)
|
||||||
|
|
||||||
|
case *ast.GoStmt:
|
||||||
|
walk(v, edge.GoStmt_Call, -1, n.Call)
|
||||||
|
|
||||||
|
case *ast.DeferStmt:
|
||||||
|
walk(v, edge.DeferStmt_Call, -1, n.Call)
|
||||||
|
|
||||||
|
case *ast.ReturnStmt:
|
||||||
|
walkList(v, edge.ReturnStmt_Results, n.Results)
|
||||||
|
|
||||||
|
case *ast.BranchStmt:
|
||||||
|
if n.Label != nil {
|
||||||
|
walk(v, edge.BranchStmt_Label, -1, n.Label)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.BlockStmt:
|
||||||
|
walkList(v, edge.BlockStmt_List, n.List)
|
||||||
|
|
||||||
|
case *ast.IfStmt:
|
||||||
|
if n.Init != nil {
|
||||||
|
walk(v, edge.IfStmt_Init, -1, n.Init)
|
||||||
|
}
|
||||||
|
walk(v, edge.IfStmt_Cond, -1, n.Cond)
|
||||||
|
walk(v, edge.IfStmt_Body, -1, n.Body)
|
||||||
|
if n.Else != nil {
|
||||||
|
walk(v, edge.IfStmt_Else, -1, n.Else)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.CaseClause:
|
||||||
|
walkList(v, edge.CaseClause_List, n.List)
|
||||||
|
walkList(v, edge.CaseClause_Body, n.Body)
|
||||||
|
|
||||||
|
case *ast.SwitchStmt:
|
||||||
|
if n.Init != nil {
|
||||||
|
walk(v, edge.SwitchStmt_Init, -1, n.Init)
|
||||||
|
}
|
||||||
|
if n.Tag != nil {
|
||||||
|
walk(v, edge.SwitchStmt_Tag, -1, n.Tag)
|
||||||
|
}
|
||||||
|
walk(v, edge.SwitchStmt_Body, -1, n.Body)
|
||||||
|
|
||||||
|
case *ast.TypeSwitchStmt:
|
||||||
|
if n.Init != nil {
|
||||||
|
walk(v, edge.TypeSwitchStmt_Init, -1, n.Init)
|
||||||
|
}
|
||||||
|
walk(v, edge.TypeSwitchStmt_Assign, -1, n.Assign)
|
||||||
|
walk(v, edge.TypeSwitchStmt_Body, -1, n.Body)
|
||||||
|
|
||||||
|
case *ast.CommClause:
|
||||||
|
if n.Comm != nil {
|
||||||
|
walk(v, edge.CommClause_Comm, -1, n.Comm)
|
||||||
|
}
|
||||||
|
walkList(v, edge.CommClause_Body, n.Body)
|
||||||
|
|
||||||
|
case *ast.SelectStmt:
|
||||||
|
walk(v, edge.SelectStmt_Body, -1, n.Body)
|
||||||
|
|
||||||
|
case *ast.ForStmt:
|
||||||
|
if n.Init != nil {
|
||||||
|
walk(v, edge.ForStmt_Init, -1, n.Init)
|
||||||
|
}
|
||||||
|
if n.Cond != nil {
|
||||||
|
walk(v, edge.ForStmt_Cond, -1, n.Cond)
|
||||||
|
}
|
||||||
|
if n.Post != nil {
|
||||||
|
walk(v, edge.ForStmt_Post, -1, n.Post)
|
||||||
|
}
|
||||||
|
walk(v, edge.ForStmt_Body, -1, n.Body)
|
||||||
|
|
||||||
|
case *ast.RangeStmt:
|
||||||
|
if n.Key != nil {
|
||||||
|
walk(v, edge.RangeStmt_Key, -1, n.Key)
|
||||||
|
}
|
||||||
|
if n.Value != nil {
|
||||||
|
walk(v, edge.RangeStmt_Value, -1, n.Value)
|
||||||
|
}
|
||||||
|
walk(v, edge.RangeStmt_X, -1, n.X)
|
||||||
|
walk(v, edge.RangeStmt_Body, -1, n.Body)
|
||||||
|
|
||||||
|
// Declarations
|
||||||
|
case *ast.ImportSpec:
|
||||||
|
if n.Doc != nil {
|
||||||
|
walk(v, edge.ImportSpec_Doc, -1, n.Doc)
|
||||||
|
}
|
||||||
|
if n.Name != nil {
|
||||||
|
walk(v, edge.ImportSpec_Name, -1, n.Name)
|
||||||
|
}
|
||||||
|
walk(v, edge.ImportSpec_Path, -1, n.Path)
|
||||||
|
if n.Comment != nil {
|
||||||
|
walk(v, edge.ImportSpec_Comment, -1, n.Comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.ValueSpec:
|
||||||
|
if n.Doc != nil {
|
||||||
|
walk(v, edge.ValueSpec_Doc, -1, n.Doc)
|
||||||
|
}
|
||||||
|
walkList(v, edge.ValueSpec_Names, n.Names)
|
||||||
|
if n.Type != nil {
|
||||||
|
walk(v, edge.ValueSpec_Type, -1, n.Type)
|
||||||
|
}
|
||||||
|
walkList(v, edge.ValueSpec_Values, n.Values)
|
||||||
|
if n.Comment != nil {
|
||||||
|
walk(v, edge.ValueSpec_Comment, -1, n.Comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.TypeSpec:
|
||||||
|
if n.Doc != nil {
|
||||||
|
walk(v, edge.TypeSpec_Doc, -1, n.Doc)
|
||||||
|
}
|
||||||
|
walk(v, edge.TypeSpec_Name, -1, n.Name)
|
||||||
|
if n.TypeParams != nil {
|
||||||
|
walk(v, edge.TypeSpec_TypeParams, -1, n.TypeParams)
|
||||||
|
}
|
||||||
|
walk(v, edge.TypeSpec_Type, -1, n.Type)
|
||||||
|
if n.Comment != nil {
|
||||||
|
walk(v, edge.TypeSpec_Comment, -1, n.Comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.BadDecl:
|
||||||
|
// nothing to do
|
||||||
|
|
||||||
|
case *ast.GenDecl:
|
||||||
|
if n.Doc != nil {
|
||||||
|
walk(v, edge.GenDecl_Doc, -1, n.Doc)
|
||||||
|
}
|
||||||
|
walkList(v, edge.GenDecl_Specs, n.Specs)
|
||||||
|
|
||||||
|
case *ast.FuncDecl:
|
||||||
|
if n.Doc != nil {
|
||||||
|
walk(v, edge.FuncDecl_Doc, -1, n.Doc)
|
||||||
|
}
|
||||||
|
if n.Recv != nil {
|
||||||
|
walk(v, edge.FuncDecl_Recv, -1, n.Recv)
|
||||||
|
}
|
||||||
|
walk(v, edge.FuncDecl_Name, -1, n.Name)
|
||||||
|
walk(v, edge.FuncDecl_Type, -1, n.Type)
|
||||||
|
if n.Body != nil {
|
||||||
|
walk(v, edge.FuncDecl_Body, -1, n.Body)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *ast.File:
|
||||||
|
if n.Doc != nil {
|
||||||
|
walk(v, edge.File_Doc, -1, n.Doc)
|
||||||
|
}
|
||||||
|
walk(v, edge.File_Name, -1, n.Name)
|
||||||
|
walkList(v, edge.File_Decls, n.Decls)
|
||||||
|
// don't walk n.Comments - they have been
|
||||||
|
// visited already through the individual
|
||||||
|
// nodes
|
||||||
|
|
||||||
|
default:
|
||||||
|
// (includes *ast.Package)
|
||||||
|
panic(fmt.Sprintf("Walk: unexpected node type %T", n))
|
||||||
|
}
|
||||||
|
|
||||||
|
v.pop(node)
|
||||||
|
}
|
||||||
295
tests/vendor/golang.org/x/tools/internal/astutil/edge/edge.go
generated
vendored
Normal file
295
tests/vendor/golang.org/x/tools/internal/astutil/edge/edge.go
generated
vendored
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package edge defines identifiers for each field of an ast.Node
|
||||||
|
// struct type that refers to another Node.
|
||||||
|
package edge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Kind describes a field of an ast.Node struct.
|
||||||
|
type Kind uint8
|
||||||
|
|
||||||
|
// String returns a description of the edge kind.
|
||||||
|
func (k Kind) String() string {
|
||||||
|
if k == Invalid {
|
||||||
|
return "<invalid>"
|
||||||
|
}
|
||||||
|
info := fieldInfos[k]
|
||||||
|
return fmt.Sprintf("%v.%s", info.nodeType.Elem().Name(), info.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeType returns the pointer-to-struct type of the ast.Node implementation.
|
||||||
|
func (k Kind) NodeType() reflect.Type { return fieldInfos[k].nodeType }
|
||||||
|
|
||||||
|
// FieldName returns the name of the field.
|
||||||
|
func (k Kind) FieldName() string { return fieldInfos[k].name }
|
||||||
|
|
||||||
|
// FieldType returns the declared type of the field.
|
||||||
|
func (k Kind) FieldType() reflect.Type { return fieldInfos[k].fieldType }
|
||||||
|
|
||||||
|
// Get returns the direct child of n identified by (k, idx).
|
||||||
|
// n's type must match k.NodeType().
|
||||||
|
// idx must be a valid slice index, or -1 for a non-slice.
|
||||||
|
func (k Kind) Get(n ast.Node, idx int) ast.Node {
|
||||||
|
if k.NodeType() != reflect.TypeOf(n) {
|
||||||
|
panic(fmt.Sprintf("%v.Get(%T): invalid node type", k, n))
|
||||||
|
}
|
||||||
|
v := reflect.ValueOf(n).Elem().Field(fieldInfos[k].index)
|
||||||
|
if idx != -1 {
|
||||||
|
v = v.Index(idx) // asserts valid index
|
||||||
|
} else {
|
||||||
|
// (The type assertion below asserts that v is not a slice.)
|
||||||
|
}
|
||||||
|
return v.Interface().(ast.Node) // may be nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
Invalid Kind = iota // for nodes at the root of the traversal
|
||||||
|
|
||||||
|
// Kinds are sorted alphabetically.
|
||||||
|
// Numbering is not stable.
|
||||||
|
// Each is named Type_Field, where Type is the
|
||||||
|
// ast.Node struct type and Field is the name of the field
|
||||||
|
|
||||||
|
ArrayType_Elt
|
||||||
|
ArrayType_Len
|
||||||
|
AssignStmt_Lhs
|
||||||
|
AssignStmt_Rhs
|
||||||
|
BinaryExpr_X
|
||||||
|
BinaryExpr_Y
|
||||||
|
BlockStmt_List
|
||||||
|
BranchStmt_Label
|
||||||
|
CallExpr_Args
|
||||||
|
CallExpr_Fun
|
||||||
|
CaseClause_Body
|
||||||
|
CaseClause_List
|
||||||
|
ChanType_Value
|
||||||
|
CommClause_Body
|
||||||
|
CommClause_Comm
|
||||||
|
CommentGroup_List
|
||||||
|
CompositeLit_Elts
|
||||||
|
CompositeLit_Type
|
||||||
|
DeclStmt_Decl
|
||||||
|
DeferStmt_Call
|
||||||
|
Ellipsis_Elt
|
||||||
|
ExprStmt_X
|
||||||
|
FieldList_List
|
||||||
|
Field_Comment
|
||||||
|
Field_Doc
|
||||||
|
Field_Names
|
||||||
|
Field_Tag
|
||||||
|
Field_Type
|
||||||
|
File_Decls
|
||||||
|
File_Doc
|
||||||
|
File_Name
|
||||||
|
ForStmt_Body
|
||||||
|
ForStmt_Cond
|
||||||
|
ForStmt_Init
|
||||||
|
ForStmt_Post
|
||||||
|
FuncDecl_Body
|
||||||
|
FuncDecl_Doc
|
||||||
|
FuncDecl_Name
|
||||||
|
FuncDecl_Recv
|
||||||
|
FuncDecl_Type
|
||||||
|
FuncLit_Body
|
||||||
|
FuncLit_Type
|
||||||
|
FuncType_Params
|
||||||
|
FuncType_Results
|
||||||
|
FuncType_TypeParams
|
||||||
|
GenDecl_Doc
|
||||||
|
GenDecl_Specs
|
||||||
|
GoStmt_Call
|
||||||
|
IfStmt_Body
|
||||||
|
IfStmt_Cond
|
||||||
|
IfStmt_Else
|
||||||
|
IfStmt_Init
|
||||||
|
ImportSpec_Comment
|
||||||
|
ImportSpec_Doc
|
||||||
|
ImportSpec_Name
|
||||||
|
ImportSpec_Path
|
||||||
|
IncDecStmt_X
|
||||||
|
IndexExpr_Index
|
||||||
|
IndexExpr_X
|
||||||
|
IndexListExpr_Indices
|
||||||
|
IndexListExpr_X
|
||||||
|
InterfaceType_Methods
|
||||||
|
KeyValueExpr_Key
|
||||||
|
KeyValueExpr_Value
|
||||||
|
LabeledStmt_Label
|
||||||
|
LabeledStmt_Stmt
|
||||||
|
MapType_Key
|
||||||
|
MapType_Value
|
||||||
|
ParenExpr_X
|
||||||
|
RangeStmt_Body
|
||||||
|
RangeStmt_Key
|
||||||
|
RangeStmt_Value
|
||||||
|
RangeStmt_X
|
||||||
|
ReturnStmt_Results
|
||||||
|
SelectStmt_Body
|
||||||
|
SelectorExpr_Sel
|
||||||
|
SelectorExpr_X
|
||||||
|
SendStmt_Chan
|
||||||
|
SendStmt_Value
|
||||||
|
SliceExpr_High
|
||||||
|
SliceExpr_Low
|
||||||
|
SliceExpr_Max
|
||||||
|
SliceExpr_X
|
||||||
|
StarExpr_X
|
||||||
|
StructType_Fields
|
||||||
|
SwitchStmt_Body
|
||||||
|
SwitchStmt_Init
|
||||||
|
SwitchStmt_Tag
|
||||||
|
TypeAssertExpr_Type
|
||||||
|
TypeAssertExpr_X
|
||||||
|
TypeSpec_Comment
|
||||||
|
TypeSpec_Doc
|
||||||
|
TypeSpec_Name
|
||||||
|
TypeSpec_Type
|
||||||
|
TypeSpec_TypeParams
|
||||||
|
TypeSwitchStmt_Assign
|
||||||
|
TypeSwitchStmt_Body
|
||||||
|
TypeSwitchStmt_Init
|
||||||
|
UnaryExpr_X
|
||||||
|
ValueSpec_Comment
|
||||||
|
ValueSpec_Doc
|
||||||
|
ValueSpec_Names
|
||||||
|
ValueSpec_Type
|
||||||
|
ValueSpec_Values
|
||||||
|
|
||||||
|
maxKind
|
||||||
|
)
|
||||||
|
|
||||||
|
// Assert that the encoding fits in 7 bits,
|
||||||
|
// as the inspector relies on this.
|
||||||
|
// (We are currently at 104.)
|
||||||
|
var _ = [1 << 7]struct{}{}[maxKind]
|
||||||
|
|
||||||
|
type fieldInfo struct {
|
||||||
|
nodeType reflect.Type // pointer-to-struct type of ast.Node implementation
|
||||||
|
name string
|
||||||
|
index int
|
||||||
|
fieldType reflect.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func info[N ast.Node](fieldName string) fieldInfo {
|
||||||
|
nodePtrType := reflect.TypeFor[N]()
|
||||||
|
f, ok := nodePtrType.Elem().FieldByName(fieldName)
|
||||||
|
if !ok {
|
||||||
|
panic(fieldName)
|
||||||
|
}
|
||||||
|
return fieldInfo{nodePtrType, fieldName, f.Index[0], f.Type}
|
||||||
|
}
|
||||||
|
|
||||||
|
var fieldInfos = [...]fieldInfo{
|
||||||
|
Invalid: {},
|
||||||
|
ArrayType_Elt: info[*ast.ArrayType]("Elt"),
|
||||||
|
ArrayType_Len: info[*ast.ArrayType]("Len"),
|
||||||
|
AssignStmt_Lhs: info[*ast.AssignStmt]("Lhs"),
|
||||||
|
AssignStmt_Rhs: info[*ast.AssignStmt]("Rhs"),
|
||||||
|
BinaryExpr_X: info[*ast.BinaryExpr]("X"),
|
||||||
|
BinaryExpr_Y: info[*ast.BinaryExpr]("Y"),
|
||||||
|
BlockStmt_List: info[*ast.BlockStmt]("List"),
|
||||||
|
BranchStmt_Label: info[*ast.BranchStmt]("Label"),
|
||||||
|
CallExpr_Args: info[*ast.CallExpr]("Args"),
|
||||||
|
CallExpr_Fun: info[*ast.CallExpr]("Fun"),
|
||||||
|
CaseClause_Body: info[*ast.CaseClause]("Body"),
|
||||||
|
CaseClause_List: info[*ast.CaseClause]("List"),
|
||||||
|
ChanType_Value: info[*ast.ChanType]("Value"),
|
||||||
|
CommClause_Body: info[*ast.CommClause]("Body"),
|
||||||
|
CommClause_Comm: info[*ast.CommClause]("Comm"),
|
||||||
|
CommentGroup_List: info[*ast.CommentGroup]("List"),
|
||||||
|
CompositeLit_Elts: info[*ast.CompositeLit]("Elts"),
|
||||||
|
CompositeLit_Type: info[*ast.CompositeLit]("Type"),
|
||||||
|
DeclStmt_Decl: info[*ast.DeclStmt]("Decl"),
|
||||||
|
DeferStmt_Call: info[*ast.DeferStmt]("Call"),
|
||||||
|
Ellipsis_Elt: info[*ast.Ellipsis]("Elt"),
|
||||||
|
ExprStmt_X: info[*ast.ExprStmt]("X"),
|
||||||
|
FieldList_List: info[*ast.FieldList]("List"),
|
||||||
|
Field_Comment: info[*ast.Field]("Comment"),
|
||||||
|
Field_Doc: info[*ast.Field]("Doc"),
|
||||||
|
Field_Names: info[*ast.Field]("Names"),
|
||||||
|
Field_Tag: info[*ast.Field]("Tag"),
|
||||||
|
Field_Type: info[*ast.Field]("Type"),
|
||||||
|
File_Decls: info[*ast.File]("Decls"),
|
||||||
|
File_Doc: info[*ast.File]("Doc"),
|
||||||
|
File_Name: info[*ast.File]("Name"),
|
||||||
|
ForStmt_Body: info[*ast.ForStmt]("Body"),
|
||||||
|
ForStmt_Cond: info[*ast.ForStmt]("Cond"),
|
||||||
|
ForStmt_Init: info[*ast.ForStmt]("Init"),
|
||||||
|
ForStmt_Post: info[*ast.ForStmt]("Post"),
|
||||||
|
FuncDecl_Body: info[*ast.FuncDecl]("Body"),
|
||||||
|
FuncDecl_Doc: info[*ast.FuncDecl]("Doc"),
|
||||||
|
FuncDecl_Name: info[*ast.FuncDecl]("Name"),
|
||||||
|
FuncDecl_Recv: info[*ast.FuncDecl]("Recv"),
|
||||||
|
FuncDecl_Type: info[*ast.FuncDecl]("Type"),
|
||||||
|
FuncLit_Body: info[*ast.FuncLit]("Body"),
|
||||||
|
FuncLit_Type: info[*ast.FuncLit]("Type"),
|
||||||
|
FuncType_Params: info[*ast.FuncType]("Params"),
|
||||||
|
FuncType_Results: info[*ast.FuncType]("Results"),
|
||||||
|
FuncType_TypeParams: info[*ast.FuncType]("TypeParams"),
|
||||||
|
GenDecl_Doc: info[*ast.GenDecl]("Doc"),
|
||||||
|
GenDecl_Specs: info[*ast.GenDecl]("Specs"),
|
||||||
|
GoStmt_Call: info[*ast.GoStmt]("Call"),
|
||||||
|
IfStmt_Body: info[*ast.IfStmt]("Body"),
|
||||||
|
IfStmt_Cond: info[*ast.IfStmt]("Cond"),
|
||||||
|
IfStmt_Else: info[*ast.IfStmt]("Else"),
|
||||||
|
IfStmt_Init: info[*ast.IfStmt]("Init"),
|
||||||
|
ImportSpec_Comment: info[*ast.ImportSpec]("Comment"),
|
||||||
|
ImportSpec_Doc: info[*ast.ImportSpec]("Doc"),
|
||||||
|
ImportSpec_Name: info[*ast.ImportSpec]("Name"),
|
||||||
|
ImportSpec_Path: info[*ast.ImportSpec]("Path"),
|
||||||
|
IncDecStmt_X: info[*ast.IncDecStmt]("X"),
|
||||||
|
IndexExpr_Index: info[*ast.IndexExpr]("Index"),
|
||||||
|
IndexExpr_X: info[*ast.IndexExpr]("X"),
|
||||||
|
IndexListExpr_Indices: info[*ast.IndexListExpr]("Indices"),
|
||||||
|
IndexListExpr_X: info[*ast.IndexListExpr]("X"),
|
||||||
|
InterfaceType_Methods: info[*ast.InterfaceType]("Methods"),
|
||||||
|
KeyValueExpr_Key: info[*ast.KeyValueExpr]("Key"),
|
||||||
|
KeyValueExpr_Value: info[*ast.KeyValueExpr]("Value"),
|
||||||
|
LabeledStmt_Label: info[*ast.LabeledStmt]("Label"),
|
||||||
|
LabeledStmt_Stmt: info[*ast.LabeledStmt]("Stmt"),
|
||||||
|
MapType_Key: info[*ast.MapType]("Key"),
|
||||||
|
MapType_Value: info[*ast.MapType]("Value"),
|
||||||
|
ParenExpr_X: info[*ast.ParenExpr]("X"),
|
||||||
|
RangeStmt_Body: info[*ast.RangeStmt]("Body"),
|
||||||
|
RangeStmt_Key: info[*ast.RangeStmt]("Key"),
|
||||||
|
RangeStmt_Value: info[*ast.RangeStmt]("Value"),
|
||||||
|
RangeStmt_X: info[*ast.RangeStmt]("X"),
|
||||||
|
ReturnStmt_Results: info[*ast.ReturnStmt]("Results"),
|
||||||
|
SelectStmt_Body: info[*ast.SelectStmt]("Body"),
|
||||||
|
SelectorExpr_Sel: info[*ast.SelectorExpr]("Sel"),
|
||||||
|
SelectorExpr_X: info[*ast.SelectorExpr]("X"),
|
||||||
|
SendStmt_Chan: info[*ast.SendStmt]("Chan"),
|
||||||
|
SendStmt_Value: info[*ast.SendStmt]("Value"),
|
||||||
|
SliceExpr_High: info[*ast.SliceExpr]("High"),
|
||||||
|
SliceExpr_Low: info[*ast.SliceExpr]("Low"),
|
||||||
|
SliceExpr_Max: info[*ast.SliceExpr]("Max"),
|
||||||
|
SliceExpr_X: info[*ast.SliceExpr]("X"),
|
||||||
|
StarExpr_X: info[*ast.StarExpr]("X"),
|
||||||
|
StructType_Fields: info[*ast.StructType]("Fields"),
|
||||||
|
SwitchStmt_Body: info[*ast.SwitchStmt]("Body"),
|
||||||
|
SwitchStmt_Init: info[*ast.SwitchStmt]("Init"),
|
||||||
|
SwitchStmt_Tag: info[*ast.SwitchStmt]("Tag"),
|
||||||
|
TypeAssertExpr_Type: info[*ast.TypeAssertExpr]("Type"),
|
||||||
|
TypeAssertExpr_X: info[*ast.TypeAssertExpr]("X"),
|
||||||
|
TypeSpec_Comment: info[*ast.TypeSpec]("Comment"),
|
||||||
|
TypeSpec_Doc: info[*ast.TypeSpec]("Doc"),
|
||||||
|
TypeSpec_Name: info[*ast.TypeSpec]("Name"),
|
||||||
|
TypeSpec_Type: info[*ast.TypeSpec]("Type"),
|
||||||
|
TypeSpec_TypeParams: info[*ast.TypeSpec]("TypeParams"),
|
||||||
|
TypeSwitchStmt_Assign: info[*ast.TypeSwitchStmt]("Assign"),
|
||||||
|
TypeSwitchStmt_Body: info[*ast.TypeSwitchStmt]("Body"),
|
||||||
|
TypeSwitchStmt_Init: info[*ast.TypeSwitchStmt]("Init"),
|
||||||
|
UnaryExpr_X: info[*ast.UnaryExpr]("X"),
|
||||||
|
ValueSpec_Comment: info[*ast.ValueSpec]("Comment"),
|
||||||
|
ValueSpec_Doc: info[*ast.ValueSpec]("Doc"),
|
||||||
|
ValueSpec_Names: info[*ast.ValueSpec]("Names"),
|
||||||
|
ValueSpec_Type: info[*ast.ValueSpec]("Type"),
|
||||||
|
ValueSpec_Values: info[*ast.ValueSpec]("Values"),
|
||||||
|
}
|
||||||
21
tests/vendor/modules.txt
vendored
21
tests/vendor/modules.txt
vendored
@@ -15,8 +15,8 @@ github.com/google/go-cmp/cmp/internal/value
|
|||||||
# github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad
|
# github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad
|
||||||
## explicit; go 1.22
|
## explicit; go 1.22
|
||||||
github.com/google/pprof/profile
|
github.com/google/pprof/profile
|
||||||
# github.com/onsi/ginkgo/v2 v2.22.2
|
# github.com/onsi/ginkgo/v2 v2.23.0
|
||||||
## explicit; go 1.22.0
|
## explicit; go 1.23.0
|
||||||
github.com/onsi/ginkgo/v2
|
github.com/onsi/ginkgo/v2
|
||||||
github.com/onsi/ginkgo/v2/config
|
github.com/onsi/ginkgo/v2/config
|
||||||
github.com/onsi/ginkgo/v2/formatter
|
github.com/onsi/ginkgo/v2/formatter
|
||||||
@@ -50,8 +50,8 @@ github.com/onsi/gomega/matchers/support/goraph/edge
|
|||||||
github.com/onsi/gomega/matchers/support/goraph/node
|
github.com/onsi/gomega/matchers/support/goraph/node
|
||||||
github.com/onsi/gomega/matchers/support/goraph/util
|
github.com/onsi/gomega/matchers/support/goraph/util
|
||||||
github.com/onsi/gomega/types
|
github.com/onsi/gomega/types
|
||||||
# golang.org/x/crypto v0.33.0
|
# golang.org/x/crypto v0.36.0
|
||||||
## explicit; go 1.20
|
## explicit; go 1.23.0
|
||||||
golang.org/x/crypto/blowfish
|
golang.org/x/crypto/blowfish
|
||||||
golang.org/x/crypto/chacha20
|
golang.org/x/crypto/chacha20
|
||||||
golang.org/x/crypto/curve25519
|
golang.org/x/crypto/curve25519
|
||||||
@@ -59,17 +59,17 @@ golang.org/x/crypto/internal/alias
|
|||||||
golang.org/x/crypto/internal/poly1305
|
golang.org/x/crypto/internal/poly1305
|
||||||
golang.org/x/crypto/ssh
|
golang.org/x/crypto/ssh
|
||||||
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
|
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
|
||||||
# golang.org/x/net v0.33.0
|
# golang.org/x/net v0.35.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
golang.org/x/net/html
|
golang.org/x/net/html
|
||||||
golang.org/x/net/html/atom
|
golang.org/x/net/html/atom
|
||||||
golang.org/x/net/html/charset
|
golang.org/x/net/html/charset
|
||||||
# golang.org/x/sys v0.30.0
|
# golang.org/x/sys v0.31.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.23.0
|
||||||
golang.org/x/sys/cpu
|
golang.org/x/sys/cpu
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
# golang.org/x/text v0.22.0
|
# golang.org/x/text v0.23.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.23.0
|
||||||
golang.org/x/text/encoding
|
golang.org/x/text/encoding
|
||||||
golang.org/x/text/encoding/charmap
|
golang.org/x/text/encoding/charmap
|
||||||
golang.org/x/text/encoding/htmlindex
|
golang.org/x/text/encoding/htmlindex
|
||||||
@@ -87,10 +87,11 @@ golang.org/x/text/internal/utf8internal
|
|||||||
golang.org/x/text/language
|
golang.org/x/text/language
|
||||||
golang.org/x/text/runes
|
golang.org/x/text/runes
|
||||||
golang.org/x/text/transform
|
golang.org/x/text/transform
|
||||||
# golang.org/x/tools v0.28.0
|
# golang.org/x/tools v0.30.0
|
||||||
## explicit; go 1.22.0
|
## explicit; go 1.22.0
|
||||||
golang.org/x/tools/cover
|
golang.org/x/tools/cover
|
||||||
golang.org/x/tools/go/ast/inspector
|
golang.org/x/tools/go/ast/inspector
|
||||||
|
golang.org/x/tools/internal/astutil/edge
|
||||||
# gopkg.in/yaml.v3 v3.0.1
|
# gopkg.in/yaml.v3 v3.0.1
|
||||||
## explicit
|
## explicit
|
||||||
gopkg.in/yaml.v3
|
gopkg.in/yaml.v3
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user