diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 92a10e4a..c00884c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,12 +29,21 @@ jobs: - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v2 + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + cache: false + - name: Make tag run: | [ "${GITHUB_EVENT_NAME}" == 'pull_request' ] && echo "TARGET_BINARY_LOCATION=pull-requests/$(echo $GITHUB_REF | awk -F / '{print $3}')-${GITHUB_HEAD_REF##*/}" >> $GITHUB_ENV || true [ "${GITHUB_EVENT_NAME}" == 'release' ] && echo "TARGET_BINARY_LOCATION=${GITHUB_REF##*/}" >> $GITHUB_ENV || true [ "${GITHUB_EVENT_NAME}" == 'push' ] && echo "TARGET_BINARY_LOCATION=latest" >> $GITHUB_ENV || true + - name: Run integration test + run: make test-integration + - name: Build image run: | make metal-hammer-initrd.img.lz4 diff --git a/Makefile b/Makefile index 97c4b1ef..b0f2f9b5 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ LINKMODE := -linkmode external -extldflags '-static -s -w' \ -X 'github.com/metal-stack/v.GitSHA1=$(SHA)' \ -X 'github.com/metal-stack/v.BuildDate=$(BUILDDATE)' -bin/$(BINARY): test $(GOSRC) +bin/$(BINARY): test-unit $(GOSRC) $(info CGO_ENABLED="$(CGO_ENABLED)") $(GO) build \ -tags netgo \ @@ -39,10 +39,14 @@ bin/$(BINARY): test $(GOSRC) $(MAINMODULE) strip bin/$(BINARY) -.PHONY: test -test: +.PHONY: test-unit +test-unit: CGO_ENABLED=1 $(GO) test -cover ./... +.PHONY: test-integration +test-integration: + CGO_ENABLED=1 find . -name '*_integration_test.go' -type f -printf '%h\n' | sort -u | xargs -r $(GO) test -cover -tags=integration + .PHONY: clean clean:: rm -f ${INITRD} ${INITRD_COMPRESSED} @@ -138,4 +142,4 @@ start: --cmdline "console=ttyS0" \ --cpus boot=4 \ --memory size=1024M \ - --net "tap=,mac=,ip=,mask=" \ No newline at end of file + --net "tap=,mac=,ip=,mask=" diff --git a/cmd/image/image.go b/cmd/image/image.go index 74889cb0..cb2a0798 100644 --- a/cmd/image/image.go +++ b/cmd/image/image.go @@ -1,13 +1,22 @@ package image import ( + "archive/tar" + "context" + "errors" "fmt" "log/slog" + "path/filepath" pb "github.com/cheggaaa/pb/v3" "github.com/mholt/archiver" lz4 "github.com/pierrec/lz4/v4" + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/mutate" + "github.com/google/go-containerregistry/pkg/v1/remote" + //nolint:gosec "crypto/md5" "io" @@ -25,7 +34,44 @@ func NewImage(log *slog.Logger) *Image { return &Image{log: log} } -// Pull a image from s3 +func (i *Image) OciPull(ctx context.Context, imageRef, mountDir, username, password string) error { + imageRefWithoutOciPrefix := strings.TrimPrefix(imageRef, "oci://") + + // TODO: just for testing - remove log statement before merging + i.log.Info("log image ref without oci prefix", "imageRefWithoutOciPrefix", imageRefWithoutOciPrefix) + ref, err := name.ParseReference(imageRefWithoutOciPrefix) + if err != nil { + return fmt.Errorf("parsing image reference: %w", err) + } + + var auth = authn.Anonymous + if username != "" || password != "" { + auth = &authn.Basic{ + Username: username, + Password: password, + } + } + + i.log.Info("pull oci image", "image", imageRef) + img, err := remote.Image(ref, remote.WithAuth(auth)) + if err != nil { + return fmt.Errorf("fetching remote image: %w", err) + } + + // Flatten layers and create a tar stream + rc := mutate.Extract(img) + defer rc.Close() + + i.log.Info(fmt.Sprintf("untar oci image into %s", mountDir), "image", imageRef) + if err := i.untar(rc, mountDir); err != nil { + return fmt.Errorf("extracting tar: %w", err) + } + + i.log.Info("pulled oci image successfully", "image", imageRef) + return nil +} + +// Pull an image from s3 func (i *Image) Pull(image, destination string) error { i.log.Info("pull image", "image", image) md5destination := destination + ".md5" @@ -49,7 +95,7 @@ func (i *Image) Pull(image, destination string) error { return nil } -// Burn a image pulling a tarball and unpack to a specific directory +// Burn an image pulling a tarball and unpack to a specific directory func (i *Image) Burn(prefix, image, source string) error { i.log.Info("burn image", "image", image) begin := time.Now() @@ -171,3 +217,74 @@ func (i *Image) download(source, dest string) error { return nil } + +func (i *Image) untar(r io.Reader, dest string) error { + tr := tar.NewReader(r) + for { + hdr, err := tr.Next() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + return fmt.Errorf("reading tar: %w", err) + } + + target := filepath.Join(dest, hdr.Name) + + i.log.Debug("untar oci image", "image", fmt.Sprintf("extracting:%s\n", target)) + + if strings.HasSuffix(target, ".log") { + i.log.Debug("untar oci image", "image", fmt.Sprintf("skipping:%s\n", target)) + continue + } + + switch hdr.Typeflag { + case tar.TypeDir: + if err := os.MkdirAll(target, os.FileMode(hdr.Mode)); err != nil { + return fmt.Errorf("creating dir: %w", err) + } + if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { + return fmt.Errorf("chown dir: %w", err) + } + + case tar.TypeReg: + if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { + return fmt.Errorf("creating parent dir: %w", err) + } + f, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(hdr.Mode)) + if err != nil { + return fmt.Errorf("creating file: %w", err) + } + if _, err := io.Copy(f, tr); err != nil { + f.Close() + return fmt.Errorf("copying file: %w", err) + } + f.Close() + + if err := os.Chmod(target, os.FileMode(hdr.Mode)); err != nil { + return fmt.Errorf("chmod file: %w", err) + } + if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { + return fmt.Errorf("chown file: %w", err) + } + + case tar.TypeSymlink: + if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { + return fmt.Errorf("creating parent dir: %w", err) + } + if err := os.Symlink(hdr.Linkname, target); err != nil { + return fmt.Errorf("creating symlink: %w", err) + } + if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { + return fmt.Errorf("chown symlink: %w", err) + } + + default: + // skip unsupported or special files, but log them + i.log.Debug("untar oci image", "image", fmt.Sprintf("skipping unsupported file type:%s\n", target)) + continue + } + } + + return nil +} diff --git a/cmd/image/image_integration_test.go b/cmd/image/image_integration_test.go new file mode 100644 index 00000000..3ca11c33 --- /dev/null +++ b/cmd/image/image_integration_test.go @@ -0,0 +1,183 @@ +//go:build integration +package image + +import ( + "context" + "crypto/rand" + "fmt" + "log/slog" + "os" + "path/filepath" + "testing" + + "github.com/foomo/htpasswd" + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/crane" + "github.com/metal-stack/metal-lib/pkg/pointer" + "github.com/stretchr/testify/require" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" +) + +func TestOciPull(t *testing.T) { + var ( + mountDir = "/tmp/oci-pull-mount-dir" + extractedBin = "a" + + anonymousUsername = "" + anonymousPassword = "" + ) + + t.Run("successful anonymous pull", func(t *testing.T) { + regIP, regPort, err := startRegistry(nil, nil, nil) + require.NoError(t, err) + registry := fmt.Sprintf("%s:%d", regIP, regPort) + + imageRef := fmt.Sprintf("%s/library/image", registry) + err = createImage(imageRef, "", "") + require.NoError(t, err) + + err = os.MkdirAll(mountDir, 0777) + require.NoError(t, err) + defer os.RemoveAll(mountDir) + + i := NewImage(slog.Default()) + if err = i.OciPull(t.Context(), imageRef, mountDir, anonymousUsername, anonymousPassword); err != nil { + require.NoError(t, err) + } + + extractedBinFullPath := filepath.Join(mountDir, extractedBin) + require.FileExists(t, extractedBinFullPath) + }) + + t.Run("successful authenticated pull", func(t *testing.T) { + var ( + username = "test-user" + password = "test-password" + ) + + f, err := os.CreateTemp("", "htpasswd") + require.NoError(t, err) + defer func() { + _ = os.Remove(f.Name()) + }() + + err = htpasswd.SetPassword(f.Name(), username, password, htpasswd.HashBCrypt) + require.NoError(t, err) + + env := map[string]string{ + "REGISTRY_AUTH": "htpasswd", + "REGISTRY_AUTH_HTPASSWD_REALM": "registry-login", + "REGISTRY_AUTH_HTPASSWD_PATH": "/htpasswd", + } + regIP, regPort, err := startRegistry(env, pointer.Pointer(f.Name()), pointer.Pointer("/htpasswd")) + require.NoError(t, err) + registry := fmt.Sprintf("%s:%d", regIP, regPort) + + imageRefBehindAuth := fmt.Sprintf("%s/library/image", registry) + err = createImage(imageRefBehindAuth, username, password) + require.NoError(t, err) + + err = os.MkdirAll(mountDir, 0777) + require.NoError(t, err) + defer os.RemoveAll(mountDir) + + i := NewImage(slog.Default()) + if err = i.OciPull(t.Context(), imageRefBehindAuth, mountDir, username, password); err != nil { + require.NoError(t, err) + } + + extractedBinFullPath := filepath.Join(mountDir, extractedBin) + require.FileExists(t, extractedBinFullPath) + }) + + t.Run("parsing of image refs fails", func(t *testing.T) { + invalidImageRef := "invalid://" + i := NewImage(slog.Default()) + err := i.OciPull(t.Context(), invalidImageRef, mountDir, anonymousUsername, anonymousPassword) + require.EqualError(t, err, "parsing image reference: could not parse reference: invalid://") + }) + + t.Run("pulling remote image fails", func(t *testing.T) { + imageRefDoesNotExist := "oci://does/not/exist:tag" + i := NewImage(slog.Default()) + err := i.OciPull(t.Context(), imageRefDoesNotExist, mountDir, anonymousUsername, anonymousPassword) + require.Error(t, err) + }) +} + +// HELPER FUNCTIONS +func startRegistry(env map[string]string, src, dst *string) (string, int, error) { + ctx := context.Background() + var ( + c testcontainers.Container + err error + ) + + req := testcontainers.ContainerRequest{ + Image: "registry:3", + ExposedPorts: []string{"5000/tcp"}, + Env: env, + WaitingFor: wait.ForAll( + wait.ForLog("listening on"), + wait.ForListeningPort("5000/tcp"), + ), + } + c, err = testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + }) + if err != nil { + return "", 0, err + } + if src != nil && dst != nil { + err = c.CopyFileToContainer(ctx, *src, *dst, 0o777) + if err != nil { + return "", 0, err + } + } + + ip, err := c.Host(ctx) + if err != nil { + return ip, 0, err + } + port, err := c.MappedPort(ctx, "5000") + if err != nil { + return ip, port.Int(), err + } + + return ip, port.Int(), nil +} + +func createImage(imageName, username, password string, tags ...string) error { + // ensure every image has distinct content + buf := make([]byte, 128) + _, err := rand.Read(buf) + if err != nil { + return err + } + img, err := crane.Image(map[string][]byte{"a": buf}) + if err != nil { + return err + } + + var auth = authn.Anonymous + if username != "" || password != "" { + auth = &authn.Basic{ + Username: username, + Password: password, + } + } + err = crane.Push(img, imageName, crane.WithAuth(auth)) + if err != nil { + return err + } + for _, tag := range tags { + err := crane.Push(img, imageName+":"+tag, crane.WithAuth(auth)) + if err != nil { + return err + } + } + + return nil +} diff --git a/cmd/image/image_test.go b/cmd/image/image_test.go index 9743ee06..87cc28c9 100644 --- a/cmd/image/image_test.go +++ b/cmd/image/image_test.go @@ -1,10 +1,14 @@ package image import ( + "archive/tar" "log/slog" "os" "os/exec" + "path/filepath" "testing" + + "github.com/stretchr/testify/require" ) func TestCheckMD5(t *testing.T) { @@ -41,5 +45,91 @@ func TestCheckMD5(t *testing.T) { if !matches { t.Error("expected md5 matches, but didn't") } +} + +func TestUntar(t *testing.T) { + tempDir := t.TempDir() + + testCases := []struct { + name string + fileType byte + mode os.FileMode + content string + }{ + {"setuid_file", tar.TypeReg, 04755, "test content"}, // Regular file with setuid bit + {"setgid_file", tar.TypeReg, 02755, "test content"}, // Regular file with setgid bit + {"sticky_file", tar.TypeReg, 01755, "test content"}, // Regular file with sticky bit + {"setgid_dir", tar.TypeDir, 02755, ""}, // Directory with setgid bit + {"sticky_dir", tar.TypeDir, 01755, ""}, // Directory with sticky bit + {"symlink", tar.TypeSymlink, 0777, "target"}, // Symbolic link + // {"shadow_file", tar.TypeReg, 0000, "test content"}, // Simulate special files - FIXME: special files need root permissions + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tarPath := filepath.Join(tempDir, tc.name+".tar") + createTestTar(t, tarPath, tc.name, tc.fileType, tc.mode, tc.content) + + destDir := filepath.Join(tempDir, "extracted_"+tc.name) + i := NewImage(slog.Default()) + + tarFile, err := os.Open(tarPath) + require.NoError(t, err) + defer tarFile.Close() + err = i.untar(tarFile, destDir) + require.NoError(t, err) + + extractedPath := filepath.Join(destDir, tc.name) + verifyExtractedFile(t, extractedPath, tc.fileType, tc.mode, tc.content) + }) + } + + // TODO: consider character and block devices -> skipped for now due to root permissions +} +func createTestTar(t *testing.T, tarPath, fileName string, fileType byte, mode os.FileMode, content string) { + tarFile, err := os.Create(tarPath) + require.NoError(t, err) + defer tarFile.Close() + + tw := tar.NewWriter(tarFile) + defer tw.Close() + + header := &tar.Header{ + Name: fileName, + Typeflag: fileType, + } + if fileType == tar.TypeSymlink { + header.Linkname = content + } else { + header.Size = int64(len(content)) + header.Mode = int64(mode) + } + + err = tw.WriteHeader(header) + require.NoError(t, err) + + if fileType == tar.TypeReg { + _, err := tw.Write([]byte(content)) + require.NoError(t, err) + } +} + +func verifyExtractedFile(t *testing.T, path string, fileType byte, mode os.FileMode, content string) { + info, err := os.Lstat(path) + require.NoError(t, err) + require.Equal(t, info.Mode().Perm(), mode.Perm()) + + switch fileType { + case tar.TypeReg: + data, err := os.ReadFile(path) + require.NoError(t, err) + require.Equal(t, string(data), content) + case tar.TypeSymlink: + target, err := os.Readlink(path) + require.NoError(t, err) + require.Equal(t, target, content) + case tar.TypeDir: + require.Equal(t, info.IsDir(), true) + } } diff --git a/cmd/install.go b/cmd/install.go index 3c41222b..a0737e7c 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -1,6 +1,7 @@ package cmd import ( + "context" "encoding/base64" "fmt" "os" @@ -29,16 +30,30 @@ func (h *hammer) Install(machine *models.V1MachineResponse) (*api.Bootinfo, erro return nil, err } - image := machine.Allocation.Image.URL + imageURL := machine.Allocation.Image.URL + newImage := img.NewImage(h.log) - err = img.NewImage(h.log).Pull(image, h.osImageDestination) - if err != nil { - return nil, err - } + h.log.Info("checking oci image", "image", imageURL) + if strings.HasPrefix(imageURL, "oci://") { + ociConfig := h.spec.MetalConfig.OciConfigs[imageURL] + ctx := context.Background() - err = img.NewImage(h.log).Burn(h.chrootPrefix, image, h.osImageDestination) - if err != nil { - return nil, err + // TODO: just for testing - remove log statement before merging + h.log.Info("log oci config", "ociConfig", ociConfig) + err = newImage.OciPull(ctx, imageURL, h.chrootPrefix, ociConfig.Username, ociConfig.Password) + if err != nil { + return nil, err + } + } else { + err = newImage.Pull(imageURL, h.osImageDestination) + if err != nil { + return nil, err + } + + err = newImage.Burn(h.chrootPrefix, imageURL, h.osImageDestination) + if err != nil { + return nil, err + } } info, err := h.install(h.chrootPrefix, machine, s.RootUUID) @@ -244,6 +259,7 @@ func (h *hammer) writeInstallerConfig(machine *models.V1MachineResponse, rootUUi return os.WriteFile(destination, yamlContent, 0600) } + func (h *hammer) onlyNicsWithNeighbors(nics []*models.V1MachineNic) []*models.V1MachineNic { noNeighbors := func(neighbors []*models.V1MachineNic) bool { if len(neighbors) == 0 { diff --git a/go.mod b/go.mod index f07ef59e..1fb13aa9 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ go 1.26 require ( github.com/beevik/ntp v1.5.0 github.com/cheggaaa/pb/v3 v3.1.7 + github.com/foomo/htpasswd v0.0.0-20200116085101-e3a90e78da9c + github.com/google/go-containerregistry v0.20.6 github.com/google/gopacket v1.1.19 github.com/google/uuid v1.6.0 github.com/grafana/loki-client-go v0.0.0-20251015150631-c42bbddc310a @@ -13,7 +15,8 @@ require ( github.com/metal-stack/go-lldpd v0.4.11 github.com/metal-stack/metal-api v0.43.0 github.com/metal-stack/metal-go v0.43.0 - github.com/metal-stack/pixie v0.3.7 + github.com/metal-stack/metal-lib v0.23.5 + github.com/metal-stack/pixie v0.4.2-0.20260316091459-620e75c3ea43 github.com/metal-stack/v v1.0.3 // archiver must stay in version v2.1.0, see replace below github.com/mholt/archiver v3.1.1+incompatible @@ -22,6 +25,8 @@ require ( github.com/prometheus/common v0.67.5 github.com/samber/slog-loki/v3 v3.7.1 github.com/samber/slog-multi v1.7.1 + github.com/stretchr/testify v1.11.1 + github.com/testcontainers/testcontainers-go v0.40.0 github.com/u-root/u-root v0.15.0 github.com/vishvananda/netlink v1.3.1 golang.org/x/sync v0.19.0 @@ -38,18 +43,39 @@ replace ( ) require ( + dario.cat/mergo v1.0.2 // indirect + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect + github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/VividCortex/ewma v1.2.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/avast/retry-go/v4 v4.7.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/containerd/errdefs v1.0.0 // indirect + github.com/containerd/errdefs/pkg v0.3.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.18.1 // indirect github.com/coreos/go-oidc/v3 v3.17.0 // indirect + github.com/cpuguy83/dockercfg v0.3.2 // indirect github.com/creack/pty v1.1.24 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/dennwc/varint v1.0.0 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/cli v29.0.0+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v28.5.2+incompatible // indirect + github.com/docker/docker-credential-helpers v0.9.4 // indirect + github.com/docker/go-connections v0.6.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dsnet/compress v0.0.1 // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/fatih/color v1.18.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/frankban/quicktest v1.14.6 // indirect github.com/gliderlabs/ssh v0.3.8 // indirect github.com/go-jose/go-jose/v4 v4.1.3 // indirect @@ -91,30 +117,45 @@ require ( github.com/jaypipes/pcidb v1.1.1 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/lestrrat-go/blackmagic v1.0.4 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httprc/v3 v3.0.4 // indirect github.com/lestrrat-go/jwx/v3 v3.0.13 // indirect github.com/lestrrat-go/option/v2 v2.0.0 // indirect + github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88 // indirect + github.com/magiconair/properties v1.8.10 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 // indirect github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5 // indirect - github.com/metal-stack/metal-lib v0.23.5 // indirect github.com/metal-stack/security v0.9.5 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/go-archive v0.2.0 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/sys/sequential v0.6.0 // indirect + github.com/moby/sys/user v0.4.0 // indirect + github.com/moby/sys/userns v0.1.0 // indirect + github.com/moby/term v0.5.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/morikuni/aec v1.1.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/nwaples/rardecode v1.1.3 // indirect github.com/oklog/ulid v1.3.1 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/procfs v0.17.0 // indirect + github.com/prometheus/procfs v0.19.1 // indirect github.com/prometheus/prometheus v0.304.0 // indirect github.com/rekby/gpt v0.0.0-20200614112001-7da10aec5566 // indirect github.com/rivo/uniseg v0.4.7 // indirect @@ -122,14 +163,20 @@ require ( github.com/samber/slog-common v0.20.0 // indirect github.com/segmentio/asm v1.2.1 // indirect github.com/sethvargo/go-password v0.3.1 // indirect + github.com/shirou/gopsutil/v4 v4.26.2 // indirect + github.com/sirupsen/logrus v1.9.4 // indirect github.com/stmcginnis/gofish v0.21.3 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect github.com/ulikunitz/xz v0.5.15 // indirect + github.com/vbatts/tar-split v0.12.2 // indirect github.com/vishvananda/netns v0.0.5 // indirect github.com/vmware/goipmi v0.0.0-20181114221114-2333cd82d702 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.mongodb.org/mongo-driver v1.17.9 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/trace v1.40.0 // indirect @@ -141,6 +188,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/oauth2 v0.35.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect howett.net/plist v1.0.2-0.20250314012144-ee69052608d9 // indirect diff --git a/go.sum b/go.sum index 8e41eb85..1950a61b 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 h1:OVoM452qUFBrX+URdH3VpR299ma4kfom0yB0URYky9g= @@ -16,6 +18,9 @@ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEK github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/GehirnInc/crypt v0.0.0-20190301055215-6c0105aabd46/go.mod h1:kC29dT1vFpj7py2OvG1khBdQpo3kInWP+6QipLbdngo= +github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 h1:IEjq88XO4PuBDcvmjQJcQGg+w+UaafSy8G5Kcb5tBhI= +github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5/go.mod h1:exZ0C/1emQJAw5tHOaUDyY1ycttqBAPcxuzf7QbY6ec= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= @@ -54,6 +59,8 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/containerd/stargz-snapshotter/estargz v0.18.1 h1:cy2/lpgBXDA3cDKSyEfNOFMA/c10O1axL69EU7iirO8= +github.com/containerd/stargz-snapshotter/estargz v0.18.1/go.mod h1:ALIEqa7B6oVDsrF37GkGN20SuvG/pIMm7FwP7ZmRb0Q= github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc= github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= @@ -71,8 +78,14 @@ github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/cli v29.0.0+incompatible h1:KgsN2RUFMNM8wChxryicn4p46BdQWpXOA1XLGBGPGAw= +github.com/docker/cli v29.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.9.4 h1:76ItO69/AP/V4yT9V4uuuItG0B1N8hvt0T0c0NN/DzI= +github.com/docker/docker-credential-helpers v0.9.4/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -88,6 +101,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foomo/htpasswd v0.0.0-20200116085101-e3a90e78da9c h1:DBGU7zCwrrPPDsD6+gqKG8UfMxenWg9BOJE/Nmfph+4= +github.com/foomo/htpasswd v0.0.0-20200116085101-e3a90e78da9c/go.mod h1:SHawtolbB0ZOFoRWgDwakX5WpwuIWAK88bUXVZqK0Ss= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= @@ -173,6 +188,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU= +github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= @@ -192,6 +209,8 @@ github.com/grafana/loki/pkg/push v0.0.0-20250903093132-95ced86f69c5 h1:XHwXGwthM github.com/grafana/loki/pkg/push v0.0.0-20250903093132-95ced86f69c5/go.mod h1:QClrwZWT4u0N/O0Z0zKnRn36D51XTJMMmy7ICgaECd0= github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hugelgupf/go-shlex v0.0.0-20200702092117-c80c9d0918fa h1:s3KPo0nThtvjEamF/aElD4k5jSsBHew3/sgNTnth+2M= github.com/hugelgupf/go-shlex v0.0.0-20200702092117-c80c9d0918fa/go.mod h1:I1uW6ymzwsy5TlQgD1bFAghdMgBYqH1qtCeHoZgHMqs= github.com/hugelgupf/vmtest v0.0.0-20240307030256-5d9f3d34a58d h1:nP8SfQJqruIVSWYJTuYc37jLHEY1Z0fF+zKSrs3K/C8= @@ -262,14 +281,16 @@ github.com/metal-stack/metal-go v0.43.0 h1:uODD0YCwnAYzyvFxWNakZrymBoMz1FAvP5hkh github.com/metal-stack/metal-go v0.43.0/go.mod h1:GSfXrAj55LGsUSMHWGDsmq5n056NG0yb1JM8bgfvKOw= github.com/metal-stack/metal-lib v0.23.5 h1:ozrkB3DNr3Cqn8nkBvmzc/KKpYqC1j1mv2OVOj8i7Ac= github.com/metal-stack/metal-lib v0.23.5/go.mod h1:7uyHIrE19dkLwCZyeh2jmd7IEq5pEpzrzUGLoMN1eqY= -github.com/metal-stack/pixie v0.3.7 h1:W5HPcv7E7shvMx+SyJmwymtThsQ3b5pMDl+43PZ8p5o= -github.com/metal-stack/pixie v0.3.7/go.mod h1:B7dVzfg7PxZzpxfuYNgC9xhSNFyycoI0dd1I+K2iPak= +github.com/metal-stack/pixie v0.4.2-0.20260316091459-620e75c3ea43 h1:AlHUBl/B/IC7OICrIjeeDKgUMaM4GuUiPBEeorTgIoI= +github.com/metal-stack/pixie v0.4.2-0.20260316091459-620e75c3ea43/go.mod h1:F921gmyW8jQt6/7eDujPDywFe68+iqZ5+w/ub5EfAi4= github.com/metal-stack/security v0.9.5 h1:dWJP1hJxvQhdyyrmKqYxsi5sZ5Wbxa66OZBiArT2z0k= github.com/metal-stack/security v0.9.5/go.mod h1:2++bUdpPbx4d7faiEUiowelT4E65U79Kcw3UOHbuw4k= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= github.com/mholt/archiver v2.1.0+incompatible h1:1ivm7KAHPtPere1YDOdrY6xGdbMNGRWThZbYh5lWZT0= github.com/mholt/archiver v2.1.0+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= +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/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= @@ -278,6 +299,8 @@ github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8 github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= +github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= @@ -331,8 +354,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= -github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/prometheus/procfs v0.19.1 h1:QVtROpTkphuXuNlnCv3m1ut3JytkXHtQ3xvck/YmzMM= +github.com/prometheus/procfs v0.19.1/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/prometheus/prometheus v0.304.0 h1:otXBqfF7bbTcW7IrXrB6HMjo4dThQbayCPFr2yTlqrQ= github.com/prometheus/prometheus v0.304.0/go.mod h1:ioGx2SGKTY+fLnJSQCdTHqARVldGNS8OlIe3kvp98so= github.com/prometheus/sigv4 v0.1.2 h1:R7570f8AoM5YnTUPFm3mjZH5q2k4D+I/phCWvZ4PXG8= @@ -364,6 +387,8 @@ github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC4 github.com/stmcginnis/gofish v0.21.3 h1:EBLCHfORnbx7MPw7lplOOVe9QAD1T3XRVz6+a1Z4z5Q= github.com/stmcginnis/gofish v0.21.3/go.mod h1:PzF5i8ecRG9A2ol8XT64npKUunyraJ+7t0kYMpQAtqU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -386,6 +411,8 @@ github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM= github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= +github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4= +github.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= @@ -404,14 +431,20 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -422,6 +455,7 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= @@ -453,6 +487,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -484,6 +520,8 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.230.0 h1:2u1hni3E+UXAXrONrrkfWpi/V6cyKVAbfGVeGtC3OxM= google.golang.org/api v0.230.0/go.mod h1:aqvtoMk7YkiXx+6U12arQFExiRV9D/ekvMCwCd/TksQ= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= @@ -498,6 +536,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= howett.net/plist v1.0.2-0.20250314012144-ee69052608d9 h1:eeH1AIcPvSc0Z25ThsYF+Xoqbn0CI/YnXVYoTLFdGQw= howett.net/plist v1.0.2-0.20250314012144-ee69052608d9/go.mod h1:fyFX5Hj5tP1Mpk8obqA9MZgXT416Q5711SDT7dQLTLk= k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=